main #6
106
server/server.js
106
server/server.js
@@ -2790,10 +2790,14 @@ function rebuildWebdavIndex() {
|
|||||||
console.warn(`⚠️ WebDAV movie index oluşturulamadı: ${err.message}`);
|
console.warn(`⚠️ WebDAV movie index oluşturulamadı: ${err.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildSeriesCategory = (dataRoot, categoryLabel) => {
|
const buildSeriesCategory = (
|
||||||
|
dataRoot,
|
||||||
|
categoryLabel,
|
||||||
|
usedShowNames,
|
||||||
|
coveredRoots
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
const dirs = fs.readdirSync(dataRoot, { withFileTypes: true });
|
const dirs = fs.readdirSync(dataRoot, { withFileTypes: true });
|
||||||
const usedShowNames = new Set();
|
|
||||||
for (const dirent of dirs) {
|
for (const dirent of dirs) {
|
||||||
if (!dirent.isDirectory()) continue;
|
if (!dirent.isDirectory()) continue;
|
||||||
const seriesDir = path.join(dataRoot, dirent.name);
|
const seriesDir = path.join(dataRoot, dirent.name);
|
||||||
@@ -2806,6 +2810,7 @@ function rebuildWebdavIndex() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const { rootFolder } = parseTvSeriesKey(dirent.name);
|
const { rootFolder } = parseTvSeriesKey(dirent.name);
|
||||||
|
if (coveredRoots) coveredRoots.add(rootFolder);
|
||||||
const showTitle = sanitizeWebdavSegment(
|
const showTitle = sanitizeWebdavSegment(
|
||||||
seriesData?.name || seriesData?.title || dirent.name
|
seriesData?.name || seriesData?.title || dirent.name
|
||||||
);
|
);
|
||||||
@@ -2863,8 +2868,101 @@ function rebuildWebdavIndex() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
buildSeriesCategory(TV_DATA_ROOT, "TV Shows");
|
const tvUsedShowNames = new Set();
|
||||||
buildSeriesCategory(ANIME_DATA_ROOT, "Anime");
|
const animeUsedShowNames = new Set();
|
||||||
|
const coveredTvRoots = new Set();
|
||||||
|
buildSeriesCategory(TV_DATA_ROOT, "TV Shows", tvUsedShowNames, coveredTvRoots);
|
||||||
|
buildSeriesCategory(ANIME_DATA_ROOT, "Anime", animeUsedShowNames, null);
|
||||||
|
|
||||||
|
const buildSeriesFromInfoJson = (categoryLabel, usedShowNames, coveredRoots) => {
|
||||||
|
try {
|
||||||
|
const roots = fs.readdirSync(DOWNLOAD_DIR, { withFileTypes: true });
|
||||||
|
for (const dirent of roots) {
|
||||||
|
if (!dirent.isDirectory()) continue;
|
||||||
|
const rootFolder = dirent.name;
|
||||||
|
if (coveredRoots?.has(rootFolder)) continue;
|
||||||
|
const infoPath = path.join(DOWNLOAD_DIR, rootFolder, "info.json");
|
||||||
|
if (!fs.existsSync(infoPath)) continue;
|
||||||
|
let info = null;
|
||||||
|
try {
|
||||||
|
info = JSON.parse(fs.readFileSync(infoPath, "utf-8"));
|
||||||
|
} catch (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const episodes = info?.seriesEpisodes;
|
||||||
|
if (!episodes || typeof episodes !== "object") continue;
|
||||||
|
|
||||||
|
const showBuckets = new Map();
|
||||||
|
for (const [relPath, episode] of Object.entries(episodes)) {
|
||||||
|
if (!episode) continue;
|
||||||
|
if (shouldSkip(relPath)) continue;
|
||||||
|
const absVideo = path.join(DOWNLOAD_DIR, rootFolder, relPath);
|
||||||
|
if (!fs.existsSync(absVideo)) continue;
|
||||||
|
const ext = path.extname(absVideo).toLowerCase();
|
||||||
|
if (!isVideoExt(ext)) continue;
|
||||||
|
|
||||||
|
const showTitleRaw =
|
||||||
|
episode.showTitle || info?.name || rootFolder || "Unknown";
|
||||||
|
const showKey = `${episode.showId || ""}__${showTitleRaw}`;
|
||||||
|
if (!showBuckets.has(showKey)) {
|
||||||
|
showBuckets.set(showKey, {
|
||||||
|
title: showTitleRaw,
|
||||||
|
episodes: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
showBuckets.get(showKey).episodes.push({
|
||||||
|
absVideo,
|
||||||
|
relPath,
|
||||||
|
season: episode.season,
|
||||||
|
episode: episode.episode,
|
||||||
|
key: episode.key
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const bucket of showBuckets.values()) {
|
||||||
|
const showTitle = sanitizeWebdavSegment(bucket.title);
|
||||||
|
const uniqueShow = makeUniqueWebdavName(
|
||||||
|
showTitle,
|
||||||
|
usedShowNames,
|
||||||
|
bucket.title
|
||||||
|
);
|
||||||
|
const showDir = path.join(WEBDAV_ROOT, categoryLabel, uniqueShow);
|
||||||
|
let createdSeasonCount = 0;
|
||||||
|
for (const entry of bucket.episodes) {
|
||||||
|
const seasonNumber = Number(entry.season);
|
||||||
|
const episodeNumber = Number(entry.episode);
|
||||||
|
const seasonLabel = Number.isFinite(seasonNumber)
|
||||||
|
? `Season ${String(seasonNumber).padStart(2, "0")}`
|
||||||
|
: "Season";
|
||||||
|
const seasonDir = path.join(showDir, seasonLabel);
|
||||||
|
if (createdSeasonCount === 0) {
|
||||||
|
ensureDirSync(showDir);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(seasonDir)) {
|
||||||
|
ensureDirSync(seasonDir);
|
||||||
|
createdSeasonCount += 1;
|
||||||
|
}
|
||||||
|
const ext = path.extname(entry.absVideo);
|
||||||
|
const code =
|
||||||
|
entry.key ||
|
||||||
|
makeEpisodeCode(seasonNumber, episodeNumber) ||
|
||||||
|
`S${String(seasonNumber || 0).padStart(2, "0")}E${String(
|
||||||
|
Number(episodeNumber) || 0
|
||||||
|
).padStart(2, "0")}`;
|
||||||
|
const fileName = sanitizeWebdavSegment(
|
||||||
|
`${uniqueShow} - ${code}${ext}`
|
||||||
|
);
|
||||||
|
const linkPath = path.join(seasonDir, fileName);
|
||||||
|
createSymlinkSafe(entry.absVideo, linkPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(`⚠️ WebDAV ${categoryLabel} info.json index oluşturulamadı: ${err.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
buildSeriesFromInfoJson("TV Shows", tvUsedShowNames, coveredTvRoots);
|
||||||
}
|
}
|
||||||
|
|
||||||
let webdavIndexLast = 0;
|
let webdavIndexLast = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user