Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, UploadFile, File, WebSocket, WebSocketDisconnect, HTTPException, Body | |
| from fastapi.staticfiles import StaticFiles | |
| from fastapi.responses import FileResponse | |
| from pydantic import BaseModel | |
| from textblob import TextBlob | |
| from passlib.context import CryptContext | |
| from typing import List, Optional | |
| import os | |
| import json | |
| import base64 | |
| app = FastAPI(title="Zenith Platform") | |
| # --- CONFIG --- | |
| pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") | |
| SUPABASE_URL = os.getenv("SUPABASE_URL") | |
| SUPABASE_KEY = os.getenv("SUPABASE_KEY") | |
| # ВАЖНО: Если переменная не задана, код будет '1234'. Проверь это! | |
| ADMIN_SECRET_CODE = os.getenv("ADMIN_SECRET_CODE", "1234") | |
| # --- MODELS --- | |
| class CreateUserModel(BaseModel): | |
| admin_code: str | |
| new_username: str | |
| new_password: str | |
| class UpdateProfileModel(BaseModel): | |
| username: str | |
| is_looking: bool | |
| class MessageInput(BaseModel): | |
| text: str | |
| # --- AUTH & ADMIN --- | |
| async def create_user(data: CreateUserModel): | |
| # Логируем для отладки (будет видно в логах HF) | |
| print(f"Admin attempt. Input code: '{data.admin_code}', Expected: '{ADMIN_SECRET_CODE}'") | |
| if data.admin_code.strip() != ADMIN_SECRET_CODE: | |
| raise HTTPException(status_code=403, detail="ACCESS DENIED: Wrong Code") | |
| hashed_pw = pwd_context.hash(data.new_password) | |
| return { | |
| "username": data.new_username, | |
| "password_hash": hashed_pw, | |
| "badge": "BETA" | |
| } | |
| async def update_profile(data: UpdateProfileModel): | |
| # Здесь просто возвращаем статус, реальная запись идет через Supabase Client на фронте | |
| # или можно расширить этот метод для серверной записи. | |
| return {"status": "ok", "looking_for_friends": data.is_looking} | |
| # --- CHAT & MOOD --- | |
| async def analyze_mood(msg: MessageInput): | |
| blob = TextBlob(msg.text) | |
| p = blob.sentiment.polarity | |
| if p > 0.5: return {"mood_color": "#00f2ea", "emoji": "✨"} | |
| elif p > 0: return {"mood_color": "#4facfe", "emoji": "😌"} | |
| elif p < -0.5: return {"mood_color": "#ff0055", "emoji": "🔥"} | |
| elif p < 0: return {"mood_color": "#8e44ad", "emoji": "🥀"} | |
| return {"mood_color": "#ffffff", "emoji": "🌫️"} | |
| async def get_config(): | |
| return {"supabase_url": SUPABASE_URL, "supabase_key": SUPABASE_KEY} | |
| # --- WEBSOCKET (FIXED) --- | |
| class ConnectionManager: | |
| def __init__(self): self.active_connections: List[WebSocket] = [] | |
| async def connect(self, websocket: WebSocket): await websocket.accept(); self.active_connections.append(websocket) | |
| def disconnect(self, websocket: WebSocket): self.active_connections.remove(websocket) | |
| async def broadcast(self, message: str, sender: WebSocket): | |
| for connection in self.active_connections: | |
| if connection != sender: | |
| try: await connection.send_text(message) | |
| except: pass | |
| manager = ConnectionManager() | |
| async def websocket_endpoint(websocket: WebSocket): | |
| await manager.connect(websocket) | |
| try: | |
| while True: | |
| data = await websocket.receive_text() | |
| await manager.broadcast(data, websocket) | |
| except WebSocketDisconnect: | |
| manager.disconnect(websocket) | |
| app.mount("/static", StaticFiles(directory="static"), name="static") | |
| async def read_index(): return FileResponse('static/index.html') |