-
Notifications
You must be signed in to change notification settings - Fork 30
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 alongside site files #16
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import { get } from 'svelte/store' | ||
import { createUniqueID } from '$lib/utilities' | ||
import pages from '$lib/stores/data/pages' | ||
import symbols from '$lib/stores/data/symbols' | ||
// import beautify from 'js-beautify' // remove for now to reduce bundle size, dynamically import later if wanted | ||
|
@@ -28,11 +29,13 @@ export async function push_site(repo_name, create_new = false) { | |
return await deploy({ files, site_id: get(site).id, repo_name }, create_new) | ||
} | ||
|
||
export async function build_site_bundle({ pages, symbols }) { | ||
export async function build_site_bundle({ pages, symbols }, include_assets = false) { | ||
let site_bundle | ||
|
||
let all_sections = [] | ||
let all_pages = [] | ||
const all_sections = [] | ||
const all_pages = [] | ||
const image_files = [] | ||
|
||
try { | ||
const page_files = await Promise.all( | ||
pages.map((page) => { | ||
|
@@ -84,6 +87,17 @@ export async function build_site_bundle({ pages, symbols }) { | |
order: ['index', { ascending: true }] | ||
}) | ||
|
||
// Download images & replace urls in sections | ||
if (include_assets && has_nested_property(sections, 'alt')) { | ||
await Promise.all( | ||
sections.map(async (section, i) => { | ||
const response = await swap_in_local_asset_urls(section.content) | ||
image_files.push(...response.image_files) // store image blobs for later download | ||
sections[i]['content'] = response.content // replace image urls in content with relative urls | ||
}) | ||
) | ||
} | ||
|
||
const { html } = await buildStaticPage({ | ||
page, | ||
page_sections: sections, | ||
|
@@ -128,8 +142,8 @@ export async function build_site_bundle({ pages, symbols }) { | |
full_url = `${language}/${full_url}` | ||
} else { | ||
// only add en sections and pages to primo.json | ||
all_sections = [...all_sections, ...sections] | ||
all_pages = [...all_pages, page] | ||
all_sections.push(...sections) | ||
all_pages.push(page) | ||
} | ||
|
||
const page_tree = [ | ||
|
@@ -184,6 +198,7 @@ export async function build_site_bundle({ pages, symbols }) { | |
}) | ||
|
||
return [ | ||
...image_files, | ||
..._.flattenDeep(pages), | ||
{ | ||
path: `primo.json`, | ||
|
@@ -214,3 +229,67 @@ export async function build_site_bundle({ pages, symbols }) { | |
] | ||
} | ||
} | ||
|
||
/** | ||
* @param {import('$lib').Content} | ||
*/ | ||
async function swap_in_local_asset_urls(content) { | ||
const files_to_fetch = [] | ||
|
||
const updated_content = _.mapValues(content, (lang_value) => | ||
_.mapValues(lang_value, (field_value) => { | ||
if (typeof field_value === 'object' && field_value.hasOwnProperty('alt')) { | ||
const urlObject = new URL(field_value.url) | ||
const pathname = urlObject.pathname | ||
const extension = pathname.slice(pathname.lastIndexOf('.')) | ||
const filename = | ||
field_value.alt.replace(/[\/:*?"<>|\s]/g, '_') + `---${createUniqueID()}` + extension | ||
|
||
files_to_fetch.push({ | ||
url: field_value.url, | ||
filename | ||
}) | ||
return { | ||
...field_value, | ||
url: `./images/${filename}` | ||
} | ||
} else { | ||
return field_value | ||
} | ||
}) | ||
) | ||
|
||
// Download images | ||
const image_files = [] | ||
await Promise.all( | ||
files_to_fetch.map(async ({ url, filename }) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could be in a try catch since fetch can try to download forbidden assets, i have stumbled with this because i have some content with bad remote urls that can not be downloaded because of cors |
||
const response = await fetch(url) | ||
const blob = await response.blob() | ||
console.log({ blob }) | ||
|
||
image_files.push({ | ||
path: `./images/${filename}`, | ||
blob | ||
}) | ||
}) | ||
) | ||
|
||
return { | ||
content: updated_content, | ||
image_files | ||
} | ||
} | ||
|
||
function has_nested_property(obj, key) { | ||
if (obj.hasOwnProperty(key)) { | ||
return true | ||
} | ||
for (let i in obj) { | ||
if (typeof obj[i] === 'object') { | ||
if (has_nested_property(obj[i], key)) { | ||
return true | ||
} | ||
} | ||
} | ||
return false | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,7 +58,7 @@ | |
|
||
async function download_site() { | ||
loading = true | ||
const files = await build_site_bundle({ pages: $pages, symbols: $symbols }) | ||
const files = await build_site_bundle({ pages: $pages, symbols: $symbols }, true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this mean it will always download the assets? A checkbox next to the download button would allow both options, with or without images. |
||
if (!files) { | ||
loading = false | ||
return | ||
|
@@ -69,8 +69,12 @@ | |
|
||
async function create_site_zip(files) { | ||
const zip = new JSZip() | ||
files.forEach(({ path, content }) => { | ||
zip.file(path, content) | ||
files.forEach(({ path, content, blob }) => { | ||
if (blob) { | ||
zip.file(path, blob, { binary: true }) | ||
} else { | ||
zip.file(path, content) | ||
} | ||
}) | ||
return await zip.generateAsync({ type: 'blob' }) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should check that field_value.url is not empty, i was getting errors when downloading the site