File size: 3,438 Bytes
b90715b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f6a3f55
b90715b
 
 
 
 
 
 
 
 
cf0a524
b90715b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ccb5cde
b90715b
ccb5cde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import logging
import os
import re
from urllib.parse import quote_plus
from typing import List, Union
import requests

from plugins.common import DownloadCancelled
from plugins.stream import download_stream_url

logger = logging.getLogger("worker.plugins.threads")


def download_threads(
    url: str,
    output_dir: str,
    progress_fn=None,
    cancel_event=None
) -> Union[str, List[str]]:
    """
    Descarga fotos o videos de posts de Threads con fallback automático.
    """
    if cancel_event and cancel_event.is_set():
        raise DownloadCancelled()

    os.makedirs(output_dir, exist_ok=True)
    delirius_key = os.getenv("DELIRIUS_API_KEY", "")

    try:
        enc_url = quote_plus(url.strip())
        api_url = f"https://api.delirius.online/download/threads?url={enc_url}"
        if delirius_key:
            api_url += f"&apikey={delirius_key}"

        resp = requests.get(api_url, timeout=25)
        if resp.status_code == 200:
            json_data = resp.json()
            if json_data.get("status") and "data" in json_data:
                data = json_data["data"]
                media_list = []

                if isinstance(data, list):
                    for idx, item in enumerate(data, 1):
                        d_url = item.get("url") or item.get("download_url") or item.get("dl_url")
                        m_type = item.get("type", "video" if ".mp4" in str(d_url) else "photo")
                        ext = ".mp4" if m_type == "video" else ".jpg"
                        if d_url:
                            media_list.append((d_url, f"threads_{idx}{ext}"))
                elif isinstance(data, dict):
                    media_arr = data.get("media") or data.get("result") or []
                    if isinstance(media_arr, list) and media_arr:
                        for idx, item in enumerate(media_arr, 1):
                            d_url = item.get("url") or item.get("download_url") if isinstance(item, dict) else str(item)
                            ext = ".mp4" if ".mp4" in str(d_url) else ".jpg"
                            if d_url:
                                media_list.append((d_url, f"threads_{idx}{ext}"))
                    else:
                        d_url = data.get("url") or data.get("download") or data.get("dl_url")
                        m_type = data.get("type", "video" if ".mp4" in str(d_url) else "photo")
                        ext = ".mp4" if m_type == "video" else ".jpg"
                        if d_url:
                            media_list.append((d_url, f"threads_1{ext}"))

                if media_list:
                    downloaded = []
                    for idx, (m_url, m_name) in enumerate(media_list):
                        if cancel_event and cancel_event.is_set():
                            raise DownloadCancelled()
                        target = os.path.join(output_dir, m_name)
                        out_path, _ = download_stream_url(m_url, target, progress_fn=progress_fn, cancel_event=cancel_event)
                        if os.path.exists(out_path):
                            downloaded.append(out_path)
                    if downloaded:
                        return downloaded[0] if len(downloaded) == 1 else downloaded
    except Exception as e:
        logger.warning(f"Descarga falló para Threads: {e}")

    raise RuntimeError("No se pudo obtener el archivo multimedia de Threads para este enlace.")