diff --git a/beets/config_default.yaml b/beets/config_default.yaml index a0726bb3f..b64600c04 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -55,8 +55,8 @@ list_format_item: $artist - $album - $title list_format_album: $albumartist - $album time_format: '%Y-%m-%d %H:%M:%S' -sort_album: smartartist+ album+ -sort_item: smartartist+ album+ disc+ track+ +sort_album: albumartist+ album+ +sort_item: artist+ album+ disc+ track+ paths: default: $albumartist/$album%aunique{}/$track $title diff --git a/beets/library.py b/beets/library.py index ae9000cff..d2d58205a 100644 --- a/beets/library.py +++ b/beets/library.py @@ -149,13 +149,13 @@ class SmartArtistSort(dbcore.query.Sort): """Sort by artist (either album artist or track artist), prioritizing the sort field over the raw field. """ - def __init__(self, model_cls, is_ascending=True): - self.model_cls = model_cls - self.is_ascending = is_ascending + def __init__(self, model_cls, ascending=True): + self.album = model_cls is Album + self.ascending = ascending def order_clause(self): - order = "ASC" if self.is_ascending else "DESC" - if 'albumartist' in self.model_cls._fields: + order = "ASC" if self.ascending else "DESC" + if self.album: field = 'albumartist' else: field = 'artist' @@ -164,11 +164,11 @@ class SmartArtistSort(dbcore.query.Sort): 'ELSE {0}_sort END) {1}').format(field, order) def sort(self, objs): - if 'albumartist' in self.model_cls._fields: + if self.album: key = lambda a: a.albumartist_sort or a.albumartist else: key = lambda i: i.artist_sort or i.artist - return sorted(objs, key=key) + return sorted(objs, key=key, reverse=not self.ascending) # Special path format key. @@ -374,7 +374,7 @@ class Item(LibModel): _formatter = FormattedItemMapping - _sorts = {'smartartist': SmartArtistSort} + _sorts = {'artist': SmartArtistSort} @classmethod def _getters(cls): @@ -739,7 +739,10 @@ class Album(LibModel): _search_fields = ('album', 'albumartist', 'genre') - _sorts = {'smartartist': SmartArtistSort} + _sorts = { + 'albumartist': SmartArtistSort, + 'artist': SmartArtistSort, + } item_keys = [ 'added', diff --git a/docs/reference/config.rst b/docs/reference/config.rst index 0d3d4b644..75592e499 100644 --- a/docs/reference/config.rst +++ b/docs/reference/config.rst @@ -193,18 +193,16 @@ option overrides this setting. sort_item ~~~~~~~~~ -Sort order to use when listing *individual items* with the :ref:`list-cmd` -command and other commands that need to print out items. Defaults to -``smartartist+``. Any command-line sort order overrides this setting. +Default sort order to use when fetching items from the database. Defaults to +``artist+ album+ disc+ track+``. Explicit sort orders override this default. .. _sort_album: sort_album ~~~~~~~~~~ -Sort order to use when listing *albums* with the :ref:`list-cmd` -command. Defaults to ``smartartist+``. Any command-line sort order overrides -this setting. +Default sort order to use when fetching items from the database. Defaults to +``albumartist+ album+``. Explicit sort orders override this default. .. _original_date: diff --git a/docs/reference/query.rst b/docs/reference/query.rst index b85a03962..7dc79461a 100644 --- a/docs/reference/query.rst +++ b/docs/reference/query.rst @@ -190,25 +190,23 @@ ones you've already added to your beets library. Sort Order ---------- -You can also specify the order used when outputting the results. Of course, this -is only useful when displaying the result, for example with the ``list`` -command, and is useless when the query is used as a filter for an command. Use -the name of the `field` you want to sort on, followed by a ``+`` or ``-`` sign -if you want ascending or descending sort. For example this command:: +Queries can specify a sort order. Use the name of the `field` you want to sort +on, followed by a ``+`` or ``-`` sign to indicate ascending or descending +sort. For example, this command:: $ beet list -a year+ -will list all albums in chronological order. - -There is a special ``smartartist`` sort that uses sort-specific field ( -``artist_sort`` for items and ``albumartist_sort`` for albums) but falls back to -standard artist fields if these are empty. When no sort order is specified, -``smartartist+`` is used (but this is configurable). - -You can also specify several sort orders, which will be used in the same order at -which they appear in your query:: +will list all albums in chronological order. You can also specify several sort +orders, which will be used in the same order as they appear in your query:: $ beet list -a genre+ year+ This command will sort all albums by genre and, in each genre, in chronological order. + +The ``artist`` and ``albumartist`` keys are special: they attempt to use their +corresponding ``artist_sort`` and ``albumartist_sort`` fields for sorting +transparently (but fall back to the ordinary fields when those are empty). + +You can set the default sorting behavior with the :ref:`sort_item` and +:ref:`sort_album` configuration options. diff --git a/test/test_sort.py b/test/test_sort.py index 2ea2d0d5a..be5706bca 100644 --- a/test/test_sort.py +++ b/test/test_sort.py @@ -62,6 +62,7 @@ class DummyDataTestCase(_common.TestCase): items[0].flex1 = "flex1-0" items[0].flex2 = "flex2-A" items[0].album_id = albums[0].id + items[0].artist_sort = None items[1].title = 'baz qux' items[1].artist = 'two' items[1].album = 'baz' @@ -70,6 +71,7 @@ class DummyDataTestCase(_common.TestCase): items[1].flex1 = "flex1-1" items[1].flex2 = "flex2-A" items[1].album_id = albums[0].id + items[1].artist_sort = None items[2].title = 'beets 4 eva' items[2].artist = 'three' items[2].album = 'foo' @@ -78,6 +80,7 @@ class DummyDataTestCase(_common.TestCase): items[2].flex1 = "flex1-2" items[2].flex2 = "flex1-B" items[2].album_id = albums[1].id + items[2].artist_sort = None items[3].title = 'beets 4 eva' items[3].artist = 'three' items[3].album = 'foo2' @@ -86,6 +89,7 @@ class DummyDataTestCase(_common.TestCase): items[3].flex1 = "flex1-2" items[3].flex2 = "flex1-C" items[3].album_id = albums[2].id + items[3].artist_sort = None for item in items: self.lib.add(item)