IGN:any2lit

This commit is contained in:
Kovid Goyal 2008-12-16 13:56:35 -08:00
parent e580719f20
commit 8327c7f235
7 changed files with 113 additions and 35 deletions

View File

@ -88,10 +88,10 @@ def initialize_container(path_to_container, opf_name='metadata.opf'):
zf.writestr('META-INF/container.xml', CONTAINER) zf.writestr('META-INF/container.xml', CONTAINER)
return zf return zf
def config(defaults=None): def config(defaults=None, name='epub'):
desc = _('Options to control the conversion to EPUB') desc = _('Options to control the conversion to EPUB')
if defaults is None: if defaults is None:
c = Config('epub', desc) c = Config(name, desc)
else: else:
c = StringConfig(defaults, desc) c = StringConfig(defaults, desc)

View File

@ -148,14 +148,14 @@ def config(defaults=None):
def formats(): def formats():
return ['html', 'rar', 'zip', 'oebzip']+list(MAP.keys()) return ['html', 'rar', 'zip', 'oebzip']+list(MAP.keys())
def option_parser(): USAGE = _('''\
return config().option_parser(usage=_('''\
%%prog [options] filename %%prog [options] filename
Convert any of a large number of ebook formats to an epub file. Supported formats are: %s Convert any of a large number of ebook formats to a %s file. Supported formats are: %s
''')%formats() ''')
)
def option_parser(usage=USAGE):
return config().option_parser(usage=usage%('EPUB', formats()))
def main(args=sys.argv): def main(args=sys.argv):
parser = option_parser() parser = option_parser()

View File

@ -64,7 +64,8 @@ def check(opf_path, pretty_print):
''' '''
Find a remove all invalid links in the HTML files Find a remove all invalid links in the HTML files
''' '''
print '\tChecking files for bad links...' logger = logging.getLogger('html2epub')
logger.info('\tChecking files for bad links...')
pathtoopf = os.path.abspath(opf_path) pathtoopf = os.path.abspath(opf_path)
with CurrentDir(os.path.dirname(pathtoopf)): with CurrentDir(os.path.dirname(pathtoopf)):
opf = OPF(open(pathtoopf, 'rb'), os.path.dirname(pathtoopf)) opf = OPF(open(pathtoopf, 'rb'), os.path.dirname(pathtoopf))

View File

@ -0,0 +1,59 @@
from __future__ import with_statement
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
'''
Convert any ebook format to LIT.
'''
import sys, os, glob, logging
from calibre.ebooks.epub.from_any import any2epub, formats, USAGE
from calibre.ebooks.epub import config as common_config
from calibre.ptempfile import TemporaryDirectory
from calibre.ebooks.lit.writer import oeb2lit
def config(defaults=None):
c = common_config(defaults=defaults, name='lit')
return c
def option_parser(usage=USAGE):
return config().option_parser(usage=usage%('LIT', formats()))
def any2lit(opts, path):
ext = os.path.splitext(path)[1]
if not ext:
raise ValueError('Unknown file type: '+path)
ext = ext.lower()[1:]
if opts.output is None:
opts.output = os.path.splitext(os.path.basename(path))[0]+'.lit'
opts.output = os.path.abspath(opts.output)
orig_output = opts.output
with TemporaryDirectory('_any2lit') as tdir:
oebdir = os.path.join(tdir, 'oeb')
os.mkdir(oebdir)
opts.output = os.path.join(tdir, 'dummy.epub')
opts.extract_to = oebdir
any2epub(opts, path)
opf = glob.glob(os.path.join(oebdir, '*.opf'))[0]
opts.output = orig_output
logging.getLogger('html2epub').info(_('Creating LIT file from EPUB...'))
oeb2lit(opts, opf)
def main(args=sys.argv):
parser = option_parser()
opts, args = parser.parse_args(args)
if len(args) < 2:
parser.print_help()
print 'No input file specified.'
return 1
any2lit(opts, args[1])
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -9,7 +9,7 @@ __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
import sys import sys
import os import os
from cStringIO import StringIO from cStringIO import StringIO
from struct import pack, unpack from struct import pack
from itertools import izip, count, chain from itertools import izip, count, chain
import time import time
import random import random
@ -17,14 +17,14 @@ import re
import copy import copy
import uuid import uuid
import functools import functools
import logging
from urlparse import urldefrag from urlparse import urldefrag
from urllib import unquote as urlunquote from urllib import unquote as urlunquote
from lxml import etree from lxml import etree
from calibre.ebooks.lit import LitError from calibre.ebooks.lit.reader import DirectoryEntry
from calibre.ebooks.lit.reader import msguid, DirectoryEntry
import calibre.ebooks.lit.maps as maps import calibre.ebooks.lit.maps as maps
from calibre.ebooks.lit.oeb import OEB_DOCS, OEB_STYLES, OEB_CSS_MIME, \ from calibre.ebooks.lit.oeb import OEB_DOCS, OEB_STYLES, OEB_CSS_MIME, \
CSS_MIME, XHTML_MIME, OPF_MIME, XML_NS, XML CSS_MIME, OPF_MIME, XML_NS, XML
from calibre.ebooks.lit.oeb import namespace, barename, urlnormalize, xpath from calibre.ebooks.lit.oeb import namespace, barename, urlnormalize, xpath
from calibre.ebooks.lit.oeb import OEBBook from calibre.ebooks.lit.oeb import OEBBook
from calibre.ebooks.lit.stylizer import Stylizer from calibre.ebooks.lit.stylizer import Stylizer
@ -135,11 +135,15 @@ def decint(value):
def randbytes(n): def randbytes(n):
return ''.join(chr(random.randint(0, 255)) for x in xrange(n)) return ''.join(chr(random.randint(0, 255)) for x in xrange(n))
def warn(x):
print x
class ReBinary(object): class ReBinary(object):
NSRMAP = {'': None, XML_NS: 'xml'} NSRMAP = {'': None, XML_NS: 'xml'}
def __init__(self, root, path, oeb, map=HTML_MAP): def __init__(self, root, path, oeb, map=HTML_MAP, warn=warn):
self.path = path self.path = path
self.log_warn = warn
self.dir = os.path.dirname(path) self.dir = os.path.dirname(path)
self.manifest = oeb.manifest self.manifest = oeb.manifest
self.tags, self.tattrs = map self.tags, self.tattrs = map
@ -268,8 +272,8 @@ class ReBinary(object):
def build_ahc(self): def build_ahc(self):
if len(self.anchors) > 6: if len(self.anchors) > 6:
print "calibre: warning: More than six anchors in file %r. " \ self.log_warn("More than six anchors in file %r. " \
"Some links may not work properly." % self.path "Some links may not work properly." % self.path)
data = StringIO() data = StringIO()
data.write(unichr(len(self.anchors)).encode('utf-8')) data.write(unichr(len(self.anchors)).encode('utf-8'))
for anchor, offset in self.anchors: for anchor, offset in self.anchors:
@ -292,8 +296,10 @@ def preserve(function):
functools.update_wrapper(wrapper, function) functools.update_wrapper(wrapper, function)
return wrapper return wrapper
class LitWriter(object): class LitWriter(object, calibre.LoggingInterface):
def __init__(self, oeb): def __init__(self, oeb, verbose=0):
calibre.LoggingInterface.__init__(self, logging.getLogger('oeb2lit'))
self.setup_cli_handler(verbose)
self._oeb = oeb self._oeb = oeb
self._litize_oeb() self._litize_oeb()
@ -319,7 +325,7 @@ class LitWriter(object):
if type not in oeb.guide: if type not in oeb.guide:
oeb.guide.add(type, title, cover.href) oeb.guide.add(type, title, cover.href)
else: else:
print "calibre: warning: No suitable cover image found." self.log_warn('No suitable cover image found.')
def dump(self, stream): def dump(self, stream):
self._stream = stream self._stream = stream
@ -461,15 +467,15 @@ class LitWriter(object):
self._add_folder('/data') self._add_folder('/data')
for item in self._oeb.manifest.values(): for item in self._oeb.manifest.values():
if item.media_type not in LIT_MIMES: if item.media_type not in LIT_MIMES:
print "calibre: warning: File %r of unknown media-type %r " \ self.log_warn("File %r of unknown media-type %r " \
"excluded from output." % (item.href, item.media_type) "excluded from output." % (item.href, item.media_type))
continue continue
name = '/data/' + item.id name = '/data/' + item.id
data = item.data data = item.data
secnum = 0 secnum = 0
if not isinstance(data, basestring): if not isinstance(data, basestring):
self._add_folder(name) self._add_folder(name)
rebin = ReBinary(data, item.href, self._oeb) rebin = ReBinary(data, item.href, self._oeb, warn=self.log_warn)
self._add_file(name + '/ahc', rebin.ahc, 0) self._add_file(name + '/ahc', rebin.ahc, 0)
self._add_file(name + '/aht', rebin.aht, 0) self._add_file(name + '/aht', rebin.aht, 0)
item.page_breaks = rebin.page_breaks item.page_breaks = rebin.page_breaks
@ -548,7 +554,7 @@ class LitWriter(object):
meta.attrib['ms--minimum_level'] = '0' meta.attrib['ms--minimum_level'] = '0'
meta.attrib['ms--attr5'] = '1' meta.attrib['ms--attr5'] = '1'
meta.attrib['ms--guid'] = '{%s}' % str(uuid.uuid4()).upper() meta.attrib['ms--guid'] = '{%s}' % str(uuid.uuid4()).upper()
rebin = ReBinary(meta, 'content.opf', self._oeb, OPF_MAP) rebin = ReBinary(meta, 'content.opf', self._oeb, map=OPF_MAP, warn=self.log_warn)
meta = rebin.content meta = rebin.content
self._meta = meta self._meta = meta
self._add_file('/meta', meta) self._add_file('/meta', meta)
@ -709,6 +715,19 @@ def option_parser():
help=_('Output file. Default is derived from input filename.')) help=_('Output file. Default is derived from input filename.'))
return parser return parser
def oeb2lit(opts, opfpath):
litpath = opts.output
if litpath is None:
litpath = os.path.basename(opfpath)
litpath = os.path.splitext(litpath)[0] + '.lit'
litpath = os.path.abspath(litpath)
lit = LitWriter(OEBBook(opfpath), opts.verbose)
with open(litpath, 'wb') as f:
lit.dump(f)
logger = logging.getLogger('oeb2lit')
logger.info(_('Output written to ')+litpath)
def main(argv=sys.argv): def main(argv=sys.argv):
parser = option_parser() parser = option_parser()
opts, args = parser.parse_args(argv[1:]) opts, args = parser.parse_args(argv[1:])
@ -716,14 +735,7 @@ def main(argv=sys.argv):
parser.print_help() parser.print_help()
return 1 return 1
opfpath = args[0] opfpath = args[0]
litpath = opts.output oeb2lit(opts, opfpath)
if litpath is None:
litpath = os.path.basename(opfpath)
litpath = os.path.splitext(litpath)[0] + '.lit'
lit = LitWriter(OEBBook(opfpath))
with open(litpath, 'wb') as f:
lit.dump(f)
print _('LIT ebook created at'), litpath
return 0 return 0
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -473,9 +473,12 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
return current_page return current_page
def save_current_position(self): def save_current_position(self):
pos = self.view.bookmark() try:
bookmark = '%d#%s'%(self.current_index, pos) pos = self.view.bookmark()
self.iterator.add_bookmark(('calibre_current_page_bookmark', bookmark)) bookmark = '%d#%s'%(self.current_index, pos)
self.iterator.add_bookmark(('calibre_current_page_bookmark', bookmark))
except:
traceback.print_exc()
def load_ebook(self, pathtoebook): def load_ebook(self, pathtoebook):
if self.iterator is not None: if self.iterator is not None:

View File

@ -47,6 +47,7 @@ entry_points = {
'fb2-meta = calibre.ebooks.metadata.fb2:main', 'fb2-meta = calibre.ebooks.metadata.fb2:main',
'any2lrf = calibre.ebooks.lrf.any.convert_from:main', 'any2lrf = calibre.ebooks.lrf.any.convert_from:main',
'any2epub = calibre.ebooks.epub.from_any:main', 'any2epub = calibre.ebooks.epub.from_any:main',
'any2lit = calibre.ebooks.lit.from_any:main',
'lrf2lrs = calibre.ebooks.lrf.lrfparser:main', 'lrf2lrs = calibre.ebooks.lrf.lrfparser:main',
'lrs2lrf = calibre.ebooks.lrf.lrs.convert_from:main', 'lrs2lrf = calibre.ebooks.lrf.lrs.convert_from:main',
'pdfreflow = calibre.ebooks.lrf.pdf.reflow:main', 'pdfreflow = calibre.ebooks.lrf.pdf.reflow:main',
@ -184,6 +185,7 @@ def setup_completion(fatal_errors):
from calibre.ebooks.odt.to_oeb import option_parser as odt2oeb from calibre.ebooks.odt.to_oeb import option_parser as odt2oeb
from calibre.ebooks.epub.from_feeds import option_parser as feeds2epub from calibre.ebooks.epub.from_feeds import option_parser as feeds2epub
from calibre.ebooks.epub.from_any import option_parser as any2epub from calibre.ebooks.epub.from_any import option_parser as any2epub
from calibre.ebooks.lit.from_any import option_parser as any2lit
from calibre.ebooks.epub.from_comic import option_parser as comic2epub from calibre.ebooks.epub.from_comic import option_parser as comic2epub
from calibre.gui2.main import option_parser as guiop from calibre.gui2.main import option_parser as guiop
any_formats = ['epub', 'htm', 'html', 'xhtml', 'xhtm', 'rar', 'zip', any_formats = ['epub', 'htm', 'html', 'xhtml', 'xhtm', 'rar', 'zip',
@ -207,7 +209,8 @@ def setup_completion(fatal_errors):
f.write(opts_and_exts('pdf2lrf', htmlop, ['pdf'])) f.write(opts_and_exts('pdf2lrf', htmlop, ['pdf']))
f.write(opts_and_exts('any2lrf', htmlop, any_formats)) f.write(opts_and_exts('any2lrf', htmlop, any_formats))
f.write(opts_and_exts('calibre', guiop, any_formats)) f.write(opts_and_exts('calibre', guiop, any_formats))
f.write(opts_and_exts('any2lrf', any2epub, any_formats)) f.write(opts_and_exts('any2epub', any2epub, any_formats))
f.write(opts_and_exts('any2lit', any2lit, any_formats))
f.write(opts_and_exts('lrf2lrs', lrf2lrsop, ['lrf'])) f.write(opts_and_exts('lrf2lrs', lrf2lrsop, ['lrf']))
f.write(opts_and_exts('lrf-meta', metaop, ['lrf'])) f.write(opts_and_exts('lrf-meta', metaop, ['lrf']))
f.write(opts_and_exts('rtf-meta', metaop, ['rtf'])) f.write(opts_and_exts('rtf-meta', metaop, ['rtf']))