fix: renaming dans le managements des series

This commit is contained in:
MasutaYunikon committed 2026-05-07 15:21:27 +02:00
1 parent bfabf9b793
commit bf3f30356e
2 files changed
+30 -43

No files matched your search

+21
View File
@@ -1,3 +1,5 @@
import path from 'path'
const FANKAI_API = 'https://metadata.fankai.fr'
export async function fankaiGet(endpoint: string): Promise<any> {
@@ -67,6 +69,25 @@ export function resolveEpNaming(ep: any, hash?: string | null): {
}
}
/**
* Calcule le nom attendu d'un fichier épisode selon le mode (NFO ou formaté).
* Source unique de vérité partagée entre organized-summary, organized/:id, rename-episode et rename-all.
*/
export function computeExpectedName(
ep : any,
orgEntry: any,
hash : string | null,
nfoSupport: boolean,
): { currentName: string; expectedName: string; needsRename: boolean } {
const currentName = orgEntry.dest_path ? path.basename(orgEntry.dest_path) : orgEntry.dest_filename
const srcExt = path.extname(currentName)
const { formatted_name: rawFmt, nfo_filename: rawNfo } = resolveEpNaming(ep, hash)
const expectedName = nfoSupport
? (rawNfo ? rawNfo.replace(/\.[^.]+$/, '') + srcExt : currentName)
: (rawFmt?.trim() ? rawFmt.replace(/[<>:"/\\|?*]/g, '').trim() + srcExt : currentName)
return { currentName, expectedName, needsRename: expectedName !== currentName }
}
/**
* Dédoublonne une liste d'épisodes par episode_number.
* Quand plusieurs variantes existent (ex. x264 + x265), on garde la première
+9 -43
View File
@@ -7,7 +7,7 @@ import { DATA_DIR } from '../config.js'
import { readSettings } from '../settings.js'
import { getGitlabTitle } from '../gitlab-map.js'
import { readSerieData, loadEnrichedSeriesData } from '../lib/github-cache.js'
import { resolveEpNaming } from '../lib/serie-helpers.js'
import { resolveEpNaming, computeExpectedName } from '../lib/serie-helpers.js'
import { GITLAB_API_NFO, GITLAB_RAW_NFO } from '../lib/nfo.js'
import { dispatchRemove } from '../torrent-clients/index.js'
@@ -157,17 +157,8 @@ router.get('/organized/:serieId', requireAuth, async (req, res) => {
}
if (!entry) continue
// Calculer needs_rename côté serveur avec la même logique que le rename endpoint
const currentName = entry.dest_path ? path.basename(entry.dest_path) : entry.dest_filename
const srcExt = path.extname(currentName)
const { formatted_name: rawFmt, nfo_filename: rawNfo } = resolveEpNaming(ep, entryHash)
let expectedName: string
if (nfoSupport) {
expectedName = rawNfo ? rawNfo.replace(/\.[^.]+$/, '') + srcExt : currentName
} else {
expectedName = rawFmt?.trim() ? rawFmt.replace(/[<>:"/\\|?*]/g, '').trim() + srcExt : currentName
}
result[String(ep.id)] = { ...entry, hash: entryHash, needs_rename: expectedName !== currentName }
const { needsRename } = computeExpectedName(ep, entry, entryHash, nfoSupport)
result[String(ep.id)] = { ...entry, hash: entryHash, needs_rename: needsRename }
}
}
res.json(result)
@@ -202,16 +193,8 @@ router.post('/rename-episode', requireAuth, async (req, res) => {
}
}
if (!orgEntry) { res.status(404).json({ error: 'Épisode non importé' }); return }
const currentName = orgEntry.dest_path ? path.basename(orgEntry.dest_path) : orgEntry.dest_filename
const srcExt = path.extname(currentName)
const { formatted_name: rawFmt, nfo_filename: rawNfo } = resolveEpNaming(ep, entryHash)
let newName: string
if (nfoSupport) {
newName = rawNfo ? rawNfo.replace(/\.[^.]+$/, '') + srcExt : currentName
} else {
newName = rawFmt?.trim() ? rawFmt.replace(/[<>:"/\\|?*]/g, '').trim() + srcExt : currentName
}
if (newName === currentName) { res.json({ ok: true, renamed: false, message: 'Nom déjà correct' }); return }
const { currentName, expectedName: newName, needsRename } = computeExpectedName(ep, orgEntry, entryHash, nfoSupport)
if (!needsRename) { res.json({ ok: true, renamed: false, message: 'Nom déjà correct' }); return }
const oldPath = orgEntry.dest_path
const newPath = path.join(path.dirname(oldPath), newName)
try {
@@ -355,17 +338,8 @@ router.get('/organized-summary', requireAuth, async (_req, res) => {
if (eps[String(ep.id)]) { orgEntry = eps[String(ep.id)]; orgHash = hash; break }
}
if (!orgEntry) continue
const currentName = orgEntry.dest_path ? path.basename(orgEntry.dest_path) : orgEntry.dest_filename
const srcExt = path.extname(currentName)
const { formatted_name: rawFmt, nfo_filename: rawNfo } = resolveEpNaming(ep, orgHash)
let expectedName: string
if (nfoSupport) {
expectedName = rawNfo ? rawNfo.replace(/\.[^.]+$/, '') + srcExt : currentName
} else {
expectedName = rawFmt?.trim() ? rawFmt.replace(/[<>:"/\\|?*]/g, '').trim() + srcExt : currentName
}
const needsRename = expectedName !== currentName
const fileExists = orgEntry.dest_path ? fs.existsSync(orgEntry.dest_path) : false
const { currentName, expectedName, needsRename } = computeExpectedName(ep, orgEntry, orgHash, nfoSupport)
const fileExists = orgEntry.dest_path ? fs.existsSync(orgEntry.dest_path) : false
episodes.push({ episode_id: ep.id, episode_number: ep.episode_number, season_number: season.season_number, title: ep.title, current_name: currentName, expected_name: expectedName, dest_path: orgEntry.dest_path, torrent_hash: orgHash, needs_rename: needsRename, file_exists: fileExists })
}
}
@@ -398,16 +372,8 @@ router.post('/rename-all', requireAuth, async (req, res) => {
if (eps[String(ep.id)]) { orgEntry = eps[String(ep.id)]; orgHash = hash; break }
}
if (!orgEntry || !orgHash) continue
const currentName = orgEntry.dest_path ? path.basename(orgEntry.dest_path) : orgEntry.dest_filename
const srcExt = path.extname(currentName)
const { formatted_name: rawFmt, nfo_filename: rawNfo } = resolveEpNaming(ep, orgHash)
let expectedName: string
if (nfoSupport) {
expectedName = rawNfo ? rawNfo.replace(/\.[^.]+$/, '') + srcExt : currentName
} else {
expectedName = rawFmt?.trim() ? rawFmt.replace(/[<>:"/\\|?*]/g, '').trim() + srcExt : currentName
}
if (expectedName === currentName) continue
const { currentName, expectedName, needsRename } = computeExpectedName(ep, orgEntry, orgHash, nfoSupport)
if (!needsRename) continue
const oldPath = orgEntry.dest_path
const newPath = path.join(path.dirname(oldPath), expectedName)
try {