better sync operations for folders

This commit is contained in:
fyears 2022-03-06 13:19:47 +08:00
parent 94c7a4a874
commit 3dfe215103
6 changed files with 58 additions and 13 deletions

View File

@ -1,8 +1,8 @@
{ {
"id": "remotely-save", "id": "remotely-save",
"name": "Remotely Save", "name": "Remotely Save",
"version": "0.3.2", "version": "0.3.3",
"minAppVersion": "0.12.15", "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",
"authorUrl": "https://github.com/fyears", "authorUrl": "https://github.com/fyears",

View File

@ -1,6 +1,6 @@
{ {
"name": "remotely-save", "name": "remotely-save",
"version": "0.3.2", "version": "0.3.3",
"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",
@ -70,7 +70,7 @@
"loglevel": "^1.8.0", "loglevel": "^1.8.0",
"mime-types": "^2.1.33", "mime-types": "^2.1.33",
"nanoid": "^3.1.30", "nanoid": "^3.1.30",
"obsidian": "^0.12.0", "obsidian": "^0.13.26",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"process": "^0.11.10", "process": "^0.11.10",
"qrcode": "^1.5.0", "qrcode": "^1.5.0",

View File

@ -113,3 +113,5 @@ export interface FileOrFolderMixedState {
syncDone?: "done"; syncDone?: "done";
remoteEncryptedKey?: string; remoteEncryptedKey?: string;
} }
export const API_VER_STAT_FOLDER = "0.13.27";

View File

@ -199,6 +199,7 @@ export default class RemotelySavePlugin extends Plugin {
origMetadataOnRemote.deletions, origMetadataOnRemote.deletions,
localHistory, localHistory,
client.serviceType, client.serviceType,
this.app.vault,
this.settings.password this.settings.password
); );
log.info(plan.mixedStates); // for debugging log.info(plan.mixedStates); // for debugging

View File

@ -1,9 +1,16 @@
import { TAbstractFile, TFile, TFolder, Vault } from "obsidian"; import {
import type { TAbstractFile,
TFile,
TFolder,
Vault,
requireApiVersion,
} from "obsidian";
import {
RemoteItem, RemoteItem,
SUPPORTED_SERVICES_TYPE, SUPPORTED_SERVICES_TYPE,
DecisionType, DecisionType,
FileOrFolderMixedState, FileOrFolderMixedState,
API_VER_STAT_FOLDER,
} from "./baseTypes"; } from "./baseTypes";
import { import {
decryptBase32ToString, decryptBase32ToString,
@ -505,9 +512,10 @@ const assignOperationToFileInplace = (
throw Error(`no decision for ${JSON.stringify(r)}`); throw Error(`no decision for ${JSON.stringify(r)}`);
}; };
const assignOperationToFolderInplace = ( const assignOperationToFolderInplace = async (
origRecord: FileOrFolderMixedState, origRecord: FileOrFolderMixedState,
keptFolder: Set<string>, keptFolder: Set<string>,
vault: Vault,
password: string = "" password: string = ""
) => { ) => {
let r = origRecord; let r = origRecord;
@ -523,10 +531,42 @@ const assignOperationToFolderInplace = (
if (r.deltimeLocal !== undefined || r.deltimeRemote !== undefined) { if (r.deltimeLocal !== undefined || r.deltimeRemote !== undefined) {
// it has some deletion "commands" // it has some deletion "commands"
if (
r.deltimeLocal !== undefined && const deltimeLocal = r.deltimeLocal !== undefined ? r.deltimeLocal : -1;
r.deltimeLocal >= (r.deltimeRemote !== undefined ? r.deltimeRemote : -1) const deltimeRemote =
) { r.deltimeRemote !== undefined ? r.deltimeRemote : -1;
// if it was created after deletion, we should keep it as is
if (requireApiVersion(API_VER_STAT_FOLDER)) {
if (r.existLocal) {
try {
const { ctime, mtime } = await vault.adapter.stat(r.key);
const cmtime = Math.max(ctime, mtime);
if (
cmtime > 0 &&
cmtime >= deltimeLocal &&
cmtime >= deltimeRemote
) {
keptFolder.add(getParentFolder(r.key));
if (r.existLocal && r.existRemote) {
r.decision = "skipFolder";
r.decisionBranch = 14;
} else if (r.existLocal || r.existRemote) {
r.decision = "createFolder";
r.decisionBranch = 15;
} else {
throw Error(
`Error: Folder ${r.key} doesn't exist locally and remotely but is marked must be kept. Abort.`
);
}
}
} catch (error) {
// pass
}
}
}
if (deltimeLocal > 0 && deltimeLocal > deltimeRemote) {
r.decision = "uploadLocalDelHistToRemoteFolder"; r.decision = "uploadLocalDelHistToRemoteFolder";
r.decisionBranch = 8; r.decisionBranch = 8;
} else { } else {
@ -585,6 +625,7 @@ export const getSyncPlan = async (
remoteDeleteHistory: DeletionOnRemote[], remoteDeleteHistory: DeletionOnRemote[],
localDeleteHistory: FileFolderHistoryRecord[], localDeleteHistory: FileFolderHistoryRecord[],
remoteType: SUPPORTED_SERVICES_TYPE, remoteType: SUPPORTED_SERVICES_TYPE,
vault: Vault,
password: string = "" password: string = ""
) => { ) => {
const mixedStates = await ensembleMixedStates( const mixedStates = await ensembleMixedStates(
@ -609,7 +650,7 @@ export const getSyncPlan = async (
// decide some folders // decide some folders
// because the keys are sorted by length // because the keys are sorted by length
// so all the children must have been shown up before in the iteration // so all the children must have been shown up before in the iteration
assignOperationToFolderInplace(val, keptFolder, password); await assignOperationToFolderInplace(val, keptFolder, vault, password);
} else { } else {
// get all operations of files // get all operations of files
// and at the same time get some helper info for folders // and at the same time get some helper info for folders

View File

@ -1,3 +1,4 @@
{ {
"0.3.2": "0.12.15" "0.3.2": "0.12.15",
"0.3.3": "0.13.21"
} }