Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a72ac8d66 | ||
|
|
d980bcbc1b | ||
|
|
6ebe1a8966 | ||
|
|
d0ab1d8abe | ||
|
|
b86d116830 | ||
|
|
7d5eaad36f | ||
|
|
7a13f4566c | ||
|
|
d355f72b7a | ||
|
|
9b1eebdf90 | ||
|
|
2ce461ed6a | ||
|
|
3aa91a2a1e |
@@ -13,6 +13,8 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
environment: env-for-buildci
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
|
||||
@@ -12,7 +12,10 @@ As of November 2021, the plugin is considered in BETA stage. **DO NOT USE IT for
|
||||
|
||||
## Features
|
||||
|
||||
- **Amazon S3 or S3-compatible, and Dropbox services are supported.** Webdav supports on the half way.
|
||||
- Supports:
|
||||
- Amazon S3 or S3-compatible
|
||||
- Dropbox
|
||||
- Webdav
|
||||
- **Obsidiain Mobile supported.** Vaults can be synced across mobile and desktop devices with the cloud service as the "broker".
|
||||
- **[End-to-end encryption](./docs/encryption.md) supported.** Files would be encrypted using openssl format before being sent to the cloud **if** user specify a password.
|
||||
- **[Minimal Intrusive](./docs/minimal_intrusive_design.md).**
|
||||
@@ -55,6 +58,8 @@ As of November 2021, the plugin is considered in BETA stage. **DO NOT USE IT for
|
||||
|
||||
### webdav
|
||||
|
||||
- **webdav support is buggy (as of now, 20211122) and considered experimental, so it's hidden by default.** Highly recommend to use the more stable s3.
|
||||
- If you decide to give it a try, open settings, and click "Choose service" area five times, then a Notice should show up. Close and open settings again then you will be able to select webdav.
|
||||
- Currently webdav server should enable CORS for requests, because of technical limitations of mobile.
|
||||
- **webdav support is considered experimental.**
|
||||
- Currently only supports BASIC authorization method.
|
||||
- Currently webdav server has to be enabled CORS for requests from `app://obsidian.md` and `capacitor://localhost` and `http://localhost`, **AND** all webdav HTTP methods and webdav headers, because of technical limitations of mobile.
|
||||
- Popular software NextCloud and OwnCloud do **NOT** enable CORS by default. If you are using any of them, you should find a way to enable CORS before using this plugin.
|
||||
- The plugin is tested successfully under python package [`wsgidav` (version 4.0)](https://github.com/mar10/wsgidav). See [this issue](https://github.com/mar10/wsgidav/issues/239) for details.
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"id": "remotely-save",
|
||||
"name": "Remotely Save",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.2",
|
||||
"minAppVersion": "0.12.15",
|
||||
"description": "Yet another unofficial plugin allowing users to sync 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",
|
||||
"authorUrl": "https://github.com/fyears",
|
||||
"isDesktopOnly": false
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "remotely-save",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.2",
|
||||
"description": "This is yet another sync plugin for Obsidian app.",
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
|
||||
+10
-49
@@ -27,8 +27,12 @@ import type { InternalDBs } from "./localdb";
|
||||
import type { SyncStatusType, PasswordCheckType } from "./sync";
|
||||
import { isPasswordOk, getSyncPlan, doActualSync } from "./sync";
|
||||
|
||||
import { S3Config, DEFAULT_S3_CONFIG } from "./s3";
|
||||
import { WebdavConfig, DEFAULT_WEBDAV_CONFIG, WebdavAuthType } from "./webdav";
|
||||
import { S3Config, DEFAULT_S3_CONFIG } from "./remoteForS3";
|
||||
import {
|
||||
WebdavConfig,
|
||||
DEFAULT_WEBDAV_CONFIG,
|
||||
WebdavAuthType,
|
||||
} from "./remoteForWebdav";
|
||||
import {
|
||||
DropboxConfig,
|
||||
DEFAULT_DROPBOX_CONFIG,
|
||||
@@ -47,7 +51,6 @@ interface RemotelySavePluginSettings {
|
||||
dropbox: DropboxConfig;
|
||||
password: string;
|
||||
serviceType: SUPPORTED_SERVICES_TYPE;
|
||||
enableExperimentService: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: RemotelySavePluginSettings = {
|
||||
@@ -56,7 +59,6 @@ const DEFAULT_SETTINGS: RemotelySavePluginSettings = {
|
||||
dropbox: DEFAULT_DROPBOX_CONFIG,
|
||||
password: "",
|
||||
serviceType: "s3",
|
||||
enableExperimentService: false,
|
||||
};
|
||||
|
||||
export default class RemotelySavePlugin extends Plugin {
|
||||
@@ -423,42 +425,9 @@ class RemotelySaveSettingTab extends PluginSettingTab {
|
||||
// we need to create the div in advance of any other service divs
|
||||
const serviceChooserDiv = generalDiv.createEl("div");
|
||||
|
||||
let clickChooserTimes = 0;
|
||||
serviceChooserDiv.onClickEvent(async (x) => {
|
||||
if (Platform.isIosApp) {
|
||||
// downgrade the experiment
|
||||
// because iOS doesn't support x.detail
|
||||
clickChooserTimes += 1;
|
||||
setTimeout(function () {
|
||||
clickChooserTimes = 0;
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
if ((Platform.isIosApp && clickChooserTimes === 5) || x.detail === 5) {
|
||||
if (this.plugin.settings.serviceType === "webdav") {
|
||||
new Notice(
|
||||
"You've enabled hidden unstable experimental webdav support before. Nothing changes."
|
||||
);
|
||||
} else if (!this.plugin.settings.enableExperimentService) {
|
||||
this.plugin.settings.enableExperimentService = true;
|
||||
await this.plugin.saveSettings();
|
||||
new Notice(
|
||||
"You've enabled hidden unstable experimental webdav support. Reopen settings again and try webdav with caution."
|
||||
);
|
||||
} else if (this.plugin.settings.enableExperimentService) {
|
||||
this.plugin.settings.enableExperimentService = false;
|
||||
await this.plugin.saveSettings();
|
||||
new Notice(
|
||||
"You've disabled hidden unstable experimental webdav support. Reopen settings again."
|
||||
);
|
||||
}
|
||||
}
|
||||
x.preventDefault();
|
||||
});
|
||||
|
||||
const s3Div = containerEl.createEl("div", { cls: "s3-hide" });
|
||||
s3Div.toggleClass("s3-hide", this.plugin.settings.serviceType !== "s3");
|
||||
s3Div.createEl("h2", { text: "S3 (-compatible) Service" });
|
||||
s3Div.createEl("h2", { text: "Remote For S3 (-compatible)" });
|
||||
|
||||
s3Div.createEl("p", {
|
||||
text: "You can use Amazon S3 or another S3-compatible service to sync your vault. Enter your bucket information below.",
|
||||
@@ -585,7 +554,7 @@ class RemotelySaveSettingTab extends PluginSettingTab {
|
||||
"dropbox-hide",
|
||||
this.plugin.settings.serviceType !== "dropbox"
|
||||
);
|
||||
dropboxDiv.createEl("h2", { text: "for Dropbox" });
|
||||
dropboxDiv.createEl("h2", { text: "Remote For Dropbox" });
|
||||
dropboxDiv.createEl("p", {
|
||||
text: "Disclaimer: Sync support for Dropbox are more experimental, and s3 functions are more stable now.",
|
||||
cls: "dropbox-disclaimer",
|
||||
@@ -706,7 +675,7 @@ class RemotelySaveSettingTab extends PluginSettingTab {
|
||||
this.plugin.settings.serviceType !== "webdav"
|
||||
);
|
||||
|
||||
webdavDiv.createEl("h2", { text: "Webdav Service" });
|
||||
webdavDiv.createEl("h2", { text: "Remote For Webdav" });
|
||||
|
||||
webdavDiv.createEl("p", {
|
||||
text: "Disclaimer: Webdav functions are more experimental, and s3 functions are more stable now.",
|
||||
@@ -768,7 +737,7 @@ class RemotelySaveSettingTab extends PluginSettingTab {
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown.addOption("basic", "basic");
|
||||
dropdown.addOption("digest", "digest");
|
||||
// dropdown.addOption("digest", "digest");
|
||||
|
||||
dropdown
|
||||
.setValue(this.plugin.settings.webdav.authType)
|
||||
@@ -806,18 +775,10 @@ class RemotelySaveSettingTab extends PluginSettingTab {
|
||||
.setDesc("Choose a service, by default s3")
|
||||
.addDropdown(async (dropdown) => {
|
||||
const currService = this.plugin.settings.serviceType;
|
||||
const enableExperimentService =
|
||||
this.plugin.settings.enableExperimentService;
|
||||
|
||||
dropdown.addOption("s3", "s3 (-compatible)");
|
||||
dropdown.addOption("dropbox", "Dropbox");
|
||||
if (currService === "webdav" || enableExperimentService) {
|
||||
dropdown.addOption("webdav", "webdav (experimental)");
|
||||
if (!enableExperimentService) {
|
||||
this.plugin.settings.enableExperimentService = true;
|
||||
await this.plugin.saveSettings();
|
||||
}
|
||||
}
|
||||
dropdown
|
||||
.setValue(this.plugin.settings.serviceType)
|
||||
.onChange(async (val: SUPPORTED_SERVICES_TYPE) => {
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { Vault } from "obsidian";
|
||||
|
||||
import type { SUPPORTED_SERVICES_TYPE } from "./baseTypes";
|
||||
import * as s3 from "./s3";
|
||||
import * as webdav from "./webdav";
|
||||
import * as s3 from "./remoteForS3";
|
||||
import * as webdav from "./remoteForWebdav";
|
||||
import * as dropbox from "./remoteForDropbox";
|
||||
|
||||
export class RemoteClient {
|
||||
|
||||
+22
-1
@@ -481,20 +481,41 @@ export const listFromRemote = async (
|
||||
throw Error("prefix not supported (yet)");
|
||||
}
|
||||
await client.init();
|
||||
const res = await client.dropbox.filesListFolder({
|
||||
let res = await client.dropbox.filesListFolder({
|
||||
path: `/${client.vaultName}`,
|
||||
recursive: true,
|
||||
include_deleted: false,
|
||||
limit: 1000,
|
||||
});
|
||||
if (res.status !== 200) {
|
||||
throw Error(JSON.stringify(res));
|
||||
}
|
||||
// console.log(res);
|
||||
|
||||
const contents = res.result.entries;
|
||||
const unifiedContents = contents
|
||||
.filter((x) => x[".tag"] !== "deleted")
|
||||
.filter((x) => x.path_display !== `/${client.vaultName}`)
|
||||
.map((x) => fromDropboxItemToRemoteItem(x, client.vaultName));
|
||||
|
||||
while (res.result.has_more) {
|
||||
res = await client.dropbox.filesListFolderContinue({
|
||||
cursor: res.result.cursor,
|
||||
});
|
||||
if (res.status !== 200) {
|
||||
throw Error(JSON.stringify(res));
|
||||
}
|
||||
|
||||
const contents2 = res.result.entries;
|
||||
const unifiedContents2 = contents2
|
||||
.filter((x) => x[".tag"] !== "deleted")
|
||||
.filter((x) => x.path_display !== `/${client.vaultName}`)
|
||||
.map((x) => fromDropboxItemToRemoteItem(x, client.vaultName));
|
||||
unifiedContents.push(...unifiedContents2);
|
||||
}
|
||||
|
||||
fixLastModifiedTimeInplace(unifiedContents);
|
||||
|
||||
return {
|
||||
Contents: unifiedContents,
|
||||
};
|
||||
|
||||
@@ -226,7 +226,7 @@ export const deleteFromRemote = async (
|
||||
remoteFileName = getWebdavPath(remoteFileName);
|
||||
try {
|
||||
await client.deleteFile(remoteFileName);
|
||||
console.log(`delete ${remoteFileName} succeeded`);
|
||||
// console.log(`delete ${remoteFileName} succeeded`);
|
||||
} catch (err) {
|
||||
console.error("some error while deleting");
|
||||
console.log(err);
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"0.2.0": "0.12.15"
|
||||
"0.2.2": "0.12.15"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user