Example #1
0
def upgrade_languages(root, data):
    langs = XPath('./opf:metadata/dc:language')(root)
    if langs:
        for lang in langs:
            lang.attrib.clear()
    else:
        # EPUB spec says dc:language is required
        metadata = XPath('./opf:metadata')(root)[0]
        l = metadata.makeelement(DC('language'))
        l.text = 'und'
        metadata.append(l)
def upgrade_series(root, data):
    series, series_index = None, '1.0'
    for meta in XPath('./opf:metadata/opf:meta[@name="calibre:series"]')(root):
        remove_element(meta, data.refines)
        series = meta.get('content')
    for meta in XPath('./opf:metadata/opf:meta[@name="calibre:series_index"]')(
            root):
        remove_element(meta, data.refines)
        series_index = meta.get('content')

    if series:
        create_series(root, data.refines, series, series_index)
Example #3
0
def upgrade_cover(root, data):
    for item in XPath('./opf:metadata/opf:meta[@name="cover"]')(root):
        remove_element(item, data.refines)
        item_id = item.get('content')
        for item in XPath(
                './opf:manifest/opf:item[@id and @href and @media-type]')(
                    root):
            if item.get('id') == item_id:
                mt = (item.get('media-type') or '').lower()
                if mt and 'xml' not in mt and 'html' not in mt:
                    item.set(
                        'properties',
                        normalize_whitespace((item.get('properties') or '') +
                                             ' cover-image'))
Example #4
0
def upgrade_authors(root, data):
    for which in 'creator', 'contributor':
        for elem in XPath('./opf:metadata/dc:' + which)(root):
            role = elem.attrib.pop(OPF('role'), None)
            sort = elem.attrib.pop(OPF('file-as'), None)
            if role or sort:
                aid = ensure_id(elem)
                metadata = elem.getparent()
                if role:
                    m = metadata.makeelement(OPF('meta'),
                                             attrib={
                                                 'refines': '#' + aid,
                                                 'property': 'role',
                                                 'scheme': 'marc:relators'
                                             })
                    m.text = role
                    metadata.append(m)
                if sort:
                    m = metadata.makeelement(OPF('meta'),
                                             attrib={
                                                 'refines': '#' + aid,
                                                 'property': 'file-as'
                                             })
                    m.text = sort
                    metadata.append(m)
Example #5
0
def upgrade_rating(root, data):
    rating = None
    for meta in XPath('./opf:metadata/opf:meta[@name="calibre:rating"]')(root):
        remove_element(meta, data.refines)
        rating = meta.get('content')
    if rating is not None:
        create_rating(root, data.prefixes, rating)
Example #6
0
def upgrade_cover(root, data):
    for item in XPath('./opf:metadata/opf:meta[@name="cover"]')(root):
        # Google Play Books does not recognize covers unless the old style
        # <meta name="cover"> is present, so leave it in
        # remove_element(item, data.refines)
        item_id = item.get('content')
        for item in XPath(
                './opf:manifest/opf:item[@id and @href and @media-type]')(
                    root):
            if item.get('id') == item_id:
                mt = (item.get('media-type') or '').lower()
                if mt and 'xml' not in mt and 'html' not in mt:
                    item.set(
                        'properties',
                        normalize_whitespace((item.get('properties') or '') +
                                             ' cover-image'))
Example #7
0
def upgrade_date(root, data):
    found = False
    for date in XPath('./opf:metadata/dc:date')(root):
        val = date.text
        if val:
            found = True
            continue
        if not val or found:  # only one dc:date allowed
            remove_element(date, data.refines)
Example #8
0
def upgrade_title(root, data):
    first_title = None
    for title in XPath('./opf:metadata/dc:title')(root):
        if not title.text or not title.text.strip():
            remove_element(title, data.refines)
            continue
        if first_title is None:
            first_title = title

    title_sort = None
    for m in XPath('./opf:metadata/opf:meta[@name="calibre:title_sort"]')(root):
        ans = m.get('content')
        if ans:
            title_sort = ans
        remove_element(m, data.refines)

    if first_title is not None:
        ts = [refdef('file-as', title_sort)] if title_sort else ()
        set_refines(first_title, data.refines, refdef('title-type', 'main'), *ts)
Example #9
0
def upgrade_timestamp(root, data):
    for meta in XPath('./opf:metadata/opf:meta[@name="calibre:timestamp"]')(root):
        m = meta.getparent()
        remove_element(meta, data.refines)
        val = meta.get('content')
        if val:
            try:
                val = parse_date(val, is_w3cdtf=True)
            except Exception:
                pass
            else:
                create_timestamp(root, data.prefixes, m, val)
Example #10
0
def upgrade_identifiers(root, data):
    for ident in XPath('./opf:metadata/dc:identifier')(root):
        val = (ident.text or '').strip()
        lval = val.lower()
        scheme = ident.attrib.pop(OPF('scheme'), None)
        if lval.startswith('urn:'):
            prefix, rest = val[4:].partition(':')[::2]
            if prefix and rest:
                scheme, val = prefix, rest
        if scheme and val:
            ident.text = '{}:{}'.format(scheme, val)
        for attr in tuple(ident.attrib):
            if attr != 'id':
                del ident.attrib[attr]
Example #11
0
def upgrade_languages(root, data):
    langs = XPath('./opf:metadata/dc:language')(root)
    if langs:
        for lang in langs:
            lang.attrib.clear()
    else:
        # EPUB spec says dc:language is required
        metadata = XPath('./opf:metadata')(root)[0]
        l = metadata.makeelement(DC('language'))
        l.text = 'und'
        metadata.append(l)
Example #12
0
def upgrade_meta(root, data):
    for meta in XPath('./opf:metadata/opf:meta[@name]')(root):
        name, content = meta.get('name'), meta.get('content') or ''
        if name.startswith('rendition:'):
            name = name.partition(':')[-1]
        prop = None
        if name in ('orientation', 'layout', 'spread'):
            prop = 'rendition:' + name
        elif name == 'fixed-layout':
            prop = 'rendition:layout'
            content = {'true': 'pre-paginated'}.get(content.lower(), 'reflowable')
        elif name == 'orientation-lock':
            prop = 'rendition:orientation'
            content = {'portrait': 'portrait', 'landscape': 'landscape'}.get(content.lower(), 'auto')
        if prop:
            del meta.attrib['name']
            del meta.attrib['content']
            meta.set('property', prop)
            meta.text = content
    def test_identifiers(self):  # {{{
        def idt(val, scheme=None, iid=''):
            return '<dc:identifier id="{id}" {scheme}>{val}</dc:identifier>'.format(scheme=('opf:scheme="%s"'%scheme if scheme else ''), val=val, id=iid)

        def ri(root):
            return dict(read_identifiers(root, read_prefixes(root), default_refines))

        for m, result in (
                (idt('abc', 'ISBN'), {}),
                (idt('isbn:9780230739581'), {'isbn':['9780230739581']}),
                (idt('urn:isbn:9780230739581'), {'isbn':['9780230739581']}),
                (idt('9780230739581', 'ISBN'), {'isbn':['9780230739581']}),
                (idt('isbn:9780230739581', 'ISBN'), {'isbn':['9780230739581']}),
                (idt('key:val'), {'key':['val']}),
                (idt('url:http://x'), {'url':['http://x']}),
                (idt('a:1')+idt('a:2'), {'a':['1', '2']}),
        ):
            self.ae(result, ri(self.get_opf(m)))
        root = self.get_opf(metadata=idt('a:1')+idt('a:2')+idt('calibre:x')+idt('uuid:y'))
        mi = read_metadata(root)
        self.ae(mi.application_id, 'x')
        set_application_id(root, {}, default_refines, 'y')
        mi = read_metadata(root)
        self.ae(mi.application_id, 'y')

        root = self.get_opf(metadata=idt('i:1', iid='uid') + idt('r:1') + idt('o:1'))
        set_identifiers(root, read_prefixes(root), default_refines, {'i':'2', 'o':'2'})
        self.ae({'i':['2', '1'], 'r':['1'], 'o':['2']}, ri(root))
        self.ae(1, len(XPath('//dc:identifier[@id="uid"]')(root)))
        root = self.get_opf(metadata=idt('i:1', iid='uid') + idt('r:1') + idt('o:1'))
        set_identifiers(root, read_prefixes(root), default_refines, {'i':'2', 'o':'2'}, force_identifiers=True)
        self.ae({'i':['2', '1'], 'o':['2']}, ri(root))
        root = self.get_opf(metadata=idt('i:1', iid='uid') + idt('r:1') + idt('o:1'))
        set_application_id(root, {}, default_refines, 'y')
        mi = read_metadata(root)
        self.ae(mi.application_id, 'y')
Example #14
0
def remove_invalid_attrs_in_dc_metadata(root, data):
    for tag in XPath('//*[namespace-uri() = "{}"]'.format(DC('')[1:-1]))(root):
        for k in tuple(tag.attrib):
            if k != 'id':
                del tag.attrib[k]