From 521320657d2b03bdd5da034ae37cd0ea599ceea8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 25 Aug 2013 10:36:47 +0530 Subject: [PATCH] Sorting for composite cols marked as dates --- src/calibre/db/fields.py | 19 +++++++++++++++++-- src/calibre/db/tests/reading.py | 7 +++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/calibre/db/fields.py b/src/calibre/db/fields.py index 1d4215434e..d176f10c07 100644 --- a/src/calibre/db/fields.py +++ b/src/calibre/db/fields.py @@ -18,7 +18,7 @@ from calibre.db.write import Writer from calibre.ebooks.metadata import title_sort, author_to_author_sort from calibre.utils.config_base import tweaks from calibre.utils.icu import sort_key -from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort +from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort, parse_date from calibre.utils.localization import calibre_langcode_to_name class Field(object): @@ -191,7 +191,15 @@ class CompositeField(OneToOneField): self.splitter = None composite_sort = m.get('display', {}).get('composite_sort', None) if composite_sort == 'number': + self._default_sort_key = 0 self._sort_key = self.number_sort_key + elif composite_sort == 'date': + self._default_sort_key = UNDEFINED_DATE + self._filter_date = lambda x: x + if tweaks['sort_dates_using_visible_fields']: + fmt = m.get('display', {}).get('date_format', None) + self._filter_date = partial(clean_date_for_sort, fmt=fmt) + self._sort_key = self.date_sort_key else: self._sort_key = sort_key @@ -202,10 +210,17 @@ class CompositeField(OneToOneField): p = 1 << (10 * self.SIZE_SUFFIX_MAP.get(val[-2:-1], 0)) val = val[:(-2 if p > 1 else -1)].strip() val = atof(val) * p - except (TypeError, AttributeError, ValueError): + except (TypeError, AttributeError, ValueError, KeyError): val = 0.0 return val + def date_sort_key(self, val): + try: + val = self._filter_date(parse_date(val)) + except (TypeError, ValueError, AttributeError, KeyError): + val = UNDEFINED_DATE + return val + def render_composite(self, book_id, mi): with self._lock: ans = self._render_cache.get(book_id, None) diff --git a/src/calibre/db/tests/reading.py b/src/calibre/db/tests/reading.py index daf7bddc6a..f0477872d7 100644 --- a/src/calibre/db/tests/reading.py +++ b/src/calibre/db/tests/reading.py @@ -556,11 +556,14 @@ class ReadingTest(BaseTest): # }}} def test_composites(self): # {{{ + from calibre.utils.date import parse_only_date as p cache = self.init_cache() cache.create_custom_column('mult', 'CC1', 'composite', True, display={'composite_template': 'b,a,c'}) cache.create_custom_column('single', 'CC2', 'composite', False, display={'composite_template': 'b,a,c'}) cache.create_custom_column('number', 'CC3', 'composite', False, display={'composite_template': '{#float}', 'composite_sort':'number'}) cache.create_custom_column('size', 'CC4', 'composite', False, display={'composite_template': '{#float:human_readable()}', 'composite_sort':'number'}) + cache.create_custom_column('ccdate', 'CC5', 'composite', False, + display={'composite_template': '{pubdate:format_date(d-M-yy)}', 'composite_sort':'date'}) cache = self.init_cache() # Test searching @@ -574,5 +577,9 @@ class ReadingTest(BaseTest): self.assertEqual([3, 1, 2], cache.multisort([('#number', True)])) cache.set_field('#float', {1:3, 2:2*1024, 3:1*1024*1024}) self.assertEqual([1, 2, 3], cache.multisort([('#size', True)])) + + # Test date sorting + cache.set_field('pubdate', {1:p('2001-2-6'), 2:p('2001-10-6'), 3:p('2001-6-6')}) + self.assertEqual([1, 3, 2], cache.multisort([('#ccdate', True)])) # }}}