YT metadata fetch: razširi --info-only output (id, uploader, description, upload_date, view_count, tags, ...). Single video submit fetcha metadata + Qnet match takoj (kot playlist). Worker preskoči info fetch če metadata že obstaja, sicer shrani vsa polja in naredi Qnet match.

- yt_download.py: get_info() probaj najprej yt.biba.live API /download/info (residential IP, sveži cookies), fallback na lokalni yt-dlp. --info-only output razširjen na 17 polj.
- main.py submit_youtube single video: fetcha metadata (yt_get_info) ob submit, shrani youtube_title/uploader/id/description/duration/thumbnail/upload_date in naredi Qnet match (parity s playlist branch).
- main.py worker: skip info fetch če youtube_title in youtube_uploader že obstajata. Sicer shrani VSE polja + Qnet match + parser fallback.
This commit is contained in:
OpenClaw Agent
2026-05-02 15:54:28 +00:00
parent bc73fd8dd3
commit 968eba7205
2 changed files with 143 additions and 25 deletions
+41 -2
View File
@@ -114,7 +114,33 @@ def download(url, output, max_height=1080, format_str=None, cookies_file=None):
def get_info(url, cookies_file=None):
"""Vrni metadata brez prenosa."""
"""Vrni metadata brez prenosa.
Strategija:
1. Najprej probaj yt.biba.live API /download/info (residential IP,
sveži cookies, signature solver — manj možnosti za bot detection).
2. Fallback na lokalni yt-dlp --dump-json.
"""
# ─── 1. Try yt.biba.live API ───
if YT_API_TOKEN:
try:
import urllib.request
import urllib.parse
params = urllib.parse.urlencode({"url": url})
req = urllib.request.Request(
f"{YT_API_URL}/download/info?{params}",
headers={"Authorization": f"Bearer {YT_API_TOKEN}"},
)
with urllib.request.urlopen(req, timeout=30) as resp:
api_data = json.loads(resp.read().decode("utf-8"))
if api_data.get("ok"):
print(f"ℹ Info via yt.biba.live API: {api_data.get('title','')[:60]}", file=sys.stderr)
# API že vrne flat dict — preimenujmo v yt-dlp obliko za kompatibilnost
return api_data
except Exception as e:
print(f"⚠ yt.biba.live /download/info failed: {e}, fallback to local", file=sys.stderr)
# ─── 2. Fallback: lokalni yt-dlp ───
cmd = ["yt-dlp", "--dump-json", "--no-playlist"]
cookies_file = get_cookies_file(cookies_file)
if cookies_file:
@@ -230,11 +256,24 @@ def main():
info = get_info(args.url, cookies_file=args.cookies)
if info:
print(json.dumps({
"id": info.get("id"),
"title": info.get("title"),
"duration": info.get("duration"),
"uploader": info.get("uploader"),
"uploader_id": info.get("uploader_id"),
"channel": info.get("channel"),
"channel_id": info.get("channel_id"),
"thumbnail": info.get("thumbnail"),
}, indent=2))
"description": info.get("description"),
"upload_date": info.get("upload_date"),
"view_count": info.get("view_count"),
"like_count": info.get("like_count"),
"categories": info.get("categories"),
"tags": info.get("tags"),
"webpage_url": info.get("webpage_url"),
"age_limit": info.get("age_limit"),
"is_live": info.get("is_live"),
}, indent=2, ensure_ascii=False))
else:
print("❌ Ne morem dobiti info", file=sys.stderr)
sys.exit(1)