From 1c1134e00f13fee92f9a0e0996d08db32579d89a Mon Sep 17 00:00:00 2001 From: kaliko Date: Wed, 6 May 2020 11:08:08 +0200 Subject: [PATCH] sphinx: Add sphinx docstring --- .gitignore | 1 + doc/source/conf.py | 187 ++++++++++++++++++++++++++++++++++++++ doc/source/contribute.rst | 34 +++++++ doc/source/doc.rst | 24 +++++ doc/source/index.rst | 20 ++++ setup.cfg | 4 + sid/plugin.py | 31 +++++-- sid/sid.py | 41 ++++++--- 8 files changed, 321 insertions(+), 21 deletions(-) create mode 100644 doc/source/conf.py create mode 100644 doc/source/contribute.rst create mode 100644 doc/source/doc.rst create mode 100644 doc/source/index.rst diff --git a/.gitignore b/.gitignore index 8e5742c..db91a1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +build dist/ venv/ __pycache__ diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 0000000..0598e81 --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# 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. +# +import os +import sys +sys.path.insert(0, os.path.abspath('../..')) +from sid import __author__, __version__ + +# -- Project information ----------------------------------------------------- + +project = 'sid' +from datetime import datetime +copyright = u'2011-{}, {}'.format(datetime.now().year, __author__) +author = 'kaliko' + +# The short X.Y version +version = __version__ +# The full version, including alpha/beta/rc tags +release = ".".join(__version__.split(".")[0:2]) + + +# -- 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', + 'sphinx.ext.coverage', + 'sphinx.ext.viewcode', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + + +# -- 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 = 'alabaster' +#html_theme = 'sphinx_rtd_theme' + +# 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 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'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'sidxmppbotdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'sidxmppbot.tex', 'sid xmpp bot Documentation', + 'kaliko', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'sidxmppbot', 'sid xmpp bot Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'sidxmppbot', 'sid xmpp bot Documentation', + author, 'sidxmppbot', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} diff --git a/doc/source/contribute.rst b/doc/source/contribute.rst new file mode 100644 index 0000000..de27929 --- /dev/null +++ b/doc/source/contribute.rst @@ -0,0 +1,34 @@ +Contributing +============= + +Use git, `learn if needed`_. + +Git Workflow +------------- +* ``master`` branch holds latest stable|release code +* ``dev`` branch holds current development code +* Work on a dedicated branch starting off ``dev`` +* I like fast forward merges, **please rebase on** ``dev`` branch before submitting changes +* Advertise your work (cf. Note) + +.. NOTE:: + **Git merge Workflow** |br| + I currently don't care about a specific workflow concerning changes submission. |br| + Don't bother with gitlab merge request or gh pull request. |br| + All we need is a public git repo and a ref to fetch from as long you rebased on ``dev`` branch. + +Coding +------- + +* follow pep8 +* actually test your code (unit and functional testing) +* write unittest + + +.. _`learn if needed`: https://git-scm.com/book/ + +.. |br| raw:: html + +
+ +.. vim: spell spelllang=en diff --git a/doc/source/doc.rst b/doc/source/doc.rst new file mode 100644 index 0000000..ad9ffa9 --- /dev/null +++ b/doc/source/doc.rst @@ -0,0 +1,24 @@ +Documentation +============== + +The Bot +------- + +.. autoclass:: sid.sid.MUCBot + :members: + :undoc-members: + :show-inheritance: + +.. user autodecorator:: with sphinx v2.0 +.. autofunction:: sid.sid.botcmd(hidden, name) + +Plugin base +----------- + +The plugin class to derive from. + +.. autoclass:: sid.plugin.Plugin + :members: + :undoc-members: + +.. vim: spell spelllang=en diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 0000000..65b0e9b --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,20 @@ +.. sid documentation master file, created by + sphinx-quickstart on Tue May 5 12:46:38 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +.. include:: ../../README.rst + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + doc.rst + contribute.rst + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/setup.cfg b/setup.cfg index ff5704a..77de5d5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,3 +21,7 @@ formats = xztar, gztar [bdist_wheel] universal=1 + +[build_sphinx] +source-dir = doc/source +build-dir = build diff --git a/sid/plugin.py b/sid/plugin.py index 6ff12ee..6db1d59 100644 --- a/sid/plugin.py +++ b/sid/plugin.py @@ -18,9 +18,13 @@ from .sid import botcmd class Plugin: - """Simple Plugin object to derive from: - Exposes the bot object and its logger - Provides some send helpers + """ + Simple Plugin object to derive from: + + * Exposes the bot object and its logger + * Provides send helpers + + :param sid.sid.MUCBot bot: bot the plugin is load from """ def __init__(self, bot): @@ -29,10 +33,17 @@ class Plugin: def send(self, dest, msg, mtype='chat'): """Send msg to dest - msg = { - mbody: 'text', - mhtml: 'text, # optional' - } + + :param str dest: Message recipient + :param dict,str msg: Message to send (use dict for xhtml-im) + + .. note:: + if **msg** is a :py:obj:`dict` to provide xhmlt-im massages:: + + msg = { + mbody: 'text', + mhtml: 'text, # optional' + } """ if isinstance(msg, str): msg = {'mbody': msg} @@ -43,7 +54,11 @@ class Plugin: def reply(self, rcv, msg): """Smart reply to message received. - Replies in private or on the muc depending on + + Replies ``msg`` in private or on the muc depending on ``rcv`` + + :param rcv: The received message (slixmpp object) + :param dict,str msg: The message to reply, refer to :py:obj:`sid.plugin.Plugin.send` for ``msg`` format """ to = rcv['from'] if rcv['type'] == 'groupchat': diff --git a/sid/sid.py b/sid/sid.py index 5b85fd1..fadb79e 100644 --- a/sid/sid.py +++ b/sid/sid.py @@ -25,7 +25,11 @@ import slixmpp def botcmd(*args, **kwargs): - """Decorator for bot command functions""" + """Decorator for bot command functions + + :param bool hidden: is the command hidden in global help + :param str name: command name, default to decorated function name + """ def decorate(func, hidden=False, name=None): setattr(func, '_bot_command', True) @@ -42,7 +46,16 @@ def botcmd(*args, **kwargs): class MUCBot(slixmpp.ClientXMPP): - + """ + :param str jid: jid to log with + :param str password: jid password + :param str room: conference room to join + :param str nick: Nickname to use in the room + """ + + #: Class attribute to define bot's command prefix + #: + #: Defaults to "!" prefix = '!' def __init__(self, jid, password, room, nick, log_file=None, @@ -56,10 +69,10 @@ class MUCBot(slixmpp.ClientXMPP): self.nick = nick self.__set_logger(log_file, log_level) self.__seen = dict() - self.register_plugin('xep_0030') # Service Discovery - self.register_plugin('xep_0045') # Multi-User Chat - self.register_plugin('xep_0071') # xhtml-im - self.register_plugin('xep_0199') # self Ping + self.register_plugin('xep_0030') # Service Discovery + self.register_plugin('xep_0045') # Multi-User Chat + self.register_plugin('xep_0071') # xhtml-im + self.register_plugin('xep_0199') # self Ping # The session_start event will be triggered when # the bot establishes its connection with the server @@ -92,7 +105,10 @@ class MUCBot(slixmpp.ClientXMPP): self.log.debug('set logger, log level : %s', log_level) def message(self, msg): - """Messages handler""" + """Messages handler + + Parses message received to detect :py:obj:`prefix` + """ if msg['type'] not in ('groupchat', 'chat'): self.log.warning('Unhandled message') return @@ -133,10 +149,8 @@ class MUCBot(slixmpp.ClientXMPP): requesting the roster and broadcasting an initial presence stanza. - Arguments: - event -- An empty dictionary. The session_start - event does not provide any additional - data. + :param dict event: An empty dictionary. The session_start + event does not provide any additional data. """ self.get_roster() self.send_presence() @@ -146,8 +160,9 @@ class MUCBot(slixmpp.ClientXMPP): # password=the_room_password, wait=True) - def register_bot_plugin(self, plugin_class): - self.plugins.append(plugin_class(self)) + :param `sid.plugin.Plugin` plugin_cls: A :py:obj:`sid.plugin.Plugin` class + """ + self.plugins.append(plugin_cls(self)) for name, value in inspect.getmembers(self.plugins[-1]): if inspect.ismethod(value) and getattr(value, '_bot_command', False): -- 2.39.2