From 5cc849c853047e211a2dd873f90511ce48c002a2 Mon Sep 17 00:00:00 2001 From: Fabian Schuh Date: Fri, 1 Dec 2023 16:33:49 +0100 Subject: [PATCH 1/6] feat: regularily try to fetch documents from api --- src/main.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main.ts b/src/main.ts index 84615c8..51422cc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -63,6 +63,11 @@ export default class RelayMdPLugin extends Plugin { } }); + // Additionally, we register a timer to fetch documents for us + this.registerInterval(window.setInterval(() => { + this.get_recent_documents(); + }, 5 * 60 * 1000)); // 5 minutes + this.addSettingTab(new RelayMDSettingTab(this.app, this)); } From 169077fdb8127c3229674cf4007cec766709cfb2 Mon Sep 17 00:00:00 2001 From: Fabian Schuh Date: Fri, 1 Dec 2023 17:08:59 +0100 Subject: [PATCH 2/6] feat: regularily try to fetch documents from api --- main.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main.js b/main.js index ee7e87c..76af310 100644 --- a/main.js +++ b/main.js @@ -68,6 +68,9 @@ var RelayMdPLugin = class extends import_obsidian.Plugin { await this.get_recent_documents(); } }); + this.registerInterval(window.setInterval(() => { + this.get_recent_documents(); + }, 5 * 60 * 1e3)); this.addSettingTab(new RelayMDSettingTab(this.app, this)); } onunload() { From 30cd942d42d6041b4f76084e8a64324999d152c6 Mon Sep 17 00:00:00 2001 From: Fabian Schuh Date: Fri, 1 Dec 2023 18:16:28 +0100 Subject: [PATCH 3/6] fix: deal with errors on api differently --- src/main.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.ts b/src/main.ts index 51422cc..1028ccc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -119,9 +119,9 @@ export default class RelayMdPLugin extends Plugin { }, } const response: RequestUrlResponse = await requestUrl(options); - if (response.status != 200) { - console.error("API server returned non-200 status code"); - new Notice("Relay.md servers seem to be unavailable. Try again later"); + if (response.json.error) { + console.error("API server returned an error"); + new Notice("Relay.md returned an error: " + response.json.error.message); return; } try { @@ -157,9 +157,9 @@ export default class RelayMdPLugin extends Plugin { }, } const response: RequestUrlResponse = await requestUrl(options); - if (response.status != 200) { - console.error("API server returned non-200 status code"); - new Notice("Relay.md servers seem to be unavailable. Try again later"); + if (response.json.error) { + console.error("API server returned an error"); + new Notice("Relay.md returned an error: " + response.json.error.message); return; } try { @@ -204,9 +204,9 @@ export default class RelayMdPLugin extends Plugin { body: body, } const response: RequestUrlResponse = await requestUrl(options); - if (response.status != 200) { - console.error("API server returned non-200 status code"); - new Notice("Relay.md servers seem to be unavailable. Try again later"); + if (response.json.error) { + console.error("API server returned an error"); + new Notice("Relay.md returned an error: " + response.json.error.message); return; } From 6b5f4aab2655eed08724aee4a0d9d1b41dca0dbf Mon Sep 17 00:00:00 2001 From: Fabian Schuh Date: Fri, 1 Dec 2023 18:49:30 +0100 Subject: [PATCH 4/6] chore: improve error handling --- src/main.ts | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/main.ts b/src/main.ts index 1028ccc..bfc506b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -119,11 +119,8 @@ export default class RelayMdPLugin extends Plugin { }, } const response: RequestUrlResponse = await requestUrl(options); - if (response.json.error) { - console.error("API server returned an error"); - new Notice("Relay.md returned an error: " + response.json.error.message); - return; - } + // we do not look for error in json response as we do not get a json + // response but markdown in the body try { const filename: string = response.headers["x-relay-filename"]; const relay_to = JSON.parse(response.headers["x-relay-to"]); @@ -165,8 +162,9 @@ export default class RelayMdPLugin extends Plugin { try { // TODO: might want to make the interface clear to get rid of "any" type response.json.result.map(async (item: any) => { - new Notice("Obtaining " + item.filename); - await this.load_document(item.id); + console.log(item); + new Notice("Obtaining " + item["relay-filename"]); + await this.load_document(item["relay-document"]); }) } catch(e) { console.log(JSON.stringify(e)); @@ -186,12 +184,12 @@ export default class RelayMdPLugin extends Plugin { // There is no frontmatter so it cannot possibly be shared with anyone return; } - const id = metadata.frontmatter["relay-id"] + const id = metadata.frontmatter["relay-document"] let method = "POST"; let url = this.settings.base_uri + '/v1/doc?filename=' + encodeURIComponent(activeFile.name); if (id) { - method = "PATCH" + method = "PUT" url = this.settings.base_uri + '/v1/doc/' + id; } const options: RequestUrlParam = { @@ -211,14 +209,13 @@ export default class RelayMdPLugin extends Plugin { } // new document -> store id in frontmatter - if (!id) { - // Get document id - const doc_id = response.json.result.id; // FIXME: prolly needs change of id key - // update document to contain new document id - app.fileManager.processFrontMatter(activeFile, (frontmatter) => { - frontmatter["relay-id"] = doc_id; - }); - } + // TODO: This overwrites an existing relay-document id potentially, + // depending on how the server responds + const doc_id = response.json.result["relay-document"]; + // update document to contain new document id + app.fileManager.processFrontMatter(activeFile, (frontmatter) => { + frontmatter["relay-document"] = doc_id; + }); } } From 567e52e97960a36d56b87e2c356a1c4b5c5982c6 Mon Sep 17 00:00:00 2001 From: Fabian Schuh Date: Fri, 1 Dec 2023 20:09:12 +0100 Subject: [PATCH 5/6] chore: ignore main.js --- .gitignore | 1 + main.js | 226 ----------------------------------------------------- 2 files changed, 1 insertion(+), 226 deletions(-) delete mode 100644 main.js diff --git a/.gitignore b/.gitignore index 517790f..5d99480 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ data.json .DS_Store dist/release.zip +main.js diff --git a/main.js b/main.js deleted file mode 100644 index 76af310..0000000 --- a/main.js +++ /dev/null @@ -1,226 +0,0 @@ -/* -THIS IS A GENERATED/BUNDLED FILE BY ESBUILD -if you want to view the source, please visit the github repository of this plugin -*/ - -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - -// src/main.ts -var main_exports = {}; -__export(main_exports, { - default: () => RelayMdPLugin -}); -module.exports = __toCommonJS(main_exports); -var import_obsidian = require("obsidian"); -var DEFAULT_SETTINGS = { - base_uri: "https://api.relay.md", - api_key: "00000000-0000-0000-0000-000000000000", - vault_base_folder: "relay.md" -}; -var RelayMdPLugin = class extends import_obsidian.Plugin { - async onload() { - await this.loadSettings(); - this.addCommand({ - id: "relay-md-send-current-active-file", - name: "Relay.md: Send current open file", - callback: async () => { - new import_obsidian.Notice("Sending document to relay.md"); - const activeFile = this.app.workspace.getActiveFile(); - if (!activeFile) { - return; - } - if (activeFile.extension !== "md") { - new import_obsidian.Notice( - "The current file is not a markdown file. Please open a markdown file and try again." - ); - return; - } - if (activeFile.path.startsWith(this.settings.vault_base_folder)) { - new import_obsidian.Notice( - "Files from the relay.md base folder cannot be sent." - ); - } else { - await this.send_document(activeFile); - } - } - }); - this.addCommand({ - id: "relay-md-fetch-documents", - name: "Relay.md: Retreive recent files", - callback: async () => { - new import_obsidian.Notice("Retreiving documents from relay.md"); - await this.get_recent_documents(); - } - }); - this.registerInterval(window.setInterval(() => { - this.get_recent_documents(); - }, 5 * 60 * 1e3)); - this.addSettingTab(new RelayMDSettingTab(this.app, this)); - } - onunload() { - } - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); - } - async saveSettings() { - await this.saveData(this.settings); - } - async upsert_document(folder, filename, body) { - folder.split("/").reduce( - (directories, directory) => { - directories += `${directory}/`; - try { - this.app.vault.createFolder(directories); - } catch (e) { - } - return directories; - }, - "" - ); - const full_path_to_file = (0, import_obsidian.normalizePath)(folder + "/" + filename); - const fileRef = this.app.vault.getAbstractFileByPath(full_path_to_file); - if (fileRef === void 0 || fileRef === null) { - await this.app.vault.create(full_path_to_file, body); - new import_obsidian.Notice("File " + full_path_to_file + " has been created!"); - } else if (fileRef instanceof import_obsidian.TFile) { - await this.app.vault.modify(fileRef, body); - new import_obsidian.Notice("File " + full_path_to_file + " has been modified!"); - } - } - async load_document(id) { - const options = { - url: this.settings.base_uri + "/v1/doc/" + id, - method: "GET", - headers: { - "X-API-KEY": this.settings.api_key, - "Content-Type": "text/markdown" - } - }; - const response = await (0, import_obsidian.requestUrl)(options); - if (response.status != 200) { - console.error("API server returned non-200 status code"); - new import_obsidian.Notice("Relay.md servers seem to be unavailable. Try again later"); - return; - } - try { - const filename = response.headers["x-relay-filename"]; - const relay_to = JSON.parse(response.headers["x-relay-to"]); - const body = response.text; - for (const to of relay_to) { - const tos = to.split("@", 2); - const team = tos[1]; - const topic = tos[0]; - let full_path_to_file = this.settings.vault_base_folder + "/"; - if (team != "_") - full_path_to_file += team + "/"; - full_path_to_file += topic; - this.upsert_document(full_path_to_file, filename, body); - } - } catch (e) { - console.log(JSON.stringify(e)); - throw e; - } - } - async get_recent_documents() { - const options = { - url: this.settings.base_uri + "/v1/docs", - method: "GET", - headers: { - "X-API-KEY": this.settings.api_key, - "Content-Type": "application/json" - } - }; - const response = await (0, import_obsidian.requestUrl)(options); - if (response.status != 200) { - console.error("API server returned non-200 status code"); - new import_obsidian.Notice("Relay.md servers seem to be unavailable. Try again later"); - return; - } - try { - response.json.result.map(async (item) => { - new import_obsidian.Notice("Obtaining " + item.filename); - await this.load_document(item.id); - }); - } catch (e) { - console.log(JSON.stringify(e)); - throw e; - } - } - // TODO: might want to make the interface clear to get rid of "any" type - async send_document(activeFile) { - const body = await this.app.vault.cachedRead(activeFile); - const metadata = this.app.metadataCache.getCache(activeFile.path); - if (metadata === null || metadata === void 0) { - return; - } - if (metadata.frontmatter === null || metadata.frontmatter === void 0) { - return; - } - const id = metadata.frontmatter["relay-id"]; - let method = "POST"; - let url = this.settings.base_uri + "/v1/doc?filename=" + encodeURIComponent(activeFile.name); - if (id) { - method = "PATCH"; - url = this.settings.base_uri + "/v1/doc/" + id; - } - const options = { - url, - method, - headers: { - "X-API-KEY": this.settings.api_key, - "Content-Type": "text/markdown" - }, - body - }; - const response = await (0, import_obsidian.requestUrl)(options); - if (response.status != 200) { - console.error("API server returned non-200 status code"); - new import_obsidian.Notice("Relay.md servers seem to be unavailable. Try again later"); - return; - } - if (!id) { - const doc_id = response.json.result.id; - app.fileManager.processFrontMatter(activeFile, (frontmatter) => { - frontmatter["relay-id"] = doc_id; - }); - } - } -}; -var RelayMDSettingTab = class extends import_obsidian.PluginSettingTab { - constructor(app2, plugin) { - super(app2, plugin); - this.plugin = plugin; - } - display() { - const { containerEl } = this; - containerEl.empty(); - new import_obsidian.Setting(containerEl).setName("Base API URI").setDesc("Base URL for API access").addText((text) => text.setPlaceholder("Enter your API url").setValue(this.plugin.settings.base_uri).onChange(async (value) => { - this.plugin.settings.base_uri = value; - await this.plugin.saveSettings(); - })); - new import_obsidian.Setting(containerEl).setName("Setting #1").setDesc("It's a secret").addText((text) => text.setPlaceholder("Enter your API-Key").setValue(this.plugin.settings.api_key).onChange(async (value) => { - this.plugin.settings.api_key = value; - await this.plugin.saveSettings(); - })); - new import_obsidian.Setting(containerEl).setName("Vault relay.md inbox").setDesc("Base folder to synchronize into").addText((text) => text.setPlaceholder("relay.md").setValue(this.plugin.settings.vault_base_folder).onChange(async (value) => { - this.plugin.settings.vault_base_folder = value; - await this.plugin.saveSettings(); - })); - } -}; From 01687b1c6ce09d2d3bfcf0f92e7ed98dd3255f4a Mon Sep 17 00:00:00 2001 From: Fabian Schuh Date: Sat, 2 Dec 2023 14:20:49 +0100 Subject: [PATCH 6/6] feat: allow to obtain access-key via click of a button in settings --- src/main.ts | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/src/main.ts b/src/main.ts index bfc506b..6601284 100644 --- a/src/main.ts +++ b/src/main.ts @@ -28,6 +28,18 @@ export default class RelayMdPLugin extends Plugin { async onload() { await this.loadSettings(); + + // To make obtaining the access-token easier, + // we register a protocol handler + this.registerObsidianProtocolHandler("relay.md:access-token", (params) =>{ + if (!params.token) { + return; + } + this.settings.api_key = params.token; + this.settings.base_uri = DEFAULT_SETTINGS.base_uri; // also potentially reset the base uri + this.saveSettings(); + new Notice("Access credentials for relay.md have been succesfully installed!"); + }); this.addCommand({ id: "relay-md-send-current-active-file", @@ -243,16 +255,28 @@ class RelayMDSettingTab extends PluginSettingTab { await this.plugin.saveSettings(); })); - new Setting(containerEl) - .setName('Setting #1') - .setDesc('It\'s a secret') - .addText(text => text - .setPlaceholder('Enter your API-Key') - .setValue(this.plugin.settings.api_key) - .onChange(async (value) => { - this.plugin.settings.api_key = value; - await this.plugin.saveSettings(); - })); + if (this.plugin.settings.api_key == DEFAULT_SETTINGS.api_key) { + new Setting(containerEl) + .setName('API Access') + .setDesc('Authenticate against the relay.md API') + .addButton((button) => + button.setButtonText("Obtain access to relay.md").onClick(async () => { + window.open("localhost:5000/configure/obsidian"); + }) + ); + } else { + new Setting(containerEl) + .setName('API Access') + .setDesc('Authenticate against the relay.md API') + .addButton((button) => + button.setButtonText("reset").onClick(async () => { + this.plugin.settings.api_key = DEFAULT_SETTINGS.api_key; + await this.plugin.saveSettings(); + // refresh settings page + this.display(); + }) + ); + } new Setting(containerEl) .setName('Vault relay.md inbox')