Files
Medios-Macina/Provider/youtube.py

77 lines
2.9 KiB
Python
Raw Normal View History

2025-12-11 19:04:02 -08:00
from __future__ import annotations
import sys
from typing import Any, Dict, List, Optional
2025-12-19 02:29:42 -08:00
from ProviderCore.base import Provider, SearchResult
2025-12-11 19:04:02 -08:00
from SYS.logger import log
2025-12-19 02:29:42 -08:00
class YouTube(Provider):
2025-12-24 05:10:07 -08:00
"""Search provider for YouTube using the yt_dlp Python package."""
2025-12-11 19:04:02 -08:00
def search(
self,
query: str,
limit: int = 10,
filters: Optional[Dict[str, Any]] = None,
**kwargs: Any,
) -> List[SearchResult]:
2025-12-24 05:10:07 -08:00
# Use the yt_dlp Python module (installed via requirements.txt).
2025-12-11 19:04:02 -08:00
try:
2025-12-24 05:10:07 -08:00
import yt_dlp # type: ignore
2025-12-29 17:05:03 -08:00
2025-12-24 05:10:07 -08:00
ydl_opts: Dict[str, Any] = {"quiet": True, "skip_download": True, "extract_flat": True}
with yt_dlp.YoutubeDL(ydl_opts) as ydl: # type: ignore[arg-type]
search_query = f"ytsearch{limit}:{query}"
info = ydl.extract_info(search_query, download=False)
entries = info.get("entries") or []
results: List[SearchResult] = []
for video_data in entries[:limit]:
title = video_data.get("title", "Unknown")
video_id = video_data.get("id", "")
url = video_data.get("url") or f"https://youtube.com/watch?v={video_id}"
uploader = video_data.get("uploader", "Unknown")
duration = video_data.get("duration", 0)
view_count = video_data.get("view_count", 0)
2025-12-29 17:05:03 -08:00
duration_str = (
f"{int(duration // 60)}:{int(duration % 60):02d}" if duration else ""
)
2025-12-24 05:10:07 -08:00
views_str = f"{view_count:,}" if view_count else ""
results.append(
SearchResult(
table="youtube",
title=title,
path=url,
detail=f"By: {uploader}",
annotations=[duration_str, f"{views_str} views"],
media_kind="video",
columns=[
("Title", title),
("Uploader", uploader),
("Duration", duration_str),
("Views", views_str),
],
full_metadata={
"video_id": video_id,
"uploader": uploader,
"duration": duration,
"view_count": view_count,
},
)
2025-12-11 19:04:02 -08:00
)
2025-12-24 05:10:07 -08:00
return results
except Exception:
log("[youtube] yt_dlp import failed", file=sys.stderr)
2025-12-11 19:04:02 -08:00
return []
def validate(self) -> bool:
2025-12-24 05:10:07 -08:00
try:
import yt_dlp # type: ignore
2025-12-29 17:05:03 -08:00
2025-12-24 05:10:07 -08:00
return True
except Exception:
return False