Tu Nombre commited on
Commit
5d9ba74
Β·
1 Parent(s): c744cc3

upload imagenes/videos del cliente al crear canal

Browse files
Files changed (2) hide show
  1. cliente_template.py +25 -12
  2. main.py +41 -9
cliente_template.py CHANGED
@@ -39,6 +39,7 @@ except Exception as e:
39
  GROQ_KEY = "GROQ_PLACEHOLDER"
40
  TIPO_VIDEO = "TIPO_PLACEHOLDER"
41
  PEXELS_KEY = "PEXELS_PLACEHOLDER"
 
42
  LOGS = []
43
  STATUS = "Iniciando..."
44
 
@@ -88,19 +89,31 @@ async def pipeline():
88
  import subprocess
89
  subprocess.run(["ffmpeg","-y","-f","lavfi","-i","anullsrc=r=44100:cl=mono","-t","60","voz.mp3"], capture_output=True)
90
  log("Voz lista")
91
- STATUS = "Descargando fondo..."
92
- h = {"Authorization": PEXELS_KEY}
93
- r = requests.get(f"https://api.pexels.com/videos/search?query={NICHO}&per_page=15", headers=h)
94
- vids = r.json().get("videos", [])
95
  fondos = []
96
- if vids:
97
- random.shuffle(vids)
98
- for i, v in enumerate(vids[:6]):
99
- try:
100
- u = v["video_files"][0]["link"]
101
- with open(f"fondo{i}.mp4","wb") as f: f.write(requests.get(u, timeout=30).content)
102
- fondos.append(f"fondo{i}.mp4")
103
- except: pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  log(f"Fondos listos: {len(fondos)}")
105
  STATUS = "Renderizando video..."
106
  from moviepy.editor import AudioFileClip as AC, VideoFileClip as VC, concatenate_videoclips
 
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
 
 
89
  import subprocess
90
  subprocess.run(["ffmpeg","-y","-f","lavfi","-i","anullsrc=r=44100:cl=mono","-t","60","voz.mp3"], capture_output=True)
91
  log("Voz lista")
92
+ STATUS = "Preparando fondos..."
 
 
 
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]
103
+ log(f"Usando {len(fondos)} archivos del cliente")
104
+ else:
105
+ STATUS = "Descargando fondo..."
106
+ h = {"Authorization": PEXELS_KEY}
107
+ r = requests.get(f"https://api.pexels.com/videos/search?query={NICHO}&per_page=15", headers=h)
108
+ vids = r.json().get("videos", [])
109
+ if vids:
110
+ random.shuffle(vids)
111
+ for i, v in enumerate(vids[:6]):
112
+ try:
113
+ u = v["video_files"][0]["link"]
114
+ with open(f"fondo{i}.mp4","wb") as f: f.write(requests.get(u, timeout=30).content)
115
+ fondos.append(f"fondo{i}.mp4")
116
+ except: pass
117
  log(f"Fondos listos: {len(fondos)}")
118
  STATUS = "Renderizando video..."
119
  from moviepy.editor import AudioFileClip as AC, VideoFileClip as VC, concatenate_videoclips
main.py CHANGED
@@ -114,7 +114,7 @@ cargar_clientes()
114
  # ══════════════════════════════════════════
115
  # CREAR SPACE EN HUGGING FACE
116
  # ══════════════════════════════════════════
117
- async def crear_space(nicho: str, email: str, tipo: str = "largo", config_parsed: dict = None) -> str:
118
  space_id = f"tb-{re.sub(r'[^a-z0-9]','', nicho.lower()[:12])}-{int(time.time())%9999}"
119
  cuentas = [
120
  (os.environ.get("HF_TOKEN_5",""), os.environ.get("HF_USER_5","Alejandro")),
@@ -167,14 +167,22 @@ RUN pip install -r requirements.txt
167
  COPY main.py .
168
  EXPOSE 7860
169
  CMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"7860\"]"""
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  commit_payload = {
171
  "summary": "TubeBot init",
172
- "files": [
173
- {"path": "main.py", "content": b64(main_code), "encoding": "base64"},
174
- {"path": "requirements.txt", "content": b64(req), "encoding": "base64"},
175
- {"path": "README.md", "content": b64(readme), "encoding": "base64"},
176
- {"path": "Dockerfile", "content": b64(dockerfile), "encoding": "base64"}
177
- ]
178
  }
179
  r2 = await client.post(
180
  f"https://huggingface.co/api/spaces/{repo_name}/commit/main",
@@ -503,6 +511,9 @@ input:focus,select:focus{border-color:#ff2d2d;}
503
  </select>
504
  <label style="font-size:.85rem;color:#aaa;margin-top:12px;display:block">✨ ΒΏTienes alguna preferencia? <span style="color:#666">(opcional)</span></label>
505
  <textarea id="config${i}" rows="4" placeholder="Ej: voz femenina en ingles, subtitulos grandes arriba, tono motivacional, sin musica..." style="width:100%;padding:12px;background:#080808;color:#fff;border:1px solid #333;border-radius:8px;resize:vertical;font-family:system-ui;margin-top:6px"></textarea>
 
 
 
506
  `;
507
  container.appendChild(div);
508
  }
@@ -547,6 +558,26 @@ async function activar(){
547
  const conf = document.getElementById('config'+i);
548
  if(n && t) canales.push({nicho: n.value, tipo: t.value, config: conf ? conf.value : ""});
549
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  document.getElementById('btn').disabled = true;
551
  document.getElementById('loading').style.display = 'block';
552
  try{
@@ -556,7 +587,7 @@ async function activar(){
556
  method:'POST',
557
  signal: ctrl.signal,
558
  headers:{'Content-Type':'application/json'},
559
- body: JSON.stringify({email, canales, token: "TOKEN_PLACEHOLDER"})
560
  });
561
  const d = await r.json();
562
  if(d.url){
@@ -644,6 +675,7 @@ async def crear(request: Request):
644
  data = await request.json()
645
  email = data.get("email","").strip().lower()
646
  canales_data = data.get("canales", [])
 
647
  if canales_data:
648
  nicho = canales_data[0].get("nicho","tecnologia")
649
  tipo = canales_data[0].get("tipo","largo")
@@ -669,7 +701,7 @@ async def crear(request: Request):
669
  # Parsear preferencias del cliente con Groq ANTES de crear
670
  config_parsed = await parsear_config_groq(config_libre)
671
  # Crear el canal pasando la config
672
- resultado = await crear_space(nicho, email, tipo, config_parsed)
673
  if not resultado:
674
  return JSONResponse({"error": "No se pudo crear el canal"}, status_code=500)
675
  u = resultado["url"]
 
114
  # ══════════════════════════════════════════
115
  # CREAR SPACE EN HUGGING FACE
116
  # ══════════════════════════════════════════
117
+ async def crear_space(nicho: str, email: str, tipo: str = "largo", config_parsed: dict = None, archivos_subidos: list = None) -> str:
118
  space_id = f"tb-{re.sub(r'[^a-z0-9]','', nicho.lower()[:12])}-{int(time.time())%9999}"
119
  cuentas = [
120
  (os.environ.get("HF_TOKEN_5",""), os.environ.get("HF_USER_5","Alejandro")),
 
167
  COPY main.py .
168
  EXPOSE 7860
169
  CMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"7860\"]"""
170
+ files_lista = [
171
+ {"path": "main.py", "content": b64(main_code), "encoding": "base64"},
172
+ {"path": "requirements.txt", "content": b64(req), "encoding": "base64"},
173
+ {"path": "README.md", "content": b64(readme), "encoding": "base64"},
174
+ {"path": "Dockerfile", "content": b64(dockerfile), "encoding": "base64"}
175
+ ]
176
+ # AΓ±adir archivos del cliente si los subiΓ³
177
+ if archivos_subidos:
178
+ for i, arc in enumerate(archivos_subidos[:20]):
179
+ nombre = arc.get("nombre", f"media_{i}.jpg").replace("/","_").replace("\\","_")
180
+ contenido = arc.get("contenido", "")
181
+ if contenido:
182
+ files_lista.append({"path": f"media_cliente/{nombre}", "content": contenido, "encoding": "base64"})
183
  commit_payload = {
184
  "summary": "TubeBot init",
185
+ "files": files_lista
 
 
 
 
 
186
  }
187
  r2 = await client.post(
188
  f"https://huggingface.co/api/spaces/{repo_name}/commit/main",
 
511
  </select>
512
  <label style="font-size:.85rem;color:#aaa;margin-top:12px;display:block">✨ ΒΏTienes alguna preferencia? <span style="color:#666">(opcional)</span></label>
513
  <textarea id="config${i}" rows="4" placeholder="Ej: voz femenina en ingles, subtitulos grandes arriba, tono motivacional, sin musica..." style="width:100%;padding:12px;background:#080808;color:#fff;border:1px solid #333;border-radius:8px;resize:vertical;font-family:system-ui;margin-top:6px"></textarea>
514
+ <label style="font-size:.85rem;color:#aaa;margin-top:12px;display:block">πŸ“Έ Sube tus imagenes o videos <span style="color:#666">(opcional, max 20)</span></label>
515
+ <input type="file" id="media${i}" multiple accept="image/*,video/*" style="margin-top:6px;width:100%;padding:10px;background:#080808;color:#fff;border:1px solid #333;border-radius:8px"/>
516
+ <div id="mediainfo${i}" style="color:#888;font-size:.8rem;margin-top:4px"></div>
517
  `;
518
  container.appendChild(div);
519
  }
 
558
  const conf = document.getElementById('config'+i);
559
  if(n && t) canales.push({nicho: n.value, tipo: t.value, config: conf ? conf.value : ""});
560
  }
561
+
562
+ // Recoger archivos y convertir a base64
563
+ const archivos = [];
564
+ const fileInput = document.getElementById('media1');
565
+ if (fileInput && fileInput.files && fileInput.files.length > 0) {
566
+ document.getElementById('mediainfo1').textContent = "Procesando archivos...";
567
+ const files = Array.from(fileInput.files).slice(0, 20);
568
+ for (const f of files) {
569
+ try {
570
+ const b64 = await new Promise((resolve, reject) => {
571
+ const reader = new FileReader();
572
+ reader.onload = () => resolve(reader.result.split(',')[1]);
573
+ reader.onerror = reject;
574
+ reader.readAsDataURL(f);
575
+ });
576
+ archivos.push({nombre: f.name, contenido: b64});
577
+ } catch(e) { console.log("Error archivo", f.name, e); }
578
+ }
579
+ document.getElementById('mediainfo1').textContent = archivos.length + " archivos listos";
580
+ }
581
  document.getElementById('btn').disabled = true;
582
  document.getElementById('loading').style.display = 'block';
583
  try{
 
587
  method:'POST',
588
  signal: ctrl.signal,
589
  headers:{'Content-Type':'application/json'},
590
+ body: JSON.stringify({email, canales, archivos, token: "TOKEN_PLACEHOLDER"})
591
  });
592
  const d = await r.json();
593
  if(d.url){
 
675
  data = await request.json()
676
  email = data.get("email","").strip().lower()
677
  canales_data = data.get("canales", [])
678
+ archivos_subidos = data.get("archivos", [])
679
  if canales_data:
680
  nicho = canales_data[0].get("nicho","tecnologia")
681
  tipo = canales_data[0].get("tipo","largo")
 
701
  # Parsear preferencias del cliente con Groq ANTES de crear
702
  config_parsed = await parsear_config_groq(config_libre)
703
  # Crear el canal pasando la config
704
+ resultado = await crear_space(nicho, email, tipo, config_parsed, archivos_subidos)
705
  if not resultado:
706
  return JSONResponse({"error": "No se pudo crear el canal"}, status_code=500)
707
  u = resultado["url"]