diff --git a/backend/src/routes/admin.js b/backend/src/routes/admin.js index 649d69d..e335a71 100644 --- a/backend/src/routes/admin.js +++ b/backend/src/routes/admin.js @@ -247,21 +247,53 @@ router.post('/webdav/sync', authenticate, requireAdmin, async (req, res) => { visited.add(current); const folder = db.prepare('SELECT id, name, parent_id FROM folders WHERE id=?').get(current); if (!folder) break; - parts.unshift(folder.name.replace(/[/\\]/g, '_')); + parts.unshift(folder.name.replace(/[\/\\]/g, '_')); current = folder.parent_id; } return parts.join('/'); } - // Alle Dateien aus DB holen mit Username und folder_id + const results = { folders: 0, ok: 0, failed: 0, errors: [] }; + + // ── Schritt 1: Alle User-Basisordner + Unterordner anlegen ─────────────── + const users = db.prepare('SELECT id, username FROM users ORDER BY id').all(); + + for (const user of users) { + const userBase = webdav.userPath(cfg, user.username); + + // User-Basisordner + try { await webdav.mkdirp(userBase); results.folders++; } catch(e) { + results.errors.push(`Ordner ${userBase}: ${e.message}`); + } + + // Upload-Freigabe Ordner + try { await webdav.mkdirp(`${userBase}/_Upload-Freigaben`); results.folders++; } catch {} + + // Alle DB-Ordner dieses Users (sortiert nach parent_id damit Parents zuerst) + const folders = db.prepare(` + WITH RECURSIVE tree AS ( + SELECT id, name, parent_id, 0 as depth FROM folders WHERE user_id=? AND parent_id IS NULL + UNION ALL + SELECT f.id, f.name, f.parent_id, t.depth+1 FROM folders f JOIN tree t ON f.parent_id=t.id + ) SELECT * FROM tree ORDER BY depth, id + `).all(user.id); + + for (const folder of folders) { + const folderPath = getFolderPath(folder.id); + const davPath = `${userBase}/${folderPath}`; + try { await webdav.mkdirp(davPath); results.folders++; } catch(e) { + results.errors.push(`Ordner ${davPath}: ${e.message}`); + } + } + } + + // ── Schritt 2: Alle Dateien hochladen ──────────────────────────────────── const files = db.prepare(` SELECT f.*, u.username FROM files f JOIN users u ON u.id = f.user_id ORDER BY f.user_id, f.folder_id, f.id `).all(); - const results = { ok: 0, failed: 0, errors: [] }; - for (const file of files) { const localPath = path.join(UPLOAD_DIR, file.filename); if (!fs.existsSync(localPath)) { @@ -284,7 +316,36 @@ router.post('/webdav/sync', authenticate, requireAdmin, async (req, res) => { } } - res.json({ total: files.length, ...results }); + // ── Schritt 3: Upload-Freigabe Dateien ─────────────────────────────────── + const uploadLogs = db.prepare(` + SELECT l.filename, l.originalname, l.mimetype, l.size, + s.user_id, u.username + FROM upload_share_logs l + JOIN upload_shares s ON s.id = l.share_id + JOIN users u ON u.id = s.user_id + WHERE l.filename IS NOT NULL + `).all(); + + for (const log of uploadLogs) { + const localPath = path.join(UPLOAD_DIR, log.filename); + if (!fs.existsSync(localPath)) continue; + try { + const buf = fs.readFileSync(localPath); + const userBase = webdav.userPath(cfg, log.username); + const davPath = `${userBase}/_Upload-Freigaben/${log.originalname || log.filename}`; + await webdav.uploadFile(buf, davPath, log.mimetype || 'application/octet-stream'); + results.ok++; + } catch(e) { + results.failed++; + results.errors.push(`Upload-Freigabe ${log.originalname}: ${e.message}`); + } + } + + res.json({ + total: files.length + uploadLogs.length, + ...results, + message: `${results.folders} Ordner angelegt, ${results.ok} Dateien kopiert, ${results.failed} fehlgeschlagen` + }); }); module.exports = router; diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 3107514..44f05ac 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -2818,7 +2818,7 @@ function WebDavSettings({ toast }) { {syncResult && !syncResult.error && (
- ✓ Sync abgeschlossen: {syncResult.ok}/{syncResult.total} erfolgreich + ✓ {syncResult.message || `Sync abgeschlossen: ${syncResult.ok}/${syncResult.total} Dateien`}
{syncResult.failed > 0 && (