Change to calibre

This commit is contained in:
Kovid Goyal 2008-04-28 20:09:20 -07:00
commit c7ced2134c
463 changed files with 8779 additions and 8275 deletions

8
.bzrignore Normal file
View File

@ -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/

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?> <?eclipse-pydev version="1.0"?>
<pydev_project> <pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property> <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH"> <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/libprs500/src</path> <path>/calibre/src</path>
<path>/libprs500/devices</path> <path>/calibre/devices</path>
<path>/libprs500/libprs500.devices.prs500</path> <path>/calibre/libprs500.devices.prs500</path>
<path>/libprs500/prs500</path> <path>/calibre/prs500</path>
<path>/libprs500/gui2</path> <path>/calibre/gui2</path>
</pydev_pathproperty> </pydev_pathproperty>
</pydev_project> </pydev_project>

View File

@ -3,19 +3,19 @@ PYTHON = python
all : gui2 translations resources all : gui2 translations resources
clean : clean :
cd src/libprs500/gui2 && ${PYTHON} make.py clean cd src/calibre/gui2 && ${PYTHON} make.py clean
gui2 : gui2 :
cd src/libprs500/gui2 && ${PYTHON} make.py cd src/calibre/gui2 && ${PYTHON} make.py
test : gui2 test : gui2
cd src/libprs500/gui2 && ${PYTHON} make.py test cd src/calibre/gui2 && ${PYTHON} make.py test
translations : translations :
cd src/libprs500 && ${PYTHON} translations/__init__.py cd src/calibre && ${PYTHON} translations/__init__.py
resources: resources:
${PYTHON} resources.py ${PYTHON} resources.py
manual: manual:
make -C src/libprs500/manual clean html make -C src/calibre/manual clean html

View File

@ -1,13 +1,13 @@
[epydoc] # Epydoc section marker (required by ConfigParser) [epydoc] # Epydoc section marker (required by ConfigParser)
# Information about the project. # Information about the project.
name: libprs500 name: calibre
url: http://libprs500.kovidgoyal.net url: http://calibre.kovidgoyal.net
# The list of modules to document. Modules can be named using # The list of modules to document. Modules can be named using
# dotted names, module filenames, or package directory names. # dotted names, module filenames, or package directory names.
# This option may be repeated. # This option may be repeated.
modules: libprs500.devices, libprs500.ebooks.lrf.web.profiles modules: calibre.devices, calibre.ebooks.lrf.web.profiles
output: pdf output: pdf
target: docs/pdf target: docs/pdf
@ -36,7 +36,7 @@ css: white
# The "top" page for the documentation. Can be a URL, the name # The "top" page for the documentation. Can be a URL, the name
# of a module or class, or one of the special names "trees.html", # of a module or class, or one of the special names "trees.html",
# "indices.html", or "help.html" # "indices.html", or "help.html"
# top: libprs500 # top: calibre
# verbosity # verbosity
# An integer indicating how verbose epydoc should be. The default # An integer indicating how verbose epydoc should be. The default

View File

@ -1,13 +1,13 @@
[epydoc] # Epydoc section marker (required by ConfigParser) [epydoc] # Epydoc section marker (required by ConfigParser)
# Information about the project. # Information about the project.
name: libprs500 - API documentation name: calibre - API documentation
url: http://libprs500.kovidgoyal.net url: http://calibre.kovidgoyal.net
# The list of modules to document. Modules can be named using # The list of modules to document. Modules can be named using
# dotted names, module filenames, or package directory names. # dotted names, module filenames, or package directory names.
# This option may be repeated. # This option may be repeated.
modules: libprs500.devices, libprs500.ebooks.lrf.web.profiles modules: calibre.devices, calibre.ebooks.lrf.web.profiles
# Write html output to the directory "docs" # Write html output to the directory "docs"
output: html output: html
@ -31,7 +31,7 @@ css: white
# HTML code for the project link in the navigation bar. If left # HTML code for the project link in the navigation bar. If left
# unspecified, the project link will be generated based on the # unspecified, the project link will be generated based on the
# project's name and URL. # project's name and URL.
link: <a href="http://libprs500.kovidgoyal.net">libprs500</a> link: <a href="http://calibre.kovidgoyal.net">calibre</a>
# top # top
# The "top" page for the documentation. Can be a URL, the name # The "top" page for the documentation. Can be a URL, the name

View File

@ -233,12 +233,12 @@ def main():
'frameworks': ['libusb.dylib', 'libunrar.dylib'], 'frameworks': ['libusb.dylib', 'libunrar.dylib'],
'includes' : ['sip', 'pkg_resources', 'PyQt4.QtSvg', 'includes' : ['sip', 'pkg_resources', 'PyQt4.QtSvg',
'mechanize', 'ClientForm', 'usbobserver', 'mechanize', 'ClientForm', 'usbobserver',
'genshi', 'libprs500.web.feeds.recipes.*', 'genshi', 'calibre.web.feeds.recipes.*',
'IPython.Extensions.*', 'pydoc'], 'IPython.Extensions.*', 'pydoc'],
'packages' : ['PIL', 'Authorization', 'rtf2xml', 'lxml'], 'packages' : ['PIL', 'Authorization', 'rtf2xml', 'lxml'],
'excludes' : [], 'excludes' : [],
'plist' : { 'CFBundleGetInfoString' : '''libprs500, an E-book management application.''' 'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.'''
''' Visit http://libprs500.kovidgoyal.net for details.''', ''' Visit http://calibre.kovidgoyal.net for details.''',
'CFBundleIdentifier':'net.kovidgoyal.librs500', 'CFBundleIdentifier':'net.kovidgoyal.librs500',
'CFBundleShortVersionString':VERSION, 'CFBundleShortVersionString':VERSION,
'CFBundleVersion':APPNAME + ' ' + VERSION, 'CFBundleVersion':APPNAME + ' ' + VERSION,

View File

@ -7,11 +7,12 @@ Compile resource files.
''' '''
import os, sys import os, sys
sys.path.insert(1, os.path.join(os.getcwd(), 'src')) sys.path.insert(1, os.path.join(os.getcwd(), 'src'))
from libprs500 import __appname__ from calibre import __appname__
RESOURCES = dict( RESOURCES = dict(
opf_template = '%p/ebooks/metadata/opf.xml', opf_template = '%p/ebooks/metadata/opf.xml',
ncx_template = '%p/ebooks/metadata/ncx.xml', ncx_template = '%p/ebooks/metadata/ncx.xml',
fb2_xsl = '%p/ebooks/lrf/fb2/fb2.xsl',
) )
def main(args=sys.argv): def main(args=sys.argv):

View File

@ -5,16 +5,16 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import sys, re, os, shutil import sys, re, os, shutil
sys.path.append('src') sys.path.append('src')
islinux = not ('win32' in sys.platform or 'win64' in sys.platform or 'darwin' in sys.platform) islinux = not ('win32' in sys.platform or 'win64' in sys.platform or 'darwin' in sys.platform)
src = open('src/libprs500/__init__.py', 'rb').read() src = open('src/calibre/__init__.py', 'rb').read()
VERSION = re.search(r'__version__\s+=\s+[\'"]([^\'"]+)[\'"]', src).group(1) VERSION = re.search(r'__version__\s+=\s+[\'"]([^\'"]+)[\'"]', src).group(1)
APPNAME = re.search(r'__appname__\s+=\s+[\'"]([^\'"]+)[\'"]', src).group(1) APPNAME = re.search(r'__appname__\s+=\s+[\'"]([^\'"]+)[\'"]', src).group(1)
print 'Setup', APPNAME, 'version:', VERSION print 'Setup', APPNAME, 'version:', VERSION
epsrc = re.compile(r'entry_points = (\{.*?\})', re.DOTALL).search(open('src/libprs500/linux.py', 'rb').read()).group(1) epsrc = re.compile(r'entry_points = (\{.*?\})', re.DOTALL).search(open('src/%s/linux.py'%APPNAME, 'rb').read()).group(1)
entry_points = eval(epsrc, {'__appname__': APPNAME}) entry_points = eval(epsrc, {'__appname__': APPNAME})
if 'win32' in sys.platform.lower() or 'win64' in sys.platform.lower(): if 'win32' in sys.platform.lower() or 'win64' in sys.platform.lower():
entry_points['console_scripts'].append('parallel = libprs500.parallel:main') entry_points['console_scripts'].append('parallel = %s.parallel:main'%APPNAME)
def _ep_to_script(ep, base='src'): def _ep_to_script(ep, base='src'):
return (base+os.path.sep+re.search(r'.*=\s*(.*?):', ep).group(1).replace('.', '/')+'.py').strip() return (base+os.path.sep+re.search(r'.*=\s*(.*?):', ep).group(1).replace('.', '/')+'.py').strip()
@ -50,16 +50,16 @@ if __name__ == '__main__':
from setuptools import setup, find_packages from setuptools import setup, find_packages
import subprocess import subprocess
entry_points['console_scripts'].append('libprs500_postinstall = libprs500.linux:post_install') entry_points['console_scripts'].append('calibre_postinstall = calibre.linux:post_install')
setup( setup(
name='libprs500', name=APPNAME,
packages = find_packages('src'), packages = find_packages('src'),
package_dir = { '' : 'src' }, package_dir = { '' : 'src' },
version=VERSION, version=VERSION,
author='Kovid Goyal', author='Kovid Goyal',
author_email='kovid@kovidgoyal.net', author_email='kovid@kovidgoyal.net',
url = 'http://libprs500.kovidgoyal.net', url = 'http://%s.kovidgoyal.net'%APPNAME,
include_package_data = True, include_package_data = True,
entry_points = entry_points, entry_points = entry_points,
zip_safe = True, zip_safe = True,
@ -99,4 +99,4 @@ if __name__ == '__main__':
) )
if 'develop' in ' '.join(sys.argv) and islinux: if 'develop' in ' '.join(sys.argv) and islinux:
subprocess.check_call('libprs500_postinstall', shell=True) subprocess.check_call('calibre_postinstall', shell=True)

View File

@ -4,7 +4,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
__version__ = '0.4.49' __version__ = '0.4.49'
__docformat__ = "epytext" __docformat__ = "epytext"
__author__ = "Kovid Goyal <kovid at kovidgoyal.net>" __author__ = "Kovid Goyal <kovid at kovidgoyal.net>"
__appname__ = 'libprs500' __appname__ = 'calibre'
import sys, os, logging, mechanize, locale, copy, cStringIO, re, subprocess, \ import sys, os, logging, mechanize, locale, copy, cStringIO, re, subprocess, \
textwrap, atexit, cPickle textwrap, atexit, cPickle
@ -17,16 +17,19 @@ from logging import Formatter
from ttfquery import findsystem, describe from ttfquery import findsystem, describe
from PyQt4.QtCore import QSettings, QVariant from PyQt4.QtCore import QSettings, QVariant
from libprs500.translations.msgfmt import make from calibre.translations.msgfmt import make
from libprs500.ebooks.chardet import detect from calibre.ebooks.chardet import detect
from libprs500.terminfo import TerminalController from calibre.terminfo import TerminalController
terminal_controller = TerminalController(sys.stdout) terminal_controller = TerminalController(sys.stdout)
iswindows = 'win32' in sys.platform.lower() or 'win64' in sys.platform.lower() iswindows = 'win32' in sys.platform.lower() or 'win64' in sys.platform.lower()
isosx = 'darwin' in sys.platform.lower() isosx = 'darwin' in sys.platform.lower()
islinux = not(iswindows or isosx) islinux = not(iswindows or isosx)
locale.setlocale(locale.LC_ALL, '') try:
locale.setlocale(locale.LC_ALL, '')
except:
pass
def osx_version(): def osx_version():
if isosx: if isosx:
@ -216,10 +219,10 @@ def extract(path, dir):
ext = os.path.splitext(path)[1][1:].lower() ext = os.path.splitext(path)[1][1:].lower()
extractor = None extractor = None
if ext == 'zip': if ext == 'zip':
from libprs500.libunzip import extract as zipextract from calibre.libunzip import extract as zipextract
extractor = zipextract extractor = zipextract
elif ext == 'rar': elif ext == 'rar':
from libprs500.libunrar import extract as rarextract from calibre.libunrar import extract as rarextract
extractor = rarextract extractor = rarextract
if extractor is None: if extractor is None:
raise Exception('Unknown archive type') raise Exception('Unknown archive type')
@ -262,7 +265,7 @@ def fit_image(width, height, pwidth, pheight):
def set_translator(): def set_translator():
# To test different translations invoke as # To test different translations invoke as
# LC_ALL=de_DE.utf8 program # LC_ALL=de_DE.utf8 program
from libprs500.translations.data import translations from calibre.translations.data import translations
lang = locale.getdefaultlocale()[0] lang = locale.getdefaultlocale()[0]
if lang is None and os.environ.has_key('LANG'): # Needed for OS X if lang is None and os.environ.has_key('LANG'): # Needed for OS X
try: try:

View File

@ -5,9 +5,9 @@ Device drivers.
''' '''
def devices(): def devices():
from libprs500.devices.prs500.driver import PRS500 from calibre.devices.prs500.driver import PRS500
from libprs500.devices.prs505.driver import PRS505 from calibre.devices.prs505.driver import PRS505
from libprs500.devices.kindle.driver import KINDLE from calibre.devices.kindle.driver import KINDLE
return (PRS500, PRS505, KINDLE) return (PRS500, PRS505, KINDLE)
import time import time

View File

@ -6,8 +6,8 @@ import re, time, functools
import os import os
from libprs500.devices.interface import BookList as _BookList from calibre.devices.interface import BookList as _BookList
from libprs500.devices import strftime as _strftime from calibre.devices import strftime as _strftime
strftime = functools.partial(_strftime, zone=time.localtime) strftime = functools.partial(_strftime, zone=time.localtime)
MIME_MAP = { MIME_MAP = {

View File

@ -6,11 +6,11 @@ Device driver for the Amazon Kindle
import sys, os, shutil, time, subprocess, re import sys, os, shutil, time, subprocess, re
from itertools import cycle from itertools import cycle
from libprs500.devices.interface import Device from calibre.devices.interface import Device
from libprs500.devices.errors import DeviceError, FreeSpaceError from calibre.devices.errors import DeviceError, FreeSpaceError
from libprs500.devices.kindle.books import BookList from calibre.devices.kindle.books import BookList
from libprs500 import iswindows, islinux, isosx from calibre import iswindows, islinux, isosx
from libprs500.devices.errors import PathError from calibre.devices.errors import PathError
class File(object): class File(object):
def __init__(self, path): def __init__(self, path):

View File

@ -8,7 +8,7 @@ from ctypes import cdll, POINTER, byref, pointer, Structure, \
c_ubyte, c_ushort, c_int, c_char, c_void_p, c_byte, c_uint c_ubyte, c_ushort, c_int, c_char, c_void_p, c_byte, c_uint
from errno import EBUSY, ENOMEM from errno import EBUSY, ENOMEM
from libprs500 import iswindows, isosx, load_library from calibre import iswindows, isosx, load_library
_libusb_name = 'libusb' _libusb_name = 'libusb'
PATH_MAX = 511 if iswindows else 1024 if isosx else 4096 PATH_MAX = 511 if iswindows else 1024 if isosx else 4096

View File

@ -8,8 +8,8 @@ Define a threaded interface for working with devices.
import threading, Queue import threading, Queue
from libprs500.devices.device import Device from calibre.devices.device import Device
from libprs500.devices.prs500.driver import PRS500 from calibre.devices.prs500.driver import PRS500
class DeviceManager(object): class DeviceManager(object):

View File

@ -9,8 +9,8 @@ from base64 import b64decode as decode
from base64 import b64encode as encode from base64 import b64encode as encode
import re import re
from libprs500.devices.interface import BookList as _BookList from calibre.devices.interface import BookList as _BookList
from libprs500.devices import strftime, strptime from calibre.devices import strftime, strptime
MIME_MAP = { \ MIME_MAP = { \
"lrf":"application/x-sony-bbeb", \ "lrf":"application/x-sony-bbeb", \

View File

@ -9,12 +9,12 @@ For usage information run the script.
import StringIO, sys, time, os import StringIO, sys, time, os
from optparse import OptionParser from optparse import OptionParser
from libprs500 import __version__, iswindows, __appname__ from calibre import __version__, iswindows, __appname__
from libprs500.devices.errors import PathError from calibre.devices.errors import PathError
from libprs500.terminfo import TerminalController from calibre.terminfo import TerminalController
from libprs500.devices.errors import ArgumentError, DeviceError, DeviceLocked from calibre.devices.errors import ArgumentError, DeviceError, DeviceLocked
from libprs500.devices import devices from calibre.devices import devices
from libprs500.devices.scanner import DeviceScanner from calibre.devices.scanner import DeviceScanner
MINIMUM_COL_WIDTH = 12 #: Minimum width of columns in ls output MINIMUM_COL_WIDTH = 12 #: Minimum width of columns in ls output

View File

@ -40,13 +40,13 @@ from array import array
from functools import wraps from functools import wraps
from StringIO import StringIO from StringIO import StringIO
from libprs500.devices.interface import Device from calibre.devices.interface import Device
from libprs500.devices.libusb import Error as USBError from calibre.devices.libusb import Error as USBError
from libprs500.devices.libusb import get_device_by_id from calibre.devices.libusb import get_device_by_id
from libprs500.devices.prs500.prstypes import * from calibre.devices.prs500.prstypes import *
from libprs500.devices.errors import * from calibre.devices.errors import *
from libprs500.devices.prs500.books import BookList, fix_ids from calibre.devices.prs500.books import BookList, fix_ids
from libprs500 import __author__, __appname__ from calibre import __author__, __appname__
# Protocol versions this driver has been tested with # Protocol versions this driver has been tested with
KNOWN_USB_PROTOCOL_VERSIONS = [0x3030303030303130L] KNOWN_USB_PROTOCOL_VERSIONS = [0x3030303030303130L]

View File

@ -33,7 +33,7 @@ import struct
import time import time
from datetime import datetime from datetime import datetime
from libprs500.devices.errors import PacketError from calibre.devices.errors import PacketError
WORD = "<H" #: Unsigned integer little endian encoded in 2 bytes WORD = "<H" #: Unsigned integer little endian encoded in 2 bytes
DWORD = "<I" #: Unsigned integer little endian encoded in 4 bytes DWORD = "<I" #: Unsigned integer little endian encoded in 4 bytes

View File

@ -9,9 +9,9 @@ from base64 import b64decode as decode
from base64 import b64encode as encode from base64 import b64encode as encode
from libprs500.devices.interface import BookList as _BookList from calibre.devices.interface import BookList as _BookList
from libprs500.devices import strftime as _strftime from calibre.devices import strftime as _strftime
from libprs500.devices import strptime from calibre.devices import strptime
strftime = functools.partial(_strftime, zone=time.localtime) strftime = functools.partial(_strftime, zone=time.localtime)

View File

@ -6,11 +6,11 @@ Device driver for the SONY PRS-505
import sys, os, shutil, time, subprocess, re import sys, os, shutil, time, subprocess, re
from itertools import cycle from itertools import cycle
from libprs500.devices.interface import Device from calibre.devices.interface import Device
from libprs500.devices.errors import DeviceError, FreeSpaceError from calibre.devices.errors import DeviceError, FreeSpaceError
from libprs500.devices.prs505.books import BookList, fix_ids from calibre.devices.prs505.books import BookList, fix_ids
from libprs500 import iswindows, islinux, isosx, __appname__ from calibre import iswindows, islinux, isosx, __appname__
from libprs500.devices.errors import PathError from calibre.devices.errors import PathError
class File(object): class File(object):
def __init__(self, path): def __init__(self, path):

View File

@ -7,8 +7,8 @@ manner.
import sys import sys
from libprs500 import iswindows, isosx from calibre import iswindows, isosx
from libprs500.devices import libusb from calibre.devices import libusb
osx_scanner = None osx_scanner = None
try: try:

View File

@ -83,11 +83,11 @@ __version__ = "3.0.5"
__copyright__ = "Copyright (c) 2004-2007 Leonard Richardson" __copyright__ = "Copyright (c) 2004-2007 Leonard Richardson"
__license__ = "New-style BSD" __license__ = "New-style BSD"
from libprs500.ebooks.sgmllib import SGMLParser, SGMLParseError from calibre.ebooks.sgmllib import SGMLParser, SGMLParseError
import codecs import codecs
import types import types
import re import re
import libprs500.ebooks.sgmllib as sgmllib import calibre.ebooks.sgmllib as sgmllib
from htmlentitydefs import name2codepoint from htmlentitydefs import name2codepoint
#This hack makes Beautiful Soup able to parse XML with namespaces #This hack makes Beautiful Soup able to parse XML with namespaces
@ -1639,7 +1639,7 @@ class SimplifyingSOAPParser(BeautifulSOAP):
# Autodetects character encodings. # Autodetects character encodings.
# Download from http://chardet.feedparser.org/ # Download from http://chardet.feedparser.org/
import libprs500.ebooks.chardet as chardet import calibre.ebooks.chardet as chardet
class UnicodeDammit: class UnicodeDammit:
"""A class for detecting the encoding of a *ML document and """A class for detecting the encoding of a *ML document and

View File

@ -14,4 +14,4 @@ class UnknownFormatError(Exception):
BOOK_EXTENSIONS = ['lrf', 'lrx', 'rar', 'zip', 'rtf', 'lit', 'txt', 'htm', 'xhtm', BOOK_EXTENSIONS = ['lrf', 'lrx', 'rar', 'zip', 'rtf', 'lit', 'txt', 'htm', 'xhtm',
'html', 'xhtml', 'epub', 'pdf', 'prc', 'mobi', 'azw', 'html', 'xhtml', 'epub', 'pdf', 'prc', 'mobi', 'azw',
'epub'] 'epub', 'fb2']

View File

@ -12,12 +12,12 @@ from uuid import uuid4
from ttfquery import describe, findsystem from ttfquery import describe, findsystem
from fontTools.ttLib import TTLibError from fontTools.ttLib import TTLibError
from libprs500.ebooks.lrf.pylrs.pylrs import Book as _Book from calibre.ebooks.lrf.pylrs.pylrs import Book as _Book
from libprs500.ebooks.lrf.pylrs.pylrs import TextBlock, Header, PutObj, \ from calibre.ebooks.lrf.pylrs.pylrs import TextBlock, Header, PutObj, \
Paragraph, TextStyle, BlockStyle Paragraph, TextStyle, BlockStyle
from libprs500.ebooks.lrf.fonts import FONT_FILE_MAP from calibre.ebooks.lrf.fonts import FONT_FILE_MAP
from libprs500.ebooks import ConversionError from calibre.ebooks import ConversionError
from libprs500 import __appname__, __version__, __author__, iswindows, OptionParser from calibre import __appname__, __version__, __author__, iswindows, OptionParser
__docformat__ = "epytext" __docformat__ = "epytext"

View File

@ -4,16 +4,17 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import sys, os, logging, shutil, tempfile, glob import sys, os, logging, shutil, tempfile, glob
from libprs500.ebooks import UnknownFormatError from calibre.ebooks import UnknownFormatError
from libprs500.ebooks.lrf import option_parser as _option_parser from calibre.ebooks.lrf import option_parser as _option_parser
from libprs500 import __appname__, setup_cli_handlers, extract from calibre import __appname__, setup_cli_handlers, extract
from libprs500.ebooks.lrf.lit.convert_from import process_file as lit2lrf from calibre.ebooks.lrf.lit.convert_from import process_file as lit2lrf
from libprs500.ebooks.lrf.pdf.convert_from import process_file as pdf2lrf from calibre.ebooks.lrf.pdf.convert_from import process_file as pdf2lrf
from libprs500.ebooks.lrf.rtf.convert_from import process_file as rtf2lrf from calibre.ebooks.lrf.rtf.convert_from import process_file as rtf2lrf
from libprs500.ebooks.lrf.txt.convert_from import process_file as txt2lrf from calibre.ebooks.lrf.txt.convert_from import process_file as txt2lrf
from libprs500.ebooks.lrf.html.convert_from import process_file as html2lrf from calibre.ebooks.lrf.html.convert_from import process_file as html2lrf
from libprs500.ebooks.lrf.epub.convert_from import process_file as epub2lrf from calibre.ebooks.lrf.epub.convert_from import process_file as epub2lrf
from libprs500.ebooks.lrf.mobi.convert_from import process_file as mobi2lrf 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): def largest_file(files):
maxsize, file = 0, None maxsize, file = 0, None
@ -126,6 +127,8 @@ def process_file(path, options, logger=None):
convertor = epub2lrf convertor = epub2lrf
elif ext in ['mobi', 'prc']: elif ext in ['mobi', 'prc']:
convertor = mobi2lrf convertor = mobi2lrf
elif ext == 'fb2':
convertor = fb22lrf
if not convertor: if not convertor:
raise UnknownFormatError('Coverting from %s to LRF is not supported.'%ext) raise UnknownFormatError('Coverting from %s to LRF is not supported.'%ext)
convertor(path, options, logger) convertor(path, options, logger)

View File

@ -3,13 +3,13 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import os, sys, shutil, logging import os, sys, shutil, logging
from tempfile import mkdtemp from tempfile import mkdtemp
from libprs500.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks.lrf import option_parser as lrf_option_parser
from libprs500.ebooks import ConversionError from calibre.ebooks import ConversionError
from libprs500.ebooks.lrf.html.convert_from import process_file as html_process_file from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file
from libprs500.ebooks.metadata.opf import OPF from calibre.ebooks.metadata.opf import OPF
from libprs500.ebooks.metadata.epub import OCFDirReader from calibre.ebooks.metadata.epub import OCFDirReader
from libprs500.libunzip import extract as zip_extract from calibre.libunzip import extract as zip_extract
from libprs500 import __appname__, setup_cli_handlers from calibre import __appname__, setup_cli_handlers
def option_parser(): def option_parser():

View File

@ -0,0 +1,91 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Anatoly Shipitsin <norguhtar at gmail.com>'
"""
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())

View File

@ -0,0 +1,328 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fb="http://www.gribuser.ru/xml/fictionbook/2.0">
<!--
#########################################################################
# #
# #
# copyright 2002 Paul Henry Tremblay #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
# General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA #
# 02111-1307 USA #
# #
# #
#########################################################################
-->
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:key name="note-link" match="fb:section" use="@id"/>
<xsl:template match="/*">
<html>
<head>
<xsl:if test="fb:description/fb:title-info/fb:lang = 'ru'">
<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
</xsl:if>
<title>
<xsl:value-of select="fb:description/fb:title-info/fb:book-title"/>
</title>
<style type="text/x-oeb1-css">
A { color : #0002CC }
A:HOVER { color : #BF0000 }
BODY { background-color : #FEFEFE; color : #000000; font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; text-align : justify }
H1{ font-size : 160%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Black; background-color : #E7E7E7; margin-left : 0px; page-break-before : always; }
H2{ font-size : 130%; font-style : normal; font-weight : bold; text-align : left; background-color : #EEEEEE; border : 1px solid Gray; page-break-before : always; }
H3{ font-size : 110%; font-style : normal; font-weight : bold; text-align : left; background-color : #F1F1F1; border : 1px solid Silver;}
H4{ font-size : 100%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
H5{ font-size : 100%; font-style : italic; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
H6{ font-size : 100%; font-style : italic; font-weight : normal; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
SMALL{ font-size : 80% }
BLOCKQUOTE{ margin-left :4em; margin-top:1em; margin-right:0.2em;}
HR{ color : Black }
UL{margin-left: 0}
.epigraph{width:50%; margin-left : 35%;}
</style>
</head>
<body>
<xsl:for-each select="fb:description/fb:title-info/fb:annotation">
<div>
<xsl:call-template name="annotation"/>
</div>
<hr/>
</xsl:for-each>
<!-- BUILD TOC -->
<ul>
<xsl:apply-templates select="fb:body" mode="toc"/>
</ul>
<hr/>
<!-- BUILD BOOK -->
<xsl:for-each select="fb:body">
<xsl:if test="position()!=1">
<hr/>
</xsl:if>
<xsl:if test="@name">
<h4 align="center">
<xsl:value-of select="@name"/>
</h4>
</xsl:if>
<!-- <xsl:apply-templates /> -->
<xsl:apply-templates/>
</xsl:for-each>
</body>
</html>
</xsl:template>
<!-- author template -->
<xsl:template name="author">
<xsl:value-of select="fb:first-name"/>
<xsl:text disable-output-escaping="no">&#032;</xsl:text>
<xsl:value-of select="fb:middle-name"/>&#032;
<xsl:text disable-output-escaping="no">&#032;</xsl:text>
<xsl:value-of select="fb:last-name"/>
<br/>
</xsl:template>
<!-- secuence template -->
<xsl:template name="sequence">
<LI/>
<xsl:value-of select="@name"/>
<xsl:if test="@number">
<xsl:text disable-output-escaping="no">,&#032;#</xsl:text>
<xsl:value-of select="@number"/>
</xsl:if>
<xsl:if test="fb:sequence">
<ul>
<xsl:for-each select="fb:sequence">
<xsl:call-template name="sequence"/>
</xsl:for-each>
</ul>
</xsl:if>
<!-- <br/> -->
</xsl:template>
<!-- toc template -->
<xsl:template match="fb:section|fb:body" mode="toc">
<xsl:choose>
<xsl:when test="name()='body' and position()=1 and not(fb:title)">
<xsl:apply-templates select="fb:section" mode="toc"/>
</xsl:when>
<xsl:otherwise>
<li>
<a href="#TOC_{generate-id()}"><xsl:value-of select="normalize-space(fb:title/fb:p[1] | @name)"/></a>
<xsl:if test="fb:section">
<ul><xsl:apply-templates select="fb:section" mode="toc"/></ul>
</xsl:if>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- description -->
<xsl:template match="fb:description">
<xsl:apply-templates/>
</xsl:template>
<!-- body -->
<xsl:template match="fb:body">
<div><xsl:apply-templates/></div>
</xsl:template>
<xsl:template match="fb:section">
<a name="TOC_{generate-id()}"></a>
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
<!-- section/title -->
<xsl:template match="fb:section/fb:title|fb:poem/fb:title">
<xsl:choose>
<xsl:when test="count(ancestor::node()) &lt; 9">
<xsl:element name="{concat('h',count(ancestor::node())-3)}">
<a name="TOC_{generate-id()}"></a>
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="h6">
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<xsl:apply-templates/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- section/title -->
<xsl:template match="fb:body/fb:title">
<h1><xsl:apply-templates mode="title"/></h1>
</xsl:template>
<xsl:template match="fb:title/fb:p">
<xsl:apply-templates/><xsl:text disable-output-escaping="no">&#032;</xsl:text><br/>
</xsl:template>
<!-- subtitle -->
<xsl:template match="fb:subtitle">
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<h5>
<xsl:apply-templates/>
</h5>
</xsl:template>
<!-- p -->
<xsl:template match="fb:p">
<div align="justify"><xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if> &#160;&#160;&#160;<xsl:apply-templates/></div>
</xsl:template>
<!-- strong -->
<xsl:template match="fb:strong">
<b><xsl:apply-templates/></b>
</xsl:template>
<!-- emphasis -->
<xsl:template match="fb:emphasis">
<i> <xsl:apply-templates/></i>
</xsl:template>
<!-- style -->
<xsl:template match="fb:style">
<span class="{@name}"><xsl:apply-templates/></span>
</xsl:template>
<!-- empty-line -->
<xsl:template match="fb:empty-line">
<br/>
</xsl:template>
<!-- link -->
<xsl:template match="fb:a">
<xsl:element name="a">
<xsl:attribute name="href"><xsl:value-of select="@xlink:href"/></xsl:attribute>
<xsl:attribute name="title">
<xsl:choose>
<xsl:when test="starts-with(@xlink:href,'#')"><xsl:value-of select="key('note-link',substring-after(@xlink:href,'#'))/fb:p"/></xsl:when>
<xsl:otherwise><xsl:value-of select="key('note-link',@xlink:href)/fb:p"/></xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:choose>
<xsl:when test="(@type) = 'note'">
<sup>
<xsl:apply-templates/>
</sup>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
<!-- annotation -->
<xsl:template name="annotation">
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<h3>Annotation</h3>
<xsl:apply-templates/>
</xsl:template>
<!-- epigraph -->
<xsl:template match="fb:epigraph">
<blockquote class="epigraph">
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<xsl:apply-templates/>
</blockquote>
</xsl:template>
<!-- epigraph/text-author -->
<xsl:template match="fb:epigraph/fb:text-author">
<blockquote>
<i><xsl:apply-templates/></i>
</blockquote>
</xsl:template>
<!-- cite -->
<xsl:template match="fb:cite">
<blockquote>
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<xsl:apply-templates/>
</blockquote>
</xsl:template>
<!-- cite/text-author -->
<xsl:template match="fb:text-author">
<blockquote>
<i> <xsl:apply-templates/></i></blockquote>
</xsl:template>
<!-- date -->
<xsl:template match="fb:date">
<xsl:choose>
<xsl:when test="not(@value)">
&#160;&#160;&#160;<xsl:apply-templates/>
<br/>
</xsl:when>
<xsl:otherwise>
&#160;&#160;&#160;<xsl:value-of select="@value"/>
<br/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- poem -->
<xsl:template match="fb:poem">
<blockquote>
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<xsl:apply-templates/>
</blockquote>
</xsl:template>
<!-- stanza -->
<xsl:template match="fb:stanza">
<xsl:apply-templates/>
<br/>
</xsl:template>
<!-- v -->
<xsl:template match="fb:v">
<xsl:if test="@id">
<xsl:element name="a">
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
</xsl:element>
</xsl:if>
<xsl:apply-templates/><br/>
</xsl:template>
<!-- image -->
<xsl:template match="fb:image">
<div align="center">
<img border="1">
<xsl:choose>
<xsl:when test="starts-with(@xlink:href,'#')">
<xsl:attribute name="src"><xsl:value-of select="substring-after(@xlink:href,'#')"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="src"><xsl:value-of select="@xlink:href"/></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</img>
</div>
</xsl:template>
</xsl:stylesheet>

View File

@ -4,12 +4,12 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
''' '''
Convert web feeds to LRF files. Convert web feeds to LRF files.
''' '''
from libprs500.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks.lrf import option_parser as lrf_option_parser
from libprs500.ebooks.lrf.html.convert_from import process_file from calibre.ebooks.lrf.html.convert_from import process_file
from libprs500.web.feeds.main import option_parser as feeds_option_parser from calibre.web.feeds.main import option_parser as feeds_option_parser
from libprs500.web.feeds.main import run_recipe from calibre.web.feeds.main import run_recipe
from libprs500.ptempfile import PersistentTemporaryDirectory from calibre.ptempfile import PersistentTemporaryDirectory
from libprs500 import sanitize_file_name from calibre import sanitize_file_name
import sys, os, time import sys, os, time

View File

@ -1,8 +1,8 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import sys, os import sys, os
from libprs500 import iswindows from calibre import iswindows
from libprs500.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
try: try:
from PIL import ImageFont from PIL import ImageFont
@ -12,7 +12,7 @@ except ImportError:
''' '''
Default fonts used in the PRS500 Default fonts used in the PRS500
''' '''
from libprs500.ebooks.lrf.fonts.prs500 import tt0003m_, tt0011m_, tt0419m_ from calibre.ebooks.lrf.fonts.prs500 import tt0003m_, tt0011m_, tt0419m_
FONT_MAP = { FONT_MAP = {
'Swis721 BT Roman' : tt0003m_, 'Swis721 BT Roman' : tt0003m_,

View File

@ -18,23 +18,23 @@ try:
except ImportError: except ImportError:
import Image as PILImage import Image as PILImage
from libprs500.ebooks.BeautifulSoup import BeautifulSoup, Comment, Tag, \ from calibre.ebooks.BeautifulSoup import BeautifulSoup, Comment, Tag, \
NavigableString, Declaration, ProcessingInstruction NavigableString, Declaration, ProcessingInstruction
from libprs500.ebooks.lrf.pylrs.pylrs import Paragraph, CR, Italic, ImageStream, \ from calibre.ebooks.lrf.pylrs.pylrs import Paragraph, CR, Italic, ImageStream, \
TextBlock, ImageBlock, JumpButton, CharButton, \ TextBlock, ImageBlock, JumpButton, CharButton, \
Plot, Image, BlockSpace, RuledLine, BookSetting, Canvas, DropCaps, \ Plot, Image, BlockSpace, RuledLine, BookSetting, Canvas, DropCaps, \
LrsError, Sup, Sub, EmpLine LrsError, Sup, Sub, EmpLine
from libprs500.ebooks.lrf.pylrs.pylrs import Span from calibre.ebooks.lrf.pylrs.pylrs import Span
from libprs500.ebooks.lrf import Book, entity_to_unicode from calibre.ebooks.lrf import Book, entity_to_unicode
from libprs500.ebooks.lrf import option_parser as lrf_option_parser from calibre.ebooks.lrf import option_parser as lrf_option_parser
from libprs500.ebooks import ConversionError from calibre.ebooks import ConversionError
from libprs500.ebooks.lrf.html.table import Table from calibre.ebooks.lrf.html.table import Table
from libprs500 import filename_to_utf8, setup_cli_handlers, __appname__, fit_image from calibre import filename_to_utf8, setup_cli_handlers, __appname__, fit_image
from libprs500.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from libprs500.ebooks.metadata.opf import OPFReader from calibre.ebooks.metadata.opf import OPFReader
from libprs500.devices.interface import Device from calibre.devices.interface import Device
from libprs500.ebooks.lrf.html.color_map import lrs_color from calibre.ebooks.lrf.html.color_map import lrs_color
from libprs500.ebooks.chardet import xml_to_unicode from calibre.ebooks.chardet import xml_to_unicode
def update_css(ncss, ocss): def update_css(ncss, ocss):
for key in ncss.keys(): for key in ncss.keys():
@ -334,10 +334,15 @@ class HTMLConverter(object):
self.book.set_author(self.get_text(a)) self.book.set_author(self.get_text(a))
if self.verbose: if self.verbose:
tdir = tempfile.gettempdir() tdir = tempfile.gettempdir()
if not os.path.exists(tdir):
os.makedirs(tdir)
try:
dump = open(os.path.join(tdir, 'html2lrf-verbose.html'), 'wb') dump = open(os.path.join(tdir, 'html2lrf-verbose.html'), 'wb')
dump.write(unicode(soup).encode('utf-8')) dump.write(unicode(soup).encode('utf-8'))
self.logger.info(_('Written preprocessed HTML to ')+dump.name) self.logger.info(_('Written preprocessed HTML to ')+dump.name)
dump.close() dump.close()
except:
pass
return soup return soup

Some files were not shown because too many files have changed in this diff Show More