Commit Graph
888 Commits
Author SHA1 Message Date
Šarūnas Nejus ebf638dce1 match: Improve Proposal and add AlbumImportTask 2026-08-27 03:00:57 +01:00
Šarūnas Nejus 98051a234d Add ability to filter flexible attributes through the Query
For a flexible attribute query, replace the `col_name` property with
a function call that extracts that attribute from the `field_attrs`
field introduced in the earlier commit.

Additionally, for boolean, numeric and date queries CAST the value to
NUMERIC SQLite affinity to ensure that our queries like 'flex:1..5' and
'flex:true' continue working fine.

This removes the concept of 'slow query', since every query for any
field now has an SQL clause.
2026-08-27 02:56:48 +01:00
Šarūnas Nejus d9e2b65758 Merge branch 'master' into fix/lrclib-null-lyrics 2026-08-22 17:41:55 +01:00
Šarūnas Nejus 467cf7a8b7 Fix lyrics integration tests 2026-08-21 20:56:39 +01:00
Šarūnas Nejus a3bb963ea0 ipfs: fix play command 2026-08-20 00:51:44 +01:00
Šarūnas Nejus 27900f58fb Prefer imports from modules that provide import aliases 2026-08-18 23:20:39 +01:00
Šarūnas Nejus 4aa5aa62ac typing: fix types in beetsplug._utils.art 2026-08-18 23:20:38 +01:00
Šarūnas Nejus 1969622874 typing: fix types in event handlers 2026-08-18 10:46:33 +01:00
J0J0 Todos 5b0e9e94cd lastgenre: Test new fetch_va_genres helper 2026-08-18 07:01:09 +02:00
Šarūnas Nejus d53af83386 Serialize BPD notifications per connection
- Track active notification tasks by connection so repeated dispatches do not
  send duplicate idle responses while a previous send is still draining.
- Add regression coverage for serialized notification delivery and idle command
  disconnect handling.
2026-08-17 05:05:21 +01:00
Šarūnas Nejus 9b16f67af1 Remove bluelet in favor of using asyncio in bpd plugin 2026-08-17 05:05:21 +01:00
Šarūnas Nejus b19f0c0967 Fix lrclib integration test 2026-08-15 17:53:34 -07:00
David HowardandClaude Opus 5 f68aefa058 lyrics: address review feedback
Return an empty string rather than INSTRUMENTAL_LYRICS from the final
fallback in LRCLyrics.get_text. That branch is not about an instrumental
track, so the marker was misleading.

Strip the LRC timestamps when synced lyrics stand in for a null
plainLyrics. The value is being used as plain text there, so the
timestamps do not belong in it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 17:52:56 -07:00
David Howard cd50a42c04 lyrics: don't match LRCLib entries that have no lyrics
LRCLib stores track metadata independently of the lyrics themselves, so an
entry can come back with both `plainLyrics` and `syncedLyrics` null while
`instrumental` is False. `LRCLyrics.is_valid` accepted such an entry as a
match on duration alone, and `get_text` then returned `self.plain`, i.e.
None, despite being annotated `-> str`.

The None propagated into `Lyrics`, and the first access of its text raised

    AttributeError: 'NoneType' object has no attribute 'splitlines'

`beet lyrics` surfaced this per track, but during an import the exception
escaped the pipeline stage and aborted the entire run: one such track
stranded every file queued behind it.

Treat an entry with no lyrics text as not a match, so the search moves on to
other candidates and backends and ultimately reports that no lyrics were
found. That is deliberately distinct from an instrumental track, where "no
lyrics" is itself the answer and the existing `instrumental` handling still
applies. Marking these as instrumental would assert something the API
response does not tell us.

Also fall back to synced lyrics when only `plainLyrics` is null, rather than
discarding lyrics we do have, and correct the annotations: `plainLyrics` and
`LRCLyrics.plain` are both nullable.
2026-08-15 17:49:54 -07:00
Henry b7993d19ac fix(discogs): retry malformed search responses #6912 2026-08-15 09:53:26 -07:00
Cohen Karnell d97d78f830 Fix KeyError in Deezer track conversion when artist is missing
_get_track resolved the artist with track_data.get('contributors', [track_data['artist']]),
whose default is evaluated eagerly, so track_data['artist'] raises KeyError whenever the
artist key is absent, even when contributors is present. Guard the fallback the same way
album_for_id already does. Fixes #4339.
2026-08-14 12:02:07 -04:00
Trey Turner afd07ce5d3 fix(discogs): retry malformed search responses 2026-08-11 16:04:08 -05:00
NoDancing f6b7e1f761 tidal: Normalize copyright text into a concise label name
_parse_label() used to store Tidal's raw copyright info as the label
name. Add _normalize_label(), a helper that strips leading markers,
years, legal entities, and boilerplate clauses.

Fixes #6796
2026-08-11 00:39:31 +01:00
Šarūnas Nejus 5933fcad85 Refactor template evaluation to handle format strings ONLY
- Handle formats as strings ONLY and evaluate them through a shared
  cached template helper.
- This removes the need for conditional logic that acts on Template
  objects or strings.
2026-08-05 01:56:59 +01:00
Šarūnas Nejus 03045b80e9 Merge branch 'master' into master 2026-08-04 16:45:30 +01:00
Piotr Szpetkowski 681f27feb6 fix(deezer): use free text for singleton searches
Singleton searches built the query as `<title> artist:"<artist>"`. Deezer
discards unquoted free text as soon as a query contains any field:"value"
filter, so that was evaluated as `artist:"<artist>"` alone - every track by
the artist, in Deezer's own relevance order, truncated to `search_limit`
(default 5). Substituting nonsense for the title returns a byte-identical
result set. For any artist with more releases than that window, the track
being imported was simply never among the candidates offered.

Filtering on the title as well (`track:"<title>" artist:"<artist>"`) is not
a fix: `artist:` matches loosely enough to return unrelated artists, so the
two filters can intersect to nothing even for a correctly tagged file.
`track:"Get Lucky" artist:"Daft Punk"` returns zero results, while the plain
free text `Get Lucky Daft Punk` returns the right track first.

Measured over 12 tracks at the default `search_limit`, counting the wanted
track appearing anywhere in the results:

  `<title> artist:"..."`              6/12, mean rank 1.50
  `track:"..." artist:"..."`          7/12, mean rank 1.00
  free text                          10/12, mean rank 1.00

Album searches are unchanged; `album:"<name>"` has no equivalent problem.

Adds test/plugins/test_deezer.py, which did not exist.
2026-07-30 21:18:59 +02:00
Alok Saboo 7a49cc4882 Merge branch 'master' into upgrade 2026-07-30 09:11:46 -04:00
Šarūnas Nejus bb66b0c378 Return Path from TestHelper.create_mediafile_fixture 2026-07-30 12:18:49 +01:00
Šarūnas Nejus b2f52ac124 Remove syspath 2026-07-30 12:18:49 +01:00
Šarūnas Nejus 951e32a852 Use pathlib.Path wherever possible in tests 2026-07-30 12:18:49 +01:00
Šarūnas Nejus 04c2304879 Replace item.path with item.filepath in tests 2026-07-30 12:18:49 +01:00
Alok Saboo 789c13e4f7 Add bitrate-based upgrade duplicate_action 2026-07-28 19:51:30 -04:00
Šarūnas Nejus 5dcc35112d Fix yoda typedefs 2026-07-27 19:33:53 +01:00
Šarūnas Nejus 02a2c5700a Make RSRC a pathlib.Path 2026-07-24 17:03:57 +01:00
Šarūnas Nejus d24c0d341e Rename PathsMixin.temp_dir_path to PathsMixin.temp_path for consistency 2026-07-21 11:15:25 +01:00
Šarūnas Nejus 2e9ace7b20 Replace PathsMixin.temp_dir attribute with PathsMixin.temp_dir_path 2026-07-21 11:15:25 +01:00
Šarūnas Nejus dc2826fa4b Replace TestHelper.libdir attribute with TestHelper.lib_path 2026-07-21 11:15:25 +01:00
Šarūnas Nejus 7970a90214 Replace ImporterMixin.import_dir attribute with ImporterMixin.import_path
- Update importer fixtures and tests to use pathlib paths directly.
- Encode import paths only at the ImportSession boundary.
2026-07-21 11:15:25 +01:00
Šarūnas Nejus 3f277ad5a0 typing: feed PathLike as database path 2026-07-16 13:11:16 +01:00
Šarūnas Nejus 439a7fa75d discogs: Refactor _coalesce_tracks to make use of various tracks type_ 2026-07-16 11:57:10 +01:00
Šarūnas Nejus 8867848612 discogs: Add descriptions of each possible Tracks 2026-07-16 11:57:10 +01:00
Šarūnas Nejus c46f6a549b discogs: Dedupe test_strip_disambiguation 2026-07-16 11:51:32 +01:00
Šarūnas Nejus bbb1b5c1ef discogs: And now add full _coalesce_tracks coverage 2026-07-16 11:51:32 +01:00
Šarūnas Nejus bd9c753b99 discogs: Test index_tracks behaviour 2026-07-16 11:51:32 +01:00
Šarūnas Nejus b8f43e994a discogs: Test inherited track group artist 2026-07-16 11:51:31 +01:00
Šarūnas Nejus bc0591fdb6 discogs: Consolidate test_parse_tracklist_subtracks... tests 2026-07-16 11:50:58 +01:00
Šarūnas Nejus 1343d613d3 discogs: Move test_parse_tracklist_positions... under TestTracklist 2026-07-16 11:50:58 +01:00
Šarūnas Nejus 951af6d3e8 discogs: Use a single global fixture to kill DiscogsPlugin.setup 2026-07-16 11:50:58 +01:00
Šarūnas Nejus a126a3aaa3 discogs: Use Release instead of Bag in tests 2026-07-16 11:50:58 +01:00
Šarūnas Nejus 69cdd58240 discogs: remove redundant check for required fields 2026-07-16 11:50:58 +01:00
Samad 4ccdcc90c9 replaygain: add metaflac backend
Add a MetaflacBackend that computes ReplayGain for FLAC files with metaflac --add-replay-gain and reads the values back with --show-tag. Only FLAC is supported. Includes docs, a changelog entry, and tests.
2026-07-15 22:22:07 +01:00
f1nn 0d65a46bbc lyrics: add lrcmux backend 2026-07-15 16:12:21 +02:00
J0J0 TodosandŠarūnas Nejus c51f5755f3 lastgenre: Whitelist/Tree fixes; Default aliases
- Fixes some inconsistencies in spelling in the data files we ship with
  the plugin as well as adds some new genres to both files that seem to
  be returned often by last.fm.
  - For some changes the default aliases feature helps to streamline
    inconsistencies that come from last.fm already.
- The default aliases file that ships with beets
  - Tests fixes that prove that most of the alias normalization patterns
    work as they are supposed to.

Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
2026-07-15 16:04:51 +02:00
J0J0 Todos 3ce8c9bbf5 lastgenre: Tests for _filter_valid helper,
even though it's indirectly tested via resolve_genres tests and
elsewhere, it makes sense to keep them to help with future refactoring.
2026-07-15 16:04:51 +02:00
J0J0 TodosandŠarūnas Nejus 1674b5e7f9 lastgenre: Tests for genre alias normalization
Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
2026-07-15 16:04:51 +02:00