mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-02-23 12:38:47 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac9428e96b | ||
|
|
280d9e1dd9 | ||
|
|
f7209e566c | ||
|
|
4a9ab2d1de | ||
|
|
cb74b5ee93 | ||
|
|
60eecd7001 | ||
|
|
4bd7b54bcd | ||
|
|
8923c73d1b | ||
|
|
11e64b13e2 | ||
|
|
983d9248ed | ||
|
|
7240e84328 | ||
|
|
0d55ae2532 | ||
|
|
dbd284f5dd |
@@ -66,7 +66,7 @@ Synchronization status is shown in statusbar.
|
||||
- ↓ Downloaded chunks and metadata
|
||||
- ⏳ Number of pending processes
|
||||
- 🧩 Number of files waiting for their chunks.
|
||||
If you have deleted or renamed files, please wait until ⏳ icon disappeared.
|
||||
If you have deleted or renamed files, please wait until ⏳ icon disappears.
|
||||
|
||||
|
||||
## Hints
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "view-in-github",
|
||||
"colab_type": "text"
|
||||
"colab_type": "text",
|
||||
"id": "view-in-github"
|
||||
},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/gist/vrtmrz/37c3efd7842e49947aaaa7f665e5020a/deploy_couchdb_to_flyio_v2_with_swap.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
@@ -12,15 +12,16 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "HiRV7G8Gk1Rs"
|
||||
},
|
||||
"source": [
|
||||
"History:\n",
|
||||
"- 18, May, 2023: Initial.\n",
|
||||
"- 19, Jun., 2023: Patched for enabling swap.\n",
|
||||
"- 22, Aug., 2023: Generating Setup-URI implemented."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "HiRV7G8Gk1Rs"
|
||||
}
|
||||
"- 22, Aug., 2023: Generating Setup-URI implemented.\n",
|
||||
"- 7, Nov., 2023: Fixed the issue of TOML editing."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -45,7 +46,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Delete once\n",
|
||||
"# Delete once (Do not care about `cannot remove './fly.toml': No such file or directory`)\n",
|
||||
"!rm ./fly.toml"
|
||||
]
|
||||
},
|
||||
@@ -78,15 +79,15 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Check the toml once.\n",
|
||||
"!cat fly.toml"
|
||||
],
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "2RSoO9o-i2TT"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Check the toml once.\n",
|
||||
"!cat fly.toml"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -96,52 +97,45 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Modify fly.toml\n",
|
||||
"## Port modification\n",
|
||||
"!sed -i 's/8080/5984/g' fly.toml\n",
|
||||
"## Add user into.\n",
|
||||
"!echo -e \"\\n[env]\\n COUCHDB_USER = \\\"${couchUser}\\\"\" >> ./fly.toml\n",
|
||||
"## Set the location of an ini file which to save configurations persistently via erlang flags.\n",
|
||||
"!echo -e \"\\nERL_FLAGS=\\\"-couch_ini /opt/couchdb/etc/default.ini /opt/couchdb/etc/default.d/ /opt/couchdb/etc/local.d /opt/couchdb/etc/local.ini /opt/couchdb/data/persistence.ini\\\"\" >> ./fly.toml\n",
|
||||
"## Mounting volumes to store data and ini file.\n",
|
||||
"!echo -e \"\\n[mounts]\\n source=\\\"couchdata\\\"\\n destination=\\\"/opt/couchdb/data\\\"\" >> ./fly.toml\n",
|
||||
"!cat fly.toml"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Modify the TOML and generate Dockerfile\n",
|
||||
"!pip install mergedeep\n",
|
||||
"from mergedeep import merge\n",
|
||||
"import toml\n",
|
||||
"fly = toml.load('fly.toml')\n",
|
||||
"override = {\n",
|
||||
" \"http_service\":{\n",
|
||||
" \"internal_port\":5984\n",
|
||||
" },\n",
|
||||
" \"build\":{\n",
|
||||
" \"dockerfile\":\"./Dockerfile\"\n",
|
||||
" },\n",
|
||||
" \"mounts\":{\n",
|
||||
" \"source\":\"couchdata\",\n",
|
||||
" \"destination\":\"/opt/couchdb/data\"\n",
|
||||
" },\n",
|
||||
" \"env\":{\n",
|
||||
" \"COUCHDB_USER\":os.environ['couchUser'],\n",
|
||||
" \"ERL_FLAGS\":\"-couch_ini /opt/couchdb/etc/default.ini /opt/couchdb/etc/default.d/ /opt/couchdb/etc/local.d /opt/couchdb/etc/local.ini /opt/couchdb/data/persistence.ini\",\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"out = merge(fly,override)\n",
|
||||
"with open('fly.toml', 'wt') as fp:\n",
|
||||
" toml.dump(out, fp)\n",
|
||||
" fp.close()\n",
|
||||
"\n",
|
||||
"# Make the Dockerfile to modify the permission of the ini file. If you want to use a specific version, you should change `latest` here.\n",
|
||||
"!echo -e \"\\n[build]\\n dockerfile = \\\"./Dockerfile\\\"\" >> ./fly.toml"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "LQPsZ_dYxkTu"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"!echo -e \"FROM couchdb:latest\\nRUN sed -i '2itouch /opt/couchdb/data/persistence.ini && chmod +w /opt/couchdb/data/persistence.ini && fallocate -l 512M /swapfile && chmod 0600 /swapfile && mkswap /swapfile && echo 10 > /proc/sys/vm/swappiness && swapon /swapfile && echo 1 > /proc/sys/vm/overcommit_memory' /docker-entrypoint.sh\" > ./Dockerfile"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "44cBeGJ9on5i"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Check dockerfile\n",
|
||||
"!cat ./Dockerfile"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "ai2R3BbpxRSe"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
"dockerfile = '''FROM couchdb:latest\n",
|
||||
"RUN sed -i '2itouch /opt/couchdb/data/persistence.ini && chmod +w /opt/couchdb/data/persistence.ini && fallocate -l 512M /swapfile && chmod 0600 /swapfile && mkswap /swapfile && echo 10 > /proc/sys/vm/swappiness && swapon /swapfile && echo 1 > /proc/sys/vm/overcommit_memory' /docker-entrypoint.sh\n",
|
||||
"'''\n",
|
||||
"with open(\"./Dockerfile\",\"wt\") as fp:\n",
|
||||
" fp.write(dockerfile)\n",
|
||||
" fp.close()\n",
|
||||
"\n",
|
||||
"!echo ------\n",
|
||||
"!cat fly.toml\n",
|
||||
"!echo ------\n",
|
||||
"!cat Dockerfile"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -189,20 +183,27 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "cGlSzVqlQG_z"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Finish setting up the CouchDB\n",
|
||||
"# Please repeat until the request is completed without error messages\n",
|
||||
"# i.e., You have to redo this block while \"curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection to xxxx\" is showing.\n",
|
||||
"#\n",
|
||||
"# Note: A few minutes might be required to be booted.\n",
|
||||
"!curl -X POST \"${couchHost}/_cluster_setup\" -H \"Content-Type: application/json\" -d \"{\\\"action\\\":\\\"enable_single_node\\\",\\\"username\\\":\\\"${couchUser}\\\",\\\"password\\\":\\\"${couchPwd}\\\",\\\"bind_address\\\":\\\"0.0.0.0\\\",\\\"port\\\":5984,\\\"singlenode\\\":true}\" --user \"${couchUser}:${couchPwd}\""
|
||||
],
|
||||
"metadata": {
|
||||
"id": "cGlSzVqlQG_z"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "JePzrsHypY18"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Please repeat until all lines are completed without error messages\n",
|
||||
"!curl -X PUT \"${couchHost}/_node/nonode@nohost/_config/chttpd/require_valid_user\" -H \"Content-Type: application/json\" -d '\"true\"' --user \"${couchUser}:${couchPwd}\"\n",
|
||||
@@ -214,28 +215,28 @@
|
||||
"!curl -X PUT \"${couchHost}/_node/nonode@nohost/_config/couchdb/max_document_size\" -H \"Content-Type: application/json\" -d '\"50000000\"' --user \"${couchUser}:${couchPwd}\"\n",
|
||||
"!curl -X PUT \"${couchHost}/_node/nonode@nohost/_config/cors/credentials\" -H \"Content-Type: application/json\" -d '\"true\"' --user \"${couchUser}:${couchPwd}\"\n",
|
||||
"!curl -X PUT \"${couchHost}/_node/nonode@nohost/_config/cors/origins\" -H \"Content-Type: application/json\" -d '\"app://obsidian.md,capacitor://localhost,http://localhost\"' --user \"${couchUser}:${couchPwd}\""
|
||||
],
|
||||
"metadata": {
|
||||
"id": "JePzrsHypY18"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "YfSOomsoXbGS"
|
||||
},
|
||||
"source": [
|
||||
"Now, our CouchDB has been surely installed and configured. Cheers!\n",
|
||||
"\n",
|
||||
"In the steps that follow, create a setup-URI.\n",
|
||||
"\n",
|
||||
"This URI could be imported directly into Self-hosted LiveSync, to configure the use of the CouchDB which we configured now."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "YfSOomsoXbGS"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "416YncOqXdNn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Database config\n",
|
||||
"import random, string\n",
|
||||
@@ -250,39 +251,39 @@
|
||||
"\n",
|
||||
"print(\"Your database:\"+os.environ['database'])\n",
|
||||
"print(\"Your passphrase:\"+os.environ['passphrase'])"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "416YncOqXdNn"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Install deno for make setup uri\n",
|
||||
"!curl -fsSL https://deno.land/x/install/install.sh | sh"
|
||||
],
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "C4d7C0HAXgsr"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Install deno for make setup uri\n",
|
||||
"!curl -fsSL https://deno.land/x/install/install.sh | sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Fetch module for encrypting a Setup URI\n",
|
||||
"!curl -o encrypt.ts https://gist.githubusercontent.com/vrtmrz/f9d1d95ee2ca3afa1a924a2c6759b854/raw/d7a070d864a6f61403d8dc74208238d5741aeb5a/encrypt.ts"
|
||||
],
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "hQL_Dx-PXise"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Fetch module for encrypting a Setup URI\n",
|
||||
"!curl -o encrypt.ts https://gist.githubusercontent.com/vrtmrz/f9d1d95ee2ca3afa1a924a2c6759b854/raw/d7a070d864a6f61403d8dc74208238d5741aeb5a/encrypt.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "o0gX_thFXlIZ"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Make buttons!\n",
|
||||
"from IPython.display import HTML\n",
|
||||
@@ -294,29 +295,24 @@
|
||||
"else:\n",
|
||||
" result = \"Failed to encrypt the setup URI\"\n",
|
||||
"result"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "o0gX_thFXlIZ"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": [],
|
||||
"include_colab_link": true,
|
||||
"private_outputs": true,
|
||||
"include_colab_link": true
|
||||
"provenance": []
|
||||
},
|
||||
"gpuClass": "standard",
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
},
|
||||
"gpuClass": "standard"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-livesync",
|
||||
"name": "Self-hosted LiveSync",
|
||||
"version": "0.20.2",
|
||||
"version": "0.20.7",
|
||||
"minAppVersion": "0.9.12",
|
||||
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
||||
"author": "vorotamoroz",
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.20.2",
|
||||
"version": "0.20.7",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.20.2",
|
||||
"version": "0.20.7",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"diff-match-patch": "^1.0.5",
|
||||
@@ -36,7 +36,7 @@
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.28.0",
|
||||
"events": "^3.3.0",
|
||||
"obsidian": "^1.3.5",
|
||||
"obsidian": "^1.4.11",
|
||||
"postcss": "^8.4.27",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"pouchdb-adapter-http": "^8.0.1",
|
||||
@@ -3223,9 +3223,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/obsidian": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.4.0.tgz",
|
||||
"integrity": "sha512-fsZMPlxgflGSBSP6P4BjQi5+0MqZl3h6FEDEZ3CNnweNdDw0doyqN3FMO/PGWfuxPT77WicVwUxekuI3e6eCGg==",
|
||||
"version": "1.4.11",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.4.11.tgz",
|
||||
"integrity": "sha512-BCVYTvaXxElJMl6MMbDdY/CGK+aq18SdtDY/7vH8v6BxCBQ6KF4kKxL0vG9UZ0o5qh139KpUoJHNm+6O5dllKA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/codemirror": "5.60.8",
|
||||
@@ -6913,9 +6913,9 @@
|
||||
}
|
||||
},
|
||||
"obsidian": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.4.0.tgz",
|
||||
"integrity": "sha512-fsZMPlxgflGSBSP6P4BjQi5+0MqZl3h6FEDEZ3CNnweNdDw0doyqN3FMO/PGWfuxPT77WicVwUxekuI3e6eCGg==",
|
||||
"version": "1.4.11",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.4.11.tgz",
|
||||
"integrity": "sha512-BCVYTvaXxElJMl6MMbDdY/CGK+aq18SdtDY/7vH8v6BxCBQ6KF4kKxL0vG9UZ0o5qh139KpUoJHNm+6O5dllKA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/codemirror": "5.60.8",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.20.2",
|
||||
"version": "0.20.7",
|
||||
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
||||
"main": "main.js",
|
||||
"type": "module",
|
||||
@@ -17,9 +17,9 @@
|
||||
"@types/diff-match-patch": "^1.0.32",
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/pouchdb": "^6.4.0",
|
||||
"@types/pouchdb-browser": "^6.1.3",
|
||||
"@types/pouchdb-adapter-http": "^6.1.3",
|
||||
"@types/pouchdb-adapter-idb": "^6.1.4",
|
||||
"@types/pouchdb-browser": "^6.1.3",
|
||||
"@types/pouchdb-core": "^7.0.11",
|
||||
"@types/pouchdb-mapreduce": "^6.1.7",
|
||||
"@types/pouchdb-replication": "^6.4.4",
|
||||
@@ -33,7 +33,7 @@
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.28.0",
|
||||
"events": "^3.3.0",
|
||||
"obsidian": "^1.3.5",
|
||||
"obsidian": "^1.4.11",
|
||||
"postcss": "^8.4.27",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"pouchdb-adapter-http": "^8.0.1",
|
||||
@@ -60,4 +60,4 @@
|
||||
"xxhash-wasm": "0.4.2",
|
||||
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ function deserialize2(str: string): PluginDataEx {
|
||||
data
|
||||
}
|
||||
)
|
||||
tokens.nextLine();
|
||||
} while (filename);
|
||||
return result;
|
||||
}
|
||||
@@ -352,11 +353,13 @@ export class ConfigSync extends LiveSyncCommands {
|
||||
}
|
||||
}
|
||||
Logger(`All files enumerated`, logLevel, "get-plugins");
|
||||
pluginIsEnumerating.set(false);
|
||||
this.createMissingConfigurationEntry();
|
||||
} finally {
|
||||
pluginIsEnumerating.set(false);
|
||||
}
|
||||
});
|
||||
pluginIsEnumerating.set(false);
|
||||
});
|
||||
// return entries;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ export class SetupLiveSync extends LiveSyncCommands {
|
||||
delete setting[k];
|
||||
}
|
||||
}
|
||||
const encryptedSetting = encodeURIComponent(await encrypt(JSON.stringify(setting), encryptingPassphrase, false, false));
|
||||
const encryptedSetting = encodeURIComponent(await encrypt(JSON.stringify(setting), encryptingPassphrase, false, true));
|
||||
const uri = `${configURIBase}${encryptedSetting}`;
|
||||
await navigator.clipboard.writeText(uri);
|
||||
Logger("Setup URI copied to clipboard", LOG_LEVEL_NOTICE);
|
||||
@@ -70,7 +70,7 @@ export class SetupLiveSync extends LiveSyncCommands {
|
||||
if (encryptingPassphrase === false)
|
||||
return;
|
||||
const setting = { ...this.settings, configPassphraseStore: "", encryptedCouchDBConnection: "", encryptedPassphrase: "" };
|
||||
const encryptedSetting = encodeURIComponent(await encrypt(JSON.stringify(setting), encryptingPassphrase, false, false));
|
||||
const encryptedSetting = encodeURIComponent(await encrypt(JSON.stringify(setting), encryptingPassphrase, false, true));
|
||||
const uri = `${configURIBase}${encryptedSetting}`;
|
||||
await navigator.clipboard.writeText(uri);
|
||||
Logger("Setup URI copied to clipboard", LOG_LEVEL_NOTICE);
|
||||
|
||||
@@ -207,21 +207,21 @@
|
||||
const local = list.find((e) => e.term == thisTerm);
|
||||
const selectedItem = list.find((e) => e.term == selected);
|
||||
if (selectedItem && (await applyData(selectedItem))) {
|
||||
scheduleTask("update-plugin-list", 250, () => addOn.updatePluginList(true, local.documentPath));
|
||||
addOn.updatePluginList(true, local?.documentPath);
|
||||
}
|
||||
}
|
||||
async function compareSelected() {
|
||||
const local = list.find((e) => e.term == thisTerm);
|
||||
const selectedItem = list.find((e) => e.term == selected);
|
||||
if (local && selectedItem && (await compareData(local, selectedItem))) {
|
||||
scheduleTask("update-plugin-list", 250, () => addOn.updatePluginList(true, local.documentPath));
|
||||
addOn.updatePluginList(true, local.documentPath);
|
||||
}
|
||||
}
|
||||
async function deleteSelected() {
|
||||
const selectedItem = list.find((e) => e.term == selected);
|
||||
// const deletedPath = selectedItem.documentPath;
|
||||
if (selectedItem && (await deleteData(selectedItem))) {
|
||||
scheduleTask("update-plugin-list", 250, () => addOn.reloadPluginList(true));
|
||||
addOn.reloadPluginList(true);
|
||||
}
|
||||
}
|
||||
async function duplicateItem() {
|
||||
|
||||
@@ -58,8 +58,7 @@ export class InputStringDialog extends Modal {
|
||||
onOpen() {
|
||||
const { contentEl } = this;
|
||||
this.titleEl.setText(this.title);
|
||||
// For enter to submit
|
||||
const formEl = contentEl.createEl("form");
|
||||
const formEl = contentEl.createDiv();
|
||||
new Setting(formEl).setName(this.key).setClass(this.isPassword ? "password-input" : "normal-input").addText((text) =>
|
||||
text.onChange((value) => {
|
||||
this.result = value;
|
||||
|
||||
2
src/lib
2
src/lib
Submodule src/lib updated: 609c7aecf3...4a4e7a26b4
153
src/main.ts
153
src/main.ts
@@ -515,58 +515,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
||||
return ret == CHOICE_V1;
|
||||
}
|
||||
|
||||
async onload() {
|
||||
logStore.subscribe(e => this.addLog(e.message, e.level, e.key));
|
||||
Logger("loading plugin");
|
||||
//@ts-ignore
|
||||
const manifestVersion: string = MANIFEST_VERSION || "0.0.0";
|
||||
//@ts-ignore
|
||||
const packageVersion: string = PACKAGE_VERSION || "0.0.0";
|
||||
|
||||
this.manifestVersion = manifestVersion;
|
||||
this.packageVersion = packageVersion;
|
||||
|
||||
Logger(`Self-hosted LiveSync v${manifestVersion} ${packageVersion} `);
|
||||
const lsKey = "obsidian-live-sync-ver" + this.getVaultName();
|
||||
const last_version = localStorage.getItem(lsKey);
|
||||
await this.loadSettings();
|
||||
|
||||
const lastVersion = ~~(versionNumberString2Number(manifestVersion) / 1000);
|
||||
if (lastVersion > this.settings.lastReadUpdates) {
|
||||
Logger("Self-hosted LiveSync has undergone a major upgrade. Please open the setting dialog, and check the information pane.", LOG_LEVEL_NOTICE);
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
if (this.app.isMobile) {
|
||||
this.isMobile = true;
|
||||
this.settings.disableRequestURI = true;
|
||||
}
|
||||
if (last_version && Number(last_version) < VER) {
|
||||
this.settings.liveSync = false;
|
||||
this.settings.syncOnSave = false;
|
||||
this.settings.syncOnEditorSave = false;
|
||||
this.settings.syncOnStart = false;
|
||||
this.settings.syncOnFileOpen = false;
|
||||
this.settings.syncAfterMerge = false;
|
||||
this.settings.periodicReplication = false;
|
||||
this.settings.versionUpFlash = "Self-hosted LiveSync has been upgraded and some behaviors have changed incompatibly. All automatic synchronization is now disabled temporary. Ensure that other devices are also upgraded, and enable synchronization again.";
|
||||
this.saveSettings();
|
||||
}
|
||||
localStorage.setItem(lsKey, `${VER}`);
|
||||
await this.openDatabase();
|
||||
this.watchWorkspaceOpen = debounce(this.watchWorkspaceOpen.bind(this), 1000, false);
|
||||
this.watchWindowVisibility = debounce(this.watchWindowVisibility.bind(this), 1000, false);
|
||||
this.watchOnline = debounce(this.watchOnline.bind(this), 500, false);
|
||||
|
||||
this.parseReplicationResult = this.parseReplicationResult.bind(this);
|
||||
|
||||
this.loadQueuedFiles = this.loadQueuedFiles.bind(this);
|
||||
|
||||
this.triggerRealizeSettingSyncMode = debounce(this.triggerRealizeSettingSyncMode.bind(this), 1000);
|
||||
|
||||
this.statusBar = this.addStatusBarItem();
|
||||
this.statusBar.addClass("syncstatusbar");
|
||||
|
||||
addUIs() {
|
||||
addIcon(
|
||||
"replicate",
|
||||
`<g transform="matrix(1.15 0 0 1.15 -8.31 -9.52)" fill="currentColor" fill-rule="evenodd">
|
||||
@@ -583,14 +532,23 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
||||
<path d="m106 346v44h70v-44zm45 16h-20v-8h20z"/>
|
||||
</g>`
|
||||
);
|
||||
await Promise.all(this.addOns.map(e => e.onload()));
|
||||
addIcon(
|
||||
"custom-sync",
|
||||
`<g transform="rotate(-90 75 218)" fill="currentColor" fill-rule="evenodd">
|
||||
<path d="m272 166-9.38 9.38 9.38 9.38 9.38-9.38c1.96-1.93 5.11-1.9 7.03 0.058 1.91 1.94 1.91 5.04 0 6.98l-9.38 9.38 5.86 5.86-11.7 11.7c-8.34 8.35-21.4 9.68-31.3 3.19l-3.84 3.98c-8.45 8.7-20.1 13.6-32.2 13.6h-5.55v-9.95h5.55c9.43-0.0182 18.5-3.84 25-10.6l3.95-4.09c-6.54-9.86-5.23-23 3.14-31.3l11.7-11.7 5.86 5.86 9.38-9.38c1.96-1.93 5.11-1.9 7.03 0.0564 1.91 1.93 1.91 5.04 2e-3 6.98z"/>
|
||||
</g>`
|
||||
);
|
||||
this.addRibbonIcon("replicate", "Replicate", async () => {
|
||||
await this.replicate(true);
|
||||
});
|
||||
}).addClass("livesync-ribbon-replicate");
|
||||
|
||||
this.addRibbonIcon("view-log", "Show log", () => {
|
||||
this.showView(VIEW_TYPE_LOG);
|
||||
});
|
||||
}).addClass("livesync-ribbon-showlog");
|
||||
this.addRibbonIcon("custom-sync", "Show Customization sync", () => {
|
||||
this.addOnConfigSync.showPluginSyncModal();
|
||||
}).addClass("livesync-ribbon-showcustom");
|
||||
|
||||
this.addCommand({
|
||||
id: "view-log",
|
||||
name: "Show log",
|
||||
@@ -598,8 +556,6 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
||||
this.showView(VIEW_TYPE_LOG);
|
||||
}
|
||||
});
|
||||
this.addSettingTab(new ObsidianLiveSyncSettingTab(this.app, this));
|
||||
this.app.workspace.onLayoutReady(this.onLayoutReady.bind(this));
|
||||
|
||||
this.addCommand({
|
||||
id: "livesync-replicate",
|
||||
@@ -672,8 +628,6 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
||||
}
|
||||
})
|
||||
|
||||
this.triggerRealizeSettingSyncMode = debounce(this.triggerRealizeSettingSyncMode.bind(this), 1000);
|
||||
|
||||
this.addCommand({
|
||||
id: "livesync-filehistory",
|
||||
name: "Pick a file to show history",
|
||||
@@ -709,6 +663,13 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
||||
this.replicator.terminateSync();
|
||||
},
|
||||
})
|
||||
this.addCommand({
|
||||
id: "livesync-global-history",
|
||||
name: "Show vault history",
|
||||
callback: () => {
|
||||
this.showGlobalHistory()
|
||||
}
|
||||
})
|
||||
|
||||
this.registerView(
|
||||
VIEW_TYPE_GLOBAL_HISTORY,
|
||||
@@ -718,13 +679,66 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
||||
VIEW_TYPE_LOG,
|
||||
(leaf) => new LogPaneView(leaf, this)
|
||||
);
|
||||
this.addCommand({
|
||||
id: "livesync-global-history",
|
||||
name: "Show vault history",
|
||||
callback: () => {
|
||||
this.showGlobalHistory()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async onload() {
|
||||
logStore.subscribe(e => this.addLog(e.message, e.level, e.key));
|
||||
Logger("loading plugin");
|
||||
this.addSettingTab(new ObsidianLiveSyncSettingTab(this.app, this));
|
||||
this.addUIs();
|
||||
//@ts-ignore
|
||||
const manifestVersion: string = MANIFEST_VERSION || "0.0.0";
|
||||
//@ts-ignore
|
||||
const packageVersion: string = PACKAGE_VERSION || "0.0.0";
|
||||
|
||||
this.manifestVersion = manifestVersion;
|
||||
this.packageVersion = packageVersion;
|
||||
|
||||
Logger(`Self-hosted LiveSync v${manifestVersion} ${packageVersion} `);
|
||||
const lsKey = "obsidian-live-sync-ver" + this.getVaultName();
|
||||
const last_version = localStorage.getItem(lsKey);
|
||||
await this.loadSettings();
|
||||
this.statusBar = this.addStatusBarItem();
|
||||
this.statusBar.addClass("syncstatusbar");
|
||||
const lastVersion = ~~(versionNumberString2Number(manifestVersion) / 1000);
|
||||
if (lastVersion > this.settings.lastReadUpdates) {
|
||||
Logger("Self-hosted LiveSync has undergone a major upgrade. Please open the setting dialog, and check the information pane.", LOG_LEVEL_NOTICE);
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
if (this.app.isMobile) {
|
||||
this.isMobile = true;
|
||||
this.settings.disableRequestURI = true;
|
||||
}
|
||||
if (last_version && Number(last_version) < VER) {
|
||||
this.settings.liveSync = false;
|
||||
this.settings.syncOnSave = false;
|
||||
this.settings.syncOnEditorSave = false;
|
||||
this.settings.syncOnStart = false;
|
||||
this.settings.syncOnFileOpen = false;
|
||||
this.settings.syncAfterMerge = false;
|
||||
this.settings.periodicReplication = false;
|
||||
this.settings.versionUpFlash = "Self-hosted LiveSync has been upgraded and some behaviors have changed incompatibly. All automatic synchronization is now disabled temporary. Ensure that other devices are also upgraded, and enable synchronization again.";
|
||||
this.saveSettings();
|
||||
}
|
||||
localStorage.setItem(lsKey, `${VER}`);
|
||||
await this.openDatabase();
|
||||
this.watchWorkspaceOpen = debounce(this.watchWorkspaceOpen.bind(this), 1000, false);
|
||||
this.watchWindowVisibility = debounce(this.watchWindowVisibility.bind(this), 1000, false);
|
||||
this.watchOnline = debounce(this.watchOnline.bind(this), 500, false);
|
||||
|
||||
this.parseReplicationResult = this.parseReplicationResult.bind(this);
|
||||
|
||||
this.loadQueuedFiles = this.loadQueuedFiles.bind(this);
|
||||
|
||||
this.triggerRealizeSettingSyncMode = debounce(this.triggerRealizeSettingSyncMode.bind(this), 1000);
|
||||
|
||||
await Promise.all(this.addOns.map(e => e.onload()));
|
||||
|
||||
this.app.workspace.onLayoutReady(this.onLayoutReady.bind(this));
|
||||
|
||||
this.triggerRealizeSettingSyncMode = debounce(this.triggerRealizeSettingSyncMode.bind(this), 1000);
|
||||
|
||||
}
|
||||
async showView(viewType: string) {
|
||||
const leaves = this.app.workspace.getLeavesOfType(viewType);
|
||||
@@ -1313,13 +1327,13 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
||||
if (this.settings.trashInsteadDelete) {
|
||||
await this.app.vault.trash(file, false);
|
||||
} else {
|
||||
await this.app.vault.delete(file);
|
||||
await this.app.vault.delete(file, true);
|
||||
}
|
||||
Logger(`xxx <- STORAGE (deleted) ${file.path}`);
|
||||
Logger(`files: ${dir.children.length}`);
|
||||
if (dir.children.length == 0) {
|
||||
if (!this.settings.doNotDeleteFolder) {
|
||||
Logger(`All files under the parent directory (${dir}) have been deleted, so delete this one.`);
|
||||
Logger(`All files under the parent directory (${dir.path}) have been deleted, so delete this one.`);
|
||||
await this.deleteVaultItem(dir);
|
||||
}
|
||||
}
|
||||
@@ -1609,6 +1623,9 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
||||
this.replicator.openReplication(this.settings, true, false);
|
||||
}
|
||||
|
||||
const q = activeDocument.querySelector(`.livesync-ribbon-showcustom`);
|
||||
q?.toggleClass("sls-hidden", !this.settings.usePluginSync);
|
||||
|
||||
this.periodicSyncProcessor.enable(this.settings.periodicReplication ? this.settings.periodicReplicationInterval * 1000 : 0);
|
||||
|
||||
|
||||
|
||||
@@ -481,7 +481,7 @@ export const requestToCouchDB = async (baseUri: string, username: string, passwo
|
||||
|
||||
export async function performRebuildDB(plugin: ObsidianLiveSyncPlugin, method: "localOnly" | "remoteOnly" | "rebuildBothByThisDevice") {
|
||||
if (method == "localOnly") {
|
||||
await plugin.addOnSetup.fetchLocalWithKeepLocal();
|
||||
await plugin.addOnSetup.fetchLocal();
|
||||
}
|
||||
if (method == "remoteOnly") {
|
||||
await plugin.addOnSetup.rebuildRemote();
|
||||
|
||||
28
updates.md
28
updates.md
@@ -15,6 +15,34 @@ This format change gives us the ability to detect some `marks` in the binary fil
|
||||
Now only a few chunks are transferred, even if we add a comment to the PDF or put new files into the ZIP archives.
|
||||
|
||||
#### Version history
|
||||
- 0.20.7
|
||||
- Fixed
|
||||
- To better replication, path obfuscation is now deterministic even if with E2EE.
|
||||
Note: Compatible with previous database without any conversion. Only new files will be obfuscated in deterministic.
|
||||
- 0.20.6
|
||||
- Fixed
|
||||
- Now empty file could be decoded.
|
||||
- Local files are no longer pre-saved before fetching from a remote database.
|
||||
- No longer deadlock while applying customisation sync.
|
||||
- Configuration with multiple files is now able to be applied correctly.
|
||||
- Deleting folder propagation now works without enabling the use of a trash bin.
|
||||
- 0.20.5
|
||||
- Fixed
|
||||
- Now the files which having digit or character prefixes in the path will not be ignored.
|
||||
- 0.20.4
|
||||
- Fixed
|
||||
- The text-input-dialogue is no longer broken.
|
||||
- Finally, we can use the Setup URI again on mobile.
|
||||
- 0.20.3
|
||||
- New feature:
|
||||
- We can launch Customization sync from the Ribbon if we enabled it.
|
||||
- Fixed:
|
||||
- Setup URI is now back to the previous spec; be encrypted by V1.
|
||||
- It may avoid the trouble with iOS 17.
|
||||
- The Settings dialogue is now registered at the beginning of the start-up process.
|
||||
- We can change the configuration even though LiveSync could not be launched in normal.
|
||||
- Improved:
|
||||
- Enumerating documents has been faster.
|
||||
- 0.20.2
|
||||
- New feature:
|
||||
- We can delete all data of customization sync from the `Delete all customization sync data` on the `Hatch` pane.
|
||||
|
||||
Reference in New Issue
Block a user