File size: 3,661 Bytes
db370a0
c95b94f
db370a0
c95b94f
 
 
 
 
 
 
 
 
 
db370a0
c95b94f
 
 
db370a0
 
c95b94f
 
 
 
 
 
 
db370a0
 
 
 
c95b94f
 
 
db370a0
c95b94f
 
db370a0
 
c95b94f
db370a0
 
c95b94f
db370a0
c95b94f
 
 
 
 
 
db370a0
 
 
 
 
 
c95b94f
db370a0
c95b94f
 
 
db370a0
 
 
 
 
c95b94f
 
 
db370a0
c95b94f
db370a0
c95b94f
 
 
 
 
 
db370a0
 
 
c95b94f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d04c0a3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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 ---
@app.post("/api/admin/create_user")
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"
    }

@app.post("/api/user/update_profile")
async def update_profile(data: UpdateProfileModel):
    # Здесь просто возвращаем статус, реальная запись идет через Supabase Client на фронте
    # или можно расширить этот метод для серверной записи.
    return {"status": "ok", "looking_for_friends": data.is_looking}

# --- CHAT & MOOD ---
@app.post("/api/analyze_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": "🌫️"}

@app.get("/api/config")
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()

@app.websocket("/ws/signal")
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")
@app.get("/")
async def read_index(): return FileResponse('static/index.html')