bugfix
This commit is contained in:
@@ -126,21 +126,63 @@ export class FileNameVideoMetaExtractor {
|
||||
return this.cleanTitle(this.getParentFolder(filePath, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a filename contains a season/episode pattern (indicates TV show)
|
||||
*/
|
||||
private filenameHasSeasonEpisodePattern(filename: string): boolean {
|
||||
const cleanedFilename = this.serieFilesNameAnalysisTool.removeKeywordsFromFilename(filename);
|
||||
const cleanedFilename2 = this.serieFilesNameAnalysisTool.removeSFV(cleanedFilename);
|
||||
const cleanedFilename3 = this.fileNameCleaner.cleanSpecialChars(cleanedFilename2);
|
||||
const cleanedFilename4 = this.fileNameCleaner.cleanSpace(cleanedFilename3);
|
||||
const [season, episode] = this.serieFilesNameAnalysisTool.findSeasonAndEpisode(cleanedFilename4);
|
||||
return season >= 0 || episode >= 0;
|
||||
}
|
||||
|
||||
computeTitleFromFilePath(filePath: string): string | undefined {
|
||||
let filename = this.fileNameCleaner.getFilenameFromPath(filePath);
|
||||
let titleFromFileName = this.computeTitleFromFileName(filename);
|
||||
let titleFromParentFolder = this.computeTitleFromParentFolder(filePath);
|
||||
let titleFromGrandParentFolder = this.computeTitleFromGrandParentFolder(filePath);
|
||||
let simpleTitle = this.stringArrayOperation.longestString([titleFromFileName, titleFromParentFolder, titleFromGrandParentFolder]);
|
||||
|
||||
// Check if filename contains season/episode pattern (indicates TV show)
|
||||
const isTvShow = this.filenameHasSeasonEpisodePattern(filename);
|
||||
|
||||
let selectedTitle;
|
||||
if (titleFromFileName && titleFromFileName.length > MIN_TITLE_LENGTH) {
|
||||
selectedTitle = titleFromFileName;
|
||||
} else if (titleFromParentFolder && titleFromParentFolder.length > MIN_TITLE_LENGTH) {
|
||||
selectedTitle = titleFromParentFolder;
|
||||
} else if (titleFromGrandParentFolder && titleFromGrandParentFolder.length > MIN_TITLE_LENGTH) {
|
||||
selectedTitle = titleFromGrandParentFolder;
|
||||
|
||||
if (isTvShow) {
|
||||
// For TV shows, prefer the longer title between filename and folder
|
||||
// This handles cases like "S01E01-The Fool.mkv" where "The Fool" is the episode name
|
||||
// but "Lord of Mysteries" in the parent folder is the actual series title
|
||||
const filenameTitleValid = titleFromFileName && titleFromFileName.length > MIN_TITLE_LENGTH;
|
||||
const folderTitleValid = titleFromParentFolder && titleFromParentFolder.length > MIN_TITLE_LENGTH;
|
||||
|
||||
if (filenameTitleValid && folderTitleValid) {
|
||||
// Both valid - prefer the longer one (series names are typically longer than episode names)
|
||||
// Use strict > to avoid preferring folder when lengths are equal (e.g., "Dexter" vs "Series")
|
||||
selectedTitle = titleFromParentFolder.length > titleFromFileName.length
|
||||
? titleFromParentFolder
|
||||
: titleFromFileName;
|
||||
} else if (folderTitleValid) {
|
||||
selectedTitle = titleFromParentFolder;
|
||||
} else if (filenameTitleValid) {
|
||||
selectedTitle = titleFromFileName;
|
||||
} else if (titleFromGrandParentFolder && titleFromGrandParentFolder.length > MIN_TITLE_LENGTH) {
|
||||
selectedTitle = titleFromGrandParentFolder;
|
||||
} else {
|
||||
selectedTitle = simpleTitle;
|
||||
}
|
||||
} else {
|
||||
selectedTitle = simpleTitle;
|
||||
// For non-TV shows (movies, etc.), use original logic: prefer filename
|
||||
if (titleFromFileName && titleFromFileName.length > MIN_TITLE_LENGTH) {
|
||||
selectedTitle = titleFromFileName;
|
||||
} else if (titleFromParentFolder && titleFromParentFolder.length > MIN_TITLE_LENGTH) {
|
||||
selectedTitle = titleFromParentFolder;
|
||||
} else if (titleFromGrandParentFolder && titleFromGrandParentFolder.length > MIN_TITLE_LENGTH) {
|
||||
selectedTitle = titleFromGrandParentFolder;
|
||||
} else {
|
||||
selectedTitle = simpleTitle;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedTitle && selectedTitle.length > MIN_TITLE_LENGTH) {
|
||||
|
||||
@@ -164,6 +164,14 @@ describe('FileNameMetaExtractor', () => {
|
||||
describe('Edge cases - title from folder (skipped)', () => {
|
||||
// These tests are skipped because the parser doesn't extract title from folder name
|
||||
// when the filename doesn't contain the show title
|
||||
// Pattern: FolderWithTitle/S01E01-EpisodeName.mkv should extract title from folder
|
||||
|
||||
it('Lord of Mysteries - title from folder, filename is S01E01-EpisodeName pattern', async () => {
|
||||
// Real-world case: folder contains title + quality info, filename is S01E01-EpisodeName format
|
||||
// Expected: extract "Lord of Mysteries" from folder, not "The Fool" from filename
|
||||
await titleSeasonEpTester('Lord of Mysteries', '1', '1',
|
||||
'/data/watch/test-files/Anime/Lord of Mysteries S01 1080p Dual Audio WEBRip DD+ x265-EMBER/S01E01-The Fool [8A4E8B1F].mkv');
|
||||
});
|
||||
|
||||
it.skip('handles files named with season in folder', async () => {
|
||||
await titleSeasonEpTester('MythBusters', '2', '1',
|
||||
@@ -180,7 +188,7 @@ describe('FileNameMetaExtractor', () => {
|
||||
'/data/watch/test-files/Anime/Le Depart/13 it a new start.mkv');
|
||||
});
|
||||
|
||||
it.skip('Akudama Drive - title from folder', async () => {
|
||||
it('Akudama Drive - title from folder', async () => {
|
||||
await titleSeasonEpTester('Akudama Drive', '1', '2',
|
||||
'/data/watch/test-files/Anime/Akudama Drive/S01E02-RESERVOIR DOGS [F1D64557].mkv');
|
||||
});
|
||||
@@ -210,8 +218,8 @@ describe('FileNameMetaExtractor', () => {
|
||||
'/data/watch/test-files/Anime/K-Project/[CBM]_K_-_02_-_Kitten_[1080p-FLAC]_[A83DF131].mkv');
|
||||
});
|
||||
|
||||
it.skip('Made in Abyss - title from folder', async () => {
|
||||
await titleSeasonEpTester('Made In Abyss', '1', '2',
|
||||
it('Made in Abyss - title from folder', async () => {
|
||||
await titleSeasonEpTester('Made in Abyss', '1', '2',
|
||||
'/data/watch/test-files/Anime/Made in Abyss/S01E02-Resurrection Festival [AE07AD68].mkv');
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user