Initial commit: webshare-api

Torznab + fake qBittorrent proxy for Webshare.cz, with Compose/Docker
packaging, MIT license, and tests.
This commit is contained in:
2026-08-07 08:37:10 +02:00
commit 3fcadfe973
19 changed files with 2047 additions and 0 deletions

58
src/torznab.js Normal file
View File

@@ -0,0 +1,58 @@
function escapeXml(s) {
return String(s)
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
function caps() {
return `<?xml version="1.0" encoding="UTF-8"?>
<caps>
<server version="1.0" title="Webshare" strapline="Webshare.cz" url="https://webshare.cz"/>
<limits max="100" default="25"/>
<registration available="no" open="no"/>
<searching>
<search available="yes" supportedParams="q"/>
<tv-search available="yes" supportedParams="q,season,ep"/>
<movie-search available="yes" supportedParams="q"/>
<music-search available="no" supportedParams=""/>
<book-search available="no" supportedParams=""/>
</searching>
<categories>
<category id="2000" name="Movies"/>
<category id="5000" name="TV"/>
<category id="5040" name="TV/HD"/>
<category id="5030" name="TV/SD"/>
</categories>
</caps>`;
}
function feed(items, baseUrl) {
const pubDate = new Date().toUTCString();
const itemsXml = items.map(item => ` <item>
<title>${escapeXml(item.name)}</title>
<guid isPermaLink="false">${escapeXml(item.ident)}</guid>
<pubDate>${pubDate}</pubDate>
<category>5040</category>
<enclosure url="${escapeXml(baseUrl + '/download/' + item.ident)}" length="${item.size}" type="application/x-bittorrent"/>
<torznab:attr name="category" value="5040"/>
<torznab:attr name="size" value="${item.size}"/>
<torznab:attr name="seeders" value="1"/>
<torznab:attr name="peers" value="1"/>
<torznab:attr name="downloadvolumefactor" value="0"/>
<torznab:attr name="uploadvolumefactor" value="1"/>
</item>`).join('\n');
return `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:torznab="http://torznab.com/schemas/2015/feed">
<channel>
<title>Webshare</title>
<description>Webshare.cz API (Torznab façade)</description>
<link>https://webshare.cz</link>
${itemsXml}
</channel>
</rss>`;
}
module.exports = { caps, feed };