diff --git a/langs/en-ca.json b/langs/en-ca.json
index b3fff92..c177655 100644
--- a/langs/en-ca.json
+++ b/langs/en-ca.json
@@ -73,7 +73,8 @@
"error": {
"db-out-of-date": "Database out of date, please try again.",
"document-ID-404": "Cannot find {dbType} with ID: {id}",
- "no-upload-permission": "Cannot save due to missing the \"Upload Files\" permission."
+ "no-upload-permission": "Cannot save due to missing the \"Upload Files\" permission.",
+ "invalid-import-type": "Invalid import type: {type}"
}
}
}
diff --git a/module/api.mjs b/module/api.mjs
index f74de0f..72ddd09 100644
--- a/module/api.mjs
+++ b/module/api.mjs
@@ -6,6 +6,7 @@ import { ImageApp } from "./apps/ImageApp.mjs";
// Utils
import { convertToWebp, getFileSize, hashFile, lastModifiedAt } from "./utils/fs.mjs";
+import { importFromURL } from "./utils/imports.mjs";
export const api = foundry.utils.deepFreeze({
Apps: {
@@ -21,5 +22,6 @@ export const api = foundry.utils.deepFreeze({
lastModifiedAt,
getFileSize,
},
+ importFromURL,
},
});
diff --git a/module/utils/imports.mjs b/module/utils/imports.mjs
new file mode 100644
index 0000000..38e2a99
--- /dev/null
+++ b/module/utils/imports.mjs
@@ -0,0 +1,70 @@
+import { getFile } from "./fs.mjs";
+
+const { Dialog } = foundry.applications.api;
+const { fetchJsonWithTimeout, mergeObject } = foundry.utils;
+
+const TRUSTED_DOMAINS = new Set([
+ `git.varify.ca`,
+ `cdn.varify.ca`,
+ window.location.host,
+]);
+
+/**
+ * Imports an existing JSON DB into the module's current database.
+ *
+ * @param {string} url The URL pointing to a raw JSON file
+ * @param {`keep`|`replace`|`merge`} type The type of import that should be performed
+ */
+export async function importFromURL(url, type) {
+
+ if (![`keep`, `replace`, `merge`].includes(type)) {
+ ui.notifications.error(_loc(`IT.notifs.error.invalid-import-type`, { type }));
+ return false;
+ };
+
+ const domain = new URL(url);
+ if (!TRUSTED_DOMAINS.has(domain.host)) {
+ const confirmed = await Dialog.confirm({
+ content: `An import is trying to happen from:
${url}
Do you trust this website?`,
+ rejectClose: false,
+ });
+ if (!confirmed) {
+ return false;
+ };
+ };
+
+ let data;
+ try {
+ data = await fetchJsonWithTimeout(url);
+ } catch (err) {
+ throw err;
+ };
+
+ const images = await getFile(`storage/db/images.json`);
+ const artists = await getFile(`storage/db/artists.json`);
+
+ switch (type) {
+ case `keep`: {
+ importKeepExisting(data, images, artists);
+ break;
+ };
+ case `replace`: {
+ importReplaceExisting(data, images, artists);
+ break;
+ };
+ case `merge`: {
+ await importMerge(data, images, artists);
+ break;
+ };
+ };
+
+ return true;
+};
+
+async function importKeepExisting(data, imageDB, artistDB) {};
+
+async function importReplaceExisting(data, imageDB, artistDB) {};
+
+async function importMerge(data, imageDB, artistDB) {
+ throw `Merge-based importing is not implemented yet`;
+};