Spaces:
Running
Running
Tu Nombre commited on
Commit Β·
1f289ea
1
Parent(s): 50ed991
editor config desde mi-cuenta
Browse files
main.py
CHANGED
|
@@ -137,6 +137,18 @@ cargar_clientes()
|
|
| 137 |
# ββββββββββββββββββββββββββββββββββββββββββ
|
| 138 |
# CREAR SPACE EN HUGGING FACE
|
| 139 |
# ββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
async def crear_space(nicho: str, email: str, tipo: str = "largo", config_parsed: dict = None, archivos_subidos: list = None) -> str:
|
| 141 |
space_id = f"tb-{re.sub(r'[^a-z0-9]','', nicho.lower()[:12])}-{int(time.time())%9999}"
|
| 142 |
cuentas = [
|
|
@@ -814,6 +826,61 @@ async def crear(request: Request):
|
|
| 814 |
return {"success": True, "url": u, "total": len(urls), "limite": limite}
|
| 815 |
|
| 816 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 817 |
@app.get("/mi-cuenta", response_class=HTMLResponse)
|
| 818 |
async def mi_cuenta(email: str = ""):
|
| 819 |
email = email.strip().lower()
|
|
@@ -832,7 +899,8 @@ async def mi_cuenta(email: str = ""):
|
|
| 832 |
yt_btn = '<div style="margin-top:10px;color:#4caf50;font-size:.9rem">YouTube conectado</div>'
|
| 833 |
else:
|
| 834 |
yt_btn = f'<a href="/oauth-youtube?email={email}&canal={i-1}" style="display:inline-block;background:#ff0000;color:#fff;padding:10px 16px;border-radius:6px;text-decoration:none;font-weight:700;margin-top:10px;font-size:.9rem">Conectar YouTube</a>'
|
| 835 |
-
|
|
|
|
| 836 |
if not lista_html:
|
| 837 |
lista_html = '<p style="color:#888;text-align:center;padding:20px">Aun no has creado ningun canal</p>'
|
| 838 |
boton_nuevo = ""
|
|
@@ -859,6 +927,20 @@ async def mi_cuenta(email: str = ""):
|
|
| 859 |
<h2 style="font-size:1.3rem;margin-top:30px;color:#fff">Mis canales</h2>
|
| 860 |
{lista_html}
|
| 861 |
<p style="text-align:center;color:#666;margin-top:40px;font-size:.85rem">WhatsApp soporte: +34 656 691 085</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 862 |
</body></html>""")
|
| 863 |
|
| 864 |
|
|
|
|
| 137 |
# ββββββββββββββββββββββββββββββββββββββββββ
|
| 138 |
# CREAR SPACE EN HUGGING FACE
|
| 139 |
# ββββββββββββββββββββββββββββββββββββββββββ
|
| 140 |
+
|
| 141 |
+
def token_de_repo(repo):
|
| 142 |
+
"""Del repo (ej Maria288/tb-xyz) saca el usuario y devuelve su token HF"""
|
| 143 |
+
usuario = repo.split("/")[0] if "/" in repo else ""
|
| 144 |
+
mapa = {
|
| 145 |
+
os.environ.get("HF_USER_5","Alejandro"): os.environ.get("HF_TOKEN_5",""),
|
| 146 |
+
os.environ.get("HF_USER_4","Maria288"): os.environ.get("HF_TOKEN_4",""),
|
| 147 |
+
os.environ.get("HF_USER_2","Cristobal2999"): os.environ.get("HF_TOKEN_2",""),
|
| 148 |
+
os.environ.get("HF_USER_3","Cristobal288"): os.environ.get("HF_TOKEN_3",""),
|
| 149 |
+
}
|
| 150 |
+
return mapa.get(usuario, "")
|
| 151 |
+
|
| 152 |
async def crear_space(nicho: str, email: str, tipo: str = "largo", config_parsed: dict = None, archivos_subidos: list = None) -> str:
|
| 153 |
space_id = f"tb-{re.sub(r'[^a-z0-9]','', nicho.lower()[:12])}-{int(time.time())%9999}"
|
| 154 |
cuentas = [
|
|
|
|
| 826 |
return {"success": True, "url": u, "total": len(urls), "limite": limite}
|
| 827 |
|
| 828 |
|
| 829 |
+
|
| 830 |
+
@app.post("/editar-config")
|
| 831 |
+
async def editar_config(request: Request):
|
| 832 |
+
data = await request.json()
|
| 833 |
+
email = data.get("email","").strip().lower()
|
| 834 |
+
canal_idx = data.get("canal_idx", -1)
|
| 835 |
+
nuevo_texto = data.get("config_texto","").strip()
|
| 836 |
+
|
| 837 |
+
if email not in CLIENTES:
|
| 838 |
+
return JSONResponse({"error":"Cuenta no encontrada"}, status_code=404)
|
| 839 |
+
canales = CLIENTES[email].get("canales", [])
|
| 840 |
+
if canal_idx < 0 or canal_idx >= len(canales):
|
| 841 |
+
return JSONResponse({"error":"Canal no encontrado"}, status_code=404)
|
| 842 |
+
|
| 843 |
+
canal = canales[canal_idx]
|
| 844 |
+
repo = canal.get("repo","")
|
| 845 |
+
nicho = canal.get("nicho","tecnologia")
|
| 846 |
+
tipo = canal.get("tipo","largo")
|
| 847 |
+
token_hf = token_de_repo(repo)
|
| 848 |
+
if not token_hf:
|
| 849 |
+
return JSONResponse({"error":"No se pudo acceder al canal"}, status_code=500)
|
| 850 |
+
|
| 851 |
+
# Re-parsear la nueva config con Groq
|
| 852 |
+
config_parsed = await parsear_config_groq(nuevo_texto)
|
| 853 |
+
if not isinstance(config_parsed, dict):
|
| 854 |
+
config_parsed = {}
|
| 855 |
+
# Conservar el proyecto google asignado
|
| 856 |
+
if "proyecto_idx" in canal.get("config", {}):
|
| 857 |
+
config_parsed["proyecto_idx"] = canal["config"]["proyecto_idx"]
|
| 858 |
+
|
| 859 |
+
# Regenerar el main.py del canal con la nueva config
|
| 860 |
+
import base64, json as _json
|
| 861 |
+
def b64(s): return base64.b64encode(s.encode("utf-8")).decode("utf-8")
|
| 862 |
+
with open("cliente_template.py","r") as _f:
|
| 863 |
+
main_code = _f.read().replace("NICHO_PLACEHOLDER", nicho).replace("EMAIL_PLACEHOLDER", email).replace("REPO_PLACEHOLDER", repo).replace("GROQ_PLACEHOLDER", os.environ.get("GROQ_KEY","")).replace("GROQ_PLACEHOLDER_2", os.environ.get("GROQ_KEY_2","")).replace("GROQ_PLACEHOLDER_3", os.environ.get("GROQ_KEY_3","")).replace("PEXELS_PLACEHOLDER", os.environ.get("PEXELS_KEY","")).replace("TIPO_PLACEHOLDER", tipo).replace("CONFIG_PLACEHOLDER", _json.dumps(config_parsed))
|
| 864 |
+
|
| 865 |
+
commit_payload = {
|
| 866 |
+
"summary": "Editar config",
|
| 867 |
+
"files": [{"path":"main.py","content":b64(main_code),"encoding":"base64"}]
|
| 868 |
+
}
|
| 869 |
+
async with httpx.AsyncClient(timeout=30) as client:
|
| 870 |
+
r = await client.post(
|
| 871 |
+
f"https://huggingface.co/api/spaces/{repo}/commit/main",
|
| 872 |
+
headers={"Authorization": f"Bearer {token_hf}", "Content-Type":"application/json"},
|
| 873 |
+
content=_json.dumps(commit_payload).encode()
|
| 874 |
+
)
|
| 875 |
+
if r.status_code not in [200,201]:
|
| 876 |
+
return JSONResponse({"error":"No se pudo aplicar"}, status_code=500)
|
| 877 |
+
|
| 878 |
+
# Guardar la nueva config en CLIENTES
|
| 879 |
+
CLIENTES[email]["canales"][canal_idx]["config"] = config_parsed
|
| 880 |
+
CLIENTES[email]["canales"][canal_idx]["config_texto"] = nuevo_texto
|
| 881 |
+
guardar_clientes()
|
| 882 |
+
return {"success": True}
|
| 883 |
+
|
| 884 |
@app.get("/mi-cuenta", response_class=HTMLResponse)
|
| 885 |
async def mi_cuenta(email: str = ""):
|
| 886 |
email = email.strip().lower()
|
|
|
|
| 899 |
yt_btn = '<div style="margin-top:10px;color:#4caf50;font-size:.9rem">YouTube conectado</div>'
|
| 900 |
else:
|
| 901 |
yt_btn = f'<a href="/oauth-youtube?email={email}&canal={i-1}" style="display:inline-block;background:#ff0000;color:#fff;padding:10px 16px;border-radius:6px;text-decoration:none;font-weight:700;margin-top:10px;font-size:.9rem">Conectar YouTube</a>'
|
| 902 |
+
cfg_texto = ch.get("config_texto","").replace('"','"').replace("\n"," ")
|
| 903 |
+
lista_html += f'''<div style="background:#111;border:1px solid #222;border-radius:10px;padding:18px;margin:10px 0"><div style="color:#D4AF37;font-weight:700;margin-bottom:8px">Canal {i}: {ch.get("nicho","-")}</div><a href="{ch_url}" target="_blank" style="color:#ff2d2d;word-break:break-all;font-size:.9rem">{ch_url}</a>{yt_btn}<div style="margin-top:10px"><button onclick="toggleEdit({i-1})" style="background:#222;color:#fff;border:1px solid #444;padding:8px 14px;border-radius:6px;font-size:.85rem;cursor:pointer">βοΈ Editar config</button></div><div id="edit{i-1}" style="display:none;margin-top:12px"><textarea id="cfg{i-1}" style="width:100%;background:#0a0a0a;color:#fff;border:1px solid #333;border-radius:8px;padding:10px;font-size:.9rem;min-height:80px" placeholder="Ej: voz femenina de Mexico, tono motivador, frase inicio Hola amigos">{cfg_texto}</textarea><button onclick="guardarCfg({i-1})" style="background:#4caf50;color:#fff;border:none;padding:10px 16px;border-radius:6px;font-weight:700;margin-top:8px;cursor:pointer">Guardar cambios</button><span id="msg{i-1}" style="margin-left:10px;font-size:.85rem"></span></div></div>'''
|
| 904 |
if not lista_html:
|
| 905 |
lista_html = '<p style="color:#888;text-align:center;padding:20px">Aun no has creado ningun canal</p>'
|
| 906 |
boton_nuevo = ""
|
|
|
|
| 927 |
<h2 style="font-size:1.3rem;margin-top:30px;color:#fff">Mis canales</h2>
|
| 928 |
{lista_html}
|
| 929 |
<p style="text-align:center;color:#666;margin-top:40px;font-size:.85rem">WhatsApp soporte: +34 656 691 085</p>
|
| 930 |
+
<script>
|
| 931 |
+
function toggleEdit(i){{var e=document.getElementById("edit"+i);e.style.display=e.style.display==="none"?"block":"none";}}
|
| 932 |
+
async function guardarCfg(i){{
|
| 933 |
+
var txt=document.getElementById("cfg"+i).value;
|
| 934 |
+
var msg=document.getElementById("msg"+i);
|
| 935 |
+
msg.textContent="Guardando...";msg.style.color="#D4AF37";
|
| 936 |
+
try{{
|
| 937 |
+
var r=await fetch("/editar-config",{{method:"POST",headers:{{"Content-Type":"application/json"}},body:JSON.stringify({{email:"{email}",canal_idx:i,config_texto:txt}})}});
|
| 938 |
+
var d=await r.json();
|
| 939 |
+
if(d.success){{msg.textContent="β
Guardado. Se aplica en los proximos videos";msg.style.color="#4caf50";}}
|
| 940 |
+
else{{msg.textContent="β "+(d.error||"Error");msg.style.color="#ff2d2d";}}
|
| 941 |
+
}}catch(e){{msg.textContent="β Error de conexion";msg.style.color="#ff2d2d";}}
|
| 942 |
+
}}
|
| 943 |
+
</script>
|
| 944 |
</body></html>""")
|
| 945 |
|
| 946 |
|