Beispiel #1
0
def create_book(mi, path, fmt='epub', opf_name='metadata.opf', html_name='start.xhtml', toc_name='toc.ncx'):
    ''' Create an empty book in the specified format at the specified location. '''
    path = os.path.abspath(path)
    lang = 'und'
    opf = metadata_to_opf(mi, as_string=False)
    for l in opf.xpath('//*[local-name()="language"]'):
        if l.text:
            lang = l.text
            break
    lang = lang_as_iso639_1(lang) or lang

    opfns = OPF_NAMESPACES['opf']
    m = opf.makeelement('{%s}manifest' % opfns)
    opf.insert(1, m)
    i = m.makeelement('{%s}item' % opfns, href=html_name, id='start')
    i.set('media-type', guess_type('a.xhtml'))
    m.append(i)
    i = m.makeelement('{%s}item' % opfns, href=toc_name, id='ncx')
    i.set('media-type', guess_type(toc_name))
    m.append(i)
    s = opf.makeelement('{%s}spine' % opfns, toc="ncx")
    opf.insert(2, s)
    i = s.makeelement('{%s}itemref' % opfns, idref='start')
    s.append(i)
    CONTAINER = '''\
<?xml version="1.0"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
   <rootfiles>
      <rootfile full-path="{0}" media-type="application/oebps-package+xml"/>
   </rootfiles>
</container>
    '''.format(prepare_string_for_xml(opf_name, True)).encode('utf-8')
    HTML = P('templates/new_book.html', data=True).decode('utf-8').replace(
        '_LANGUAGE_', prepare_string_for_xml(lang, True)
    ).replace(
        '_TITLE_', prepare_string_for_xml(mi.title)
    ).replace(
        '_AUTHORS_', prepare_string_for_xml(authors_to_string(mi.authors))
    ).encode('utf-8')
    h = parse(HTML)
    pretty_html_tree(None, h)
    HTML = serialize(h, 'text/html')
    ncx = etree.tostring(create_toc(mi, opf, html_name, lang), encoding='utf-8', xml_declaration=True, pretty_print=True)
    pretty_xml_tree(opf)
    opf = etree.tostring(opf, encoding='utf-8', xml_declaration=True, pretty_print=True)
    if fmt == 'azw3':
        with TemporaryDirectory('create-azw3') as tdir, CurrentDir(tdir):
            for name, data in ((opf_name, opf), (html_name, HTML), (toc_name, ncx)):
                with open(name, 'wb') as f:
                    f.write(data)
            c = Container(os.path.dirname(os.path.abspath(opf_name)), opf_name, DevNull())
            opf_to_azw3(opf_name, path, c)
    else:
        with ZipFile(path, 'w', compression=ZIP_STORED) as zf:
            zf.writestr('mimetype', b'application/epub+zip', compression=ZIP_STORED)
            zf.writestr('META-INF/', b'', 0755)
            zf.writestr('META-INF/container.xml', CONTAINER)
            zf.writestr(opf_name, opf)
            zf.writestr(html_name, HTML)
            zf.writestr(toc_name, ncx)
Beispiel #2
0
def get_preprocess_html(path_to_ebook, output=None):
    from calibre.ebooks.conversion.plumber import set_regex_wizard_callback, Plumber
    from calibre.utils.logging import DevNull
    from calibre.ptempfile import TemporaryDirectory
    raw = {}
    set_regex_wizard_callback(raw.__setitem__)
    with TemporaryDirectory('_regex_wiz') as tdir:
        pl = Plumber(path_to_ebook,
                     os.path.join(tdir, 'a.epub'),
                     DevNull(),
                     for_regex_wizard=True)
        pl.run()
        items = [raw[item.href] for item in pl.oeb.spine if item.href in raw]

    with (sys.stdout if output is None else open(output, 'wb')) as out:
        for html in items:
            out.write(html.encode('utf-8'))
            out.write(b'\n\n' + b'-' * 80 + b'\n\n')
Beispiel #3
0
def create_book(mi,
                path,
                fmt='epub',
                opf_name='metadata.opf',
                html_name='start.xhtml',
                toc_name='toc.ncx'):
    ''' Create an empty book in the specified format at the specified location. '''
    if fmt not in valid_empty_formats:
        raise ValueError('Cannot create empty book in the %s format' % fmt)
    if fmt == 'txt':
        with open(path, 'wb') as f:
            if not mi.is_null('title'):
                f.write(as_bytes(mi.title))
        return
    if fmt == 'docx':
        from calibre.ebooks.conversion.plumber import Plumber
        from calibre.ebooks.docx.writer.container import DOCX
        from calibre.utils.logging import default_log
        p = Plumber('a.docx', 'b.docx', default_log)
        p.setup_options()
        # Use the word default of one inch page margins
        for x in 'left right top bottom'.split():
            setattr(p.opts, 'margin_' + x, 72)
        DOCX(p.opts, default_log).write(path, mi, create_empty_document=True)
        return
    path = os.path.abspath(path)
    lang = 'und'
    opf = metadata_to_opf(mi, as_string=False)
    for l in opf.xpath('//*[local-name()="language"]'):
        if l.text:
            lang = l.text
            break
    lang = lang_as_iso639_1(lang) or lang

    opfns = OPF_NAMESPACES['opf']
    m = opf.makeelement('{%s}manifest' % opfns)
    opf.insert(1, m)
    i = m.makeelement('{%s}item' % opfns, href=html_name, id='start')
    i.set('media-type', guess_type('a.xhtml'))
    m.append(i)
    i = m.makeelement('{%s}item' % opfns, href=toc_name, id='ncx')
    i.set('media-type', guess_type(toc_name))
    m.append(i)
    s = opf.makeelement('{%s}spine' % opfns, toc="ncx")
    opf.insert(2, s)
    i = s.makeelement('{%s}itemref' % opfns, idref='start')
    s.append(i)
    CONTAINER = '''\
<?xml version="1.0"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
   <rootfiles>
      <rootfile full-path="{0}" media-type="application/oebps-package+xml"/>
   </rootfiles>
</container>
    '''.format(prepare_string_for_xml(opf_name, True)).encode('utf-8')
    HTML = P('templates/new_book.html', data=True).decode('utf-8').replace(
        '_LANGUAGE_', prepare_string_for_xml(lang, True)).replace(
            '_TITLE_', prepare_string_for_xml(mi.title)).replace(
                '_AUTHORS_',
                prepare_string_for_xml(authors_to_string(
                    mi.authors))).encode('utf-8')
    h = parse(HTML)
    pretty_html_tree(None, h)
    HTML = serialize(h, 'text/html')
    ncx = etree.tostring(create_toc(mi, opf, html_name, lang),
                         encoding='utf-8',
                         xml_declaration=True,
                         pretty_print=True)
    pretty_xml_tree(opf)
    opf = etree.tostring(opf,
                         encoding='utf-8',
                         xml_declaration=True,
                         pretty_print=True)
    if fmt == 'azw3':
        with TemporaryDirectory('create-azw3') as tdir, CurrentDir(tdir):
            for name, data in ((opf_name, opf), (html_name, HTML), (toc_name,
                                                                    ncx)):
                with open(name, 'wb') as f:
                    f.write(data)
            c = Container(os.path.dirname(os.path.abspath(opf_name)), opf_name,
                          DevNull())
            opf_to_azw3(opf_name, path, c)
    else:
        with ZipFile(path, 'w', compression=ZIP_STORED) as zf:
            zf.writestr('mimetype',
                        b'application/epub+zip',
                        compression=ZIP_STORED)
            zf.writestr('META-INF/', b'', 0o755)
            zf.writestr('META-INF/container.xml', CONTAINER)
            zf.writestr(opf_name, opf)
            zf.writestr(html_name, HTML)
            zf.writestr(toc_name, ncx)
Beispiel #4
0
    def do_ebook_convert(self, f):
        from calibre.ebooks.conversion.plumber import supported_input_formats
        from calibre.web.feeds.recipes.collection import get_builtin_recipe_titles
        from calibre.customize.ui import available_output_formats
        from calibre.ebooks.conversion.cli import create_option_parser, group_titles
        from calibre.utils.logging import DevNull
        input_fmts = set(supported_input_formats())
        output_fmts = set(available_output_formats())
        iexts = {x.upper() for x in input_fmts}.union(input_fmts)
        oexts = {x.upper() for x in output_fmts}.union(output_fmts)
        w = polyglot_write(f)
        # Arg 1
        w('\n_ebc_input_args() {')
        w('\n  local extras; extras=(')
        w('\n    {-h,--help}":Show Help"')
        w('\n    "--version:Show program version"')
        w('\n    "--list-recipes:List builtin recipe names"')
        for recipe in sorted(set(get_builtin_recipe_titles())):
            recipe = recipe.replace(':', '\\:').replace('"', '\\"')
            w(u'\n    "%s.recipe"' % (recipe))
        w('\n  ); _describe -t recipes "ebook-convert builtin recipes" extras')
        w('\n  _files -g "%s"' % ' '.join(('*.%s' % x for x in iexts)))
        w('\n}\n')

        # Arg 2
        w('\n_ebc_output_args() {')
        w('\n  local extras; extras=(')
        for x in output_fmts:
            w('\n    ".{0}:Convert to a .{0} file with the same name as the input file"'
              .format(x))
        w('\n  ); _describe -t output "ebook-convert output" extras')
        w('\n  _files -g "%s"' % ' '.join(('*.%s' % x for x in oexts)))
        w('\n  _path_files -/')
        w('\n}\n')

        log = DevNull()

        def get_parser(input_fmt='epub', output_fmt=None):
            of = ('dummy2.' + output_fmt) if output_fmt else 'dummy'
            return create_option_parser(
                ('ec', 'dummy1.' + input_fmt, of, '-h'), log)[0]

        # Common options
        input_group, output_group = group_titles()
        p = get_parser()
        opts = p.option_list
        for group in p.option_groups:
            if group.title not in {input_group, output_group}:
                opts += group.option_list
        opts.append(p.get_option('--pretty-print'))
        opts.append(p.get_option('--input-encoding'))
        opts = '\\\n  '.join(
            tuple(self.get_options(opts, file_map={'--search-replace': ()})))
        w('\n_ebc_common_opts() {')
        w('\n  _arguments -s \\\n  ' + opts)
        w('\n}\n')

        # Input/Output format options
        for fmts, group_title, func in (
            (input_fmts, input_group, '_ebc_input_opts_%s'),
            (output_fmts, output_group, '_ebc_output_opts_%s'),
        ):
            for fmt in fmts:
                is_input = group_title == input_group
                if is_input and fmt in {'rar', 'zip', 'oebzip'}:
                    continue
                p = (get_parser(input_fmt=fmt) if is_input else get_parser(
                    output_fmt=fmt))
                opts = None
                for group in p.option_groups:
                    if group.title == group_title:
                        opts = [
                            o for o in group.option_list
                            if '--pretty-print' not in o._long_opts
                            and '--input-encoding' not in o._long_opts
                        ]
                if not opts:
                    continue
                opts = '\\\n  '.join(tuple(sorted(self.get_options(opts))))
                w('\n%s() {' % (func % fmt))
                w('\n  _arguments -s \\\n  ' + opts)
                w('\n}\n')

        w('\n_ebook_convert() {')
        w('\n  local iarg oarg context state_descr state line\n  typeset -A opt_args\n  local ret=1'
          )
        w("\n  _arguments '1: :_ebc_input_args' '*::ebook-convert output:->args' && ret=0"
          )
        w("\n  case $state in \n  (args)")
        w('\n    iarg=${line[1]##*.}; ')
        w("\n    _arguments '1: :_ebc_output_args' '*::ebook-convert options:->args' && ret=0"
          )
        w("\n     case $state in \n    (args)")

        w('\n      oarg=${line[1]##*.}')
        w('\n      iarg="_ebc_input_opts_${(L)iarg}"; oarg="_ebc_output_opts_${(L)oarg}"'
          )
        w('\n      _call_function - $iarg; _call_function - $oarg; _ebc_common_opts; ret=0'
          )
        w('\n    ;;\n    esac')

        w("\n  ;;\n  esac\n  return ret")
        w('\n}\n')
Beispiel #5
0
        raw = lopen(src, 'rb').read().decode('utf-8')
        try:
            with lopen(x, 'wb') as f:
                f.write(raw.encode('utf-8'))
            build_book(x,
                       ans,
                       args=[
                           '--level1-toc=//h:h2', '--language=en',
                           '--authors=Kovid Goyal', '--cover=' + I('lt.png')
                       ])
        finally:
            os.remove(x)
    return ans


devnull = DevNull()


class BaseTest(unittest.TestCase):

    longMessage = True
    maxDiff = None

    def setUp(self):
        pc.default_log = devnull
        self.tdir = PersistentTemporaryDirectory(suffix='-polish-test')

    def tearDown(self):
        shutil.rmtree(self.tdir, ignore_errors=True)
        del self.tdir