I've spent 2 hours troubleshooting why none of my music had genre tag.
It was because the single `genre`, without `s` doesn't seem to cover any
good ganre tags... at least it didn't on my opus files
looking at the code:
7ecd86101e/mediafile.py (L1669-L2167)
i don't honestly know why anyone created the single `ganre` field in the
first place
* Fixes#5513
* Fixes#5518
This PR adds the `test` folder and manuals to the package source tarball
and upgrades the dependencies to fix a few vulnerabilities.
I also added a fix for the changelog not making it to the release notes.
Fixes#5148.
When importing, the code that matches tracks does not consider the
medium number. This causes problems on Hybrid SACDs (and other releases)
where the artists, track numbers, titles, and lengths are the same on
both layers.
I added a distance penalty for mismatching medium numbers.
Before:
```
$ beet imp .
/Volumes/Music/ti/Red Garland/1958 - All Mornin' Long - 1 (6 items)
Match (95.4%):
The Red Garland Quintet - All Mornin' Long
≠ media, year
MusicBrainz, 2xHybrid SACD (CD layer), 2013, US, Analogue Productions, CPRJ 7130 SA, mono
https://musicbrainz.org/release/6a584522-58ea-470b-81fb-e60e5cd7b21e
* Artist: The Red Garland Quintet
* Album: All Mornin' Long
* Hybrid SACD (CD layer) 1
≠ (#2-1) All Mornin' Long (20:21) -> (#1-1) All Mornin' Long (20:21)
≠ (#2-2) They Can't Take That Away From Me (10:24) -> (#1-2) They Can't Take That Away From Me (10:27)
≠ (#2-3) Our Delight (6:23) -> (#1-3) Our Delight (6:23)
* Hybrid SACD (CD layer) 2
≠ (#1-1) All mornin' long (20:21) -> (#2-1) All Mornin' Long (20:21)
≠ (#1-2) They can't take that away from me (10:27) -> (#2-2) They Can't Take That Away From Me (10:25)
≠ (#1-3) Our delight (6:23) -> (#2-3) Our Delight (6:23)
➜ [A]pply, More candidates, Skip, Use as-is, as Tracks, Group albums,
Enter search, enter Id, aBort, eDit, edit Candidates?
```
Note that all tracks tagged with disc 1 get moved to disc 2 and vice
versa.
After:
```
$ beet-test imp .
/Volumes/Music/ti/Red Garland/1958 - All Mornin' Long - 1 (6 items)
Match (95.4%):
The Red Garland Quintet - All Mornin' Long
≠ media, year
MusicBrainz, 2xMedia, 2013, US, Analogue Productions, CPRJ 7130 SA, mono
https://musicbrainz.org/release/6a584522-58ea-470b-81fb-e60e5cd7b21e
* Artist: The Red Garland Quintet
* Album: All Mornin' Long
* Hybrid SACD (CD layer) 1
≠ (#1-1) All mornin' long (20:21) -> (#1-1) All Mornin' Long (20:21)
≠ (#1-2) They can't take that away from me (10:27) -> (#1-2) They Can't Take That Away From Me (10:27)
≠ (#1-3) Our delight (6:23) -> (#1-3) Our Delight (6:23)
* Hybrid SACD (SACD layer) 2
* (#2-1) All Mornin' Long (20:21)
* (#2-2) They Can't Take That Away From Me (10:24)
* (#2-3) Our Delight (6:23)
➜ [A]pply, More candidates, Skip, Use as-is, as Tracks, Group albums,
Enter search, enter Id, aBort, eDit, edit Candidates?
```
Yay!
Quick fix for #5467.
Checks if the path for python is under the windows store folder then
error and point the user to the beets
[documentation](https://beets.readthedocs.io/en/stable/guides/main.html).
Happy for feedback to improve, but thought it best to exit as early as
possible.
This utilises regex substitution in the substitute plugin. The previous
approach only used regex to match the pattern, then replaced it with a
static string. This change allows more complex substitutions, where the
output depends on the input.
### Example use case
Say we want to keep only the first artist of a multi-artist credit, as
in the following list:
```
Neil Young & Crazy Horse -> Neil Young
Michael Hurley, The Holy Modal Rounders, Jeffrey Frederick & The Clamtones -> Michael Hurley
James Yorkston and the Athletes -> James Yorkston
````
This would previously have required three separate rules, one for each
resulting artist. By using a regex substitution, we can get the desired
behaviour in a single rule:
```yaml
substitute:
^(.*?)(,| &| and).*: \1
```
(Capture the text until the first `,` ` &` or ` and`, then use that
capture group as the output)
### Notes
I've kept the previous behaviour of only applying the first matching
rule, but I'm not 100% sure it's the ideal approach.
I can imagine both cases where you want to apply several rules in
sequence and cases where you want to stop after the first match.
This PR refactors the test codebase by removing redundant functions and
simplifying item and album creation. Key changes include:
- Removed redundant `_item_ident` index tracker from `_common.py`.
- Removed `album` function from `_common.py` replacing it with direct
`library.Album` invocations.
- Removed `generate_album_info` and `generate_track_info` functions,
replacing them directly with `TrackInfo` and `AlbumInfo`.
- Updated `setup.cfg` to exclude test helper files from coverage
reports.
- Adjusted the tests regarding the changes, and simplified
`test_mbsync.py`.