Compare commits

..

1 Commits

4 changed files with 69 additions and 9 deletions

View File

@@ -1,3 +1,7 @@
## 0.1.80.0-dev - 2026-03-13
- dev: YouTube-Plugin: yt-dlp Suche, Bug-Fix Any-Import
## 0.1.79.5-dev - 2026-03-11
- dev: Changelog-Hook auf prepare-commit-msg umgestellt

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.80.0-dev" provider-name="ViewIt">
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.80.5-dev" provider-name="ViewIt">
<requires>
<import addon="xbmc.python" version="3.0.0" />
<import addon="script.module.requests" />

View File

@@ -1698,13 +1698,70 @@ def _sync_ytdlp_status_setting() -> None:
_set_setting_string("ytdlp_status", status)
def _fetch_ytdlp_zip_url() -> str:
"""Ermittelt die aktuellste ZIP-URL fuer script.module.yt-dlp von GitHub."""
api_url = "https://api.github.com/repos/lekma/script.module.yt-dlp/releases/latest"
try:
data = json.loads(_read_binary_url(api_url, timeout=10).decode("utf-8"))
for asset in data.get("assets", []):
url = asset.get("browser_download_url", "")
if url.endswith(".zip"):
return url
except Exception as exc:
_log(f"yt-dlp Release-URL nicht ermittelbar: {exc}", xbmc.LOGWARNING)
return ""
def _install_ytdlp_from_zip(zip_url: str) -> bool:
"""Laedt script.module.yt-dlp ZIP von GitHub und entpackt es in den Addons-Ordner."""
try:
zip_bytes = _read_binary_url(zip_url, timeout=60)
except Exception as exc:
_log(f"yt-dlp ZIP-Download fehlgeschlagen: {exc}", xbmc.LOGWARNING)
return False
if xbmcvfs is None:
return False
addons_root = xbmcvfs.translatePath("special://home/addons")
addons_root_real = os.path.realpath(addons_root)
try:
with zipfile.ZipFile(io.BytesIO(zip_bytes)) as archive:
for member in archive.infolist():
name = str(member.filename or "")
if not name or name.endswith("/"):
continue
target = os.path.realpath(os.path.join(addons_root, name))
if not target.startswith(addons_root_real + os.sep):
continue
os.makedirs(os.path.dirname(target), exist_ok=True)
with archive.open(member, "r") as src, open(target, "wb") as dst:
dst.write(src.read())
except Exception as exc:
_log(f"yt-dlp Entpacken fehlgeschlagen: {exc}", xbmc.LOGWARNING)
return False
builtin = getattr(xbmc, "executebuiltin", None)
if callable(builtin):
builtin("UpdateLocalAddons")
return _is_addon_installed(YTDLP_ADDON_ID)
def _ensure_ytdlp_installed(*, force: bool, silent: bool) -> bool:
if _is_addon_installed(YTDLP_ADDON_ID):
_sync_ytdlp_status_setting()
return True
wait_seconds = 20 if force else 0
ok = _install_kodi_addon(YTDLP_ADDON_ID, wait_seconds=wait_seconds)
zip_url = _fetch_ytdlp_zip_url()
if not zip_url:
_sync_ytdlp_status_setting()
if not silent:
xbmcgui.Dialog().notification(
"yt-dlp",
"Aktuelle Version nicht ermittelbar (GitHub nicht erreichbar?).",
xbmcgui.NOTIFICATION_ERROR,
5000,
)
return False
ok = _install_ytdlp_from_zip(zip_url)
_sync_ytdlp_status_setting()
if not silent:
@@ -1718,7 +1775,7 @@ def _ensure_ytdlp_installed(*, force: bool, silent: bool) -> bool:
else:
xbmcgui.Dialog().notification(
"yt-dlp",
"Installation fehlgeschlagen. Bitte Repository/Netzwerk pruefen.",
"Installation fehlgeschlagen.",
xbmcgui.NOTIFICATION_ERROR,
5000,
)

View File

@@ -172,14 +172,13 @@ def _resolve_with_ytdlp(video_id: str) -> Optional[str]:
except ImportError:
log_error("[YouTube] yt-dlp nicht verfuegbar (script.module.yt-dlp fehlt)")
try:
import xbmc
import xbmcgui
yes = xbmcgui.Dialog().yesno(
xbmcgui.Dialog().notification(
"yt-dlp fehlt",
"script.module.yt-dlp ist nicht installiert.\nJetzt installieren?",
"Bitte yt-dlp in den ViewIT-Einstellungen installieren.",
xbmcgui.NOTIFICATION_ERROR,
5000,
)
if yes:
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.viewit/?action=install_ytdlp)")
except Exception:
pass
return None