track deletions of .obsidian

This commit is contained in:
fyears 2024-01-06 11:44:34 +08:00
parent 832828e6f6
commit c3ed69af66
4 changed files with 110 additions and 27 deletions

View File

@ -330,7 +330,7 @@ export const clearDeleteRenameHistoryOfKeyAndVault = async (
export const insertDeleteRecordByVault = async ( export const insertDeleteRecordByVault = async (
db: InternalDBs, db: InternalDBs,
fileOrFolder: TAbstractFile, fileOrFolder: TAbstractFile | string,
vaultRandomID: string vaultRandomID: string
) => { ) => {
// log.info(fileOrFolder); // log.info(fileOrFolder);
@ -347,6 +347,7 @@ export const insertDeleteRecordByVault = async (
renameTo: "", renameTo: "",
vaultRandomID: vaultRandomID, vaultRandomID: vaultRandomID,
}; };
await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k);
} else if (fileOrFolder instanceof TFolder) { } else if (fileOrFolder instanceof TFolder) {
// key should endswith "/" // key should endswith "/"
const key = fileOrFolder.path.endsWith("/") const key = fileOrFolder.path.endsWith("/")
@ -365,8 +366,57 @@ export const insertDeleteRecordByVault = async (
renameTo: "", renameTo: "",
vaultRandomID: vaultRandomID, vaultRandomID: vaultRandomID,
}; };
await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k);
} else if (typeof fileOrFolder === "string") {
// always the deletions in .obsidian folder
// so annoying that the path doesn't exists
// and we have to guess whether the path is folder or file
k = {
key: fileOrFolder,
ctime: 0,
mtime: 0,
size: 0,
actionWhen: Date.now(),
actionType: "delete",
keyType: "file",
renameTo: "",
vaultRandomID: vaultRandomID,
};
await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k);
for (const ext of [
"json",
"js",
"mjs",
"ts",
"md",
"txt",
"css",
"png",
"gif",
"jpg",
"jpeg",
"gitignore",
"gitkeep",
]) {
if (fileOrFolder.endsWith(`.${ext}`)) {
// stop here, no more need to insert the folder record later
return;
}
}
// also add a deletion record as folder if not ending with special exts
k = {
key: `${fileOrFolder}/`,
ctime: 0,
mtime: 0,
size: 0,
actionWhen: Date.now(),
actionType: "delete",
keyType: "folder",
renameTo: "",
vaultRandomID: vaultRandomID,
};
await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k);
} }
await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k);
}; };
/** /**

View File

@ -7,6 +7,8 @@ import {
setIcon, setIcon,
FileSystemAdapter, FileSystemAdapter,
Platform, Platform,
TFile,
TFolder,
} from "obsidian"; } from "obsidian";
import cloneDeep from "lodash/cloneDeep"; import cloneDeep from "lodash/cloneDeep";
import { createElement, RotateCcw, RefreshCcw, FileText } from "lucide"; import { createElement, RotateCcw, RefreshCcw, FileText } from "lucide";
@ -496,6 +498,31 @@ export default class RemotelySavePlugin extends Plugin {
}) })
); );
function getMethods(obj: any) {
var result = [];
for (var id in obj) {
try {
if (typeof obj[id] == "function") {
result.push(id + ": " + obj[id].toString());
}
} catch (err) {
result.push(id + ": inaccessible");
}
}
return result.join("\n");
}
this.registerEvent(
this.app.vault.on("raw" as any, async (fileOrFolder) => {
// special track on .obsidian folder
const name = `${fileOrFolder}`;
if (name.startsWith(this.app.vault.configDir)) {
if (!(await this.app.vault.adapter.exists(name))) {
await insertDeleteRecordByVault(this.db, name, this.vaultRandomID);
}
}
})
);
this.registerObsidianProtocolHandler(COMMAND_URI, async (inputParams) => { this.registerObsidianProtocolHandler(COMMAND_URI, async (inputParams) => {
const parsed = importQrCodeUri(inputParams, this.app.vault.getName()); const parsed = importQrCodeUri(inputParams, this.app.vault.getName());
if (parsed.status === "error") { if (parsed.status === "error") {

View File

@ -427,3 +427,31 @@ export const statFix = async (vault: Vault, path: string) => {
} }
return s; return s;
}; };
export const isFolderToSkip = (x: string, more: string[] | undefined) => {
let specialFolders = [
".git",
".github",
".gitlab",
".svn",
"node_modules",
".DS_Store",
"__MACOSX ",
"Icon\r", // https://superuser.com/questions/298785/icon-file-on-os-x-desktop
"desktop.ini",
"Desktop.ini",
"thumbs.db",
"Thumbs.db",
].concat(more !== undefined ? more : []);
for (const iterator of specialFolders) {
if (
x === iterator ||
x === `${iterator}/` ||
x.endsWith(`/${iterator}`) ||
x.endsWith(`/${iterator}/`)
) {
return true;
}
}
return false;
};

View File

@ -2,7 +2,7 @@ import { Vault, Stat, ListedFiles } from "obsidian";
import { Queue } from "@fyears/tsqueue"; import { Queue } from "@fyears/tsqueue";
import chunk from "lodash/chunk"; import chunk from "lodash/chunk";
import flatten from "lodash/flatten"; import flatten from "lodash/flatten";
import { statFix } from "./misc"; import { statFix, isFolderToSkip } from "./misc";
export interface ObsConfigDirFileType { export interface ObsConfigDirFileType {
key: string; key: string;
@ -12,28 +12,6 @@ export interface ObsConfigDirFileType {
type: "folder" | "file"; type: "folder" | "file";
} }
const isFolderToSkip = (x: string) => {
let specialFolders = [
".git",
".github",
".gitlab",
".svn",
"node_modules",
".DS_Store",
];
for (const iterator of specialFolders) {
if (
x === iterator ||
x === `${iterator}/` ||
x.endsWith(`/${iterator}`) ||
x.endsWith(`/${iterator}/`)
) {
return true;
}
}
return false;
};
const isPluginDirItself = (x: string, pluginId: string) => { const isPluginDirItself = (x: string, pluginId: string) => {
return ( return (
x === pluginId || x === pluginId ||
@ -106,7 +84,7 @@ export const listFilesInObsFolder = async (
const isInsideSelfPlugin = isPluginDirItself(iter.itself.key, pluginId); const isInsideSelfPlugin = isPluginDirItself(iter.itself.key, pluginId);
if (iter.children !== undefined) { if (iter.children !== undefined) {
for (const iter2 of iter.children.folders) { for (const iter2 of iter.children.folders) {
if (isFolderToSkip(iter2)) { if (isFolderToSkip(iter2, ["workspace", "workspace.json"])) {
continue; continue;
} }
if (isInsideSelfPlugin && !isLikelyPluginSubFiles(iter2)) { if (isInsideSelfPlugin && !isLikelyPluginSubFiles(iter2)) {
@ -116,7 +94,7 @@ export const listFilesInObsFolder = async (
q.push(iter2); q.push(iter2);
} }
for (const iter2 of iter.children.files) { for (const iter2 of iter.children.files) {
if (isFolderToSkip(iter2)) { if (isFolderToSkip(iter2, ["workspace", "workspace.json"])) {
continue; continue;
} }
if (isInsideSelfPlugin && !isLikelyPluginSubFiles(iter2)) { if (isInsideSelfPlugin && !isLikelyPluginSubFiles(iter2)) {