diff --git a/package.json b/package.json index 3d25e9d..73bd57a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "netfelix-audio-fix", - "version": "2026.04.21.17", + "version": "2026.04.21.18", "scripts": { "dev:server": "NODE_ENV=development bun --hot server/index.tsx", "dev:client": "vite", diff --git a/server/services/__tests__/path-parser.test.ts b/server/services/__tests__/path-parser.test.ts index 7eb63f3..a717ced 100644 --- a/server/services/__tests__/path-parser.test.ts +++ b/server/services/__tests__/path-parser.test.ts @@ -106,6 +106,20 @@ describe("parsePath", () => { expect(parsePath("/other/Hot Fuzz (2007)/Hot Fuzz (2007) [imdbid-tt0425112].mkv", MOVIES, TV)).toBeNull(); }); + test("episode without episode title falls back to SxxExx", () => { + const result = parsePath( + "/tv/Lost (2004)/Season 02/Lost (2004) - S02E21 - [DSNP WEBDL-1080p][EAC3 5.1][h264]-FLUX.mkv", + MOVIES, + TV, + ); + expect(result).not.toBeNull(); + expect(result!.type).toBe("Episode"); + expect(result!.seriesName).toBe("Lost"); + expect(result!.seasonNumber).toBe(2); + expect(result!.episodeNumber).toBe(21); + expect(result!.name).toBe("S02E21"); + }); + test("movie without provider ids (bare folder)", () => { const result = parsePath( "/movies/No Country for Old Men (2007)/No Country for Old Men (2007) - [Bluray-1080p].mkv", diff --git a/server/services/path-parser.ts b/server/services/path-parser.ts index 6be48ca..529cffc 100644 --- a/server/services/path-parser.ts +++ b/server/services/path-parser.ts @@ -100,8 +100,9 @@ function parseEpisode(filePath: string, tvPrefix: string, fileName: string, ext: // Episode title: everything after "- S01E01... -" up to the first "[". // e.g. "Breaking Bad (2008) - S05E03 - Hazard Pay [WEBDL-...]" - const epTitleMatch = fileName.match(/S\d{2}E\d{2}(?:-E\d{2})?\s*-\s*(.+?)(?:\s*\[|$)/i); - const episodeTitle = epTitleMatch ? epTitleMatch[1].trim() : fileName; + // Some files have no episode title: "Lost (2004) - S02E21 - [DSNP WEBDL-1080p]..." + const epTitleMatch = fileName.match(/S\d{2}E\d{2}(?:-E\d{2})?\s*-\s*([^\[]+?)(?:\s*\[|$)/i); + const episodeTitle = epTitleMatch ? epTitleMatch[1].trim() || `S${seMatch[1]}E${seMatch[2]}` : `S${seMatch[1]}E${seMatch[2]}`; return { type: "Episode",