Commit graph

13301 commits

Author SHA1 Message Date
Šarūnas Nejus
ca0b3171cc
musicbrainz: access the custom server directly, if configured 2025-12-20 01:35:51 +00:00
Šarūnas Nejus
6b034da147
musicbrainz: browse directly 2025-12-20 01:35:51 +00:00
Šarūnas Nejus
abad03c1cb
musicbrainz: search directly 2025-12-20 01:35:51 +00:00
Šarūnas Nejus
d70e591738
musicbrainz: lookup recordings directly 2025-12-20 01:35:51 +00:00
Šarūnas Nejus
2a63e13617
musicbrainz: lookup release directly 2025-12-20 01:35:51 +00:00
Šarūnas Nejus
7fdb458524
Move pseudo release lookup under the plugin 2025-12-20 01:35:51 +00:00
Šarūnas Nejus
69e3a8233d
Add missing blame ignore revs from musicbrainz plugin 2025-12-20 01:35:51 +00:00
Šarūnas Nejus
a866347345
Define MusicBrainzAPI class with rate limiting 2025-12-20 01:35:51 +00:00
Šarūnas Nejus
fda3bbaea5
Move TimeoutSession under beetsplug._utils 2025-12-20 01:35:51 +00:00
Henry Oberholtzer
ac0b6ec5e4 Merge branch 'Nedra1998-improved-multiartist' 2025-12-19 12:18:03 -08:00
Arden Rasmussen
a7170fae45 expand tests to include check for track artists 2025-12-18 16:23:58 -08:00
henry
09476bdad9
Titlecase Plugin Improvements (#6220)
- Add preserving strings that are all lowercase or all upper case
- Fix spelling of 'separator' in config, docs and code
- Move most of the logging for the plugin to debug to keep log cleaner.

Improvements I found a need for in my daily use with the plugin.

- [x] Documentation. (If you've added a new command-line flag, for
example, find the appropriate page under `docs/` to describe it.)
- [x] Changelog. (Skipping as the plugin has not been released yet)
- [x] Tests. (Very much encouraged but not strictly required.)
2025-12-17 16:10:16 -08:00
Arden Rasmussen
9cbbad19f8 remove changes for lastgenre as there was an existing PR for that work 2025-12-17 15:57:23 -08:00
Arden Rasmussen
01e0aeb662 address linter and ai comments from pr 2025-12-17 12:20:05 -08:00
Arden Rasmussen
963a9692cc added tests for multi-artist spotify and lastgenre changes 2025-12-17 11:54:12 -08:00
Arden Rasmussen
62256adf4e support multiple artists for spotify and improve multiartist support for lastgenre 2025-12-17 10:52:50 -08:00
Henry
e039df4eb4 Cleanup, fix format 2025-12-16 19:06:37 -08:00
Henry
d7b9ccab3b Titlecase Plugin Improvements: Add preserving all lowercase and all upper case strings; Fix spelling of 'separator' in config, docs and code; Move most of the logging for the plugin to debug to keep log cleaner. 2025-12-16 18:56:39 -08:00
Sebastian Mohr
ffede9d4e6
preserve the order in which queries were specified in the configuration (#6185)
## Description

Fixes #6183

The problem was that the plugin was combining multiple queries using
`OrQuery`, which didn't preserve the order in which queries were
specified in the configuration.
2025-12-10 14:12:32 +01:00
Alok Saboo
515f9b6154
Merge branch 'master' into smartplaylist 2025-12-09 13:35:21 -05:00
Guy Bloom
2bd77b9895
Fix convert --format with never_convert_lossy_files (#6171)
## Description

Fixes #5625 

When `convert.never_convert_lossy_files` is enabled, `beet convert` was
ignoring the explicit `--format` option and just copying the lossy files
without
transcoding them. For example:

- `beet convert format:mp3 --format opus`

would still produce MP3 files instead of OPUS.

Change:

- Allows to override options `never_convert_lossy_files`, `max_bitrate`
or `no_convert` for `beet convert` as well as trying to convert to the
same format as existing already with a new option `--force`. That way,
for example lossy files selected by the query are transcoded to the
requested format anyway.
- Keeps existing behavior for automatic conversion on import (no CLI
override there).
- Adds tests to cover checking whether `--force` correctly overrides
settings or CLI options.
- Documents the behavior in the convert plugin docs

Co-authored-by: J0J0 Todos <jojo@peek-a-boo.at>
2025-12-03 22:48:41 +01:00
Alok Saboo
7cf6d7594e Merge remote-tracking branch 'upstream/master' into smartplaylist 2025-12-02 09:31:20 -05:00
Alok Saboo
20d9b6a136 Fix URL-encoding path conversion 2025-12-02 09:27:24 -05:00
Alok Saboo
03283aaf27 update
lint
2025-12-02 09:27:23 -05:00
Alok Saboo
b7541bedbd Annotated handlers to accept a Library instead of Any and added typed playlist helpers 2025-12-02 09:10:06 -05:00
Alok Saboo
715b2a97e7 Merge remote-tracking branch 'upstream/master' into smartplaylist 2025-12-02 09:02:15 -05:00
Sebastian Mohr
53931279a3
docs: fix link to plugin development docs (#6198)
Fixes the link to the plugin development documentation.
2025-12-02 11:45:05 +01:00
Robin Bowes
fdaebc653a docs: Fix link to plugin development docs 2025-12-02 11:40:18 +01:00
Sebastian Mohr
ca7e959f5b
Sanitize log messages by removing control characters (#6199)
This pull request addresses an issue where control characters in log
messages could halt beets execution entirely. The fix implements
sanitization of log messages by removing C0 and C1 control characters
before they reach the terminal.
2025-12-02 11:32:00 +01:00
Anton Bobov
67e668d81f
fix: Sanitize log messages by removing control characters
Added regex pattern to strip C0/C1 control characters (excluding useful
whitespace) from log messages before terminal output. This prevents
disruptive/malicious control sequences from affecting terminal
rendering.
2025-12-02 15:27:24 +05:00
Šarūnas Nejus
6abb901b6b
Add deprecation warning for musicbrainz.enabled but use it to load the plugin, centralise deprecations handling (#6127)
Fixes: #6121

This PR introduces a centralized deprecation system and adjusts
`musicbrainz` plugin loading to properly handle the deprecated
`musicbrainz.enabled` configuration option.

#### MusicBrainz

- Added deprecation warnings for the `musicbrainz.enabled` configuration
option:
- When set to `true`, warns users to explicitly add `musicbrainz` to
their `plugins` configuration and adds it if not already present
- When set to `false`, warns users and adds the plugin to
`disabled_plugins` (list
    received by the `--disable-plugins` flag)

#### Deprecations

- Created new `beets/util/deprecation.py` module with standardized
deprecation helpers:
  - `deprecate_for_user()` - logs warnings visible to end users
- `deprecate_for_maintainers()` - emits `DeprecationWarning` for
developers
- `deprecate_imports()` - handles deprecated module imports with
automatic version calculation
- `_format_message()` - generates consistent deprecation messages that
auto-calculate next major version

- Migrated all deprecation handling to use the new centralized
functions:
  - Replaced inline `warnings.warn()` calls throughout codebase
- Updated `deprecate_imports()` signature to remove explicit `version`
parameter
- Converted user-facing deprecation warnings in plugins to use
logger-based `deprecate_for_user()`
2025-12-02 01:56:00 +00:00
Šarūnas Nejus
05430f312c
Move PromptChoice to beets.util module
And update imports that have been raising the deprecation warning.
2025-12-02 01:51:14 +00:00
Šarūnas Nejus
dd72704d3d
Do not force load musicbrainz, add a test to show the behaviour 2025-11-30 07:42:21 +00:00
Šarūnas Nejus
b643fc4ce5
Do not show a warning to users that have musicbrainz disabled 2025-11-30 07:42:19 +00:00
Šarūnas Nejus
3bb068a675
Warn users of deprecated musicbrainz.enabled option 2025-11-30 07:02:46 +00:00
Šarūnas Nejus
9f7cb8dbe4
Load musicbrainz implicitly and supply a deprecation warning 2025-11-30 07:02:46 +00:00
Šarūnas Nejus
5a3ecf6842
Add deprecate_for_user function 2025-11-30 07:02:46 +00:00
Šarūnas Nejus
39288637b9
Centralise warnings for maintainers into deprecate_for_maintainers 2025-11-30 07:02:46 +00:00
Šarūnas Nejus
c79cad4ed1
Move deprecate_imports to beets.util.deprecation 2025-11-30 07:02:46 +00:00
Šarūnas Nejus
95b3364361
reflink() doesn't take Path parameters (#6186)
Fix `test_successful_reflink`, by passing the right kinds of parameters.

This was failing inside the reflink package:

```
/usr/lib/python3/dist-packages/reflink/reflink.py:34: in reflink
    backend.clone(oldpath, newpath)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

oldpath = PosixPath('/tmp/tmpx3jirmhp/testfile')
newpath = PosixPath('/tmp/tmpx3jirmhp/testfile.dest')

    def clone(oldpath, newpath):
        if isinstance(oldpath, unicode):
            oldpath = oldpath.encode(sys.getfilesystemencoding())
        if isinstance(newpath, unicode):
            newpath = newpath.encode(sys.getfilesystemencoding())

>       newpath_c = ffi.new('char[]', newpath)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: expected new array length or list/tuple/str, not PosixPath
```
2025-11-30 05:42:38 +00:00
Šarūnas Nejus
26fde1ebf0
Merge branch 'master' into fix-reflink 2025-11-30 05:37:48 +00:00
henry
cb0d15ff84
Remove gmusic plugin (#6192)
Sometimes it is time to let go of old things:
This PR removes the old gmusic plugin and all related docs. 

---

The google play music service was shutdown in 2020 and already
deprecated in beets 1.6.0.
2025-11-28 12:19:10 -08:00
Sebastian Mohr
5cc7dcfce7 Sometimes it is time to let go of old things:
This removes old references and docs for the old gmusic plugin.
2025-11-27 21:58:29 +01:00
Alok Saboo
6bfe7cfbc9 refactor(smartplaylist): Improve type safety in query building 2025-11-26 13:47:18 -05:00
Alok Saboo
002a051d06 fix(smartplaylist): Resolve mypy type errors and update tests 2025-11-26 13:44:29 -05:00
Alok Saboo
b9de8f9aab Remove duplication in matches method 2025-11-26 13:39:02 -05:00
Alok Saboo
028401ac28 lint 2025-11-26 13:33:07 -05:00
Alok Saboo
1f3f3fa377 Merge remote-tracking branch 'upstream/master' into smartplaylist 2025-11-26 13:30:14 -05:00
Alok Saboo
67d6e7dd62 feat(types): Add type hints to smartplaylist.py 2025-11-26 13:27:44 -05:00
henry
b4f0dbf53b
Fix recursion in inline plugin when item_fields shadow DB fields (#6115) (#6174)
## Description

Fixes [#6115](https://github.com/beetbox/beets/issues/6115).

When an inline field definition shadows a built-in database field (e.g.,
redefining `track_no` in `item_fields`), the inline plugin evaluates the
field template by constructing a dictionary of all item values.
Previously, this triggered unbounded recursion because `_dict_for(obj)`
re-entered `__getitem__` for the same key while evaluating the computed
field.

This PR adds a per-object, per-key evaluation guard to prevent re-entry
when the same inline field is accessed during expression evaluation.
This resolves the recursion error while preserving normal computed-field
behavior.

A regression test
(`TestInlineRecursion.test_no_recursion_when_inline_shadows_fixed_field`)
verifies that `$track_no` evaluates correctly (`'01'`) when shadowed.

## To Do

- [x] ~Documentation.~
- [x] ~Changelog.~
- [x] Tests.
2025-11-25 16:25:25 -08:00