Implement ViewIt Plugin System Documentation and Update Project Notes
- Added comprehensive documentation for the ViewIt Plugin System, detailing the plugin loading process, required methods, optional features, and community extension workflow. - Updated project notes to reflect the current structure, build process, search logic, and known issues. - Introduced new build scripts for installing the add-on and creating ZIP packages. - Added test scripts for TMDB API integration, including argument parsing and logging functionality. - Enhanced existing plugins with improved search logic and error handling.
This commit is contained in:
127
addon/plugins/_template_plugin.py
Normal file
127
addon/plugins/_template_plugin.py
Normal file
@@ -0,0 +1,127 @@
|
||||
"""Template fuer ein neues ViewIt-Plugin (Basis: serienstream_plugin).
|
||||
|
||||
Diese Datei wird NICHT automatisch geladen (Dateiname beginnt mit `_`).
|
||||
Zum Verwenden:
|
||||
1) Kopiere/benenne die Datei um (ohne fuehrenden Unterstrich), z.B. `my_site_plugin.py`
|
||||
2) Passe `name`, `BASE_URL` und die Implementierungen an.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, List, Optional, TypeAlias
|
||||
|
||||
try: # pragma: no cover - optional dependency
|
||||
import requests
|
||||
from bs4 import BeautifulSoup # type: ignore[import-not-found]
|
||||
except ImportError as exc: # pragma: no cover - optional dependency
|
||||
requests = None
|
||||
BeautifulSoup = None
|
||||
REQUESTS_AVAILABLE = False
|
||||
REQUESTS_IMPORT_ERROR = exc
|
||||
else:
|
||||
REQUESTS_AVAILABLE = True
|
||||
REQUESTS_IMPORT_ERROR = None
|
||||
|
||||
try: # pragma: no cover - optional Kodi helpers
|
||||
import xbmcaddon # type: ignore[import-not-found]
|
||||
except ImportError: # pragma: no cover - allow running outside Kodi
|
||||
xbmcaddon = None
|
||||
|
||||
from plugin_interface import BasisPlugin
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from requests import Session as RequestsSession
|
||||
from bs4 import BeautifulSoup as BeautifulSoupT # type: ignore[import-not-found]
|
||||
else: # pragma: no cover
|
||||
RequestsSession: TypeAlias = Any
|
||||
BeautifulSoupT: TypeAlias = Any
|
||||
|
||||
|
||||
ADDON_ID = "plugin.video.viewit"
|
||||
BASE_URL = "https://example.com"
|
||||
DEFAULT_TIMEOUT = 20
|
||||
HEADERS = {
|
||||
"User-Agent": "Mozilla/5.0 (Kodi; ViewIt) AppleWebKit/537.36 (KHTML, like Gecko)",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||
"Accept-Language": "de-DE,de;q=0.9,en;q=0.8",
|
||||
"Connection": "keep-alive",
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TitleHit:
|
||||
"""Ein Suchtreffer mit Titel und Detail-URL."""
|
||||
|
||||
title: str
|
||||
url: str
|
||||
|
||||
|
||||
class TemplatePlugin(BasisPlugin):
|
||||
"""Vorlage fuer eine Streamingseiten-Integration.
|
||||
|
||||
Optional kann ein Plugin Capabilities deklarieren (z.B. `popular_series`),
|
||||
damit der Router passende Menüpunkte anbieten kann.
|
||||
"""
|
||||
|
||||
name = "Template"
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._session: RequestsSession | None = None
|
||||
|
||||
@property
|
||||
def is_available(self) -> bool:
|
||||
return REQUESTS_AVAILABLE
|
||||
|
||||
@property
|
||||
def unavailable_reason(self) -> str:
|
||||
if REQUESTS_AVAILABLE:
|
||||
return ""
|
||||
return f"requests/bs4 nicht verfuegbar: {REQUESTS_IMPORT_ERROR}"
|
||||
|
||||
def _get_session(self) -> RequestsSession:
|
||||
if requests is None:
|
||||
raise RuntimeError(self.unavailable_reason)
|
||||
if self._session is None:
|
||||
session = requests.Session()
|
||||
session.headers.update(HEADERS)
|
||||
self._session = session
|
||||
return self._session
|
||||
|
||||
async def search_titles(self, query: str) -> List[str]:
|
||||
"""TODO: Suche auf der Zielseite implementieren."""
|
||||
_ = query
|
||||
return []
|
||||
|
||||
def seasons_for(self, title: str) -> List[str]:
|
||||
"""TODO: Staffeln fuer einen Titel liefern."""
|
||||
_ = title
|
||||
return []
|
||||
|
||||
def episodes_for(self, title: str, season: str) -> List[str]:
|
||||
"""TODO: Episoden fuer Titel+Staffel liefern."""
|
||||
_ = (title, season)
|
||||
return []
|
||||
|
||||
def capabilities(self) -> set[str]:
|
||||
"""Optional: Deklariert Fähigkeiten dieses Plugins.
|
||||
|
||||
Beispiele:
|
||||
- `popular_series`: Plugin kann beliebte Serien liefern
|
||||
- `genres`: Plugin unterstützt Genre-Browser
|
||||
"""
|
||||
|
||||
return set()
|
||||
|
||||
def popular_series(self) -> List[str]:
|
||||
"""Optional: Liste beliebter Serien (nur wenn `popular_series` gesetzt ist)."""
|
||||
return []
|
||||
|
||||
def stream_link_for(self, title: str, season: str, episode: str) -> Optional[str]:
|
||||
"""Optional: Embed-/Hoster-Link fuer eine Episode."""
|
||||
_ = (title, season, episode)
|
||||
return None
|
||||
|
||||
def resolve_stream_link(self, link: str) -> Optional[str]:
|
||||
"""Optional: Redirect-/Mirror-Aufloesung."""
|
||||
return link
|
||||
Reference in New Issue
Block a user