import os import json import time from datetime import datetime from uuid import uuid4 from flask import Flask, render_template_string, request, jsonify from huggingface_hub import HfApi, hf_hub_download from huggingface_hub.utils import RepositoryNotFoundError, HfHubHTTPError from dotenv import load_dotenv import requests load_dotenv() app = Flask(__name__) app.secret_key = 'level_designer_secret_key_12345' REPO_ID = "Kgshop/Testai" HF_TOKEN_WRITE = os.getenv("HF_TOKEN") HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") DOWNLOAD_RETRIES = 3 DOWNLOAD_DELAY = 5 def upload_project_to_hf(local_path, project_name): if not HF_TOKEN_WRITE: print("HF_TOKEN_WRITE is not set. Cannot upload.") return False try: api = HfApi() api.upload_file( path_or_fileobj=local_path, path_in_repo=f"projects/{project_name}.json", repo_id=REPO_ID, repo_type="dataset", token=HF_TOKEN_WRITE, commit_message=f"Save project {project_name} at {datetime.now()}" ) return True except Exception as e: print(f"Error uploading {project_name} to HF: {e}") return False def download_project_from_hf(project_name, retries=DOWNLOAD_RETRIES, delay=DOWNLOAD_DELAY): token_to_use = HF_TOKEN_READ if HF_TOKEN_READ else HF_TOKEN_WRITE if not token_to_use: print("No Hugging Face token found for reading.") return None for attempt in range(retries + 1): try: local_path = hf_hub_download( repo_id=REPO_ID, filename=f"projects/{project_name}.json", repo_type="dataset", token=token_to_use, local_dir=".", local_dir_use_symlinks=False, force_download=True ) with open(local_path, 'r', encoding='utf-8') as f: data = json.load(f) if os.path.exists(local_path): os.remove(local_path) return data except (HfHubHTTPError, RepositoryNotFoundError) as e: print(f"Project '{project_name}' not found on HF Hub on attempt {attempt + 1}: {e}") return None except Exception as e: print(f"An unexpected error occurred during download attempt {attempt + 1}: {e}") if attempt < retries: time.sleep(delay) return None def list_projects_from_hf(): token_to_use = HF_TOKEN_READ if HF_TOKEN_READ else HF_TOKEN_WRITE if not token_to_use: return [] try: api = HfApi() repo_info = api.list_repo_files(repo_id=REPO_ID, repo_type="dataset", token=token_to_use) project_files = [f.split('/')[-1].replace('.json', '') for f in repo_info if f.startswith('projects/') and f.endswith('.json')] return sorted(project_files) except RepositoryNotFoundError: print("Repository not found, creating 'projects' directory might be needed on first save.") return [] except Exception as e: print(f"Error listing projects from HF: {e}") return [] EDITOR_TEMPLATE = ''' 3D Level Designer

Режим

Проект


Ландшафт

Кисть

Управление текстурами


Текстуры ландшафта

Объекты

Нажмите, чтобы играть

Движение: WASD
Прыжок: ПРОБЕЛ
Осмотр: МЫШЬ

Нажмите ESC для выхода

''' @app.route('/') def editor(): projects = list_projects_from_hf() return render_template_string(EDITOR_TEMPLATE, projects=projects) @app.route('/api/project', methods=['POST']) def save_project_api(): data = request.get_json() project_name = data.get('name') if not project_name: return jsonify({"error": "Project name is required"}), 400 local_filename = f"{uuid4().hex}.json" with open(local_filename, 'w', encoding='utf-8') as f: json.dump(data, f) success = upload_project_to_hf(local_filename, project_name) if os.path.exists(local_filename): os.remove(local_filename) if success: return jsonify({"message": "Project saved successfully"}), 201 else: return jsonify({"error": "Failed to upload project to Hugging Face Hub"}), 500 @app.route('/api/project/', methods=['GET']) def load_project_api(project_name): project_data = download_project_from_hf(project_name) if project_data: return jsonify(project_data) else: return jsonify({"error": "Project not found or failed to download"}), 404 if __name__ == '__main__': port = int(os.environ.get('PORT', 7860)) app.run(debug=False, host='0.0.0.0', port=port)