File browser özelliği eklendi.

This commit is contained in:
2025-10-30 21:24:41 +03:00
parent 69549d12b9
commit 09b76bfc0d
2 changed files with 1466 additions and 175 deletions

View File

@@ -2939,6 +2939,37 @@ app.get("/api/files", requireAuth, (req, res) => {
if (isIgnored(entry.name) || isIgnored(rel)) continue;
if (entry.isDirectory()) {
const safeRel = sanitizeRelative(rel);
if (!safeRel) continue;
const dirInfo = getInfo(safeRel) || {};
const rootFolder = rootFromRelPath(safeRel);
const added = dirInfo.added ?? dirInfo.createdAt ?? null;
const completedAt = dirInfo.completedAt ?? null;
const tracker = dirInfo.tracker ?? null;
const torrentName = dirInfo.name ?? null;
const infoHash = dirInfo.infoHash ?? null;
result.push({
name: safeRel,
size: 0,
type: "inode/directory",
isDirectory: true,
rootFolder,
added,
completedAt,
tracker,
torrentName,
infoHash,
extension: null,
mediaInfo: null,
primaryVideoPath: null,
primaryMediaInfo: null,
movieMatch: null,
seriesEpisode: null,
thumbnail: null,
});
result = result.concat(walk(full));
} else {
if (entry.name.toLowerCase() === INFO_FILENAME) continue;
@@ -4059,6 +4090,88 @@ app.post("/api/match/manual", requireAuth, async (req, res) => {
}
});
// --- Klasör oluşturma endpoint'i ---
app.post("/api/folder", requireAuth, async (req, res) => {
try {
const { name, path: targetPath } = req.body;
if (!name || !targetPath) {
return res.status(400).json({ error: "Klasör adı ve yol gerekli" });
}
// Güvenli yol kontrolü
const safePath = sanitizeRelative(targetPath);
if (!safePath) {
return res.status(400).json({ error: "Geçersiz klasör yolu" });
}
const fullPath = path.join(DOWNLOAD_DIR, safePath);
// Klasörü oluştur
try {
fs.mkdirSync(fullPath, { recursive: true });
console.log(`📁 Klasör oluşturuldu: ${fullPath}`);
// İlişkili info.json dosyasını güncelle
const rootFolder = rootFromRelPath(safePath);
if (rootFolder) {
const rootDir = path.join(DOWNLOAD_DIR, rootFolder);
upsertInfoFile(rootDir, {
folder: rootFolder,
updatedAt: Date.now()
});
broadcastFileUpdate(rootFolder);
}
// /downloads klasörüne de aynı yapıda oluştur
try {
// Mevcut yolun yapısını analiz et
const pathSegments = safePath.split('/').filter(Boolean);
// Eğer mevcut dizin Home ise doğrudan downloads içine oluştur
if (pathSegments.length === 1) {
const downloadsPath = path.join(DOWNLOAD_DIR, name);
fs.mkdirSync(downloadsPath, { recursive: true });
console.log(`📁 Downloads klasörü oluşturuldu: ${downloadsPath}`);
} else {
// İç içe klasör yapısını koru
// Örn: Home/IT.Welcome.to.Derry.S01E01.1080p.x265-ELiTE ise
// downloads/1761836594224/IT.Welcome.to.Derry.S01E01.1080p.x265-ELiTE oluştur
const rootSegment = pathSegments[0]; // İlk segment (örn: 1761836594224)
const remainingPath = pathSegments.slice(1).join('/'); // Kalan path
const downloadsRootPath = path.join(DOWNLOAD_DIR, rootSegment);
const downloadsFullPath = path.join(downloadsRootPath, remainingPath);
fs.mkdirSync(downloadsFullPath, { recursive: true });
console.log(`📁 Downloads iç klasör oluşturuldu: ${downloadsFullPath}`);
}
} catch (downloadsErr) {
console.warn("⚠️ Downloads klasörü oluşturulamadı:", downloadsErr.message);
// Ana klasör oluşturulduysa hata döndürme
}
res.json({
success: true,
message: "Klasör başarıyla oluşturuldu",
path: safePath
});
} catch (mkdirErr) {
console.error("❌ Klasör oluşturma hatası:", mkdirErr);
const friendlyMessage =
mkdirErr?.code === "EACCES"
? "Sunucu bu dizine yazma iznine sahip değil. Lütfen downloads klasörünün izinlerini güncelle."
: "Klasör oluşturulamadı: " + (mkdirErr?.message || "Bilinmeyen hata");
res.status(500).json({
error: friendlyMessage
});
}
} catch (err) {
console.error("❌ Folder API error:", err);
res.status(500).json({ error: err.message });
}
});
client.on("error", (err) => {
if (!String(err).includes("uTP"))
console.error("WebTorrent error:", err.message);