Implement book_producer

This commit is contained in:
Kovid Goyal 2016-06-21 11:12:36 +05:30
parent 5e53d334e6
commit 00e255b91a
2 changed files with 55 additions and 1 deletions

View File

@ -401,6 +401,40 @@ def set_authors(root, prefixes, refines, authors):
m = metadata.makeelement(OPF('meta'), attrib={'refines':'#'+aid, 'property':'file-as'})
m.text = author.sort
metadata.append(m)
def read_book_producers(root, prefixes, refines):
ans = []
for item in XPath('./opf:metadata/dc:contributor')(root):
val = (item.text or '').strip()
if val:
props = properties_for_id_with_scheme(item.get('id'), prefixes, refines)
role = props.get('role')
opf_role = item.get(OPF('role'))
if role:
scheme_ns, scheme, role = role
if role.lower() == 'bkp' and (scheme_ns is None or (scheme_ns, scheme) == (reserved_prefixes['marc'], 'relators')):
ans.append(normalize_whitespace(val))
elif opf_role and opf_role.lower() == 'bkp':
ans.append(normalize_whitespace(val))
return ans
def set_book_producers(root, prefixes, refines, producers):
for item in XPath('./opf:metadata/dc:contributor')(root):
props = properties_for_id_with_scheme(item.get('id'), prefixes, refines)
role = props.get('role')
opf_role = item.get(OPF('role'))
if (role and role.lower() != 'bkp') or (opf_role and opf_role.lower() != 'bkp'):
continue
remove_element(item, refines)
metadata = XPath('./opf:metadata')(root)[0]
for bkp in producers:
a = metadata.makeelement(DC('contributor'))
aid = ensure_id(a)
a.text = bkp
metadata.append(a)
m = metadata.makeelement(OPF('meta'), attrib={'refines':'#'+aid, 'property':'role', 'scheme':'marc:relators'})
m.text = 'bkp'
metadata.append(m)
# }}}
def read_metadata(root):
@ -422,6 +456,9 @@ def read_metadata(root):
auts.append(a.name), aus.append(a.sort)
ans.authors = auts or ans.authors
ans.author_sort = authors_to_string(aus) or ans.author_sort
bkp = read_book_producers(root, prefixes, refines)
if bkp:
ans.book_producer = bkp[0]
return ans
def get_metadata(stream):

View File

@ -13,7 +13,8 @@ from calibre.ebooks.metadata.opf3 import (
parse_prefixes, reserved_prefixes, expand_prefix, read_identifiers,
read_metadata, set_identifiers, XPath, set_application_id, read_title,
read_refines, set_title, read_title_sort, read_languages, set_languages,
read_authors, Author, set_authors, ensure_prefix, read_prefixes
read_authors, Author, set_authors, ensure_prefix, read_prefixes,
read_book_producers, set_book_producers
)
TEMPLATE = '''<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="uid"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">{metadata}</metadata></package>''' # noqa
@ -130,6 +131,22 @@ class TestOPF3(unittest.TestCase):
self.assertIsNone(root.get('prefix'))
# }}}
def test_book_producer(self): # {{{
def rl(root):
return read_book_producers(root, reserved_prefixes, read_refines(root))
def st(root, producers):
set_book_producers(root, reserved_prefixes, read_refines(root), producers)
return rl(root)
for scheme in ('scheme="marc:relators"', ''):
root = self.get_opf('''<dc:contributor>a b</dc:contributor><dc:contributor id="1">c d</dc:contributor>'''
'''<meta refines="#1" property="role" %s>bkp</meta>''' % scheme)
self.ae(['c d'], rl(root))
root = self.get_opf('''<dc:contributor>a b</dc:contributor><dc:contributor opf:role="bkp">c d</dc:contributor>''')
self.ae(['c d'], rl(root))
self.ae('12'.split(), st(root, '12'.split()))
# }}}
# Run tests {{{
class TestRunner(unittest.main):