Skip to content

Commit

Permalink
Issue #938: added hack for mirrobrain magnet URIs
Browse files Browse the repository at this point in the history
  • Loading branch information
rgaudin committed Oct 2, 2023
1 parent e13324f commit 07931db
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions static/skin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,63 @@
}
}

/* 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 = [];
try {
const metalink = await fetch(`${zimUrl}.meta4`).then(response => {
return response.ok ? response.text() : '';
}).catch((_error) => '');
if (metalink) {
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 retrieve 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

magnetLink = 'magnet:?';
// we don't want params.ToString()'s urlencoding
for (const [key, value] of params.entries()) {
magnetLink += `&${key}=${value}`;
}
return magnetLink;
}

async function getMagnetLink(downloadLink) {
const magnetUrl = downloadLink + '.magnet';
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
const magnetLink = await fetch(magnetUrl, { signal: controller.signal }).then(response => {
return response.ok ? response.text() : '';
}).catch((_error) => '');
if (magnetLink) {
return await getFixedMirrorbrainMagnet(magnetLink);
}
return magnetLink;
}

Expand Down

0 comments on commit 07931db

Please sign in to comment.