From cb729809a965203a118ffdedb39db66025a22d0e Mon Sep 17 00:00:00 2001 From: admtracksteel Date: Tue, 24 Mar 2026 00:02:56 +0000 Subject: [PATCH] Refactor: fix async errors, CRLF line endings and bot tokens. --- audio_handler.py | 84 +++++++++++++++++++++---------------------- config.py | 56 ++++++++++++++--------------- credential_manager.py | 1 - main.py | 11 +++--- start.sh | 26 +++++++------- update.sh | 30 ++++++++-------- 6 files changed, 103 insertions(+), 105 deletions(-) diff --git a/audio_handler.py b/audio_handler.py index 32cc515..525a187 100644 --- a/audio_handler.py +++ b/audio_handler.py @@ -1,42 +1,42 @@ -import os -import speech_recognition as sr -from pydub import AudioSegment -from gtts import gTTS -import uuid -import re - -def transcribe_audio(file_path: str) -> str: - """Converte áudio (qualquer formato compatível com pydub) para WAV e transcreve com Google Speech.""" - recognizer = sr.Recognizer() - - # Se não for wav, converte usando pydub (precisa de ffmpeg na VPS) - temp_wav = f"/tmp/{uuid.uuid4()}.wav" - try: - audio = AudioSegment.from_file(file_path) - audio.export(temp_wav, format="wav") - - with sr.AudioFile(temp_wav) as source: - audio_data = recognizer.record(source) - text = recognizer.recognize_google(audio_data, language="pt-BR") - return text - finally: - if os.path.exists(temp_wav): - os.remove(temp_wav) - -def text_to_speech(text: str) -> str: - """Sintetiza texto em áudio MP3, removendo tags visuais e emojis.""" - # Limpeza para narração - texto_limpo = text.replace("🤖", "").replace("🧑‍🏫", "").replace("*", "").replace("`", "") - # Remove o bloco se houver, pois ele é para leitura visual apenas - texto_limpo = re.sub(r'.*?', '', texto_limpo, flags=re.DOTALL).strip() - - # Se sobrar texto vazio após limpar o refinado (raro), fala algo genérico - if not texto_limpo: - texto_limpo = "Relatório processado. Os detalhes estão no painel visual." - - filename = f"audio_reply_{uuid.uuid4().hex[:8]}.mp3" - filepath = os.path.join("/tmp", filename) - - tts = gTTS(text=texto_limpo, lang='pt-br', tld='com.br', slow=False) - tts.save(filepath) - return filename +import os +import speech_recognition as sr +from pydub import AudioSegment +from gtts import gTTS +import uuid +import re + +def transcribe_audio(file_path: str) -> str: + """Converte áudio (qualquer formato compatível com pydub) para WAV e transcreve com Google Speech.""" + recognizer = sr.Recognizer() + + # Se não for wav, converte usando pydub (precisa de ffmpeg na VPS) + temp_wav = f"/tmp/{uuid.uuid4()}.wav" + try: + audio = AudioSegment.from_file(file_path) + audio.export(temp_wav, format="wav") + + with sr.AudioFile(temp_wav) as source: + audio_data = recognizer.record(source) + text = recognizer.recognize_google(audio_data, language="pt-BR") + return text + finally: + if os.path.exists(temp_wav): + os.remove(temp_wav) + +def text_to_speech(text: str) -> str: + """Sintetiza texto em áudio MP3, removendo tags visuais e emojis.""" + # Limpeza para narração + texto_limpo = text.replace("🤖", "").replace("🧑‍🏫", "").replace("*", "").replace("`", "") + # Remove o bloco se houver, pois ele é para leitura visual apenas + texto_limpo = re.sub(r'.*?', '', texto_limpo, flags=re.DOTALL).strip() + + # Se sobrar texto vazio após limpar o refinado (raro), fala algo genérico + if not texto_limpo: + texto_limpo = "Relatório processado. Os detalhes estão no painel visual." + + filename = f"audio_reply_{uuid.uuid4().hex[:8]}.mp3" + filepath = os.path.join("/tmp", filename) + + tts = gTTS(text=texto_limpo, lang='pt-br', tld='com.br', slow=False) + tts.save(filepath) + return filename diff --git a/config.py b/config.py index 62b6e40..0879261 100644 --- a/config.py +++ b/config.py @@ -1,28 +1,28 @@ -import json -import os - -CONFIG_FILE = "/app/data/config.json" - -def get_config(): - if not os.path.exists("/app/data"): - os.makedirs("/app/data", exist_ok=True) - - if os.path.exists(CONFIG_FILE): - try: - with open(CONFIG_FILE, "r") as f: - return json.load(f) - except Exception: - pass - - # Configuração Padrão - return { - "active_provider": "gemini", - "gemini_api_key": "", - "web_password": "@@Gi05Br;;" - } - -def save_config(cfg): - if not os.path.exists("/app/data"): - os.makedirs("/app/data", exist_ok=True) - with open(CONFIG_FILE, "w") as f: - json.dump(cfg, f, indent=4) +import json +import os + +CONFIG_FILE = "/app/data/config.json" + +def get_config(): + if not os.path.exists("/app/data"): + os.makedirs("/app/data", exist_ok=True) + + if os.path.exists(CONFIG_FILE): + try: + with open(CONFIG_FILE, "r") as f: + return json.load(f) + except Exception: + pass + + # Configuração Padrão + return { + "active_provider": "gemini", + "gemini_api_key": "", + "web_password": "@@Gi05Br;;" + } + +def save_config(cfg): + if not os.path.exists("/app/data"): + os.makedirs("/app/data", exist_ok=True) + with open(CONFIG_FILE, "w") as f: + json.dump(cfg, f, indent=4) diff --git a/credential_manager.py b/credential_manager.py index 30af015..af8dfcf 100644 --- a/credential_manager.py +++ b/credential_manager.py @@ -148,4 +148,3 @@ def gitea_api_url(): return GITEA_API_URL def supabase_url(): return "https://supabase.reifonas.cloud" def supabase_anon_key(): return get_segredo("supabase", "ANON_KEY") def supabase_service_role_key(): return get_segredo("supabase", "SERVICE_ROLE_KEY") -print(f" Coolify API: {coolify_api_base()}") diff --git a/main.py b/main.py index e2b6d0b..ac0b851 100644 --- a/main.py +++ b/main.py @@ -5,14 +5,14 @@ import time import json import asyncio from fastapi import FastAPI, Request, Header, Depends, HTTPException, status -from fastapi.responses import HTMLResponse, JSONResponse +from fastapi.responses import HTMLResponse, JSONResponse, FileResponse from fastapi.templating import Jinja2Templates from dotenv import load_dotenv from starlette.concurrency import run_in_threadpool from ai_agent import query_agent from config import get_config, save_config -from credential_manager import sync_credentials, sync_from_gitea_repo +from credential_manager import fetch_from_gitea_repo_async from orchestrator import ( orchestrate_async, handle_message_async, get_orchestrator_status, get_llm_config, set_llm_config, format_confirmation_message, @@ -30,8 +30,7 @@ templates = Jinja2Templates(directory="templates") @app.on_event("startup") async def startup_event(): print("[INIT] Sincronizando credenciais...") - sync_from_gitea_repo() - sync_credentials() + await fetch_from_gitea_repo_async(force=True) # --- SEGURANÇA --- async def verify_password(x_web_password: str = Header(None)): @@ -41,9 +40,9 @@ async def verify_password(x_web_password: str = Header(None)): return True # --- WEB UI --- -@app.get("/", response_class=HTMLResponse) +@app.get("/", response_class=FileResponse) async def read_root(request: Request): - return templates.TemplateResponse("index.html", {"request": request}) + return FileResponse("templates/index.html") @app.get("/api/status") async def get_system_status(is_auth: bool = Depends(verify_password)): diff --git a/start.sh b/start.sh index c237cac..4625dd4 100755 --- a/start.sh +++ b/start.sh @@ -1,13 +1,13 @@ -#!/bin/bash -# Tenta limpar processos conflitantes no host se tiver acesso privilégido -if [ -d "/host_root" ]; then - echo "Limpando processos conflitantes no HOST..." - chroot /host_root /bin/bash -c "pkill -f telegram_bot.js" || true - chroot /host_root /bin/bash -c "pkill -f bot_logic.py" || true -fi - -# Inicia o serviço web -uvicorn main:app --host 0.0.0.0 --port 8000 & - -# Inicia o Polling do Bot -python bot_logic.py +#!/bin/bash +# Tenta limpar processos conflitantes no host se tiver acesso privilégido +if [ -d "/host_root" ]; then + echo "Limpando processos conflitantes no HOST..." + chroot /host_root /bin/bash -c "pkill -f telegram_bot.js" || true + chroot /host_root /bin/bash -c "pkill -f bot_logic.py" || true +fi + +# Inicia o serviço web +uvicorn main:app --host 0.0.0.0 --port 8000 & + +# Inicia o Polling do Bot +python bot_logic.py diff --git a/update.sh b/update.sh index 4a717ad..2d45b43 100755 --- a/update.sh +++ b/update.sh @@ -1,15 +1,15 @@ -#!/bin/bash -# Script de deploy e sincronização automática -echo "🚀 Iniciando deploy e push para o Gitea..." - -# 1. Build do Docker -echo "📦 Reconstruindo container..." -docker compose down && docker compose build && docker compose up -d - -# 2. Sincronização com Git (Gitea) -echo "git Pushing para o Gitea..." -git add . -git commit -m "🔒 Implementação de segurança: Login Web fixo e proteção de API" -git push origin master - -echo "✅ Sucesso! Agente atualizado e código no Gitea." +#!/bin/bash +# Script de deploy e sincronização automática +echo "🚀 Iniciando deploy e push para o Gitea..." + +# 1. Build do Docker +echo "📦 Reconstruindo container..." +docker compose down && docker compose build && docker compose up -d + +# 2. Sincronização com Git (Gitea) +echo "git Pushing para o Gitea..." +git add . +git commit -m "🔒 Implementação de segurança: Login Web fixo e proteção de API" +git push origin master + +echo "✅ Sucesso! Agente atualizado e código no Gitea."