homepage/main.py

158 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Flask, render_template, request, jsonify, make_response
import yaml
from datetime import datetime
import os
import requests
import time
import locale
app = Flask(__name__)
CONFIG_PATH = 'config.yaml'
# Кэш для погоды
weather_cache = {'data': None, 'ts': 0}
# Кэш для прогноза
weather_forecast_cache = {'data': None, 'ts': 0}
def load_config():
with open(CONFIG_PATH, encoding='utf-8') as f:
return yaml.safe_load(f)
def save_config(yaml_text):
with open(CONFIG_PATH, 'w', encoding='utf-8') as f:
f.write(yaml_text)
def get_weather_cache_ttl():
config = load_config()
w = config.get('weather', {})
ttl = w.get('cache_ttl')
try:
return int(ttl) * 60 if ttl else 3600
except Exception:
return 3600
def get_weather():
global weather_cache
now = time.time()
WEATHER_CACHE_TTL = get_weather_cache_ttl()
if weather_cache['data'] and now - weather_cache['ts'] < WEATHER_CACHE_TTL:
return weather_cache['data']
config = load_config()
w = config.get('weather', {})
api_key = w.get('api_key')
lat = w.get('lat')
lon = w.get('lon')
if not api_key or not lat or not lon:
return None
url = f"https://api.weatherapi.com/v1/current.json?key={api_key}&q={lat},{lon}&lang=ru"
try:
resp = requests.get(url, timeout=5)
resp.raise_for_status()
data = resp.json()
temp = data['current']['temp_c']
cloud = data['current']['cloud']
condition = data['current'].get('condition', {})
icon = condition.get('icon', '')
text = condition.get('text', '')
result = {'temp': temp, 'cloud': cloud, 'icon': icon, 'text': text}
weather_cache = {'data': result, 'ts': now}
return result
except Exception:
return None
def get_weather_forecast():
global weather_forecast_cache
now = time.time()
WEATHER_CACHE_TTL = get_weather_cache_ttl()
if weather_forecast_cache['data'] and now - weather_forecast_cache['ts'] < WEATHER_CACHE_TTL:
return weather_forecast_cache['data']
config = load_config()
w = config.get('weather', {})
api_key = w.get('api_key')
lat = w.get('lat')
lon = w.get('lon')
if not api_key or not lat or not lon:
raise Exception('Не заданы api_key, lat или lon')
url = f"https://api.weatherapi.com/v1/forecast.json?key={api_key}&q={lat},{lon}&days=10&lang=ru"
try:
resp = requests.get(url, timeout=5)
resp.raise_for_status()
data = resp.json()
forecast = []
for day in data['forecast']['forecastday']:
d = day['day']
temp = d.get('avgtemp_c')
if temp is None:
temp = d.get('maxtemp_c')
cloud = d.get('cloud', 0)
condition = d.get('condition', {})
forecast.append({
'date': day['date'],
'temp': temp,
'cloud': cloud,
'text': condition.get('text', ''),
'icon': condition.get('icon', '')
})
weather_forecast_cache = {'data': forecast, 'ts': now}
return forecast
except Exception as e:
try:
return {'_error': resp.text}
except:
return {'_error': str(e)}
@app.route('/api/config', methods=['GET'])
def get_config():
try:
with open(CONFIG_PATH, encoding='utf-8') as f:
content = f.read()
return jsonify({'content': content})
except Exception as e:
return make_response(jsonify({'error': str(e)}), 500)
@app.route('/api/config', methods=['POST'])
def update_config():
data = request.get_json()
yaml_text = data.get('content', '')
try:
# Проверка валидности yaml
yaml.safe_load(yaml_text)
save_config(yaml_text)
return jsonify({'status': 'ok'})
except Exception as e:
return make_response(jsonify({'error': str(e)}), 400)
@app.route('/api/weather-forecast', methods=['GET'])
def api_weather_forecast():
forecast = get_weather_forecast()
if forecast is None:
return {'error': 'Ошибка получения прогноза'}, 500
if isinstance(forecast, dict) and '_error' in forecast:
return {'error': forecast['_error']}, 500
return {'forecast': forecast}
# config = load_config() # Удаляем глобальную переменную
@app.route('/')
def index():
# Словари для русских дат
days = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье']
months = [
'', 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'
]
now = datetime.now()
day = days[now.weekday()]
month = months[now.month]
now_str = f"{day}, {now.day} {month} {now.year}"
current_time = now.strftime('%H:%M:%S')
weather = get_weather()
config = load_config() # Загружаем актуальный конфиг при каждом запросе
return render_template('index.html', applications=config['applications'], bookmarks=config['bookmarks'], now=now_str, current_time=current_time, weather=weather)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')