mirror of https://github.com/kiwix/libkiwix.git
Merge pull request #1001 from kiwix/magnet
This commit is contained in:
commit
4425cd2122
|
@ -197,6 +197,58 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeURLSearchString(params, keysToURIEncode) {
|
||||||
|
let output = '';
|
||||||
|
for (const [key, value] of params.entries()) {
|
||||||
|
let finalValue = (keysToURIEncode.indexOf(key) >= 0) ? encodeURIComponent(value) : value;
|
||||||
|
output += `&${key}=${finalValue}`;
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hack for library.kiwix.org magnet links (created by MirrorBrain)
|
||||||
|
See https://github.com/kiwix/container-images/issues/242 */
|
||||||
|
async function getFixedMirrorbrainMagnet(magnetLink) {
|
||||||
|
// parse as query parameters
|
||||||
|
const params = new URLSearchParams(
|
||||||
|
magnetLink.replaceAll('&', '&').replace(/^magnet:/, ''));
|
||||||
|
|
||||||
|
const zimUrl = params.get('as'); // as= is fallback URL
|
||||||
|
// download metalink to build list of mirrored URLs
|
||||||
|
let mirrorUrls = [];
|
||||||
|
|
||||||
|
const metalink = await fetch(`${zimUrl}.meta4`).then(response => {
|
||||||
|
return response.ok ? response.text() : '';
|
||||||
|
}).catch((_error) => '');
|
||||||
|
if (metalink) {
|
||||||
|
try {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(metalink, "application/xml");
|
||||||
|
doc.querySelectorAll("url").forEach((node) => {
|
||||||
|
if (node.hasAttribute("priority")) { // ensures its a mirror link
|
||||||
|
mirrorUrls.push(node.innerHTML);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
// not a big deal, magnet will only contain primary URL
|
||||||
|
console.debug(`Failed to parse mirror links for ${zimUrl}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set webseed (ws=) URL to primary download URL (redirects to mirror)
|
||||||
|
params.set('ws', zimUrl);
|
||||||
|
// if we got metalink mirror URLs, append them all
|
||||||
|
if (mirrorUrls) {
|
||||||
|
mirrorUrls.forEach((url) => {
|
||||||
|
params.append('ws', url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
params.set('xs', `${zimUrl}.torrent`); // adding xs= to point to torrent URL
|
||||||
|
|
||||||
|
return 'magnet:?' + makeURLSearchString(params, ['ws', 'as', 'dn', 'xs', 'tr']);
|
||||||
|
}
|
||||||
|
|
||||||
async function getMagnetLink(downloadLink) {
|
async function getMagnetLink(downloadLink) {
|
||||||
const magnetUrl = downloadLink + '.magnet';
|
const magnetUrl = downloadLink + '.magnet';
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
|
@ -204,6 +256,9 @@
|
||||||
const magnetLink = await fetch(magnetUrl, { signal: controller.signal }).then(response => {
|
const magnetLink = await fetch(magnetUrl, { signal: controller.signal }).then(response => {
|
||||||
return response.ok ? response.text() : '';
|
return response.ok ? response.text() : '';
|
||||||
}).catch((_error) => '');
|
}).catch((_error) => '');
|
||||||
|
if (magnetLink) {
|
||||||
|
return await getFixedMirrorbrainMagnet(magnetLink);
|
||||||
|
}
|
||||||
return magnetLink;
|
return magnetLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ const ResourceCollection resources200Compressible{
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.css" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.css" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.css?cacheid=e4d76d16" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.css?cacheid=e4d76d16" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.js" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.js" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=e1b1ae55" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=ce19da2a" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js" },
|
||||||
|
@ -288,7 +288,7 @@ R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/index.css?cacheid=e4d76d16"
|
||||||
<script type="text/javascript" src="/ROOT%23%3F/skin/languages.js?cacheid=648526e1" defer></script>
|
<script type="text/javascript" src="/ROOT%23%3F/skin/languages.js?cacheid=648526e1" defer></script>
|
||||||
<script src="/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" defer></script>
|
<script src="/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" defer></script>
|
||||||
<script src="/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3"></script>
|
<script src="/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3"></script>
|
||||||
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=e1b1ae55" defer></script>
|
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=ce19da2a" defer></script>
|
||||||
<img src="/ROOT%23%3F/skin/feed.svg?cacheid=055b333f"
|
<img src="/ROOT%23%3F/skin/feed.svg?cacheid=055b333f"
|
||||||
<img src="/ROOT%23%3F/skin/langSelector.svg?cacheid=00b59961"
|
<img src="/ROOT%23%3F/skin/langSelector.svg?cacheid=00b59961"
|
||||||
)EXPECTEDRESULT"
|
)EXPECTEDRESULT"
|
||||||
|
|
Loading…
Reference in New Issue