Improved API documentation in User Manual

This commit is contained in:
Kovid Goyal 2010-07-25 15:43:24 -06:00
parent 3c4f91204b
commit 5f70956b86
11 changed files with 290 additions and 411 deletions

View File

@ -262,31 +262,21 @@ class CatalogPlugin(Plugin):
type = _('Catalog generator')
#: CLI parser options specific to this plugin, declared as namedtuple Option
#: CLI parser options specific to this plugin, declared as namedtuple Option::
#:
#: from collections import namedtuple
#: Option = namedtuple('Option', 'option, default, dest, help')
#: cli_options = [Option('--catalog-title',
#: from collections import namedtuple
#: Option = namedtuple('Option', 'option, default, dest, help')
#: cli_options = [Option('--catalog-title',
#: default = 'My Catalog',
#: dest = 'catalog_title',
#: help = (_('Title of generated catalog. \nDefault:') + " '" +
#: '%default' + "'"))]
#: cli_options parsed in library.cli:catalog_option_parser()
#: cli_options parsed in library.cli:catalog_option_parser()
cli_options = []
def search_sort_db(self, db, opts):
'''
# Don't add Catalogs to the generated Catalogs
cat = _('Catalog')
if opts.search_text:
opts.search_text += ' not tag:'+cat
else:
opts.search_text = 'not tag:'+cat
'''
db.search(opts.search_text)
if opts.sort_by:
@ -349,8 +339,7 @@ class CatalogPlugin(Plugin):
It should generate the catalog in the format specified
in file_types, returning the absolute path to the
generated catalog file. If an error is encountered
it should raise an Exception and return None. The default
implementation simply returns None.
it should raise an Exception.
The generated catalog file should be created with the
:meth:`temporary_file` method.
@ -358,9 +347,6 @@ class CatalogPlugin(Plugin):
:param path_to_output: Absolute path to the generated catalog file.
:param opts: A dictionary of keyword arguments
:param db: A LibraryDatabase2 object
:return: None
'''
# Default implementation does nothing
raise NotImplementedError('CatalogPlugin.generate_catalog() default '

View File

@ -28,7 +28,7 @@ class ConversionOption(object):
def validate_parameters(self):
'''
Validate the parameters passed to :method:`__init__`.
Validate the parameters passed to :meth:`__init__`.
'''
if re.match(r'[a-zA-Z_]([a-zA-Z0-9_])*', self.name) is None:
raise ValueError(self.name + ' is not a valid Python identifier')
@ -96,7 +96,7 @@ class InputFormatPlugin(Plugin):
InputFormatPlugins are responsible for converting a document into
HTML+OPF+CSS+etc.
The results of the conversion *must* be encoded in UTF-8.
The main action happens in :method:`convert`.
The main action happens in :meth:`convert`.
'''
type = _('Conversion Input')
@ -109,7 +109,7 @@ class InputFormatPlugin(Plugin):
#: If True, this input plugin generates a collection of images,
#: one per HTML file. You can obtain access to the images via
#: convenience method, :method:`get_image_collection`.
#: convenience method, :meth:`get_image_collection`.
is_image_collection = False
#: If set to True, the input plugin will perform special processing
@ -117,7 +117,7 @@ class InputFormatPlugin(Plugin):
for_viewer = False
#: Options shared by all Input format plugins. Do not override
#: in sub-classes. Use :member:`options` instead. Every option must be an
#: in sub-classes. Use :attr:`options` instead. Every option must be an
#: instance of :class:`OptionRecommendation`.
common_options = set([
OptionRecommendation(name='input_encoding',
@ -173,7 +173,6 @@ class InputFormatPlugin(Plugin):
returns.
:param stream: A file like object that contains the input file.
:param options: Options to customize the conversion process.
Guaranteed to have attributes corresponding
to all the options declared by this plugin. In
@ -182,14 +181,11 @@ class InputFormatPlugin(Plugin):
mean be more verbose. Another useful attribute is
``input_profile`` that is an instance of
:class:`calibre.customize.profiles.InputProfile`.
:param file_ext: The extension (without the .) of the input file. It
is guaranteed to be one of the `file_types` supported
by this plugin.
:param log: A :class:`calibre.utils.logging.Log` object. All output
should use this object.
:param accelarators: A dictionary of various information that the input
plugin can get easily that would speed up the
subsequent stages of the conversion.
@ -235,7 +231,7 @@ class OutputFormatPlugin(Plugin):
(OPF+HTML) into an output ebook.
The OEB document can be assumed to be encoded in UTF-8.
The main action happens in :method:`convert`.
The main action happens in :meth:`convert`.
'''
type = _('Conversion Output')
@ -247,7 +243,7 @@ class OutputFormatPlugin(Plugin):
file_type = None
#: Options shared by all Input format plugins. Do not override
#: in sub-classes. Use :member:`options` instead. Every option must be an
#: in sub-classes. Use :attr:`options` instead. Every option must be an
#: instance of :class:`OptionRecommendation`.
common_options = set([
OptionRecommendation(name='pretty_print',
@ -277,17 +273,15 @@ class OutputFormatPlugin(Plugin):
:class:`calibre.ebooks.oeb.OEBBook` to the file specified by output.
:param output: Either a file like object or a string. If it is a string
it is the path to a directory that may or may not exist. The output
plugin should write its output into that directory. If it is a file like
object, the output plugin should write its output into the file.
it is the path to a directory that may or may not exist. The output
plugin should write its output into that directory. If it is a file like
object, the output plugin should write its output into the file.
:param input_plugin: The input plugin that was used at the beginning of
the conversion pipeline.
the conversion pipeline.
:param opts: Conversion options. Guaranteed to have attributes
corresponding to the OptionRecommendations of this plugin.
corresponding to the OptionRecommendations of this plugin.
:param log: The logger. Print debug/info messages etc. using this.
'''
raise NotImplementedError

View File

@ -1,10 +1,5 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
"""
Define the minimum interface that a device backend must satisfy to be used in
the GUI. A device backend must subclass the L{Device} class. See prs500.py for
a backend that implement the Device interface for the SONY PRS500 Reader.
"""
import os
from collections import namedtuple
@ -15,32 +10,38 @@ class DevicePlugin(Plugin):
"""
Defines the interface that should be implemented by backends that
communicate with an ebook reader.
The C{end_session} variables are used for USB session management. Sometimes
the front-end needs to call several methods one after another, in which case
the USB session should not be closed after each method call.
"""
type = _('Device Interface')
# Ordered list of supported formats
#: Ordered list of supported formats
FORMATS = ["lrf", "rtf", "pdf", "txt"]
#: VENDOR_ID can be either an integer, a list of integers or a dictionary
#: If it is a dictionary, it must be a dictionary of dictionaries, of the form
#: {
#: integer_vendor_id : { product_id : [list of BCDs], ... },
#: ...
#: }
#: If it is a dictionary, it must be a dictionary of dictionaries,
#: of the form::
#:
#: {
#: integer_vendor_id : { product_id : [list of BCDs], ... },
#: ...
#: }
#:
VENDOR_ID = 0x0000
#: An integer or a list of integers
PRODUCT_ID = 0x0000
# BCD can be either None to not distinguish between devices based on BCD, or
# it can be a list of the BCD numbers of all devices supported by this driver.
#: BCD can be either None to not distinguish between devices based on BCD, or
#: it can be a list of the BCD numbers of all devices supported by this driver.
BCD = None
THUMBNAIL_HEIGHT = 68 # Height for thumbnails on device
# Whether the metadata on books can be set via the GUI.
#: Height for thumbnails on the device
THUMBNAIL_HEIGHT = 68
#: Whether the metadata on books can be set via the GUI.
CAN_SET_METADATA = True
#: Path separator for paths to books on device
path_sep = os.sep
#: Icon for this device
icon = I('reader.svg')
@ -121,6 +122,7 @@ class DevicePlugin(Plugin):
Return True, device_info if a device handled by this plugin is currently connected.
:param devices_on_system: List of devices currently connected
'''
if iswindows:
return self.is_usb_connected_windows(devices_on_system,
@ -157,13 +159,14 @@ class DevicePlugin(Plugin):
def reset(self, key='-1', log_packets=False, report_progress=None,
detected_device=None) :
"""
:key: The key to unlock the device
:log_packets: If true the packet stream to/from the device is logged
:report_progress: Function that is called with a % progress
:param key: The key to unlock the device
:param log_packets: If true the packet stream to/from the device is logged
:param report_progress: Function that is called with a % progress
(number between 0 and 100) for various tasks
If it is called with -1 that means that the
task does not have any progress information
:detected_device: Device information from the device scanner
:param detected_device: Device information from the device scanner
"""
raise NotImplementedError()
@ -174,19 +177,21 @@ class DevicePlugin(Plugin):
is only called after the vendor, product ids and the bcd have matched, so
it can do some relatively time intensive checks. The default implementation
returns True. This method is called only on windows. See also
:method:`can_handle`.
:meth:`can_handle`.
:param device_info: On windows a device ID string. On Unix a tuple of
``(vendor_id, product_id, bcd)``.
``(vendor_id, product_id, bcd)``.
'''
return True
def can_handle(self, device_info, debug=False):
'''
Unix version of :method:`can_handle_windows`
Unix version of :meth:`can_handle_windows`
:param device_info: Is a tupe of (vid, pid, bcd, manufacturer, product,
serial number)
serial number)
'''
return True
@ -198,7 +203,8 @@ class DevicePlugin(Plugin):
For example: For devices that present themselves as USB Mass storage
devices, this method would be responsible for mounting the device or
if the device has been automounted, for finding out where it has been
mounted. The base class within USBMS device.py has a implementation of
mounted. The method :meth:`calibre.devices.usbms.device.Device.open` has
an implementation of
this function that should serve as a good example for USB Mass storage
devices.
'''
@ -219,17 +225,20 @@ class DevicePlugin(Plugin):
def set_progress_reporter(self, report_progress):
'''
@param report_progress: Function that is called with a % progress
:param report_progress: Function that is called with a % progress
(number between 0 and 100) for various tasks
If it is called with -1 that means that the
task does not have any progress information
'''
raise NotImplementedError()
def get_device_information(self, end_session=True):
"""
Ask device for device information. See L{DeviceInfoQuery}.
@return: (device name, device version, software version on device, mime type)
:return: (device name, device version, software version on device, mime type)
"""
raise NotImplementedError()
@ -252,8 +261,9 @@ class DevicePlugin(Plugin):
2. Memory Card A
3. Memory Card B
@return: A 3 element list with total space in bytes of (1, 2, 3). If a
particular device doesn't have any of these locations it should return 0.
:return: A 3 element list with total space in bytes of (1, 2, 3). If a
particular device doesn't have any of these locations it should return 0.
"""
raise NotImplementedError()
@ -264,19 +274,23 @@ class DevicePlugin(Plugin):
2. Card A
3. Card B
@return: A 3 element list with free space in bytes of (1, 2, 3). If a
particular device doesn't have any of these locations it should return -1.
:return: A 3 element list with free space in bytes of (1, 2, 3). If a
particular device doesn't have any of these locations it should return -1.
"""
raise NotImplementedError()
def books(self, oncard=None, end_session=True):
"""
Return a list of ebooks on the device.
@param oncard: If 'carda' or 'cardb' return a list of ebooks on the
:param oncard: If 'carda' or 'cardb' return a list of ebooks on the
specific storage card, otherwise return list of ebooks
in main memory of device. If a card is specified and no
books are on the card return empty list.
@return: A BookList.
:return: A BookList.
"""
raise NotImplementedError()
@ -285,25 +299,27 @@ class DevicePlugin(Plugin):
'''
Upload a list of books to the device. If a file already
exists on the device, it should be replaced.
This method should raise a L{FreeSpaceError} if there is not enough
This method should raise a :class:`FreeSpaceError` if there is not enough
free space on the device. The text of the FreeSpaceError must contain the
word "card" if C{on_card} is not None otherwise it must contain the word "memory".
:files: A list of paths and/or file-like objects. If they are paths and
the paths point to temporary files, they may have an additional
attribute, original_file_path pointing to the originals. They may have
another optional attribute, deleted_after_upload which if True means
that the file pointed to by original_file_path will be deleted after
being uploaded to the device.
:names: A list of file names that the books should have
once uploaded to the device. len(names) == len(files)
word "card" if ``on_card`` is not None otherwise it must contain the word "memory".
:param files: A list of paths and/or file-like objects. If they are paths and
the paths point to temporary files, they may have an additional
attribute, original_file_path pointing to the originals. They may have
another optional attribute, deleted_after_upload which if True means
that the file pointed to by original_file_path will be deleted after
being uploaded to the device.
:param names: A list of file names that the books should have
once uploaded to the device. len(names) == len(files)
:param metadata: If not None, it is a list of :class:`MetaInformation` objects.
The idea is to use the metadata to determine where on the device to
put the book. len(metadata) == len(files). Apart from the regular
cover (path to cover), there may also be a thumbnail attribute, which should
be used in preference. The thumbnail attribute is of the form
(width, height, cover_data as jpeg).
:return: A list of 3-element tuples. The list is meant to be passed
to L{add_books_to_metadata}.
:metadata: If not None, it is a list of :class:`MetaInformation` objects.
The idea is to use the metadata to determine where on the device to
put the book. len(metadata) == len(files). Apart from the regular
cover (path to cover), there may also be a thumbnail attribute, which should
be used in preference. The thumbnail attribute is of the form
(width, height, cover_data as jpeg).
to :meth:`add_books_to_metadata`.
'''
raise NotImplementedError()
@ -312,12 +328,15 @@ class DevicePlugin(Plugin):
'''
Add locations to the booklists. This function must not communicate with
the device.
@param locations: Result of a call to L{upload_books}
@param metadata: List of MetaInformation objects, same as for
:method:`upload_books`.
@param booklists: A tuple containing the result of calls to
(L{books}(oncard=None), L{books}(oncard='carda'),
L{books}(oncard='cardb')).
:param locations: Result of a call to L{upload_books}
:param metadata: List of :class:`MetaInformation` objects, same as for
:meth:`upload_books`.
:param booklists: A tuple containing the result of calls to
(:meth:`books(oncard=None)`,
:meth:`books(oncard='carda')`,
:meth`books(oncard='cardb')`).
'''
raise NotImplementedError
@ -332,26 +351,35 @@ class DevicePlugin(Plugin):
'''
Remove books from the metadata list. This function must not communicate
with the device.
@param paths: paths to books on the device.
@param booklists: A tuple containing the result of calls to
(L{books}(oncard=None), L{books}(oncard='carda'),
L{books}(oncard='cardb')).
:param paths: paths to books on the device.
:param booklists: A tuple containing the result of calls to
(:meth:`books(oncard=None)`,
:meth:`books(oncard='carda')`,
:meth`books(oncard='cardb')`).
'''
raise NotImplementedError()
def sync_booklists(self, booklists, end_session=True):
'''
Update metadata on device.
@param booklists: A tuple containing the result of calls to
(L{books}(oncard=None), L{books}(oncard='carda'),
L{books}(oncard='cardb')).
:param booklists: A tuple containing the result of calls to
(:meth:`books(oncard=None)`,
:meth:`books(oncard='carda')`,
:meth`books(oncard='cardb')`).
'''
raise NotImplementedError()
def get_file(self, path, outfile, end_session=True):
'''
Read the file at C{path} on the device and write it to outfile.
@param outfile: file object like C{sys.stdout} or the result of an C{open} call
Read the file at ``path`` on the device and write it to outfile.
:param outfile: file object like ``sys.stdout`` or the result of an
:func:`open` call.
'''
raise NotImplementedError()
@ -365,8 +393,8 @@ class DevicePlugin(Plugin):
@classmethod
def save_settings(cls, settings_widget):
'''
Should save settings to disk. Takes the widget created in config_widget
and saves all settings to disk.
Should save settings to disk. Takes the widget created in
:meth:`config_widget` and saves all settings to disk.
'''
raise NotImplementedError()
@ -381,16 +409,18 @@ class DevicePlugin(Plugin):
class BookList(list):
'''
A list of books. Each Book object must have the fields:
1. title
2. authors
3. size (file size of the book)
4. datetime (a UTC time tuple)
5. path (path on the device to the book)
6. thumbnail (can be None) thumbnail is either a str/bytes object with the
A list of books. Each Book object must have the fields
#. title
#. authors
#. size (file size of the book)
#. datetime (a UTC time tuple)
#. path (path on the device to the book)
#. thumbnail (can be None) thumbnail is either a str/bytes object with the
image data or it should have an attribute image_path that stores an
absolute (platform native) path to the image
7. tags (a list of strings, can be empty).
#. tags (a list of strings, can be empty).
'''
__getslice__ = None
@ -427,6 +457,7 @@ class BookList(list):
created from series, in which case series_index is used.
:param collection_attributes: A list of attributes of the Book object
'''
raise NotImplementedError()

View File

@ -47,8 +47,8 @@ class Device(DeviceConfig, DevicePlugin):
'''
This class provides logic common to all drivers for devices that export themselves
as USB Mass Storage devices. If you are writing such a driver, inherit from this
class.
as USB Mass Storage devices. Provides implementations for mounting/ejecting
of USBMS devices on all platforms.
'''
VENDOR_ID = 0x0
@ -57,9 +57,19 @@ class Device(DeviceConfig, DevicePlugin):
VENDOR_NAME = None
# These can be None, string, list of strings or compiled regex
#: String identifying the main memory of the device in the windows PnP id
#: strings
#: This can be None, string, list of strings or compiled regex
WINDOWS_MAIN_MEM = None
#: String identifying the first card of the device in the windows PnP id
#: strings
#: This can be None, string, list of strings or compiled regex
WINDOWS_CARD_A_MEM = None
#: String identifying the second card of the device in the windows PnP id
#: strings
#: This can be None, string, list of strings or compiled regex
WINDOWS_CARD_B_MEM = None
# The following are used by the check_ioreg_line method and can be either:
@ -68,9 +78,9 @@ class Device(DeviceConfig, DevicePlugin):
OSX_CARD_A_MEM = None
OSX_CARD_B_MEM = None
# Used by the new driver detection to disambiguate main memory from
# storage cards. Should be a regular expression that matches the
# main memory mount point assigned by OS X
#: Used by the new driver detection to disambiguate main memory from
#: storage cards. Should be a regular expression that matches the
#: main memory mount point assigned by OS X
OSX_MAIN_MEM_VOL_PAT = None
OSX_EJECT_COMMAND = ['diskutil', 'eject']
@ -780,7 +790,7 @@ class Device(DeviceConfig, DevicePlugin):
def filename_callback(self, default, mi):
'''
Callback to allow drivers to change the default file name
set by :method:`create_upload_path`.
set by :meth:`create_upload_path`.
'''
return default

View File

@ -33,6 +33,10 @@ def debug_print(*args):
# CLI must come before Device as it implements the CLI functions that
# are inherited from the device interface in Device.
class USBMS(CLI, Device):
'''
The base class for all USBMS devices. Implements the logic for
sending/getting/updating metadata/caching metadata/etc.
'''
description = _('Communicate with an eBook reader.')
author = _('John Schember')
@ -195,10 +199,13 @@ class USBMS(CLI, Device):
def upload_cover(self, path, filename, metadata):
'''
:path: the full path were the associated book is located.
:filename: the name of the book file without the extension.
:metadata: metadata belonging to the book. Use metadata.thumbnail
for cover
Upload book cover to the device. Default implementation does nothing.
:param path: the full path were the associated book is located.
:param filename: the name of the book file without the extension.
:param metadata: metadata belonging to the book. Use metadata.thumbnail
for cover
'''
pass

View File

@ -15,6 +15,22 @@ from calibre.ebooks.metadata.library_thing import check_for_cover
metadata_config = None
class MetadataSource(Plugin): # {{{
'''
Represents a source to query for metadata. Subclasses must implement
at least the fetch method.
When :meth:`fetch` is called, the `self` object will have the following
useful attributes (each of which may be None)::
title, book_author, publisher, isbn, log, verbose and extra
Use these attributes to construct the search query. extra is reserved for
future use.
The fetch method must store the results in `self.results` as a list of
:class:`MetaInformation` objects. If there is an error, it should be stored
in `self.exception` and `self.tb` (for the traceback).
'''
author = 'Kovid Goyal'

View File

@ -25,7 +25,7 @@ clean:
html:
mkdir -p .build/html .build/doctrees
$(SPHINXBUILD) -b custom $(ALLSPHINXOPTS) .build/html
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .build/html
@echo
@echo "Build finished. The HTML pages are in .build/html."

View File

@ -3,17 +3,13 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import sys, os, inspect, re, textwrap
import sys, os, re, textwrap
sys.path.insert(0, os.path.abspath('../../'))
sys.extensions_location = '../plugins'
sys.resources_location = '../../../resources'
from sphinx.util import rpartition
from sphinx.util.console import bold
from sphinx.ext.autodoc import prepare_docstring
from docutils.statemachine import ViewList
from docutils import nodes
sys.path.append(os.path.abspath('../../../'))
from calibre.linux import entry_points
@ -244,61 +240,9 @@ def cli_docs(app):
raw += '\n'+'\n'.join(lines)
update_cli_doc(os.path.join('cli', cmd+'.rst'), raw, info)
def auto_member(dirname, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
name = arguments[0]
env = state.document.settings.env
mod_cls, obj = rpartition(name, '.')
if not mod_cls and hasattr(env, 'autodoc_current_class'):
mod_cls = env.autodoc_current_class
if not mod_cls:
mod_cls = env.currclass
mod, cls = rpartition(mod_cls, '.')
if not mod and hasattr(env, 'autodoc_current_module'):
mod = env.autodoc_current_module
if not mod:
mod = env.currmodule
module = __import__(mod, None, None, ['foo'])
cls = getattr(module, cls)
lines = inspect.getsourcelines(cls)[0]
comment_lines = []
for i, line in enumerate(lines):
if re.search(r'%s\s*=\s*\S+'%obj, line) and not line.strip().startswith('#:'):
for j in range(i-1, 0, -1):
raw = lines[j].strip()
if not raw.startswith('#:'):
break
comment_lines.append(raw[2:])
break
comment_lines.reverse()
docstring = '\n'.join(comment_lines)
if module is not None and docstring is not None:
docstring = docstring.decode('utf-8')
result = ViewList()
result.append('.. attribute:: %s.%s'%(cls.__name__, obj), '<autodoc>')
result.append('', '<autodoc>')
docstring = prepare_docstring(docstring)
for i, line in enumerate(docstring):
result.append(' ' + line, '<docstring of %s>' % name, i)
result.append('', '')
result.append(' **Default**: ``%s``'%repr(getattr(cls, obj, None)), '<default memeber value>')
result.append('', '')
node = nodes.paragraph()
state.nested_parse(result, content_offset, node)
return list(node)
def setup(app):
app.add_config_value('epub_cover', None, False)
app.add_builder(EPUBHelpBuilder)
app.add_directive('automember', auto_member, 1, (1, 0, 1))
app.connect('doctree-read', substitute)
app.connect('builder-inited', cli_docs)
app.connect('build-finished', finished)

View File

@ -6,145 +6,12 @@ API Documentation for recipes
===============================
.. module:: calibre.web.feeds.news
:synopsis: Defines various abstract base classes that can be subclassed to create powerful news fetching recipes.
:synopsis: The API for writing recipes is defined by the :class:`BasicNewsRecipe`
Defines various abstract base classes that can be subclassed to create powerful news fetching recipes. The useful
subclasses are:
The API for writing recipes is defined by the :class:`BasicNewsRecipe`
.. contents::
:depth: 1
:local:
BasicNewsRecipe
-----------------
.. class:: BasicNewsRecipe
Abstract base class that contains a number of members and methods to customize the fetching of contents in your recipes. All
recipes must inherit from this class or a subclass of it.
The members and methods are organized as follows:
.. contents::
:depth: 1
:local:
Customizing e-book download
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automember:: BasicNewsRecipe.title
.. automember:: BasicNewsRecipe.description
.. automember:: BasicNewsRecipe.__author__
.. automember:: BasicNewsRecipe.max_articles_per_feed
.. automember:: BasicNewsRecipe.oldest_article
.. automember:: BasicNewsRecipe.recursions
.. automember:: BasicNewsRecipe.delay
.. automember:: BasicNewsRecipe.simultaneous_downloads
.. automember:: BasicNewsRecipe.timeout
.. automember:: BasicNewsRecipe.timefmt
.. automember:: BasicNewsRecipe.conversion_options
.. automember:: BasicNewsRecipe.feeds
.. automember:: BasicNewsRecipe.no_stylesheets
.. automember:: BasicNewsRecipe.encoding
.. automethod:: BasicNewsRecipe.get_browser
.. automethod:: BasicNewsRecipe.get_cover_url
.. automethod:: BasicNewsRecipe.get_feeds
.. automethod:: BasicNewsRecipe.parse_index
Customizing feed parsing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automember:: BasicNewsRecipe.summary_length
.. automember:: BasicNewsRecipe.use_embedded_content
.. automethod:: BasicNewsRecipe.get_article_url
.. automethod:: BasicNewsRecipe.print_version
.. automethod:: BasicNewsRecipe.parse_feeds
Pre/post processing of downloaded HTML
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automember:: BasicNewsRecipe.extra_css
.. automember:: BasicNewsRecipe.match_regexps
.. automember:: BasicNewsRecipe.filter_regexps
.. automember:: BasicNewsRecipe.remove_tags
.. automember:: BasicNewsRecipe.remove_tags_after
.. automember:: BasicNewsRecipe.remove_tags_before
.. automember:: BasicNewsRecipe.remove_attributes
.. automember:: BasicNewsRecipe.keep_only_tags
.. automember:: BasicNewsRecipe.preprocess_regexps
.. automember:: BasicNewsRecipe.template_css
.. automember:: BasicNewsRecipe.remove_javascript
.. automethod:: BasicNewsRecipe.skip_ad_pages
.. automethod:: BasicNewsRecipe.preprocess_html
.. automethod:: BasicNewsRecipe.postprocess_html
.. automethod:: BasicNewsRecipe.populate_article_metadata
Convenience methods
~~~~~~~~~~~~~~~~~~~~~~~
.. automethod:: BasicNewsRecipe.cleanup
.. automethod:: BasicNewsRecipe.index_to_soup
.. automethod:: BasicNewsRecipe.sort_index_by
.. automethod:: BasicNewsRecipe.tag_to_string
Miscellaneous
~~~~~~~~~~~~~~~~~~
.. automember:: BasicNewsRecipe.requires_version
CustomIndexRecipe
---------------------
.. class:: CustomIndexRecipe
This class is useful for getting content from websites that don't follow the "multiple articles in several feeds" content model.
.. automethod:: CustomIndexRecipe.custom_index
.. autoclass:: BasicNewsRecipe
:members:
:member-order: groupwise

View File

@ -5,7 +5,7 @@
API Documentation for plugins
===============================
.. module:: calibre.customize.__init__
.. module:: calibre.customize
:synopsis: Defines various abstract base classes that can be subclassed to create plugins.
Defines various abstract base classes that can be subclassed to create powerful plugins. The useful
@ -20,113 +20,136 @@ classes are:
Plugin
-----------------
.. class:: Plugin
Abstract base class that contains a number of members and methods to create your plugin. All
plugins must inherit from this class or a subclass of it.
The members and methods are:
.. automember:: Plugin.name
.. automember:: Plugin.author
.. automember:: Plugin.description
.. automember:: Plugin.version
.. automember:: Plugin.supported_platforms
.. automember:: Plugin.priority
.. automember:: Plugin.minimum_calibre_version
.. automember:: Plugin.can_be_disabled
.. automethod:: Plugin.initialize
.. automethod:: Plugin.customization_help
.. automethod:: Plugin.temporary_file
.. autoclass:: Plugin
:members:
:member-order: bysource
.. _pluginsFTPlugin:
FileTypePlugin
-----------------
.. class:: Plugin
Abstract base class that contains a number of members and methods to create your file type plugin. All file type
plugins must inherit from this class or a subclass of it.
The members and methods are:
.. automember:: FileTypePlugin.file_types
.. automember:: FileTypePlugin.on_import
.. automember:: FileTypePlugin.on_preprocess
.. automember:: FileTypePlugin.on_postprocess
.. automethod:: FileTypePlugin.run
.. autoclass:: FileTypePlugin
:show-inheritance:
:members:
:member-order: bysource
.. _pluginsMetadataPlugin:
Metadata plugins
-------------------
.. class:: MetadataReaderPlugin
Abstract base class that contains a number of members and methods to create your metadata reader plugin. All metadata
reader plugins must inherit from this class or a subclass of it.
The members and methods are:
.. automember:: MetadataReaderPlugin.file_types
.. automethod:: MetadataReaderPlugin.get_metadata
.. autoclass:: MetadataReaderPlugin
:show-inheritance:
:members:
:member-order: bysource
.. class:: MetadataWriterPlugin
Abstract base class that contains a number of members and methods to create your metadata writer plugin. All metadata
writer plugins must inherit from this class or a subclass of it.
The members and methods are:
.. automember:: MetadataWriterPlugin.file_types
.. automethod:: MetadataWriterPlugin.set_metadata
.. autoclass:: MetadataWriterPlugin
:show-inheritance:
:members:
:member-order: bysource
.. _pluginsMetadataSource:
Catalog plugins
----------------
.. autoclass:: CatalogPlugin
:show-inheritance:
:members:
:member-order: bysource
Metadata download plugins
--------------------------
.. class:: calibre.ebooks.metadata.fetch.MetadataSource
.. module:: calibre.ebooks.metadata.fetch
Represents a source to query for metadata. Subclasses must implement
at least the fetch method.
.. autoclass:: MetadataSource
:show-inheritance:
:members:
:member-order: bysource
When :meth:`fetch` is called, the `self` object will have the following
useful attributes (each of which may be None)::
Conversion plugins
--------------------
title, book_author, publisher, isbn, log, verbose and extra
.. module:: calibre.customize.conversion
Use these attributes to construct the search query. extra is reserved for
future use.
.. autoclass:: InputFormatPlugin
:show-inheritance:
:members:
:member-order: bysource
The fetch method must store the results in `self.results` as a list of
:class:`MetaInformation` objects. If there is an error, it should be stored
in `self.exception` and `self.tb` (for the traceback).
.. autoclass:: OutputFormatPlugin
:show-inheritance:
:members:
:member-order: bysource
.. automember:: calibre.ebooks.metadata.fetch.MetadataSource.metadata_type
Device Drivers
-----------------
.. automember:: calibre.ebooks.metadata.fetch.MetadataSource.string_customization_help
.. module:: calibre.devices.interface
.. automethod:: calibre.ebooks.metadata.fetch.MetadataSource.fetch
The base class for all device drivers is :class:`DevicePlugin`. However, if your device exposes itself as a USBMS drive to the operating system, you should use the USBMS class instead as it implements all the logic needed to support these kinds of devices.
.. autoclass:: DevicePlugin
:show-inheritance:
:members:
:member-order: bysource
.. autoclass:: BookList
:show-inheritance:
:members:
:member-order: bysource
USB Mass Storage based devices
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The base class for such devices is :class:`calibre.devices.usbms.driver.USBMS`. This class in turn inherits some of its functionality from its bases, documented below. A typical basic USBMS based driver looks like this:
.. code-block:: python
from calibre.devices.usbms.driver import USBMS
class PDNOVEL(USBMS):
name = 'Pandigital Novel device interface'
gui_name = 'PD Novel'
description = _('Communicate with the Pandigital Novel')
author = 'Kovid Goyal'
supported_platforms = ['windows', 'linux', 'osx']
FORMATS = ['epub', 'pdf']
VENDOR_ID = [0x18d1]
PRODUCT_ID = [0xb004]
BCD = [0x224]
VENDOR_NAME = 'ANDROID'
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '__UMS_COMPOSITE'
THUMBNAIL_HEIGHT = 144
EBOOK_DIR_MAIN = 'eBooks'
SUPPORTS_SUB_DIRS = False
def upload_cover(self, path, filename, metadata):
coverdata = getattr(metadata, 'thumbnail', None)
if coverdata and coverdata[2]:
with open('%s.jpg' % os.path.join(path, filename), 'wb') as coverfile:
coverfile.write(coverdata[2])
.. autoclass:: calibre.devices.usbms.device.Device
:show-inheritance:
:members:
:member-order: bysource
.. autoclass:: calibre.devices.usbms.cli.CLI
:members:
:member-order: bysource
.. autoclass:: calibre.devices.usbms.driver.USBMS
:show-inheritance:
:members:
:member-order: bysource

View File

@ -37,7 +37,10 @@ class DownloadDenied(ValueError):
class BasicNewsRecipe(Recipe):
'''
Abstract base class that contains logic needed in all feed fetchers.
Base class that contains logic needed in all recipes. By overriding
progressively more of the functionality in this class, you can make
progressively more customized/powerful recipes. For a tutorial introduction
to creating recipes, see :doc:`news`.
'''
#: The title to use for the ebook
@ -127,7 +130,7 @@ class BasicNewsRecipe(Recipe):
#: embedded content.
use_embedded_content = None
#: Set to True and implement :method:`get_obfuscated_article` to handle
#: Set to True and implement :meth:`get_obfuscated_article` to handle
#: websites that try to make it difficult to scrape content.
articles_are_obfuscated = False
@ -147,7 +150,7 @@ class BasicNewsRecipe(Recipe):
#: If True empty feeds are removed from the output.
#: This option has no effect if parse_index is overriden in
#: the sub class. It is meant only for recipes that return a list
#: of feeds using `feeds` or :method:`get_feeds`.
#: of feeds using `feeds` or :meth:`get_feeds`.
remove_empty_feeds = False
#: List of regular expressions that determines which links to follow
@ -538,8 +541,7 @@ class BasicNewsRecipe(Recipe):
HTML fetching engine, so it can contain links to pages/images on the web.
This method is typically useful for sites that try to make it difficult to
access article content automatically. See for example the
:module:`calibre.web.recipes.iht` recipe.
access article content automatically.
'''
raise NotImplementedError
@ -700,8 +702,7 @@ class BasicNewsRecipe(Recipe):
Download and pre-process all articles from the feeds in this recipe.
This method should be called only once on a particular Recipe instance.
Calling it more than once will lead to undefined behavior.
@return: Path to index.html
@rtype: string
:return: Path to index.html
'''
try:
res = self.build_index()
@ -1359,7 +1360,7 @@ class BasicNewsRecipe(Recipe):
'''
If your recipe when converted to EPUB has problems with images when
viewed in Adobe Digital Editions, call this method from within
:method:`postprocess_html`.
:meth:`postprocess_html`.
'''
for item in soup.findAll('img'):
for attrib in ['height','width','border','align','style']: