mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use attribute objects for Pythonic access to all allowed (and only allowed) OPF 2.0 metadata attributes.
This commit is contained in:
parent
daabc8bd5b
commit
047814a7a5
@ -471,7 +471,7 @@ class MobiWriter(object):
|
|||||||
if term == 'identifier':
|
if term == 'identifier':
|
||||||
if data.lower().startswith('urn:isbn:'):
|
if data.lower().startswith('urn:isbn:'):
|
||||||
data = data[9:]
|
data = data[9:]
|
||||||
elif item.get('scheme', '').lower() == 'isbn':
|
elif item.scheme.lower() == 'isbn':
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
@ -220,12 +220,37 @@ class Metadata(object):
|
|||||||
CALIBRE_TERMS = set(['series', 'series_index', 'rating'])
|
CALIBRE_TERMS = set(['series', 'series_index', 'rating'])
|
||||||
OPF_ATTRS = {'role': OPF('role'), 'file-as': OPF('file-as'),
|
OPF_ATTRS = {'role': OPF('role'), 'file-as': OPF('file-as'),
|
||||||
'scheme': OPF('scheme'), 'event': OPF('event'),
|
'scheme': OPF('scheme'), 'event': OPF('event'),
|
||||||
'type': XSI('type'), 'id': 'id'}
|
'type': XSI('type'), 'lang': XML('lang'), 'id': 'id'}
|
||||||
OPF1_NSMAP = {'dc': DC11_NS, 'oebpackage': OPF1_NS}
|
OPF1_NSMAP = {'dc': DC11_NS, 'oebpackage': OPF1_NS}
|
||||||
OPF2_NSMAP = {'opf': OPF2_NS, 'dc': DC11_NS, 'dcterms': DCTERMS_NS,
|
OPF2_NSMAP = {'opf': OPF2_NS, 'dc': DC11_NS, 'dcterms': DCTERMS_NS,
|
||||||
'xsi': XSI_NS, 'calibre': CALIBRE_NS}
|
'xsi': XSI_NS, 'calibre': CALIBRE_NS}
|
||||||
|
|
||||||
class Item(object):
|
class Item(object):
|
||||||
|
class Attribute(object):
|
||||||
|
def __init__(self, attr, allowed=None):
|
||||||
|
if not callable(attr):
|
||||||
|
attr_, attr = attr, lambda term: attr_
|
||||||
|
self.attr = attr
|
||||||
|
self.allowed = allowed
|
||||||
|
|
||||||
|
def term_attr(self, obj):
|
||||||
|
term = obj.term
|
||||||
|
if namespace(term) != DC11_NS:
|
||||||
|
term = OPF('meta')
|
||||||
|
allowed = self.allowed
|
||||||
|
if allowed is not None and term not in allowed:
|
||||||
|
raise AttributeError(
|
||||||
|
'attribute %r not valid for metadata term %r' \
|
||||||
|
% (self.attr(term), barename(obj.term)))
|
||||||
|
return self.attr(term)
|
||||||
|
|
||||||
|
def __get__(self, obj, cls):
|
||||||
|
if obj is None: return None
|
||||||
|
return obj.attrib.get(self.term_attr(obj), '')
|
||||||
|
|
||||||
|
def __set__(self, obj, value):
|
||||||
|
obj.attrib[self.term_attr(obj)] = value
|
||||||
|
|
||||||
def __init__(self, term, value, attrib={}, nsmap={}, **kwargs):
|
def __init__(self, term, value, attrib={}, nsmap={}, **kwargs):
|
||||||
self.attrib = attrib = dict(attrib)
|
self.attrib = attrib = dict(attrib)
|
||||||
self.nsmap = nsmap = dict(nsmap)
|
self.nsmap = nsmap = dict(nsmap)
|
||||||
@ -246,26 +271,27 @@ class Metadata(object):
|
|||||||
if isprefixname(value):
|
if isprefixname(value):
|
||||||
attrib[attr] = qname(value, nsmap)
|
attrib[attr] = qname(value, nsmap)
|
||||||
nsattr = Metadata.OPF_ATTRS.get(attr, attr)
|
nsattr = Metadata.OPF_ATTRS.get(attr, attr)
|
||||||
|
if nsattr == OPF('scheme') and namespace(term) != DC11_NS:
|
||||||
|
# The opf:meta element takes @scheme, not @opf:scheme
|
||||||
|
nsattr = 'scheme'
|
||||||
if attr != nsattr:
|
if attr != nsattr:
|
||||||
attrib[nsattr] = attrib.pop(attr)
|
attrib[nsattr] = attrib.pop(attr)
|
||||||
self.__setattr__ = self._setattr
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def scheme(term):
|
||||||
attr = name.replace('_', '-')
|
if term == OPF('meta'):
|
||||||
if attr in Metadata.OPF_ATTRS:
|
return 'scheme'
|
||||||
attr = Metadata.OPF_ATTRS[attr]
|
return OPF('scheme')
|
||||||
return self.attrib.get(attr, None)
|
scheme = Attribute(scheme, [DC('identifier'), OPF('meta')])
|
||||||
raise AttributeError(
|
file_as = Attribute(OPF('file-as'), [DC('creator'), DC('contributor')])
|
||||||
'%r object has no attribute %r' \
|
role = Attribute(OPF('role'), [DC('creator'), DC('contributor')])
|
||||||
% (self.__class__.__name__, name))
|
event = Attribute(OPF('event'), [DC('date')])
|
||||||
|
id = Attribute('id')
|
||||||
def _setattr(self, name, value):
|
type = Attribute(XSI('type'), [DC('date'), DC('format'), DC('type')])
|
||||||
attr = name.replace('_', '-')
|
lang = Attribute(XML('lang'), [DC('contributor'), DC('coverage'),
|
||||||
if attr in Metadata.OPF_ATTRS:
|
DC('creator'), DC('publisher'),
|
||||||
attr = Metadata.OPF_ATTRS[attr]
|
DC('relation'), DC('rights'),
|
||||||
self.attrib[attr] = value
|
DC('source'), DC('subject'),
|
||||||
return
|
OPF('meta')])
|
||||||
super(Item, self).__setattr__(self, name, value)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return self.attrib[key]
|
return self.attrib[key]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user