From 0ada2ad42bf3f05fd780d989ed640bc76163e99f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 9 Mar 2020 09:36:48 +0530 Subject: [PATCH] DB: Ensure that set_metadata() sets author_sort to a correct value if the Metadata object has authors but no author_sort. Fixes #1116 (Generate an author_sort in fetch-ebook-metadata output) --- src/calibre/db/cache.py | 12 ++++++++++-- src/calibre/db/tests/writing.py | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 11e02d083b..f2b01b68b5 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -26,7 +26,7 @@ from calibre.db.tables import VirtualTable from calibre.db.write import get_series_values, uniq from calibre.db.lazy import FormatMetadata, FormatsList, ProxyMetadata from calibre.ebooks import check_ebook_format -from calibre.ebooks.metadata import string_to_authors, author_to_author_sort +from calibre.ebooks.metadata import string_to_authors, author_to_author_sort, authors_to_sort_string from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.opf2 import metadata_to_opf from calibre.ptempfile import (base_dir, PersistentTemporaryFile, @@ -1297,6 +1297,7 @@ class Cache(object): if set_title and mi.title: path_changed = True set_field('title', mi.title) + authors_changed = False if set_authors: path_changed = True if not mi.authors: @@ -1305,6 +1306,7 @@ class Cache(object): for a in mi.authors: authors += string_to_authors(a) set_field('authors', authors) + authors_changed = True if path_changed: self._update_path({book_id}) @@ -1339,7 +1341,13 @@ class Cache(object): if val is not None: protected_set_field(field, val) - for field in ('author_sort', 'publisher', 'series', 'tags', 'comments', + val = mi.get('author_sort', None) + if authors_changed and (not val or mi.is_null('author_sort')): + val = authors_to_sort_string(mi.authors) + if authors_changed or (force_changes and val is not None) or not mi.is_null('author_sort'): + protected_set_field('author_sort', val) + + for field in ('publisher', 'series', 'tags', 'comments', 'languages', 'pubdate'): val = mi.get(field, None) if (force_changes and val is not None) or not mi.is_null(field): diff --git a/src/calibre/db/tests/writing.py b/src/calibre/db/tests/writing.py index 74c43aee4c..8d858c12d9 100644 --- a/src/calibre/db/tests/writing.py +++ b/src/calibre/db/tests/writing.py @@ -11,6 +11,7 @@ from functools import partial from io import BytesIO from calibre.ebooks.metadata import author_to_author_sort, title_sort +from calibre.ebooks.metadata.book.base import Metadata from calibre.utils.date import UNDEFINED_DATE from calibre.db.tests.base import BaseTest, IMG from polyglot.builtins import iteritems, itervalues, unicode_type @@ -436,6 +437,12 @@ class WritingTest(BaseTest): cache.set_metadata(3, mi) self.assertEqual(set(otags), set(cache.field_for('tags', 3)), 'case changes should not be allowed in set_metadata') + # test that setting authors without author sort results in an + # auto-generated authors sort + mi = Metadata('empty', ['a1', 'a2']) + cache.set_metadata(1, mi) + self.assertEqual('a1 & a2', cache.field_for('author_sort', 1)) + # }}} def test_conversion_options(self): # {{{