updates: show installed/available versions and apply channel explicitly

This commit is contained in:
2026-02-23 20:42:09 +01:00
parent db5748e012
commit 59728875e9
2 changed files with 119 additions and 8 deletions

View File

@@ -23,6 +23,8 @@ import xml.etree.ElementTree as ET
from pathlib import Path
from types import ModuleType
from urllib.parse import parse_qs, urlencode
from urllib.error import URLError
from urllib.request import Request, urlopen
def _ensure_windows_selector_policy() -> None:
@@ -970,6 +972,8 @@ UPDATE_CHANNEL_MAIN = 0
UPDATE_CHANNEL_NIGHTLY = 1
UPDATE_CHANNEL_CUSTOM = 2
AUTO_UPDATE_INTERVAL_SEC = 6 * 60 * 60
UPDATE_HTTP_TIMEOUT_SEC = 8
UPDATE_ADDON_ID = "plugin.video.viewit"
def _selected_update_channel() -> int:
@@ -979,6 +983,14 @@ def _selected_update_channel() -> int:
return channel
def _channel_label(channel: int) -> str:
if channel == UPDATE_CHANNEL_NIGHTLY:
return "Nightly"
if channel == UPDATE_CHANNEL_CUSTOM:
return "Custom"
return "Main"
def _resolve_update_info_url() -> str:
channel = _selected_update_channel()
if channel == UPDATE_CHANNEL_NIGHTLY:
@@ -993,6 +1005,72 @@ def _resolve_update_info_url() -> str:
return info_url
def _read_text_url(url: str, *, timeout: int = UPDATE_HTTP_TIMEOUT_SEC) -> str:
request = Request(url, headers={"User-Agent": "ViewIT/1.0"})
response = None
try:
response = urlopen(request, timeout=timeout)
data = response.read()
finally:
if response is not None:
try:
response.close()
except Exception:
pass
return data.decode("utf-8", errors="replace")
def _extract_repo_addon_version(xml_text: str, addon_id: str = UPDATE_ADDON_ID) -> str:
try:
root = ET.fromstring(xml_text)
except Exception:
return "-"
if root.tag == "addon":
return str(root.attrib.get("version") or "-")
for node in root.findall("addon"):
if str(node.attrib.get("id") or "").strip() == addon_id:
version = str(node.attrib.get("version") or "").strip()
return version or "-"
return "-"
def _fetch_repo_addon_version(info_url: str) -> str:
url = _normalize_update_info_url(info_url)
try:
xml_text = _read_text_url(url)
except URLError:
return "-"
except Exception:
return "-"
return _extract_repo_addon_version(xml_text)
def _sync_update_channel_status_settings() -> None:
channel = _selected_update_channel()
channel_label = _channel_label(channel)
selected_info_url = _resolve_update_info_url()
main_info_url = _normalize_update_info_url(_get_setting_string("update_repo_url_main"))
nightly_info_url = _normalize_update_info_url(_get_setting_string("update_repo_url_nightly"))
available_main = _fetch_repo_addon_version(main_info_url)
available_nightly = _fetch_repo_addon_version(nightly_info_url)
if channel == UPDATE_CHANNEL_MAIN:
available_selected = available_main
elif channel == UPDATE_CHANNEL_NIGHTLY:
available_selected = available_nightly
else:
available_selected = _fetch_repo_addon_version(selected_info_url)
_set_setting_string("update_active_channel", channel_label)
_set_setting_string("update_active_repo_url", selected_info_url)
_set_setting_string("update_available_main", available_main)
_set_setting_string("update_available_nightly", available_nightly)
_set_setting_string("update_available_selected", available_selected)
def _repo_addon_xml_path() -> str:
if xbmcvfs is None:
return ""
@@ -1044,6 +1122,7 @@ def _sync_update_version_settings() -> None:
except Exception:
addon_version = "0.0.0"
_set_setting_string("update_version_addon", addon_version)
_set_setting_string("update_installed_version", addon_version)
versions = {
"update_version_serienstream": "-",
@@ -1060,6 +1139,8 @@ def _sync_update_version_settings() -> None:
for key, value in versions.items():
_set_setting_string(key, value)
_sync_update_channel_status_settings()
def _show_root_menu() -> None:
handle = _get_handle()
@@ -3129,19 +3210,40 @@ def _open_settings() -> None:
addon.openSettings()
def _apply_update_channel(*, silent: bool = False) -> bool:
if xbmc is None: # pragma: no cover - outside Kodi
return False
info_url = _resolve_update_info_url()
_sync_update_version_settings()
applied = _update_repository_source(info_url)
builtin = getattr(xbmc, "executebuiltin", None)
if callable(builtin):
builtin("UpdateAddonRepos")
builtin("UpdateLocalAddons")
if not silent:
if applied:
message = f"Kanal angewendet: {_channel_label(_selected_update_channel())}"
xbmcgui.Dialog().notification("Updates", message, xbmcgui.NOTIFICATION_INFO, 4000)
else:
warning_icon = getattr(xbmcgui, "NOTIFICATION_WARNING", xbmcgui.NOTIFICATION_INFO)
xbmcgui.Dialog().notification(
"Updates",
"Kanal gespeichert, aber repository.viewit nicht gefunden.",
warning_icon,
5000,
)
return applied
def _run_update_check(*, silent: bool = False) -> None:
"""Stoesst Kodi-Repo- und Addon-Updates an."""
if xbmc is None: # pragma: no cover - outside Kodi
return
try:
info_url = _resolve_update_info_url()
_sync_update_version_settings()
_update_repository_source(info_url)
builtin = getattr(xbmc, "executebuiltin", None)
if callable(builtin):
builtin("UpdateAddonRepos")
builtin("UpdateLocalAddons")
if not silent:
_apply_update_channel(silent=True)
if not silent:
builtin = getattr(xbmc, "executebuiltin", None)
if callable(builtin):
builtin("ActivateWindow(addonbrowser,addons://updates/)")
if not silent:
xbmcgui.Dialog().notification("Updates", "Update-Check gestartet.", xbmcgui.NOTIFICATION_INFO, 4000)
@@ -3579,6 +3681,8 @@ def run() -> None:
_open_settings()
elif action == "check_updates":
_run_update_check()
elif action == "apply_update_channel":
_apply_update_channel()
elif action == "seasons":
_show_seasons(params.get("plugin", ""), params.get("title", ""), params.get("series_url", ""))
elif action == "episodes":

View File

@@ -37,8 +37,15 @@
<category label="Updates">
<setting id="update_channel" type="enum" label="Update-Kanal" default="1" values="Main|Nightly|Custom" />
<setting id="apply_update_channel" type="action" label="Update-Kanal jetzt anwenden" action="RunPlugin(plugin://plugin.video.viewit/?action=apply_update_channel)" option="close" />
<setting id="auto_update_enabled" type="bool" label="Automatische Updates (beim Start pruefen)" default="false" />
<setting id="run_update_check" type="action" label="Jetzt nach Updates suchen" action="RunPlugin(plugin://plugin.video.viewit/?action=check_updates)" option="close" />
<setting id="update_installed_version" type="text" label="Installierte Version" default="-" enable="false" />
<setting id="update_available_selected" type="text" label="Verfuegbar (gewaehlter Kanal)" default="-" enable="false" />
<setting id="update_available_main" type="text" label="Verfuegbar Main" default="-" enable="false" />
<setting id="update_available_nightly" type="text" label="Verfuegbar Nightly" default="-" enable="false" />
<setting id="update_active_channel" type="text" label="Aktiver Kanal" default="-" enable="false" />
<setting id="update_active_repo_url" type="text" label="Aktive Repo URL" default="-" enable="false" />
<setting id="update_info" type="text" label="Updates laufen ueber den normalen Kodi-Update-Mechanismus." default="" enable="false" />
<setting id="update_repo_url_main" type="text" label="Main URL (addons.xml)" default="https://gitea.it-drui.de/viewit/ViewIT-Kodi-Repo/raw/branch/main/addons.xml" />
<setting id="update_repo_url_nightly" type="text" label="Nightly URL (addons.xml)" default="https://gitea.it-drui.de/viewit/ViewIT-Kodi-Repo/raw/branch/nightly/addons.xml" />