Tu Nombre commited on
Commit
da68fbf
·
1 Parent(s): 898104f

rotacion automatica proyectos google

Browse files
Files changed (2) hide show
  1. cliente_template.py +11 -5
  2. main.py +55 -8
cliente_template.py CHANGED
@@ -39,7 +39,6 @@ except Exception as e:
39
  GROQ_KEY = "GROQ_PLACEHOLDER"
40
  TIPO_VIDEO = "TIPO_PLACEHOLDER"
41
  PEXELS_KEY = "PEXELS_PLACEHOLDER"
42
- os.makedirs("media_cliente", exist_ok=True)
43
  LOGS = []
44
  STATUS = "Iniciando..."
45
 
@@ -93,10 +92,9 @@ async def pipeline():
93
  fondos = []
94
  # Revisar si hay media propia del cliente
95
  archivos_propios = []
96
- if os.path.exists("media_cliente"):
97
- for f in sorted(os.listdir("media_cliente")):
98
- if f.lower().endswith((".mp4", ".mov", ".jpg", ".jpeg", ".png", ".webp")):
99
- archivos_propios.append(f"media_cliente/{f}")
100
  if archivos_propios:
101
  random.shuffle(archivos_propios)
102
  fondos = archivos_propios[:6]
@@ -184,6 +182,14 @@ async def pipeline():
184
  while resp is None:
185
  _, resp = req_yt.next_chunk()
186
  log(f"Subido: {titulo[:40]}")
 
 
 
 
 
 
 
 
187
  except FileNotFoundError:
188
  log("Sin token.json, saltando subida")
189
  except Exception as ey:
 
39
  GROQ_KEY = "GROQ_PLACEHOLDER"
40
  TIPO_VIDEO = "TIPO_PLACEHOLDER"
41
  PEXELS_KEY = "PEXELS_PLACEHOLDER"
 
42
  LOGS = []
43
  STATUS = "Iniciando..."
44
 
 
92
  fondos = []
93
  # Revisar si hay media propia del cliente
94
  archivos_propios = []
95
+ for f in sorted(os.listdir(".")):
96
+ if f.startswith("media_") and f.lower().endswith((".mp4", ".mov", ".jpg", ".jpeg", ".png", ".webp")):
97
+ archivos_propios.append(f)
 
98
  if archivos_propios:
99
  random.shuffle(archivos_propios)
100
  fondos = archivos_propios[:6]
 
182
  while resp is None:
183
  _, resp = req_yt.next_chunk()
184
  log(f"Subido: {titulo[:40]}")
185
+ # Reportar uso al IAweb
186
+ try:
187
+ proyecto_idx = CONFIG.get("proyecto_idx", -1)
188
+ if proyecto_idx >= 0:
189
+ requests.post("https://cristobal299-iaweb.hf.space/reportar-uso",
190
+ json={"proyecto_idx": proyecto_idx}, timeout=10)
191
+ except Exception as eu:
192
+ log(f"No se pudo reportar uso: {eu}")
193
  except FileNotFoundError:
194
  log("Sin token.json, saltando subida")
195
  except Exception as ey:
main.py CHANGED
@@ -191,7 +191,7 @@ CMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"7860\"]""
191
  if not contenido_b64: continue
192
  binario = base64.b64decode(contenido_b64)
193
  r_up = await client.put(
194
- f"https://huggingface.co/api/repos/{repo_name}/upload/main/media_cliente/{nombre}",
195
  headers={"Authorization": f"Bearer {token_actual}", "Content-Type": "application/octet-stream"},
196
  content=binario
197
  )
@@ -708,6 +708,11 @@ async def crear(request: Request):
708
  return JSONResponse({"error": f"Has alcanzado el limite de tu plan {plan} ({limite} canales)"}, status_code=400)
709
  # Parsear preferencias del cliente con Groq ANTES de crear
710
  config_parsed = await parsear_config_groq(config_libre)
 
 
 
 
 
711
  # Crear el canal pasando la config
712
  resultado = await crear_space(nicho, email, tipo, config_parsed, archivos_subidos)
713
  if not resultado:
@@ -966,19 +971,37 @@ GOOGLE_PROYECTOS = [
966
  ]
967
  GOOGLE_PROYECTOS = [(c,s) for c,s in GOOGLE_PROYECTOS if c and s]
968
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
969
  def get_proyecto_cliente(email):
970
  """Devuelve el proyecto Google asignado al cliente, o asigna uno nuevo"""
971
  if email in CLIENTES and "google_index" in CLIENTES[email]:
972
  idx = CLIENTES[email]["google_index"]
973
  if idx < len(GOOGLE_PROYECTOS):
974
  return GOOGLE_PROYECTOS[idx], idx
975
- # Asignar el de menos uso
976
- contador = [0] * len(GOOGLE_PROYECTOS)
977
- for c in CLIENTES.values():
978
- gi = c.get("google_index", -1)
979
- if 0 <= gi < len(GOOGLE_PROYECTOS):
980
- contador[gi] += 1
981
- idx = contador.index(min(contador))
982
  return GOOGLE_PROYECTOS[idx], idx
983
 
984
  # Default para arranque (se sobrescribe por cliente)
@@ -1087,3 +1110,27 @@ async def oauth_callback(code: str, state: str):
1087
  </body></html>
1088
  """)
1089
  # restart
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  if not contenido_b64: continue
192
  binario = base64.b64decode(contenido_b64)
193
  r_up = await client.put(
194
+ f"https://huggingface.co/api/repos/{repo_name}/upload/main/media_{nombre}",
195
  headers={"Authorization": f"Bearer {token_actual}", "Content-Type": "application/octet-stream"},
196
  content=binario
197
  )
 
708
  return JSONResponse({"error": f"Has alcanzado el limite de tu plan {plan} ({limite} canales)"}, status_code=400)
709
  # Parsear preferencias del cliente con Groq ANTES de crear
710
  config_parsed = await parsear_config_groq(config_libre)
711
+ # Asignar proyecto disponible y guardarlo en config
712
+ if not isinstance(config_parsed, dict):
713
+ config_parsed = {}
714
+ idx_disponible = proyecto_disponible()
715
+ config_parsed["proyecto_idx"] = idx_disponible
716
  # Crear el canal pasando la config
717
  resultado = await crear_space(nicho, email, tipo, config_parsed, archivos_subidos)
718
  if not resultado:
 
971
  ]
972
  GOOGLE_PROYECTOS = [(c,s) for c,s in GOOGLE_PROYECTOS if c and s]
973
 
974
+ import datetime as _dt
975
+ USOS_PROYECTO = {} # {idx: {"fecha": "2026-05-27", "count": 5}}
976
+
977
+ def reset_si_nuevo_dia(idx):
978
+ hoy = _dt.date.today().isoformat()
979
+ if idx not in USOS_PROYECTO or USOS_PROYECTO[idx].get("fecha") != hoy:
980
+ USOS_PROYECTO[idx] = {"fecha": hoy, "count": 0}
981
+
982
+ def incrementar_uso(idx):
983
+ reset_si_nuevo_dia(idx)
984
+ USOS_PROYECTO[idx]["count"] += 1
985
+
986
+ def proyecto_disponible():
987
+ """Devuelve indice del proyecto con menos usos hoy (max 5 videos/dia)"""
988
+ if not GOOGLE_PROYECTOS:
989
+ return 0
990
+ contadores = []
991
+ for i in range(len(GOOGLE_PROYECTOS)):
992
+ reset_si_nuevo_dia(i)
993
+ contadores.append((USOS_PROYECTO[i]["count"], i))
994
+ contadores.sort()
995
+ return contadores[0][1] # el indice con menos usos
996
+
997
  def get_proyecto_cliente(email):
998
  """Devuelve el proyecto Google asignado al cliente, o asigna uno nuevo"""
999
  if email in CLIENTES and "google_index" in CLIENTES[email]:
1000
  idx = CLIENTES[email]["google_index"]
1001
  if idx < len(GOOGLE_PROYECTOS):
1002
  return GOOGLE_PROYECTOS[idx], idx
1003
+ # Asignar el proyecto con menos USOS hoy (mejor reparto de cuota)
1004
+ idx = proyecto_disponible()
 
 
 
 
 
1005
  return GOOGLE_PROYECTOS[idx], idx
1006
 
1007
  # Default para arranque (se sobrescribe por cliente)
 
1110
  </body></html>
1111
  """)
1112
  # restart
1113
+
1114
+
1115
+ @app.post("/reportar-uso")
1116
+ async def reportar_uso(request: Request):
1117
+ """Endpoint que cada cliente Space llama cuando sube un video"""
1118
+ try:
1119
+ data = await request.json()
1120
+ idx = data.get("proyecto_idx", -1)
1121
+ if 0 <= idx < len(GOOGLE_PROYECTOS):
1122
+ incrementar_uso(idx)
1123
+ return {"ok": True, "usos_hoy": USOS_PROYECTO[idx]["count"]}
1124
+ except Exception as e:
1125
+ print(f"Error reportar uso: {e}", flush=True)
1126
+ return {"ok": False}
1127
+
1128
+
1129
+ @app.get("/estado-proyectos")
1130
+ async def estado_proyectos():
1131
+ """Ver estado de los proyectos Google"""
1132
+ estado = []
1133
+ for i in range(len(GOOGLE_PROYECTOS)):
1134
+ reset_si_nuevo_dia(i)
1135
+ estado.append({"proyecto": i+1, "usos_hoy": USOS_PROYECTO[i]["count"]})
1136
+ return estado