Skip to content

Instantly share code, notes, and snippets.

@moekhalil
Last active July 15, 2020 07:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moekhalil/87776121845801f6e0b4dfde788c9183 to your computer and use it in GitHub Desktop.
Save moekhalil/87776121845801f6e0b4dfde788c9183 to your computer and use it in GitHub Desktop.
// Direcory Listing Downloader - "Index Of/" Downloader
// Moe Khalil - me@mkhalil.org
// This is to download files located in directories with directory list permissions enabled
// set MINIMUM_SIZE to filter smaller files.
// File names will be what they are on server with date prepended and host domain appended.
(() => {
// minimum file-size to download
const MINIMUM_SIZE = '800K';
const bytesLUT = { K: 10**3, M: 10**6, G: 10**9, T: 10**12 };
const toBytes = x => parseInt(x.match(/[0-9.]*/)[0], 10) * bytesLUT[x.substr(-1)];
const minimumBytes = toBytes(MINIMUM_SIZE);
// filename-prefix: en-CA => 12-31-2020. this => 12.31.2020
const prefix = new Date().toLocaleDateString('en-CA').replace(/-/g, '.');
const suffix = `[${window.location.host}]`;
// filename
const namer = (x) => {
const ogName = x.href.split(/\//).pop();
const [name, extension] = [ogName.slice(0, ogName.lastIndexOf('.')), ogName.slice(ogName.lastIndexOf('.'))];
return `${prefix}-${name}-${suffix}${extension}`;
}
// to download based on size in table and MINIMUM_SIZE
// the seemingly FRAGILE Dom navigation navigates to the size column of the table
const toDownload = (x) => {
const fileSize = x.parentElement.nextSibling.nextSibling.textContent;
const fileSizeInBytes = toBytes(fileSize);
return toBytes(fileSize) >= minimumBytes;
};
const downloader = (file, k) => {
if (!toDownload(file)) { return; }
file.download = namer(file);
globalThis.setTimeout(() => file.click(), k * 100);
}
document.querySelectorAll('table td a').forEach(downloader);
// For non-standard "/index of" pages
// Make sure the next sibling of the anchor tag includes file size.
/*
const FILTER = "filename-includes-this";
Array.from(
document.querySelectorAll('a')
).filter(i =>
i.text.toLowerCase().includes(FILTER) &&
i.nextSibling.textContent.match('[0-9]*k') >= MINIMUM_SIZE
).forEach((file, k) => {
file.download = namer(file);
globalThis.setTimeout(() => file.click(), k * 100);
});
*/
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment