Skip to content

Instantly share code, notes, and snippets.

@duanemoody
Last active November 2, 2022 20:06
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 duanemoody/2956d7ca8b73de777dbfdd5d20b0a4d1 to your computer and use it in GitHub Desktop.
Save duanemoody/2956d7ca8b73de777dbfdd5d20b0a4d1 to your computer and use it in GitHub Desktop.
Refactoring a thread image downloader bookmarklet to use 4chan's API instead of requiring 4chanX
/* Initialize this thread's variables */
let tp = window.location.pathname.split('/'),
board = tp[1],
threadNum = tp[3],
jsonurl = `https://a.4cdn.org/${board}/thread/${threadNum}.json`,
imho = `https://i.4cdn.org/${board}`,
images = [];
/* Get board JSON, populate images array */
await fetch(jsonurl)
.then((response) => response.json())
.then((data) => {
for (post of data['posts']) {
(typeof post['tim'] != 'undefined') && images.push({
url: `${imho}/${post['tim']}${post['ext']}`,
filename: `${post['filename']}${post['ext']}`
});
}
});
/* await fetch(jsonurl)
.then((response) => response.json())
.then((data) => Object.keys(data['posts']).filter(([key]) => (key=='tim')));
*/
console.log(images);
function sleep(ms) {
return new Promise(resolve => setInterval(resolve, ms));
}
/* retrieve files from images one second apart and download them using the original filenames */
// not having a fun time getting the function to actually wait instead of repeating the same download X number of times where X is the number of images
async function downloadImage(imageSrc, imageFilename) {
let image = await fetch(imageSrc),
imageBlob = await image.blob(),
imageURL = URL.createObjectURL(imageBlob),
link = document.createElement('a');
link.href = imageURL;
link.download = imageFilename;
sleep(2000).then(() => {document.body.appendChild(link); link.click(); document.body.removeChild(link);});
}
for (img of images) {
sleep(2000).then(() => {
console.log(img['url'], img['filename']);
downloadImage(img['url'], img['filename']);
});
}
//let p=document.querySelectorAll("a.download-button"), i=0,
//v=setInterval(() => {p[i++].click(); (i>p.length) && clearInterval(v);}, 1000);
@duanemoody
Copy link
Author

Hardest part is remembering how to ensure a 1 second pause between downloads so that it doesn't hit 4chan's throttling and also so that it doesn't repeatedly download the first image in the array

@duanemoody
Copy link
Author

The 'tim' key is the timestamp that only appears in posts with attachments; remove loop iteration checking each post for it to pack images, and try instead to use native object filters to reduce the JSON object to only posts with the 'tim' key in them. Still learning the syntax here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment