diff options
Diffstat (limited to 'docs')
28 files changed, 755 insertions, 402 deletions
diff --git a/docs/_static/pygments.css b/docs/_static/pygments.css deleted file mode 100644 index f04bc738..00000000 --- a/docs/_static/pygments.css +++ /dev/null @@ -1,70 +0,0 @@ -.highlight .hll { background-color: #ffffcc } -.highlight { background: #000000; color: #f6f3e8; } -.highlight .c { color: #7C7C7C; } /* Comment */ -.highlight .err { color: #f6f3e8; } /* Error */ -.highlight .g { color: #f6f3e8; } /* Generic */ -.highlight .k { color: #00ADEE; } /* Keyword */ -.highlight .l { color: #f6f3e8; } /* Literal */ -.highlight .n { color: #f6f3e8; } /* Name */ -.highlight .o { color: #f6f3e8; } /* Operator */ -.highlight .x { color: #f6f3e8; } /* Other */ -.highlight .p { color: #f6f3e8; } /* Punctuation */ -.highlight .cm { color: #7C7C7C; } /* Comment.Multiline */ -.highlight .cp { color: #96CBFE; } /* Comment.Preproc */ -.highlight .c1 { color: #7C7C7C; } /* Comment.Single */ -.highlight .cs { color: #7C7C7C; } /* Comment.Special */ -.highlight .gd { color: #f6f3e8; } /* Generic.Deleted */ -.highlight .ge { color: #f6f3e8; } /* Generic.Emph */ -.highlight .gr { color: #ffffff; background-color: #ff0000 } /* Generic.Error */ -.highlight .gh { color: #f6f3e8; font-weight: bold; } /* Generic.Heading */ -.highlight .gi { color: #f6f3e8; } /* Generic.Inserted */ -.highlight .go { color: #070707; } /* Generic.Output */ -.highlight .gp { color: #f6f3e8; } /* Generic.Prompt */ -.highlight .gs { color: #f6f3e8; } /* Generic.Strong */ -.highlight .gu { color: #f6f3e8; font-weight: bold; } /* Generic.Subheading */ -.highlight .gt { color: #ffffff; font-weight: bold; background-color: #FF6C60 } /* Generic.Traceback */ -.highlight .kc { color: #6699CC; } /* Keyword.Constant */ -.highlight .kd { color: #6699CC; } /* Keyword.Declaration */ -.highlight .kn { color: #6699CC; } /* Keyword.Namespace */ -.highlight .kp { color: #6699CC; } /* Keyword.Pseudo */ -.highlight .kr { color: #6699CC; } /* Keyword.Reserved */ -.highlight .kt { color: #FFFFB6; } /* Keyword.Type */ -.highlight .ld { color: #f6f3e8; } /* Literal.Date */ -.highlight .m { color: #FF73FD; } /* Literal.Number */ -.highlight .s { color: #F46DBA;/*#A8FF60;*/ } /* Literal.String */ -.highlight .na { color: #f6f3e8; } /* Name.Attribute */ -.highlight .nb { color: #f6f3e8; } /* Name.Builtin */ -.highlight .nc { color: #f6f3e8; } /* Name.Class */ -.highlight .no { color: #99CC99; } /* Name.Constant */ -.highlight .nd { color: #f6f3e8; } /* Name.Decorator */ -.highlight .ni { color: #E18964; } /* Name.Entity */ -.highlight .ne { color: #f6f3e8; } /* Name.Exception */ -.highlight .nf { color: #F64DBA; } /* Name.Function */ -.highlight .nl { color: #f6f3e8; } /* Name.Label */ -.highlight .nn { color: #f6f3e8; } /* Name.Namespace */ -.highlight .nx { color: #f6f3e8; } /* Name.Other */ -.highlight .py { color: #f6f3e8; } /* Name.Property */ -.highlight .nt { color: #00ADEE; } /* Name.Tag */ -.highlight .nv { color: #C6C5FE; } /* Name.Variable */ -.highlight .ow { color: #ffffff; } /* Operator.Word */ -.highlight .w { color: #f6f3e8; } /* Text.Whitespace */ -.highlight .mf { color: #FF73FD; } /* Literal.Number.Float */ -.highlight .mh { color: #FF73FD; } /* Literal.Number.Hex */ -.highlight .mi { color: #FF73FD; } /* Literal.Number.Integer */ -.highlight .mo { color: #FF73FD; } /* Literal.Number.Oct */ -.highlight .sb { color: #A8FF60; } /* Literal.String.Backtick */ -.highlight .sc { color: #A8FF60; } /* Literal.String.Char */ -.highlight .sd { color: #A8FF60; } /* Literal.String.Doc */ -.highlight .s2 { color: #A8FF60; } /* Literal.String.Double */ -.highlight .se { color: #A8FF60; } /* Literal.String.Escape */ -.highlight .sh { color: #A8FF60; } /* Literal.String.Heredoc */ -.highlight .si { color: #A8FF60; } /* Literal.String.Interpol */ -.highlight .sx { color: #A8FF60; } /* Literal.String.Other */ -.highlight .sr { color: #A8FF60; } /* Literal.String.Regex */ -.highlight .s1 { color: #A8FF60; } /* Literal.String.Single */ -.highlight .ss { color: #A8FF60; } /* Literal.String.Symbol */ -.highlight .bp { color: #f6f3e8; } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #C6C5FE; } /* Name.Variable.Class */ -.highlight .vg { color: #C6C5FE; } /* Name.Variable.Global */ -.highlight .vi { color: #C6C5FE; } /* Name.Variable.Instance */ -.highlight .il { color: #FF73FD; } /* Literal.Number.Integer.Long */ diff --git a/docs/_templates/defindex.html b/docs/_templates/defindex.html deleted file mode 100644 index ce8d3af6..00000000 --- a/docs/_templates/defindex.html +++ /dev/null @@ -1,35 +0,0 @@ -{# - basic/defindex.html - ~~~~~~~~~~~~~~~~~~~ - - Default template for the "index" page. - - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -#} -{% extends "layout.html" %} -{% set title = _('Overview') %} -{% block body %} - <h1>{{ docstitle|e }}</h1> - <p> - Welcome! This is - {% block description %}the documentation for {{ project|e }} - {{ release|e }}{% if last_updated %}, last updated {{ last_updated|e }}{% endif %}{% endblock %}. - </p> - {% block tables %} - <p><strong>{{ _('Indices and tables:') }}</strong></p> - <table class="contentstable" align="center"><tr> - <td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">{{ _('Complete Table of Contents') }}</a><br> - <span class="linkdescr">{{ _('lists all sections and subsections') }}</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("search") }}">{{ _('Search Page') }}</a><br> - <span class="linkdescr">{{ _('search this documentation') }}</span></p> - </td><td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("modindex") }}">{{ _('Global Module Index') }}</a><br> - <span class="linkdescr">{{ _('quick access to all modules') }}</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">{{ _('General Index') }}</a><br> - <span class="linkdescr">{{ _('all functions, classes, terms') }}</span></p> - </td></tr> - </table> - {% endblock %} -{% endblock %} diff --git a/docs/_templates/indexcontent.html b/docs/_templates/indexcontent.html deleted file mode 100644 index d5e17cd6..00000000 --- a/docs/_templates/indexcontent.html +++ /dev/null @@ -1,61 +0,0 @@ -{% extends "defindex.html" %} -{% block tables %} - <p><strong>Parts of the documentation:</strong></p> - <table class="contentstable" align="center"><tr> - <td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("whatsnew/" + version) }}">What's new in Python {{ version }}?</a><br/> - <span class="linkdescr">or <a href="{{ pathto("whatsnew/index") }}">all "What's new" documents</a> since 2.0</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("tutorial/index") }}">Tutorial</a><br/> - <span class="linkdescr">start here</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("library/index") }}">Library Reference</a><br/> - <span class="linkdescr">keep this under your pillow</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("reference/index") }}">Language Reference</a><br/> - <span class="linkdescr">describes syntax and language elements</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("using/index") }}">Python Setup and Usage</a><br/> - <span class="linkdescr">how to use Python on different platforms</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("howto/index") }}">Python HOWTOs</a><br/> - <span class="linkdescr">in-depth documents on specific topics</span></p> - </td><td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("extending/index") }}">Extending and Embedding</a><br/> - <span class="linkdescr">tutorial for C/C++ programmers</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("c-api/index") }}">Python/C API</a><br/> - <span class="linkdescr">reference for C/C++ programmers</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("install/index") }}">Installing Python Modules</a><br/> - <span class="linkdescr">information for installers & sys-admins</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("distutils/index") }}">Distributing Python Modules</a><br/> - <span class="linkdescr">sharing modules with others</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("documenting/index") }}">Documenting Python</a><br/> - <span class="linkdescr">guide for documentation authors</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("faq/index") }}">FAQs</a><br/> - <span class="linkdescr">frequently asked questions (with answers!)</span></p> - </td></tr> - </table> - - <p><strong>Indices and tables:</strong></p> - <table class="contentstable" align="center"><tr> - <td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("py-modindex") }}">Global Module Index</a><br/> - <span class="linkdescr">quick access to all modules</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">General Index</a><br/> - <span class="linkdescr">all functions, classes, terms</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("glossary") }}">Glossary</a><br/> - <span class="linkdescr">the most important terms explained</span></p> - </td><td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("search") }}">Search page</a><br/> - <span class="linkdescr">search this documentation</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">Complete Table of Contents</a><br/> - <span class="linkdescr">lists all sections and subsections</span></p> - </td></tr> - </table> - - <p><strong>Meta information:</strong></p> - <table class="contentstable" align="center"><tr> - <td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("bugs") }}">Reporting bugs</a></p> - <p class="biglink"><a class="biglink" href="{{ pathto("about") }}">About the documentation</a></p> - </td><td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("license") }}">History and License of Python</a></p> - <p class="biglink"><a class="biglink" href="{{ pathto("copyright") }}">Copyright</a></p> - </td></tr> - </table> -{% endblock %} diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html deleted file mode 100644 index a5dd7c82..00000000 --- a/docs/_templates/layout.html +++ /dev/null @@ -1,69 +0,0 @@ -{# - haiku/layout.html - ~~~~~~~~~~~~~~~~~ - - Sphinx layout template for the haiku theme. - - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -#} -{% extends "basic/layout.html" %} -{% set script_files = script_files + ['_static/theme_extras.js'] %} -{% set css_files = css_files + ['_static/print.css'] %} - -{# do not display relbars #} -{% block relbar1 %}{% endblock %} -{% block relbar2 %}{% endblock %} - -{% macro nav() %} - <p> - {%- block haikurel1 %} - {%- endblock %} - {%- if prev %} - «  <a href="{{ prev.link|e }}">{{ prev.title }}</a> -   ::   - {%- endif %} - <a class="uplink" href="{{ pathto(master_doc) }}">{{ _('Contents') }}</a> - {%- if next %} -   ::   - <a href="{{ next.link|e }}">{{ next.title }}</a>  » - {%- endif %} - {%- block haikurel2 %} - {%- endblock %} - </p> -{% endmacro %} - -{% block content %} - <div class="header"> - {%- block haikuheader %} - {%- if theme_full_logo != "false" %} - <a href="{{ pathto('index') }}"> - <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/> - </a> - {%- else %} - {%- if logo -%} - <img class="rightlogo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/> - {%- endif -%} - <h1 class="heading"> - <a href="{{ pathto('index') }}"><span>{{ project|e }}</span></a> - </h1> - <h2 class="heading"><span>{{ shorttitle|e }}</span></h2> - {%- endif %} - {%- endblock %} - </div> - <div class="topnav"> - {{ nav() }} - </div> - <div class="content"> - {#{%- if display_toc %} - <div id="toc"> - <h3>Table Of Contents</h3> - {{ toc }} - </div> - {%- endif %}#} - {% block body %}{% endblock %} - </div> - <div class="bottomnav"> - {{ nav() }} - </div> -{% endblock %} diff --git a/docs/api/basexmpp.rst b/docs/api/basexmpp.rst index 841df3db..fa96322e 100644 --- a/docs/api/basexmpp.rst +++ b/docs/api/basexmpp.rst @@ -1,5 +1,5 @@ ======== -basexmpp +BaseXMPP ======== .. module:: sleekxmpp.basexmpp diff --git a/docs/api/clientxmpp.rst b/docs/api/clientxmpp.rst index 8f87664e..a6f32c43 100644 --- a/docs/api/clientxmpp.rst +++ b/docs/api/clientxmpp.rst @@ -1,17 +1,8 @@ ========== -clientxmpp +ClientXMPP ========== .. module:: sleekxmpp.clientxmpp .. autoclass:: ClientXMPP - - .. automethod:: connect - - .. automethod:: register_feature - - .. automethod:: get_roster - - .. automethod:: update_roster - - .. automethod:: del_roster_item + :members: diff --git a/docs/api/componentxmpp.rst b/docs/api/componentxmpp.rst new file mode 100644 index 00000000..989120c2 --- /dev/null +++ b/docs/api/componentxmpp.rst @@ -0,0 +1,8 @@ +============= +ComponentXMPP +============= + +.. module:: sleekxmpp.componentxmpp + +.. autoclass:: ComponentXMPP + :members: diff --git a/docs/api/exceptions.rst b/docs/api/exceptions.rst new file mode 100644 index 00000000..7bc72ce5 --- /dev/null +++ b/docs/api/exceptions.rst @@ -0,0 +1,14 @@ +Exceptions +========== + +.. module:: sleekxmpp.exceptions + + +.. autoexception:: XMPPError + :members: + +.. autoexception:: IqError + :members: + +.. autoexception:: IqTimeout + :members: diff --git a/docs/api/xmlstream.rst b/docs/api/xmlstream.rst deleted file mode 100644 index 7835bf57..00000000 --- a/docs/api/xmlstream.rst +++ /dev/null @@ -1,8 +0,0 @@ -========= -xmlstream -========= - -.. module:: sleekxmpp.xmlstream - -.. autoclass:: XMLStream - :members: diff --git a/docs/api/xmlstream/filesocket.rst b/docs/api/xmlstream/filesocket.rst new file mode 100644 index 00000000..35f44019 --- /dev/null +++ b/docs/api/xmlstream/filesocket.rst @@ -0,0 +1,12 @@ +.. module:: sleekxmpp.xmlstream.filesocket + +.. _filesocket: + +Python 2.6 File Socket Shims +============================ + +.. autoclass:: FileSocket + :members: + +.. autoclass:: Socket26 + :members: diff --git a/docs/api/xmlstream/handler.rst b/docs/api/xmlstream/handler.rst new file mode 100644 index 00000000..33c0bf42 --- /dev/null +++ b/docs/api/xmlstream/handler.rst @@ -0,0 +1,24 @@ +Stanza Handlers +=============== + +The Basic Handler +----------------- +.. module:: sleekxmpp.xmlstream.handler.base + +.. autoclass:: BaseHandler + :members: + +Callback +-------- +.. module:: sleekxmpp.xmlstream.handler.callback + +.. autoclass:: Callback + :members: + + +Waiter +------ +.. module:: sleekxmpp.xmlstream.handler.waiter + +.. autoclass:: Waiter + :members: diff --git a/docs/api/xmlstream/jid.rst b/docs/api/xmlstream/jid.rst new file mode 100644 index 00000000..22a2db45 --- /dev/null +++ b/docs/api/xmlstream/jid.rst @@ -0,0 +1,7 @@ +Jabber IDs (JID) +================= + +.. module:: sleekxmpp.xmlstream.jid + +.. autoclass:: JID + :members: diff --git a/docs/api/xmlstream/matcher.rst b/docs/api/xmlstream/matcher.rst new file mode 100644 index 00000000..df3591bc --- /dev/null +++ b/docs/api/xmlstream/matcher.rst @@ -0,0 +1,41 @@ +Stanza Matchers +=============== + +The Basic Matcher +----------------- +.. module:: sleekxmpp.xmlstream.matcher.base + +.. autoclass:: MatcherBase + :members: + + +ID Matching +----------- +.. module:: sleekxmpp.xmlstream.matcher.id + +.. autoclass:: MatcherId + :members: + + +Stanza Path Matching +-------------------- +.. module:: sleekxmpp.xmlstream.matcher.stanzapath + +.. autoclass:: StanzaPath + :members: + + +XPath +----- +.. module:: sleekxmpp.xmlstream.matcher.xpath + +.. autoclass:: MatchXPath + :members: + + +XMLMask +------- +.. module:: sleekxmpp.xmlstream.matcher.xmlmask + +.. autoclass:: MatchXMLMask + :members: diff --git a/docs/api/xmlstream/scheduler.rst b/docs/api/xmlstream/scheduler.rst new file mode 100644 index 00000000..ff91701e --- /dev/null +++ b/docs/api/xmlstream/scheduler.rst @@ -0,0 +1,11 @@ +========= +Scheduler +========= + +.. module:: sleekxmpp.xmlstream.scheduler + +.. autoclass:: Task + :members: + +.. autoclass:: Scheduler + :members: diff --git a/docs/api/xmlstream/stanzabase.rst b/docs/api/xmlstream/stanzabase.rst new file mode 100644 index 00000000..f575299e --- /dev/null +++ b/docs/api/xmlstream/stanzabase.rst @@ -0,0 +1,123 @@ +.. _stanzabase: + +============== +Stanza Objects +============== + +.. module:: sleekxmpp.xmlstream.stanzabase + +The :mod:`~sleekmxpp.xmlstream.stanzabase` module provides a wrapper for the +standard :mod:`~xml.etree.ElementTree` module that makes working with XML +less painful. Instead of having to manually move up and down an element +tree and insert subelements and attributes, you can interact with an object +that behaves like a normal dictionary or JSON object, which silently maps +keys to XML attributes and elements behind the scenes. + +Overview +-------- + +The usefulness of this layer grows as the XML you have to work with +becomes nested. The base unit here, :class:`ElementBase`, can map to a +single XML element, or several depending on how advanced of a mapping +is desired from interface keys to XML structures. For example, a single +:class:`ElementBase` derived class could easily describe: + +.. code-block:: xml + + <message to="user@example.com" from="friend@example.com"> + <body>Hi!</body> + <x:extra> + <x:item>Custom item 1</x:item> + <x:item>Custom item 2</x:item> + <x:item>Custom item 3</x:item> + </x:extra> + </message> + +If that chunk of XML were put in the :class:`ElementBase` instance +``msg``, we could extract the data from the XML using:: + + >>> msg['extra'] + ['Custom item 1', 'Custom item 2', 'Custom item 3'] + +Provided we set up the handler for the ``'extra'`` interface to load the +``<x:item>`` element content into a list. + +The key concept is that given an XML structure that will be repeatedly +used, we can define a set of :term:`interfaces` which when we read from, +write to, or delete, will automatically manipulate the underlying XML +as needed. In addition, some of these interfaces may in turn reference +child objects which expose interfaces for particularly complex child +elements of the original XML chunk. + +.. seealso:: + :ref:`create-stanza-interfaces`. + +Because the :mod:`~sleekxmpp.xmlstream.stanzabase` module was developed +as part of an `XMPP <http://xmpp.org>`_ library, these chunks of XML are +referred to as :term:`stanzas <stanza>`, and in SleekXMPP we refer to a +subclass of :class:`ElementBase` which defines the interfaces needed for +interacting with a given :term:`stanza` a :term:`stanza object`. + +To make dealing with more complicated and nested :term:`stanzas <stanza>` +or XML chunks easier, :term:`stanza objects <stanza object>` can be +composed in two ways: as iterable child objects or as plugins. Iterable +child stanzas, or :term:`substanzas`, are accessible through a special +``'substanzas'`` interface. This option is useful for stanzas which +may contain more than one of the same kind of element. When there is +only one child element, the plugin method is more useful. For plugins, +a parent stanza object delegates one of its XML child elements to the +plugin stanza object. Here is an example: + +.. code-block:: xml + + <iq type="result"> + <query xmlns="http://jabber.org/protocol/disco#info"> + <identity category="client" type="bot" name="SleekXMPP Bot" /> + </query> + </iq> + +We can can arrange this stanza into two objects: an outer, wrapper object for +dealing with the ``<iq />`` element and its attributes, and a plugin object to +control the ``<query />`` payload element. If we give the plugin object the +name ``'disco_info'`` (using its :attr:`ElementBase.plugin_attrib` value), then +we can access the plugin as so:: + + >>> iq['disco_info'] + '<query xmlns="http://jabber.org/protocol/disco#info"> + <identity category="client" type="bot" name="SleekXMPP Bot" /> + </query>' + +We can then drill down through the plugin object's interfaces as desired:: + + >>> iq['disco_info']['identities'] + [('client', 'bot', 'SleekXMPP Bot')] + +Plugins may also add new interfaces to the parent stanza object as if they +had been defined by the parent directly, and can also override the behaviour +of an interface defined by the parent. + +.. seealso:: + + - :ref:`create-stanza-plugins` + - :ref:`create-extension-plugins` + - :ref:`override-parent-interfaces` + + +Registering Stanza Plugins +-------------------------- + +.. autofunction:: register_stanza_plugin + +ElementBase +----------- + +.. autoclass:: ElementBase + :members: + :private-members: + :special-members: + +StanzaBase +---------- + +.. autoclass:: StanzaBase + :members: diff --git a/docs/api/xmlstream/tostring.rst b/docs/api/xmlstream/tostring.rst new file mode 100644 index 00000000..82a8c2a5 --- /dev/null +++ b/docs/api/xmlstream/tostring.rst @@ -0,0 +1,46 @@ +.. module:: sleekxmpp.xmlstream.tostring + +.. _tostring: + +XML Serialization +================= + +Since the XML layer of SleekXMPP is based on :mod:`~xml.etree.ElementTree`, +why not just use the built-in :func:`~xml.etree.ElementTree.tostring` +method? The answer is that using that method produces ugly results when +using namespaces. The :func:`tostring()` method used here intelligently +hides namespaces when able and does not introduce excessive namespace +prefixes:: + + >>> from sleekxmpp.xmlstream.tostring import tostring + >>> from xml.etree import cElementTree as ET + >>> xml = ET.fromstring('<foo xmlns="bar"><baz /></foo>') + >>> ET.tostring(xml) + '<ns0:foo xmlns:ns0="bar"><ns0:baz /></foo>' + >>> tostring(xml) + '<foo xmlns="bar"><baz /></foo>' + +As a side effect of this namespace hiding, using :func:`tostring()` may +produce unexpected results depending on how the :func:`tostring()` method +is invoked. For example, when sending XML on the wire, the main XMPP +stanzas with their namespace of ``jabber:client`` will not include the +namespace because that is already declared by the stream header. But, if +you create a :class:`~sleekxmpp.stanza.message.Message` instance and dump +it to the terminal, the ``jabber:client`` namespace will appear. + +.. autofunction:: tostring + +Escaping Special Characters +--------------------------- + +In order to prevent errors when sending arbitrary text as the textual +content of an XML element, certain characters must be escaped. These +are: ``&``, ``<``, ``>``, ``"``, and ``'``. The default escaping +mechanism is to replace those characters with their equivalent escape +entities: ``&``, ``<``, ``>``, ``'``, and ``"``. + +In the future, the use of CDATA sections may be allowed to reduce the +size of escaped text or for when other XMPP processing agents do not +undertand these entities. + +.. autofunction:: xml_escape diff --git a/docs/api/xmlstream/xmlstream.rst b/docs/api/xmlstream/xmlstream.rst new file mode 100644 index 00000000..90a7a6af --- /dev/null +++ b/docs/api/xmlstream/xmlstream.rst @@ -0,0 +1,10 @@ +========== +XML Stream +========== + +.. module:: sleekxmpp.xmlstream.xmlstream + +.. autoexception:: RestartStream + +.. autoclass:: XMLStream + :members: diff --git a/docs/architecture.rst b/docs/architecture.rst index 53c326e1..a2e0a27d 100644 --- a/docs/architecture.rst +++ b/docs/architecture.rst @@ -17,21 +17,21 @@ of the tedium of creating/manipulating XML. The Foundation: XMLStream ------------------------- -``XMLStream`` is a mostly XMPP-agnostic class whose purpose is to read -and write from a bi-directional XML stream. It also allows for callback -functions to execute when XML matching given patterns is received; these -callbacks are also referred to as :term:`stream handlers <stream handler>`. -The class also provides a basic eventing system which can be triggered -either manually or on a timed schedule. +:class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` is a mostly XMPP-agnostic +class whose purpose is to read and write from a bi-directional XML stream. +It also allows for callback functions to execute when XML matching given +patterns is received; these callbacks are also referred to as :term:`stream +handlers <stream handler>`. The class also provides a basic eventing system +which can be triggered either manually or on a timed schedule. The Main Threads ~~~~~~~~~~~~~~~~ -``XMLStream`` instances run using at least three background threads: the -send thread, the read thread, and the scheduler thread. The send thread is -in charge of monitoring the send queue and writing text to the outgoing -XML stream. The read thread pulls text off of the incoming XML stream and -stores the results in an event queue. The scheduler thread is used to emit -events after a given period of time. +:class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` instances run using at +least three background threads: the send thread, the read thread, and the +scheduler thread. The send thread is in charge of monitoring the send queue +and writing text to the outgoing XML stream. The read thread pulls text off +of the incoming XML stream and stores the results in an event queue. The +scheduler thread is used to emit events after a given period of time. Additionally, the main event processing loop may be executed in its own thread if SleekXMPP is being used in the background for another @@ -61,9 +61,10 @@ when this bit of XML is received (with an assumed namespace of new object is determined using a map of namespaced element names to classes. - Our incoming XML is thus turned into a ``Message`` :term:`stanza object` - because the namespaced element name ``{jabber:client}message`` is - associated with the class ``sleekxmpp.stanza.Message``. + Our incoming XML is thus turned into a :class:`~sleekxmpp.stanza.Message` + :term:`stanza object` because the namespaced element name + ``{jabber:client}message`` is associated with the class + :class:`~sleekxmpp.stanza.Message`. 2. **Match stanza objects to callbacks.** @@ -72,8 +73,8 @@ when this bit of XML is received (with an assumed namespace of :term:`stanza object` is paired with a reference to the handler and placed into the event queue. - Our ``Message`` object is thus paired with the message stanza handler - ``BaseXMPP._handle_message`` to create the tuple:: + Our :class:`~sleekxmpp.stanza.Message` object is thus paired with the message stanza handler + :meth:`BaseXMPP._handle_message` to create the tuple:: ('stanza', stanza_obj, handler) @@ -88,7 +89,7 @@ when this bit of XML is received (with an assumed namespace of parameter. .. warning:: - The callback, aka :term:`stream handler`, is executed in the main + The callback, aka :term:`stream handler`, is executed in the main event processing thread. If the handler blocks, event processing will also block. @@ -96,20 +97,22 @@ when this bit of XML is received (with an assumed namespace of Since a :term:`stream handler` shouldn't block, if extensive processing for a stanza is required (such as needing to send and receive an - ``Iq`` stanza), then custom events must be used. These events are not - explicitly tied to the incoming XML stream and may be raised at any - time. Importantly, these events may be handled in their own thread. + :class:`~sleekxmpp.stanza.Iq` stanza), then custom events must be used. + These events are not explicitly tied to the incoming XML stream and may + be raised at any time. Importantly, these events may be handled in their + own thread. When the event is raised, a copy of the stanza is created for each - handler registered for the event. In contrast to :term:`stream handlers <stream handler>`, - these functions are referred to as :term:`event handlers <event handler>`. - Each stanza/handler pair is then put into the event queue. + handler registered for the event. In contrast to :term:`stream handlers + <stream handler>`, these functions are referred to as :term:`event + handlers <event handler>`. Each stanza/handler pair is then put into the + event queue. .. note:: It is possible to skip the event queue and process an event immediately by using ``direct=True`` when raising the event. - The code for ``BaseXMPP._handle_message`` follows this pattern, and + The code for :meth:`BaseXMPP._handle_message` follows this pattern, and raises a ``'message'`` event:: self.event('message', msg) @@ -145,125 +148,30 @@ when this bit of XML is received (with an assumed namespace of Raising XMPP Awareness: BaseXMPP -------------------------------- -While ``XMLStream`` attempts to shy away from anything too XMPP specific, -``BaseXMPP``'s sole purpose is to provide foundational support for sending -and receiving XMPP stanzas. This support includes registering the basic -message, presence, and iq stanzas, methods for creating and sending -stanzas, and default handlers for incoming messages and keeping track of -presence notifications. +While :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` attempts to shy away +from anything too XMPP specific, :class:`~sleekxmpp.basexmpp.BaseXMPP`'s +sole purpose is to provide foundational support for sending and receiving +XMPP stanzas. This support includes registering the basic message, +presence, and iq stanzas, methods for creating and sending stanzas, and +default handlers for incoming messages and keeping track of presence +notifications. The plugin system for adding new XEP support is also maintained by -``BaseXMPP``. +:class:`~sleekxmpp.basexmpp.BaseXMPP`. .. index:: ClientXMPP, BaseXMPP ClientXMPP ---------- -``ClientXMPP`` extends ``BaseXMPP`` with additional logic for connecting to -an XMPP server by performing DNS lookups. It also adds support for stream +:class:`~sleekxmpp.clientxmpp.ClientXMPP` extends +:class:`~sleekxmpp.clientxmpp.BaseXMPP` with additional logic for connecting +to an XMPP server by performing DNS lookups. It also adds support for stream features such as STARTTLS and SASL. .. index:: ComponentXMPP, BaseXMPP ComponentXMPP ------------- -``ComponentXMPP`` is only a thin layer on top of ``BaseXMPP`` that -implements the component handshake protocol. - -.. index:: - double: object; stanza - -Stanza Objects: A Brief Look ----------------------------- -.. seealso:: - See :ref:`api-stanza-objects` for a more detailed overview. - -Almost worthy of their own standalone library, :term:`stanza objects <stanza object>` -are wrappers for XML objects which expose dictionary like interfaces -for manipulating their XML content. For example, consider the XML: - -.. code-block:: xml - - <message /> - -A very plain element to start with, but we can create a :term:`stanza object` -using ``sleekxmpp.stanza.Message`` as so:: - - msg = Message(xml=ET.fromstring("<message />")) - -The ``Message`` stanza class defines interfaces such as ``'body'`` and -``'to'``, so we can assign values to those interfaces to include new XML -content:: - - msg['body'] = "Following so far?" - msg['to'] = 'user@example.com' - -Dumping the XML content of ``msg`` (using ``msg.xml``), we find: - -.. code-block:: xml - - <message to="user@example.com"> - <body>Following so far?</body> - </message> - -The process is similar for reading from interfaces and deleting interface -contents. A :term:`stanza object` behaves very similarly to a regular -``dict`` object: you may assign to keys, read from keys, and ``del`` keys. - -Stanza interfaces come with built-in behaviours such as adding/removing -attribute and sub element values. However, a lot of the time more custom -logic is needed. This can be provided by defining methods of the form -``get_*``, ``set_*``, and ``del_*`` for any interface which requires custom -behaviour. - -Stanza Plugins -~~~~~~~~~~~~~~ -Since it is generally possible to embed one XML element inside another, -:term:`stanza objects <stanza object>` may be nested. Nested -:term:`stanza objects <stanza object>` are referred to as :term:`stanza plugins <stanza plugin>` -or :term:`substanzas <substanza>`. - -A :term:`stanza plugin` exposes its own interfaces by adding a new -interface to its parent stanza. To demonstrate, consider these two stanza -class definitions using ``sleekxmpp.xmlstream.ElementBase``: - - -.. code-block:: python - - class Parent(ElementBase): - name = "the-parent-xml-element-name" - namespace = "the-parent-namespace" - interfaces = set(('foo', 'bar')) - - class Child(ElementBase): - name = "the-child-xml-element-name" - namespace = "the-child-namespace" - plugin_attrib = 'child' - interfaces = set(('baz',)) - - -If we register the ``Child`` stanza as a plugin of the ``Parent`` stanza as -so, using ``sleekxmpp.xmlstream.register_stanza_plugin``:: - - register_stanza_plugin(Parent, Child) - -Then we can access content in the child stanza through the parent. -Note that the interface used to access the child stanza is the same as -``Child.plugin_attrib``:: - - parent = Parent() - parent['foo'] = 'a' - parent['child']['baz'] = 'b' - -The above code would produce: - -.. code-block:: xml - - <the-parent-xml-element xmlns="the-parent-namespace" foo="a"> - <the-child-xml-element xmlsn="the-child-namespace" baz="b" /> - </the-parent-xml-element> - -It is also possible to allow a :term:`substanza` to appear multiple times -by using ``iterable=True`` in the ``register_stanza_plugin`` call. All -iterable :term:`substanzas <substanza>` can be accessed using a standard -``substanzas`` interface. +:class:`~sleekxmpp.componentxmpp.ComponentXMPP` is only a thin layer on top of +:class:`~sleekxmpp.basexmpp.BaseXMPP` that implements the component handshake +protocol. diff --git a/docs/conf.py b/docs/conf.py index 8a165872..dd83f243 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,7 +16,7 @@ import sys, os # 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('.')) +sys.path.insert(0, os.path.abspath('..')) # -- General configuration ----------------------------------------------------- @@ -25,7 +25,7 @@ import sys, os # 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.viewcode'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.intersphinx'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -50,7 +50,7 @@ copyright = u'2011, Nathan Fritz, Lance Stout' # The short X.Y version. version = '1.0' # The full version, including alpha/beta/rc tags. -release = '1.0RC1' +release = '1.0RC3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -81,7 +81,7 @@ exclude_patterns = ['_build'] #show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'default' +pygments_style = 'tango' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] @@ -91,7 +91,7 @@ pygments_style = 'default' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'haiku' +html_theme = 'nature' # 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 @@ -218,3 +218,5 @@ man_pages = [ ('index', 'sleekxmpp', u'SleekXMPP Documentation', [u'Nathan Fritz, Lance Stout'], 1) ] + +intersphinx_mapping = {'python': ('http://docs.python.org/3.2', 'python-objects.inv')} diff --git a/docs/create_plugin.rst b/docs/create_plugin.rst index 112ef505..12efa84c 100644 --- a/docs/create_plugin.rst +++ b/docs/create_plugin.rst @@ -1,3 +1,5 @@ +.. _create-plugin: + Creating a SleekXMPP Plugin =========================== diff --git a/docs/getting_started/component.rst b/docs/getting_started/component.rst index ca9ec066..ce548ba4 100644 --- a/docs/getting_started/component.rst +++ b/docs/getting_started/component.rst @@ -1,2 +1,75 @@ +.. _echocomponent: + +================================= Create and Run a Server Component ================================= + +.. note:: + + If you have any issues working through this quickstart guide + or the other tutorials here, please either send a message to the + `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_ + or join the chat room at `sleek@conference.jabber.org + <xmpp:sleek@conference.jabber.org?join>`_. + +If you have not yet installed SleekXMPP, do so now by either checking out a version +from `Github <http://github.com/fritzy/SleekXMPP>`_, or installing it using ``pip`` +or ``easy_install``. + +.. code-block:: sh + + pip install sleekxmpp # Or: easy_install sleekxmpp + + +Many XMPP applications eventually graduate to requiring to run as a server +component in order to meet scalability requirements. To demonstrate how to +turn an XMPP client bot into a component, we'll turn the echobot example +(:ref:`echobot`) into a component version. + +The first difference is that we will add an additional import statement: + +.. code-block:: python + + from sleekxmpp.componentxmpp import ComponentXMPP + +Likewise, we will change the bot's class definition to match: + +.. code-block:: python + + class EchoComponent(ComponentXMPP): + + def __init__(self, jid, secret, server, port): + ComponentXMPP.__init__(self, jid, secret, server, port) + +A component instance requires two extra parameters compared to a client +instance: ``server`` and ``port``. These specifiy the name and port of +the XMPP server that will be accepting the component. For example, for +a MUC component, the following could be used: + +.. code-block:: python + + muc = ComponentXMPP('muc.sleekxmpp.com', '******', 'sleekxmpp.com', 5555) + +.. note:: + + The ``server`` value is **NOT** derived from the provided JID for the + component, unlike with client connections. + +One difference with the component version is that we do not have +to handle the :term:`session_start` event if we don't wish to deal +with presence. + +The other, main difference with components is that the +``'from'`` value for every stanza must be explicitly set, since +components may send stanzas from multiple JIDs. To do so, +the :meth:`~sleekxmpp.basexmpp.BaseXMPP.send_message()` and +:meth:`~sleekxmpp.basexmpp.BaseXMPP.send_presence()` accept the parameters +``mfrom`` and ``pfrom``, respectively. For any method that uses +:class:`~sleekxmpp.stanza.iq.Iq` stanzas, ``ifrom`` may be used. + + +Final Product +------------- + +.. include:: ../../examples/echo_component.py + :literal: diff --git a/docs/getting_started/iq.rst b/docs/getting_started/iq.rst index 7ac1508c..98e0bdaf 100644 --- a/docs/getting_started/iq.rst +++ b/docs/getting_started/iq.rst @@ -1,2 +1,182 @@ Send/Receive IQ Stanzas ======================= + +Unlike :class:`~sleekxmpp.stanza.message.Message` and +:class:`~sleekxmpp.stanza.presence.Presence` stanzas which only use +text data for basic usage, :class:`~sleekxmpp.stanza.iq.Iq` stanzas +require using XML payloads, and generally entail creating a new +SleekXMPP plugin to provide the necessary convenience methods to +make working with them easier. + +Basic Use +--------- + +XMPP's use of :class:`~sleekxmpp.stanza.iq.Iq` stanzas is built around +namespaced ``<query />`` elements. For clients, just sending the +empty ``<query />`` element will suffice for retrieving information. For +example, a very basic implementation of service discovery would just +need to be able to send: + +.. code-block:: xml + + <iq to="user@example.com" type="get" id="1"> + <query xmlns="http://jabber.org/protocol/disco#info" /> + </iq> + +Creating Iq Stanzas +~~~~~~~~~~~~~~~~~~~ + +SleekXMPP provides built-in support for creating basic :class:`~sleekxmpp.stanza.iq.Iq` +stanzas this way. The relevant methods are: + +* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq` +* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_get` +* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_set` +* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_result` +* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_error` +* :meth:`~sleekxmpp.basexmpp.BaseXMPP.make_iq_query` + +These methods all follow the same pattern: create or modify an existing +:class:`~sleekxmpp.stanza.iq.Iq` stanza, set the ``'type'`` value based +on the method name, and finally add a ``<query />`` element with the given +namespace. For example, to produce the query above, you would use: + +.. code-block:: python + + self.make_iq_get(queryxmlns='http://jabber.org/protocol/disco#info', + ito='user@example.com') + + +Sending Iq Stanzas +~~~~~~~~~~~~~~~~~~ + +Once an :class:`~sleekxmpp.stanza.iq.Iq` stanza is created, sending it +over the wire is done using its :meth:`~sleekxmpp.stanza.iq.Iq.send()` +method, like any other stanza object. However, there are a few extra +options to control how to wait for the query's response. + +These options are: + +* ``block``: The default behaviour is that :meth:`~sleekxmpp.stanza.iq.Iq.send()` + will block until a response is received and the response stanza will be the + return value. Setting ``block`` to ``False`` will cause the call to return + immediately. In which case, you will need to arrange some way to capture + the response stanza if you need it. + +* ``timeout``: When using the blocking behaviour, the call will eventually + timeout with an error. The default timeout is 30 seconds, but this may + be overidden two ways. To change the timeout globally, set: + + .. code-block:: python + + self.response_timeout = 10 + + To change the timeout for a single call, the ``timeout`` parameter works: + + .. code-block:: python + + iq.send(timeout=60) + +* ``callback``: When not using a blocking call, using the ``callback`` + argument is a simple way to register a handler that will execute + whenever a response is finally received. Using this method, there + is no timeout limit. In case you need to remove the callback, the + name of the newly created callback is returned. + + .. code-block:: python + + cb_name = iq.send(callback=self.a_callback) + + # ... later if we need to cancel + self.remove_handler(cb_name) + +Properly working with :class:`~sleekxmpp.stanza.iq.Iq` stanzas requires +handling the intended, normal flow, error responses, and timed out +requests. To make this easier, two exceptions may be thrown by +:meth:`~sleekxmpp.stanza.iq.Iq.send()`: :exc:`~sleekxmpp.exceptions.IqError` +and :exc:`~sleekxmpp.exceptions.IqTimeout`. These exceptions only +apply to the default, blocking calls. + +.. code-block:: python + + try: + resp = iq.send() + # ... do stuff with expected Iq result + except IqError as e: + err_resp = e.iq + # ... handle error case + except IqTimeout: + # ... no response received in time + pass + +If you do not care to distinguish between errors and timeouts, then you +can combine both cases with a generic :exc:`~sleekxmpp.exceptions.XMPPError` +exception: + +.. code-block:: python + + try: + resp = iq.send() + except XMPPError: + # ... Don't care about the response + pass + +Advanced Use +------------ + +Going beyond the basics provided by SleekXMPP requires building at least a +rudimentary SleekXMPP plugin to create a :term:`stanza object` for +interfacting with the :class:`~sleekxmpp.stanza.iq.Iq` payload. + +.. seealso:: + + * :ref:`create-plugin` + * :ref:`work-with-stanzas` + * :ref:`using-handlers-matchers` + + +The typical way to respond to :class:`~sleekxmpp.stanza.iq.Iq` requests is +to register stream handlers. As an example, suppose we create a stanza class +named ``CustomXEP`` which uses the XML element ``<query xmlns="custom-xep" />``, +and has a :attr:`~sleekxmpp.xmlstream.stanzabase.ElementBase.plugin_attrib` value +of ``custom_xep``. + +There are two types of incoming :class:`~sleekxmpp.stanza.iq.Iq` requests: +``get`` and ``set``. You can register a handler that will accept both and then +filter by type as needed, as so: + +.. code-block:: python + + self.register_handler(Callback( + 'CustomXEP Handler', + StanzaPath('iq/custom_xep'), + self._handle_custom_iq)) + + # ... + + def _handle_custom_iq(self, iq): + if iq['type'] == 'get': + # ... + pass + elif iq['type'] == 'set': + # ... + pass + else: + # ... This will capture error responses too + pass + +If you want to filter out query types beforehand, you can adjust the matching +filter by using ``@type=get`` or ``@type=set`` if you are using the recommended +:class:`~sleekxmpp.xmlstream.matcher.stanzapath.StanzaPath` matcher. + +.. code-block:: python + + self.register_handler(Callback( + 'CustomXEP Handler', + StanzaPath('iq@type=get/custom_xep'), + self._handle_custom_iq_get)) + + # ... + + def _handle_custom_iq_get(self, iq): + assert(iq['type'] == 'get') diff --git a/docs/getting_started/proxy.rst b/docs/getting_started/proxy.rst index 02ad10ae..60d521c5 100644 --- a/docs/getting_started/proxy.rst +++ b/docs/getting_started/proxy.rst @@ -1,2 +1,42 @@ +.. _proxy: + +========================= Enable HTTP Proxy Support ========================= + +.. note:: + + If you have any issues working through this quickstart guide + or the other tutorials here, please either send a message to the + `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_ + or join the chat room at `sleek@conference.jabber.org + <xmpp:sleek@conference.jabber.org?join>`_. + +In some instances, you may wish to route XMPP traffic through +an HTTP proxy, probably to get around restrictive firewalls. +SleekXMPP provides support for basic HTTP proxying with DIGEST +authentication. + +Enabling proxy support is done in two steps. The first is to instruct SleekXMPP +to use a proxy, and the second is to configure the proxy details: + +.. code-block:: python + + xmpp = ClientXMPP(...) + xmpp.use_proxy = True + xmpp.proxy_config = { + 'host': 'proxy.example.com', + 'port': 5555, + 'username': 'example_user', + 'password': '******' + } + +The ``'username'`` and ``'password'`` fields are optional if the proxy does not +require authentication. + + +The Final Product +----------------- + +.. include:: ../../examples/proxy_echo_client.py + :literal: diff --git a/docs/handlersmatchers.rst b/docs/handlersmatchers.rst index 7ac750c0..628c4142 100644 --- a/docs/handlersmatchers.rst +++ b/docs/handlersmatchers.rst @@ -1,2 +1,4 @@ +.. _using-handlers-matchers: + Using Stream Handlers and Matchers ================================== diff --git a/docs/howto/stanzas.rst b/docs/howto/stanzas.rst new file mode 100644 index 00000000..d52a90d4 --- /dev/null +++ b/docs/howto/stanzas.rst @@ -0,0 +1,30 @@ +.. _work-with-stanzas: + +How to Work with Stanza Objects +=============================== + + +.. _create-stanza-interfaces: + +Defining Stanza Interfaces +-------------------------- + + +.. _create-stanza-plugins: + +Creating Stanza Plugins +----------------------- + + + +.. _create-extension-plugins: + +Creating a Stanza Extension +--------------------------- + + + +.. _override-parent-interfaces: + +Overriding a Parent Stanza +-------------------------- diff --git a/docs/index.rst b/docs/index.rst index 5da389b9..fc6541d6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,13 +12,8 @@ SleekXMPP ``master`` branch, while the latest development version is in the ``develop`` branch. - **Stable Releases** - - `1.0 Beta6.1 <http://github.com/fritzy/SleekXMPP/zipball/1.0-Beta6.1>`_ - - `1.0 Beta5 <http://github.com/fritzy/SleekXMPP/zipball/1.0-Beta5>`_ - - `1.0 Beta4 <http://github.com/fritzy/SleekXMPP/zipball/1.0-Beta4>`_ - - `1.0 Beta3 <http://github.com/fritzy/SleekXMPP/zipball/1.0-Beta3>`_ - - `1.0 Beta2 <http://github.com/fritzy/SleekXMPP/zipball/1.0-Beta2>`_ - - `1.0 Beta1 <http://github.com/fritzy/SleekXMPP/zipball/1.0-Beta1>`_ + **Latest Stable Release** + - `1.0 RC3 <http://github.com/fritzy/SleekXMPP/zipball/1.0-RC3>`_ **Develop Releases** - `Latest Develop Version <http://github.com/fritzy/SleekXMPP/zipball/develop>`_ @@ -84,8 +79,10 @@ Tutorials, FAQs, and How To Guides .. toctree:: :maxdepth: 1 + faq xeps xmpp_tdg + howto/stanzas create_plugin features sasl @@ -113,8 +110,35 @@ API Reference event_index api/clientxmpp + api/componentxmpp api/basexmpp - api/xmlstream + api/exceptions + api/xmlstream/jid + api/xmlstream/stanzabase + api/xmlstream/handler + api/xmlstream/matcher + api/xmlstream/xmlstream + api/xmlstream/scheduler + api/xmlstream/tostring + api/xmlstream/filesocket + +Core Stanzas +~~~~~~~~~~~~ +.. toctree:: + :maxdepth: 2 + + api/stanza/rootstanza + api/stanza/message + api/stanza/presence + api/stanza/iq + api/stanza/error + api/stanza/stream_error + +Plugins +~~~~~~~ +.. toctree:: + :maxdepth: 2 + Additional Info --------------- diff --git a/docs/python-objects.inv b/docs/python-objects.inv Binary files differnew file mode 100644 index 00000000..b7afc07e --- /dev/null +++ b/docs/python-objects.inv diff --git a/docs/xeps.rst b/docs/xeps.rst index a541a586..3653d10a 100644 --- a/docs/xeps.rst +++ b/docs/xeps.rst @@ -1,2 +1,50 @@ Supported XEPS ============== + +======= ============================= ================ +XEP Description Notes +======= ============================= ================ +`0004`_ Data forms +`0009`_ Jabber RPC +`0012`_ Last Activity +`0030`_ Service Discovery +`0033`_ Extended Stanza Addressing +`0045`_ Multi-User Chat (MUC) Client-side only +`0050`_ Ad-hoc Commands +`0059`_ Result Set Management +`0060`_ Publish/Subscribe (PubSub) Client-side only +`0066`_ Out-of-band Data +`0078`_ Non-SASL Authentication +`0082`_ XMPP Date and Time Profiles +`0085`_ Chat-State Notifications +`0086`_ Error Condition Mappings +`0092`_ Software Version +`0128`_ Service Discovery Extensions +`0202`_ Entity Time +`0203`_ Delayed Delivery +`0224`_ Attention +`0249`_ Direct MUC Invitations +======= ============================= ================ + + +.. _0004: http://xmpp.org/extensions/xep-0004.html +.. _0009: http://xmpp.org/extensions/xep-0009.html +.. _0012: http://xmpp.org/extensions/xep-0012.html +.. _0030: http://xmpp.org/extensions/xep-0030.html +.. _0033: http://xmpp.org/extensions/xep-0033.html +.. _0045: http://xmpp.org/extensions/xep-0045.html +.. _0050: http://xmpp.org/extensions/xep-0050.html +.. _0059: http://xmpp.org/extensions/xep-0059.html +.. _0060: http://xmpp.org/extensions/xep-0060.html +.. _0066: http://xmpp.org/extensions/xep-0066.html +.. _0078: http://xmpp.org/extensions/xep-0078.html +.. _0082: http://xmpp.org/extensions/xep-0082.html +.. _0085: http://xmpp.org/extensions/xep-0085.html +.. _0086: http://xmpp.org/extensions/xep-0086.html +.. _0092: http://xmpp.org/extensions/xep-0092.html +.. _0128: http://xmpp.org/extensions/xep-0128.html +.. _0199: http://xmpp.org/extensions/xep-0199.html +.. _0202: http://xmpp.org/extensions/xep-0202.html +.. _0203: http://xmpp.org/extensions/xep-0203.html +.. _0224: http://xmpp.org/extensions/xep-0224.html +.. _0249: http://xmpp.org/extensions/xep-0249.html |