Skip to content

Commit

Permalink
[Docs] Add documentation for status' events to RTD
Browse files Browse the repository at this point in the history
* remove event docs from status.py
* internal re-organisation of docs file stuff
* add 1 sec wait for other cogs to perform expensive actions
  • Loading branch information
Vexed01 committed Mar 3, 2021
1 parent 1f7c679 commit 739d624
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 70 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 7 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ Welcome to Vex-Cogs's documentation!
:maxdepth: 2
:caption: Cogs:

anotherpingcog
aliases
status
system
cogs/anotherpingcog
cogs/aliases
cogs/status
cogs/system

If you're a developer, there are custom events you can listen to for :ref:`status_dev`.




Expand Down
97 changes: 97 additions & 0 deletions docs/status_dev.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
.. _status_dev:

======
Status
======

The status cog has two events you can listen to, ``on_vexed_status_update`` and
``on_vexed_status_channel_send``.

``status_channel_send`` is fired in quick succession, espscially on larger bots with
lots of channels added, so you shouldn't do anything expensive. ``status_channel_send``
is dispatched after a successful channel send.

``status_update`` is dispatched with the channels the cog intends to send updates to when
an update has been confirmed as a non-ghost update.

There is a guaranteed delay of 1 second between ``status_update`` and the first
``status_channel_send`` to allow you to perform an expensive process (eg get data
from config) and then cache the result for the when ``status_channel_send`` despatches
for each channel so you get the timing correct and you can guarantee it was sent.

Though this is incredibly unlikely, the cog will cancel sending updates (and the subsequent
``status_channel_send`` if it lasts longer than 1 minute and 50 seconds after
``status_update`` the update was detected.

Note that ``status_update`` will not trigger if no channels are subscribed to service -
the cog only checks feeds that have channels subscribed to it.

In terms of testing, the ``devforcestatus`` (alias ``dfs`` command can be used for this.
It simulates an actual/organic update as closely as possible so sends to all registered
channels. The ``force`` parameter will be ``True`` in such cases.


.. function:: on_vexed_status_update(feed, fp_data, service, channels, force)

This event triggers before updates are sent to channels. See above for details.

:type feed: :class:`dict`
:param feed: A fully parsed dictionary with individual updates in the incident
split up.

.. note::
The time the ``time`` key should be a datetime object but it could
be something else. Make sure you handle this.
.. note::
Some feeds only supply the latest update. See the file-level const
``AVALIBLE_MODES`` in ``status.py``.
.. note::
The majority of updates are in the incorrect order in the ``field`` key.
They will need reversing if you are using this key. See file-level const
``DONT_REVERSE`` in ``status.py`` for ones that don't need it.
:type fp_data: :class:`FeedParserDict`
:param fp_data: The raw data from feedparser. The above ``feed`` is reccomended
where possible.
:type service: :class:`str`
:param service: The name of the service, in lower case. Guaranteed to be on of
the keys in the file-level consts of ``status.py``, though new services are
being added over time so don't copy-paste and expect it to be one of them.
:type channels: :class:`dict`
:param channels: A dict with the keys as channel IDs and the values as a nested
dict contaning the settings for that channel.
:type force: :class`bool`
:param force: Whether or not the update was forced to update with
``devforcestatus``/``dfs``

.. function:: on_vexed_status_channel_send(feed, service, channel, webhook, embed)

This is has similarties and differnces to the above feed, mainly that it has less
data and dispatches after an update was successfully sent to a specific channel.
See above info at the top of this page for details.

:type feed: :class:`dict`
:param feed: A fully parsed dictionary with individual updates in the incident
split up.

.. note::
The time the ``time`` key should be a datetime object but it could
be something else. Make sure you handle this.
.. note::
Some feeds only supply the latest update. See the file-level const
``AVALIBLE_MODES`` in ``status.py``.
.. note::
The majority of updates are in the incorrect order in the ``field`` key.
They will need reversing if you are using this key. See file-level const
``DONT_REVERSE`` in ``status.py`` for ones that don't need it.
:type service: :class:`str`
:param service: The name of the service, in lower case. Guaranteed to be on of
the keys in the file-level consts of ``status.py``, though new services are
being added over time so don't copy-paste and expect it to be one of them.
:type channel: :class:`discord.TextChannel`
:param channel: The discord.TextChannel object the update was successfully sent to.
:type webhook: :class:`bool`
:param webhook: Whether or not the update was sent as a webhook.
:type embed: :class:`bool`
:param embed: Whether or not the update was sent as an embed. Will always be ``True``
if ``webhook`` is ``True``.

75 changes: 9 additions & 66 deletions status/status.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# HELLO!
# This file is formatted with black, line length 120
# If you are looking for an event your cog can listen to, take a look around lines 170 and 210
# If you are looking for an event your cog can listen to, take a look here:
# [link here]

import asyncio
import datetime
Expand Down Expand Up @@ -181,7 +182,7 @@ async def _check_for_updates(self):
await asyncio.wait_for(self._actually_check_updates(), timeout=110.0) # 1 min 50 secs
except TimeoutError:
log.error(
"Loop timed out after 2 minutes 20 seconds. Will try again shortly. If this keeps happening "
"Loop timed out after 1 minute 50 seconds. Will try again shortly. If this keeps happening "
"when there's an update for a specific service, contact Vexed."
)
except Exception as e:
Expand All @@ -197,38 +198,8 @@ async def before_start(self):

async def _update_dispatch(self, feed, feedparser, service, channels, force):
"""
This can be used by anyone. If you wish to test it, run the hidden command
`devforcestatus` in discord (alias `dfs`).
Please note this will NOT trigger if no channels have registered the service
you are looking for.
This event is triggered BEFORE any updates are sent to channels.
This event can trigger multiple times in short sucession due to how this cog
works.
Parameters
----------
feed : dict
A fully parsed dict with individual updates split up
NOTE: The time the feed was published may be a datetime object OR
something else. Make sure you can handle this
NOTE: Some feeds only supply the latest update. See the file-level
const AVALIBLE_MODES.
NOTE: The majority of feeds are in the incorrect order. They need
reversing. See file-level const DONT_REVERSE.
feedparser : FeedParserDict
The raw dict from feedparser. Unless there's specific data you need,
I highly reccomend using the above `feed` where possible.
service : str
The service name. Guaranteed to be one of the keys in the FEED_URLS
file-level const (unless dev commands are used)
channels : dict
A dict with the keys as channel IDs and the values as another dict contining
the settings for that channel.
force : bool
Whether or not the feed was forced to update with the `devforcestatus`/`dfs`
command.
For more information on this event, take a look at the docs:
[link here]
"""
self.bot.dispatch(
"vexed_status_update",
Expand All @@ -241,37 +212,8 @@ async def _update_dispatch(self, feed, feedparser, service, channels, force):

async def _channel_send_dispatch(self, feed, service, channel, webhook, embed):
"""
This can be used by other cogs. For testing, run the hidden comman
`devforcestatus` in discord (alias `dfs`).
This event is triggered AFTER the update has been sent to channel and will
NOT be triggered if it failed to send.
Due to this, this event will trigger in burts, many times a second.
If you need the raw feed data from feedparser, take a look at the above event.
Unlike the above event, this does not distinguish between forced and organic
triggers
Parameters
----------
feed : dict
A fully parsed dict with individual updates split up
NOTE: The time the feed was published may be a datetime object OR
something else. Make sure you can handle this
NOTE: Some feeds only supply the latest update. See the file-level
const AVALIBLE_MODES
NOTE: The majority of feeds that support all updates of the incidents
need reversing. See file-level const DONT_REVERSE
service : str
The service name. Guaranteed to be one of the keys in the FEED_URLS
file-level const (unless dev commands are used)
channel : discord.TextChannel
The discord.TextChannel object the update was sent to
webhook : bool
Whether or not the feed was sent as a webhook
embed : bool
Whether or not the feed was sent as a embed. Will always be True if
embed is True
For more information on this event, take a look at the docs:
[link here]
"""
self.bot.dispatch(
"vexed_status_channel_send",
Expand Down Expand Up @@ -344,8 +286,9 @@ async def _actually_check_updates(self):
continue
# log.debug(f"Feed dict for {service}: {feeddict}")
channels = await self._get_channels(service)
await self._update_dispatch(feeddict, fp_data, service, channels, False)
await self._make_send_cache(feeddict, service)
await self._update_dispatch(feeddict, fp_data, service, channels, False)
await asyncio.sleep(1) # guaranteed wait for other CCs
log.debug(f"Sending status update for {service} to {len(channels)} channels...")
for channel in channels.items():
await self._send_updated_feed(feeddict, channel, service)
Expand Down

0 comments on commit 739d624

Please sign in to comment.