06-sep: [videoclub] temporada completa, rangos bajar X-Y, pelis solo castellano
This commit is contained in:
@@ -51,7 +51,8 @@ CALIDAD_MALA = re.compile(
|
||||
r"(CAMRip|TS\.|HDTS|Telesync|KinoRip|Screener|HDCAM|HC\b|r5|360p|240p)",
|
||||
re.IGNORECASE)
|
||||
CASTELLANO = re.compile(
|
||||
r"(Esp|Castellano|Span|Spanish|dual|lat|\bES\b|audio)", re.IGNORECASE)
|
||||
r"(Esp[añ]ol|Castellano|Spanish|Latino|DualLat|\bdual\b|\bESS?\b|\bESP\b)",
|
||||
re.IGNORECASE)
|
||||
INGLES = re.compile(r"(Eng|English|Ingl[eé]s|\bEN\b)", re.IGNORECASE)
|
||||
OTRO_IDIOMA = re.compile(
|
||||
r"(Ita\b|MIRCrew|RO\s?EN|South Wind|Silver Zero|Francais|Deutsch|Portugu[eê]s)",
|
||||
@@ -193,7 +194,7 @@ def buscar_peliculas(termino, items=None):
|
||||
continue
|
||||
if not it["buena_calidad"]:
|
||||
continue
|
||||
if not (it.get("castellano") or bool(INGLES.search(it.get("name", "")))):
|
||||
if not it.get("castellano"):
|
||||
continue
|
||||
clean = (it.get("clean") or "").lower()
|
||||
name = (it.get("name") or "").lower()
|
||||
@@ -294,11 +295,13 @@ def formatear_series(grupos):
|
||||
etiqueta = f"S{temp:02d}E{cap:02d}"
|
||||
else:
|
||||
etiqueta = it["clean"]
|
||||
lineas.append(f" <b>{num_global}.</b> {etiqueta} — {resto}")
|
||||
idioma = " · cast." if it.get("castellano") else ""
|
||||
lineas.append(f" <b>{num_global}.</b> {etiqueta} — {resto}{idioma}")
|
||||
num_global += 1
|
||||
lineas.append("")
|
||||
|
||||
lineas.append("Responde <b>/torrents NUMERO</b> de episodio para ver opciones y descargar.")
|
||||
lineas.append("O <b>/temporada N</b> (temporada completa) o <b>/bajar X-Y</b> (rango).")
|
||||
return trocear_texto(lineas)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
@@ -800,8 +801,11 @@ def procesar(texto, chat_id):
|
||||
n = _int_arg(texto)
|
||||
procesar_torrents(n, chat_id)
|
||||
elif t.startswith("bajar ") or t.startswith("/bajar "):
|
||||
spec = texto.split(" ", 1)[1].strip() if " " in texto else ""
|
||||
procesar_bajar(spec, chat_id)
|
||||
elif t.startswith("temporada ") or t.startswith("/temporada "):
|
||||
n = _int_arg(texto)
|
||||
procesar_bajar(n, chat_id)
|
||||
procesar_temporada(n, chat_id)
|
||||
elif comando == "aspiradora":
|
||||
procesar_aspiradora(argumento, chat_id)
|
||||
elif comando in ("menu", "menú", "inicio", "start") and not argumento:
|
||||
@@ -823,8 +827,8 @@ def procesar(texto, chat_id):
|
||||
" ✏️ Ej: <code>/genero</code> → 1 (pelis) → 12 (Horror)\n"
|
||||
"<b>3.</b> <code>torrents <n></code> — torrents del resultado n\n"
|
||||
" ✏️ Ej: <code>/torrents 1</code>\n"
|
||||
"<b>4.</b> <code>bajar <n></code> — descargar al NAS el torrent n\n"
|
||||
" ✏️ Ej: <code>/bajar 1</code>\n"
|
||||
"<b>4.</b> <code>bajar <n></code> — descargar al NAS el torrent n\n"
|
||||
" ✏️ Ej: <code>/bajar 1</code>, <code>/bajar 2-5</code>, <code>/temporada 1</code>\n"
|
||||
"<b>5.</b> <code>pelicula <nombre></code> — buscar película (catálogo)\n"
|
||||
" ✏️ Ej: <code>/pelicula ant-man</code>\n"
|
||||
"<b>6.</b> <code>serie <nombre></code> — buscar serie (catálogo)\n"
|
||||
@@ -1274,51 +1278,148 @@ def procesar_torrents(n, chat_id):
|
||||
log(f"TORRENTS '{r['name']}': {len(torrents)} torrents")
|
||||
|
||||
|
||||
def procesar_bajar(n, chat_id):
|
||||
"""Descarga el torrent numero n al NAS (Download Station via magnet)."""
|
||||
def procesar_bajar(spec, chat_id):
|
||||
"""Descarga al NAS: numero, rango (2-5) o episodios directos."""
|
||||
estado = ultimos_torrents.get(chat_id)
|
||||
if not estado or n is None or n < 1 or n > len(estado["torrents"]):
|
||||
titulos = ultima_titulos.get(chat_id) or {}
|
||||
if estado and estado.get("torrents"):
|
||||
idx = _parse_indices(spec, len(estado["torrents"]))
|
||||
if not idx:
|
||||
enviar("Uso: <b>/bajar <numero></b> o <b>/bajar X-Y</b>.",
|
||||
chat_id)
|
||||
return
|
||||
buenas, malas = [], []
|
||||
for i in idx:
|
||||
uri, etiqueta = _bajar_torrent(estado["torrents"][i - 1],
|
||||
estado.get("titulo") or "")
|
||||
if not uri:
|
||||
malas.append(etiqueta)
|
||||
continue
|
||||
ok, _ = _bajar_uri(uri, etiqueta)
|
||||
(buenas if ok else malas).append(etiqueta)
|
||||
log(f"BAJAR '{estado.get('titulo')}' torrent {i}: ok={ok}")
|
||||
partes = []
|
||||
if buenas:
|
||||
partes.append(f"📥 Añadidos al NAS ({len(buenas)}):\n" +
|
||||
"\n".join(f"• {b}" for b in buenas))
|
||||
if malas:
|
||||
partes.append("❌ Fallaron:\n" +
|
||||
"\n".join(f"• {m}" for m in malas))
|
||||
enviar("\n".join(partes) or "❌ Nada que descargar.", chat_id)
|
||||
return
|
||||
if titulos.get("origen") == "catalogo" and titulos.get("results"):
|
||||
resultados = titulos["results"]
|
||||
idx = _parse_indices(spec, len(resultados))
|
||||
if not idx:
|
||||
enviar("Uso: <b>/bajar <numero></b>, <b>/bajar X-Y</b> o "
|
||||
"<b>/temporada N</b>.", chat_id)
|
||||
return
|
||||
buenas, malas = [], []
|
||||
for i in idx:
|
||||
it = resultados[i - 1]
|
||||
nombre = it.get("clean") or it.get("name") or f"episodio {i}"
|
||||
if not it.get("enlace"):
|
||||
malas.append(f"{nombre} (sin enlace)")
|
||||
continue
|
||||
ok, _ = _bajar_uri(it["enlace"], nombre)
|
||||
(buenas if ok else malas).append(nombre)
|
||||
log(f"BAJAR catalogo '{nombre}': ok={ok}")
|
||||
partes = []
|
||||
if buenas:
|
||||
partes.append(f"📥 Añadidos al NAS ({len(buenas)}):\n" +
|
||||
"\n".join(f"• {b}" for b in buenas))
|
||||
if malas:
|
||||
partes.append("❌ Fallaron:\n" +
|
||||
"\n".join(f"• {m}" for m in malas))
|
||||
enviar("\n".join(partes) or "❌ Nada que descargar.", chat_id)
|
||||
return
|
||||
enviar("Primero usa <b>/busca</b>, <b>/pelicula</b>, <b>/serie</b>, "
|
||||
"<b>/novedades</b> o <b>/genero</b>, luego "
|
||||
"<b>/torrents <numero></b>.", chat_id)
|
||||
return
|
||||
t = estado["torrents"][n - 1]
|
||||
if t.get("enlace") and not t.get("info_hash"):
|
||||
# Enlace directo de catalogo: al NAS sin magnet.
|
||||
|
||||
|
||||
def _parse_indices(spec, total, maximo=10):
|
||||
"""'3' -> [3]; '2-5' o '2:5' -> [2..5]. Recorta al total (max 10)."""
|
||||
spec = str(spec or "").strip()
|
||||
m = re.match(r"(\d+)\s*[-:]\s*(\d+)$", spec)
|
||||
if m:
|
||||
a, b = int(m.group(1)), int(m.group(2))
|
||||
if a > b:
|
||||
a, b = b, a
|
||||
elif spec.isdigit():
|
||||
a = b = int(spec)
|
||||
else:
|
||||
return []
|
||||
a = max(a, 1)
|
||||
b = min(b, total)
|
||||
if a > b:
|
||||
return []
|
||||
return list(range(a, min(b, a + maximo - 1) + 1))
|
||||
|
||||
|
||||
def _bajar_uri(uri, etiqueta):
|
||||
"""Anade un magnet/enlace al NAS. Devuelve (ok, etiqueta)."""
|
||||
try:
|
||||
import nas_dl
|
||||
ok = nas_dl.add_torrent(t["enlace"])
|
||||
ok = nas_dl.add_torrent(uri)
|
||||
except Exception as e:
|
||||
log(f"bajar error: {e}")
|
||||
enviar(f"❌ Error al anadir al NAS: {e}", chat_id)
|
||||
return
|
||||
if ok:
|
||||
enviar(f"📥 Añadido al NAS: <b>{t.get('filename') or estado['titulo']}</b>.",
|
||||
chat_id)
|
||||
else:
|
||||
enviar("❌ No se pudo añadir al NAS.", chat_id)
|
||||
return
|
||||
return False, f"{etiqueta} (error: {e})"
|
||||
return bool(ok), etiqueta
|
||||
|
||||
|
||||
def _bajar_torrent(t, titulo):
|
||||
"""Resuelve un item de ultimos_torrents a (uri, etiqueta)."""
|
||||
if t.get("enlace") and not t.get("info_hash"):
|
||||
return t["enlace"], t.get("filename") or titulo
|
||||
try:
|
||||
gol = _import_global_buscar()
|
||||
except Exception as e:
|
||||
log(f"global_buscar import error: {e}")
|
||||
enviar("❌ No se pudo cargar el modulo", chat_id)
|
||||
return None, "sin modulo"
|
||||
tam = f"{t['size']:.1f}GB" if t.get("size") else "?"
|
||||
return gol.magnet_de(t), f"{t.get('filename') or titulo} ({t.get('calidad')}, {tam})"
|
||||
|
||||
|
||||
def procesar_temporada(n, chat_id):
|
||||
"""Descarga la temporada N completa de la ultima serie del catalogo."""
|
||||
titulos = ultima_titulos.get(chat_id) or {}
|
||||
if titulos.get("origen") != "catalogo" or not titulos.get("results"):
|
||||
enviar("Primero busca una <b>/serie</b> y luego "
|
||||
"<b>/temporada <N></b>.", chat_id)
|
||||
return
|
||||
if n is None or n < 1:
|
||||
enviar("Uso: <b>/temporada <N></b>.", chat_id)
|
||||
return
|
||||
magnet = gol.magnet_de(t)
|
||||
log(f"BAJAR '{estado['titulo']}' torrent {n}: {magnet[:60]}...")
|
||||
try:
|
||||
import nas_dl
|
||||
ok = nas_dl.add_torrent(magnet)
|
||||
sys.path.insert(0, os.path.join(BASE, "..", "videoclub"))
|
||||
import videoclub_buscador as vcb
|
||||
except Exception as e:
|
||||
log(f"bajar error: {e}")
|
||||
enviar(f"❌ Error al anadir al NAS: {e}", chat_id)
|
||||
log(f"videoclub_buscador import error: {e}")
|
||||
enviar("❌ No se pudo cargar el modulo videoclub", chat_id)
|
||||
return
|
||||
if ok:
|
||||
tamaño = f"{t['size']:.1f}GB" if t.get("size") else "?"
|
||||
enviar(f"📥 Añadido al NAS: <b>{t['filename'] or estado['titulo']}</b> "
|
||||
f"({t['calidad']}, {tamaño}).", chat_id)
|
||||
else:
|
||||
enviar("❌ No se pudo añadir al NAS.", chat_id)
|
||||
capitulos = []
|
||||
for it in titulos["results"]:
|
||||
try:
|
||||
temp, _cap = vcb.parsear_episodio(it.get("name") or "")
|
||||
except Exception:
|
||||
temp = 0
|
||||
if temp == n and it.get("enlace"):
|
||||
capitulos.append(it)
|
||||
if not capitulos:
|
||||
enviar(f"❌ No hay capitulos con enlace en la temporada {n}.",
|
||||
chat_id)
|
||||
return
|
||||
buenas, malas = [], []
|
||||
for it in capitulos[:25]:
|
||||
nombre = it.get("clean") or it.get("name") or "capitulo"
|
||||
ok, _ = _bajar_uri(it["enlace"], nombre)
|
||||
(buenas if ok else malas).append(nombre)
|
||||
partes = [f"📥 Temporada {n} al NAS ({len(buenas)} capitulos)."]
|
||||
if malas:
|
||||
partes.append("❌ Fallaron: " + ", ".join(malas))
|
||||
enviar("\n".join(partes), chat_id)
|
||||
log(f"TEMPORADA {n}: {len(buenas)} ok, {len(malas)} fallo")
|
||||
|
||||
|
||||
def monitor_temperatura():
|
||||
|
||||
Reference in New Issue
Block a user