Compare commits

..
9 Commits
Author SHA1 Message Date
fyears 62b176d709 bump to beta 0.4.4
Release A New Version / build (16.x) (push) Failing after 41s
2024-03-18 02:21:25 +08:00
fyears 9553bff44a mobile status bar 2024-03-18 02:20:56 +08:00
fyears ede1f4e1bc obfuscateSettingFile 2024-03-18 01:45:33 +08:00
fyears 97f4c0c427 fix grammar 2024-03-18 01:30:47 +08:00
fyears 94a56dabdd add debug log 2024-03-18 01:30:29 +08:00
fyears 4947eb91a2 bump to beta 0.4.3
Release A New Version / build (16.x) (push) Failing after 44s
2024-03-18 00:49:15 +08:00
fyears 2d12c9977d fix param 2024-03-18 00:48:53 +08:00
fyears f2794ac539 bump to beta 0.4.2
Release A New Version / build (16.x) (push) Failing after 40s
2024-03-18 00:46:02 +08:00
fyears 519fd27dd5 fix s3 time 2024-03-18 00:45:28 +08:00
11 changed files with 167 additions and 27 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"id": "remotely-save", "id": "remotely-save",
"name": "Remotely Save", "name": "Remotely Save",
"version": "0.4.1", "version": "0.4.4",
"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",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "remotely-save", "name": "remotely-save",
"version": "0.4.1", "version": "0.4.4",
"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 --watch", "dev2": "node esbuild.config.mjs --watch",
+4
View File
@@ -115,6 +115,10 @@ export interface RemotelySavePluginSettings {
protectModifyPercentage?: number; protectModifyPercentage?: number;
syncDirection?: SyncDirectionType; syncDirection?: SyncDirectionType;
obfuscateSettingFile?: boolean;
enableMobileStatusBar?: boolean;
/** /**
* @deprecated * @deprecated
*/ */
+13 -9
View File
@@ -7,25 +7,25 @@
"sometext": "Here are some texts.", "sometext": "Here are some texts.",
"syncrun_alreadyrunning": "{{pluginName}} already running in stage {{syncStatus}}!", "syncrun_alreadyrunning": "{{pluginName}} already running in stage {{syncStatus}}!",
"syncrun_syncingribbon": "{{pluginName}}: syncing from {{triggerSource}}", "syncrun_syncingribbon": "{{pluginName}}: syncing from {{triggerSource}}",
"syncrun_step0": "0/8 Remotely Save running in dry mode, not actual file changes would happen.", "syncrun_step0": "0/8 Remotely Save is running in dry mode, thus not actual file changes would happen.",
"syncrun_step1": "1/8 Remotely Save Sync Preparing ({{serviceType}})", "syncrun_step1": "1/8 Remotely Save is preparing ({{serviceType}})",
"syncrun_step2": "2/8 Starting to fetch remote meta data.", "syncrun_step2": "2/8 Starting to fetch remote meta data.",
"syncrun_step3": "3/8 Checking password correct or not.", "syncrun_step3": "3/8 Checking password correct or not.",
"syncrun_passworderr": "Something goes wrong while checking password.", "syncrun_passworderr": "Something goes wrong while checking password.",
"syncrun_step4": "4/8 Starting to fetch local meta data.", "syncrun_step4": "4/8 Starting to fetch local meta data.",
"syncrun_step5": "5/8 Starting to fetch local prev sync data.", "syncrun_step5": "5/8 Starting to fetch local prev sync data.",
"syncrun_step6": "6/8 Starting to generate sync plan.", "syncrun_step6": "6/8 Starting to generate sync plan.",
"syncrun_step7": "7/8 Remotely Save Sync data exchanging!", "syncrun_step7": "7/8 Remotely Save Sync data is exchanging!",
"syncrun_step7skip": "7/8 Remotely Save real sync is skipped in dry run mode.", "syncrun_step7skip": "7/8 Remotely Save real sync is skipped in dry run mode.",
"syncrun_step8": "8/8 Remotely Save finish!", "syncrun_step8": "8/8 Remotely Save finished!",
"syncrun_shortstep0": "0/2 Remotely Save running in dry mode, not actual file changes would happen.", "syncrun_shortstep0": "0/2 Remotely Save is running in dry mode, not actual file changes would happen.",
"syncrun_shortstep1": "1/2 Remotely Save Sync Start Running ({{serviceType}})", "syncrun_shortstep1": "1/2 Remotely Save starts running ({{serviceType}})",
"syncrun_shortstep2skip": "2/2 Remotely Save real sync is skipped in dry run mode.", "syncrun_shortstep2skip": "2/2 Remotely Save real sync is skipped in dry run mode.",
"syncrun_shortstep2": "2/2 Remotely Save finish!", "syncrun_shortstep2": "2/2 Remotely Save finished!",
"syncrun_abort": "{{manifestID}}-{{theDate}}: abort sync, triggerSource={{triggerSource}}, error while {{syncStatus}}", "syncrun_abort": "{{manifestID}}-{{theDate}}: abort sync, triggerSource={{triggerSource}}, error while {{syncStatus}}",
"syncrun_abort_protectmodifypercentage": "Abort! you set changing files >= {{protectModifyPercentage}}% is not allowed but {{realModifyDeleteCount}}/{{allFilesCount}}={{percent}}% is going to be modified or deleted! If you are sure you want this sync, please adjust the allowed ratio in the settings.", "syncrun_abort_protectmodifypercentage": "Abort! you set changing files >= {{protectModifyPercentage}}% is not allowed but {{realModifyDeleteCount}}/{{allFilesCount}}={{percent}}% is going to be modified or deleted! If you are sure you want this sync, please adjust the allowed ratio in the settings.",
"protocol_saveqr": "New not-oauth2 settings for {{manifestName}} saved. Reopen the plugin Settings to the effect.", "protocol_saveqr": "New not-oauth2 settings for {{manifestName}} is saved. Reopen the plugin settings to make it effective.",
"protocol_callbacknotsupported": "Your uri call a callback that's not supported yet: {{params}}", "protocol_callbacknotsupported": "Your uri calls a callback that's not supported yet: {{params}}",
"protocol_dropbox_connecting": "Connecting to Dropbox...\nPlease DO NOT close this modal.", "protocol_dropbox_connecting": "Connecting to Dropbox...\nPlease DO NOT close this modal.",
"protocol_dropbox_connect_succ": "Good! We've connected to Dropbox as user {{username}}!", "protocol_dropbox_connect_succ": "Good! We've connected to Dropbox as user {{username}}!",
"protocol_dropbox_connect_succ_revoke": "You've connected as user {{username}}. If you want to disconnect, click this button.", "protocol_dropbox_connect_succ_revoke": "You've connected as user {{username}}. If you want to disconnect, click this button.",
@@ -264,6 +264,8 @@
"setting_syncdirection_bidirectional_desc": "Bidirectional (default)", "setting_syncdirection_bidirectional_desc": "Bidirectional (default)",
"setting_syncdirection_incremental_push_only_desc": "Incremental Push Only (aka backup mode)", "setting_syncdirection_incremental_push_only_desc": "Incremental Push Only (aka backup mode)",
"setting_syncdirection_incremental_pull_only_desc": "Incremental Pull Only", "setting_syncdirection_incremental_pull_only_desc": "Incremental Pull Only",
"settings_enablemobilestatusbar": "Enable Mobile Status Bar Or Not",
"settings_enablemobilestatusbar_desc": "By default Obsidian mobile hides status bar. But some users want to show it up. So here is a hack.",
"settings_importexport": "Import and Export Partial Settings", "settings_importexport": "Import and Export Partial Settings",
"settings_export": "Export", "settings_export": "Export",
"settings_export_desc": "Export not-oauth2 settings by generating a qrcode.", "settings_export_desc": "Export not-oauth2 settings by generating a qrcode.",
@@ -277,6 +279,8 @@
"settings_outputsettingsconsole_desc": "The settings save on disk in encoded. Click this to see the decoded settings in console.", "settings_outputsettingsconsole_desc": "The settings save on disk in encoded. Click this to see the decoded settings in console.",
"settings_outputsettingsconsole_button": "Output", "settings_outputsettingsconsole_button": "Output",
"settings_outputsettingsconsole_notice": "Finished outputing in console.", "settings_outputsettingsconsole_notice": "Finished outputing in console.",
"settings_obfuscatesettingfile": "Obfuscate The Setting File Or Not",
"settings_obfuscatesettingfile_desc": "The setting file (data.json) has some sensitive information. It's strongly recommended to obfuscate it to avoid unexpected read and modification. If you are sure to view and edit it manually, you can disable the obfuscation.",
"settings_viewconsolelog": "View Console Log", "settings_viewconsolelog": "View Console Log",
"settings_viewconsolelog_desc": "On desktop, please press \"ctrl+shift+i\" or \"cmd+shift+i\" to view the log. On mobile, please install the third-party plugin <a href='https://obsidian.md/plugins?search=Logstravaganza'>Logstravaganza</a> to export the console log to a note.", "settings_viewconsolelog_desc": "On desktop, please press \"ctrl+shift+i\" or \"cmd+shift+i\" to view the log. On mobile, please install the third-party plugin <a href='https://obsidian.md/plugins?search=Logstravaganza'>Logstravaganza</a> to export the console log to a note.",
"settings_syncplans": "Export Sync Plans", "settings_syncplans": "Export Sync Plans",
+4
View File
@@ -264,6 +264,8 @@
"setting_syncdirection_bidirectional_desc": "双向同步(默认)", "setting_syncdirection_bidirectional_desc": "双向同步(默认)",
"setting_syncdirection_incremental_push_only_desc": "只增量推送(也即:备份模式)", "setting_syncdirection_incremental_push_only_desc": "只增量推送(也即:备份模式)",
"setting_syncdirection_incremental_pull_only_desc": "只增量拉取", "setting_syncdirection_incremental_pull_only_desc": "只增量拉取",
"settings_enablemobilestatusbar": "是否显示手机的状态栏",
"settings_enablemobilestatusbar_desc": "Obsidian 手机版默认隐藏了状态栏。有些用户希望展示它。这里提供了设置选项。",
"settings_importexport": "导入导出部分设置", "settings_importexport": "导入导出部分设置",
"settings_export": "导出", "settings_export": "导出",
"settings_export_desc": "用 QR 码导出非 oauth2 的设置信息。", "settings_export_desc": "用 QR 码导出非 oauth2 的设置信息。",
@@ -277,6 +279,8 @@
"settings_outputsettingsconsole_desc": "硬盘上的设置文件是编码过的,点击这里从而解码并输出到终端。", "settings_outputsettingsconsole_desc": "硬盘上的设置文件是编码过的,点击这里从而解码并输出到终端。",
"settings_outputsettingsconsole_button": "输出", "settings_outputsettingsconsole_button": "输出",
"settings_outputsettingsconsole_notice": "已输出到终端", "settings_outputsettingsconsole_notice": "已输出到终端",
"settings_obfuscatesettingfile": "是否混淆保存设置文件",
"settings_obfuscatesettingfile_desc": "设置文件(data.json)含有敏感信息。强烈建议混淆后保存它,从而避免出乎意料的读取和修改。如果您确认要手动查看和修改它,可以关闭混淆保存。",
"settings_viewconsolelog": "查看终端输出", "settings_viewconsolelog": "查看终端输出",
"settings_viewconsolelog_desc": "电脑上,输入“ctrl+shift+i”或“cmd+shift+i”来查看终端输出。手机上,安装第三方插件 <a href='https://obsidian.md/plugins?search=Logstravaganza'>Logstravaganza</a> 来导出终端输出到一篇笔记上。", "settings_viewconsolelog_desc": "电脑上,输入“ctrl+shift+i”或“cmd+shift+i”来查看终端输出。手机上,安装第三方插件 <a href='https://obsidian.md/plugins?search=Logstravaganza'>Logstravaganza</a> 来导出终端输出到一篇笔记上。",
"settings_syncplans": "导出同步计划", "settings_syncplans": "导出同步计划",
+4
View File
@@ -264,6 +264,8 @@
"setting_syncdirection_bidirectional_desc": "雙向同步(預設)", "setting_syncdirection_bidirectional_desc": "雙向同步(預設)",
"setting_syncdirection_incremental_push_only_desc": "只增量推送(也即:備份模式)", "setting_syncdirection_incremental_push_only_desc": "只增量推送(也即:備份模式)",
"setting_syncdirection_incremental_pull_only_desc": "只增量拉取", "setting_syncdirection_incremental_pull_only_desc": "只增量拉取",
"settings_enablemobilestatusbar": "是否顯示手機的狀態列",
"settings_enablemobilestatusbar_desc": "Obsidian 手機版預設隱藏了狀態列。有些使用者希望展示它。這裡提供了設定選項。",
"settings_importexport": "匯入匯出部分設定", "settings_importexport": "匯入匯出部分設定",
"settings_export": "匯出", "settings_export": "匯出",
"settings_export_desc": "用 QR 碼匯出非 oauth2 的設定資訊。", "settings_export_desc": "用 QR 碼匯出非 oauth2 的設定資訊。",
@@ -277,6 +279,8 @@
"settings_outputsettingsconsole_desc": "硬碟上的設定檔案是編碼過的,點選這裡從而解碼並輸出到終端。", "settings_outputsettingsconsole_desc": "硬碟上的設定檔案是編碼過的,點選這裡從而解碼並輸出到終端。",
"settings_outputsettingsconsole_button": "輸出", "settings_outputsettingsconsole_button": "輸出",
"settings_outputsettingsconsole_notice": "已輸出到終端", "settings_outputsettingsconsole_notice": "已輸出到終端",
"settings_obfuscatesettingfile": "是否混淆儲存設定檔案",
"settings_obfuscatesettingfile_desc": "設定檔案(data.json)含有敏感資訊。強烈建議混淆後儲存它,從而避免出乎意料的讀取和修改。如果您確認要手動檢視和修改它,可以關閉混淆儲存。",
"settings_viewconsolelog": "檢視終端輸出", "settings_viewconsolelog": "檢視終端輸出",
"settings_viewconsolelog_desc": "電腦上,輸入“ctrl+shift+i”或“cmd+shift+i”來檢視終端輸出。手機上,安裝第三方外掛 <a href='https://obsidian.md/plugins?search=Logstravaganza'>Logstravaganza</a> 來匯出終端輸出到一篇筆記上。", "settings_viewconsolelog_desc": "電腦上,輸入“ctrl+shift+i”或“cmd+shift+i”來檢視終端輸出。手機上,安裝第三方外掛 <a href='https://obsidian.md/plugins?search=Logstravaganza'>Logstravaganza</a> 來匯出終端輸出到一篇筆記上。",
"settings_syncplans": "匯出同步計劃", "settings_syncplans": "匯出同步計劃",
+31 -4
View File
@@ -66,7 +66,7 @@ import { SyncAlgoV3Modal } from "./syncAlgoV3Notice";
import AggregateError from "aggregate-error"; import AggregateError from "aggregate-error";
import { exportVaultSyncPlansToFiles } from "./debugMode"; import { exportVaultSyncPlansToFiles } from "./debugMode";
import { compareVersion } from "./misc"; import { changeMobileStatusBar, compareVersion } from "./misc";
const DEFAULT_SETTINGS: RemotelySavePluginSettings = { const DEFAULT_SETTINGS: RemotelySavePluginSettings = {
s3: DEFAULT_S3_CONFIG, s3: DEFAULT_S3_CONFIG,
@@ -95,6 +95,8 @@ const DEFAULT_SETTINGS: RemotelySavePluginSettings = {
howToCleanEmptyFolder: "skip", howToCleanEmptyFolder: "skip",
protectModifyPercentage: 50, protectModifyPercentage: 50,
syncDirection: "bidirectional", syncDirection: "bidirectional",
obfuscateSettingFile: true,
enableMobileStatusBar: false,
}; };
interface OAuth2Info { interface OAuth2Info {
@@ -304,7 +306,8 @@ export default class RemotelySavePlugin extends Plugin {
this.app.vault.configDir, this.app.vault.configDir,
this.settings.syncUnderscoreItems ?? false, this.settings.syncUnderscoreItems ?? false,
this.settings.ignorePaths ?? [], this.settings.ignorePaths ?? [],
this.settings.password this.settings.password,
this.settings.serviceType
); );
mixedEntityMappings = await getSyncPlanInplace( mixedEntityMappings = await getSyncPlanInplace(
mixedEntityMappings, mixedEntityMappings,
@@ -720,8 +723,14 @@ export default class RemotelySavePlugin extends Plugin {
async () => this.syncRun("manual") async () => this.syncRun("manual")
); );
// Create Status Bar Item (not supported on mobile) this.enableMobileStatusBarIfSet();
if (!Platform.isMobileApp && this.settings.enableStatusBarInfo === true) {
// Create Status Bar Item
if (
(!Platform.isMobile ||
(Platform.isMobile && this.settings.enableMobileStatusBar)) &&
this.settings.enableStatusBarInfo === true
) {
const statusBarItem = this.addStatusBarItem(); const statusBarItem = this.addStatusBarItem();
this.statusBarElement = statusBarItem.createEl("span"); this.statusBarElement = statusBarItem.createEl("span");
this.statusBarElement.setAttribute("data-tooltip-position", "top"); this.statusBarElement.setAttribute("data-tooltip-position", "top");
@@ -894,11 +903,23 @@ export default class RemotelySavePlugin extends Plugin {
this.settings.syncDirection = "bidirectional"; this.settings.syncDirection = "bidirectional";
} }
if (this.settings.obfuscateSettingFile === undefined) {
this.settings.obfuscateSettingFile = true;
}
if (this.settings.enableMobileStatusBar === undefined) {
this.settings.enableMobileStatusBar = false;
}
await this.saveSettings(); await this.saveSettings();
} }
async saveSettings() { async saveSettings() {
if (this.settings.obfuscateSettingFile) {
await this.saveData(normalConfigToMessy(this.settings)); await this.saveData(normalConfigToMessy(this.settings));
} else {
await this.saveData(this.settings);
}
} }
/** /**
@@ -1125,6 +1146,12 @@ export default class RemotelySavePlugin extends Plugin {
} }
} }
enableMobileStatusBarIfSet() {
if (Platform.isMobile && this.settings.enableMobileStatusBar) {
changeMobileStatusBar("enable");
}
}
async saveAgreeToUseNewSyncAlgorithm() { async saveAgreeToUseNewSyncAlgorithm() {
this.settings.agreeToUseSyncV3 = true; this.settings.agreeToUseSyncV3 = true;
await this.saveSettings(); await this.saveSettings();
+20
View File
@@ -503,3 +503,23 @@ export const stringToFragment = (string: string) => {
wrapper.innerHTML = string; wrapper.innerHTML = string;
return wrapper.content; return wrapper.content;
}; };
/**
* https://forum.obsidian.md/t/css-to-show-status-bar-on-mobile-devices/77185
* @param op
*/
export const changeMobileStatusBar = (op: "enable" | "disable") => {
if (op === "enable") {
(
document.querySelector(
".is-mobile .app-container .status-bar"
) as HTMLElement
).style.setProperty("display", "flex");
} else {
(
document.querySelector(
".is-mobile .app-container .status-bar"
) as HTMLElement
).style.setProperty("display", "none");
}
};
+3 -3
View File
@@ -257,7 +257,7 @@ const fromS3HeadObjectToEntity = (
const mtimeSvr = Math.floor(x.LastModified!.valueOf() / 1000.0) * 1000; const mtimeSvr = Math.floor(x.LastModified!.valueOf() / 1000.0) * 1000;
let mtimeCli = mtimeSvr; let mtimeCli = mtimeSvr;
if (x.Metadata !== undefined) { if (x.Metadata !== undefined) {
const m2 = Math.round( const m2 = Math.floor(
parseFloat(x.Metadata.mtime || x.Metadata.MTime || "0") parseFloat(x.Metadata.mtime || x.Metadata.MTime || "0")
); );
if (m2 !== 0) { if (m2 !== 0) {
@@ -539,12 +539,12 @@ const listFromRemoteRaw = async (
if (rspHead.Metadata === undefined) { if (rspHead.Metadata === undefined) {
// pass // pass
} else { } else {
mtimeRecords[content.Key!] = Math.round( mtimeRecords[content.Key!] = Math.floor(
parseFloat( parseFloat(
rspHead.Metadata.mtime || rspHead.Metadata.MTime || "0" rspHead.Metadata.mtime || rspHead.Metadata.MTime || "0"
) )
); );
ctimeRecords[content.Key!] = Math.round( ctimeRecords[content.Key!] = Math.floor(
parseFloat( parseFloat(
rspHead.Metadata.ctime || rspHead.Metadata.CTime || "0" rspHead.Metadata.ctime || rspHead.Metadata.CTime || "0"
) )
+59 -1
View File
@@ -45,7 +45,11 @@ import {
} from "./remoteForOnedrive"; } from "./remoteForOnedrive";
import { messyConfigToNormal } from "./configPersist"; import { messyConfigToNormal } from "./configPersist";
import type { TransItemType } from "./i18n"; import type { TransItemType } from "./i18n";
import { checkHasSpecialCharForDir, stringToFragment } from "./misc"; import {
changeMobileStatusBar,
checkHasSpecialCharForDir,
stringToFragment,
} from "./misc";
import { simpleTransRemotePrefix } from "./remoteForS3"; import { simpleTransRemotePrefix } from "./remoteForS3";
class PasswordModal extends Modal { class PasswordModal extends Modal {
@@ -2017,6 +2021,36 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
}); });
}); });
if (Platform.isMobile) {
new Setting(advDiv)
.setName(t("settings_enablemobilestatusbar"))
.setDesc(t("settings_enablemobilestatusbar_desc"))
.addDropdown(async (dropdown) => {
dropdown
.addOption("enable", t("enable"))
.addOption("disable", t("disable"));
dropdown
.setValue(
`${
this.plugin.settings.enableMobileStatusBar
? "enable"
: "disable"
}`
)
.onChange(async (val) => {
if (val === "enable") {
this.plugin.settings.enableMobileStatusBar = true;
changeMobileStatusBar("enable");
} else {
this.plugin.settings.enableMobileStatusBar = false;
changeMobileStatusBar("disable");
}
await this.plugin.saveSettings();
});
});
}
////////////////////////////////////////////////// //////////////////////////////////////////////////
// below for import and export functions // below for import and export functions
////////////////////////////////////////////////// //////////////////////////////////////////////////
@@ -2075,6 +2109,30 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
}); });
}); });
new Setting(debugDiv)
.setName(t("settings_obfuscatesettingfile"))
.setDesc(t("settings_obfuscatesettingfile_desc"))
.addDropdown(async (dropdown) => {
dropdown
.addOption("enable", t("enable"))
.addOption("disable", t("disable"));
dropdown
.setValue(
`${
this.plugin.settings.obfuscateSettingFile ? "enable" : "disable"
}`
)
.onChange(async (val) => {
if (val === "enable") {
this.plugin.settings.obfuscateSettingFile = true;
} else {
this.plugin.settings.obfuscateSettingFile = false;
}
await this.plugin.saveSettings();
});
});
new Setting(debugDiv) new Setting(debugDiv)
.setName(t("settings_viewconsolelog")) .setName(t("settings_viewconsolelog"))
.setDesc(stringToFragment(t("settings_viewconsolelog_desc"))); .setDesc(stringToFragment(t("settings_viewconsolelog_desc")));
+26 -7
View File
@@ -5,6 +5,7 @@ import type {
EmptyFolderCleanType, EmptyFolderCleanType,
Entity, Entity,
MixedEntity, MixedEntity,
SUPPORTED_SERVICES_TYPE,
SyncDirectionType, SyncDirectionType,
} from "./baseTypes"; } from "./baseTypes";
import { isInsideObsFolder } from "./obsFolderLister"; import { isInsideObsFolder } from "./obsFolderLister";
@@ -186,12 +187,19 @@ const isSkipItemByName = (
); );
}; };
const copyEntityAndFixTimeFormat = (src: Entity) => { const copyEntityAndFixTimeFormat = (
src: Entity,
serviceType: SUPPORTED_SERVICES_TYPE
) => {
const result = Object.assign({}, src); const result = Object.assign({}, src);
if (result.mtimeCli !== undefined) { if (result.mtimeCli !== undefined) {
if (result.mtimeCli === 0) { if (result.mtimeCli === 0) {
result.mtimeCli = undefined; result.mtimeCli = undefined;
} else { } else {
if (serviceType === "s3") {
// round to second instead of millisecond
result.mtimeCli = Math.floor(result.mtimeCli / 1000.0) * 1000;
}
result.mtimeCliFmt = unixTimeToStr(result.mtimeCli); result.mtimeCliFmt = unixTimeToStr(result.mtimeCli);
} }
} }
@@ -199,6 +207,10 @@ const copyEntityAndFixTimeFormat = (src: Entity) => {
if (result.mtimeSvr === 0) { if (result.mtimeSvr === 0) {
result.mtimeSvr = undefined; result.mtimeSvr = undefined;
} else { } else {
if (serviceType === "s3") {
// round to second instead of millisecond
result.mtimeSvr = Math.floor(result.mtimeSvr / 1000.0) * 1000;
}
result.mtimeSvrFmt = unixTimeToStr(result.mtimeSvr); result.mtimeSvrFmt = unixTimeToStr(result.mtimeSvr);
} }
} }
@@ -206,6 +218,10 @@ const copyEntityAndFixTimeFormat = (src: Entity) => {
if (result.prevSyncTime === 0) { if (result.prevSyncTime === 0) {
result.prevSyncTime = undefined; result.prevSyncTime = undefined;
} else { } else {
if (serviceType === "s3") {
// round to second instead of millisecond
result.prevSyncTime = Math.floor(result.prevSyncTime / 1000.0) * 1000;
}
result.prevSyncTimeFmt = unixTimeToStr(result.prevSyncTime); result.prevSyncTimeFmt = unixTimeToStr(result.prevSyncTime);
} }
} }
@@ -361,7 +377,8 @@ export const ensembleMixedEnties = async (
configDir: string, configDir: string,
syncUnderscoreItems: boolean, syncUnderscoreItems: boolean,
ignorePaths: string[], ignorePaths: string[],
password: string password: string,
serviceType: SUPPORTED_SERVICES_TYPE
): Promise<SyncPlanType> => { ): Promise<SyncPlanType> => {
const finalMappings: SyncPlanType = {}; const finalMappings: SyncPlanType = {};
@@ -369,7 +386,7 @@ export const ensembleMixedEnties = async (
for (const remote of remoteEntityList) { for (const remote of remoteEntityList) {
const remoteCopied = ensureMTimeOfRemoteEntityValid( const remoteCopied = ensureMTimeOfRemoteEntityValid(
await decryptRemoteEntityInplace( await decryptRemoteEntityInplace(
copyEntityAndFixTimeFormat(remote), copyEntityAndFixTimeFormat(remote, serviceType),
password password
) )
); );
@@ -418,14 +435,14 @@ export const ensembleMixedEnties = async (
if (finalMappings.hasOwnProperty(key)) { if (finalMappings.hasOwnProperty(key)) {
const prevSyncCopied = await encryptLocalEntityInplace( const prevSyncCopied = await encryptLocalEntityInplace(
copyEntityAndFixTimeFormat(prevSync), copyEntityAndFixTimeFormat(prevSync, serviceType),
password, password,
finalMappings[key].remote?.keyEnc finalMappings[key].remote?.keyEnc
); );
finalMappings[key].prevSync = prevSyncCopied; finalMappings[key].prevSync = prevSyncCopied;
} else { } else {
const prevSyncCopied = await encryptLocalEntityInplace( const prevSyncCopied = await encryptLocalEntityInplace(
copyEntityAndFixTimeFormat(prevSync), copyEntityAndFixTimeFormat(prevSync, serviceType),
password, password,
undefined undefined
); );
@@ -456,14 +473,14 @@ export const ensembleMixedEnties = async (
if (finalMappings.hasOwnProperty(key)) { if (finalMappings.hasOwnProperty(key)) {
const localCopied = await encryptLocalEntityInplace( const localCopied = await encryptLocalEntityInplace(
copyEntityAndFixTimeFormat(local), copyEntityAndFixTimeFormat(local, serviceType),
password, password,
finalMappings[key].remote?.keyEnc finalMappings[key].remote?.keyEnc
); );
finalMappings[key].local = localCopied; finalMappings[key].local = localCopied;
} else { } else {
const localCopied = await encryptLocalEntityInplace( const localCopied = await encryptLocalEntityInplace(
copyEntityAndFixTimeFormat(local), copyEntityAndFixTimeFormat(local, serviceType),
password, password,
undefined undefined
); );
@@ -474,6 +491,8 @@ export const ensembleMixedEnties = async (
} }
} }
console.debug("in the end of ensembleMixedEnties, finalMappings is:");
console.debug(finalMappings);
return finalMappings; return finalMappings;
}; };