Some of these tests load plugins using beets' normal plugin loader, but
didn't call unload_plugins to tidy up afterwards. This led to any future
plugin loads being ignored until the next unload_plugins call.
This commit changes the config tests so that we always call load_plugins
on setup (to store the default beets state) and unload_plugins on
teardown (to restore the previously stored state).
This changes greatly improves the speed of `beet export` and `beet info`
when the `--include-keys` option is used. It also removes the globbing
feature of `--include-keys` that was added in #1295. (See #3762 for
discussion).
Listing all fields for an item requires querying the database to find
any flex attributes. This is slow when done for every item being
exported. We already have a way for the user to specify a fixed set
of keys, but we previously queried everything and filtered it afterwards.
The new approach is more efficient.
Code that iterates through all fields now have to handle invalid field
names. The export and info plugins output invalid fields as None.
Timings before:
> /usr/bin/time beet export -i title,path,artist -l Bob Dylan
13.26user 20.22system 0:34.01elapsed 98%CPU (0avgtext+0avgdata 52544maxresident)k
> /usr/bin/time beet export -l Bob Dylan
12.93user 20.15system 0:33.58elapsed 98%CPU (0avgtext+0avgdata 53632maxresident)k
Timings after:
> /usr/bin/time beet export -l Bob Dylan
13.33user 20.17system 0:34.02elapsed 98%CPU (0avgtext+0avgdata 53500maxresident)k
> /usr/bin/time beet export -i title,path,artist -l Bob Dylan
0.49user 0.07system 0:00.56elapsed 98%CPU (0avgtext+0avgdata 50496maxresident)k
Notice the dramatic speedup in the last example!
Squashed from the PR, relevant commit messages follow below:
Added file size option to artresizer
- In line with comments on PR, adjusted the ArtResizer API to add
functionality to "resize to X bytes" through `max_filesize` arg
- Adjustment to changelog.rst to include max_filesize change to ArtResizer
and addition of new plugin.
Added explicit tests for PIL & Imagemagick Methods
- Checks new resizing functions do reduce the filesize of images
Expose max_filesize logic to fetchart plugin
- Add syspath escaping for OS cross compatibility
- Return smaller PIL image even if max filesize not reached.
- Test resize logic against known smaller filesize (//2)
- Pass integer (not float) quality argument to PIL
- Remove Pillow from dependencies
- Implement "max_filesize" fetchart option, including
logic to resize and rescale if maxwidth is also set.
Added tests & documentation for fetchart additions.
Tests now check that a target filesize is reached with a
higher initial quality (a difficult check to pass).
With a starting quality of 95% PIL takes 4 iterations to succeed
in lowering the example cover image to 90% its original size.
To cover all bases, the PIL loop has been changed to 5 iterations
in the worst case, and the documentation altered to reflect the
50% loss in quality this implies. This seems reasonable as users
concerned about performance would most likely be persuaded to
install ImageMagick, or remove the maximum filesize constraint.
The previous 30% figure was arbitrary.
Also simplified the setup of the `readonly` value in the tests which
fixes a test ordering issue found using --random-order.
Signed-off-by: Graham R. Cobb <g+beets@cobb.uk.net>
Track item paths and album artpaths should be removed from results unless
INCLUDE_PATHS is set. This works for items but for albums the artpath is always
removed.
This patch makes the artpath removal conditional on INCLUDE_PATHS not being set
and includes a regression test. Note: the default value for INCLUDE_PATHS is
False so no changes will be seen by users unless they already have
INCLUDE_PATHS set.
Signed-off-by: Graham R. Cobb <g+beets@cobb.uk.net>
Added a test (test_get_stats) for the /stats web API.
This involved adding another item so that we can check both items and albums
are being counted correctly, which required a few small changes to some item
tests.
Signed-off-by: Graham R. Cobb <g+beets@cobb.uk.net>
Documentation says that ?expand does not need a value (i.e. ?expand=1 is wrong),
so the test is changed to reflect that syntax.
Signed-off-by: Graham R. Cobb <g+beets@cobb.uk.net>
Added test_get_album_details to test fetching /album/2?expand=1.
Also changed second album name to make tests more robust.
Signed-off-by: Graham R. Cobb <g+beets@cobb.uk.net>
self.lib.add ignores the "id" field from the entry being added and overwrites
it with the next free number. So remove the misleading id fields.
Add a test to confirm that the album query response contains the expected
album id number.
Signed-off-by: Graham R. Cobb <g+beets@cobb.uk.net>
References in the documentation to this plugin were removed in
beetbox/beets#3127 (beetbox/beets#3130) but no actual code
changes were made.
This PR removes support for this dependency entirely.
This adds support for the JSON Lines format as documented at
https://jsonlines.org/.
In this mode the data is output incrementally, whereas the other
modes load every item into memory and don't produce output until
the end.
* fetchart: Improve Cover Art Archive source.
Instead of blindly selecting the first image, we now treat all "front"
images as candidates.
This is useful where some digital releases have both an animated cover
and a still image and the animated image is the first image returned
from the API.
The previous test worked (on my machine, and on Github CI and AppVeyor),
but it is not obvious whether the order is really guaranteed (given that
the full beets database stack and sqlite are involved). Thus, to prevent
this from exploding at some point, only verify the number of deletions
for now.
MPD keeps the current track in the queue when stopping, so it's not
really like a skip, and I use it so that I can stop the music, and later
start at the beginning of a track.
I do this by keeping track of the current song id, and then comparing
them when we receive a stop signal.
* If import move is true, files will be deleted after converting.
Fixes#2947
* Removed trailing whitespace to comply with W293, fixing build
* Add period to the end of the comment
Co-Authored-By: Adrian Sampson <adrian@radbox.org>
* Added changelog entry for this fix.
* Added delete_originals option to remove source files after transcode
* Added unit test, removed redundant syspath call
Co-authored-by: Logan Arens <logan-arens@users.noreply.github.com>
Co-authored-by: Logan Arens <heresmygithub@protonmail.com>
Co-authored-by: Adrian Sampson <adrian@radbox.org>
Co-authored-by: Logan Arens <logan.arens@protonmail.com>
* clean-up code & add tests for genius lyrics backend
* add genius fetch tests
* organize imports: standard lib -> pip -> local
* check in sample genius lyrics page
* fix mock import
* force utf-8 encoding for opened files
* use io.open to force utf-8 encoding w/ python2.7
- renamed test test_format_fixed_field to test_format_fixed_field_string
- test_format_fixed_field_string not tests `field_two` with string values
- added new test_format_fixed_field_integer to test field `field_one` as INTEGER
- added new test_format_fixed_field_integer_normalized to test rounding float values
* safer version comparison
* regex bytes directly
* handle b'\x08 ...' case
* test_replaygain.py: injected command output should match the type of the actual output
* Fix unspecified `gain_adjustment` when method defined in config
* Fix difference between dB and LUFS values in case of mismatched `target_level`/`method`:
```
db_to_lufs( target_level <dB> ) - lufs_to_dB( -23 <LUFS> )
```
* Ignore single assertion in case of bs1770gain
(cherry picked from commit 2395bf224032c44f1ea5d28e0c63af96a92b96df)
Assert that the replaygain plugin does not write REPLAYGAIN_* tags but R128_*
tags, when instructed to do so.
This test is skipped for the `command` backend as it does not support OPUS.
Add replaygain backend using ffmpeg's ebur128 filter.
The album gain is calculated as the mean of all BS.1770 gating block powers.
Besides differences in gating block offset, this should be equivalent to a
BS.1770 analysis of a proper concatenation of all tracks.
Just calculating the mean of all track gains (as implemented by the bs1770gain
backend) yields incorrect results as that would:
- completely ignore track lengths
- just using length in seconds won't work either (e.g. BS.1770 ignores
passages below a threshold)
- take the mean of track loudness, not power
When using the ffmpeg replaygain backend to create R128_*_GAIN tags, the
targetlevel will be set to -23 LUFS. GitHub PullRequest #3065 will make this
configurable.
It will also skip peak calculation, as there is no R128_*_PEAK tag.
It is checked if the libavfilter library supports replaygain calculation. Before
version 6.67.100 that did require the `--enable-libebur128` compile-time-option,
after that the ebur128 library is included in libavfilter itself. Thus we
require either a recent enough libavfilter version or the `--enable-libebur128`
option.
When setting up bpd tests, two servers are startet: first a control server, then
bpd. Both send their assigned ports down a queue. The recipient only needs bpd's
port and thus skips the first queue entry.
Use a `multiprocessing.Queue` instead of a `multiprocessing.Value` to avoid the
manual polling/timeout handling.
TODO: Strangely Listener seems to be constructed twice. Only the second one is
used. Fix that and then remove the code working around it.
The bpd test bind a socket in order to test the protocol implementation. When
running concurrently this often resulted in an attempt to bind an already
occupied port.
By using the port number `0` we instead let the OS choose a free port. We then
have to extract it from the socket (which is handled by `bluelet`) via
`mock.patch`ing.
Return a namedtuple CommandOutput(stdout, stderr) instead of just stdout from
util.command_ouput, allowing separate access to stdout and stderr.
This change is required by the ffmpeg replaygain backend (GitHub
PullRequest #3056) as ffmpeg's ebur128 filter outputs only to stderr.
*All* URLs were checked manually, but only once per domain!
I mostly concerned myself with URLs in documentation rather than source
code because the latter may or may not have impactful changes, while the
former should be straight forward.
Changes in addition to simply adding an s:
- changed pip and pypi references as their location has changed
- MPoD (iOS app) url redirects to Regelian, so I replaced those
- updated homebrew references
Notable observations:
- beets.io does have HTTPS set up properly (via gh-pages)
- beatport.py uses the old HTTP url for beatport
- as does lyrics.py for lyrics.wikia.com
- https://tomahawk-player.org/ expired long ago, but the http page
redirects to https regardless
- none of the sourceforge subdomains have https (in 2019!)
Prevents reloading a model from the database when it hasn't changed.
Now we're back to almost the same speed as before the addition of album
field fallbacks.
The real MPD ignores `noidle` when the client is not idle. It doesn't
even send a successful response, just ignores the command. Although
I don't understand why a client would fail to keep track of its own
state, it seems that this is necessary to get ncmpcpp working.
The playlistid command is supposed to list the whole playlist if no
argument is provided, but we were accidentally trying to look up an
impossible negative id in that case causing an error to always be
returned.
When using pytest's test collector, any class with a name starting with
Test is collected. If it notices that the class has an `__init__` member
then it skips it with a warning since it's probably a false positive.
This isn't a big deal, but we can avoid warnings like this:
test/test_ui_importer.py:33
beets/test/test_ui_importer.py:33: PytestCollectionWarning: cannot collect test class 'TestTerminalImportSession' because it has a __init__ constructor
class TestTerminalImportSession(TerminalImportSession):
simply by renaming TestX to XFixture.
By comparing `sys.path` as setup by nose vs. testall.py it seems that we
weren't adding the top-level beets directory to the path. The script was
also previously changing the working directory before running the tests.
This is a hacky but effective way to work around a problem when running
the tests in parallel where two different test executions want to use
the same port.