Compare commits
4 Commits
757eb5c801
...
2645ff34e6
Author | SHA1 | Date |
---|---|---|
fyears | 2645ff34e6 | |
fyears | f25a2c2992 | |
fyears | 3d1269a9f2 | |
fyears | ed52a8542f |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "remotely-save",
|
||||
"name": "Remotely Save",
|
||||
"version": "0.4.19",
|
||||
"version": "0.4.20",
|
||||
"minAppVersion": "0.13.21",
|
||||
"description": "Yet another unofficial plugin allowing users to synchronize notes between local device and the cloud service.",
|
||||
"author": "fyears",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "remotely-save",
|
||||
"name": "Remotely Save",
|
||||
"version": "0.4.19",
|
||||
"version": "0.4.20",
|
||||
"minAppVersion": "0.13.21",
|
||||
"description": "Yet another unofficial plugin allowing users to synchronize notes between local device and the cloud service.",
|
||||
"author": "fyears",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "remotely-save",
|
||||
"version": "0.4.19",
|
||||
"version": "0.4.20",
|
||||
"description": "This is yet another sync plugin for Obsidian app.",
|
||||
"scripts": {
|
||||
"dev2": "node esbuild.config.mjs --watch",
|
||||
|
|
|
@ -4,14 +4,14 @@ import { FakeFs } from "./fsAll";
|
|||
import { TFile, TFolder, type Vault } from "obsidian";
|
||||
import { listFilesInObsFolder } from "./obsFolderLister";
|
||||
import { Profiler } from "./profiler";
|
||||
import { getFolderLevels, mkdirpInVault, statFix } from "./misc";
|
||||
import { getFolderLevels, mkdirpInVault, statFix, unixTimeToStr } from "./misc";
|
||||
|
||||
export class FakeFsLocal extends FakeFs {
|
||||
vault: Vault;
|
||||
syncConfigDir: boolean;
|
||||
configDir: string;
|
||||
pluginID: string;
|
||||
profiler: Profiler;
|
||||
profiler: Profiler | undefined;
|
||||
deleteToWhere: "obsidian" | "system";
|
||||
kind: "local";
|
||||
constructor(
|
||||
|
@ -19,7 +19,7 @@ export class FakeFsLocal extends FakeFs {
|
|||
syncConfigDir: boolean,
|
||||
configDir: string,
|
||||
pluginID: string,
|
||||
profiler: Profiler,
|
||||
profiler: Profiler | undefined,
|
||||
deleteToWhere: "obsidian" | "system"
|
||||
) {
|
||||
super();
|
||||
|
@ -34,12 +34,12 @@ export class FakeFsLocal extends FakeFs {
|
|||
}
|
||||
|
||||
async walk(): Promise<Entity[]> {
|
||||
this.profiler.addIndent();
|
||||
this.profiler.insert("enter walk for local");
|
||||
this.profiler?.addIndent();
|
||||
this.profiler?.insert("enter walk for local");
|
||||
const local: Entity[] = [];
|
||||
|
||||
const localTAbstractFiles = this.vault.getAllLoadedFiles();
|
||||
this.profiler.insert("finish getting walk for local");
|
||||
this.profiler?.insert("finish getting walk for local");
|
||||
for (const entry of localTAbstractFiles) {
|
||||
let r: Entity | undefined = undefined;
|
||||
let key = entry.path;
|
||||
|
@ -89,10 +89,10 @@ export class FakeFsLocal extends FakeFs {
|
|||
}
|
||||
}
|
||||
|
||||
this.profiler.insert("finish transforming walk for local");
|
||||
this.profiler?.insert("finish transforming walk for local");
|
||||
|
||||
if (this.syncConfigDir) {
|
||||
this.profiler.insert("into syncConfigDir");
|
||||
this.profiler?.insert("into syncConfigDir");
|
||||
const syncFiles = await listFilesInObsFolder(
|
||||
this.configDir,
|
||||
this.vault,
|
||||
|
@ -101,11 +101,11 @@ export class FakeFsLocal extends FakeFs {
|
|||
for (const f of syncFiles) {
|
||||
local.push(f);
|
||||
}
|
||||
this.profiler.insert("finish syncConfigDir");
|
||||
this.profiler?.insert("finish syncConfigDir");
|
||||
}
|
||||
|
||||
this.profiler.insert("finish walk for local");
|
||||
this.profiler.removeIndent();
|
||||
this.profiler?.insert("finish walk for local");
|
||||
this.profiler?.removeIndent();
|
||||
return local;
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,8 @@ export class FakeFsLocal extends FakeFs {
|
|||
keyRaw: isFolder ? `${key}/` : key,
|
||||
mtimeCli: statRes.mtime,
|
||||
mtimeSvr: statRes.mtime,
|
||||
mtimeCliFmt: unixTimeToStr(statRes.mtime),
|
||||
mtimeSvrFmt: unixTimeToStr(statRes.mtime),
|
||||
size: statRes.size, // local always unencrypted
|
||||
sizeRaw: statRes.size,
|
||||
};
|
||||
|
|
12
src/fsS3.ts
12
src/fsS3.ts
|
@ -340,13 +340,14 @@ const fromS3ObjectToEntity = (
|
|||
const fromS3HeadObjectToEntity = (
|
||||
fileOrFolderPathWithRemotePrefix: string,
|
||||
x: HeadObjectCommandOutput,
|
||||
remotePrefix: string
|
||||
remotePrefix: string,
|
||||
useAccurateMTime: boolean
|
||||
) => {
|
||||
// console.debug(`fromS3HeadObjectToEntity: ${fileOrFolderPathWithRemotePrefix}: ${JSON.stringify(x,null,2)}`);
|
||||
// S3 officially only supports seconds precision!!!!!
|
||||
const mtimeSvr = Math.floor(x.LastModified!.valueOf() / 1000.0) * 1000;
|
||||
let mtimeCli = mtimeSvr;
|
||||
if (x.Metadata !== undefined) {
|
||||
if (useAccurateMTime && x.Metadata !== undefined) {
|
||||
const m2 = Math.floor(
|
||||
parseFloat(x.Metadata.mtime || x.Metadata.MTime || "0")
|
||||
);
|
||||
|
@ -561,7 +562,12 @@ export class FakeFsS3 extends FakeFs {
|
|||
})
|
||||
);
|
||||
|
||||
return fromS3HeadObjectToEntity(key, res, this.s3Config.remotePrefix ?? "");
|
||||
return fromS3HeadObjectToEntity(
|
||||
key,
|
||||
res,
|
||||
this.s3Config.remotePrefix ?? "",
|
||||
this.s3Config.useAccurateMTime ?? false
|
||||
);
|
||||
}
|
||||
|
||||
async mkdir(key: string, mtime?: number, ctime?: number): Promise<Entity> {
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
"statusbar_time_days": "Synced {{time}} days ago",
|
||||
"statusbar_time_hours": "Synced {{time}} hours ago",
|
||||
"statusbar_time_minutes": "Synced {{time}} minutes ago",
|
||||
"statusbar_time_lessminute": "Synced less than a minute ago",
|
||||
"statusbar_time_lessminute": "Synced last minute ago",
|
||||
"statusbar_lastsync": "Synced {{time}} ago",
|
||||
"statusbar_syncing": "Syncing...",
|
||||
"statusbar_now": "Synced just now",
|
||||
|
@ -342,5 +342,7 @@
|
|||
"syncalgov3_checkbox_manual_backup": "I will backup my vault manually firstly.",
|
||||
"syncalgov3_checkbox_requiremultidevupdate": "I understand I need to update the plugin ACROSS ALL DEVICES to make them work properly.",
|
||||
"syncalgov3_button_agree": "Agree",
|
||||
"syncalgov3_button_disagree": "Do Not Agree"
|
||||
"syncalgov3_button_disagree": "Do Not Agree",
|
||||
|
||||
"menu_check_file_stat": "Check file stats"
|
||||
}
|
||||
|
|
|
@ -341,5 +341,7 @@
|
|||
"syncalgov3_checkbox_manual_backup": "我将会首先手动备份我的库(Vault)。",
|
||||
"syncalgov3_checkbox_requiremultidevupdate": "我理解,我需要在所有设备上都更新此插件使之正常运行。",
|
||||
"syncalgov3_button_agree": "同意",
|
||||
"syncalgov3_button_disagree": "不同意"
|
||||
"syncalgov3_button_disagree": "不同意",
|
||||
|
||||
"menu_check_file_stat": "查看文件属性"
|
||||
}
|
||||
|
|
|
@ -340,5 +340,7 @@
|
|||
"syncalgov3_checkbox_manual_backup": "我將會首先手動備份我的庫(Vault)。",
|
||||
"syncalgov3_checkbox_requiremultidevupdate": "我理解,我需要在所有裝置上都更新此外掛使之正常執行。",
|
||||
"syncalgov3_button_agree": "同意",
|
||||
"syncalgov3_button_disagree": "不同意"
|
||||
"syncalgov3_button_disagree": "不同意",
|
||||
|
||||
"menu_check_file_stat": "檢視檔案屬性"
|
||||
}
|
||||
|
|
38
src/main.ts
38
src/main.ts
|
@ -9,6 +9,7 @@ import {
|
|||
Platform,
|
||||
requireApiVersion,
|
||||
Events,
|
||||
TFolder,
|
||||
} from "obsidian";
|
||||
import cloneDeep from "lodash/cloneDeep";
|
||||
import { createElement, RotateCcw, RefreshCcw, FileText } from "lucide";
|
||||
|
@ -783,6 +784,8 @@ export default class RemotelySavePlugin extends Plugin {
|
|||
// console.info("click", evt);
|
||||
// });
|
||||
|
||||
this.enableCheckingFileStat();
|
||||
|
||||
if (!this.settings.agreeToUseSyncV3) {
|
||||
const syncAlgoV3Modal = new SyncAlgoV3Modal(this.app, this);
|
||||
syncAlgoV3Modal.open();
|
||||
|
@ -1198,6 +1201,41 @@ export default class RemotelySavePlugin extends Plugin {
|
|||
});
|
||||
}
|
||||
|
||||
enableCheckingFileStat() {
|
||||
this.app.workspace.onLayoutReady(() => {
|
||||
const t = (x: TransItemType, vars?: any) => {
|
||||
return this.i18n.t(x, vars);
|
||||
};
|
||||
this.registerEvent(
|
||||
this.app.workspace.on("file-menu", (menu, file) => {
|
||||
if (file instanceof TFolder) {
|
||||
// folder not supported yet
|
||||
return;
|
||||
}
|
||||
|
||||
menu.addItem((item) => {
|
||||
item
|
||||
.setTitle(t("menu_check_file_stat"))
|
||||
.setIcon("file-cog")
|
||||
.onClick(async () => {
|
||||
const filePath = file.path;
|
||||
const fsLocal = new FakeFsLocal(
|
||||
this.app.vault,
|
||||
this.settings.syncConfigDir ?? false,
|
||||
this.app.vault.configDir,
|
||||
this.manifest.id,
|
||||
undefined,
|
||||
this.settings.deleteToWhere ?? "system"
|
||||
);
|
||||
const s = await fsLocal.stat(filePath);
|
||||
new Notice(JSON.stringify(s, null, 2), 10000);
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async saveAgreeToUseNewSyncAlgorithm() {
|
||||
this.settings.agreeToUseSyncV3 = true;
|
||||
await this.saveSettings();
|
||||
|
|
Loading…
Reference in New Issue