Dokumentace Addon Systému
Kompletní průvodce tvorbou externích doplňků úložišť pro StreamujTo
Úvod
Aplikace StreamujTo v základní instalaci neobsahuje žádný zdroj streamů ani přístup k žádnému úložišti. Veškerá funkcionalita spojená s vyhledáváním a přehráváním souborů z externích služeb je zajištěna doplňky (addony), které si uživatel importuje sám – z URL adresy nebo lokálního JSON souboru.
Addon je čistě deklarativní JSON soubor, který popisuje:
- Manifest – metadata addonu (název, autor, verze, schopnosti)
- Autentizace – jak se přihlásit k dané službě
- Vyhledávání – jak vyhledat soubory podle dotazu
- Streamování – jak získat přímý odkaz na stream
Addon neobsahuje žádný spustitelný kód. Jedná se o deklarativní pipeline, kterou interpretuje vestavěný Addon Engine aplikace.
Addon systém je navržen tak, aby byl maximálně bezpečný. JSON definice nemůže spustit libovolný kód – může pouze provádět předem definované akce (HTTP požadavky, hashování, regex).
Architektura
Addon systém se skládá z následujících komponent:
| Komponenta | Popis |
|---|---|
AddonDefinition | Datový model parsovaný z JSON souboru. Obsahuje manifest, auth, search a streamUrl sekce. |
AddonEngine | Interpret, který implementuje AddonInterface na základě JSON definice. Vykonává pipeline kroků (steps). |
AddonStore | Persistentní úložiště (SharedPreferences). Ukládá raw JSON definice, takže přežijí restart aplikace. |
AddonRegistry | Singleton registr běžících addonů. Spravuje stav, credentials, aktivní addon. |
AddonImporter | Import z URL (HTTP download) nebo lokálního souboru (file picker). |
AddonInterface | Abstraktní kontrakt definující metody: authenticate, search, getStreamUrl, atd. |
Životní cyklus addonu
- Import – uživatel zadá URL nebo vybere JSON soubor.
AddonImporterstáhne/přečte JSON a validuje ho. - Parsování –
AddonDefinition.fromJson()rozloží JSON na strukturované objekty (manifest, auth, search, streamUrl). - Registrace – vytvoří se
AddonEngineinstance a zaregistruje se doAddonRegistry. - Persistence – raw JSON se uloží do
AddonStore(SharedPreferences), aby addon přežil restart. - Autentizace – uživatel vyplní přihlašovací údaje → engine spustí
auth.loginpipeline. - Použití – při vyhledávání engine spustí
searchpipeline, při přehrávánístreamUrlpipeline. - Obnova – při startu aplikace
StorageManagernačte všechny definice zAddonStorea obnoví enginy + autentizaci.
Kořenová struktura JSON
Každý addon je jeden JSON soubor s následující kořenovou strukturou:
JSON{
"manifest": { ... },
"auth": { ... },
"search": { ... },
"streamUrl": { ... }
}
| Klíč | Typ | Povinný | Popis |
|---|---|---|---|
manifest | Object | Ano | Metadata addonu – identifikace, verze, schopnosti. |
auth | Object | Ne | Definice autentizačního flow. Pokud chybí, addon nevyžaduje přihlášení. |
search | Object | Ano | Pipeline pro vyhledávání souborů. |
streamUrl | Object | Ano | Pipeline pro získání přímého stream odkazu. |
Sekce manifest
Manifest obsahuje veškeré metadata o addonu. Tyto informace se zobrazují v nastavení aplikace.
JSON{
"manifest": {
"id": "muj-addon",
"name": "Můj Addon",
"version": "1.0.0",
"description": "Popis toho, co addon dělá.",
"author": "Jan Novák",
"type": "api",
"capabilities": ["search", "auth", "directStream"],
"homeUrl": "https://example.com",
"iconUrl": "https://example.com/icon.png"
}
}
| Pole | Typ | Povinný | Popis |
|---|---|---|---|
id | String | Ano | Unikátní identifikátor addonu. Používá se interně pro ukládání stavu, credentials apod. Doporučený formát: kebab-case bez mezer a diakritiky (např. "webshare", "muj-addon"). |
name | String | Ano | Zobrazovaný název addonu v UI (např. "Webshare.cz"). |
version | String | Ne | Verze addonu ve formátu semver. Výchozí: "1.0.0". |
description | String | Ne | Krátký popis addonu. |
author | String | Ne | Jméno autora addonu. Výchozí: "Unknown". |
type | String | Ne | Typ addonu: "api", "scraper" nebo "hybrid". Výchozí: "api". Viz Addon Types. |
capabilities | Array<String> | Ne | Seznam schopností addonu. Výchozí: ["search"]. Viz Capabilities. |
homeUrl | String | Ne | URL domovské stránky služby. |
iconUrl | String | Ne | URL ikony addonu (zobrazuje se v UI). |
Pole id musí být napříč všemi addony unikátní. Pokud se pokusíte importovat addon se stejným id jako již nainstalovaný, import bude odmítnut.
Sekce auth
Definuje autentizační flow – tj. jaká pole uživatel vyplní a jaké kroky se provedou pro přihlášení, ověření stavu a odhlášení.
JSON{
"auth": {
"type": "credentials",
"fields": [
{
"key": "username",
"label": "Uživatelské jméno",
"hint": "Zadejte uživatelské jméno",
"isSecret": false,
"required": true
},
{
"key": "password",
"label": "Heslo",
"hint": "Zadejte heslo",
"isSecret": true,
"required": true
}
],
"login": [ ... ],
"check": [ ... ],
"logout": [ ... ]
}
}
Typy autentizace
Hodnota type | Popis |
|---|---|
"none" | Addon nevyžaduje přihlášení. Sekce auth může zcela chybět. |
"credentials" | Klasické přihlášení uživatelským jménem a heslem. |
"token" | Autentizace API tokenem / klíčem. |
"oauth" | OAuth2 flow (rezervováno pro budoucí použití). |
Definice polí (fields)
Pole definují formulář, který se zobrazí uživateli v nastavení. Klíč (key) se použije jako název proměnné – viz Proměnné.
| Pole | Typ | Povinný | Popis |
|---|---|---|---|
key | String | Ano | Unikátní klíč pole. Stane se názvem runtime proměnné (např. "username", "api_key"). |
label | String | Ano | Popisek zobrazený v UI. |
hint | String | Ne | Placeholder / nápověda v textovém poli. |
isSecret | Boolean | Ne | Zobrazit jako heslo (skryté znaky). Výchozí: false. |
required | Boolean | Ne | Je pole povinné? Výchozí: true. |
Login / Check / Logout pipelines
Každá z těchto sekcí je pole kroků (steps) – viz Akce.
| Pipeline | Kdy se spouští | Povinný |
|---|---|---|
login | Když uživatel vyplní credentials a potvrdí přihlášení. | Ne (ale bez něj se přihlášení nespustí) |
check | Když engine potřebuje ověřit, zda je session stále platná. | Ne (fallback: kontrola existence proměnné token) |
logout | Když se uživatel odhlásí. | Ne |
Pokud pipeline check není definován, engine jako fallback zkontroluje, zda existuje neprázdná runtime proměnná token. Proto je doporučeno, aby login kroky uložily token do proměnné s klíčem "token".
Sekce search
Definuje pipeline pro vyhledávání souborů. Výsledkem musí být seznam položek (viz Seznam výsledků).
JSON{
"search": {
"steps": [
{
"action": "http",
"method": "POST",
"url": "https://api.example.com/search",
"contentType": "application/x-www-form-urlencoded",
"body": "q={{query}}&limit=100&token={{token}}",
"responseType": "xml",
"listElement": "file",
"itemMapping": {
"title": "name",
"size": "size",
"link": "ident"
}
}
]
}
}
Search pipeline má přístup k těmto automaticky dostupným proměnným:
| Proměnná | Hodnota |
|---|---|
{{query}} | Hledaný text zadaný uživatelem. |
{{page}} | Číslo stránky (1-based) pro stránkování výsledků. |
{{token}} | Autentizační token (pokud addon vyžaduje auth). |
Item Mapping
Klíčový parametr HTTP kroku v search pipeline je itemMapping, který mapuje pole z odpovědi na interní strukturu:
| Cílové pole | Povinný | Popis |
|---|---|---|
title nebo name | Ano | Název souboru. Engine nejdřív hledá title, pak name. |
size | Ne | Velikost souboru v bajtech (celé číslo). Engine automaticky převede na čitelný formát (MB/GB). |
link nebo url | Ano | Unikátní identifikátor položky. Bude předán do streamUrl pipeline jako {{identifier}}. |
Sekce streamUrl
Definuje pipeline pro získání přímého streamovacího odkazu ze zvoleného souboru.
JSON{
"streamUrl": {
"steps": [
{
"action": "http",
"method": "POST",
"url": "https://api.example.com/file_link",
"contentType": "application/x-www-form-urlencoded",
"body": "ident={{identifier}}&token={{token}}",
"responseType": "xml",
"outputs": {
"stream_url": "link"
}
}
],
"result": "{{stream_url}}",
"headers": {
"Referer": "https://example.com/",
"User-Agent": "StreamujTo/1.0",
"Authorization": "Bearer {{token}}"
}
}
}
| Pole | Typ | Popis |
|---|---|---|
steps | Array<Step> | Pipeline kroků pro získání odkazu. |
result | String | Template s proměnnou, která obsahuje finální stream URL. Typicky "{{stream_url}}". |
headers | Object | Ne Extra HTTP hlavičky, které přehrávač pošle při streamování. Podporuje template proměnné. Typicky Referer, User-Agent, Cookie nebo Authorization. |
StreamUrl pipeline má automaticky k dispozici:
| Proměnná | Hodnota |
|---|---|
{{identifier}} | Identifikátor souboru ze search výsledků (hodnota z link/url v itemMapping). |
{{token}} | Autentizační token. |
Akce: http
Provede HTTP požadavek. Nejdůležitější a nejčastěji používaná akce.
JSON{
"action": "http",
"method": "POST",
"url": "https://api.example.com/endpoint",
"contentType": "application/x-www-form-urlencoded",
"body": "param1={{value1}}¶m2={{value2}}",
"responseType": "xml",
"headers": {
"Authorization": "Bearer {{token}}",
"X-Custom": "value"
},
"outputs": {
"moje_promenna": "xml_tag_name"
}
}
| Parametr | Typ | Výchozí | Popis |
|---|---|---|---|
action | String | — | Musí být "http". |
method | String | "GET" | HTTP metoda: "GET" nebo "POST". |
url | String | — | URL endpointu. Podporuje interpolaci. |
contentType | String | — | Hodnota hlavičky Content-Type. |
body | String | — | Tělo požadavku (pro POST). Podporuje interpolaci. |
responseType | String | "xml" | Formát odpovědi: "xml" nebo "json". Ovlivňuje parsování outputs. |
headers | Object | {} | Vlastní HTTP hlavičky. Hodnoty podporují interpolaci. |
outputs | Object | — | Mapování: { "nazev_promenne": "cesta_v_odpovedi" }. Viz XML / JSON parsing. |
listElement | String | — | Pouze v search: název elementu, který představuje jednu položku v seznamu. |
itemMapping | Object | — | Pouze v search: mapování polí položky. Viz Seznam výsledků. |
Pokud HTTP krok vrátí jiný status než 200, celá pipeline selže. Engine nepodporuje přesměrování ani jiné 2xx kódy.
Akce: md5crypt
Vypočítá Unix MD5-crypt hash (formát $1$salt$hash). Používá se typicky pro starší API, které vyžadují tento typ hashování hesel.
JSON{
"action": "md5crypt",
"input": "{{password}}",
"salt": "{{salt}}",
"output": "crypted_password"
}
| Parametr | Typ | Popis |
|---|---|---|
input | String | Vstupní text (typicky heslo). Podporuje interpolaci. |
salt | String | Salt pro hashování. Podporuje interpolaci. Max 8 znaků. |
output | String | Název proměnné, do které se uloží výsledný hash. |
Příklad výstupu: $1$abcdefgh$k4x3gHwmKj1vC0B.Xr5M/.
Akce: sha1
Vypočítá SHA-1 hash vstupního textu.
JSON{
"action": "sha1",
"input": "{{crypted_password}}",
"output": "hashed_password"
}
| Parametr | Typ | Popis |
|---|---|---|
input | String | Vstupní text. Podporuje interpolaci. |
output | String | Název proměnné pro hex-encoded výstup. |
Příklad výstupu: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Akce: md5
Vypočítá MD5 hash vstupního textu.
JSON{
"action": "md5",
"input": "{{some_value}}",
"output": "md5_hash"
}
| Parametr | Typ | Popis |
|---|---|---|
input | String | Vstupní text. Podporuje interpolaci. |
output | String | Název proměnné pro hex-encoded výstup. |
Příklad výstupu: 5d41402abc4b2a76b9719d911017c592
Akce: assert
Porovná hodnotu runtime proměnné s očekávanou hodnotou. Pokud se neshodují, pipeline selže a další kroky se neprovádí.
JSON{
"action": "assert",
"variable": "login_status",
"equals": "OK"
}
| Parametr | Typ | Popis |
|---|---|---|
variable | String | Název runtime proměnné k ověření. |
equals | String | Očekávaná hodnota. |
Assert je klíčový pro validaci odpovědí API. Umístěte ho bezprostředně za HTTP krok, abyste ověřili, že operace (přihlášení, vyhledávání) proběhla úspěšně.
Akce: clear
Odstraní runtime proměnné ze stavu enginu.
JSON{
"action": "clear",
"variables": ["token", "salt", "crypted_password", "temp_value"]
}
| Parametr | Typ | Popis |
|---|---|---|
variables | Array<String> | Seznam názvů proměnných k odstranění. |
Typicky se používá v logout pipeline pro vyčištění tokenů.
Akce: regex
Extrahuje text z hodnoty proměnné pomocí regulárního výrazu.
JSON{
"action": "regex",
"input": "{{_response}}",
"pattern": "href=\"(https://[^\"]+\\.mp4)\"",
"group": 1,
"output": "video_url"
}
| Parametr | Typ | Výchozí | Popis |
|---|---|---|---|
input | String | — | Vstupní text. Podporuje interpolaci. Typicky {{_response}}. |
pattern | String | — | Regulární výraz (Dart/PCRE syntaxe). |
group | Integer | 1 | Číslo zachytávací skupiny k extrakci. |
output | String | — | Název proměnné pro extrahovanou hodnotu. |
optional | Boolean | false | Pokud true, selhání kroku nezpůsobí selhání celého pipeline — pokračuje se dalším krokem. Viz Volitelné kroky. |
Pokud regex nenajde shodu a krok není označený jako "optional": true, pipeline selže. Ujistěte se, že vzor odpovídá formátu odpovědi, nebo použijte volitelné kroky s fallbackem.
Volitelné kroky (optional)
Jakýkoli krok v pipeline může být označen jako volitelný přidáním "optional": true. Pokud volitelný krok selže, pipeline pokračuje dalším krokem místo okamžitého ukončení.
U akce regex platí navíc: pokud je výstupní proměnná (output) již naplněná předchozím krokem, volitelný regex se přeskočí. To umožňuje řetězení fallbacků:
Příklad — fallback řetězení{
"steps": [
{ "action": "http", "method": "GET", "url": "https://api.example.com/{{identifier}}", "responseType": "json" },
{
"action": "regex",
"input": "{{_response}}",
"pattern": "\"name\":\\s*\"([^\"]+\\.mp4)\",\\s*\"source\":\\s*\"original\"",
"group": 1,
"output": "video_file",
"optional": true
},
{
"action": "regex",
"input": "{{_response}}",
"pattern": "\"name\":\\s*\"([^/\"]+\\.mp4)\"",
"group": 1,
"output": "video_file",
"optional": true
}
],
"result": "https://example.com/download/{{identifier}}/{{video_file|urlencode}}"
}
V tomto příkladě se nejprve hledá MP4 soubor s source: "original". Pokud není nalezen, druhý regex zkusí najít jakýkoli MP4. Pokud první regex uspěje, druhý se přeskočí (proměnná video_file je již nastavena).
Parametr optional lze použít u všech akcí (http, regex, assert, atd.), nejen u regex.
Akce: set
Přímo nastaví proměnnou na zadanou hodnotu. Užitečné pro sestavení složených hodnot z více proměnných nebo nastavení výchozí hodnoty.
JSON{
"action": "set",
"output": "full_url",
"value": "https://cdn.example.com/{{path}}/{{filename|urlencode}}"
}
| Parametr | Typ | Popis |
|---|---|---|
output | String | Název proměnné, do které se uloží výsledek. |
value | String | Hodnota (podporuje interpolaci a filtry). |
Akce: parallel
Spustí více nezávislých kroků současně. Všechny vnořené kroky běží paralelně a výsledek je úspěšný, pokud všechny uspějí.
JSON{
"action": "parallel",
"steps": [
{
"action": "http",
"method": "GET",
"url": "https://api.example.com/metadata/{{identifier}}",
"responseType": "json",
"outputs": { "meta_title": "title" }
},
{
"action": "http",
"method": "GET",
"url": "https://api.example.com/files/{{identifier}}",
"responseType": "json",
"outputs": { "file_url": "url" }
}
]
}
| Parametr | Typ | Popis |
|---|---|---|
steps | Array<Step> | Seznam kroků ke spuštění paralelně. Každý krok je standardní definice akce. |
Paralelní kroky by neměly záviset navzájem na svých výstupech. Pokud krok B potřebuje výstup kroku A, musí běžet sekvenčně (mimo parallel).
Proměnné
Addon Engine udržuje runtime slovník proměnných (Map<String, String>). Proměnné se plní z:
- Credentials – klíče z
auth.fields(např.username,password,api_key) - HTTP outputs – hodnoty extrahované z API odpovědí
- Crypto kroky – výstupy hashů (
md5crypt,sha1,md5) - Regex – extrahované podřetězce
- Automatické –
query,page,identifier
Interpolace {{proměnná}}
Kde je v parametrech textová hodnota, lze použít interpolaci dvojitými složenými závorkami:
Příklad"url": "https://api.example.com/search?q={{query}}&token={{token}}"
"body": "username={{username}}&password={{hashed_password}}"
"input": "{{crypted}}"
Engine nahradí každý výskyt {{nazev}} aktuální hodnotou ze slovníku proměnných. Pokud proměnná neexistuje, nahradí se prázdným řetězcem.
Filtry {{proměnná|filtr}}
Za název proměnné lze přidat filtr oddělený svislítkem (|), který transformuje hodnotu před vložením:
Příklad"url": "https://api.example.com/search?q={{query|urlencode}}"
"body": "token={{token|base64}}"
"header": "{{api_key|uppercase}}"
| Filtr | Popis | Příklad vstupu → výstupu |
|---|---|---|
urlencode | URL-enkódování (percent-encoding). Doporučeno pro {{query}} v URL. | Český film → %C4%8Cesk%C3%BD%20film |
base64 | Base64 enkódování. | hello → aGVsbG8= |
lowercase | Převod na malá písmena. | HELLO → hello |
uppercase | Převod na velká písmena. | hello → HELLO |
trim | Odstraň bílé znaky na začátku a konci. | hello → hello |
htmldecode | Dekoduje HTML entity. | & < → & < |
length | Délka řetězce (výstup je číslo). | hello → 5 |
reverse | Obrátí znaky v řetězci. | hello → olleh |
timestamp | Vrátí aktuální Unix timestamp v sekundách (ignoruje hodnotu proměnné). | → 1741700000 |
timestamp_ms | Vrátí aktuální Unix timestamp v milisekundách. | → 1741700000000 |
Pokud filtr není rozpoznán, hodnota se vloží bez transformace.
Speciální proměnné
| Proměnná | Automaticky dostupná | Popis |
|---|---|---|
_response | Po každém HTTP kroku | Celé tělo poslední HTTP odpovědi (raw text). Užitečné pro regex akci. |
_http_status | Po neúspěšném HTTP kroku | HTTP stavový kód posledního neúspěšného požadavku (např. 403, 500). Užitečné pro diagnostiku. |
query | V search pipeline | Text, který uživatel hledá. |
page | V search pipeline | Číslo stránky (1, 2, 3...). |
identifier | V streamUrl pipeline | Identifikátor vybraného souboru (z itemMapping link/url). |
token | Po login pipeline | Autentizační token. Doporučený název pro výstup z login kroků. |
{{timestamp}} | Vždy | Aktuální Unix timestamp v sekundách. Lze použít přímo bez proměnné. |
{{timestamp_ms}} | Vždy | Aktuální Unix timestamp v milisekundách. |
XML parsing
Při "responseType": "xml" engine extrahuje hodnoty pomocí názvů XML tagů.
XML odpověď<response>
<status>OK</status>
<token>abc123xyz</token>
<user_id>42</user_id>
</response>
outputs"outputs": {
"status_var": "status",
"token": "token",
"uid": "user_id"
}
Výsledek: status_var = "OK", token = "abc123xyz", uid = "42"
XML parser podporuje tagy s atributy – např. <file id="123">...</file> bude nalezeno při hledání tagu file. Pro extrakci atributů použijte notáci tag@attr v mappingu (viz níže).
Pro extrakci atributů z XML tagů použijte notáci tag@atribut:
XML s atributy<files>
<file id="abc123" type="video">Film.mp4</file>
<file id="def456" type="subtitle">Film.srt</file>
</files>
itemMapping"itemMapping": {
"title": "file",
"link": "file@id",
"type": "file@type"
}
Výsledek: link = "abc123", type = "video". Notáce @attr (bez tagu) extrahuje atribut z rodičovského elementu.
JSON parsing
Při "responseType": "json" engine používá tečkovou notaci pro navigaci v JSON struktuře.
JSON odpověď{
"status": "ok",
"data": {
"token": "xyz789",
"user": {
"id": 42,
"name": "Jan"
}
}
}
outputs"outputs": {
"my_token": "data.token",
"user_name": "data.user.name",
"user_id": "data.user.id"
}
Výsledek: my_token = "xyz789", user_name = "Jan", user_id = "42"
Pro přístup k prvkům pole použijte číselný index nebo hranatou notaci:
JSON cesta s polem"outputs": {
"first_item": "results[0].name",
"first_item_alt": "results.0.name"
}
Pro filtrování pole podle hodnoty klíče použijte [?(@.key=='value')]:
JSON cesta s filtrem"outputs": {
"video_file": "files[?(@.source=='original')].name"
}
Filtr projde pole files a vrátí první prvek, kde source je "original", pak z něj extrahuje name.
V itemMapping search kroků lze rovněž použít vnořené cesty: "title": "metadata.title" nebo "id": "files[0].id".
Seznam výsledků (List parsing)
Pro search pipeline musí HTTP krok s listElement identifikovat opakující se prvky v odpovědi:
XML seznam
XML odpověď<response>
<status>OK</status>
<file>
<name>Film.2024.CZ.mkv</name>
<size>1536000000</size>
<ident>abc123</ident>
</file>
<file>
<name>Film.2024.EN.mp4</name>
<size>987000000</size>
<ident>def456</ident>
</file>
</response>
Search krok{
"action": "http",
"method": "POST",
"url": "https://api.example.com/search",
"body": "q={{query}}&token={{token}}",
"responseType": "xml",
"listElement": "file",
"itemMapping": {
"title": "name",
"size": "size",
"link": "ident"
}
}
Engine najde všechny <file>...</file> bloky a z každého extrahuje name, size, ident podle mappingu.
JSON seznam
JSON odpověď{
"status": "ok",
"results": [
{ "title": "Film.2024.CZ.mkv", "filesize": 1536000000, "id": "abc123" },
{ "title": "Film.2024.EN.mp4", "filesize": 987000000, "id": "def456" }
]
}
Search krok{
"action": "http",
"method": "GET",
"url": "https://api.example.com/search?q={{query|urlencode}}",
"responseType": "json",
"listElement": "results",
"itemMapping": {
"title": "title",
"size": "filesize",
"link": "id"
}
}
listElement u JSON odpovědi je cesta (tečková notace) k poli objektů. U každého objektu se klíče z itemMapping použijí k nalezení příslušné hodnoty.
Příklad: Kompletní addon s autentizací
Ukázkový addon pro fiktivní službu „CloudStorage.cz" s plným auth flow (salt + md5crypt + sha1):
cloudstorage.json{
"manifest": {
"id": "cloudstorage",
"name": "CloudStorage.cz",
"version": "1.0.0",
"description": "Demo addon pro CloudStorage.cz.",
"author": "Komunita",
"type": "api",
"capabilities": ["search", "auth", "directStream"],
"homeUrl": "https://cloudstorage.cz"
},
"auth": {
"type": "credentials",
"fields": [
{
"key": "username",
"label": "Uživatelské jméno",
"hint": "Váš e-mail nebo přezdívka",
"isSecret": false,
"required": true
},
{
"key": "password",
"label": "Heslo",
"hint": "Zadejte heslo k účtu",
"isSecret": true,
"required": true
}
],
"login": [
{
"action": "http",
"method": "POST",
"url": "https://cloudstorage.cz/api/salt/",
"contentType": "application/x-www-form-urlencoded",
"body": "username={{username}}",
"responseType": "xml",
"outputs": {
"salt": "salt",
"salt_status": "status"
}
},
{
"action": "assert",
"variable": "salt_status",
"equals": "OK"
},
{
"action": "md5crypt",
"input": "{{password}}",
"salt": "{{salt}}",
"output": "crypted"
},
{
"action": "sha1",
"input": "{{crypted}}",
"output": "hashed_password"
},
{
"action": "http",
"method": "POST",
"url": "https://cloudstorage.cz/api/login/",
"contentType": "application/x-www-form-urlencoded",
"body": "username={{username}}&password={{hashed_password}}&keep_logged_in=1",
"responseType": "xml",
"outputs": {
"token": "token",
"login_status": "status"
}
},
{
"action": "assert",
"variable": "login_status",
"equals": "OK"
}
],
"check": [
{
"action": "http",
"method": "POST",
"url": "https://cloudstorage.cz/api/user_data/",
"contentType": "application/x-www-form-urlencoded",
"body": "token={{token}}",
"responseType": "xml",
"outputs": {
"check_status": "status"
}
},
{
"action": "assert",
"variable": "check_status",
"equals": "OK"
}
],
"logout": [
{
"action": "clear",
"variables": ["token", "salt", "crypted", "hashed_password"]
}
]
},
"search": {
"steps": [
{
"action": "http",
"method": "POST",
"url": "https://cloudstorage.cz/api/search/",
"contentType": "application/x-www-form-urlencoded",
"body": "what={{query}}&sort=largest&limit=100&category=video&token={{token}}",
"responseType": "xml",
"listElement": "file",
"itemMapping": {
"title": "name",
"size": "size",
"link": "ident"
}
}
]
},
"streamUrl": {
"steps": [
{
"action": "http",
"method": "POST",
"url": "https://cloudstorage.cz/api/file_link/",
"contentType": "application/x-www-form-urlencoded",
"body": "ident={{identifier}}&download_type=video_stream&token={{token}}",
"responseType": "xml",
"outputs": {
"stream_url": "link"
}
}
],
"result": "{{stream_url}}"
}
}
Příklad: Addon bez autentizace
Jednoduchý addon pro veřejné API, které nevyžaduje přihlášení:
public-api.json{
"manifest": {
"id": "public-videos",
"name": "Public Videos API",
"version": "1.0.0",
"description": "Veřejné API pro vyhledávání videí.",
"author": "Komunita",
"type": "api",
"capabilities": ["search", "directStream"]
},
"search": {
"steps": [
{
"action": "http",
"method": "GET",
"url": "https://public-api.example.com/videos?search={{query|urlencode}}&page={{page}}",
"responseType": "json",
"listElement": "data.videos",
"itemMapping": {
"title": "filename",
"size": "bytes",
"link": "video_id"
}
}
]
},
"streamUrl": {
"steps": [
{
"action": "http",
"method": "GET",
"url": "https://public-api.example.com/videos/{{identifier}}/stream",
"responseType": "json",
"outputs": {
"stream_url": "url"
}
}
],
"result": "{{stream_url}}"
}
}
Pokud addon nevyžaduje autentizaci, sekce auth může zcela chybět – nebo nastavte "type": "none".
Příklad: JSON API s vnořenou strukturou
Addon, který pracuje s REST JSON API a používá vnořené JSON cesty:
nested-json.json{
"manifest": {
"id": "nested-api",
"name": "Nested JSON API",
"version": "1.0.0",
"description": "Příklad práce s vnořeným JSON.",
"author": "Komunita",
"type": "api",
"capabilities": ["search", "auth", "directStream"]
},
"auth": {
"type": "token",
"fields": [
{
"key": "api_key",
"label": "API klíč",
"hint": "Vložte váš API klíč",
"isSecret": true,
"required": true
}
],
"login": [
{
"action": "http",
"method": "POST",
"url": "https://api.example.com/v2/auth",
"contentType": "application/json",
"body": "{\"api_key\": \"{{api_key}}\"}",
"responseType": "json",
"outputs": {
"token": "data.session.token",
"auth_status": "status"
}
},
{
"action": "assert",
"variable": "auth_status",
"equals": "ok"
}
]
},
"search": {
"steps": [
{
"action": "http",
"method": "GET",
"url": "https://api.example.com/v2/files?q={{query|urlencode}}&page={{page}}",
"responseType": "json",
"headers": {
"Authorization": "Bearer {{token}}"
},
"listElement": "data.files",
"itemMapping": {
"title": "name",
"size": "size_bytes",
"link": "file_id"
}
}
]
},
"streamUrl": {
"steps": [
{
"action": "http",
"method": "GET",
"url": "https://api.example.com/v2/files/{{identifier}}/download",
"responseType": "json",
"headers": {
"Authorization": "Bearer {{token}}"
},
"outputs": {
"stream_url": "data.download_url"
}
}
],
"result": "{{stream_url}}"
}
}
Příklad: Token-based auth s regexem
Addon, který extrahuje token z HTML odpovědi pomocí regexu:
scraper-addon.json{
"manifest": {
"id": "my-scraper",
"name": "My Scraper",
"version": "1.0.0",
"description": "Ukázkový scraper addon s regex extrakcí.",
"author": "Komunita",
"type": "scraper",
"capabilities": ["search", "auth", "directStream"]
},
"auth": {
"type": "credentials",
"fields": [
{
"key": "email",
"label": "E-mail",
"isSecret": false,
"required": true
},
{
"key": "password",
"label": "Heslo",
"isSecret": true,
"required": true
}
],
"login": [
{
"action": "http",
"method": "POST",
"url": "https://example.com/login",
"contentType": "application/x-www-form-urlencoded",
"body": "email={{email}}&password={{password}}",
"responseType": "xml"
},
{
"action": "regex",
"input": "{{_response}}",
"pattern": "session_token[\"']?\\s*[:=]\\s*[\"']([a-f0-9]{32})[\"']",
"group": 1,
"output": "token"
}
]
},
"search": {
"steps": [
{
"action": "http",
"method": "GET",
"url": "https://example.com/search?q={{query|urlencode}}",
"responseType": "xml",
"headers": {
"Cookie": "session={{token}}"
}
},
{
"action": "regex",
"input": "{{_response}}",
"pattern": "data-results='(\\[.*?\\])'",
"group": 1,
"output": "json_results"
},
{
"action": "http",
"method": "GET",
"url": "https://example.com/api/parse-results",
"responseType": "json",
"headers": {
"X-Data": "{{json_results}}"
},
"listElement": "items",
"itemMapping": {
"title": "name",
"size": "size",
"link": "url"
}
}
]
},
"streamUrl": {
"steps": [
{
"action": "http",
"method": "GET",
"url": "{{identifier}}",
"responseType": "xml",
"headers": {
"Cookie": "session={{token}}"
}
},
{
"action": "regex",
"input": "{{_response}}",
"pattern": "source\\s+src=[\"'](https://[^\"']+\\.mp4)[\"']",
"group": 1,
"output": "stream_url"
}
],
"result": "{{stream_url}}"
}
}
Capabilities (schopnosti)
| Hodnota | Popis |
|---|---|
"search" | Addon umí vyhledávat soubory. Povinné – každý addon musí umět vyhledávat. |
"auth" | Addon vyžaduje autentizaci (přihlášení). |
"directStream" | Addon poskytuje přímé streamovací odkazy (ne redirect). |
"subtitles" | Addon podporuje titulky (rezervováno pro budoucí použití). |
"download" | Addon podporuje stahování souborů (rezervováno pro budoucí použití). |
Addon Types (typy)
| Hodnota | Popis |
|---|---|
"api" | Data jsou získávána přes strukturované API (REST, XML-RPC, GraphQL...). |
"scraper" | Data jsou získávána parsováním HTML stránek (pomocí regexu). |
"hybrid" | Kombinace obojího – některé endpointy jsou API, některé vyžadují scraping. |
Typ addonu je informativní metadata – nemá vliv na chování enginu. Engine vykonává kroky stejně bez ohledu na typ.
Chybové stavy
Engine může selhat v několika situacích:
| Situace | Co se stane |
|---|---|
| HTTP krok vrátí jiný status než 200 | Pipeline se zastaví, krok vrátí false. |
| Assert selže (hodnota != expected) | Pipeline se zastaví, celý flow vrátí false. |
| Regex nenajde shodu | Pipeline se zastaví, krok vrátí false. |
| Neznámá akce | Pipeline se zastaví, vypíše se warning do konzole. |
| Timeout HTTP požadavku | Engine zachytí výjimku, krok vrátí false. |
| Neplatný JSON soubor | Import selže, zobrazí se chybová hláška. |
| Duplicitní addon ID | Import je odmítnut s upozorněním. |
Omezení a limity
- Pouze HTTP GET a POST – jiné metody (PUT, DELETE, PATCH) nejsou podporovány.
- Žádný JavaScript – addon nemůže spouštět JS kód (na rozdíl od browser pluginů).
- XML jmenné prostory – parser podporuje tagy s atributy, ale nepodporuje XML namespaces (např.
ns:tag). - JSONPath bez wildcards – nelze použít
data.*.name. Podporovány jsou indexy[0]a filtry[?(@.key=='val')]. - MD5-crypt salt max 8 znaků – delší salty jsou oříznuty.
- Žádné cookies – engine automaticky nespravuje cookies. Tokeny je nutné předávat explicitně.
- Žádné přesměrování – HTTP klient nesleduje 3xx redirecty automaticky v kontextu parsování odpovědí.
- Proměnné jsou string only – všechny runtime hodnoty jsou řetězce, žádné číselné operace.
- Jedna search stránka = jeden HTTP krok s listElement – nelze kombinovat výsledky z více volání v jedné pipeline (ale lze použít
parallelpro nezávislá volání).
Právní upozornění
Aplikace StreamujTo neobsahuje žádný obsah ani přístup k jakémukoli úložišti. Veškerá funkcionalita úložišť je zajištěna výhradně doplňky, které si uživatel importuje na vlastní odpovědnost. Vývojář aplikace neposkytuje, neschvaluje ani nekontroluje žádné doplňky.
Instalací jakéhokoli doplňku přebíráte plnou odpovědnost za jeho použití. Ujistěte se, že dodržujete platné zákony vaší země, zejména v oblasti autorských práv. Vývojář nenese žádnou zodpovědnost za obsah zpřístupněný prostřednictvím doplňků třetích stran.