diff --git a/.bzrignore b/.bzrignore new file mode 100644 index 0000000000..51fd860418 --- /dev/null +++ b/.bzrignore @@ -0,0 +1,8 @@ +*_ui.py +src/calibre.egg-info/ +src/calibre/resources.py +src/calibre/gui2/images.qrc +src/calibre/gui2/images_rc.py +src/calibre/manual/.build/ +src/calibre/manual/cli/ + diff --git a/resources.py b/resources.py index 1a1e2e0497..55629557dd 100644 --- a/resources.py +++ b/resources.py @@ -12,6 +12,7 @@ from calibre import __appname__ RESOURCES = dict( opf_template = '%p/ebooks/metadata/opf.xml', ncx_template = '%p/ebooks/metadata/ncx.xml', + fb2_xsl = '%p/ebooks/lrf/fb2/fb2.xsl', ) def main(args=sys.argv): diff --git a/src/calibre/ebooks/__init__.py b/src/calibre/ebooks/__init__.py index 5b5f5ce0e6..0fceb4bcf8 100644 --- a/src/calibre/ebooks/__init__.py +++ b/src/calibre/ebooks/__init__.py @@ -14,4 +14,4 @@ class UnknownFormatError(Exception): BOOK_EXTENSIONS = ['lrf', 'lrx', 'rar', 'zip', 'rtf', 'lit', 'txt', 'htm', 'xhtm', 'html', 'xhtml', 'epub', 'pdf', 'prc', 'mobi', 'azw', - 'epub'] + 'epub', 'fb2'] diff --git a/src/calibre/ebooks/lrf/any/convert_from.py b/src/calibre/ebooks/lrf/any/convert_from.py index 697bc1e393..8a191b9fc5 100644 --- a/src/calibre/ebooks/lrf/any/convert_from.py +++ b/src/calibre/ebooks/lrf/any/convert_from.py @@ -14,6 +14,7 @@ from calibre.ebooks.lrf.txt.convert_from import process_file as txt2lrf from calibre.ebooks.lrf.html.convert_from import process_file as html2lrf from calibre.ebooks.lrf.epub.convert_from import process_file as epub2lrf from calibre.ebooks.lrf.mobi.convert_from import process_file as mobi2lrf +from calibre.ebooks.lrf.fb2.convert_from import process_file as fb22lrf def largest_file(files): maxsize, file = 0, None @@ -52,7 +53,7 @@ def unhidden_directories(base, listing): if os.path.isdir(os.path.join(base, i)) and not i.startswith('__') and \ not i.startswith('.'): ans.append(i) - return ans + return ans def traverse_subdirs(tdir): temp = os.listdir(tdir) @@ -85,7 +86,7 @@ def process_file(path, options, logger=None): if logger is None: level = logging.DEBUG if options.verbose else logging.INFO logger = logging.getLogger('any2lrf') - setup_cli_handlers(logger, level) + setup_cli_handlers(logger, level) if not os.access(path, os.R_OK): logger.critical('Cannot read from %s', path) return 1 @@ -126,6 +127,8 @@ def process_file(path, options, logger=None): convertor = epub2lrf elif ext in ['mobi', 'prc']: convertor = mobi2lrf + elif ext == 'fb2': + convertor = fb22lrf if not convertor: raise UnknownFormatError('Coverting from %s to LRF is not supported.'%ext) convertor(path, options, logger) @@ -158,4 +161,4 @@ def main(args=sys.argv, logger=None, gui_mode=False): return process_file(args[1], options, logger) if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/src/calibre/ebooks/lrf/fb2/__init__.py b/src/calibre/ebooks/lrf/fb2/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/calibre/ebooks/lrf/fb2/convert_from.py b/src/calibre/ebooks/lrf/fb2/convert_from.py new file mode 100644 index 0000000000..6cd6ca971e --- /dev/null +++ b/src/calibre/ebooks/lrf/fb2/convert_from.py @@ -0,0 +1,91 @@ +__license__ = 'GPL v3' +__copyright__ = '2008, Anatoly Shipitsin ' +""" +Convert .fb2 files to .lrf +""" +import os, sys, tempfile, subprocess, shutil, logging, glob + +from calibre.ptempfile import PersistentTemporaryFile +from calibre.ebooks.lrf import option_parser as lrf_option_parser +from calibre.ebooks import ConversionError +from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file +from calibre import setup_cli_handlers, __appname__ +from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup +from calibre.resources import fb2_xsl + +def option_parser(): + parser = lrf_option_parser( +_('''%prog [options] mybook.fb2 + + +%prog converts mybook.fb2 to mybook.lrf''')) + parser.add_option('--debug-html-generation', action='store_true', default=False, + dest='debug_html_generation', help=_('Print generated HTML to stdout and quit.')) + return parser + + +def generate_html(fb2file, encoding, logger): + from lxml import etree + tdir = tempfile.mkdtemp(prefix=__appname__+'_') + ofile = os.path.join(tdir, 'index.xml') + cwd = os.getcwdu() + os.chdir(tdir) + try: + logger.info('Parsing XML...') + parser = etree.XMLParser(recover=True, no_network=True) + try: + doc = etree.parse(fb2file, parser) + except: + raise + logger.info('Parsing failed. Trying to clean up XML...') + soup = BeautifulStoneSoup(open(fb2file, 'rb').read()) + doc = etree.fromstring(str(soup)) + logger.info('Converting XML to HTML...') + styledoc = etree.fromstring(fb2_xsl) + + transform = etree.XSLT(styledoc) + result = transform(doc) + html = os.path.join(tdir, 'index.html') + f = open(html, 'wb') + f.write(transform.tostring(result)) + f.close() + finally: + os.chdir(cwd) + return html + +def process_file(path, options, logger=None): + if logger is None: + level = logging.DEBUG if options.verbose else logging.INFO + logger = logging.getLogger('fb22lrf') + setup_cli_handlers(logger, level) + fb2 = os.path.abspath(os.path.expanduser(path)) + htmlfile = generate_html(fb2, options.encoding, logger) + tdir = os.path.dirname(htmlfile) + cwd = os.getcwdu() + try: + if not options.output: + ext = '.lrs' if options.lrs else '.lrf' + options.output = os.path.abspath(os.path.basename(os.path.splitext(path)[0]) + ext) + options.output = os.path.abspath(os.path.expanduser(options.output)) + os.chdir(tdir) + html_process_file(htmlfile, options, logger) + finally: + os.chdir(cwd) + if hasattr(options, 'keep_intermediate_files') and options.keep_intermediate_files: + logger.debug('Intermediate files in '+ tdir) + else: + shutil.rmtree(tdir) + +def main(args=sys.argv, logger=None): + parser = option_parser() + options, args = parser.parse_args(args) + if len(args) != 2: + parser.print_help() + print + print 'No fb2 file specified' + return 1 + process_file(args[1], options, logger) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/calibre/ebooks/lrf/fb2/fb2.xsl b/src/calibre/ebooks/lrf/fb2/fb2.xsl new file mode 100644 index 0000000000..098532e44b --- /dev/null +++ b/src/calibre/ebooks/lrf/fb2/fb2.xsl @@ -0,0 +1,328 @@ + + + + + + + + + + + + <xsl:value-of select="fb:description/fb:title-info/fb:book-title"/> + + + + + +
+ +
+
+
+ +
    + +
+
+ + + +
+
+ +

+ +

+
+ + +
+ + +
+ + + + + + + +
+
+ + +
  • + + + , # + + + +
      + + + +
    +
    + + + + + + + + + +
  • + + +
    +
    +
  • + + +
    + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + +
    +
    + + + + + + + +
    + +
    +
    + + +
    + + + +    
    +
    + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Annotation

    + +
    + + +
    + + + + + + +
    +
    + + +
    + +
    +
    + + +
    + + + + + + +
    +
    + + +
    +
    +
    + + + + +     +
    +
    + +     +
    +
    +
    +
    + + +
    + + + + + + +
    +
    + + + + +
    +
    + + + + + + + +
    +
    + + +
    + + + + + + + + + + +
    +
    +
    diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 312966d005..bfb631ad10 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -36,6 +36,7 @@ entry_points = { 'web2lrf = calibre.ebooks.lrf.web.convert_from:main', 'pdf2lrf = calibre.ebooks.lrf.pdf.convert_from:main', 'mobi2lrf = calibre.ebooks.lrf.mobi.convert_from:main', + 'fb22lrf = calibre.ebooks.lrf.fb2.convert_from:main', 'any2lrf = calibre.ebooks.lrf.any.convert_from:main', 'lrf2lrs = calibre.ebooks.lrf.parser:main', 'lrs2lrf = calibre.ebooks.lrf.lrs.convert_from:main', @@ -172,9 +173,11 @@ def setup_completion(fatal_errors): f.write(opts_and_exts('epub2lrf', htmlop, ['epub'])) f.write(opts_and_exts('rtf2lrf', htmlop, ['rtf'])) f.write(opts_and_exts('mobi2lrf', htmlop, ['mobi', 'prc'])) + f.write(opts_and_exts('fb22lrf', htmlop, ['fb2'])) f.write(opts_and_exts('pdf2lrf', htmlop, ['pdf'])) f.write(opts_and_exts('any2lrf', htmlop, - ['epub', 'htm', 'html', 'xhtml', 'xhtm', 'rar', 'zip', 'txt', 'lit', 'rtf', 'pdf', 'prc', 'mobi'])) + ['epub', 'htm', 'html', 'xhtml', 'xhtm', 'rar', 'zip', + 'txt', 'lit', 'rtf', 'pdf', 'prc', 'mobi', 'fb2'])) f.write(opts_and_exts('lrf2lrs', lrf2lrsop, ['lrf'])) f.write(opts_and_exts('lrf-meta', metaop, ['lrf'])) f.write(opts_and_exts('rtf-meta', metaop, ['rtf'])) diff --git a/src/calibre/translations/ca.po b/src/calibre/translations/ca.po index acc795782e..8c6881863a 100644 --- a/src/calibre/translations/ca.po +++ b/src/calibre/translations/ca.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: ca\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-04-04 09:07+PDT\n" +"POT-Creation-Date: 2008-04-07 16:11+IST\n" "PO-Revision-Date: 2007-11-16 09:07+0100\n" "Last-Translator: calibre\n" "Language-Team: \n" @@ -330,7 +330,7 @@ msgid "" "default is to try and guess the encoding." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:143 msgid "" "any2lrf [options] myfile\n" "\n" @@ -341,7 +341,7 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:155 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:158 msgid "No file to convert specified." msgstr "" @@ -353,6 +353,19 @@ msgid "" "%prog converts mybook.epub to mybook.lrf" msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:18 +msgid "" +"%prog [options] mybook.fb2\n" +"\n" +"\n" +"%prog converts mybook.fb2 to mybook.lrf" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:23 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 +msgid "Print generated HTML to stdout and quit." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:20 msgid "Options to control the behavior of feeds2disk" msgstr "" @@ -377,78 +390,78 @@ msgstr "" msgid "\tBaen file detected. Re-parsing..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:339 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:341 msgid "Written preprocessed HTML to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:350 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:352 msgid "Processing %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:364 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:366 msgid "\tConverting to BBeB..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:502 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:509 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:504 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:511 msgid "Could not parse file: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:521 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:523 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:564 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:566 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:906 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:908 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:944 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:946 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:959 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:961 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1649 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1651 msgid "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1651 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1653 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1673 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1675 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1701 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1703 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1741 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1743 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1744 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1746 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1873 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1875 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1879 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1881 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -605,10 +618,6 @@ msgid "" "%prog converts mybook.txt to mybook.lrf" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 -msgid "Print generated HTML to stdout and quit." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:20 msgid "Set the authors" msgstr "" @@ -2131,9 +2140,8 @@ msgid "" "right:0px; -qt-block-indent:0; text-indent:0px;\">For help visit calibre.kovidgoyal.net

    calibre: %1 by " -"Kovid Goyal %2
    %3

    " +"a>

    calibre: %1 by Kovid Goyal %2
    %3

    " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:271 @@ -2511,8 +2519,8 @@ msgstr "" #~ "right:0px; -qt-block-indent:0; text-indent:0px;\">For help visit
    calibre.kovidgoyal.net

    calibre: %" -#~ "1 by Kovid Goyal %2
    %3



    calibre: %1 " +#~ "by Kovid Goyal %2
    %3

    " #~ msgstr "" #~ "\n

    Create a basic news recipe, by adding RSS feeds to it.
    For most feeds, you will have to use the "Advanced mode" to further customize the fetch process.

    \x00\n

    \x00\n

    For help visit calibre.kovidgoyal.net

    calibre: %1 by Kovid Goyal %2
    %3

    \x00
  • book-designer - HTML0 files from Book Designer
  • \x00
  • pdftohtml - HTML files that are the output of the program pdftohtml
  • \x00
    1. baen - Books from BAEN Publishers
    2. \x00

      An invalid database already exists at %s, delete it before trying to move the existing database.
      Error: %s\x00

      Books with the same title as the following already exist in the database. Add them anyway?