Commit graph

205 commits

Author SHA1 Message Date
Thomas Scholtes
766c8b190b Add path argument to item.write()
Symmetrical to item.read(), this allows us to update the tags of files that are
not in the library. The motivation was this issue [1].

The commit also includes a nasty hack in the plugin code that prevents breaking
other plugins.

[1]: https://github.com/geigerzaehler/beets-check/issues/1
2014-04-04 14:56:10 +02:00
Thomas Scholtes
ee2cf0df8e Plugins can't extend MediaFile anymore
Backported from #607.
See https://github.com/sampsyo/beets/pull/607#issuecomment-38387100

This will be return in #644.
2014-04-04 14:28:47 +02:00
Thomas Scholtes
eb4c323bcb Plugins can now extend MediaField 2014-04-04 00:48:29 +02:00
Thomas Scholtes
a399f294e8 Handle exceptions in item.write and use plugin abort 2014-03-22 13:25:25 +01:00
Thomas Scholtes
92061099fe Add BeforeWriteError for plugins
The idea is that plugins may want to prevent beets from writing a file (for
example if an integrity check failed).
2014-03-22 13:25:25 +01:00
Thomas Scholtes
e2718d792e Prevent plugin classes from being loaded twice 2014-03-12 14:17:16 +01:00
Thomas Scholtes
d091c7e5b4 Remove unused plugin configure method 2014-03-11 22:29:44 +01:00
Adrian Sampson
9ee4adc5e1 move remaining generic Query types to dbcore.query
NumericQuery is still broken. This, of course, is the whole reason for the
change.
2014-01-20 16:40:50 -08:00
Adrian Sampson
da794ffc44 remove vestigial plugin hooks
These have been superseded by the new function-based approach.
2013-12-25 00:37:04 -08:00
Adrian Sampson
13b1e0f115 first stab at computed fields
The idea is to have uniform access to plugin-provided (computed) fields of
items and albums. This also permits queries over these computed fields.
2013-12-24 14:52:40 -08:00
Adrian Sampson
f6faf72328 move Distance class to hooks module 2013-06-10 15:21:32 -07:00
Tai Lee
e6ac8e1646 Use a Distance object instead of floats for distance calculations.
The new Distance object knows how to perform various types of distance
calculations (expression, equality, number, priority, string).

It will keep track of each individual penalty that has been applied so
that we can utilise that information in the UI and when making decisions
about the recommendation level.

We now display the top 3 penalties (sorted by weight) on the release
list (and "..." if there are more than 3), and we display all penalties
on the album info line and track change line.

The implementation of the `max_rec` setting has been simplified by
removing duplicate validation and instead looking at the penalties that
have been applied to a distance. As a result, we can now configure a
maximum recommendation for any penalty that might be applied.

We have a few new checks when calculating album distance:

`match: preferred: countries` and `match: preferred: media` can each be
set to a list of countries and media in order of your preference. These
are empty by default. A value that matches the first item will have no
penalty, and a value that doesn't match any item will have an unweighted
penalty of 1.0.

If `match: preferred: original_year` is set to "yes", beets will apply
an unweighted penalty of 1.0 for each year of difference between the
release year and the original year.

We now configure individual weights for `mediums` (disctotal), `label`,
`catalognum`, `country` and `albumdisambig` instead of a single generic
`minor` weight. This gives more control, but more importantly separates
and names the applied penalties so that the UI can convey exactly which
fields have contributed to the overall distance penalty.

Likewise, `missing tracks` and `unmatched tracks` are penalised and
displayed in the UI separately, instead of a combined `partial` penalty.

Display non-MusicBrainz source in the disambiguation string, and
"source" in the list of penalties if a release is penalised for being
a non-MusicBrainz.
2013-06-02 18:25:10 +10:00
Adrian Sampson
a408f691b4 #291: plugin hook for track_for_id
For symmetry with album candidates, plugins can now provide item candidates by
ID.
2013-05-29 15:31:59 -07:00
Adrian Sampson
73a904f7e8 #291: simplify plugin interface for album_for_id 2013-05-29 15:02:42 -07:00
Adrian Sampson
303cd9ba00 Merge pull request #291 from jbaiter/discogs_albumid
Support for manually entered IDs in plugins
2013-05-29 14:43:59 -07:00
Johannes Baiter
adb22c3511 Return a list of candidates in hooks._album_for_id 2013-05-29 10:53:55 +02:00
Adrian Sampson
a0cb31956d distinguish Album and Item template fields
An earlier change (due to @pedros) added the ability for plugins to define
template fields that work with Albums as well as Items. This enables some
cool new use cases but required that every template field definition check the
type of its arguments. Instead, this iteration on the idea distinguishes
between fields meant for Items and those meant for Albums.

In addition to simplifying the implementation of these functions, this also
enables the creation of album fields with identical names to item fields.
(For example, a user contacted me recently about adding a $bitrate field for
albums, which would be the average bitrate of the items. They can do this now
using a plugin.)

I also changed the docs to stop using the decorator approach to registering
template fields. We're moving toward removing those.
2013-05-28 22:30:23 -07:00
Johannes Baiter
a82e3f9f52 Delegate album_for_id to plugins if no MusicBrainz match is found 2013-05-28 12:57:02 +02:00
Tai Lee
3eb6f8e5eb Add discogs plugin, which extends the autotagger to include results from the discogs database.
This is a refactor of the plugin developed by `imenem`.

- Pass `artist`, `album` and `va_likely` to `candidates()` so that
  plugins don't have to work this out from `items` all over again.
- Pass `artist` and `title` to `item_candidates()`.
- Silence spurious `urllib3` info log lines.
- Use a proper "beets" user agent with `discogs_client`.
- Remove `abstract_search` plugin. It seems unnecessary. How many
  music databases are there? How many will beets support? How much
  common code might there be between them? We can add some abstraction
  if or when more databases are supported.
- Derive more AlbumInfo and TrackInfo properties from discogs Release
  objects, especially album ID so that beets doesn't just use the first
  release and think all subsequent releases are duplicates.
- Add basic documentation, doc strings and code comments.
- Sanitise search query. Remove non-word characters and medium info that
  might filter out good search results.
- Use artist `join` strings from discogs Release object when an album
  or track has multiple artists.
- Don't rely on discogs track position, which is unreliable. But tracks
  are in order, so we can recalculate medium and medium_index as long as
  we can extract a consistent medium across tracks from the position.
- Add "various" as a known signal to indicate various artists.
- Prevent `chroma` plugin from returning a a huge track distance for any
  track that is missing an ID (e.g. all discog tracks).
- `TrackInfo.index` should be the release index (calculated by beets),
  not the medium index (derived from discogs track position).
- Add `AlbumInfo.data_source`. It's "Unknown" by default which is shown
  in red when displaying a suggested or selected match. The built in
  auto tagger sets it to "MusicBrainz" which is shown in green. Anything
  else (e.g. "Discogs") is shown in yellow.
- Remove double spaces from album titles (bad data from Discogs).
2013-05-21 21:16:52 +10:00
Adrian Sampson
40b49ac786 some low-level tweaks to extensible queries (#214) 2013-03-13 21:59:03 -07:00
Philippe Mongeau
9bae47f8ab update the docstrings and cleanup the new PluginQuery system 2013-03-13 00:39:35 -04:00
Philippe Mongeau
ca8af62e9c change queries() function to returns a dict
of {prefix: PluginQuery}

use the class __name__ as sqlite function name

make RegexpQuery use the AnyPluginQuery
2013-03-10 20:11:42 -04:00
Philippe Mongeau
f7ced33b8e add support for extending the query syntax with plugins 2013-03-10 16:43:34 -04:00
Dang Mai
ea3a7ea45d Run plugins in predictable order
In the config file, if 2 plugins listen to the same event, make sure the
one that is listed first is executed earlier.
2013-02-03 10:00:44 -05:00
Adrian Sampson
887d1c1287 fix inline and rewrite for instance fields
I'm transitioning to using exclusively instance-level fields instead of
class-level fields in plugin objects, but I neglected to bring inline and
rewrite into the future. This manifested as silent inaction on the part of
these plugins.

This change restores the old behavior (for compatibility) but also updates the
plugins to use the new behavior.
2013-02-02 08:35:54 -08:00
Adrian Sampson
58d9a775cc remove singleton enforcement from plugins
The plugin system itself now enforces single instances.
2013-01-31 12:13:19 -08:00
Adrian Sampson
7a410f636b happy new year
For future reference, this command did the trick:
ack -l 'Copyright 201' | xargs perl -pi -E 's/Copyright 201./Copyright 2013/'
2013-01-11 10:43:41 -08:00
Adrian Sampson
2f5165d4e1 avoid loading a "phantom" plugin
I'm not sure when this was introduced, but "beet version" could list a plugin
called "plugins" because the load_plugins function would pick up the
BeetsPlugin class itself. This was benign but confusing.
2012-12-20 17:08:05 -08:00
Adrian Sampson
4a5594bec6 begin adding convenient plugin defaults
We need plugins to set their config values at run time instead of module import
time. That is, defaults should be put in the __init__ method. This is easy
enough, but to make it even more convenient, I added a BeetsPlugin.config
field, which is a Confit view into a subsection of the configuration named
after the plugin.
2012-12-18 20:42:42 -08:00
Adrian Sampson
71a5a5b02f only load plugins from specified modules
Eliminate the __subclasses__ trick for finding all plugins. Now we explicitly
look in each plugin module for a plugin class. This allows us to import plugin
modules with unintentionally loading them. This lets us reuse the image
embedding machinery without copypasta.
2012-10-12 21:55:54 -07:00
Adrian Sampson
96de3ee400 add track mapping to album_distance plugin method 2012-08-03 18:12:58 -07:00
Adrian Sampson
6503e85a57 fetchart: autofetch option
This necessitated a slight refactoring in the plugin event handling mechanism.
Rather than loading all handlers up front and storing them in a module-scope
structure, we now scan for event handlers at every send(). This is probably
very slightly less efficient but allows for more flexible logic.
2012-06-24 19:01:19 -07:00
Adrian Sampson
48ffa08928 plugin import stages 2012-06-08 14:49:04 -07:00
Adrian Sampson
760fff3ace use new "except ... as ...:" syntax
This replaces the older "except ..., ...:" syntax.
2012-05-13 21:18:50 -07:00
Adrian Sampson
b68e87b92c The Great Trailing Whitespace Purge of 2012
What can I say? I used to use TextMate!
2012-05-13 20:22:17 -07:00
Adrian Sampson
08e93a5309 plugin API to extend MediaFile (#324) 2012-02-09 14:35:47 -08:00
Adrian Sampson
91901fc379 plugin-extensible path format fields (#169) 2011-12-17 21:29:15 -08:00
Adrian Sampson
f1ebc82a55 plugin hooks for template functions (#231) 2011-12-16 11:56:40 -08:00
Adrian Sampson
95f38dbe52 "info dictionaries" replaced with AlbumInfo and TrackInfo 2011-10-23 14:12:13 -07:00
Adrian Sampson
21d919fbd0 share last.fm API key among plugins 2011-09-23 12:37:56 -07:00
Adrian Sampson
f567c505d8 plugin item candidates, including lastid support for singletons 2011-04-13 21:20:21 -07:00
Adrian Sampson
1896f397a2 debug message on events 2011-04-09 13:18:44 -07:00
Adrian Sampson
565257988a docs/whitespace and change register_listener to a class method 2011-04-09 13:15:19 -07:00
Peter B
4a30ad6bbc added register_listeners method to BeetsPlugin class 2011-04-09 12:34:44 -04:00
Adrian Sampson
ed89394368 mpdupdate plugin (and config system for plugins) 2010-09-21 10:40:39 -07:00
Adrian Sampson
8c159fa2f0 remove BPD from default plugins, no more dependency on eventlet 2010-09-16 23:19:22 -07:00
Adrian Sampson
8b02dd176c lastid plugin can now generate its own candidates
That is, in addition to contributing to the distance function, the plugin can
also influence the initial search into MusicBrainz. This will allow albums to be
tagged even when they're missing metadata entirely. This change required a
significant bit of refactoring to the "mb" module -- it's much nicer now.
2010-09-16 12:27:04 -07:00
Adrian Sampson
4d978f3541 album-level distance function in lastid plugin
This involves yet another new plugin method: album_distance. This leaves as the
last major puzzle piece for lastid the ability to augment the initial search
into MB (i.e., can start a search using fingerprinted metadata).
2010-09-14 14:42:51 -07:00
Adrian Sampson
d9383aceb1 merge with events branch 2010-09-13 21:46:03 -07:00
Adrian Sampson
fba874932c beginnings of last.fm fingerprinting plugin for autotagger
This required the introduction of a track_distance method on plugins. We'll also
need to add an album_distance method as well as a mechanism for extending the
search routine (so we can search for albums in MusicBrainz even when they have
no tags). This commit also adds the '-v' flag for printing debug logs (something
we should do more of).
2010-09-13 21:14:49 -07:00
Adrian Sampson
00300cdf81 move event-handling logic into plugin system 2010-08-30 12:50:17 -07:00
Jeffrey Aylesworth
5bf2d86221 Send event after plugins have been loaded 2010-08-29 10:30:02 -04:00
Adrian Sampson
7cdcc9a277 add config option for importing additional plugins 2010-07-08 17:18:43 -07:00
Adrian Sampson
8ccc8e1ccd move bpd and dadd commands to plugins
--HG--
rename : beets/player/bpd.py => beetsplug/bpd/__init__.py
rename : beets/player/gstplayer.py => beetsplug/bpd/gstplayer.py
rename : beets/device.py => beetsplug/device.py
2010-07-08 17:09:07 -07:00
Adrian Sampson
78efe771b1 extremely simple plugin system with discovery 2010-07-08 16:35:15 -07:00