From b8f7bbcd575af0b16779e1f690e3606b98b2584c Mon Sep 17 00:00:00 2001 From: Adam Argyle Date: Thu, 3 Dec 2020 08:36:30 -0800 Subject: [PATCH 1/4] works but only with pngs --- app/plugins/_registry.js | 3 +++ app/plugins/download-images.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 app/plugins/download-images.js diff --git a/app/plugins/_registry.js b/app/plugins/_registry.js index 6caed334..c281970b 100644 --- a/app/plugins/_registry.js +++ b/app/plugins/_registry.js @@ -11,6 +11,7 @@ import { commands as tota11y_commands, default as Tota11yPlugin } from './tota11 import { commands as shuffle_commands, default as ShufflePlugin } from './shuffle' import { commands as colorblind_commands, default as ColorblindPlugin } from './colorblind' import { commands as zindex_commands, default as ZIndexPlugin } from './zindex' +import { commands as dl_images_commands, default as DlImagesPlugin } from './download-images' const commandsToHash = (plugin_commands, plugin_fn) => plugin_commands.reduce((commands, command) => @@ -31,6 +32,7 @@ export const PluginRegistry = new Map(Object.entries({ ...commandsToHash(shuffle_commands, ShufflePlugin), ...commandsToHash(colorblind_commands, ColorblindPlugin), ...commandsToHash(zindex_commands, ZIndexPlugin), + ...commandsToHash(dl_images_commands, DlImagesPlugin), })) export const PluginHints = [ @@ -46,5 +48,6 @@ export const PluginHints = [ tota11y_commands[0], shuffle_commands[0], zindex_commands[0], + dl_images_commands[0], ...colorblind_commands, ].map(command => `/${command}`) diff --git a/app/plugins/download-images.js b/app/plugins/download-images.js new file mode 100644 index 00000000..6d64ded8 --- /dev/null +++ b/app/plugins/download-images.js @@ -0,0 +1,29 @@ +export const commands = [ + 'download-images', + 'download-all-images', +] + +export default async function() { + const dirHandle = await window.showDirectoryPicker() + const imgs = document.querySelectorAll("img") + let i = 0 + + imgs.forEach(async (img) => { + const url = img.src + const name = `img-${i}.png` + i++ + + try { + console.log(`Fetching ${url}`) + const response = await fetch(url) + + console.log(`Saving to ${name}`) + + const file = await dirHandle.getFileHandle(name, { create: true }) + const writable = await file.createWritable() + await response.body.pipeTo(writable) + } catch (err) { + console.error(err) + } + }) +} From 8802da1f867a9ce09a6fc021b512f66d9a027bf7 Mon Sep 17 00:00:00 2001 From: aashu0148 <71861291+aashu0148@users.noreply.github.com> Date: Tue, 5 Jan 2021 00:09:15 +0530 Subject: [PATCH 2/4] All urls will have a name (#492) --- app/plugins/download-images.js | 50 ++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/app/plugins/download-images.js b/app/plugins/download-images.js index 6d64ded8..56de7139 100644 --- a/app/plugins/download-images.js +++ b/app/plugins/download-images.js @@ -3,22 +3,56 @@ export const commands = [ 'download-all-images', ] -export default async function() { +export default async function () { + if (window.showDirectoryPicker === undefined) { + console.log('no directory support :(') + return; + } const dirHandle = await window.showDirectoryPicker() const imgs = document.querySelectorAll("img") - let i = 0 imgs.forEach(async (img) => { const url = img.src - const name = `img-${i}.png` - i++ - + const name = url.substr(url.lastIndexOf('/') + 1); try { - console.log(`Fetching ${url}`) const response = await fetch(url) + const file = await dirHandle.getFileHandle(name, { create: true }) + const writable = await file.createWritable() + await response.body.pipeTo(writable) + } catch (err) { + console.error(err) + } + }) + // CSS urls + let css_urls = [...document.styleSheets] + .filter(sheet => { + try { return sheet.cssRules } + catch { } + }) + .flatMap(sheet => Array.from(sheet.cssRules)) + .filter(rule => rule.style) + .filter(rule => rule.style.backgroundImage !== '') + .filter(rule => rule.style.backgroundImage !== 'initial') + .filter(rule => rule.style.backgroundImage.includes("url")) + .reduce((urls, { style }) => { + urls.push(style.backgroundImage); + return urls; + }, []); - console.log(`Saving to ${name}`) - + css_urls.forEach(async (item, i) => { + let cots = false; + let start = item.indexOf('('); + if (item.charAt(start + 1) == '"') cots = true; + let end = item.lastIndexOf(')'); + if (cots) { + start += 2; + end -= 6; + } + const url = item.substr(start, end); + const truncated = url.substr(0, url.indexOf("?")); + const name = truncated.slice(truncated.lastIndexOf("/") + 1, truncated.lastIndexOf("/") + 39) + ".jpg" + try { + const response = await fetch(url) const file = await dirHandle.getFileHandle(name, { create: true }) const writable = await file.createWritable() await response.body.pipeTo(writable) From 4ac33b307dedaee6e25a140724cc89d9a6035607 Mon Sep 17 00:00:00 2001 From: Adam Argyle Date: Mon, 4 Jan 2021 11:57:11 -0800 Subject: [PATCH 3/4] update ux, fetch with promise all --- app/plugins/download-images.js | 110 ++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/app/plugins/download-images.js b/app/plugins/download-images.js index 56de7139..b6f051ee 100644 --- a/app/plugins/download-images.js +++ b/app/plugins/download-images.js @@ -3,28 +3,32 @@ export const commands = [ 'download-all-images', ] +const fetchAndWrite = async ({url, filename}, dirHandle) => { + try { + const response = await fetch(url) + const file = await dirHandle.getFileHandle(filename, { create: true }) + const writable = await file.createWritable() + + return await response.body.pipeTo(writable) + } catch (err) { + console.error(err) + } +} + export default async function () { if (window.showDirectoryPicker === undefined) { - console.log('no directory support :(') - return; + alert('missing the Directory Picker api 🙁') + return } - const dirHandle = await window.showDirectoryPicker() - const imgs = document.querySelectorAll("img") - - imgs.forEach(async (img) => { - const url = img.src - const name = url.substr(url.lastIndexOf('/') + 1); - try { - const response = await fetch(url) - const file = await dirHandle.getFileHandle(name, { create: true }) - const writable = await file.createWritable() - await response.body.pipeTo(writable) - } catch (err) { - console.error(err) - } - }) - // CSS urls - let css_urls = [...document.styleSheets] + + const imgs = [...document.querySelectorAll("img")] + .filter(img => img.src) + .map(img => ({ + url: img.src, + filename: img.src.substr(img.src.lastIndexOf('/') + 1), + })) + + const css_urls = [...document.styleSheets] .filter(sheet => { try { return sheet.cssRules } catch { } @@ -35,29 +39,47 @@ export default async function () { .filter(rule => rule.style.backgroundImage !== 'initial') .filter(rule => rule.style.backgroundImage.includes("url")) .reduce((urls, { style }) => { - urls.push(style.backgroundImage); - return urls; - }, []); - - css_urls.forEach(async (item, i) => { - let cots = false; - let start = item.indexOf('('); - if (item.charAt(start + 1) == '"') cots = true; - let end = item.lastIndexOf(')'); - if (cots) { - start += 2; - end -= 6; - } - const url = item.substr(start, end); - const truncated = url.substr(0, url.indexOf("?")); - const name = truncated.slice(truncated.lastIndexOf("/") + 1, truncated.lastIndexOf("/") + 39) + ".jpg" - try { - const response = await fetch(url) - const file = await dirHandle.getFileHandle(name, { create: true }) - const writable = await file.createWritable() - await response.body.pipeTo(writable) - } catch (err) { - console.error(err) - } - }) + let filename = '' + let url = '' + + let cots = false + let start = style.backgroundImage.indexOf('(') + if (style.backgroundImage.charAt(start + 1) == '"') cots = true + let end = style.backgroundImage.lastIndexOf(')') + if (cots) { + start += 2 + end -= 6 + } + url = style.backgroundImage.substr(start, end) + filename = style.backgroundImage.substr(start, end) + + const hasParams = url.indexOf("?") + if (hasParams > 0) { + url = url.substr(0, hasParams) +// filename = url.substr(0, hasParams) +// +// const type = url.slice(url.lastIndexOf(".") + 1, url.length) +// +// if (type <= 4) +// filename += type + } + + urls.push({ + url, + filename: url.substr(url.lastIndexOf('/') + 1), + }) + return urls + }, []) + + if (!confirm(`Download around ${imgs.length + css_urls.length} images?`)) return + const dirHandle = await window.showDirectoryPicker() + + const downloads = [...imgs, ...css_urls] + .map(image => + fetchAndWrite(image, dirHandle)) + + const results = await Promise.allSettled(downloads) + const successes = results.filter(res => res.status == 'fulfilled') + + confirm(`Successfully downloaded ${successes.length} images 👍`) } From ab02f7094733af1e24d91e5c8e874f1f7986596b Mon Sep 17 00:00:00 2001 From: Adam Argyle Date: Mon, 4 Jan 2021 12:19:02 -0800 Subject: [PATCH 4/4] getting closer to a resilient pass across remote origins --- app/plugins/download-images.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/app/plugins/download-images.js b/app/plugins/download-images.js index b6f051ee..05ae2605 100644 --- a/app/plugins/download-images.js +++ b/app/plugins/download-images.js @@ -6,12 +6,18 @@ export const commands = [ const fetchAndWrite = async ({url, filename}, dirHandle) => { try { const response = await fetch(url) - const file = await dirHandle.getFileHandle(filename, { create: true }) + const file = await dirHandle.getFileHandle( + filename.length > 40 + ? filename.substr(0, 40) + : filename, + { create: true } + ) const writable = await file.createWritable() return await response.body.pipeTo(writable) } catch (err) { console.error(err) + throw new Error(err) } } @@ -51,22 +57,18 @@ export default async function () { end -= 6 } url = style.backgroundImage.substr(start, end) - filename = style.backgroundImage.substr(start, end) const hasParams = url.indexOf("?") - if (hasParams > 0) { + if (hasParams > 0) url = url.substr(0, hasParams) -// filename = url.substr(0, hasParams) -// -// const type = url.slice(url.lastIndexOf(".") + 1, url.length) -// -// if (type <= 4) -// filename += type - } + + filename = url.substr(url.lastIndexOf('/') + 1) urls.push({ url, - filename: url.substr(url.lastIndexOf('/') + 1), + filename: filename + ? filename + : url, }) return urls }, [])