Add reMarkable backup system with web UI
- Docker container with rmapi cloud backup, PDF conversion pipeline - Web UI: file browser, multi-select, delete/move, thumbnail preview - Sync: backup from reMarkable cloud, rmdoc→PDF conversion via rmc+Inkscape - Excluded-files mechanism to prevent deleted items from returning after sync Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
64
remarkable/web/sync.php
Executable file
64
remarkable/web/sync.php
Executable file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/auth.php';
|
||||
|
||||
$BASE_DIR = rtrim(getenv('BASE_DIR') ?: '/data', '/');
|
||||
$BACKUP_SCRIPT = '/usr/local/bin/remarkable-backup.sh';
|
||||
$CONVERT_SCRIPT= '/usr/local/bin/remarkable-convert.sh';
|
||||
$SNAPSHOT_KEEP = getenv('SNAPSHOT_KEEP') ?: '60';
|
||||
|
||||
// Läuft bereits ein Sync?
|
||||
$LOCK = $BASE_DIR . '/.backup.lock';
|
||||
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
header('X-Accel-Buffering: no');
|
||||
header('Cache-Control: no-cache');
|
||||
if (ob_get_level()) ob_end_clean();
|
||||
|
||||
function stream(string $cmd): int {
|
||||
$handle = popen($cmd . ' 2>&1', 'r');
|
||||
if ($handle === false) return 1;
|
||||
while (!feof($handle)) {
|
||||
$chunk = fread($handle, 256);
|
||||
if ($chunk !== false && $chunk !== '') {
|
||||
echo $chunk;
|
||||
flush();
|
||||
}
|
||||
}
|
||||
return pclose($handle);
|
||||
}
|
||||
|
||||
echo "=== Backup ===\n";
|
||||
flush();
|
||||
$exit = stream("SNAPSHOT_KEEP={$SNAPSHOT_KEEP} {$BACKUP_SCRIPT} {$BASE_DIR} /");
|
||||
|
||||
if ($exit !== 0) {
|
||||
echo "\n[FEHLER] Backup fehlgeschlagen (exit {$exit})\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Web-gelöschte Dateien wieder entfernen (kommen durch Sync zurück)
|
||||
$excludeFile = $BASE_DIR . '/.web_deleted';
|
||||
if (file_exists($excludeFile)) {
|
||||
$lines = file($excludeFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$removed = 0;
|
||||
foreach (array_unique($lines) as $p) {
|
||||
$p = '/' . ltrim($p, '/');
|
||||
$local = $BASE_DIR . '/current' . $p;
|
||||
if (is_dir($local)) {
|
||||
shell_exec('rm -rf ' . escapeshellarg($local));
|
||||
$removed++;
|
||||
} else {
|
||||
foreach ([$local, $local.'.pdf', $local.'.rmdoc', $local.'.thumb.jpg'] as $f) {
|
||||
if (is_file($f) && @unlink($f)) $removed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($removed) echo "\n[Web-Löschung] $removed Element(e) erneut entfernt.\n";
|
||||
}
|
||||
|
||||
echo "\n=== PDF-Konvertierung ===\n";
|
||||
flush();
|
||||
stream("{$CONVERT_SCRIPT} {$BASE_DIR}/current");
|
||||
|
||||
echo "\n=== Fertig ===\n";
|
||||
Reference in New Issue
Block a user