diff options
author | Patrick Totzke <patricktotzke@gmail.com> | 2012-02-11 11:28:32 +0000 |
---|---|---|
committer | Patrick Totzke <patricktotzke@gmail.com> | 2012-02-11 11:28:32 +0000 |
commit | ccb576780e37da9c29e08c6aea901d561f298ee0 (patch) | |
tree | 20541d5dc1a36549058dee16c3576432142714b8 /docs/source/api | |
parent | c3561539399dc70021045ac57ed31c9b46e8df78 (diff) |
joined and cleaned up user/api docs
Diffstat (limited to 'docs/source/api')
-rw-r--r-- | docs/source/api/accounts.rst | 5 | ||||
-rw-r--r-- | docs/source/api/commands.rst | 80 | ||||
-rw-r--r-- | docs/source/api/conf.py | 255 | ||||
-rw-r--r-- | docs/source/api/contributing.rst | 23 | ||||
-rw-r--r-- | docs/source/api/database.rst | 55 | ||||
-rw-r--r-- | docs/source/api/index.rst | 15 | ||||
-rw-r--r-- | docs/source/api/interface.rst | 110 | ||||
-rw-r--r-- | docs/source/api/overview.rst | 19 | ||||
-rw-r--r-- | docs/source/api/settings.rst | 55 | ||||
-rw-r--r-- | docs/source/api/utils.rst | 7 |
10 files changed, 624 insertions, 0 deletions
diff --git a/docs/source/api/accounts.rst b/docs/source/api/accounts.rst new file mode 100644 index 00000000..c09b43fa --- /dev/null +++ b/docs/source/api/accounts.rst @@ -0,0 +1,5 @@ +Accounts +======== + +.. automodule:: alot.account + :members: diff --git a/docs/source/api/commands.rst b/docs/source/api/commands.rst new file mode 100644 index 00000000..f38ac04c --- /dev/null +++ b/docs/source/api/commands.rst @@ -0,0 +1,80 @@ +Commands +========= + +.. module:: alot.commands + +User actions are represented by :class:`Command` objects that can then be triggered by +:meth:`alot.ui.UI.apply_command`. +Commandline strings given by the user via the prompt or keybindings can be translated to +:class:`Command` objects using :func:`alot.commands.commandfactory`. +Specific actions are defined as subclasses of :class:`Command` and can be registered +to a global command pool using the :class:`registerCommand` decorator. + +.. Note:: + + that the return value + of :func:`commandfactory` depends on the current *mode* the user interface is in. + The mode identifier is a string that is uniquely defined by the currently focussed + :class:`~alot.buffers.Buffer`. + +.. note:: + + The names of the commands available to the user in any given mode do not correspond + one-to-one to these subclasses. You can register a Command multiple times under different + names, with different forced constructor parameters and so on. See for instance the + definition of BufferFocusCommand in 'commands/globals.py':: + + @registerCommand(MODE, 'bprevious', forced={'offset': -1}, + help='focus previous buffer') + @registerCommand(MODE, 'bnext', forced={'offset': +1}, + help='focus next buffer') + class BufferFocusCommand(Command): + def __init__(self, buffer=None, offset=0, **kwargs): + ... + +.. autoclass:: Command + :members: + +.. autoclass:: CommandParseError +.. autoclass:: CommandArgumentParser +.. autofunction:: commandfactory +.. autofunction:: lookup_command +.. autofunction:: lookup_parser +.. autoclass:: registerCommand + + +Globals +-------- + +.. automodule:: alot.commands.globals + :members: + +Envelope +-------- + +.. automodule:: alot.commands.envelope + :members: + +Bufferlist +---------- + +.. automodule:: alot.commands.bufferlist + :members: + +Search +-------- + +.. automodule:: alot.commands.search + :members: + +Taglist +-------- + +.. automodule:: alot.commands.taglist + :members: + +Thread +-------- + +.. automodule:: alot.commands.thread + :members: diff --git a/docs/source/api/conf.py b/docs/source/api/conf.py new file mode 100644 index 00000000..0c36a73f --- /dev/null +++ b/docs/source/api/conf.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# +# alot documentation build configuration file, created by +# sphinx-quickstart on Tue Aug 9 15:00:51 2011. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +############################### +# readthedocs.org hack, +# needed to use autodocs on their build-servers: +# http://readthedocs.org/docs/read-the-docs/en/latest/faq.html?highlight=autodocs#where-do-i-need-to-put-my-docs-for-rtd-to-find-it + +class Mock(object): + def __init__(self, *args, **kwargs): + pass + + def __call__(self, *args, **kwargs): + return Mock() + + @classmethod + def __getattr__(self, name): + return Mock() if name not in ('__file__', '__path__') else '/dev/null' + +MOCK_MODULES = ['notmuch', 'notmuch.globals', + 'twisted', 'twisted.internet', + 'twisted.internet.defer', + 'twisted.python', + 'twisted.python.failure', + 'urwid', + 'magic', + 'argparse'] +for mod_name in MOCK_MODULES: + sys.modules[mod_name] = Mock() + +# end of readthedocs.org hack +############################## + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('..')) +from alot import __version__,__author__ + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'alot' +copyright = u'2011 ' + __author__ + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = __version__ +# The full version, including alpha/beta/rc tags. +release = __version__ + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'alotdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'alot.tex', u'alot Documentation', + u'Patrick Totzke', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'alot', u'alot Documentation', + [u'Patrick Totzke'], 1) +] + +autodoc_member_order = 'bysource' +autoclass_content = 'both' +intersphinx_mapping = { + 'python': ('http://docs.python.org/3.2', None), + 'notmuch': ('http://packages.python.org/notmuch', None), + 'urwid': ('http://urwid.readthedocs.org/en/latest', None), + } diff --git a/docs/source/api/contributing.rst b/docs/source/api/contributing.rst new file mode 100644 index 00000000..c5770aca --- /dev/null +++ b/docs/source/api/contributing.rst @@ -0,0 +1,23 @@ +Contributing +============ + +Development is coordinated entirely via the projects `github page <https://github.com/pazz/alot>`_ +especially the `issue tracker <https://github.com/pazz/alot/issues>`_. +Current HEAD can be found in branch `testing` from `git@github.com:pazz/alot.git`. + +You can send patches to notmuch's mailing list but pull requests on github are preferred. +Here are a few more things you should know and check before you send pull requests: + +* Follow :pep:`8`. This means in particular a maximum linewidth of *79* and no trailing + white spaces. If in doubt, use an `automatic tool <http://pypi.python.org/pypi/pep8>`_ + to verify your code. + +* Document! Needless to say, we want readable and well documented code. Moreover, + + * use `sphinx directives <http://sphinx.pocoo.org/rest.html>`_ to document + the parameters and return values of your methods so that we maintain up-to-date API docs. + * Make sure your patch doesn't break the API docs. The build service at `readthedocs.org <http:alot.rtfd.org>`_ + is fragile when it comes to new import statements in our code. + * If you implemented a new feature, update the user manual in :file:`/docs/user` accordingly. + + diff --git a/docs/source/api/database.rst b/docs/source/api/database.rst new file mode 100644 index 00000000..00334a4b --- /dev/null +++ b/docs/source/api/database.rst @@ -0,0 +1,55 @@ +Email Database +============== + +.. module:: alot.db + +The python bindings to libnotmuch define :class:`notmuch.Thread` and +:class:`notmuch.Message`, which unfortunately are very fragile. +Alot defines the wrapper classes :class:`Thread` and :class:`~alot.message.Message` that +use an :class:`DBManager` instance to transparently provide persistent objects. + +:class:`~alot.message.Message` moreover contains convenience methods +to extract information about the message like reformated header values, a summary, +decoded and interpreted body text and a list of :class:`Attachments <alot.message.Attachment>`. + +The central :class:`~alot.ui.UI` instance carries around a :class:`DBManager` object that +is used for any lookups or modifications of the email base. :class:`DBManager` can +directly look up :class:`Thread` and :class:`~alot.message.Message` objects and is able to +postpone/cache/retry writing operations in case the Xapian index is locked by another +process. + + +Database Manager +----------------- +.. autoclass:: DBManager + :members: + + +Exceptions +---------- +.. autoclass:: DatabaseError + :members: +.. autoclass:: DatabaseROError + :members: +.. autoclass:: DatabaseLockedError + :members: + +Wrapper +------- +.. autoclass:: Thread + :members: + +.. module:: alot.message + +.. autoclass:: Message + :members: + + +Other Structures +--------------------------- + +.. autoclass:: Attachment + :members: + +.. autoclass:: Envelope + :members: diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst new file mode 100644 index 00000000..35b4fd7c --- /dev/null +++ b/docs/source/api/index.rst @@ -0,0 +1,15 @@ +API and Development +******************* + +.. module:: alot +.. toctree:: + :maxdepth: 1 + + overview + contributing + database + interface + settings + accounts + utils + commands diff --git a/docs/source/api/interface.rst b/docs/source/api/interface.rst new file mode 100644 index 00000000..0df9d7ca --- /dev/null +++ b/docs/source/api/interface.rst @@ -0,0 +1,110 @@ +User Interface +================== + +Alot sets up a widget tree and an :class:`mainloop <urwid.main_loop.TwistedEventLoop>` +in the constructor of :class:`alot.ui.UI`. The visible area is +a :class:`urwid.Frame`, where the footer is used as a status line and the body part +displays the currently active :class:`alot.buffers.Buffer`. + +To be able to bind keystrokes and translate them to :class:`Commands +<alot.commands.Command>`, keypresses are *not* propagated down the widget tree as is +customary in urwid. Instead, the root widget given to urwids mainloop is a custom wrapper +(:class:`alot.ui.Inputwrap`) that interprets key presses. A dedicated +:class:`~alot.commands.globals.SendKeypressCommand` can be used to trigger +key presses to the wrapped root widget and thereby accessing standard urwid +behaviour. + +In order to keep the interface non-blocking, alot makes use of twisted's deferred_ - a +framework that makes it easy to deal with callbacks. Many commands in alot make use of +`inline callbacks`_, which allow you to treat deferred-returning functions almost like +syncronous functions. Consider the following example of a function that prompts for some +input and acts on it: + +.. _deferred: http://twistedmatrix.com/documents/current/core/howto/defer.html +.. _`inline callbacks`: http://twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#inlineCallbacks + +.. code-block:: python + + from twisted.internet import defer + + @defer.inlineCallbacks + def greet(ui): # ui is instance of alot.ui.UI + name = yield ui.prompt(prefix='pls enter your name>') + ui.notify('your name is: ' + name) + + +:class:`UI` - the main component +----------------------------------- + +.. module:: alot.ui +.. autoclass:: UI + + .. autoattribute:: buffers + .. autoattribute:: current_buffer + .. autoattribute:: dbman + .. autoattribute:: accountman + + .. automethod:: apply_command + .. automethod:: prompt + .. automethod:: choice + .. automethod:: notify + .. automethod:: clear_notify + .. automethod:: buffer_open + .. automethod:: buffer_focus + .. automethod:: buffer_close + .. automethod:: get_buffers_of_type + .. automethod:: exit + + +Buffers +---------- + +A buffer defines a view to your data. It knows how to render itself, to interpret +keypresses and is visible in the "body" part of the widget frame. +Different modes are defined by subclasses of the following base class. + +.. autoclass:: alot.buffers.Buffer + :members: + +Available modes are: + +========== ======================================== + Mode Buffer Subclass +========== ======================================== +search :class:`~alot.buffers.SearchBuffer` +thread :class:`~alot.buffers.ThreadBuffer` +bufferlist :class:`~alot.buffers.BufferlistBuffer` +taglist :class:`~alot.buffers.TagListBuffer` +envelope :class:`~alot.buffers.EnvelopeBuffer` +========== ======================================== + +.. automodule:: alot.buffers + :members: BufferlistBuffer, EnvelopeBuffer,SearchBuffer,ThreadBuffer,TagListBuffer + +Widgets +-------- +What follows is a list of the non-standard urwid widgets used in alot. +Some of them respect :doc:`user settings <settings>`, themes in particular. + +.. automodule:: alot.widgets + :members: + +Completion +---------- + +:meth:`alot.ui.UI.prompt` allows tab completion using a :class:`~alot.completion.Completer` +object handed as 'completer' parameter. :mod:`alot.completion` defines several +subclasses for different occasions like completing email addresses from an +:class:`~alot.account.AddressBook`, notmuch tagstrings. Some of these actually build on top +of each other; the :class:`~alot.completion.QueryCompleter` for example uses a +:class:`~alot.completion.TagsCompleter` internally to allow tagstring completion after +"is:" or "tag:" keywords when typing a notmuch querystring. + +All these classes overide the method :class:`~alot.completion.Completer.complete`, which +for a given string and cursor position in that string returns +a list of tuples `(completed_string, new_cursor_position)` that are taken to be +the completed values. Note that `completed_string` does not need to have the original +string as prefix. + +.. automodule:: alot.completion + :members: diff --git a/docs/source/api/overview.rst b/docs/source/api/overview.rst new file mode 100644 index 00000000..051eacaa --- /dev/null +++ b/docs/source/api/overview.rst @@ -0,0 +1,19 @@ +Overview +======== + +The main component is :class:`alot.ui.UI`, which provides methods for user input and notifications, +sets up an :mod:`urwid` :class:`mainloop <urwid.main_loop.TwistedEventLoop>` and widget tree and +maintains the list of active buffers. Moreover, it integrates different "managers" responsible for +core functionalities: + +* a :class:`~db.DBManager` to access the email database +* an :class:`~account.AccountManager` to deal with user accounts +* a :class:`~settings.AlotConfigParser` (subclasses :class:`configparser.ConfigParser`) for user settings + +Every user action, triggered either by keybindings or as input to the commandprompt, is +given as commandline string that gets :func:`translated <commands.commandfactory>` +to a :class:`~commands.Command` which is then :meth:`applied <ui.UI.apply_command>`. +Different actions are defined as a subclasses of :class:`~commands.Command`, which live +in `alot/commands/MODE.py`, where MODE is the name of the mode (:class:`Buffer` type) they +are used in. + diff --git a/docs/source/api/settings.rst b/docs/source/api/settings.rst new file mode 100644 index 00000000..f7272756 --- /dev/null +++ b/docs/source/api/settings.rst @@ -0,0 +1,55 @@ +Accessing User Settings +======================= + +.. module:: alot.settings + +There are four types of user settings: notmuchs and alot's config +files, the hooks-file for user provided python code and the mailcap, +defining shellcomands as handlers for files of certain mime types. + +Alot sets up :class:`FallbackConfigParser` objects to access the configs +of alot and notmuch`. +Hooks can be accessed via :meth:`AlotConfigParser.get_hook` +and MIME handlers can be looked up using :func:`alot.settings.get_mime_handler`. + ++----------------+-----------------------------------+------------------------------+ +| What | accessible via | Type | ++================+===================================+==============================+ +| alot config | :obj:`alot.settings.config` | :class:`AlotConfigParser` | ++----------------+-----------------------------------+------------------------------+ +| notmuch config | :obj:`alot.settings.notmuchconfig`| :class:`FallbackConfigParser`| ++----------------+-----------------------------------+------------------------------+ + +Through these objects you can access user settings (or their default values +if unset) in the following manner:: + + from alot.settings import config, notmuchconfig + + # alot config + >>> config.getint('general', 'notify_timeout') + 5 + >>> config.getboolean('general', 'show_statusbar') + True + >>> config.getstringlist('general', 'displayed_headers') + [u'From', u'To', u'Cc', u'Bcc', u'Subject'] + + # notmuch config + >>> notmuchconfig.get('user', 'primary_email') + 'patricktotzke@gmail.com' + >>> notmuchconfig.getboolean('maildir', 'synchronize_flags') + True + +Hooks can be looked up using :meth:`AlotConfigParser.get_hook`. +They are user defined callables that expect to be called with the following parameters: + + :ui: :class:`~alot.ui.UI` -- the initialized main component + :dbm: :class:`~alot.db.DBManager` -- :obj:`ui.dbman` + :aman: :class:`~alot.account.AccountManager` -- :obj:`ui.accountman` + :log: :class:`~logging.Logger` -- :obj:`ui.logger` + :config: :class:`AlotConfigParser` :obj:`alot.settings.config` + +.. autoclass:: FallbackConfigParser + :members: +.. autoclass:: AlotConfigParser + :members: +.. autofunction:: get_mime_handler diff --git a/docs/source/api/utils.rst b/docs/source/api/utils.rst new file mode 100644 index 00000000..8cfae2b7 --- /dev/null +++ b/docs/source/api/utils.rst @@ -0,0 +1,7 @@ +Utils +===== + +.. currentmodule:: alot.helper + +.. automodule:: alot.helper + :members: |