The aforementioned commits introduced a nmuber of changes since I
implemented this test:
- The syntax `self.assertExists(m3u_filepath)` was an old and now invalid
way of checking existence of a path using assertion, change to `assert
m3u_filepath.exists()` which now use string instead of bytes
- Use of `Path()` and strings instead of `path.join` and bytes for
handling directory path
Test functions inspired from `test_playlist_update_output_extm3u()` in
`test_smartplaylist.py`.
Test successfully passed using:
`poetry run pytest test/plugins/test_smartplaylist.py`
Fixes#6316
When importing compilations/various artists albums, several fields used the
hardcoded string "Various Artists" instead of the user-configured `va_name`
setting:
- In the **musicbrainz plugin**, only `info.artist` was overridden with `va_name`
when a release was identified as VA. The `artist_sort`, `artists_sort`,
`artist_credit`, `artists_credit`, and `artists` fields were left with the raw
MusicBrainz value ("Various Artists"), which then propagated to
`albumartist_sort`, `albumartists_sort`, `albumartist_credit`,
`albumartists_credit`, and `albumartists` on items.
- In the **beatport plugin**, the VA artist name was hardcoded to
"Various Artists" instead of reading from config.
## Changes
- `beetsplug/musicbrainz.py`: When `info.va` is true, override all artist-related
fields (`artist_sort`, `artists`, `artists_sort`, `artist_credit`,
`artists_credit`) with `va_name`, not just `artist`.
- `beetsplug/beatport.py`: Replace hardcoded "Various Artists" with
`config["va_name"].as_str()`.
- `docs/changelog.rst`: Add changelog entries for both fixes.
When importing compilations, albumartist_sort, albumartists_sort,
albumartist_credit, albumartists_credit, and albumartists were
hardcoded to "Various Artists" instead of using the user-configured
va_name setting. This also fixes the same issue in the beatport plugin.
Fixes#6316
Fixes#6412.
This is my first time submitting a PR for an open source project so
please point out any mistakes!
## Summary
- Add `discogs.extra_tags` configuration option to narrow Discogs search
queries using existing tag values.
- Map supported tags (`barcode`, `catalognum`, `country`, `label`,
`media`, `year`) to corresponding Discogs search parameters.
- Update Discogs plugin documentation and tests to cover the new
behavior.
## Details
The Discogs plugin now mirrors `musicbrainz.extra_tags` by allowing
users to specify additional tags that should be used when building
Discogs search filters.
- New config option: `discogs.extra_tags` (default: `[]`).
- Supported tags and their Discogs search parameters:
- `barcode` → `barcode`
- `catalognum` → `catno` (whitespace removed)
- `country` → `country`
- `label` → `label`
- `media` → `format`
- `year` → `year`
- Tags `alias` and `tracks` are recognized but intentionally ignored for
Discogs, since the Discogs API does not provide direct equivalents for
these MusicBrainz-specific fields.
When `extra_tags` are configured, the plugin uses `beets.util.plurality`
over the items in the import session to select the most common value for
each configured tag and adds the corresponding Discogs filter.
## Testing
- Added unit tests in `test/plugins/test_discogs.py` to verify:
- Default search filters remain unchanged when `extra_tags` is not set.
- `discogs.extra_tags: [label, catalognum]` results in `label` and
`catno` filters populated from library items (with catalog number
whitespace stripped).
- Ran:
- `pytest test/plugins/test_discogs.py`
- `pytest test/plugins/test_musicbrainz.py`
## Enforce Changelog Entries Under 'Unreleased' Section
I've had enough checking this manually 😆. Adds a CI lint step
that prevents contributors from accidentally adding changelog entries
under an already-released version header in `docs/changelog.rst`.
### How it works
The check runs `git diff --word-diff=plain -U1000` against the base
branch, then pipes through `awk` to scan the diff for new list entries
(`{+- ...`) that appear after any versioned release header (e.g. `1.2.3
(`). If such an entry is found, the step fails with a human-readable
error pointing to the offending line which GitHub should show in the
diff view.
* `--word-diff=plain` is required to match _truly new_ changelog entries
instead of some formatting adjustments in the middle of the line.
* `-U1000` should ensure that we grab the first 1000 lines in the
changelog to reliably match the headers.
Fixes#5993
The section is outdated. MacOS (or HomeBrew's python package?) by
default disallows using `pip3 install` even with `--user` option.
I'd actually propose to add more information around how to use `pipx` in
this installation guide to install beets and its plugins (both provided
as extras and third-party), maybe even make it the main focus of this
page as a recommended way regardless of which OS and Linux distro is
used. I can create a separate issue/discussion to discuss and align on
this if it's fine by you.
* official/master: (54 commits)
Require data_source in album_for_id and track_for_id functions
Invoke album_matched hook from AlbumMatch.__post_init__
Refactor match_by_id
Take data source into account when deciding duplicate candidates
Return album candidates from multiple sources when matching by IDs
Add a test to reproduce the issue
Move assignment tests to test/autotag/test_match.py
Pulled latest changelog and added my entry to 'Unreleased > Bug fixes' section.
Moved changelog note to top, under Unreleased.
This PR improves the regex detection used for the drive_sep_replace default.
This PR improves the regex detection used for the drive_sep_replace default.
refactor: Use deprecate_for_user for beatport/bpsync deprecation warnings
Fix docs: use single-line deprecated directive compatible with docstrfmt
Fix docs formatting for beatport and bpsync rst files
Deprecate beatport and bpsync plugins
Update changelog.rst
try to fix fish plugin
Make get_search_query_with_filters abstract
Document new methods
Document shared metadata search plugin workflow
...
Closes#6178 (multiple metadata source results per ID) and #6181
(duplicate/overwrite of candidates).
- (#6178) Replace `album_for_id` / `track_for_id` with `albums_for_ids`
/ `tracks_for_ids` in `metadata_plugins` that yield candidates from all
metadata sources
- (#6181) Use `Info.identifier` (`(data_source, id)`) as candidate keys
to avoid cross-source ID collisions.
- Add tests (`test/autotag/test_match.py`) for assignment logic and
multi-source ID matching
- Simplify `match_by_id`
- Dedupe `album_matched` event emission by moving it to
`AlbumMatch.__post_init__` (and convert `AlbumMatch` / `TrackMatch` to
dataclasses)
These functions now accept both an ID and data_source parameter,
enabling plugins like mbsync and missing to retrieve metadata from the
correct source.
Update mbsync and missing plugins to use the restored functions with
explicit data_source parameters. Add data_source validation to prevent
lookups when the source is not specified.
Add get_metadata_source helper function to retrieve plugins by their
data_source name, cached for performance.
I imported an album where a track had the name `1:00 AM - Clear` and
another track named `12:00 AM - Clear` (just two examples).
See: [Animal Crossing: New Horizons
OST](https://musicbrainz.org/release/263f7ed3-60c2-4251-ac7d-6da3f8691256)
After import, the former was renamed `1_00 AM - Clear`, and the latter
`12;00 AM - Clear`. Notice the inconsistency of how the `:` was
replaced.
I did not make use of the (hidden) `drive_sep_replace` setting. These
were my `replace` settings:
```
replace: # prevent file name incompatibiliy
'[\s]' : ' ' # standardize whitespace
'["`‘’“”]' : "'" # standardize quotes
'[\u002D\u2010-\u2015\u2E3A]' : '-' # standardize dashes
'[\u2E3B\uFE58\uFE63\uFF0D]' : '-' # standardize dashes
'[\xAD]' : '-' # standardize dashes
'[\\\|\/]' : ' ' # slashes, pipe > space
'[:]' : ';' # colon > semicolon
'[<>]' : '-' # chevrons > dashes
'[\?\*]' : '' # remove restricted characters
'[\x00-\x1F\x7F]' : '' # remove basic control characters
'[\x80-\x9F]' : '' # remove extra control characters
'^\.' : '' # remove leading period
'\.$' : '' # remove trailing period
'^\s+' : '' # remove leading space
'\s+$' : '' # remove trailing space
```
I found the issue to be too generic regex for drive separator detection.
I'm on macOS, so this is irrelevant to me anyway (and I got around it by
adding `drive_sep_replace: ';'` to my settings), but regardless, I think
this could be improved.
This PR improves the regex to detect drive separators. Instead of merely
looking for any first character followed by a colon (`^\w:`), we look
for a letter, followed by a colon, followed by a backslash instead
(`^[a-zA-Z]:\\`).
The regex logic is solid, but I am not able to test this on a real
Windows environment.
~Still have to add an entry to the changelog, will do so soon.~
# Update
Initially this commit failed the
`MoveTest.test_move_file_with_colon_alt_separator` test because it
checks the logic using a `C:DOS` path. So I had to make the logic less
restrictive again, not checking for a backslash (`^[a-zA-Z]:`). I would
argue the test itself should be amended (test with `C:\DOS` instead),
but that's not up to me.
As a result, my case of "1:00 AM" being replaced incorrectly is still
resolved, but other hypothetical cases like "a:b" would still not be
covered due to an arguably incorrect test limiting a more precise regex.