Skip to content

fix: naming tokens, multi-season search, and NAS CPU spike - #435

Merged
keonramses merged 9 commits into
MoldyTaint:devfrom
keonramses:dev
Jul 26, 2026
Merged

fix: naming tokens, multi-season search, and NAS CPU spike#435
keonramses merged 9 commits into
MoldyTaint:devfrom
keonramses:dev

Conversation

@keonramses

Copy link
Copy Markdown
Owner

Summary

  • Fix all MediaNamingInfo call sites so tokens like {TmdbId}, {OriginalTitle}, {ImdbId}, and {CollectionName} are populated at every folder/file naming point without requiring a manual rename
  • Fix multi-season pack search missing releases using S01-S07 / S01-07 notation from Bitmagnet
  • Fix CPU lockout on NAS-backed Docker volumes caused by accumulating D-state ffprobe processes

Related Issues

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring (no functional changes)
  • Documentation
  • Dependency update
  • Other:

Changes Made

Naming token coverage (fix: populate all MediaNamingInfo tokens at every naming call site)

  • +server.ts (series POST): generateSeriesFolderName wrapper was omitting tmdbId, imdbId, and originalTitle - the root cause of {TmdbId} not applying on series add
  • RenamePreviewService: movie/series folder name calls missing originalTitle, collectionName, and imdbId
  • SmartListService: movie add/auto-add called generateMovieFolderName before fetchMovieExternalIds; reordered fetch and added all missing fields to movie and series add/auto-add paths
  • manual-import-service: movie and series new-folder paths missing originalTitle, imdbId, collectionName
  • LibraryDestinationPlanner: widened MoviePlanInput and EpisodePlanInput to accept and pass through originalTitle, collectionName, imdbId
  • ReadyProviderFileMapper: widened MovieContext and SeriesContext to accept the same fields
  • DebridPollService: mediaContext now passes originalTitle, collectionName (movie) and originalTitle, tmdbId, imdbId (series) into context objects
  • StrmService: widened SeriesData interface and both buildMovieStrmPath/buildEpisodeStrmPath inputs; propagated fields through all DB-to-SeriesData assignments

Multi-season search (fix(search): fix multi-season pack search missing S01-S07 style releases)

  • MultiSeasonSearchStrategy Phase 1: changed ?? to || in complete-series filter - ?? never fell through because isCompleteSeries is always a boolean, making the seasons.length fallback dead code
  • MultiSeasonSearchStrategy Phase 2: removed season: startSeason from search criteria - it caused filterBySeasonEpisode to strip multi-season packs before Phase 2's own range check could see them
  • Added parser tests confirming S01-S07, S01-07, and bracketed [S01-S07] formats are all correctly detected as complete-series packs

NAS CPU lockout (fix(scan): prevent CPU lockout on NAS-backed Docker volumes during folder scan)

  • ffprobe.ts: added a global concurrency semaphore (default 1, configurable via FFPROBE_CONCURRENCY env var) to prevent D-state ffprobe processes accumulating on NAS mounts where SIGKILL has no effect
  • media-matcher.ts: changed per-file yield in processUnmatchedByRootFolder from setImmediate to a 250ms delay to prevent back-to-back NAS I/O saturation during the match phase

Areas Affected

  • UI/Frontend
  • API/Backend
  • Indexers
  • Download Clients
  • Library Management
  • Database/Schema
  • Subtitles
  • Documentation

Testing

  • Tested locally
  • Added/updated tests
  • All tests pass (npm run test)
  • Type checking passes (npm run check)

Checklist

  • Code follows project conventions
  • Ran npm run format
  • Commit messages follow conventional commits (feat:, fix:, etc.)
  • Svelte 5 runes used correctly ($state, $derived, $effect, $props)
  • No new warnings in console or build output
  • Documentation updated (if applicable)

Screenshots

N/A

- show all TMDB collection parts (not just library siblings), with missing entries dimmed and grayed out
- add Add Collection CTA that bulk-adds missing parts, inheriting rootFolderId and scoringProfileId from the current movie
- add per-movie hover overlay with + (add) (add individually) and i (info)  (Discover page) buttons
- add POST /api/library/collections/[tmdbId]/track endpoint that fetches collection from TMDB, skips existing library entries, and bulk-inserts missing movies using the standard add pipeline
- add contextual header buttons: search (missing-file tracked movies) and subtitle auto-download, each hidden when there is nothing to act on
…rch state

- show a primary "Search in Discover" button when no movies/tv match a library search, which links to ` /discover?type=movie` or `/discover?type=tv` depending on where the search is intiated
  - Both links carry the current search query via ?q= so Discover loads results without the user having to retype search query
- replace filteredOutResults.length === 0 guard in debug $effect with a debugResultsLoaded flag
- set debugResultsLoaded = true in the finally block after each load
- add clearAllFiles() to logHistoryService
- add DELETE handler to /api/settings/logs/history
…ng manual import

- resolveTvEpisodeMapping now returns episodeNumbers[] instead of a single episodeNumber
- buildEpisodeNamingInfo receives the full episode array so NamingService generates the correct multi-episode filename (e.g. S01E02-E03 instead of S01E02)
- add parsedEpisodes?: number[] to ManualImportDetectionData and DetectionGroup
- populate from resolveTvEpisodeIdentifier when episodeNumbers.length > 1
- replace editable episode input with a read-only E1-E2 (auto) display for multi-episode files
…lder scan

- add a global ffprobe concurrency semaphore (default 1, configurable via FFPROBE_CONCURRENCY env var) to prevent D-state ffprobe processes accumulating on NAS mounts where SIGKILL has no effect
- change processUnmatchedByRootFolder per-file yield from setImmediate to 250ms delay, matching processAllUnmatched, to prevent back-to-back NAS I/O saturation during the match phase
- change Phase 1 complete-series filter from ?? to || so the seasons-length fallback actually runs; ?? never falls through because isCompleteSeries is always a boolean (never undefined)
- remove season: startSeason from Phase 2 search criteria; passing a season caused filterBySeasonEpisode to strip multi-season packs before Phase 2's own range filter could see them
- add parser tests confirming S01-S07, S01-07, and bracketed [S01-S07] in localized titles are correctly detected as complete-series packs
- fix series folder naming on add: generateSeriesFolderName wrapper in series POST handler was omitting tmdbId, imdbId, and originalTitle
- fix RenamePreviewService: movie and series folder name calls missing originalTitle, collectionName (movie), and imdbId (series)
- fix SmartListService: movie add/auto-add called generateMovieFolderName before fetchMovieExternalIds; reordered and added all missing fields to both movie and series add/auto-add paths
- fix manual-import-service: movie and series new-folder paths missing originalTitle, imdbId, collectionName
- fix LibraryDestinationPlanner: widen MoviePlanInput and EpisodePlanInput to accept originalTitle, collectionName, imdbId; pass all fields through to MediaNamingInfo in planMovie and planEpisode
- fix ReadyProviderFileMapper: widen MovieContext and SeriesContext to accept originalTitle, collectionName (movie), tmdbId, imdbId (series)
- fix DebridPollService: mediaContext now passes originalTitle, collectionName (movie) and originalTitle, tmdbId, imdbId (series) into the context objects consumed by ReadyProviderFileMapper
- fix StrmService: widen SeriesData interface and buildMovieStrmPath / buildEpisodeStrmPath inputs to include originalTitle, collectionName, imdbId; propagate fields through all DB-to-SeriesData assignments and createStrmFileDirect's inline show object
@keonramses
keonramses requested a review from MoldyTaint as a code owner July 26, 2026 02:01
@keonramses
keonramses merged commit 87616eb into MoldyTaint:dev Jul 26, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant