WebUI: Rework torrent export to use archive format (zip)

This commit is contained in:
Faris Mektem 2025-05-04 13:50:42 +01:00
commit 69c0a56073
5 changed files with 77 additions and 8 deletions

View file

@ -26,6 +26,7 @@
<script defer src="scripts/lib/MooTools-Core-1.6.0-compat-compressed.js"></script> <script defer src="scripts/lib/MooTools-Core-1.6.0-compat-compressed.js"></script>
<script defer src="scripts/lib/MooTools-More-1.6.0-compat-compressed.js"></script> <script defer src="scripts/lib/MooTools-More-1.6.0-compat-compressed.js"></script>
<script defer src="scripts/lib/mocha.min.js"></script> <script defer src="scripts/lib/mocha.min.js"></script>
<script defer src="scripts/lib/jszip.min.js"></script>
<script defer src="scripts/cache.js?v=${CACHEID}"></script> <script defer src="scripts/cache.js?v=${CACHEID}"></script>
<script defer src="scripts/localpreferences.js?v=${CACHEID}"></script> <script defer src="scripts/localpreferences.js?v=${CACHEID}"></script>
<script defer src="scripts/color-scheme.js?v=${CACHEID}"></script> <script defer src="scripts/color-scheme.js?v=${CACHEID}"></script>

File diff suppressed because one or more lines are too long

View file

@ -46,6 +46,7 @@ window.qBittorrent.Misc ??= (() => {
containsAllTerms: containsAllTerms, containsAllTerms: containsAllTerms,
sleep: sleep, sleep: sleep,
downloadFile: downloadFile, downloadFile: downloadFile,
downloadBlob: downloadBlob,
// variables // variables
FILTER_INPUT_DELAY: 400, FILTER_INPUT_DELAY: 400,
MAX_ETA: 8640000 MAX_ETA: 8640000
@ -291,6 +292,15 @@ window.qBittorrent.Misc ??= (() => {
fileName = fileName.slice(1, -1); fileName = fileName.slice(1, -1);
} }
downloadBlob(blob, fileName, errorMessage);
}
catch (error) {
alert(errorMessage);
}
};
const downloadBlob = async (blob, fileName, errorMessage = "QBT_TR(Unable to download file)QBT_TR[CONTEXT=HttpServer]") => {
try {
const link = document.createElement("a"); const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob); link.href = window.URL.createObjectURL(blob);
link.download = fileName; link.download = fileName;

View file

@ -1187,22 +1187,66 @@ const initializeWindows = () => {
exportTorrentFN = async () => { exportTorrentFN = async () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
for (const hash of hashes) {
if (hashes.length === 0)
return;
if (hashes.length === 1) {
// Single file - direct download
const hash = hashes[0];
const row = torrentsTable.getRow(hash); const row = torrentsTable.getRow(hash);
if (!row) if (!row)
continue; return;
const name = row.full_data.name; const name = row.full_data.name;
const url = new URL("api/v2/torrents/export", window.location); const url = new URL("api/v2/torrents/export", window.location);
url.search = new URLSearchParams({ url.search = new URLSearchParams({ hash });
hash: hash
await window.qBittorrent.Misc.downloadFile(url, `${name}.torrent`, "QBT_TR(Unable to export torrent file)QBT_TR[CONTEXT=MainWindow]");
}
if (hashes.length > 1) {
// Multi-file - distributed in a zip
const zip = new JSZip();
const fetchTorrents = hashes.map(async (hash) => {
const row = torrentsTable.getRow(hash);
if (!row)
return true;
const url = new URL("api/v2/torrents/export", window.location);
url.search = new URLSearchParams({ hash });
try {
const response = await fetch(url, {
method: "GET",
cache: "no-store",
});
if (!response.ok)
throw new Error();
const name = row.full_data.name;
const blob = await response.blob();
zip.file(`${name}.torrent`, blob);
return false;
}
catch (error) {
return true;
}
}); });
// download response to file // Wait for all fetches to finish
await window.qBittorrent.Misc.downloadFile(url, `${name}.torrent`, "QBT_TR(Unable to export torrent file)QBT_TR[CONTEXT=MainWindow]"); const result = await Promise.all(fetchTorrents);
// https://stackoverflow.com/questions/53560991/automatic-file-downloads-limited-to-10-files-on-chrome-browser if (result.includes(true))
await window.qBittorrent.Misc.sleep(200); alert("QBT_TR(Unable to export torrent file)QBT_TR[CONTEXT=MainWindow]");
const content = await zip.generateAsync({ type: "blob" });
// Set output zip file date and time
const timestamp = new Date();
const zipFilename = `torrents_export_${timestamp.toString().split(" ").slice(1, 5).join("_").replace(/:/g, "_")}.zip`;
// Use qBittorrent's internal downloadBlob function
window.qBittorrent.Misc.downloadBlob(content, zipFilename);
} }
}; };

View file

@ -401,6 +401,7 @@
<file>private/scripts/file-tree.js</file> <file>private/scripts/file-tree.js</file>
<file>private/scripts/filesystem.js</file> <file>private/scripts/filesystem.js</file>
<file>private/scripts/lib/clipboard.min.js</file> <file>private/scripts/lib/clipboard.min.js</file>
<file>private/scripts/lib/jszip.min.js</file>
<file>private/scripts/lib/mocha.min.js</file> <file>private/scripts/lib/mocha.min.js</file>
<file>private/scripts/lib/MooTools-Core-1.6.0-compat-compressed.js</file> <file>private/scripts/lib/MooTools-Core-1.6.0-compat-compressed.js</file>
<file>private/scripts/lib/MooTools-More-1.6.0-compat-compressed.js</file> <file>private/scripts/lib/MooTools-More-1.6.0-compat-compressed.js</file>