home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_886 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  5.1 KB  |  128 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. __license__ = 'GPL v3'
  6. __copyright__ = '2008, Anatoly Shipitsin <norguhtar at gmail.com>'
  7. import os
  8. import re
  9. from base64 import b64decode
  10. from lxml import etree
  11. from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation
  12. from calibre import guess_type
  13. FB2NS = 'http://www.gribuser.ru/xml/fictionbook/2.0'
  14.  
  15. class FB2Input(InputFormatPlugin):
  16.     name = 'FB2 Input'
  17.     author = 'Anatoly Shipitsin'
  18.     description = 'Convert FB2 files to HTML'
  19.     file_types = set([
  20.         'fb2'])
  21.     recommendations = set([
  22.         ('level1_toc', '//h:h1', OptionRecommendation.MED),
  23.         ('level2_toc', '//h:h2', OptionRecommendation.MED),
  24.         ('level3_toc', '//h:h3', OptionRecommendation.MED)])
  25.     options = set([
  26.         OptionRecommendation(name = 'no_inline_fb2_toc', recommended_value = False, level = OptionRecommendation.LOW, help = _('Do not insert a Table of Contents at the beginning of the book.'))])
  27.     
  28.     def convert(self, stream, options, file_ext, log, accelerators):
  29.         OPFCreator = OPFCreator
  30.         import calibre.ebooks.metadata.opf2
  31.         get_metadata = get_metadata
  32.         import calibre.ebooks.metadata.meta
  33.         XLINK_NS = XLINK_NS
  34.         XHTML_NS = XHTML_NS
  35.         RECOVER_PARSER = RECOVER_PARSER
  36.         import calibre.ebooks.oeb.base
  37.         NAMESPACES = {
  38.             'f': FB2NS,
  39.             'l': XLINK_NS }
  40.         log.debug('Parsing XML...')
  41.         raw = stream.read().replace('\x00', '')
  42.         
  43.         try:
  44.             doc = etree.fromstring(raw)
  45.         except etree.XMLSyntaxError:
  46.             
  47.             try:
  48.                 doc = etree.fromstring(raw, parser = RECOVER_PARSER)
  49.             doc = etree.fromstring(raw.replace('& ', '&'), parser = RECOVER_PARSER)
  50.  
  51.  
  52.         stylesheets = doc.xpath('//*[local-name() = "stylesheet" and @type="text/css"]')
  53.         css = ''
  54.         for s in stylesheets:
  55.             css += etree.tostring(s, encoding = unicode, method = 'text', with_tail = False) + '\n\n'
  56.         
  57.         if css:
  58.             import cssutils
  59.             import logging
  60.             parser = cssutils.CSSParser(fetcher = None, log = logging.getLogger('calibre.css'))
  61.             XHTML_CSS_NAMESPACE = '@namespace "%s";\n' % XHTML_NS
  62.             text = XHTML_CSS_NAMESPACE + css
  63.             log.debug('Parsing stylesheet...')
  64.             stylesheet = parser.parseString(text)
  65.             stylesheet.namespaces['h'] = XHTML_NS
  66.             css = unicode(stylesheet.cssText).replace('h|style', 'h|span')
  67.             css = re.sub('name\\s*=\\s*', 'class=', css)
  68.         
  69.         self.extract_embedded_content(doc)
  70.         log.debug('Converting XML to HTML...')
  71.         ss = open(P('templates/fb2.xsl'), 'rb').read()
  72.         if options.no_inline_fb2_toc:
  73.             log('Disabling generation of inline FB2 TOC')
  74.             ss = re.compile('<!-- BUILD TOC -->.*<!-- END BUILD TOC -->', re.DOTALL).sub('', ss)
  75.         
  76.         styledoc = etree.fromstring(ss)
  77.         transform = etree.XSLT(styledoc)
  78.         result = transform(doc)
  79.         for img in result.xpath('//img[@src]'):
  80.             src = img.get('src')
  81.             img.set('src', self.binary_map.get(src, src))
  82.         
  83.         index = transform.tostring(result)
  84.         open('index.xhtml', 'wb').write(index)
  85.         open('inline-styles.css', 'wb').write(css)
  86.         stream.seek(0)
  87.         mi = get_metadata(stream, 'fb2')
  88.         if not mi.title:
  89.             mi.title = _('Unknown')
  90.         
  91.         if not mi.authors:
  92.             mi.authors = [
  93.                 _('Unknown')]
  94.         
  95.         opf = OPFCreator(os.getcwdu(), mi)
  96.         entries = [ (f, guess_type(f)[0]) for f in os.listdir('.') ]
  97.         opf.create_manifest(entries)
  98.         opf.create_spine([
  99.             'index.xhtml'])
  100.         for img in doc.xpath('//f:coverpage/f:image', namespaces = NAMESPACES):
  101.             href = img.get('{%s}href' % XLINK_NS, img.get('href', None))
  102.             if href is not None:
  103.                 opf.guide.set_cover(os.path.abspath(href))
  104.                 continue
  105.             None if href.startswith('#') else []
  106.         
  107.         opf.render(open('metadata.opf', 'wb'))
  108.         return os.path.join(os.getcwd(), 'metadata.opf')
  109.  
  110.     
  111.     def extract_embedded_content(self, doc):
  112.         self.binary_map = { }
  113.         for elem in doc.xpath('./*'):
  114.             if 'binary' in elem.tag and elem.attrib.has_key('id'):
  115.                 ct = elem.get('content-type', '')
  116.                 fname = elem.attrib['id']
  117.                 ext = ct.rpartition('/')[-1].lower()
  118.                 if ext in ('png', 'jpeg', 'jpg'):
  119.                     fname += '.' + ext
  120.                     self.binary_map[elem.get('id')] = fname
  121.                 
  122.                 data = b64decode(elem.text.strip())
  123.                 open(fname, 'wb').write(data)
  124.                 continue
  125.         
  126.  
  127.  
  128.