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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user