Commit graph

418 commits

Author SHA1 Message Date
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
1066c79b56 simplify path type coercion in MatchQuery (#470) 2013-12-11 16:03:29 -08:00
Johann Klähn
c539c36886 fix MatchQuery('path', ...) for unicode value 2013-12-11 12:18:13 +01:00
Adrian Sampson
2e46a6f067 opportunistic cleanup 2013-11-25 15:52:34 -08:00
Adrian Sampson
20bdffcbd6 API docs: slightly less skeletal 2013-10-09 01:09:02 -07:00
Adrian Sampson
c0c01b2680 id3v23 config option (fix #388) 2013-10-06 20:20:18 -07:00
Adrian Sampson
2e2e0b2919 get_album (and evalute_template) with non-DB items
Alternative fix for #403.
2013-10-05 11:06:08 -07:00
Adrian Sampson
dd8c667ce9 remove magic strings from Library.__init___
We now pull the table names from the models.
2013-09-17 09:13:56 -07:00
Adrian Sampson
c5032f925e move Destination method to Item class 2013-09-17 09:09:10 -07:00
Adrian Sampson
f82d466b77 eliminate lib argument to Item.evaluate_template 2013-09-17 08:44:26 -07:00
Adrian Sampson
22d5e564c6 move move method to model objects 2013-09-16 22:12:26 -07:00
Adrian Sampson
76b1ee434e move remove method to model objects
--HG--
extra : amend_source : 31d3ccbdde816b82bb5ec943ecb870e0df699dd0
2013-09-16 21:30:55 -07:00
Adrian Sampson
25a02cac92 reorganize library.py 2013-09-16 20:58:35 -07:00
Adrian Sampson
3229c59b60 python 2.6 compatibility 2013-09-16 18:35:31 -07:00
Adrian Sampson
c5de56c4fd filter wide integers (closes #348) 2013-09-16 17:25:41 -07:00
Adrian Sampson
3b4e3d47f5 consolidate excess SELECT in load() 2013-09-09 20:41:30 -07:00
Adrian Sampson
4ee4169349 simplify get_query using class attributes 2013-09-09 20:20:22 -07:00
Adrian Sampson
f70ddfbd1d deduplicate albums() and items() methods
This also drops the keyword arguments to these methods, which were vestigial.
2013-09-08 23:18:58 -07:00
Adrian Sampson
d80576fec1 get rid of dictionary comprehensions
for Python 2.6 compatibility
2013-08-29 17:07:04 -07:00
Adrian Sampson
c7fe017752 remove Library.{move,store} methods
These methods are now provided by LibModel, which makes dealing with items and
albums symmetric.
2013-08-21 15:34:45 -07:00
Adrian Sampson
15cf046285 don't reset mtime on awakening from DB 2013-08-21 11:38:48 -07:00
Adrian Sampson
9e61e49457 fix NumericQuery constructor 2013-08-21 09:42:16 -07:00
Adrian Sampson
9609e41cf8 store albums after moving art 2013-08-21 09:25:47 -07:00
Adrian Sampson
c2acab510d album.move() now also stores
This lets items see any modifications to the album (when the album's fields
are dirty). It's also symmetric with the same method on items.
2013-08-21 09:07:20 -07:00
Adrian Sampson
8bcbe1dea2 fix outdated SQL query 2013-08-20 16:22:24 -07:00
Adrian Sampson
8bdf2d0efe fix dirtying when unchanged, artpath wrapping
Also some naming mistakes.
2013-08-20 16:05:45 -07:00
Adrian Sampson
238e743b5e add load() method to LibModel 2013-08-20 15:47:28 -07:00
Adrian Sampson
4d20d3b296 album.store() now also affects tracks 2013-08-20 15:32:27 -07:00
Adrian Sampson
50f724186f revamp ResultIterator (now Results)
This new design lets us provide better common functionality. The `get()`
method is a particularly good example: we can now avoid the try/except dance
that was previously necessary to get the only result for a single-result
query. This also lets us continue using `len()` on the result of
`album.items()`, which previously returned a materialized list.
2013-08-20 14:54:24 -07:00
Adrian Sampson
276ce14dd2 flexattrs work for Albums
A second base class, LibModel, maintains a reference to the Library and should
take care of database-related tasks like load and store. This is the beginning
of the end of the terrible incongruity between Item and Album objects (only
the latter had a library reference). More refactoring to come.

One large side effect: Album objects no longer automatically store
modifications. You have to call album.store(). Several places in the code
assume otherwise; they need cleaning up.

ResultIterator is now polymorphic (it takes a type parameter, which must be a
subclass of LibModel).
2013-08-16 18:36:30 -07:00
Adrian Sampson
abfad7b2a9 kill BaseAlbum
I added this back when I thought I would implement a different subclass that
represented iPods. That means I wrote this code when I had a lime iPod mini. I
am old.
2013-08-16 17:28:21 -07:00
Adrian Sampson
38f1e6aec2 new FlexModel base class
I intend to use this for both Item and Album to avoid code duplication and
simplify code that uses both entities.
2013-08-16 17:22:17 -07:00
Adrian Sampson
206dee34f8 flexible attributes as slow queries
Queries over flexible attributes now Just Work!
2013-08-16 14:46:46 -07:00
Adrian Sampson
7d9f556cbe introducing "slow queries"
In preparation for enabling queries over flexattrs, this is a new path that
lets queries avoid generating SQLite expressions altogether. Any query that
can be completely evaluated in SQLite will be, but when it can't, we now fall
back to running the entire query in Python by selecting everything from the
database and running the `match` predicate.

To begin with, this mechanism replaces RegisteredFieldQueries, which
previously used Python callbacks for evaluation. Now they just indicate that
they're slow queries and the query system falls back automatically.

This has the great upside that it lets use implement arbitrarily complex
queries without shoehorning everything into SQLite when that (a) is way too
complicated and (b) doesn't buy us much performance anyway. The obvious
drawback is that any code dealing with queries now has to handle two cases
(slow and fast).

In the future, we could optimize this further by combing fast and slow query
styles. For example, if you want to match with a substring *and* a regular
expression, we can do a first pass in SQLite and apply the regex predicate on
the results. Avoided for now because premature optimization, etc., etc.

Next step: implement flexattr matches as slow queries.
2013-08-16 14:28:46 -07:00
Adrian Sampson
1a0d9c507d drop flexattr namespaces
Namespaces were a worthy idea, but they added a lot of complexity to both the
library code itself and every client of the flexattrs interfaces. Getting rid
of them, and having one flat namespace of both traditional fields and
flexattrs, has one huge benefit: we can "promote" flexattrs to real attributes
(and vice versa) without code changes in every client.

This frees us to have a somewhat less efficient implementation of flexattrs
because we have a smooth upgrade path for making attributes more efficient via
promotion.
2013-08-16 11:18:05 -07:00
Adrian Sampson
3b9b39e5c9 merge with master 2013-08-15 18:14:33 -07:00
Adrian Sampson
3757aec494 fix homebrew gstreamer instructions 2013-08-15 17:46:03 -07:00
Adrian Sampson
c1b66105dd fix regex (and other) queries in path field 2013-08-04 13:12:25 -07:00
Dale Sedivec
0e994c2274 Add Item instance to item_moved event
This brings this plug-in event in to line with similar events.
2013-06-26 22:10:19 -05:00
Dale Sedivec
fe886d363a Send a plug-in event when file is moved
I use this in one of my plug-ins to notice when I've moved all the audio
files in an album from one directory to another, at which point I move
any associated non-album files to the new directory and delete the old
directory.
2013-06-24 00:17:37 -05:00
Adrian Sampson
7c430a791c possibly fix error for some Mutagen exceptions 2013-06-03 10:06:54 -07:00
Adrian Sampson
5904959b8a item templates now expand all fields
A user noticed that $id wasn't being expanded. There's no good reason for
that.
2013-06-02 16:49:10 -07:00
Adrian Sampson
e75718d196 use album template fields in item templates
This lets you use, for example, the example album bitrate field in path
formats.
2013-05-29 10:10:07 -07: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
Adrian Sampson
6334f4d1a5 refinements to artpath modification patch
That's 371cc72f2d09 in hg. This makes the patch slightly more general by
reusing our type conversion infrastructure. It also uses "bytes" as a synonym
for "str" that I find a little bit clearer.
2013-05-28 21:41:03 -07:00
Lucas Duailibe
76e310d811 different paths for convert
the paths configuration for converted files can be different from the importer
closes #232
2013-05-22 11:03:00 -03:00
Adrian Sampson
bf78751090 human-readable errors in read() and write() 2013-05-21 15:58:22 -07:00
Adrian Sampson
475228a5e8 fix #281: album art filename respects replace 2013-05-19 10:34:46 -07:00
Adrian Sampson
3e740b7d24 remove timeout Library field 2013-05-19 10:19:52 -07:00
Adrian Sampson
c56ef31da0 remove art_filename Library field
This is the first of a handful of refactorings that take advantage of the new
confit system to simplify parameter passing boilerplate.
2013-05-19 10:18:41 -07:00
Adrian Sampson
71666c7ac2 fix #280: unicode error when formatting artpath
The `artpath` field for Albums is a bytestring, not a Unicode string, and this
was causing a UnicodeDecodeError in `format_for_path`.
2013-05-19 10:05:23 -07:00
Pedro Silva
106ad99556 Perform template field substitution on albums
- adds another traversal through all plugins' template_fields for each
  'evaluate_template' call.
- requires the following idiom (or equivalent):

    @Plugin.template_field(field')
    def _tmpl_field(album):
        """Return stuff.
        """
        if isinstance(album, Album):
            return stuff
2013-05-15 13:05:55 +01:00
Adrian Sampson
c1815a5d72 FIELDS lists use real types instead of SQL strings
This should enable some useful simplifications down the road.
2013-05-11 16:41:04 -07:00
Adrian Sampson
6f77169ad2 itime (#264): name change
I changed the "itime" field to "added" and the %format function to %time.
2013-05-11 13:24:23 -07:00
Adrian Sampson
4704c4a3c8 simplify album-adding by marking itime as album
Since both albums and items have an itime field, I'm putting itime into
ALBUM_KEYS_ITEM. This simplifies a lot of handling code. It also will make the
item and album itimes synchronize at some points, which is probably fine -- I
can't see a major use case for maintaining separate added dates for an album
and its tracks.
2013-05-11 13:20:04 -07:00
Adrian Sampson
8806f2d02b remove a stray constant 2013-05-11 13:11:42 -07:00
Adrian Sampson
4904106a72 config option for time format string 2013-05-11 13:10:31 -07:00
Adrian Sampson
24c90b565a move time formatting to format_for_path
This is where field value transformations belong.
2013-05-11 13:06:24 -07:00
Adrian Sampson
dd00fe0cff fix stray character and tweak whitespace 2013-05-11 12:54:53 -07:00
Lucas Duailibe
c7c2b266cd correcting identation 2013-05-11 10:58:19 -03:00
Lucas Duailibe
4d5773c195 Support for date/time fields 2013-05-11 10:53:43 -03:00
Lucas Duailibe
5c31d3ac15 Formatting the import time in the view and paths
Added the %format{} template function to output the time to any format supported by time.strftime()
2013-05-11 10:53:43 -03:00
Lucas Duailibe
0a631bcda2 Using time.time() to store the import time 2013-05-11 10:53:43 -03:00
Lucas Duailibe
d907dd6b40 Preliminary support for "date added" fields
This isn't yet finished, it needs some input on how to organize the data, and actually where to implement the use of this data, but it already works in setting the date
2013-05-11 10:53:43 -03:00
Adrian Sampson
ea0928c845 generalize YearQuery to NumericQuery 2013-05-09 15:47:25 -07:00
Adrian Sampson
0f06c79991 Merge pull request #261 from mschuerig/master
Support for year queries with ranges
2013-05-09 15:00:49 -07:00
Adrian Sampson
ba288ce604 move type conversion to commands module (#265)
This change also uses the existing str2bool utility function.
2013-05-08 22:56:27 -07:00
Lucas Duailibe
e72fcc4b68 Changing to some more meaningful names 2013-05-05 20:32:33 -03:00
Lucas Duailibe
c7f4b8a095 "Modify" for non-string values
Added the possibility to modify float, integer e bool values (using explicitly true/false)
2013-05-05 20:22:38 -03:00
Michael Schuerig
42b5060fb7 Well, really add it... 2013-04-25 00:45:56 +02:00
Michael Schuerig
fe41bba380 Add a query class for years with support for ranges. 2013-04-25 00:36:21 +02:00
Adrian Sampson
2a22e6eae8 sort Album.items() output
This closes #181 and #255, which fixed the problem in one usage (importfeeds).
2013-04-20 13:37:29 -07:00
Adrian Sampson
d41fb7f0ea merge with master
We should work off the latest changes because of the recent changes to the
Query class hierarchy.
2013-03-16 12:50:55 -07:00
Adrian Sampson
4c85dc8f72 reduce redundancy in item queries
Now the SELECT query for items only appears in Library.items(). All other
functions that retrieve items go through this method. This should make it
easier to change the way flexattrs are picked up.
2013-03-16 12:50:24 -07:00
Adrian Sampson
fe8092139b fix construction of conditional path queries
I broke this in the last flurry of refactors but, as is usually the case, I
have no idea why it ever worked before.
2013-03-14 11:05:35 -07:00
Adrian Sampson
d0e9e3db1e initial support for non-field queries
With this change, we can get slightly closer to letting plugins extend the
query syntax with queries that don't pertain to a specific field. This will
likely need some more tweaking in the future, but it should allow for
some very interesting things.
2013-03-14 10:20:31 -07:00
Adrian Sampson
79c79bfcc3 refactor query parsing
It's long overdue that the parsing of individual query components was moved
out of classes and into top-level functions, where it belongs.
2013-03-14 10:12:20 -07:00
Adrian Sampson
f474f3aed2 split FieldQuery into base and registered versions 2013-03-14 10:00:30 -07:00
Adrian Sampson
a4fb44ab1b refactor RegexpQuery to use new FieldQuery (#214) 2013-03-13 23:03:21 -07:00
Adrian Sampson
f005ec2de0 refactor: everything is like a plugin query (#214)
The initial idea for this refactor was motivated by the need to make
PluginQuery.match() have the same method signature as the match() methods on
other queries. That is, it needed to take an *item*, not the pattern and
value. (The pattern is supplied when the query is constructed.) So it made
sense to move the value-to-pattern code to a class method.

But then I realized that all the other FieldQuery subclasses needed to do
essentially the same thing. So I eliminated PluginQuery altogether and
refactored FieldQuery to subsume its functionality. I then changed all the
other FieldQuery subclasses to conform to the same pattern.

This has the side effect of allowing different kinds of queries (even
non-field queries) down the road.
2013-03-13 22:57:20 -07: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
685972bbc5 update query tests
fix escape colons in the query term
2013-03-10 20:26:45 -04:00
Philippe Mongeau
5d5b52629d fix wrong indentation Oooops! 2013-03-10 20:13:56 -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
c9c57cbb29 fix param odrder for match function of PluginQuery 2013-03-10 19:06:27 -04:00
Philippe Mongeau
7bc0b3a518 expclude prefix from query term 2013-03-10 18:51:43 -04:00
Philippe Mongeau
f7ced33b8e add support for extending the query syntax with plugins 2013-03-10 16:43:34 -04:00
Philippe Mongeau
a5f1357a94 use fuzzy threshold from config file 2013-03-09 22:14:12 -05:00
Philippe Mongeau
40dca74390 add AnyFuzzyQuery to match on any fields using fuzzy matching 2013-03-09 22:14:02 -05:00
Philippe Mongeau
da81c7e596 add internal FuzzyQuery using ~ as prefix 2013-03-09 22:13:48 -05:00
Adrian Sampson
3e05d6614c get and set flexattrs with hyphen keys
Here's another little experiment: to make flexattrs a little easier to use for
end users, you can now get and set them by using 'namespace-key' as the
argument to __getattr__ or __setattr__.

For example, try:
$ beet mod foo-bar=baz
$ beet ls -f '${foo-bar}'
baz
baz
baz
...
2013-03-09 13:16:24 -08:00
Adrian Sampson
4fe91b342b experiments with "un-registered" flexattrs 2013-03-09 12:54:55 -08:00
steini
410bdf6ddd Code for reading attributes from concatenated flex columns into dicts moved to an outside methods to make it usable for both BaseAlbum and Item objects. 2013-03-06 23:25:31 +00:00
steini
7d1f67881e ironing out some kinks 2013-03-06 18:29:22 +00:00
steini
8e342a16a1 Fixed up a couple of query classes for flex attr support. 2013-03-06 14:38:17 +00:00
steini
fbd85ef6ba Started hacking CollectionQuery to search flexible attribute fields. 2013-03-05 05:20:03 +00:00
steini
f5d658c58f An attempt at flexible attributes with plugin namespaces.
Mostly untested.
2013-03-04 05:55:43 +00:00
Adrian Sampson
54e070d06b mbsync: use SingletonQuery for item updates 2013-03-03 16:29:31 -08:00
Adrian Sampson
d71737114a format None values as the empty string
Fix due to @pscn. Includes test. Closes #108.
2013-02-28 10:00:26 -08:00