1
from __future__ import with_statement
3
__copyright__ = '2008, Anatoly Shipitsin <norguhtar at gmail.com>'
5
Convert .fb2 files to .lrf
7
import os, sys, shutil, logging
8
from base64 import b64decode
11
from calibre.ebooks.lrf import option_parser as lrf_option_parser
12
from calibre.ebooks.metadata.meta import get_metadata
13
from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file
14
from calibre import setup_cli_handlers
15
from calibre.resources import fb2_xsl
16
from calibre.ptempfile import PersistentTemporaryDirectory
17
from calibre.ebooks.metadata.opf import OPFCreator
18
from calibre.ebooks.metadata import MetaInformation
22
parser = lrf_option_parser(
23
_('''%prog [options] mybook.fb2
26
%prog converts mybook.fb2 to mybook.lrf'''))
27
parser.add_option('--debug-html-generation', action='store_true', default=False,
28
dest='debug_html_generation', help=_('Print generated HTML to stdout and quit.'))
29
parser.add_option('--keep-intermediate-files', action='store_true', default=False,
30
help=_('Keep generated HTML files after completing conversion to LRF.'))
33
def extract_embedded_content(doc):
34
for elem in doc.xpath('./*'):
35
if 'binary' in elem.tag and elem.attrib.has_key('id'):
36
fname = elem.attrib['id']
37
data = b64decode(elem.text.strip())
38
open(fname, 'wb').write(data)
40
def to_html(fb2file, tdir):
41
fb2file = os.path.abspath(fb2file)
45
print 'Parsing XML...'
46
parser = etree.XMLParser(recover=True, no_network=True)
47
doc = etree.parse(fb2file, parser)
48
extract_embedded_content(doc)
49
print 'Converting XML to HTML...'
50
styledoc = etree.fromstring(fb2_xsl)
52
transform = etree.XSLT(styledoc)
53
result = transform(doc)
54
open('index.html', 'wb').write(transform.tostring(result))
56
mi = get_metadata(open(fb2file, 'rb'), 'fb2')
58
mi = MetaInformation(None, None)
60
mi.title = os.path.splitext(os.path.basename(fb2file))[0]
62
mi.authors = [_('Unknown')]
63
opf = OPFCreator(tdir, mi)
64
opf.create_manifest([('index.html', None)])
65
opf.create_spine(['index.html'])
66
opf.render(open('metadata.opf', 'wb'))
67
return os.path.join(tdir, 'metadata.opf')
72
def generate_html(fb2file, encoding, logger):
73
tdir = PersistentTemporaryDirectory('_fb22lrf')
74
to_html(fb2file, tdir)
75
return os.path.join(tdir, 'index.html')
77
def process_file(path, options, logger=None):
79
level = logging.DEBUG if options.verbose else logging.INFO
80
logger = logging.getLogger('fb22lrf')
81
setup_cli_handlers(logger, level)
82
fb2 = os.path.abspath(os.path.expanduser(path))
84
mi = get_metadata(f, 'fb2')
86
htmlfile = generate_html(fb2, options.encoding, logger)
87
tdir = os.path.dirname(htmlfile)
90
if not options.output:
91
ext = '.lrs' if options.lrs else '.lrf'
92
options.output = os.path.abspath(os.path.basename(os.path.splitext(path)[0]) + ext)
93
options.output = os.path.abspath(os.path.expanduser(options.output))
95
mi.title = os.path.splitext(os.path.basename(fb2))[0]
96
if (not options.title or options.title == _('Unknown')):
97
options.title = mi.title
98
if (not options.author or options.author == _('Unknown')) and mi.authors:
99
options.author = mi.authors.pop()
100
if (not options.category or options.category == _('Unknown')) and mi.category:
101
options.category = mi.category
102
if (not options.freetext or options.freetext == _('Unknown')) and mi.comments:
103
options.freetext = mi.comments
105
html_process_file(htmlfile, options, logger)
108
if getattr(options, 'keep_intermediate_files', False):
109
logger.debug('Intermediate files in '+ tdir)
113
def main(args=sys.argv, logger=None):
114
parser = option_parser()
115
options, args = parser.parse_args(args)
119
print 'No fb2 file specified'
121
process_file(args[1], options, logger)
124
if __name__ == '__main__':