dev: bump to 0.1.76.0-dev – aeltere Versionen im Update-Dialog, Release-Branch-Zuordnung, README ueberarbeitet
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
## 0.1.74-dev - 2026-03-10
|
||||
|
||||
- dev: bump to 0.1.74-dev – BurningSeries entfernt, Paging-Fix Neuste Titel
|
||||
|
||||
## 0.1.73-dev - 2026-03-07
|
||||
|
||||
- dev: bump to 0.1.73-dev – Autoplay-Setting, Moflix Hoster-Dialog, Update-Hinweis im Hauptmenue
|
||||
|
||||
108
README.md
108
README.md
@@ -2,42 +2,86 @@
|
||||
|
||||
<img src="addon/resources/logo.png" alt="ViewIT Logo" width="220" />
|
||||
|
||||
ViewIT ist ein Kodi Addon.
|
||||
Es durchsucht Provider und startet Streams.
|
||||
**ViewIT** ist ein Kodi-Addon zum Streamen von Filmen und Serien aus verschiedenen Quellen – alles an einem Ort.
|
||||
|
||||
## Projektstruktur
|
||||
- `addon/` Kodi Addon Quellcode
|
||||
- `scripts/` Build Scripts
|
||||
- `dist/` Build Ausgaben
|
||||
- `docs/` Doku
|
||||
- `tests/` Tests
|
||||
## Was kann ViewIT?
|
||||
|
||||
## Build und Release
|
||||
- Addon Ordner bauen: `./scripts/build_install_addon.sh`
|
||||
- Kodi ZIP bauen: `./scripts/build_kodi_zip.sh`
|
||||
- Version pflegen: `addon/addon.xml`
|
||||
- Reproduzierbares ZIP: `SOURCE_DATE_EPOCH` optional setzen
|
||||
- **Filme und Serien** aus mehreren Streaming-Quellen durchsuchen und abspielen
|
||||
- **Trakt-Anbindung** – Watchlist, Weiterschauen, Watch-History und automatisches Scrobbling
|
||||
- **TMDB-Metadaten** – Poster, Beschreibungen, Bewertungen und Fanart automatisch laden
|
||||
- **Autoplay** – Bevorzugten Hoster einstellen und direkt abspielen
|
||||
- **Automatische Updates** – Neue Versionen werden erkannt und koennen direkt installiert werden
|
||||
|
||||
## Lokales Kodi Repository
|
||||
- Repository bauen: `./scripts/build_local_kodi_repo.sh`
|
||||
- Repository starten: `./scripts/serve_local_kodi_repo.sh`
|
||||
- Repo-Artefakte pruefen: `./scripts/verify_repo_artifacts.py ./dist/repo`
|
||||
- Standard URL: `http://127.0.0.1:8080/repo/addons.xml`
|
||||
- Eigene URL beim Build: `REPO_BASE_URL=http://<host>:<port>/repo ./scripts/build_local_kodi_repo.sh`
|
||||
## Installation
|
||||
|
||||
## Entwicklung
|
||||
- Router: `addon/default.py`
|
||||
- Plugins: `addon/plugins/*_plugin.py`
|
||||
- Settings: `addon/resources/settings.xml`
|
||||
1. Die neueste ZIP-Datei herunterladen (siehe [Releases](https://gitea.it-drui.de/viewit/ViewIT/releases))
|
||||
2. In Kodi: **Einstellungen** > **Addons** > **Aus ZIP-Datei installieren**
|
||||
3. Die heruntergeladene ZIP-Datei auswaehlen
|
||||
4. ViewIT erscheint unter **Video-Addons**
|
||||
|
||||
## Tests
|
||||
- Dev Pakete installieren: `./.venv/bin/pip install -r requirements-dev.txt`
|
||||
- Tests starten: `./.venv/bin/pytest`
|
||||
- XML Report: `./.venv/bin/pytest --cov-report=xml`
|
||||
### Updates
|
||||
|
||||
### Linting & Formatierung
|
||||
- Ruff Linting: `./.venv/bin/ruff check addon docs`
|
||||
- Black Format Check: `./.venv/bin/black --check addon docs`
|
||||
ViewIT kann sich selbst aktualisieren. In den Addon-Einstellungen unter **Updates** den gewuenschten Kanal waehlen:
|
||||
|
||||
## Dokumentation
|
||||
Siehe `docs/`.
|
||||
- **Main** – Stabile Versionen
|
||||
- **Nightly** – Aktuelle Entwicklungsversionen
|
||||
- **Dev** – Neueste Aenderungen (kann instabil sein)
|
||||
|
||||
## Einstellungen
|
||||
|
||||
Die wichtigsten Einstellungen im Addon:
|
||||
|
||||
- **Quellen** – Basis-URLs der einzelnen Streaming-Seiten (falls sich Domains aendern)
|
||||
- **Metadaten** – TMDB aktivieren/deaktivieren, Sprache einstellen
|
||||
- **Wiedergabe** – Autoplay und bevorzugten Hoster festlegen
|
||||
- **Trakt** – Konto verbinden fuer Watchlist und Scrobbling
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Kodi 19 (Matrix) oder neuer
|
||||
- **ResolveURL** – wird beim ersten Start automatisch installiert (kann auch manuell ueber die Einstellungen nachinstalliert werden)
|
||||
|
||||
## Fuer Entwickler
|
||||
|
||||
<details>
|
||||
<summary>Build und Projektstruktur</summary>
|
||||
|
||||
### Projektstruktur
|
||||
|
||||
```
|
||||
addon/ Kodi-Addon Quellcode
|
||||
default.py Hauptdatei und Router
|
||||
plugins/ Streaming-Plugins (eins pro Quelle)
|
||||
core/ Kernmodule (Trakt, Metadaten, Updates, ...)
|
||||
resources/ Einstellungen, Icons, Sprachdateien
|
||||
scripts/ Build- und Deploy-Skripte
|
||||
tests/ Automatisierte Tests
|
||||
dist/ Build-Ausgaben
|
||||
```
|
||||
|
||||
### Addon bauen
|
||||
|
||||
```bash
|
||||
# Addon-Ordner erzeugen
|
||||
bash scripts/build_install_addon.sh
|
||||
|
||||
# ZIP fuer Kodi-Installation erzeugen
|
||||
bash scripts/build_kodi_zip.sh
|
||||
```
|
||||
|
||||
### Tests ausfuehren
|
||||
|
||||
```bash
|
||||
pip install -r requirements-dev.txt
|
||||
pytest
|
||||
```
|
||||
|
||||
### Lokales Kodi-Repository
|
||||
|
||||
```bash
|
||||
bash scripts/build_local_kodi_repo.sh
|
||||
bash scripts/serve_local_kodi_repo.sh
|
||||
# Erreichbar unter http://127.0.0.1:8080/repo/addons.xml
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.74-dev" provider-name="ViewIt">
|
||||
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.76.0-dev" provider-name="ViewIt">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="3.0.0" />
|
||||
<import addon="script.module.requests" />
|
||||
|
||||
@@ -1383,6 +1383,25 @@ def _fetch_repo_versions(info_url: str) -> list[str]:
|
||||
version = match.group(1).strip()
|
||||
if version:
|
||||
versions.append(version)
|
||||
|
||||
# Zusaetzlich Gitea Releases API abfragen (aeltere Versionen)
|
||||
try:
|
||||
source_repo = repo.replace("ViewIT-Kodi-Repo", "ViewIT").replace("-Kodi-Repo", "")
|
||||
releases_api = f"{scheme}://{host}/api/v1/repos/{owner}/{source_repo}/releases?limit=50"
|
||||
releases_payload = _read_text_url(releases_api)
|
||||
releases_data = json.loads(releases_payload)
|
||||
if isinstance(releases_data, list):
|
||||
for release in releases_data:
|
||||
for asset in release.get("assets", []):
|
||||
aname = str(asset.get("name") or "")
|
||||
m = re.match(rf"^{re.escape(UPDATE_ADDON_ID)}-(.+)\.zip$", aname)
|
||||
if m:
|
||||
v = m.group(1).strip()
|
||||
if v:
|
||||
versions.append(v)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
unique = sorted(set(versions), key=_version_sort_key, reverse=True)
|
||||
return unique
|
||||
|
||||
@@ -1462,9 +1481,33 @@ def _install_addon_version_manual(info_url: str, version: str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def _install_addon_version(info_url: str, version: str) -> bool:
|
||||
def _resolve_zip_url(info_url: str, version: str) -> str:
|
||||
"""Gibt die Download-URL fuer eine bestimmte Version zurueck.
|
||||
|
||||
Prueft zuerst das Kodi-Repo, dann den Gitea-Release-Download.
|
||||
"""
|
||||
base = info_url[: -len("/addons.xml")] if info_url.endswith("/addons.xml") else info_url.rstrip("/")
|
||||
zip_url = f"{base}/{UPDATE_ADDON_ID}/{UPDATE_ADDON_ID}-{version}.zip"
|
||||
repo_url = f"{base}/{UPDATE_ADDON_ID}/{UPDATE_ADDON_ID}-{version}.zip"
|
||||
# Pruefen ob die ZIP im Kodi-Repo existiert
|
||||
try:
|
||||
req = Request(repo_url, method="HEAD", headers={"User-Agent": "ViewIT/1.0"})
|
||||
resp = urlopen(req, timeout=UPDATE_HTTP_TIMEOUT_SEC)
|
||||
if resp.status == 200:
|
||||
return repo_url
|
||||
except Exception:
|
||||
pass
|
||||
# Fallback: Gitea Release Asset
|
||||
identity = _extract_repo_identity(info_url)
|
||||
if identity:
|
||||
scheme, host, owner, repo_branch = identity
|
||||
repo = repo_branch.split("|", 1)[0]
|
||||
source_repo = repo.replace("ViewIT-Kodi-Repo", "ViewIT").replace("-Kodi-Repo", "")
|
||||
return f"{scheme}://{host}/{owner}/{source_repo}/releases/download/v{version}/{UPDATE_ADDON_ID}-{version}.zip"
|
||||
return repo_url
|
||||
|
||||
|
||||
def _install_addon_version(info_url: str, version: str) -> bool:
|
||||
zip_url = _resolve_zip_url(info_url, version)
|
||||
|
||||
# Prefer Kodi's own installer to get proper install flow and dependency handling.
|
||||
builtin = getattr(xbmc, "executebuiltin", None)
|
||||
|
||||
@@ -7,19 +7,17 @@ branch=$(git symbolic-ref --short HEAD 2>/dev/null)
|
||||
root=$(git rev-parse --show-toplevel)
|
||||
cd "$root"
|
||||
|
||||
# Aktuelle Version aus addon.xml (bereits vom pre-commit Hook hochgezählt)
|
||||
version=$(grep -oP 'version="\K[0-9]+\.[0-9]+\.[0-9]+[^"]*' addon/addon.xml | head -1)
|
||||
# Aktuelle Version aus addon.xml (bereits vom pre-commit Hook hochgezaehlt)
|
||||
version=$(grep -oP 'version="\K[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?[^"]*' addon/addon.xml | head -1)
|
||||
|
||||
# Commit-Message: alte Versionsnummern durch aktuelle ersetzen
|
||||
# z.B. "dev: bump to 0.1.72-dev – ..." → "dev: bump to 0.1.73-dev – ..."
|
||||
msg=$(cat "$1")
|
||||
updated_msg=$(echo "$msg" | sed -E "s/bump to [0-9]+\.[0-9]+\.[0-9]+[^ ]*/bump to ${version}/g")
|
||||
updated_msg=$(echo "$msg" | sed -E "s/bump to [0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?[^ ]*/bump to ${version}/g")
|
||||
echo "$updated_msg" > "$1"
|
||||
|
||||
today=$(date +%Y-%m-%d)
|
||||
|
||||
# Changelog-Eintrag aufbauen
|
||||
# Jede nicht-leere Zeile der Commit-Message wird ein "- ..." Eintrag
|
||||
{
|
||||
echo "## ${version} - ${today}"
|
||||
echo ""
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
# pre-commit: Patch-Version in addon.xml automatisch hochzählen (nur dev-Branch)
|
||||
# Unterstuetzt 3-teilig (x.x.xx) und 4-teilig (x.x.xx.x)
|
||||
# 4-teilig: zaehlt den 4. Teil in 5er-Schritten hoch (z.B. 0.1.75.5 → 0.1.76.0)
|
||||
|
||||
branch=$(git symbolic-ref --short HEAD 2>/dev/null)
|
||||
[[ "$branch" != "dev" ]] && exit 0
|
||||
@@ -7,18 +9,43 @@ branch=$(git symbolic-ref --short HEAD 2>/dev/null)
|
||||
root=$(git rev-parse --show-toplevel)
|
||||
cd "$root"
|
||||
|
||||
# Version aus addon.xml lesen
|
||||
current=$(grep -oP 'version="\K[0-9]+\.[0-9]+\.[0-9]+[^"]*' addon/addon.xml | head -1)
|
||||
# Version aus addon.xml lesen (3- oder 4-teilig mit optionalem Suffix)
|
||||
current=$(grep -oP 'version="\K[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?[^"]*' addon/addon.xml | head -1)
|
||||
if [[ -z "$current" ]]; then
|
||||
echo "[hook] Fehler: Version nicht gefunden in addon/addon.xml" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Patch-Nummer extrahieren und hochzählen
|
||||
IFS='.' read -r major minor patch_full <<< "$current"
|
||||
patch=$(echo "$patch_full" | grep -oP '^\d+')
|
||||
suffix=$(echo "$patch_full" | grep -oP '[^0-9].*' || true)
|
||||
new_version="${major}.${minor}.$((patch + 1))${suffix}"
|
||||
# Suffix extrahieren (z.B. -dev)
|
||||
suffix=$(echo "$current" | grep -oP '[-][a-zA-Z].*' || true)
|
||||
version_only=$(echo "$current" | sed "s/${suffix}$//")
|
||||
|
||||
# Parts zaehlen
|
||||
IFS='.' read -ra parts <<< "$version_only"
|
||||
num_parts=${#parts[@]}
|
||||
|
||||
if [[ $num_parts -eq 4 ]]; then
|
||||
# 4-teilig: 4. Teil um 5 erhoehen, bei >= 10 den 3. Teil erhoehen
|
||||
major=${parts[0]}
|
||||
minor=${parts[1]}
|
||||
patch=${parts[2]}
|
||||
sub=${parts[3]}
|
||||
new_sub=$((sub + 5))
|
||||
if [[ $new_sub -ge 10 ]]; then
|
||||
new_sub=$((new_sub - 10))
|
||||
patch=$((patch + 1))
|
||||
fi
|
||||
new_version="${major}.${minor}.${patch}.${new_sub}${suffix}"
|
||||
elif [[ $num_parts -eq 3 ]]; then
|
||||
# 3-teilig: Patch hochzaehlen
|
||||
major=${parts[0]}
|
||||
minor=${parts[1]}
|
||||
patch=${parts[2]}
|
||||
new_version="${major}.${minor}.$((patch + 1))${suffix}"
|
||||
else
|
||||
echo "[hook] Fehler: Unerwartetes Versionsformat: $current" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# addon.xml aktualisieren
|
||||
sed -i "s/version=\"${current}\"/version=\"${new_version}\"/" addon/addon.xml
|
||||
|
||||
@@ -128,14 +128,27 @@ print(json.load(open(sys.argv[1], encoding="utf-8"))["id"])
|
||||
PY
|
||||
)"
|
||||
elif [[ "${http_code}" == "404" ]]; then
|
||||
payload="$(python3 - "${TAG}" "${TITLE}" "${NOTES}" <<'PY'
|
||||
# Branch und prerelease aus Version ableiten
|
||||
read -r TARGET_BRANCH IS_PRERELEASE < <(python3 - "${ADDON_VERSION}" <<'PY'
|
||||
import sys
|
||||
v = sys.argv[1]
|
||||
if "-dev" in v:
|
||||
print("dev", "true")
|
||||
elif "-nightly" in v:
|
||||
print("nightly", "true")
|
||||
else:
|
||||
print("main", "false")
|
||||
PY
|
||||
)
|
||||
payload="$(python3 - "${TAG}" "${TITLE}" "${NOTES}" "${TARGET_BRANCH}" "${IS_PRERELEASE}" <<'PY'
|
||||
import json,sys
|
||||
print(json.dumps({
|
||||
"tag_name": sys.argv[1],
|
||||
"name": sys.argv[2],
|
||||
"body": sys.argv[3],
|
||||
"target_commitish": sys.argv[4],
|
||||
"draft": False,
|
||||
"prerelease": False
|
||||
"prerelease": sys.argv[5] == "true"
|
||||
}))
|
||||
PY
|
||||
)"
|
||||
|
||||
Reference in New Issue
Block a user