Skip to content

Instantly share code, notes, and snippets.

@Digital39999
Created October 2, 2022 17:13
Show Gist options
  • Save Digital39999/64e3fd8124d22abb12c0b6237036d3a7 to your computer and use it in GitHub Desktop.
Save Digital39999/64e3fd8124d22abb12c0b6237036d3a7 to your computer and use it in GitHub Desktop.
const https = require(`node:https`);
const fs = require(`node:fs`);
const config = {
token: ``,
fetchAll: true, // Fetch all files or just specific number
downloadFromDomain: null, // null or cdn.something.com
sortByMonth: true // would you like sort files by month
};
main();
async function main() {
if (!config.token) return console.log(`No token provided.`);
else console.log(`\x1b[35m\x1b[1m` + `Starting to fetch files.` + `\x1b[0m` + `\n`);
const totalUploads = await getTotalUploads(config.fetchAll);
if (!totalUploads) return console.log(`\x1b[31m\x1b[1m` + `Failed to fetch uploads.` + `\x1b[0m`);
const allFiles = await getAllFiles(totalUploads);
if (!allFiles) return console.log(`\x1b[31m\x1b[1m` + `Failed to fetch files.` + `\x1b[0m`);
if (config.downloadFromDomain) {
const files = allFiles.filter(file => file.domain == config.downloadFromDomain);
if (!files.length) return console.log(`\x1b[31m\x1b[1m` + `No files found on domain ${config.downloadFromDomain}.` + `\x1b[0m`);
else allfiles = files;
};
const chunks = allFiles.reduce((resultArray, item, index) => {
const chunkIndex = Math.floor(index / 1024);
if (!resultArray[chunkIndex]) resultArray[chunkIndex] = [];
resultArray[chunkIndex].push(item);
return resultArray;
}, []);
let downloadedFiles = 0;
for await (const chunk of chunks) downloadedFiles += await downloadFiles(chunk);
console.log(`\n` + `\x1b[35m\x1b[1m` + `Finished downloading ${downloadedFiles} files.` + `\x1b[0m`);
};
async function getTotalUploads(number) {
if (typeof number == `number`) return number;
const res = await fetch(`https://api.tixte.com/v1/users/@me/uploads`, {
method: `GET`,
headers: {
Authorization: config.token
}
}).then(res => res.json()).catch(() => null);
return res?.data?.total;
};
async function getAllFiles(totalUploads) {
const pages = totalUploads > 150 ? Math.ceil(totalUploads / 150) : 1;
const files = []; let uploadsLeft = totalUploads;
for (let i = 0; i < pages; i++) {
const amount = uploadsLeft > 150 ? 150 : uploadsLeft; uploadsLeft -= amount;
const res = await fetch(`https://api.tixte.com/v1/users/@me/uploads?page=${i}&amount=${amount}&permission_levels=[3]`, {
method: `GET`,
headers: {
Authorization: config.token
}
}).then(res => res.json()).catch(() => null);
files.push(...res?.data?.uploads); console.log(`\x1b[34m\x1b[1m` + `Added page ${(i + 1)} of ${pages} (${files.length} files).` + `\x1b[0m`);
};
return files;
};
async function downloadFiles(files) {
if (!fs.existsSync(`./files`)) fs.mkdirSync(`./files`);
let yes = 0, no = 0, alr = 0, i = 0, erCheck = false;
for await (const fileObject of files) {
const month = fileObject.uploaded_at.split('-')?.[1]; i++;
if (config.sortByMonth && !fs.existsSync(`./files/${month}`)) fs.mkdirSync(`./files/${month}`);
if (fs.existsSync(config.sortByMonth ? `./files/${month}/${fileObject.name}.${fileObject.extension}` : `./files/${fileObject.name}.${fileObject.extension}`)) {
console.log(`\x1b[33m\x1b[1m` + `File ${fileObject.name}.${fileObject.extension} already exists.` + `\x1b[0m`); alr++;
} else {
let file = config.sortByMonth ? fs.createWriteStream(`./files/${month}/${fileObject.name}.${fileObject.extension}`) : fs.createWriteStream(`./files/${fileObject.name}.${fileObject.extension}`);
let request = await https.get(`https://us-east-1.tixte.net/uploads/${fileObject.domain}/${fileObject.name}.${fileObject.extension}`, (response) => {
response.pipe(file);
file.on(`finish`, () => {
file.close((aaa) => { if (aaa) erCheck = true; }); console.log(`\x1b[32m\x1b[1m` + `Downloaded ${fileObject.name}.${fileObject.extension}.` + `\x1b[0m`); yes++;
});
}).on(`error`, (err) => {
fs.unlink(config.sortByMonth ? `./files/${month}/${fileObject.name}.${fileObject.extension}` : `./files/${fileObject.name}.${fileObject.extension}`, (aaa) => { if (aaa) erCheck = true; });
if (erCheck == true) console.log(`\x1b[31m\x1b[1m` + `Error downloading ${fileObject.name}.${fileObject.extension}` + `\x1b[0m`); no++;
});
};
};
return new Promise((resolve, reject) => {
let interval = setInterval(() => {
if (yes + no + alr == files?.length) {
clearInterval(interval); return resolve(yes);
};
}, 1000);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment