Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download images plugin #481

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/plugins/_registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand All @@ -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 = [
Expand All @@ -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}`)
87 changes: 87 additions & 0 deletions app/plugins/download-images.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
export const commands = [
'download-images',
'download-all-images',
]

const fetchAndWrite = async ({url, filename}, dirHandle) => {
try {
const response = await fetch(url)
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)
}
}

export default async function () {
if (window.showDirectoryPicker === undefined) {
alert('missing the Directory Picker api 🙁')
return
}

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 { }
})
.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 }) => {
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)

const hasParams = url.indexOf("?")
if (hasParams > 0)
url = url.substr(0, hasParams)

filename = url.substr(url.lastIndexOf('/') + 1)

urls.push({
url,
filename: filename
? filename
: url,
})
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 👍`)
}