From 4958ce83c3b81e2c5fc8b104c0cec437415ea4e5 Mon Sep 17 00:00:00 2001 From: Pierre Rust Date: Wed, 11 Jun 2014 22:54:39 +0200 Subject: [PATCH] Add defaut sort on artist_sort field. For items and albums, defaulting on artist field if artist field is empty. --- beets/dbcore/query.py | 30 ++++++++++++++++++++++++++++++ beets/library.py | 19 ++++++++++++------- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index 21ba3b572..97b8833bb 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -628,6 +628,36 @@ 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. + """ + def __init__(self, model_cls, is_ascending=True): + self.model_cls = model_cls + self.is_ascending = is_ascending + + def select_clause(self): + return "" + + def union_clause(self): + return "" + + def order_clause(self): + order = "ASC" if self.is_ascending else "DESC" + if 'albumartist_sort' in self.model_cls._fields: + exp1 = 'albumartist_sort' + exp2 = 'albumartist' + elif 'artist_sort' in self.model_cls_fields: + exp1 = 'artist_sort' + exp2 = 'artist' + else: + return "" + + order_str = ('(CASE {0} WHEN NULL THEN {1} ' + 'WHEN "" THEN {1} ' + 'ELSE {0} END) {2} ').format(exp1, exp2, order) + return order_str + def build_sql(model_cls, query, sort_order): """ Generate a sql statement (and the values that must be injected into it) diff --git a/beets/library.py b/beets/library.py index 61ddfab96..3965b6fb9 100644 --- a/beets/library.py +++ b/beets/library.py @@ -29,6 +29,7 @@ from beets.util import bytestring_path, syspath, normpath, samefile from beets.util.functemplate import Template from beets import dbcore from beets.dbcore import types +from beets.dbcore.query import SmartArtistSort import beets @@ -1013,11 +1014,11 @@ class Library(dbcore.Database): # Querying. def _fetch(self, model_cls, query, sort_order=None): - """Parse a query and fetch. If a sort_order is explicitly given, - any sort order specification present in the query string is ignored. + """Parse a query and fetch. If a order specification is present in the + query string the sort_order argument is ignored. """ (query, sort) = get_query(query, model_cls) - sort = sort if sort_order is None else sort_order + sort = sort_order if sort is None else sort return super(Library, self)._fetch( model_cls, query, sort @@ -1025,16 +1026,20 @@ 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 sort_order is explicitly given, - any sort order specification present in the query string is ignored. + 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(Album) return self._fetch(Album, query, sort_order) def items(self, query=None, sort_order=None): """Get a sorted list of :class:`Item` objects matching the given - given sort order. If a sort_order is explicitly given, - any sort order specification present in the query string is ignored. + 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.