a large semi-rewrite of fs logic
This commit is contained in:
+171
@@ -0,0 +1,171 @@
|
||||
import { DEFAULT_DEBUG_FOLDER, Entity } from "./baseTypes";
|
||||
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";
|
||||
|
||||
export class FakeFsLocal extends FakeFs {
|
||||
vault: Vault;
|
||||
syncConfigDir: boolean;
|
||||
configDir: string;
|
||||
pluginID: string;
|
||||
profiler: Profiler;
|
||||
deleteToWhere: "obsidian" | "system";
|
||||
kind: "local";
|
||||
constructor(
|
||||
vault: Vault,
|
||||
syncConfigDir: boolean,
|
||||
configDir: string,
|
||||
pluginID: string,
|
||||
profiler: Profiler,
|
||||
deleteToWhere: "obsidian" | "system"
|
||||
) {
|
||||
super();
|
||||
|
||||
this.vault = vault;
|
||||
this.syncConfigDir = syncConfigDir;
|
||||
this.configDir = configDir;
|
||||
this.pluginID = pluginID;
|
||||
this.profiler = profiler;
|
||||
this.deleteToWhere = deleteToWhere;
|
||||
this.kind = "local";
|
||||
}
|
||||
|
||||
async walk(): Promise<Entity[]> {
|
||||
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");
|
||||
for (const entry of localTAbstractFiles) {
|
||||
let r: Entity | undefined = undefined;
|
||||
let key = entry.path;
|
||||
|
||||
if (entry.path === "/") {
|
||||
// ignore
|
||||
continue;
|
||||
} else if (entry instanceof TFile) {
|
||||
let mtimeLocal: number | undefined = entry.stat.mtime;
|
||||
if (mtimeLocal <= 0) {
|
||||
mtimeLocal = entry.stat.ctime;
|
||||
}
|
||||
if (mtimeLocal === 0) {
|
||||
mtimeLocal = undefined;
|
||||
}
|
||||
if (mtimeLocal === undefined) {
|
||||
throw Error(
|
||||
`Your file has last modified time 0: ${key}, don't know how to deal with it`
|
||||
);
|
||||
}
|
||||
r = {
|
||||
key: entry.path, // local always unencrypted
|
||||
keyRaw: entry.path,
|
||||
mtimeCli: mtimeLocal,
|
||||
mtimeSvr: mtimeLocal,
|
||||
size: entry.stat.size, // local always unencrypted
|
||||
sizeRaw: entry.stat.size,
|
||||
};
|
||||
} else if (entry instanceof TFolder) {
|
||||
key = `${entry.path}/`;
|
||||
r = {
|
||||
key: key,
|
||||
keyRaw: key,
|
||||
size: 0,
|
||||
sizeRaw: 0,
|
||||
};
|
||||
} else {
|
||||
throw Error(`unexpected ${entry}`);
|
||||
}
|
||||
|
||||
if (r.keyRaw.startsWith(DEFAULT_DEBUG_FOLDER)) {
|
||||
// skip listing the debug folder,
|
||||
// which should always not involved in sync
|
||||
continue;
|
||||
} else {
|
||||
local.push(r);
|
||||
}
|
||||
}
|
||||
|
||||
this.profiler.insert("finish transforming walk for local");
|
||||
|
||||
if (this.syncConfigDir) {
|
||||
this.profiler.insert("into syncConfigDir");
|
||||
const syncFiles = await listFilesInObsFolder(
|
||||
this.configDir,
|
||||
this.vault,
|
||||
this.pluginID
|
||||
);
|
||||
for (const f of syncFiles) {
|
||||
local.push(f);
|
||||
}
|
||||
this.profiler.insert("finish syncConfigDir");
|
||||
}
|
||||
|
||||
this.profiler.insert("finish walk for local");
|
||||
this.profiler.removeIndent();
|
||||
return local;
|
||||
}
|
||||
|
||||
async stat(key: string): Promise<Entity> {
|
||||
const statRes = await statFix(this.vault, key);
|
||||
if (statRes === undefined || statRes === null) {
|
||||
throw Error(`${key} does not exist! cannot stat for local`);
|
||||
}
|
||||
const isFolder = statRes.type === "folder";
|
||||
return {
|
||||
key: isFolder ? `${key}/` : key, // local always unencrypted
|
||||
keyRaw: isFolder ? `${key}/` : key,
|
||||
mtimeCli: statRes.mtime,
|
||||
mtimeSvr: statRes.mtime,
|
||||
size: statRes.size, // local always unencrypted
|
||||
sizeRaw: statRes.size,
|
||||
};
|
||||
}
|
||||
|
||||
async mkdir(key: string, mtime?: number, ctime?: number): Promise<Entity> {
|
||||
// console.debug(`mkdir: ${key}`);
|
||||
await mkdirpInVault(key, this.vault);
|
||||
return await this.stat(key);
|
||||
}
|
||||
|
||||
async writeFile(
|
||||
key: string,
|
||||
content: ArrayBuffer,
|
||||
mtime: number,
|
||||
ctime: number
|
||||
): Promise<Entity> {
|
||||
await this.vault.adapter.writeBinary(key, content, {
|
||||
mtime: mtime,
|
||||
});
|
||||
return await this.stat(key);
|
||||
}
|
||||
|
||||
async readFile(key: string): Promise<ArrayBuffer> {
|
||||
return await this.vault.adapter.readBinary(key);
|
||||
}
|
||||
|
||||
async rm(key: string): Promise<void> {
|
||||
if (this.deleteToWhere === "obsidian") {
|
||||
await this.vault.adapter.trashLocal(key);
|
||||
} else {
|
||||
// "system"
|
||||
if (!(await this.vault.adapter.trashSystem(key))) {
|
||||
await this.vault.adapter.trashLocal(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
async checkConnect(callbackFunc?: any): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
async getUserDisplayName(): Promise<string> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
async revokeAuth(): Promise<any> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user