Compare commits

..
11 Commits
Author SHA1 Message Date
fyears 474216b9ab bump to 0.3.18
Release A New Version / build (16.x) (push) Failing after 48s
2022-04-10 17:39:12 +08:00
fyears 99f143115b export sync plans in table format 2022-04-10 17:38:37 +08:00
fyears 39940deb3f fix output 2022-04-10 11:54:34 +08:00
fyears df53ea957f add commands 2022-04-10 11:18:48 +08:00
fyears 0cf8023278 cast headers to lower cases 2022-04-10 11:05:37 +08:00
fyears be1386b345 update aws dep 2022-04-10 11:05:08 +08:00
fyears 9a189d63c9 add more desc for seafile 2022-04-09 17:29:29 +08:00
fyears 00d0c557df Merge pull request #67 from Paul1365972/patch-1
Seafile is indeed connectable
2022-04-09 17:25:57 +08:00
Paul1365972 a70a53eeec Seafile is indeed connectable 2022-04-08 18:51:01 +02:00
fyears 8cec2b00eb remove unused debug log 2022-04-09 00:18:48 +08:00
fyears 6efe52b26e some logs for onedrive 2022-04-09 00:18:23 +08:00
10 changed files with 164 additions and 28 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ The list is for information purposes only.
| [Nginx `ngx_http_dav_module`](http://nginx.org/en/docs/http/ngx_http_dav_module.html) | Yes? | | Yes? | | Yes? | ? | | [Nginx `ngx_http_dav_module`](http://nginx.org/en/docs/http/ngx_http_dav_module.html) | Yes? | | Yes? | | Yes? | ? |
| NextCloud | Yes? | | Yes? | | Yes? | No CORS config by default. | | NextCloud | Yes? | | Yes? | | Yes? | No CORS config by default. |
| OwnCloud | Yes? | | Yes? | | Yes? | No CORS config by default. | | OwnCloud | Yes? | | Yes? | | Yes? | No CORS config by default. |
| Seafile | Yes? | | Yes? | | Yes? | | | Seafile | Yes | | Yes | | Yes? | No CORS config by default. |
| `rclone serve webdav` | Yes | | Yes | | Yes | No CORS support. | | `rclone serve webdav` | Yes | | Yes | | Yes | No CORS support. |
| [Nutstore 坚果云](https://www.jianguoyun.com/) | Yes | | Yes | | Yes | No CORS support. | | [Nutstore 坚果云](https://www.jianguoyun.com/) | Yes | | Yes | | Yes | No CORS support. |
| [TeraCLOUD](https://teracloud.jp/en/) | Yes | | Yes | | Yes | No CORS support. | | [TeraCLOUD](https://teracloud.jp/en/) | Yes | | Yes | | Yes | No CORS support. |
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"id": "remotely-save", "id": "remotely-save",
"name": "Remotely Save", "name": "Remotely Save",
"version": "0.3.17", "version": "0.3.18",
"minAppVersion": "0.13.21", "minAppVersion": "0.13.21",
"description": "Yet another unofficial plugin allowing users to synchronize notes between local device and the cloud service.", "description": "Yet another unofficial plugin allowing users to synchronize notes between local device and the cloud service.",
"author": "fyears", "author": "fyears",
+8 -8
View File
@@ -1,6 +1,6 @@
{ {
"name": "remotely-save", "name": "remotely-save",
"version": "0.3.17", "version": "0.3.18",
"description": "This is yet another sync plugin for Obsidian app.", "description": "This is yet another sync plugin for Obsidian app.",
"scripts": { "scripts": {
"dev2": "node esbuild.config.mjs", "dev2": "node esbuild.config.mjs",
@@ -51,13 +51,13 @@
"webpack-cli": "^4.9.1" "webpack-cli": "^4.9.1"
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "^3.54.0", "@aws-sdk/client-s3": "^3.67.0",
"@aws-sdk/fetch-http-handler": "^3.54.0", "@aws-sdk/fetch-http-handler": "^3.58.0",
"@aws-sdk/lib-storage": "^3.54.0", "@aws-sdk/lib-storage": "^3.67.0",
"@aws-sdk/protocol-http": "^3.54.0", "@aws-sdk/protocol-http": "^3.58.0",
"@aws-sdk/querystring-builder": "^3.54.0", "@aws-sdk/querystring-builder": "^3.55.0",
"@aws-sdk/signature-v4-crt": "^3.54.0", "@aws-sdk/signature-v4-crt": "^3.66.0",
"@aws-sdk/types": "^3.54.0", "@aws-sdk/types": "^3.55.0",
"@azure/msal-node": "^1.6.0", "@azure/msal-node": "^1.6.0",
"@fyears/tsqueue": "^1.0.1", "@fyears/tsqueue": "^1.0.1",
"@microsoft/microsoft-graph-client": "^3.0.1", "@microsoft/microsoft-graph-client": "^3.0.1",
+70 -4
View File
@@ -11,14 +11,73 @@ import {
DEFAULT_DEBUG_FOLDER, DEFAULT_DEBUG_FOLDER,
DEFAULT_LOG_HISTORY_FILE_PREFIX, DEFAULT_LOG_HISTORY_FILE_PREFIX,
DEFAULT_SYNC_PLANS_HISTORY_FILE_PREFIX, DEFAULT_SYNC_PLANS_HISTORY_FILE_PREFIX,
FileOrFolderMixedState,
} from "./baseTypes"; } from "./baseTypes";
import { log } from "./moreOnLog"; import { log } from "./moreOnLog";
const turnSyncPlanToTable = (record: string) => {
const syncPlan: SyncPlanType = JSON.parse(record);
const { ts, tsFmt, remoteType, mixedStates } = syncPlan;
type allowedHeadersType = keyof FileOrFolderMixedState;
const headers: allowedHeadersType[] = [
"key",
"remoteEncryptedKey",
"existLocal",
"sizeLocal",
"mtimeLocal",
"deltimeLocal",
"changeLocalMtimeUsingMapping",
"existRemote",
"sizeRemote",
"mtimeRemote",
"deltimeRemote",
"changeRemoteMtimeUsingMapping",
"decision",
"decisionBranch",
];
const lines = [
`ts: ${ts}${tsFmt !== undefined ? " / " + tsFmt : ""}`,
`remoteType: ${remoteType}`,
`| ${headers.join(" | ")} |`,
`| ${headers.map((x) => "---").join(" | ")} |`,
];
for (const [k1, v1] of Object.entries(syncPlan.mixedStates)) {
const k = k1 as string;
const v = v1 as FileOrFolderMixedState;
const singleLine = [];
for (const h of headers) {
const field = v[h];
if (field === undefined) {
singleLine.push("");
continue;
}
if (
h === "mtimeLocal" ||
h === "deltimeLocal" ||
h === "mtimeRemote" ||
h === "deltimeRemote"
) {
const fmt = v[(h + "Fmt") as allowedHeadersType] as string;
const s = `${field}${fmt !== undefined ? " / " + fmt : ""}`;
singleLine.push(s);
} else {
singleLine.push(field);
}
}
lines.push(`| ${singleLine.join(" | ")} |`);
}
return lines.join("\n");
};
export const exportVaultSyncPlansToFiles = async ( export const exportVaultSyncPlansToFiles = async (
db: InternalDBs, db: InternalDBs,
vault: Vault, vault: Vault,
vaultRandomID: string vaultRandomID: string,
toFormat: "table" | "json" = "json"
) => { ) => {
log.info("exporting"); log.info("exporting");
await mkdirpInVault(DEFAULT_DEBUG_FOLDER, vault); await mkdirpInVault(DEFAULT_DEBUG_FOLDER, vault);
@@ -27,9 +86,16 @@ export const exportVaultSyncPlansToFiles = async (
if (records.length === 0) { if (records.length === 0) {
md = "No sync plans history found"; md = "No sync plans history found";
} else { } else {
md = if (toFormat === "json") {
"Sync plans found:\n\n" + md =
records.map((x) => "```json\n" + x + "\n```\n").join("\n"); "Sync plans found:\n\n" +
records.map((x) => "```json\n" + x + "\n```\n").join("\n");
} else if (toFormat === "table") {
md =
"Sync plans found:\n\n" + records.map(turnSyncPlanToTable).join("\n\n");
} else {
const _: never = toFormat;
}
} }
const ts = Date.now(); const ts = Date.now();
const filePath = `${DEFAULT_DEBUG_FOLDER}${DEFAULT_SYNC_PLANS_HISTORY_FILE_PREFIX}${ts}.md`; const filePath = `${DEFAULT_DEBUG_FOLDER}${DEFAULT_SYNC_PLANS_HISTORY_FILE_PREFIX}${ts}.md`;
+58 -3
View File
@@ -8,7 +8,7 @@ import {
FileSystemAdapter, FileSystemAdapter,
} from "obsidian"; } from "obsidian";
import cloneDeep from "lodash/cloneDeep"; import cloneDeep from "lodash/cloneDeep";
import { createElement, RotateCcw, RefreshCcw } from "lucide"; import { createElement, RotateCcw, RefreshCcw, FileText } from "lucide";
import type { RemotelySavePluginSettings } from "./baseTypes"; import type { RemotelySavePluginSettings } from "./baseTypes";
import { import {
COMMAND_CALLBACK, COMMAND_CALLBACK,
@@ -57,6 +57,10 @@ import { applyPresetRulesInplace } from "./presetRules";
import { applyLogWriterInplace, log } from "./moreOnLog"; import { applyLogWriterInplace, log } from "./moreOnLog";
import AggregateError from "aggregate-error"; import AggregateError from "aggregate-error";
import {
exportVaultLoggerOutputToFiles,
exportVaultSyncPlansToFiles,
} from "./debugMode";
const DEFAULT_SETTINGS: RemotelySavePluginSettings = { const DEFAULT_SETTINGS: RemotelySavePluginSettings = {
s3: DEFAULT_S3_CONFIG, s3: DEFAULT_S3_CONFIG,
@@ -89,6 +93,7 @@ type SyncTriggerSourceType = "manual" | "auto" | "dry" | "autoOnceInit";
const iconNameSyncWait = `remotely-save-sync-wait`; const iconNameSyncWait = `remotely-save-sync-wait`;
const iconNameSyncRunning = `remotely-save-sync-running`; const iconNameSyncRunning = `remotely-save-sync-running`;
const iconNameLogs = `remotely-save-logs`;
const getIconSvg = () => { const getIconSvg = () => {
const iconSvgSyncWait = createElement(RotateCcw); const iconSvgSyncWait = createElement(RotateCcw);
@@ -97,13 +102,18 @@ const getIconSvg = () => {
const iconSvgSyncRunning = createElement(RefreshCcw); const iconSvgSyncRunning = createElement(RefreshCcw);
iconSvgSyncRunning.setAttribute("width", "100"); iconSvgSyncRunning.setAttribute("width", "100");
iconSvgSyncRunning.setAttribute("height", "100"); iconSvgSyncRunning.setAttribute("height", "100");
const iconSvgLogs = createElement(FileText);
iconSvgLogs.setAttribute("width", "100");
iconSvgLogs.setAttribute("height", "100");
const res = { const res = {
iconSvgSyncWait: iconSvgSyncWait.outerHTML, iconSvgSyncWait: iconSvgSyncWait.outerHTML,
iconSvgSyncRunning: iconSvgSyncRunning.outerHTML, iconSvgSyncRunning: iconSvgSyncRunning.outerHTML,
iconSvgLogs: iconSvgLogs.outerHTML,
}; };
iconSvgSyncWait.empty(); iconSvgSyncWait.empty();
iconSvgSyncRunning.empty(); iconSvgSyncRunning.empty();
iconSvgLogs.empty();
return res; return res;
}; };
@@ -204,7 +214,7 @@ export default class RemotelySavePlugin extends Plugin {
() => self.saveSettings() () => self.saveSettings()
); );
const remoteRsp = await client.listFromRemote(); const remoteRsp = await client.listFromRemote();
log.debug(remoteRsp); // log.debug(remoteRsp);
getNotice( getNotice(
t("syncrun_step3", { t("syncrun_step3", {
@@ -369,10 +379,11 @@ export default class RemotelySavePlugin extends Plugin {
async onload() { async onload() {
log.info(`loading plugin ${this.manifest.id}`); log.info(`loading plugin ${this.manifest.id}`);
const { iconSvgSyncWait, iconSvgSyncRunning } = getIconSvg(); const { iconSvgSyncWait, iconSvgSyncRunning, iconSvgLogs } = getIconSvg();
addIcon(iconNameSyncWait, iconSvgSyncWait); addIcon(iconNameSyncWait, iconSvgSyncWait);
addIcon(iconNameSyncRunning, iconSvgSyncRunning); addIcon(iconNameSyncRunning, iconSvgSyncRunning);
addIcon(iconNameLogs, iconSvgLogs);
this.oauth2Info = { this.oauth2Info = {
verifier: "", verifier: "",
@@ -664,6 +675,50 @@ export default class RemotelySavePlugin extends Plugin {
}, },
}); });
this.addCommand({
id: "export-sync-plans-json",
name: t("command_exportsyncplans_json"),
icon: iconNameLogs,
callback: async () => {
await exportVaultSyncPlansToFiles(
this.db,
this.app.vault,
this.vaultRandomID,
"json"
);
new Notice(t("settings_syncplans_notice"));
},
});
this.addCommand({
id: "export-sync-plans-table",
name: t("command_exportsyncplans_table"),
icon: iconNameLogs,
callback: async () => {
await exportVaultSyncPlansToFiles(
this.db,
this.app.vault,
this.vaultRandomID,
"table"
);
new Notice(t("settings_syncplans_notice"));
},
});
this.addCommand({
id: "export-logs-in-db",
name: t("command_exportlogsindb"),
icon: iconNameLogs,
callback: async () => {
await exportVaultLoggerOutputToFiles(
this.db,
this.app.vault,
this.vaultRandomID
);
new Notice(t("settings_logtodbexport_notice"));
},
});
this.addSettingTab(new RemotelySaveSettingTab(this.app, this)); this.addSettingTab(new RemotelySaveSettingTab(this.app, this));
// this.registerDomEvent(document, "click", (evt: MouseEvent) => { // this.registerDomEvent(document, "click", (evt: MouseEvent) => {
+2 -1
View File
@@ -400,7 +400,7 @@ export class WrappedOnedriveClient {
// log.info(`already checked, /${this.remoteBaseDir} exist before`) // log.info(`already checked, /${this.remoteBaseDir} exist before`)
} else { } else {
const k = await this.getJson("/drive/special/approot/children"); const k = await this.getJson("/drive/special/approot/children");
log.debug(k); // log.debug(k);
this.vaultFolderExists = this.vaultFolderExists =
(k.value as DriveItem[]).filter((x) => x.name === this.remoteBaseDir) (k.value as DriveItem[]).filter((x) => x.name === this.remoteBaseDir)
.length > 0; .length > 0;
@@ -617,6 +617,7 @@ export const listFromRemote = async (
`/drive/special/approot:/${client.remoteBaseDir}:/delta` `/drive/special/approot:/${client.remoteBaseDir}:/delta`
); );
let driveItems = res.value as DriveItem[]; let driveItems = res.value as DriveItem[];
// log.debug(driveItems);
while (NEXT_LINK_KEY in res) { while (NEXT_LINK_KEY in res) {
res = await client.getJson(res[NEXT_LINK_KEY]); res = await client.getJson(res[NEXT_LINK_KEY]);
+6 -1
View File
@@ -109,6 +109,11 @@ class ObsHttpHandler extends FetchHttpHandler {
const raceOfPromises = [ const raceOfPromises = [
requestUrl(param).then((rsp) => { requestUrl(param).then((rsp) => {
const headers = rsp.headers;
const headersLower: Record<string, string> = {};
for (const key of Object.keys(headers)) {
headersLower[key.toLowerCase()] = headers[key];
}
const stream = new ReadableStream<Uint8Array>({ const stream = new ReadableStream<Uint8Array>({
start(controller) { start(controller) {
controller.enqueue(new Uint8Array(rsp.arrayBuffer)); controller.enqueue(new Uint8Array(rsp.arrayBuffer));
@@ -117,7 +122,7 @@ class ObsHttpHandler extends FetchHttpHandler {
}); });
return { return {
response: new HttpResponse({ response: new HttpResponse({
headers: rsp.headers, headers: headersLower,
statusCode: rsp.status, statusCode: rsp.status,
body: stream, body: stream,
}), }),
+16 -7
View File
@@ -1678,11 +1678,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
button.setButtonText(t("settings_outputsettingsconsole_button")); button.setButtonText(t("settings_outputsettingsconsole_button"));
button.onClick(async () => { button.onClick(async () => {
const c = messyConfigToNormal(await this.plugin.loadData()); const c = messyConfigToNormal(await this.plugin.loadData());
if (c.currLogLevel === "debug") { log.info(c);
// no need to ouput it again because debug mode already output it
} else {
log.info(c);
}
new Notice(t("settings_outputsettingsconsole_notice")); new Notice(t("settings_outputsettingsconsole_notice"));
}); });
}); });
@@ -1691,12 +1687,25 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
.setName(t("settings_syncplans")) .setName(t("settings_syncplans"))
.setDesc(t("settings_syncplans_desc")) .setDesc(t("settings_syncplans_desc"))
.addButton(async (button) => { .addButton(async (button) => {
button.setButtonText(t("settings_syncplans_button")); button.setButtonText(t("settings_syncplans_button_json"));
button.onClick(async () => { button.onClick(async () => {
await exportVaultSyncPlansToFiles( await exportVaultSyncPlansToFiles(
this.plugin.db, this.plugin.db,
this.app.vault, this.app.vault,
this.plugin.vaultRandomID this.plugin.vaultRandomID,
"json"
);
new Notice(t("settings_syncplans_notice"));
});
})
.addButton(async (button) => {
button.setButtonText(t("settings_syncplans_button_table"));
button.onClick(async () => {
await exportVaultSyncPlansToFiles(
this.plugin.db,
this.app.vault,
this.plugin.vaultRandomID,
"table"
); );
new Notice(t("settings_syncplans_notice")); new Notice(t("settings_syncplans_notice"));
}); });
+1 -1
View File
@@ -1,4 +1,4 @@
{ {
"0.3.2": "0.12.15", "0.3.2": "0.12.15",
"0.3.17": "0.13.21" "0.3.18": "0.13.21"
} }