Skip to content

Commit

Permalink
EPUB 3 metadata: If a book defines no authors but does define editors…
Browse files Browse the repository at this point in the history
…, use the editors as authors. Also support the display-seq refinement to sort authors. See #1950579 (Private bug)
  • Loading branch information
kovidgoyal committed Nov 12, 2021
1 parent b3c2cf0 commit eea263f
Showing 1 changed file with 20 additions and 5 deletions.
25 changes: 20 additions & 5 deletions src/calibre/ebooks/metadata/opf3.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import json
import re
from collections import defaultdict, namedtuple
from contextlib import suppress
from operator import attrgetter
from functools import wraps
from polyglot.builtins import iteritems

from lxml import etree

from calibre import prints
Expand All @@ -29,6 +29,7 @@
)
from calibre.utils.iso8601 import parse_iso8601
from calibre.utils.localization import canonicalize_lang
from polyglot.builtins import iteritems

# Utils {{{
_xpath_cache = {}
Expand Down Expand Up @@ -424,7 +425,7 @@ def set_languages(root, prefixes, refines, languages):
# Creator/Contributor {{{


Author = namedtuple('Author', 'name sort')
Author = namedtuple('Author', 'name sort seq')


def is_relators_role(props, q):
Expand All @@ -438,6 +439,7 @@ def is_relators_role(props, q):

def read_authors(root, prefixes, refines):
roled_authors, unroled_authors = [], []
editors_map = {}

def author(item, props, val):
aus = None
Expand All @@ -446,7 +448,11 @@ def author(item, props, val):
aus = file_as[0][-1]
else:
aus = item.get(OPF('file-as')) or None
return Author(normalize_whitespace(val), normalize_whitespace(aus))
seq = 0
ds = props.get('display-seq')
with suppress(Exception):
seq = int(ds[0][-1])
return Author(normalize_whitespace(val), normalize_whitespace(aus), seq)

for item in XPath('./opf:metadata/dc:creator')(root):
val = (item.text or '').strip()
Expand All @@ -457,13 +463,22 @@ def author(item, props, val):
if role:
if is_relators_role(props, 'aut'):
roled_authors.append(author(item, props, val))
if is_relators_role(props, 'edt'):
# See https://bugs.launchpad.net/calibre/+bug/1950579
a = author(item, props, val)
editors_map[a.name] = a
elif opf_role:
if opf_role.lower() == 'aut':
roled_authors.append(author(item, props, val))
else:
unroled_authors.append(author(item, props, val))

return uniq(roled_authors or unroled_authors)
if roled_authors or unroled_authors:
ans = uniq(roled_authors or unroled_authors)
else:
ans = uniq(editors_map.values())
ans.sort(key=attrgetter('seq'))
return ans


def set_authors(root, prefixes, refines, authors):
Expand Down

0 comments on commit eea263f

Please sign in to comment.