- We introduce a new submodule of beets.util named id_extractors.
- Parts of the ID extraction utilites required by metadata source plugins
should live there.
- Also this enables future usage of those utilities from the "outside" of
metadata source plugins.
- Move Discogs ID extractor to the new module and change test_discogs to use
the new location.
- Add spotify_id_regex variable to the new module.
@mkhl was kind enough to do a drive-by review of my proposed changes,
which I'll include here as the GitHub URI may bit-rot over time (it's
technically
[here](bc21caa0d5),
but that commit isn't part of the `beets` repo, so may get GC'd).
I've encorporated all their proposed changes, as their code is being run
against an existing Beets library, whereas my changes were made as I
tried to set up Beets for the first time - thus I'm inclined to trust
their known-working code more than my own!
This is a review starting at
bc21caa0d5 (diff-d53f73df7f26990645e7bdac865ef86a52b67bafc6fe6ad69890b510a57e2955R210)
(`class DelimeteredString(String):`)
> for context this is the version i'm using now:
>
> ```python
> class DelimitedString(String):
> model_type = list
>
> def __init__(self, delimiter):
> self.delimiter = delimiter
>
> def format(self, value):
> return self.delimiter.join(value)
>
> def parse(self, string):
> if not string:
> return []
> return string.split(self.delimiter)
>
> def to_sql(self, model_value):
> return self.delimiter.join(model_value)
> ```
>
> i think 'delimited string' is the correct term here
>
> the rest of the code doesn't seem to use many abbreviations, so calling the property `delimiter` seems appropriate
>
> i don't think a default value for the delimiter makes a lot of sense?
>
> the list comprehension and string conversions in `to_sql` don't seem necessary to me, see above. did you run into trouble without them?
>
> the `from_sql` seems to just be missing functionality from the `Type` parent and seems completely unnecessary
>
> `parse` shouldn't be able to fail because at that point, we've ensured that its argument is actually a string. i also added a `if not string` condition because otherwise the empty list of album types would turn into the list containing the empty string (because that's what split returns)
>
> if we don't define a `format` method here we print the internal python representation of the values (i.e. `['album', 'live']` or somesuch) in the `beet write` output. joining on the delimiter nicely formats the output :)
>
> just so i don't ping you twice unnecessarily, i think it's better to instantiate this type with `'; '` (semicolon space) as the delimiter, because that's what was used before to join the albumtypes and what we'll find in the database
All these changes have been made, including the switch from `;` to
`;<space>` as the in-DB separator.
Fixes#4627.
AcousticBrainz is shutting down as of early 2023. Deprecate the absubmit
plugin and update the acousticbrainz plugin to require configuration of
an AcousticBrainz server instance.
tighten/loosen/fix some types as required and to the extent that we're
actually able to name the relevant types. Used a bunch of `cast(T, value)`
to help the type checker, in particular around confuse (that should probably
be fixed by typing confuse) and around getters for Item fields (not sure
whether we can do anything about that. We could add runtime checks (but what
the error handling do?))
PR #3748 changed the way cover art is fetched from the cover art
archive, but the manual addition of a `-` to the width suffix that was
needed when the image URI was being constructed manually was not
removed. Because of this the plugin would try to look up the property
under `thumbnails` that didn't exist (for example `-1200` instead of
`1200`), which would fail.
- some cleanup for recent Python which has samefile() on Windows
- also, fix this function by only upper-/lower-casing one path component
at a time. It is unclear to me how this could have ever worked.
- samefile exists on all platforms for recent python
- don't rely on monkey-patching os/os.path and on specifics on the
implementation: as a result of doing so, the tests start failing in
obscure ways as soon as the implementation (and its usage of
os.path.exists and os.path.samefile) is changed
This guards the os.chmod calls so it's only called IF the
permissions need changing. This guards against an exception in
certain complex library setups.