import json
import uuid
import os
import subprocess
import threading
import time
import socket
import hashlib
from pathlib import Path
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse, JSONResponse
import uvicorn
# ========== КОНФИГ ==========
PORT = int(os.getenv("PORT", 7860))
DATA_DIR = Path("/data")
DATA_DIR.mkdir(exist_ok=True)
USERS_FILE = DATA_DIR / "users.json"
FRIENDS_FILE = DATA_DIR / "friends.json"
for f in [USERS_FILE, FRIENDS_FILE]:
if not f.exists():
with open(f, "w") as fp:
json.dump({}, fp)
# ========== РАБОТА С ДАННЫМИ ==========
def load_json(file):
with open(file, "r") as f:
return json.load(f)
def save_json(file, data):
with open(file, "w") as f:
json.dump(data, f, indent=2)
# ========== СЛОВА ДЛЯ КОДОВ ==========
WORDS = [
"солнце", "луна", "звезда", "небо", "море", "ветер", "дождь", "снег",
"гора", "река", "лес", "поле", "цветок", "трава", "дерево", "птица",
"рыба", "волк", "лиса", "медведь", "заяц", "ёжик", "белка", "сова",
"орёл", "сокол", "дельфин", "кит", "тигр", "лев", "пантера", "гепард",
"радуга", "молния", "гром", "туча", "роса", "иней", "туман", "буря",
"мир", "друг", "свет", "тепло", "радость", "счастье", "любовь", "надежда"
]
def generate_word_code():
import random
word1 = random.choice(WORDS)
word2 = random.choice(WORDS)
word3 = str(random.randint(10, 99))
return f"{word1}-{word2}-{word3}".upper()
# ========== ЗАПУСК PEERJS ==========
def start_peerjs():
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(('127.0.0.1', 9000))
sock.close()
if result != 0:
print("🚀 Запускаем PeerJS Server...")
subprocess.Popen(
["peer", "--port", "9000", "--path", "/peerjs"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True
)
time.sleep(3)
print("✅ PeerJS Server запущен")
except Exception as e:
print(f"⚠️ Ошибка запуска PeerJS: {e}")
threading.Thread(target=start_peerjs, daemon=True).start()
# ========== FASTAPI ==========
app = FastAPI()
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
html = """
🔐 HF Message
🔐 HF Message
Код-слово = вход в аккаунт · ID = добавление в друзья
👤 Мой профиль
👥 0 пользователей
"""
return HTMLResponse(html)
# ========== API ==========
@app.post("/api/login")
async def login(data: dict):
try:
code = data.get("code", "").upper()
users = load_json(USERS_FILE)
if code in users:
# Вход в существующий аккаунт
return JSONResponse({
"success": True,
"name": users[code]["name"],
"peer_id": users[code]["peer_id"]
})
else:
# Создание нового аккаунта
peer_id = str(uuid.uuid4())
name = f"User_{len(users) + 1}"
users[code] = {
"name": name,
"peer_id": peer_id,
"created_at": time.time()
}
save_json(USERS_FILE, users)
return JSONResponse({
"success": True,
"name": name,
"peer_id": peer_id
})
except Exception as e:
return JSONResponse({"success": False, "error": str(e)})
@app.post("/api/generate_code")
async def generate_code():
try:
users = load_json(USERS_FILE)
code = generate_word_code()
# Проверяем уникальность
while code in users:
code = generate_word_code()
return JSONResponse({"success": True, "code": code})
except Exception as e:
return JSONResponse({"success": False, "error": str(e)})
@app.post("/api/add_friend")
async def add_friend(data: dict):
try:
peer_id = data.get("peer_id", "").strip()
name = data.get("name", "Друг")
if not peer_id:
return JSONResponse({"success": False, "error": "ID не указан"})
friends = load_json(FRIENDS_FILE)
if peer_id not in friends:
friends[peer_id] = {"name": name, "added_at": time.time()}
save_json(FRIENDS_FILE, friends)
return JSONResponse({"success": True})
except Exception as e:
return JSONResponse({"success": False, "error": str(e)})
@app.get("/api/friends")
async def get_friends():
friends = load_json(FRIENDS_FILE)
return JSONResponse({
"friends": [{"peer_id": k, "name": v.get("name", "Друг")} for k, v in friends.items()]
})
@app.get("/api/stats")
async def get_stats():
users = load_json(USERS_FILE)
return JSONResponse({"total_users": len(users)})
# ========== ЗАПУСК ==========
if __name__ == "__main__":
print("=" * 50)
print("🔐 HF Message - Безопасный P2P Чат")
print("=" * 50)
print(f"📁 Данные в: {DATA_DIR}")
print("🚀 Запуск...")
uvicorn.run(app, host="0.0.0.0", port=PORT, log_level="info")