feat(movies): film tekrarlarını ve önbelleği temizle

Aynı film için birden fazla önbellek girdisi olduğunda en güncel olanı
tutup eski önbellekleri temizleyen mekanizma eklendi. Video yolu
bulunamayan filmlerin metadatası otomatik silinir.
This commit is contained in:
2026-02-01 18:02:08 +03:00
parent e7925aa39f
commit 6ac608a0b1

View File

@@ -7565,7 +7565,7 @@ app.get("/api/movies", requireAuth, (req, res) => {
.readdirSync(MOVIE_DATA_ROOT, { withFileTypes: true })
.filter((d) => d.isDirectory());
const movies = entries
const rawMovies = entries
.map((dirent) => {
const key = dirent.name;
const paths = movieDataPathsByKey(key);
@@ -7587,6 +7587,17 @@ app.get("/api/movies", requireAuth, (req, res) => {
const dupe = metadata._dupe || {};
const rootFolder = dupe.folder || key;
const videoPath = dupe.videoPath || metadata.videoPath || null;
const absVideo = resolveMovieVideoAbsPath(metadata);
if (!absVideo) {
try {
fs.rmSync(paths.dir, { recursive: true, force: true });
} catch (err) {
console.warn(
`⚠️ Movie metadata temizlenemedi (${paths.dir}): ${err.message}`
);
}
return null;
}
const encodedKey = key
.split(path.sep)
.map(encodeURIComponent)
@@ -7605,6 +7616,14 @@ app.get("/api/movies", requireAuth, (req, res) => {
: null);
const cacheKey = paths.key;
return {
_absVideo: absVideo,
_cacheDir: paths.dir,
_cacheKey: cacheKey,
_dedupeKey:
typeof metadata.id === "number" && metadata.id
? `id:${metadata.id}`
: `title:${(metadata.title || metadata.matched_title || rootFolder)
.toLowerCase()}-${year || "unknown"}`,
folder: rootFolder,
cacheKey,
id:
@@ -7639,6 +7658,51 @@ app.get("/api/movies", requireAuth, (req, res) => {
})
.filter(Boolean);
const dedupedMap = new Map();
for (const item of rawMovies) {
const key = item._dedupeKey;
if (!dedupedMap.has(key)) {
dedupedMap.set(key, item);
continue;
}
const existing = dedupedMap.get(key);
const existingScore =
existing?.metadata?._dupe?.fetchedAt ||
existing?.metadata?._dupe?.matchedAt ||
existing?.metadata?.matchedAt ||
0;
const nextScore =
item?.metadata?._dupe?.fetchedAt ||
item?.metadata?._dupe?.matchedAt ||
item?.metadata?.matchedAt ||
0;
if (nextScore > existingScore) {
if (existing?._cacheDir) {
try {
fs.rmSync(existing._cacheDir, { recursive: true, force: true });
} catch (err) {
console.warn(
`⚠️ Movie metadata temizlenemedi (${existing._cacheDir}): ${err.message}`
);
}
}
dedupedMap.set(key, item);
} else if (item?._cacheDir) {
try {
fs.rmSync(item._cacheDir, { recursive: true, force: true });
} catch (err) {
console.warn(
`⚠️ Movie metadata temizlenemedi (${item._cacheDir}): ${err.message}`
);
}
}
}
const movies = Array.from(dedupedMap.values()).map((item) => {
const { _absVideo, _cacheDir, _cacheKey, _dedupeKey, ...rest } = item;
return rest;
});
movies.sort((a, b) => {
const yearA = a.year || 0;
const yearB = b.year || 0;