diff --git a/languages/de.json b/languages/de.json index 8f4a738..12e075e 100644 --- a/languages/de.json +++ b/languages/de.json @@ -20,7 +20,8 @@ "author": "Ersteller", "version": "Version", "includeImages": "Bilder exportieren", - "saveToFile": "Manifest-Link generieren" + "saveToFile": "Manifest-Link generieren", + "includeURLImages": "URL-gehostete Bilder einschließen" }, "cancel": "Abbrechen", "close": "Schließen", diff --git a/languages/en.json b/languages/en.json index cab0d13..07845e5 100644 --- a/languages/en.json +++ b/languages/en.json @@ -20,7 +20,8 @@ "author": "Author", "version": "Version", "includeImages": "Include Images", - "saveToFile": "Generate manifest link" + "saveToFile": "Generate manifest link", + "includeURLImages": "Include URL hosted images" }, "cancel": "Cancel", "close": "Close", diff --git a/scripts/AdvancedExporter.js b/scripts/AdvancedExporter.js index a46c0b7..4584536 100644 --- a/scripts/AdvancedExporter.js +++ b/scripts/AdvancedExporter.js @@ -65,5 +65,11 @@ export class AdvancedExporter extends FormApplication { html.find("button.copyToClipboard").on("click", async (event) => { await Compendium2Module.copyToClipboard(event) }) + + html.find("input#includeImages").on("click", async (event) => { + const includeURLImages = $("input#includeURLImages")[0] + includeURLImages.disabled = !event.target.checked + if (includeURLImages.disabled) includeURLImages.checked = false; + }) } } \ No newline at end of file diff --git a/scripts/Compendium2Module.js b/scripts/Compendium2Module.js index cf1f310..af5063c 100644 --- a/scripts/Compendium2Module.js +++ b/scripts/Compendium2Module.js @@ -39,8 +39,9 @@ export class Compendium2Module { * @param {{data: {string: string}, images: string[]}} dbData The data for the compendiums that are included with the module * @param {FormApplication} formApplication * @param {boolean} saveToFile If the module should be saved to the local file system + * @param {boolean} includeURLImages If images hosted at URLs should be included or filtered out */ - static async generateZIP(moduleId, moduleJSON, dbData, formApplication, saveToFile) { + static async generateZIP(moduleId, moduleJSON, dbData, formApplication, saveToFile, includeURLImages) { let zip = new JSZip() let parentDir = zip.folder(moduleId) parentDir.file("module.json", moduleJSON) @@ -55,10 +56,16 @@ export class Compendium2Module { let assets = parentDir.folder("assets") let request let imageContent + // This will be used to map image URLs back to URL.pathname. This is important because the full URL shouldn't be recreated in the module's assets folder + let urlPathMap = {} await this.asyncForEach(dbData.images.filter((value => { try { - new URL(value) + const imgURL = new URL(value) + if (includeURLImages) { + urlPathMap[value] = imgURL.pathname + return true; + } return false } catch (e) { return true @@ -71,7 +78,11 @@ export class Compendium2Module { return } imageContent = await request.blob() - assets.file(decodeURI(image), imageContent) + let imageDest = decodeURI(image) + if (includeURLImages && urlPathMap[image]) { + imageDest = decodeURI(urlPathMap[imageDest]) + } + assets.file(imageDest, imageContent) } catch (e) { ui.notifications.warn(game.i18n.localize("compendium2module.assets.notFound").replace("", image)) } @@ -106,7 +117,8 @@ export class Compendium2Module { let dialog = $('.compendium2moduleDialog') let manifestLink = dialog.find('input.manifestLink') - manifestLink.val(new URL(`${window.location.origin}/compendium2module/${moduleId}/module.json`).href) + const resourcePath = await this.getResourcePath(); + manifestLink.val(new URL(`${resourcePath}/compendium2module/${moduleId}/module.json`).href) dialog.find('button#cancel').html(`${game.i18n.localize('compendium2module.edit.close')}`) let generateButton = dialog.find('button#generate') let generateButtonIcon = generateButton.find('i') @@ -150,23 +162,30 @@ export class Compendium2Module { * @param {Document[]} documents * @param {string} moduleId * @param {boolean} includeImages + * @param {boolean} includeURLImages * @param {string[]} images * @returns {{images: string[], data: string}} */ - static transformCompendiumData(documents, moduleId, includeImages, images = []) { + static transformCompendiumData(documents, moduleId, includeImages, includeURLImages, images = []) { images = includeImages ? Compendium2Module.collectImagePathsFromCompendium(documents, images) : images let documentData = [] documents.forEach(d => { let json = d.toJSON() if (includeImages) { try { - new URL(json.img) + const imgURL = new URL(json.img) + if (includeURLImages) { + json.img = `modules/${moduleId}/assets/${imgURL.pathname}` + } } catch (e) { json.img = `modules/${moduleId}/assets/${json.img}` } if (json.type === "character") { try { - new URL(json.img) + const imgURL = new URL(json.prototypeToken.texture.src) + if (includeURLImages) { + json.prototypeToken.texture.src = `modules/${moduleId}/assets/${imgURL.pathname}` + } } catch (e) { json.prototypeToken.texture.src = `modules/${moduleId}/assets/${json.prototypeToken.texture.src}` } @@ -202,14 +221,16 @@ export class Compendium2Module { "version" : overrideData.version.length > 0 ? overrideData.version : "1.0.0", "displayName" : overrideData.displayName.length > 0 ? overrideData.displayName : (isSingleCompendium ? compendiums[0].metadata.label : `Generated Module #${now}`), "includeImages": overrideData.includeImages, - "saveToFile" : overrideData.saveToFile + "saveToFile" : overrideData.saveToFile, + "includeURLImages" : overrideData.includeURLImages } let manifestURL, downloadURL if (moduleOptions.saveToFile) { - manifestURL = (new URL(`${window.location.origin}/compendium2module/${moduleOptions.id}/module.json`)).href - downloadURL = (new URL(`${window.location.origin}/compendium2module/${moduleOptions.id}/module-zip.txt`)).href + const resourcePath = await this.getResourcePath(); + manifestURL = (new URL(`${resourcePath}/compendium2module/${moduleOptions.id}/module.json`)).href + downloadURL = (new URL(`${resourcePath}/compendium2module/${moduleOptions.id}/module-zip.txt`)).href } else { manifestURL = "" downloadURL = "" @@ -241,7 +262,7 @@ export class Compendium2Module { }) documents = await compendium.getDocuments() - transformedData = Compendium2Module.transformCompendiumData(documents, moduleOptions.id, moduleOptions.includeImages, images) + transformedData = Compendium2Module.transformCompendiumData(documents, moduleOptions.id, moduleOptions.includeImages, moduleOptions.includeURLImages, images) images = transformedData.images dbData.data[packName] = transformedData.data } @@ -270,7 +291,7 @@ export class Compendium2Module { ui.notifications.info(game.i18n.localize("compendium2module.info.dataCollected")) // noinspection JSCheckFunctionSignatures - return Compendium2Module.generateZIP(moduleOptions.id, JSON.stringify(moduleJSON, null, 4), dbData, formApplication, moduleOptions.saveToFile) + return Compendium2Module.generateZIP(moduleOptions.id, JSON.stringify(moduleJSON, null, 4), dbData, formApplication, moduleOptions.saveToFile, moduleOptions.includeURLImages) } /** @@ -298,4 +319,19 @@ export class Compendium2Module { } } } + + /** + * Return a path where resources will be hosted, usually the world host. + * Hosting providers or integrations may specify a different path. + * @returns {Promise} path + * @private + */ + static async getResourcePath() { + let path = window.location.origin; + // If running on The Forge, link to user's Assets Library + if (typeof ForgeVTT !== "undefined" && ForgeVTT.usingTheForge) { + path = ForgeVTT.ASSETS_LIBRARY_URL_PREFIX + await ForgeAPI.getUserId(); + } + return path; + } } \ No newline at end of file diff --git a/scripts/SimpleExporter.js b/scripts/SimpleExporter.js index 6dc9502..6cb66cb 100644 --- a/scripts/SimpleExporter.js +++ b/scripts/SimpleExporter.js @@ -56,5 +56,11 @@ export class SimpleExporter extends FormApplication { html.find("button.copyToClipboard").on("click", async (event) => { await Compendium2Module.copyToClipboard(event) }) + + html.find("input#includeImages").on("click", async (event) => { + const includeURLImages = $("input#includeURLImages")[0] + includeURLImages.disabled = !event.target.checked + if (includeURLImages.disabled) includeURLImages.checked = false; + }) } } \ No newline at end of file diff --git a/templates/advancedCompendium.hbs b/templates/advancedCompendium.hbs index 606904c..7bcfca6 100644 --- a/templates/advancedCompendium.hbs +++ b/templates/advancedCompendium.hbs @@ -36,6 +36,8 @@ + + diff --git a/templates/singleCompendium.hbs b/templates/singleCompendium.hbs index 4f75af6..4a79f9b 100644 --- a/templates/singleCompendium.hbs +++ b/templates/singleCompendium.hbs @@ -13,6 +13,8 @@ + +