Skip to content

Commit

Permalink
docs: add guide/lifecycle section; improved readability
Browse files Browse the repository at this point in the history
  • Loading branch information
blueset committed Jan 18, 2020
1 parent d0a5c54 commit f8e9c85
Show file tree
Hide file tree
Showing 18 changed files with 495 additions and 305 deletions.
41 changes: 19 additions & 22 deletions docs/API/channel.rst
Expand Up @@ -31,28 +31,25 @@ Statuses MUST be sent using :meth:`.coordinator.send_status`.
When the object is passed onto the coordinator, it will be
further processed by the middleware and then to its destination.


.. admonition:: Example

To send a message to the master channel

.. code-block:: python
def on_message(self, data: Dict[str, Any]):
"""Callback when a message is received by the slave channel from
the IM platform.
"""
# Prepare message content ...
message = coordinator.send_message(Message(
chat=chat,
author=author,
type=message_type,
text=text,
# more details ...
uid=data['uid'],
deliver_to=coordinator.master
))
# Post-processing ...
For example, to send a message to the master channel

.. code-block:: python
def on_message(self, data: Dict[str, Any]):
"""Callback when a message is received by the slave channel from
the IM platform.
"""
# Prepare message content ...
message = coordinator.send_message(Message(
chat=chat,
author=author,
type=message_type,
text=text,
# more details ...
uid=data['uid'],
deliver_to=coordinator.master
))
# Post-processing ...
About Channel ID
----------------
Expand Down
22 changes: 22 additions & 0 deletions docs/API/chat.rst
@@ -1,5 +1,27 @@
Chat and Chat Members
=====================

.. py:currentmodule:: ehforwarderbot.chat
.. rubric:: Inheritance diagram

.. inheritance-diagram:: ehforwarderbot.chat
:parts: 1

.. rubric:: Summary

.. autosummary::

PrivateChat
SystemChat
GroupChat
ChatMember
SelfChatMember
SystemChatMember
ChatNotificationState

.. rubric:: Modules

.. automodule:: ehforwarderbot.chat
:members:
:show-inheritance:
1 change: 1 addition & 0 deletions docs/API/index.rst
Expand Up @@ -6,6 +6,7 @@ current API of EH Forwarder Bot.

.. toctree::
:glob:
:maxdepth: 2

*

Expand Down
15 changes: 15 additions & 0 deletions docs/API/message.rst
@@ -1,5 +1,20 @@
Message
=======
.. py:currentmodule:: ehforwarderbot.message
.. rubric:: Summary

.. autosummary::

Message
LinkAttribute
LocationAttribute
StatusAttribute
MessageCommands
MessageCommand
Substitutions

.. rubric:: Classes

.. autoclass:: ehforwarderbot.message.Message
:members:
Expand Down
83 changes: 42 additions & 41 deletions docs/API/middleware.rst
Expand Up @@ -42,44 +42,45 @@ Chat-specific interactions
Middlewares can have chat-specific interactions through capturing messages
and reply to them with a chat member created by the middleware.

.. admonition:: Example

When the master channel sends a message with a text starts with ``time```,
the middleware captures this message and reply with the name of the chat
and current time on the server. The message captured is not delivered to
any following middlewares or the slave channel.

.. code-block:: python
def process_message(self: Middleware, message: Message) -> Optional[Message]:
if message.deliver_to != coordinator.master and \ # sent from master channel
text.startswith('time`'):
# Make a system chat object.
# For difference between `make_system_member()` and `add_system_member()`,
# see their descriptions above.
author = message.chat.make_system_member(
uid="__middleware_example_time_reporter__",
name="Time reporter",
middleware=self
)
# Make a reply message
reply = Message(
uid=f"__middleware_example_{uuid.uuid4()}__",
text=f"Greetings from chat {message.chat.name} on {datetime.now().strftime('%c')}.",
chat=chat,
author=author, # Using the new chat we created before
type=MsgType.Text,
target=message, # Quoting the incoming message
deliver_to=coordinator.master # message is to be delivered to master
)
# Send the message back to master channel
coordinator.send_message(reply)
# Capture the message to prevent it from being delivered to following middlewares
# and the slave channel.
return None
# Continue to deliver messages not matching the pattern above.
return message
The following code is an example of a middleware that interact with the user
by capturing messages.

When the master channel sends a message with a text starts with ``time```,
the middleware captures this message and reply with the name of the chat
and current time on the server. The message captured is not delivered to
any following middlewares or the slave channel.

.. code-block:: python
def process_message(self: Middleware, message: Message) -> Optional[Message]:
if message.deliver_to != coordinator.master and \ # sent from master channel
text.startswith('time`'):
# Make a system chat object.
# For difference between `make_system_member()` and `add_system_member()`,
# see their descriptions above.
author = message.chat.make_system_member(
uid="__middleware_example_time_reporter__",
name="Time reporter",
middleware=self
)
# Make a reply message
reply = Message(
uid=f"__middleware_example_{uuid.uuid4()}__",
text=f"Greetings from chat {message.chat.name} on {datetime.now().strftime('%c')}.",
chat=chat,
author=author, # Using the new chat we created before
type=MsgType.Text,
target=message, # Quoting the incoming message
deliver_to=coordinator.master # message is to be delivered to master
)
# Send the message back to master channel
coordinator.send_message(reply)
# Capture the message to prevent it from being delivered to following middlewares
# and the slave channel.
return None
# Continue to deliver messages not matching the pattern above.
return message
25 changes: 24 additions & 1 deletion docs/conf.py
Expand Up @@ -40,10 +40,14 @@
'sphinx.ext.viewcode',
'sphinx.ext.githubpages',
'sphinx.ext.napoleon',
'sphinx.ext.autosummary',
'sphinx.ext.graphviz',
'sphinx.ext.inheritance_diagram',
'sphinx.ext.autosectionlabel',
'sphinx.ext.intersphinx',
'sphinx_autodoc_typehints',
'sphinxcontrib.restbuilder']
'sphinxcontrib.restbuilder',
'sphinxcontrib.plantuml']

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Expand Down Expand Up @@ -115,6 +119,15 @@
# html_theme = 'readable'
# html_logo = "_static/logo.png"
html_theme = 'alabaster'
html_sidebars = {
'**': [
'about.html',
'navigation.html',
'relations.html',
'searchbox.html',
'donate.html',
]
}
html_theme_options = {
'logo': 'logo.png',
'logo_name': True,
Expand All @@ -127,6 +140,12 @@
'description': 'An extensible message tunneling chat bot framework.',
'donate_url': 'https://github.com/blueset/.github',
'github_banner': "github_banner.svg",
'show_related': True,
'show_relbars': True,
'extra_nav_links': {
'Community wiki': 'https://efb.1a23.studio/wiki',
'Modules repository': 'https://efb-modules.1a23.studio/',
}
}

# import sphinx_py3doc_enhanced_theme
Expand Down Expand Up @@ -239,6 +258,10 @@
# $HTTP_PROXY environment variable.
intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}

graphviz_output_format = "svg"
plantuml_output_format = "svg"
plantuml_latex_output_format = "pdf"

def setup(self):
self.config.language = conversion.get(self.config.language, self.config.language)
self.config.overrides['language'] = conversion.get(self.config.overrides.get('language', None),
Expand Down
100 changes: 48 additions & 52 deletions docs/config.rst
Expand Up @@ -40,34 +40,30 @@ so as to isolate instances.
Please avoid having two modules with the same set of module ID and instance ID
as it may leads to unexpected results.


.. admonition:: Example
:class: tip

To enable the following modules:

* Master channel
* Demo Master (``foo.demo_master``)
* Slave channels
* Demo Slave (``foo.demo_slave``)
* Dummy Slave (``bar.dummy``)
* Dummy Slave (``bar.dummy``) at ``alt`` instance
* Middlewares
* Message Archiver (``foo.msg_archiver``)
* Null Middleware (``foo.null``)

``config.yaml`` should have the following lines:

.. code-block:: yaml
master_channel: foo.demo_master
slave_channels:
- foo.demo_slave
- bar.dummy
- bar.dummy#alt
middlewares:
- foo.msg_archiver
- foo.null
For example, To enable the following modules:

* Master channel
* Demo Master (``foo.demo_master``)
* Slave channels
* Demo Slave (``foo.demo_slave``)
* Dummy Slave (``bar.dummy``)
* Dummy Slave (``bar.dummy``) at ``alt`` instance
* Middlewares
* Message Archiver (``foo.msg_archiver``)
* Null Middleware (``foo.null``)

``config.yaml`` should have the following lines:

.. code-block:: yaml
master_channel: foo.demo_master
slave_channels:
- foo.demo_slave
- bar.dummy
- bar.dummy#alt
middlewares:
- foo.msg_archiver
- foo.null
Granulated logging control
~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -77,31 +73,31 @@ by the framework and running modules, you can use specify the log
configuration with `Python's configuration dictionary schema`_ under
section ``logging``.

.. admonition:: Example

.. code-block:: yaml
logging:
version: 1
disable_existing_loggers: false
formatters:
standard:
format: '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
handlers:
default:
An example of logging control settings:

.. code-block:: yaml
logging:
version: 1
disable_existing_loggers: false
formatters:
standard:
format: '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
handlers:
default:
level: INFO
formatter: standard
class: logging.StreamHandler
stream: ext://sys.stdout
loggers:
'':
handlers: [default,]
level: INFO
formatter: standard
class: logging.StreamHandler
stream: ext://sys.stdout
loggers:
'':
handlers: [default,]
level: INFO
propagate: true
AliceIRCChannel:
handlers: [default, ]
level: WARN
propagate: false
propagate: true
AliceIRCChannel:
handlers: [default, ]
level: WARN
propagate: false
.. _Python's configuration dictionary schema: https://docs.python.org/3.7/library/logging.config.html#logging-config-dictschema

0 comments on commit f8e9c85

Please sign in to comment.