initial commit

This commit is contained in:
2026-05-31 14:23:01 +02:00
commit e39fbca087
136 changed files with 58061 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
import { RmapiNode } from "../types";
import RemarkablePlugin from "../main";
import { RmapiBridge } from "../rmapi/bridge";
import { SyncTracker } from "./tracker";
import { Notice } from "obsidian";
function sanitizeFileName(name: string): string {
return name.replace(/[\\/:*?"<>|]/g, "_");
}
export class DocumentDownloader {
plugin: RemarkablePlugin;
rmapi: RmapiBridge;
tracker: SyncTracker;
constructor(plugin: RemarkablePlugin) {
this.plugin = plugin;
this.rmapi = new RmapiBridge(plugin);
this.tracker = new SyncTracker(plugin);
}
async syncAll(): Promise<void> {
try {
new Notice("Syncing from reMarkable...");
const allDocs = await this.listAllDocuments("/");
for (const doc of allDocs) {
await this.downloadDocument(doc);
}
new Notice(`Sync completed! ${allDocs.length} document(s) synced.`);
} catch (e) {
new Notice(`Sync failed: ${e}`);
console.error("Sync error:", e);
}
}
async listAllDocuments(path: string): Promise<RmapiNode[]> {
const nodes = await this.rmapi.list(path);
let docs = nodes.filter((n) => n.type === "DocumentType");
for (const col of nodes.filter((n) => n.type === "CollectionType")) {
const subPath = path === "/" ? `/${col.name}` : `${path}/${col.name}`;
const subDocs = await this.listAllDocuments(subPath);
docs = docs.concat(subDocs);
}
return docs;
}
async downloadDocument(doc: RmapiNode): Promise<void> {
// Incremental sync: skip if already synced and not modified
const synced = await this.tracker.getSyncedDocument(doc.id);
if (synced && synced.lastSynced >= doc.modifiedClient) {
return;
}
const safeName = sanitizeFileName(doc.name);
const localDir = this.plugin.settings.downloadPath;
const localPath = `${localDir}/${safeName}`;
// Ensure directory exists
try {
await this.plugin.app.vault.adapter.mkdir(localDir);
} catch (err) {
console.warn("mkdir failed (may already exist):", err);
}
// Download raw .rm file
await this.rmapi.downloadFile(doc.name, localPath);
// Convert to PDF if enabled
let hasPdf = false;
if (this.plugin.settings.convertToPdf) {
const pdfPath = `${localDir}/${safeName}.pdf`;
await this.rmapi.downloadAnnotatedPdf(doc.name, pdfPath);
hasPdf = true;
}
// Track document
await this.tracker.trackDocument(doc.id, doc.name, localPath, hasPdf, false);
}
}