Skip to content

Add library search by file path when query looks like a file name - #5681

Open
nathanpride wants to merge 1 commit into
advplyr:masterfrom
nathanpride:feat/search-by-filename
Open

nathanpride wants to merge 1 commit into
advplyr:masterfrom
nathanpride:feat/search-by-filename

Conversation

@nathanpride

Copy link
Copy Markdown

Brief summary

Library search now recognizes file-shape queries: when the query ends with a supported audio or ebook extension (e.g. lalalalala.mp3, dune.epub), items are additionally matched by their stored file paths and item folder path. Matches merge into the existing book/podcast result buckets.

Which issue is fixed?

Fixes #5680

In-depth Description

The trigger is a whitelist of extensions derived from the existing globals.SupportedAudioTypes + SupportedEbookTypes lists, so the extra path search only runs for queries that cannot match metadata fields anyway — ordinary searches are byte-for-byte unchanged and pay no extra cost (relevant to #5667: no libraryFiles scan on normal keystrokes).

  • New server/utils/queries/searchFileHelpers.js:
    • isFileSearchQuery(query) — case-insensitive suffix check against the extension whitelist (bare .mp3 counts)
    • getFileMatchIds(libraryId, textSearchQuery) — guarded json_each query over libraryFiles[].metadata.path (mirrors the existing narrator/tag/genre raw-SQL pattern, json_valid guard, LIMIT 1000) plus a plain libraryItems.path scan for folder-only matches
  • libraryItemsBookFilters.search() / libraryItemsPodcastFilters.search(): when triggered, one extra OR-term .id$ IN (...) is added to the existing findAll — dedup, limit/offset and user-permission filtering come from the existing query machinery
  • Podcast episode file matches are attributed to the parent podcast (episode library item → episode → podcast)
  • Same normalization as existing search (TextSearchQuery: case-insensitive, accent-folded)
  • No client changes, no API contract change, no schema change

How have you tested this?

  • 25 new tests in test/server/utils/queries/ (unit for the trigger incl. unicode/whitespace/edge inputs; in-memory sqlite integration for path matching, dedup, restricted-user exclusion, bare-extension query, metadata-only regression, podcast episode attribution)
  • Full suite: npm run build:server && mocha dist-server/test → 388 passing, 0 failing
  • eslint clean on all changed files
  • Manual: search track.mp3 returns items whose audio file matches; dune behaves exactly as before

Screenshots

N/A — server-only change, no UI changes (results render in the existing search shelves).

Queries ending with a supported audio or ebook extension (e.g.
lalalalala.mp3) now additionally match library items by their stored
file paths or item folder path. Matches are merged into the existing
book/podcast search buckets, deduplicated and permission-filtered by
the existing query. Metadata-only queries are unchanged and pay no
extra cost.

- New server/utils/queries/searchFileHelpers.js (isFileSearchQuery,
  getFileMatchIds) with unit + in-memory sqlite integration tests
- Book and podcast filter search() integration, podcast episode file
  matches attributed to the parent podcast
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.

[Enhancement]: Search library items by file name or path

1 participant