~ubuntu-branches/ubuntu/karmic/calibre/karmic

« back to all changes in this revision

Viewing changes to src/calibre/ebooks/lrf/fb2/convert_from.py

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-30 12:49:41 UTC
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20090730124941-kviipg9ypwgppulc
Tags: upstream-0.6.3+dfsg
ImportĀ upstreamĀ versionĀ 0.6.3+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from __future__ import with_statement
2
 
__license__   = 'GPL v3'
3
 
__copyright__ = '2008, Anatoly Shipitsin <norguhtar at gmail.com>'
4
 
"""
5
 
Convert .fb2 files to .lrf
6
 
"""
7
 
import os, sys, shutil, logging
8
 
from base64 import b64decode
9
 
from lxml import etree
10
 
    
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
19
 
 
20
 
 
21
 
def option_parser():
22
 
    parser = lrf_option_parser(
23
 
_('''%prog [options] mybook.fb2
24
 
 
25
 
 
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.'))
31
 
    return parser
32
 
    
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)
39
 
 
40
 
def to_html(fb2file, tdir):
41
 
    fb2file = os.path.abspath(fb2file)
42
 
    cwd = os.getcwd()
43
 
    try:
44
 
        os.chdir(tdir)
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)
51
 
    
52
 
        transform = etree.XSLT(styledoc)
53
 
        result = transform(doc)
54
 
        open('index.html', 'wb').write(transform.tostring(result))
55
 
        try:
56
 
            mi = get_metadata(open(fb2file, 'rb'), 'fb2')
57
 
        except:
58
 
            mi = MetaInformation(None, None)
59
 
        if not mi.title:
60
 
            mi.title = os.path.splitext(os.path.basename(fb2file))[0]
61
 
        if not mi.authors:
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')
68
 
    finally:
69
 
        os.chdir(cwd)
70
 
 
71
 
    
72
 
def generate_html(fb2file, encoding, logger):
73
 
    tdir = PersistentTemporaryDirectory('_fb22lrf')
74
 
    to_html(fb2file, tdir)
75
 
    return os.path.join(tdir, 'index.html')
76
 
    
77
 
def process_file(path, options, logger=None):
78
 
    if logger is 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))
83
 
    f = open(fb2, 'rb')
84
 
    mi = get_metadata(f, 'fb2')
85
 
    f.close()
86
 
    htmlfile = generate_html(fb2, options.encoding, logger)
87
 
    tdir = os.path.dirname(htmlfile)
88
 
    cwd = os.getcwdu()
89
 
    try:
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))
94
 
        if not mi.title:
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
104
 
        os.chdir(tdir)
105
 
        html_process_file(htmlfile, options, logger)
106
 
    finally:
107
 
        os.chdir(cwd)
108
 
        if getattr(options, 'keep_intermediate_files', False):
109
 
            logger.debug('Intermediate files in '+ tdir)
110
 
        else:
111
 
            shutil.rmtree(tdir)
112
 
 
113
 
def main(args=sys.argv, logger=None):
114
 
    parser = option_parser()    
115
 
    options, args = parser.parse_args(args)
116
 
    if len(args) != 2:
117
 
        parser.print_help()
118
 
        print
119
 
        print 'No fb2 file specified'
120
 
        return 1
121
 
    process_file(args[1], options, logger)
122
 
    return 0
123
 
 
124
 
if __name__ == '__main__':
125
 
    sys.exit(main())