Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion languages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 2 additions & 1 deletion languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 6 additions & 0 deletions scripts/AdvancedExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
})
}
}
60 changes: 48 additions & 12 deletions scripts/Compendium2Module.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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("<filename>", image))
}
Expand Down Expand Up @@ -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(`<i class='fas fa-ban'></i>${game.i18n.localize('compendium2module.edit.close')}`)
let generateButton = dialog.find('button#generate')
let generateButtonIcon = generateButton.find('i')
Expand Down Expand Up @@ -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}`
}
Expand Down Expand Up @@ -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 = ""
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
}

/**
Expand Down Expand Up @@ -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<string>} 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;
}
}
6 changes: 6 additions & 0 deletions scripts/SimpleExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
})
}
}
2 changes: 2 additions & 0 deletions templates/advancedCompendium.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
<input id="version" name="version" type="text" placeholder="{{this.version}}">
<label for="includeImages">{{localize "compendium2module.edit.fields.includeImages"}}:</label>
<input id="includeImages" name="includeImages" type="checkbox">
<label for="includeURLImages">{{localize "compendium2module.edit.fields.includeURLImages"}}:</label>
<input id="includeURLImages" name="includeURLImages" type="checkbox" disabled>
<label for="saveToFile">{{localize "compendium2module.edit.fields.saveToFile"}}:</label>
<input id="saveToFile" name="saveToFile" type="checkbox">
</div>
Expand Down
2 changes: 2 additions & 0 deletions templates/singleCompendium.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
<input id="version" name="version" type="text" placeholder="{{this.version}}">
<label for="includeImages">{{localize "compendium2module.edit.fields.includeImages"}}:</label>
<input id="includeImages" name="includeImages" type="checkbox">
<label for="includeURLImages">{{localize "compendium2module.edit.fields.includeURLImages"}}:</label>
<input id="includeURLImages" name="includeURLImages" type="checkbox" disabled>
<label for="saveToFile">{{localize "compendium2module.edit.fields.saveToFile"}}:</label>
<input id="saveToFile" name="saveToFile" type="checkbox">
</div>
Expand Down