diff --git "a/app.py" "b/app.py" --- "a/app.py" +++ "b/app.py" @@ -1,4 +1,4 @@ -from flask import Flask, render_template_string, request, redirect, url_for, session +from flask import Flask, render_template_string, request, redirect, url_for, session, jsonify import random import string import json @@ -10,26 +10,23 @@ import threading from datetime import datetime from huggingface_hub import HfApi, hf_hub_download from huggingface_hub.utils import RepositoryNotFoundError +from urllib.parse import urlparse, parse_qs app = Flask(__name__) app.config['SECRET_KEY'] = 'your-very-secret-key-here' -socketio = SocketIO(app) +socketio = SocketIO(app, async_mode='threading') -# --- Hugging Face Hub Settings --- -REPO_ID = "flpolprojects/Clients" # ваш репозиторий -HF_TOKEN_WRITE = os.getenv("HF_TOKEN") # токен с правами на запись -HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") # токен с правами на чтение (можно тот же, если у него есть и чтение, и запись) +REPO_ID = "flpolprojects/Clients" +HF_TOKEN_WRITE = os.getenv("HF_TOKEN") +HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") -# --- File Paths --- ROOMS_DB = os.path.join(app.root_path, 'rooms.json') USERS_DB = os.path.join(app.root_path, 'users.json') GAMES_DB = os.path.join(app.root_path, 'games.json') -# --- Data Loading and Saving with Hugging Face Backup --- - def load_json(file_path, default={}): try: - download_db_from_hf() # Скачиваем перед загрузкой + download_db_from_hf() if os.path.exists(file_path): with open(file_path, 'r', encoding='utf-8') as f: return json.load(f) @@ -38,25 +35,24 @@ def load_json(file_path, default={}): print(f"Ошибка загрузки JSON из {file_path}: {e}") return default except Exception as e: - print(f"Непредвиденная ошибка при загрузке: {e}") #Добавил обработку + print(f"Непредвиденная ошибка при загрузке: {e}") return default def save_json(file_path, data): try: with open(file_path, 'w', encoding='utf-8') as f: json.dump(data, f, indent=4, ensure_ascii=False) - upload_db_to_hf() # Загружаем после сохранения + upload_db_to_hf() except OSError as e: print(f"Ошибка сохранения JSON в {file_path}: {e}") - except Exception as e: #Добавил обработку + except Exception as e: print(f"Непредвиденная ошибка при сохранении: {e}") def upload_db_to_hf(): try: api = HfApi() - # Загружаем все три JSON файла for file_path, repo_path in [(ROOMS_DB, "rooms.json"), (USERS_DB, "users.json"), (GAMES_DB, "games.json")]: - if os.path.exists(file_path): # Проверяем наличие файла + if os.path.exists(file_path): api.upload_file( path_or_fileobj=file_path, path_in_repo=repo_path, @@ -65,16 +61,12 @@ def upload_db_to_hf(): token=HF_TOKEN_WRITE, commit_message=f"Backup: {repo_path} ({datetime.now().strftime('%Y-%m-%d %H:%M:%S')})" ) - print(f"Файл {file_path} успешно загружен на Hugging Face Hub.") - else: - print(f"Файл {file_path} не существует, пропуск загрузки.") except Exception as e: print(f"Ошибка при загрузке файлов на Hugging Face Hub: {e}") def download_db_from_hf(): try: api = HfApi() - # Скачиваем все три JSON файла for file_path, repo_path in [(ROOMS_DB, "rooms.json"), (USERS_DB, "users.json"), (GAMES_DB, "games.json")]: try: hf_hub_download( @@ -82,66 +74,56 @@ def download_db_from_hf(): filename=repo_path, repo_type="dataset", token=HF_TOKEN_READ, - local_dir=".", # Сохраняем в текущую директорию - local_dir_use_symlinks=False # Важно для корректной работы на некоторых платформах + local_dir=".", + local_dir_use_symlinks=False ) - print(f"Файл {repo_path} успешно скачан с Hugging Face Hub.") except RepositoryNotFoundError: - print(f"Файл {repo_path} не найден в репозитории. Создание локального.") - # Создаем пустой файл, если его нет в репозитории if not os.path.exists(file_path): with open(file_path, 'w') as f: - json.dump({}, f) # Создание пустого + json.dump({}, f) except Exception as e: print(f"Ошибка при скачивании файла {repo_path}: {e}") - - except Exception as e: print(f"Ошибка при скачивании файлов с Hugging Face Hub: {e}") def periodic_backup(): while True: upload_db_to_hf() - time.sleep(15) # Резервное копирование каждые 15 секунд - + time.sleep(15) -# --- Initial Data Loading --- rooms = load_json(ROOMS_DB) users = load_json(USERS_DB) games_data = load_json(GAMES_DB, default={ "crocodile": { "name": "Крокодил", - "description": "Один игрок (ведущий) получает слово и должен показать его жестами остальным игрокам, не произнося ни слова. Остальные игроки пытаются угадать слово.", + "description": "Один игрок показывает слово жестами.", "min_players": 2, - "max_players": 5, + "max_players": 10, "state": {} }, "alias": { "name": "Alias", - "description": "Один игрок (ведущий) получает слово и должен объяснить его другими словами, не используя однокоренные. Остальные игроки пытаются угадать слово.", + "description": "Один игрок объясняет слово.", "min_players": 2, - "max_players": 5, + "max_players": 10, "state": {} }, "mafia": { "name": "Мафия", - "description": "Игроки делятся на две команды: мафию и мирных жителей. Мафия пытается тайно убивать мирных жителей, а мирные жители пытаются вычислить и казнить мафию.", + "description": "Мафия против мирных жителей.", "min_players": 4, - "max_players": 5, # Можно увеличить, но для теста оставим так + "max_players": 10, "state": {} }, "durak": { "name": "Дурак", - "description": "Карточная игра, в которой игроки стараются избавиться от всех своих карт.", + "description": "Карточная игра.", "min_players": 2, - "max_players": 5, - "state": {} # Состояние игры + "max_players": 10, + "state": {} } }) -save_json(GAMES_DB, games_data) # Сохраняем изменения (на случай, если файл был создан) - - -# --- Helper Functions --- +save_json(GAMES_DB, games_data) def generate_token(): return ''.join(random.choices(string.ascii_letters + string.digits, k=15)) @@ -149,8 +131,21 @@ def generate_token(): def hash_password(password): return hashlib.sha256(password.encode('utf-8')).hexdigest() - -# --- Flask Routes --- +def get_youtube_id(url): + if not url: + return None + parsed_url = urlparse(url) + if parsed_url.hostname in ('www.youtube.com', 'youtube.com'): + if parsed_url.path == '/watch': + query = parse_qs(parsed_url.query) + return query.get('v', [None])[0] + elif parsed_url.path.startswith('/embed/'): + return parsed_url.path.split('/embed/')[1].split('?')[0] + elif parsed_url.path.startswith('/v/'): + return parsed_url.path.split('/v/')[1].split('?')[0] + elif parsed_url.hostname in ('youtu.be', 'www.youtu.be'): + return parsed_url.path[1:].split('?')[0] + return None @app.route('/', methods=['GET', 'POST']) def index(): @@ -165,18 +160,19 @@ def index(): if action == 'register': if username in users: return "Пользователь уже существует", 400 - users[username] = hash_password(password) + users[username] = {'password': hash_password(password), 'rooms': []} save_json(USERS_DB, users) session['username'] = username return redirect(url_for('dashboard')) elif action == 'login': - if username in users and users[username] == hash_password(password): + if username in users and users[username]['password'] == hash_password(password): session['username'] = username return redirect(url_for('dashboard')) return "Неверный логин или пароль", 401 - return render_template_string(''' + return render_template_string(''' +
@@ -273,7 +269,8 @@ def index(): -''') +