mirror of
https://github.com/remotely-save/remotely-save.git
synced 2024-06-07 21:10:45 +00:00
track local history
This commit is contained in:
parent
9ea3bdca7e
commit
c75962aad5
@ -30,6 +30,7 @@
|
||||
"@types/mime-types": "^2.1.1",
|
||||
"aws-crt": "^1.10.1",
|
||||
"codemirror": "^5.63.1",
|
||||
"lovefield-ts": "^0.7.0",
|
||||
"mime-types": "^2.1.33",
|
||||
"obsidian": "^0.12.0",
|
||||
"rimraf": "^3.0.2",
|
||||
|
53
src/localdb.ts
Normal file
53
src/localdb.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import * as lf from "lovefield-ts/dist/es6/lf.js";
|
||||
|
||||
export type DatabaseConnection = lf.DatabaseConnection;
|
||||
|
||||
export const DEFAULT_DB_NAME = "saveremotedb";
|
||||
export const DEFAULT_TBL_DELETE_HISTORY = "filefolderoperationhistory";
|
||||
|
||||
export interface FileFolderHistoryRecord {
|
||||
key: string;
|
||||
ctime: number;
|
||||
mtime: number;
|
||||
size: number;
|
||||
action_when: number;
|
||||
action_type: "delete" | "rename";
|
||||
key_type: "folder" | "file";
|
||||
rename_to: string;
|
||||
}
|
||||
|
||||
export async function prepareDB() {
|
||||
const schemaBuilder = lf.schema.create(DEFAULT_DB_NAME, 1);
|
||||
schemaBuilder
|
||||
.createTable(DEFAULT_TBL_DELETE_HISTORY)
|
||||
.addColumn("id", lf.Type.INTEGER)
|
||||
.addColumn("key", lf.Type.STRING)
|
||||
.addColumn("ctime", lf.Type.INTEGER)
|
||||
.addColumn("mtime", lf.Type.INTEGER)
|
||||
.addColumn("size", lf.Type.INTEGER)
|
||||
.addColumn("action_when", lf.Type.INTEGER)
|
||||
.addColumn("action_type", lf.Type.STRING)
|
||||
.addColumn("key_type", lf.Type.STRING)
|
||||
.addPrimaryKey(["id"], true)
|
||||
.addIndex("idxKey", ["key"]);
|
||||
const db = await schemaBuilder.connect({
|
||||
storeType: lf.DataStoreType.INDEXED_DB,
|
||||
});
|
||||
console.log("db connected");
|
||||
return db;
|
||||
}
|
||||
|
||||
export function destroyDB(db: lf.DatabaseConnection) {
|
||||
db.close();
|
||||
const req = indexedDB.deleteDatabase(DEFAULT_DB_NAME);
|
||||
req.onsuccess = (event) => {
|
||||
console.log("db deleted");
|
||||
};
|
||||
req.onblocked = (event) => {
|
||||
console.warn("trying to delete db but it was blocked");
|
||||
};
|
||||
req.onerror = (event) => {
|
||||
console.error("tried to delete db but something bad!");
|
||||
console.error(event);
|
||||
};
|
||||
}
|
@ -12,12 +12,21 @@ import {
|
||||
Setting,
|
||||
request,
|
||||
Platform,
|
||||
TFile,
|
||||
TFolder,
|
||||
} from "obsidian";
|
||||
import * as CodeMirror from "codemirror";
|
||||
import type { FileFolderHistoryRecord, DatabaseConnection } from "./localdb";
|
||||
import {
|
||||
prepareDB,
|
||||
destroyDB,
|
||||
DEFAULT_DB_NAME,
|
||||
DEFAULT_TBL_DELETE_HISTORY,
|
||||
} from "./localdb";
|
||||
|
||||
import {
|
||||
S3Client,
|
||||
ListObjectsCommand,
|
||||
ListObjectsV2Command,
|
||||
PutObjectCommand,
|
||||
GetObjectCommand,
|
||||
} from "@aws-sdk/client-s3";
|
||||
@ -103,12 +112,96 @@ const getObjectBodyToArrayBuffer = async (
|
||||
export default class SaveRemotePlugin extends Plugin {
|
||||
settings: SaveRemotePluginSettings;
|
||||
cm: CodeMirror.Editor;
|
||||
db: DatabaseConnection;
|
||||
|
||||
async onload() {
|
||||
console.log("loading plugin obsidian-save-remote");
|
||||
|
||||
await this.loadSettings();
|
||||
|
||||
await this.prepareDB();
|
||||
|
||||
this.registerEvent(
|
||||
this.app.vault.on("delete", async (fileOrFolder) => {
|
||||
const schema = this.db.getSchema().table(DEFAULT_TBL_DELETE_HISTORY);
|
||||
const tbl = this.db.getSchema().table(DEFAULT_TBL_DELETE_HISTORY);
|
||||
// console.log(fileOrFolder);
|
||||
let k: FileFolderHistoryRecord;
|
||||
if (fileOrFolder instanceof TFile) {
|
||||
k = {
|
||||
key: fileOrFolder.path,
|
||||
ctime: fileOrFolder.stat.ctime,
|
||||
mtime: fileOrFolder.stat.mtime,
|
||||
size: fileOrFolder.stat.size,
|
||||
action_when: Date.now(),
|
||||
action_type: "delete",
|
||||
key_type: "file",
|
||||
rename_to: "",
|
||||
};
|
||||
} else if (fileOrFolder instanceof TFolder) {
|
||||
k = {
|
||||
key: fileOrFolder.path,
|
||||
ctime: 0,
|
||||
mtime: 0,
|
||||
size: 0,
|
||||
action_when: Date.now(),
|
||||
action_type: "delete",
|
||||
key_type: "folder",
|
||||
rename_to: "",
|
||||
};
|
||||
}
|
||||
const row = tbl.createRow(k);
|
||||
await this.db.insertOrReplace().into(tbl).values([row]).exec();
|
||||
})
|
||||
);
|
||||
|
||||
this.registerEvent(
|
||||
this.app.vault.on("rename", async (fileOrFolder, oldPath) => {
|
||||
const schema = this.db.getSchema().table(DEFAULT_TBL_DELETE_HISTORY);
|
||||
const tbl = this.db.getSchema().table(DEFAULT_TBL_DELETE_HISTORY);
|
||||
// console.log(fileOrFolder);
|
||||
let k: FileFolderHistoryRecord;
|
||||
if (fileOrFolder instanceof TFile) {
|
||||
k = {
|
||||
key: oldPath,
|
||||
ctime: fileOrFolder.stat.ctime,
|
||||
mtime: fileOrFolder.stat.mtime,
|
||||
size: fileOrFolder.stat.size,
|
||||
action_when: Date.now(),
|
||||
action_type: "rename",
|
||||
key_type: "file",
|
||||
rename_to: fileOrFolder.path,
|
||||
};
|
||||
} else if (fileOrFolder instanceof TFolder) {
|
||||
k = {
|
||||
key: oldPath,
|
||||
ctime: 0,
|
||||
mtime: 0,
|
||||
size: 0,
|
||||
action_when: Date.now(),
|
||||
action_type: "rename",
|
||||
key_type: "folder",
|
||||
rename_to: fileOrFolder.path,
|
||||
};
|
||||
}
|
||||
const row = tbl.createRow(k);
|
||||
await this.db.insertOrReplace().into(tbl).values([row]).exec();
|
||||
})
|
||||
);
|
||||
|
||||
this.addRibbonIcon("dice", "Misc", async () => {
|
||||
const a = this.app.vault.getAllLoadedFiles();
|
||||
console.log(a);
|
||||
|
||||
const schema = this.db.getSchema().table(DEFAULT_TBL_DELETE_HISTORY);
|
||||
|
||||
const h = await this.db.select().from(schema).exec();
|
||||
|
||||
console.log(h);
|
||||
|
||||
// console.log(b)
|
||||
});
|
||||
|
||||
this.addRibbonIcon("right-arrow-with-tail", "Upload", async () => {
|
||||
// console.log(this.app.vault.getFiles());
|
||||
// console.log(this.app.vault.getAllLoadedFiles());
|
||||
@ -183,10 +276,15 @@ export default class SaveRemotePlugin extends Plugin {
|
||||
|
||||
try {
|
||||
const listObj = await s3Client.send(
|
||||
new ListObjectsCommand({ Bucket: this.settings.s3BucketName })
|
||||
new ListObjectsV2Command({ Bucket: this.settings.s3BucketName })
|
||||
);
|
||||
|
||||
for (const singleContent of listObj.Contents) {
|
||||
const mtimeSec = Math.round(
|
||||
singleContent.LastModified.valueOf() / 1000.0
|
||||
);
|
||||
console.log(`key ${singleContent.Key} mtime ${mtimeSec}`);
|
||||
|
||||
const foldersToBuild = getFolderLevels(singleContent.Key);
|
||||
for (const folder of foldersToBuild) {
|
||||
const r = await this.app.vault.adapter.exists(folder);
|
||||
@ -246,6 +344,7 @@ export default class SaveRemotePlugin extends Plugin {
|
||||
|
||||
onunload() {
|
||||
console.log("unloading plugin obsidian-save-remote");
|
||||
this.destroyDB();
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
@ -255,6 +354,14 @@ export default class SaveRemotePlugin extends Plugin {
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
|
||||
async prepareDB() {
|
||||
this.db = await prepareDB();
|
||||
}
|
||||
|
||||
destroyDB() {
|
||||
destroyDB(this.db);
|
||||
}
|
||||
}
|
||||
|
||||
class SaveRemoteSettingTab extends PluginSettingTab {
|
@ -2,7 +2,7 @@ const path = require("path");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
|
||||
module.exports = {
|
||||
entry: "./main.ts",
|
||||
entry: "./src/main.ts",
|
||||
target: "web",
|
||||
output: {
|
||||
filename: "main.js",
|
||||
|
Loading…
Reference in New Issue
Block a user