from fastapi import FastAPI, HTTPException from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse from fastapi.staticfiles import StaticFiles import subprocess import os import json from pathlib import Path import asyncio import time from datetime import datetime import re app = FastAPI(title="Windows XP RDP") # Informações sobre o container Windows WINDOWS_CONTAINER_NAME = "windows-rdp" WINDOWS_IMAGE = "dockurr/windows:latest" def get_installation_progress(): """Tenta detectar o progresso da instalação do Windows""" progress = { "stage": "unknown", "percentage": 0, "message": "Aguardando inicialização..." } # Verificar se há arquivos de log do Windows storage_path = Path("/storage") if storage_path.exists(): # Verificar se há arquivo de disco (indica que está criando) disk_file = storage_path / "disk.qcow2" if disk_file.exists(): size_mb = disk_file.stat().st_size / (1024 * 1024) if size_mb < 100: progress = { "stage": "downloading", "percentage": min(int(size_mb / 10), 10), "message": f"Baixando ISO do Windows XP... ({size_mb:.1f} MB)" } elif size_mb < 2000: progress = { "stage": "creating_disk", "percentage": min(10 + int((size_mb - 100) / 20), 30), "message": f"Criando disco virtual... ({size_mb:.1f} MB)" } else: progress = { "stage": "installing", "percentage": min(30 + int((size_mb - 2000) / 100), 90), "message": f"Instalando Windows XP... ({size_mb:.1f} MB)" } # Verificar se a porta 8006 está respondendo (Windows iniciou) try: import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(1) result = sock.connect_ex(('localhost', 8006)) sock.close() if result == 0: progress = { "stage": "ready", "percentage": 100, "message": "Windows XP está pronto!" } except: pass return progress @app.get("/", response_class=HTMLResponse) async def root(): """Página inicial com logs em tempo real""" html_content = """ Windows XP RDP

🖥️ Windows XP RDP

Aguardando inicialização...
0%
Aguardando

📋 Informações de Conexão

Versão: Windows XP

Usuário RDP: Docker

Senha RDP: admin

Porta RDP: 3389

Web Viewer: Abrir Web Viewer

Status: Verificando...

📊 Logs de Instalação

[Aguardando logs...]

ℹ️ Informações

""" return html_content @app.get("/progress") async def get_progress(): """Retorna o progresso da instalação""" progress = get_installation_progress() return progress @app.get("/status") async def get_status(): """Verifica o status do Windows (rodando no mesmo container)""" try: import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(2) result = sock.connect_ex(('localhost', 8006)) sock.close() web_viewer_available = result == 0 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(2) result = sock.connect_ex(('localhost', 3389)) sock.close() rdp_available = result == 0 running = web_viewer_available or rdp_available return { "running": running, "web_viewer_available": web_viewer_available, "rdp_available": rdp_available, "mode": "direct" } except Exception as e: return { "running": True, "web_viewer_available": False, "rdp_available": False, "mode": "direct", "note": "Status não pôde ser verificado, mas o container está ativo" } @app.get("/logs-stream") async def get_logs_stream(): """Retorna logs do Windows em formato de texto""" logs = [] # Tentar ler logs do FastAPI try: fastapi_log = Path("/tmp/fastapi.log") if fastapi_log.exists(): with open(fastapi_log, 'r', encoding='utf-8', errors='ignore') as f: lines = f.readlines() logs.extend(lines[-50:]) # Últimas 50 linhas except: pass # Tentar ler logs do sistema try: # Verificar processos relacionados ao Windows/QEMU result = subprocess.run( ["ps", "aux"], capture_output=True, text=True, timeout=2 ) if "qemu" in result.stdout.lower() or "windows" in result.stdout.lower(): logs.append("Windows/QEMU está rodando\n") except: pass # Adicionar informações de progresso progress = get_installation_progress() logs.append(f"Status: {progress['message']} ({progress['percentage']}%)\n") if not logs: logs.append("Aguardando logs do Windows...\n") return "".join(logs) @app.get("/web-viewer") async def web_viewer(): """Redireciona para o web viewer do Windows""" import socket try: hostname = socket.gethostname() except: hostname = "localhost" return HTMLResponse(f""" Windows XP Web Viewer """) @app.get("/info") async def get_info(): """Retorna informações sobre o ambiente""" import socket try: hostname = socket.gethostname() except: hostname = "localhost" status = await get_status() progress = get_installation_progress() hf_space_host = os.environ.get("SPACE_HOST", None) return { "hostname": hostname, "hf_space_host": hf_space_host, "status": status, "progress": progress, "mode": "direct", "version": "Windows XP", "rdp_info": { "username": "Docker", "password": "admin", "port": 3389, "host": "localhost" }, "web_viewer": { "url": "http://localhost:8006", "note": "No HuggingFace Spaces, use o hostname do Space se localhost não funcionar" } } if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)