From a2187a86aca91fae73cdb34ebc62d1c86a0726c1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 31 May 2009 10:42:44 -0700 Subject: [PATCH] ... --- src/calibre/constants.py | 8 +- src/calibre/customize/__init__.py | 120 +++++++++++++++--------------- src/calibre/customize/builtins.py | 4 +- src/calibre/customize/ui.py | 3 +- src/calibre/ebooks/mobi/writer.py | 5 +- upload.py | 10 ++- 6 files changed, 79 insertions(+), 71 deletions(-) diff --git a/src/calibre/constants.py b/src/calibre/constants.py index e03d5e5edc..e7f7ffc344 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -2,8 +2,14 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __appname__ = 'calibre' -__version__ = '0.5.14' +__version__ = '0.6.0b1' __author__ = "Kovid Goyal " + +import re +_ver = __version__.split('.') +_ver = [int(re.search(r'(\d+)', x).group(1)) for x in _ver] +numeric_version = tuple(_ver) + ''' Various run time constants. ''' diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index 0e6bad8d2e..deec0fcedf 100644 --- a/src/calibre/customize/__init__.py +++ b/src/calibre/customize/__init__.py @@ -5,58 +5,58 @@ __copyright__ = '2008, Kovid Goyal ' import sys from calibre.ptempfile import PersistentTemporaryFile -from calibre.constants import __version__, __author__ +from calibre.constants import numeric_version class Plugin(object): ''' A calibre plugin. Useful members include: - + * ``self.plugin_path``: Stores path to the zip file that contains this plugin or None if it is a builtin plugin * ``self.site_customization``: Stores a customization string entered by the user. - + Methods that should be overridden in sub classes: - + * :meth:`initialize` * :meth:`customization_help` - + Useful methods: - + * :meth:`temporary_file` - + ''' #: List of platforms this plugin works on #: For example: ``['windows', 'osx', 'linux'] supported_platforms = [] - + #: The name of this plugin name = 'Trivial Plugin' - + #: The version of this plugin as a 3-tuple (major, minor, revision) version = (1, 0, 0) - + #: A short string describing what this plugin does description = _('Does absolutely nothing') - + #: The author of this plugin author = _('Unknown') - + #: When more than one plugin exists for a filetype, #: the plugins are run in order of decreasing priority #: i.e. plugins with higher priority will be run first. #: The highest possible priority is ``sys.maxint``. #: Default pririty is 1. priority = 1 - + #: The earliest version of calibre this plugin requires minimum_calibre_version = (0, 4, 118) - + #: If False, the user will not be able to disable this plugin. Use with #: care. can_be_disabled = True - + #: The type of this plugin. Used for categorizing plugins in the #: GUI type = _('Base') @@ -64,109 +64,109 @@ class Plugin(object): def __init__(self, plugin_path): self.plugin_path = plugin_path self.site_customization = None - + def initialize(self): ''' Called once when calibre plugins are initialized. Plugins are re-initialized every time a new plugin is added. - + Perform any plugin specific initialization here, such as extracting resources from the plugin zip file. The path to the zip file is available as ``self.plugin_path``. - + Note that ``self.site_customization`` is **not** available at this point. ''' pass - + def customization_help(self, gui=False): ''' Return a string giving help on how to customize this plugin. By default raise a :class:`NotImplementedError`, which indicates that the plugin does not require customization. - + If you re-implement this method in your subclass, the user will be asked to enter a string as customization for this plugin. - The customization string will be available as + The customization string will be available as ``self.site_customization``. - + Site customization could be anything, for example, the path to a needed binary on the user's computer. - - :param gui: If True return HTML help, otherwise return plain text help. - + + :param gui: If True return HTML help, otherwise return plain text help. + ''' raise NotImplementedError - + def temporary_file(self, suffix): ''' Return a file-like object that is a temporary file on the file system. This file will remain available even after being closed and will only be removed on interpreter shutdown. Use the ``name`` member of the returned object to access the full path to the created temporary file. - + :param suffix: The suffix that the temporary file will have. ''' return PersistentTemporaryFile(suffix) - + def is_customizable(self): try: self.customization_help() return True except NotImplementedError: return False - + def __enter__(self, *args): if self.plugin_path is not None: sys.path.insert(0, self.plugin_path) - + def __exit__(self, *args): if self.plugin_path in sys.path: sys.path.remove(self.plugin_path) - - + + class FileTypePlugin(Plugin): ''' A plugin that is associated with a particular set of file types. ''' - + #: Set of file types for which this plugin should be run #: For example: ``set(['lit', 'mobi', 'prc'])`` file_types = set([]) - + #: If True, this plugin is run when books are added #: to the database on_import = False - + #: If True, this plugin is run whenever an any2* tool #: is used, on the file passed to the any2* tool. on_preprocess = False - + #: If True, this plugin is run after an any2* tool is #: used, on the final file produced by the tool. on_postprocess = False - + type = _('File type') def run(self, path_to_ebook): ''' Run the plugin. Must be implemented in subclasses. - It should perform whatever modifications are required - on the ebook and return the absolute path to the + It should perform whatever modifications are required + on the ebook and return the absolute path to the modified ebook. If no modifications are needed, it should return the path to the original ebook. If an error is encountered it should raise an Exception. The default implementation simply return the path to the original ebook. - - The modified ebook file should be created with the + + The modified ebook file should be created with the :meth:`temporary_file` method. - + :param path_to_ebook: Absolute path to the ebook. - :return: Absolute path to the modified ebook. + :return: Absolute path to the modified ebook. ''' # Default implementation does nothing return path_to_ebook - + class MetadataReaderPlugin(Plugin): ''' A plugin that implements reading metadata from a set of file types. @@ -174,26 +174,26 @@ class MetadataReaderPlugin(Plugin): #: Set of file types for which this plugin should be run #: For example: ``set(['lit', 'mobi', 'prc'])`` file_types = set([]) - + supported_platforms = ['windows', 'osx', 'linux'] - version = tuple(map(int, (__version__.split('.'))[:3])) + version = numeric_version author = 'Kovid Goyal' - + type = _('Metadata reader') - + def get_metadata(self, stream, type): ''' Return metadata for the file represented by stream (a file like object - that supports reading). Raise an exception when there is an error + that supports reading). Raise an exception when there is an error with the input data. - + :param type: The type of file. Guaranteed to be one of the entries in :attr:`file_types`. - :return: A :class:`calibre.ebooks.metadata.MetaInformation` object + :return: A :class:`calibre.ebooks.metadata.MetaInformation` object ''' return None - + class MetadataWriterPlugin(Plugin): ''' A plugin that implements reading metadata from a set of file types. @@ -201,24 +201,24 @@ class MetadataWriterPlugin(Plugin): #: Set of file types for which this plugin should be run #: For example: ``set(['lit', 'mobi', 'prc'])`` file_types = set([]) - + supported_platforms = ['windows', 'osx', 'linux'] - version = tuple(map(int, (__version__.split('.'))[:3])) + version = numeric_version author = 'Kovid Goyal' - + type = _('Metadata writer') - + def set_metadata(self, stream, mi, type): ''' Set metadata for the file represented by stream (a file like object - that supports reading). Raise an exception when there is an error + that supports reading). Raise an exception when there is an error with the input data. - + :param type: The type of file. Guaranteed to be one of the entries in :attr:`file_types`. - :param mi: A :class:`calibre.ebooks.metadata.MetaInformation` object + :param mi: A :class:`calibre.ebooks.metadata.MetaInformation` object ''' pass - + diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index d107413e38..54fa0e862e 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -5,7 +5,7 @@ import textwrap import os import glob from calibre.customize import FileTypePlugin, MetadataReaderPlugin, MetadataWriterPlugin -from calibre.constants import __version__ +from calibre.constants import numeric_version class HTML2ZIP(FileTypePlugin): name = 'HTML to ZIP' @@ -15,7 +15,7 @@ Follow all local links in an HTML file and create a ZIP \ file containing all linked files. This plugin is run \ every time you add an HTML file to the library.\ ''')) - version = tuple(map(int, (__version__.split('.'))[:3])) + version = numeric_version file_types = set(['html', 'htm', 'xhtml', 'xhtm']) supported_platforms = ['windows', 'osx', 'linux'] on_import = True diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index f6ab19a910..2227f6d6f5 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -9,13 +9,12 @@ from calibre.customize import Plugin, FileTypePlugin, MetadataReaderPlugin, \ from calibre.customize.conversion import InputFormatPlugin, OutputFormatPlugin from calibre.customize.profiles import InputProfile, OutputProfile from calibre.customize.builtins import plugins as builtin_plugins -from calibre.constants import __version__, iswindows, isosx +from calibre.constants import numeric_version as version, iswindows, isosx from calibre.devices.interface import DevicePlugin from calibre.ebooks.metadata import MetaInformation from calibre.utils.config import make_config_dir, Config, ConfigProxy, \ plugin_dir, OptionParser -version = tuple([int(x) for x in __version__.split('.')]) platform = 'linux' if iswindows: diff --git a/src/calibre/ebooks/mobi/writer.py b/src/calibre/ebooks/mobi/writer.py index c525f27937..5b058870bb 100644 --- a/src/calibre/ebooks/mobi/writer.py +++ b/src/calibre/ebooks/mobi/writer.py @@ -653,8 +653,9 @@ class MobiWriter(object): def _generate_end_records(self): self._flis_number = len(self._records) self._records.append( - 'FLIS\0\0\0\x08\0\x41\0\0\0\0\0\0\xff\xff\xff\xff\0\x01\0\x03\0\0\0\x03\0\0\0\x01') - fcis = 'FCIS\x00\x00\x00\x14\x00\x00\x00\x10\x00\x00\x00\x00' + 'FLIS\0\0\0\x08\0\x41\0\0\0\0\0\0\xff\xff\xff\xff\0\x01\0\x03\0\0\0\x03\0\0\0\x01'+ + '\xff'*4) + fcis = 'FCIS\x00\x00\x00\x14\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x00' fcis += pack('>I', self._text_length) fcis += '\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x08\x00\x01\x00\x01\x00\x00\x00\x00' self._fcis_number = len(self._records) diff --git a/upload.py b/upload.py index dd6bb78e89..973e31c8ab 100644 --- a/upload.py +++ b/upload.py @@ -17,6 +17,7 @@ __appname__ = re.search(r'__appname__\s+=\s+[\'"]([^\'"]+)[\'"]', raw).group(1) PREFIX = "/var/www/calibre.kovidgoyal.net" DOWNLOADS = PREFIX+"/htdocs/downloads" +BETAS = DOWNLOADS +'/betas' DOCS = PREFIX+"/htdocs/apidocs" USER_MANUAL = PREFIX+'/htdocs/user_manual' HTML2LRF = "src/calibre/ebooks/lrf/html/demo" @@ -429,8 +430,9 @@ class upload_demo(OptionlessCommand): def run(self): check_call( - '''html2lrf --title='Demonstration of html2lrf' --author='Kovid Goyal' ''' - '''--header --output=/tmp/html2lrf.lrf %s/demo.html ''' + '''ebook-convert %s/demo.html /tmp/html2lrf.lrf ''' + '''--title='Demonstration of html2lrf' --author='Kovid Goyal' ''' + '''--header ''' '''--serif-family "/usr/share/fonts/corefonts, Times New Roman" ''' '''--mono-family "/usr/share/fonts/corefonts, Andale Mono" ''' ''''''%(HTML2LRF,), shell=True) @@ -442,8 +444,8 @@ class upload_demo(OptionlessCommand): check_call('scp /tmp/html-demo.zip divok:%s/'%(DOWNLOADS,), shell=True) check_call( - '''txt2lrf -t 'Demonstration of txt2lrf' -a 'Kovid Goyal' ''' - '''--header -o /tmp/txt2lrf.lrf %s/demo.txt'''%(TXT2LRF,), shell=True) + ("ebook-convert %s/demo.txt /tmp/txt2lrf.lrf -t 'Demonstration of txt2lrf'" + "-a 'Kovid Goyal' --header ")%(TXT2LRF,), shell=True) check_call('cd src/calibre/ebooks/lrf/txt/demo/ && ' 'zip -j /tmp/txt-demo.zip * /tmp/txt2lrf.lrf', shell=True)