mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Improved API documentation in User Manual
This commit is contained in:
parent
3c4f91204b
commit
5f70956b86
@ -262,7 +262,7 @@ 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')
|
||||
@ -272,21 +272,11 @@ class CatalogPlugin(Plugin):
|
||||
#: help = (_('Title of generated catalog. \nDefault:') + " '" +
|
||||
#: '%default' + "'"))]
|
||||
#: 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 '
|
||||
|
@ -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',
|
||||
@ -280,14 +276,12 @@ class OutputFormatPlugin(Plugin):
|
||||
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.
|
||||
|
||||
:param opts: Conversion options. Guaranteed to have attributes
|
||||
corresponding to the OptionRecommendations of this plugin.
|
||||
|
||||
:param log: The logger. Print debug/info messages etc. using this.
|
||||
|
||||
'''
|
||||
raise NotImplementedError
|
||||
|
||||
|
@ -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
|
||||
#: 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)``.
|
||||
|
||||
'''
|
||||
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)
|
||||
|
||||
'''
|
||||
|
||||
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
|
||||
: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
|
||||
: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
|
||||
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.
|
||||
:names: A list of file names that the books should have
|
||||
:param names: A list of file names that the books should have
|
||||
once uploaded to the device. len(names) == len(files)
|
||||
: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.
|
||||
: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 :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()
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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."
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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']:
|
||||
|
Loading…
x
Reference in New Issue
Block a user