mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement setting of dc:creator
This commit is contained in:
parent
999575bec0
commit
0ae246c0c1
@ -10,7 +10,7 @@ import re
|
|||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from calibre.ebooks.metadata import check_isbn, authors_to_string
|
from calibre.ebooks.metadata import check_isbn, authors_to_string, string_to_authors
|
||||||
from calibre.ebooks.metadata.book.base import Metadata
|
from calibre.ebooks.metadata.book.base import Metadata
|
||||||
from calibre.ebooks.metadata.utils import parse_opf, pretty_print_opf, ensure_unique, normalize_languages
|
from calibre.ebooks.metadata.utils import parse_opf, pretty_print_opf, ensure_unique, normalize_languages
|
||||||
from calibre.ebooks.oeb.base import OPF2_NSMAP, OPF, DC
|
from calibre.ebooks.oeb.base import OPF2_NSMAP, OPF, DC
|
||||||
@ -93,7 +93,15 @@ def properties_for_id_with_scheme(item_id, prefixes, refines):
|
|||||||
ans[key] = (scheme_ns, scheme, val)
|
ans[key] = (scheme_ns, scheme, val)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def ensure_id(root, elem):
|
def getroot(elem):
|
||||||
|
while True:
|
||||||
|
q = elem.getparent()
|
||||||
|
if q is None:
|
||||||
|
return elem
|
||||||
|
elem = q
|
||||||
|
|
||||||
|
def ensure_id(elem):
|
||||||
|
root = getroot(elem)
|
||||||
eid = elem.get('id')
|
eid = elem.get('id')
|
||||||
if not eid:
|
if not eid:
|
||||||
eid = ensure_unique('id', frozenset(XPath('//*/@id')(root)))
|
eid = ensure_unique('id', frozenset(XPath('//*/@id')(root)))
|
||||||
@ -124,6 +132,15 @@ def read_prefixes(root):
|
|||||||
|
|
||||||
def expand_prefix(raw, prefixes):
|
def expand_prefix(raw, prefixes):
|
||||||
return regex(r'(\S+)\s*:\s*(\S+)').sub(lambda m:(prefixes.get(m.group(1), m.group(1)) + ':' + m.group(2)), raw)
|
return regex(r'(\S+)\s*:\s*(\S+)').sub(lambda m:(prefixes.get(m.group(1), m.group(1)) + ':' + m.group(2)), raw)
|
||||||
|
|
||||||
|
def ensure_prefix(root, prefixes, prefix, value):
|
||||||
|
prefixes[prefix] = value
|
||||||
|
prefixes = {k:v for k, v in prefixes.iteritems() if reserved_prefixes.get(k) != v}
|
||||||
|
if prefixes:
|
||||||
|
root.set('prefix', ' '.join('%s: %s' % (k, v) for k, v in prefixes.iteritems()))
|
||||||
|
else:
|
||||||
|
root.attrib.pop('prefix', None)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Refines {{{
|
# Refines {{{
|
||||||
@ -139,7 +156,7 @@ def refdef(prop, val, scheme=None):
|
|||||||
return (prop, val, scheme)
|
return (prop, val, scheme)
|
||||||
|
|
||||||
def set_refines(elem, existing_refines, *new_refines):
|
def set_refines(elem, existing_refines, *new_refines):
|
||||||
eid = ensure_id(elem.getroottree().getroot(), elem)
|
eid = ensure_id(elem)
|
||||||
remove_refines(elem, existing_refines)
|
remove_refines(elem, existing_refines)
|
||||||
for ref in reversed(new_refines):
|
for ref in reversed(new_refines):
|
||||||
prop, val, scheme = ref
|
prop, val, scheme = ref
|
||||||
@ -362,6 +379,28 @@ def read_authors(root, prefixes, refines):
|
|||||||
|
|
||||||
return uniq(roled_authors or unroled_authors)
|
return uniq(roled_authors or unroled_authors)
|
||||||
|
|
||||||
|
def set_authors(root, prefixes, refines, authors):
|
||||||
|
ensure_prefix(root, prefixes, 'marc', reserved_prefixes['marc'])
|
||||||
|
for item in XPath('./opf:metadata/dc:creator')(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() != 'aut') or (opf_role and opf_role.lower() != 'aut'):
|
||||||
|
continue
|
||||||
|
remove_element(item, refines)
|
||||||
|
metadata = XPath('./opf:metadata')(root)[0]
|
||||||
|
for author in authors:
|
||||||
|
a = metadata.makeelement(DC('creator'))
|
||||||
|
aid = ensure_id(a)
|
||||||
|
a.text = author.name
|
||||||
|
metadata.append(a)
|
||||||
|
m = metadata.makeelement(OPF('meta'), attrib={'refines':'#'+aid, 'property':'role', 'scheme':'marc:relators'})
|
||||||
|
m.text = 'aut'
|
||||||
|
metadata.append(m)
|
||||||
|
if author.sort:
|
||||||
|
m = metadata.makeelement(OPF('meta'), attrib={'refines':'#'+aid, 'property':'file-as'})
|
||||||
|
m.text = author.sort
|
||||||
|
metadata.append(m)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
def read_metadata(root):
|
def read_metadata(root):
|
||||||
@ -394,6 +433,11 @@ def apply_metadata(root, mi, cover_prefix='', cover_data=None, apply_null=False,
|
|||||||
set_identifiers(root, prefixes, refines, mi.identifiers, force_identifiers=force_identifiers)
|
set_identifiers(root, prefixes, refines, mi.identifiers, force_identifiers=force_identifiers)
|
||||||
set_title(root, prefixes, refines, mi.title, mi.title_sort)
|
set_title(root, prefixes, refines, mi.title, mi.title_sort)
|
||||||
set_languages(root, prefixes, refines, mi.languages)
|
set_languages(root, prefixes, refines, mi.languages)
|
||||||
|
aus = string_to_authors(mi.author_sort or '')
|
||||||
|
authors = []
|
||||||
|
for i, aut in enumerate(mi.authors):
|
||||||
|
authors.append(Author(aut, aus[i] if i < len(aus) else None))
|
||||||
|
set_authors(root, prefixes, refines, authors)
|
||||||
|
|
||||||
pretty_print_opf(root)
|
pretty_print_opf(root)
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ from calibre.ebooks.metadata.opf3 import (
|
|||||||
parse_prefixes, reserved_prefixes, expand_prefix, read_identifiers,
|
parse_prefixes, reserved_prefixes, expand_prefix, read_identifiers,
|
||||||
read_metadata, set_identifiers, XPath, set_application_id, read_title,
|
read_metadata, set_identifiers, XPath, set_application_id, read_title,
|
||||||
read_refines, set_title, read_title_sort, read_languages, set_languages,
|
read_refines, set_title, read_title_sort, read_languages, set_languages,
|
||||||
read_authors, Author
|
read_authors, Author, set_authors
|
||||||
)
|
)
|
||||||
|
|
||||||
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
|
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
|
||||||
@ -107,8 +107,8 @@ class TestOPF3(unittest.TestCase):
|
|||||||
def test_authors(self): # {{{
|
def test_authors(self): # {{{
|
||||||
def rl(root):
|
def rl(root):
|
||||||
return read_authors(root, reserved_prefixes, read_refines(root))
|
return read_authors(root, reserved_prefixes, read_refines(root))
|
||||||
def st(root, languages):
|
def st(root, authors):
|
||||||
set_languages(root, reserved_prefixes, read_refines(root), languages)
|
set_authors(root, reserved_prefixes, read_refines(root), authors)
|
||||||
return rl(root)
|
return rl(root)
|
||||||
root = self.get_opf('''<dc:creator>a b</dc:creator>''')
|
root = self.get_opf('''<dc:creator>a b</dc:creator>''')
|
||||||
self.ae([Author('a b', None)], rl(root))
|
self.ae([Author('a b', None)], rl(root))
|
||||||
@ -121,6 +121,9 @@ class TestOPF3(unittest.TestCase):
|
|||||||
root = self.get_opf('''<dc:creator opf:file-as="b, a">a b</dc:creator><dc:creator id="1">c d</dc:creator>
|
root = self.get_opf('''<dc:creator opf:file-as="b, a">a b</dc:creator><dc:creator id="1">c d</dc:creator>
|
||||||
<meta refines="#1" property="file-as">d, c</meta>''')
|
<meta refines="#1" property="file-as">d, c</meta>''')
|
||||||
self.ae([Author('a b', 'b, a'), Author('c d', 'd, c')], rl(root))
|
self.ae([Author('a b', 'b, a'), Author('c d', 'd, c')], rl(root))
|
||||||
|
authors = [Author('x y', 'y, x'), Author('u i', None)]
|
||||||
|
self.ae(authors, st(root, authors))
|
||||||
|
self.assertIsNone(root.get('prefix'))
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Run tests {{{
|
# Run tests {{{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user