feat: WebDAV Echtzeit-Sync bei Datei/Ordner erstellen und löschen
This commit is contained in:
@@ -10,6 +10,42 @@ const UPLOAD_DIR = process.env.UPLOAD_DIR || '/data/uploads';
|
||||
if (!fs.existsSync(UPLOAD_DIR)) fs.mkdirSync(UPLOAD_DIR, { recursive: true });
|
||||
const webdav = require('./webdav');
|
||||
|
||||
// ── WebDAV Hilfsfunktionen ────────────────────────────────────────────────
|
||||
function getFolderPathById(folderId) {
|
||||
if (!folderId) return '';
|
||||
const parts = [];
|
||||
let cur = folderId;
|
||||
const seen = new Set();
|
||||
while (cur) {
|
||||
if (seen.has(cur)) break; seen.add(cur);
|
||||
const fo = db.prepare('SELECT name, parent_id FROM folders WHERE id=?').get(cur);
|
||||
if (!fo) break;
|
||||
parts.unshift(fo.name.replace(/[\/]/g, '_'));
|
||||
cur = fo.parent_id;
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function davFileUrl(username, folderId, filename) {
|
||||
const cfg = webdav.getConfig();
|
||||
if (!cfg.enabled) return null;
|
||||
const base = webdav.userPath(cfg, username);
|
||||
const folder = getFolderPathById(folderId);
|
||||
return folder ? `${base}/${folder}/${filename}` : `${base}/${filename}`;
|
||||
}
|
||||
|
||||
function davFolderUrl(username, folderId) {
|
||||
const cfg = webdav.getConfig();
|
||||
if (!cfg.enabled) return null;
|
||||
const base = webdav.userPath(cfg, username);
|
||||
const folder = getFolderPathById(folderId);
|
||||
return folder ? `${base}/${folder}` : base;
|
||||
}
|
||||
|
||||
function getUserName(userId) {
|
||||
return db.prepare('SELECT username FROM users WHERE id=?').get(userId)?.username || String(userId);
|
||||
}
|
||||
|
||||
const getSetting = key => db.prepare('SELECT value FROM admin_settings WHERE key=?').get(key)?.value;
|
||||
|
||||
const diskStorage = multer.diskStorage({
|
||||
@@ -102,7 +138,11 @@ router.post('/folders', authenticate, (req, res) => {
|
||||
if (!parent) return res.status(404).json({ error: 'Überordner nicht gefunden' });
|
||||
}
|
||||
const r = db.prepare('INSERT INTO folders (user_id,name,parent_id) VALUES (?,?,?)').run(req.user.id, name.trim(), parentId);
|
||||
res.json(enrichFolder(db.prepare('SELECT * FROM folders WHERE id=?').get(r.lastInsertRowid)));
|
||||
const newFolder = db.prepare('SELECT * FROM folders WHERE id=?').get(r.lastInsertRowid);
|
||||
// WebDAV: Ordner anlegen
|
||||
const _davFolderCreate = davFolderUrl(getUserName(req.user.id), newFolder.id);
|
||||
if (_davFolderCreate) webdav.mkdirp(_davFolderCreate).catch(e => console.warn('[webdav] mkdir:', e.message));
|
||||
res.json(enrichFolder(newFolder));
|
||||
});
|
||||
|
||||
router.delete('/folders/:id', authenticate, (req, res) => {
|
||||
@@ -111,6 +151,9 @@ router.delete('/folders/:id', authenticate, (req, res) => {
|
||||
// Delete all files inside
|
||||
const files = db.prepare('SELECT * FROM files WHERE folder_id=? AND user_id=?').all(folder.id, req.user.id);
|
||||
for (const f of files) { try { fs.unlinkSync(path.join(UPLOAD_DIR, f.filename)); } catch {} }
|
||||
// WebDAV: Ordner löschen (vor DB-Löschung damit Pfad noch auflösbar)
|
||||
const _davFolderDel = davFolderUrl(getUserName(req.user.id), folder.id);
|
||||
if (_davFolderDel) webdav.deleteFile(_davFolderDel).catch(e => console.warn('[webdav] rmdir:', e.message));
|
||||
db.prepare('DELETE FROM files WHERE folder_id=? AND user_id=?').run(folder.id, req.user.id);
|
||||
db.prepare('DELETE FROM folders WHERE id=?').run(folder.id);
|
||||
res.json({ success: true });
|
||||
@@ -200,32 +243,11 @@ router.post('/', authenticate, (req, res) => {
|
||||
.run(uid, req.file.filename, req.file.originalname, req.file.mimetype||'application/octet-stream', req.file.size, folderId);
|
||||
const newFile = db.prepare('SELECT f.*,u.username as owner FROM files f JOIN users u ON u.id=f.user_id WHERE f.id=?').get(r.lastInsertRowid);
|
||||
|
||||
// WebDAV: Datei asynchron spiegeln mit Ordnerstruktur
|
||||
const cfg = webdav.getConfig();
|
||||
if (cfg.enabled) {
|
||||
const user = db.prepare('SELECT username FROM users WHERE id=?').get(uid);
|
||||
// Ordnerpfad auflösen
|
||||
function getFolderPath(fid) {
|
||||
if (!fid) return '';
|
||||
const parts = [];
|
||||
let cur = fid;
|
||||
const seen = new Set();
|
||||
while (cur) {
|
||||
if (seen.has(cur)) break; seen.add(cur);
|
||||
const fo = db.prepare('SELECT name, parent_id FROM folders WHERE id=?').get(cur);
|
||||
if (!fo) break;
|
||||
parts.unshift(fo.name.replace(/[/\\]/g, '_'));
|
||||
cur = fo.parent_id;
|
||||
}
|
||||
return parts.join('/');
|
||||
}
|
||||
const folderPath = getFolderPath(folderId);
|
||||
const userBase = webdav.userPath(cfg, user.username);
|
||||
const davPath = folderPath
|
||||
? `${userBase}/${folderPath}/${req.file.originalname}`
|
||||
: `${userBase}/${req.file.originalname}`;
|
||||
// WebDAV: Datei asynchron spiegeln
|
||||
const _davPath = davFileUrl(getUserName(uid), folderId, req.file.originalname);
|
||||
if (_davPath) {
|
||||
fs.readFile(path.join(UPLOAD_DIR, req.file.filename), (err, buf) => {
|
||||
if (!err) webdav.uploadFile(buf, davPath, req.file.mimetype).catch(e => console.error('[webdav upload]', e.message));
|
||||
if (!err) webdav.uploadFile(buf, _davPath, req.file.mimetype).catch(e => console.error('[webdav upload]', e.message));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -333,6 +355,9 @@ router.get('/:id/download', authenticate, async (req, res) => {
|
||||
router.delete('/:id', authenticate, (req, res) => {
|
||||
const file = db.prepare('SELECT * FROM files WHERE id=? AND user_id=?').get(req.params.id, req.user.id);
|
||||
if (!file) return res.status(404).json({ error: 'Nicht gefunden' });
|
||||
// WebDAV: Datei löschen
|
||||
const _davFileDel = davFileUrl(getUserName(file.user_id), file.folder_id, file.originalname);
|
||||
if (_davFileDel) webdav.deleteFile(_davFileDel).catch(e => console.warn('[webdav] delete:', e.message));
|
||||
try { fs.unlinkSync(path.join(UPLOAD_DIR, file.filename)); } catch {}
|
||||
db.prepare('DELETE FROM files WHERE id=?').run(file.id);
|
||||
res.json({ success: true });
|
||||
|
||||
Reference in New Issue
Block a user