diff --git a/beets/config_default.yaml b/beets/config_default.yaml index d35368ea5..e43345933 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -54,6 +54,9 @@ list_format_item: $artist - $album - $title list_format_album: $albumartist - $album time_format: '%Y-%m-%d %H:%M:%S' +sort_album: smartartist+ +sort_item: smartartist+ + paths: default: $albumartist/$album%aunique{}/$track $title singleton: Non-Album/$artist/$title diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index 97b8833bb..9952fcf4b 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -628,6 +628,7 @@ class FixedFieldSort(Sort): order = "ASC" if self.is_ascending else "DESC" return "{0} {1}".format(self.field, order) + class SmartArtistSort(Sort): """ Sort Album or Item on artist sort fields, defaulting back on artist field if the sort specific field is empty. @@ -659,6 +660,9 @@ class SmartArtistSort(Sort): return order_str +special_sorts = {'smartartist': SmartArtistSort} + + def build_sql(model_cls, query, sort_order): """ Generate a sql statement (and the values that must be injected into it) from a query, sort and a model class. diff --git a/beets/dbcore/queryparse.py b/beets/dbcore/queryparse.py index 05ee28add..1a94c1831 100644 --- a/beets/dbcore/queryparse.py +++ b/beets/dbcore/queryparse.py @@ -134,6 +134,8 @@ def construct_sort_part(model_cls, part): elif field in model_cls._getters(): # Computed field, all following fields must use the slow path. pass + elif field in query.special_sorts: + sort = query.special_sorts[field](model_cls, is_ascending) else: # Neither fixed nor computed : must be a flex attr. sort = query.FlexFieldSort(model_cls, field, is_ascending) diff --git a/beets/library.py b/beets/library.py index 3965b6fb9..16aeed772 100644 --- a/beets/library.py +++ b/beets/library.py @@ -1027,10 +1027,8 @@ class Library(dbcore.Database): def albums(self, query=None, sort_order=None): """Get a sorted list of :class:`Album` objects matching the given sort order. If a order specification is present in the query - string the sort_order argument is ignored. + string the sort_order argument is ignored. """ - if sort_order is None: - sort_order = SmartArtistSort(Album) return self._fetch(Album, query, sort_order) def items(self, query=None, sort_order=None): @@ -1038,8 +1036,6 @@ class Library(dbcore.Database): given sort order. If a order specification is present in the query string the sort_order argument is ignored. """ - if sort_order is None: - sort_order = SmartArtistSort(Item) return self._fetch(Item, query, sort_order) # Convenience accessors. diff --git a/beets/ui/commands.py b/beets/ui/commands.py index c32c1f313..dbd6806f4 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -38,6 +38,7 @@ from beets.util.functemplate import Template from beets import library from beets import config from beets.util.confit import _package_path +from beets.dbcore import sort_from_strings VARIOUS_ARTISTS = u'Various Artists' @@ -898,11 +899,16 @@ def list_items(lib, query, album, fmt): albums instead of single items. """ tmpl = Template(ui._pick_format(album, fmt)) + if album: - for album in lib.albums(query): + sort_order = sort_from_strings(library.Album, + [str(config['sort_album'])]) + for album in lib.albums(query, sort_order): ui.print_obj(album, lib, tmpl) else: - for item in lib.items(query): + sort_order = sort_from_strings(library.Item, + [str(config['sort_item'])]) + for item in lib.items(query, sort_order): ui.print_obj(item, lib, tmpl)