diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py
index ff48a14138..5714fa5f08 100644
--- a/src/calibre/ebooks/metadata/opf3.py
+++ b/src/calibre/ebooks/metadata/opf3.py
@@ -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):
diff --git a/src/calibre/ebooks/metadata/opf3_test.py b/src/calibre/ebooks/metadata/opf3_test.py
index 771174cd94..d0cadc74c7 100644
--- a/src/calibre/ebooks/metadata/opf3_test.py
+++ b/src/calibre/ebooks/metadata/opf3_test.py
@@ -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 = '''{metadata}''' # 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('''a bc d'''
+ '''bkp''' % scheme)
+ self.ae(['c d'], rl(root))
+ root = self.get_opf('''a bc d''')
+ self.ae(['c d'], rl(root))
+ self.ae('12'.split(), st(root, '12'.split()))
+ # }}}
+
+
# Run tests {{{
class TestRunner(unittest.main):