a7c62223ea
Ignore-this: bff39c43073f3576e31bda52b7383e6b - Link URL matching no longer requires the URL to be at the beginningfront of the line - Includes test case and documentation fix. darcs-hash:20101227093449-82ea9-727739b99ac86256216350b90dc3e710ea181f51.gz
927 lines
33 KiB
Plaintext
927 lines
33 KiB
Plaintext
====================================================
|
|
MeetBot, a supybot plugin for IRC meeting notetaking
|
|
====================================================
|
|
|
|
|
|
|
|
MeetBot is a plugin to the IRC bot supybot to facilitate taking of
|
|
notes during IRC meetings. This allows you to better communicate with
|
|
your project or groups after the IRC meeting, as well as keep the
|
|
meeting more under control and on-topic.
|
|
|
|
.. contents::
|
|
|
|
|
|
|
|
|
|
Tutorial
|
|
========
|
|
|
|
Let's go through, step by step, how a typical meeting might run::
|
|
|
|
< MrBeige> #startmeeting
|
|
|
|
We use the ``#startmeeting`` command to tell MeetBot to start the
|
|
meeting. The person who calls the command becomes the chair - having
|
|
the power to guide the meeting. However, by default MeetBot allows
|
|
other participants to enter most things into the logs, since inviting
|
|
contributions is generally a good thing.::
|
|
|
|
< MeetBot> Meeting started Wed Jun 17 05:00:49 2009 UTC. The chair
|
|
is MrBeige.
|
|
< MeetBot> Information about MeetBot at
|
|
http://wiki.debian.org/MeetBot , Useful Commands: #action
|
|
#agreed #halp #info #idea #link #topic.
|
|
|
|
MeetBot gives us a little bit of information about the meeting.::
|
|
|
|
< MrBeige> #topic should we release or not?
|
|
-!- MeetBot changed the topic of #meetbot-test to: should we release
|
|
or not?
|
|
|
|
We use the ``#topic`` command to tell MeetBot to move to the first
|
|
topic. MeetBot sets the topic in the channel to the topic which is
|
|
given on the line. Don't worry, the topic will be restored at the end
|
|
of the meeting.::
|
|
|
|
< MrBeige> #info we have two major blocking bugs: the character set
|
|
conversion, and the segfaults heisenbug in the save
|
|
routine.
|
|
|
|
When there is important things said, we don't want them to be lost in
|
|
the irclogs. Thus, we use the ``#info`` command to make a note of
|
|
it in the meeting minutes. It is also highlighted in the irclogs
|
|
which MeetBot takes.::
|
|
|
|
< MrBeige> #agreed we give one week to fix these (no other changes
|
|
accepted), and then release
|
|
|
|
We also have the ``#agreed`` command to use. This can only be used by
|
|
the chairs of the meeting, and should (obviously) be used to document
|
|
agreement. The rest of the line goes into the minutes as the thing
|
|
agreed on.::
|
|
|
|
< MrBeige> #action MrGreen and MrMauve work together to fix the bugs
|
|
< MrBeige> #action MrBeige releases when done
|
|
|
|
We have the ``#action`` command. This one is works just like the last
|
|
two, but has one extra feature: at the end of the meeting, it makes a
|
|
list of "Action Items", useful for being sure things get taken care
|
|
of. But there is more: it also makes a list of action items sorted by
|
|
*nick*. This can be used to easily see what is assigned to you. In
|
|
order for an item to be sorted by a nick, that nick has got to say
|
|
something during the meeting (but also see the ``#nick`` command), and
|
|
you have to use their nick exactly (use tab completion!).::
|
|
|
|
< MrBeige> #topic goals for release after next
|
|
-!- MeetBot changed the topic of #meetbot-test to: goals for release
|
|
after next
|
|
|
|
Moving on to the next topic...::
|
|
|
|
...
|
|
< MrBeige> #info make it better
|
|
...
|
|
< MrBeige> #info release faster
|
|
...
|
|
|
|
Record some of the important items from this section.::
|
|
|
|
< MrBeige> #endmeeting
|
|
|
|
Hit the ``#endmeeting`` command. The meeting ends, and logs and
|
|
minutes are saved::
|
|
|
|
-!- MeetBot changed the topic of #meetbot-test to: General
|
|
discussion of MeetBot
|
|
< MeetBot> Meeting ended Wed Jun 17 05:03:45 2009 UTC. Information
|
|
about MeetBot at http://wiki.debian.org/MeetBot .
|
|
< MeetBot> Minutes: http://rkd.zgib.net/meetbot/meetbot-test/meetbot-test.html
|
|
< MeetBot> Log: http://rkd.zgib.net/meetbot/meetbot-test/meetbot-test.log.html
|
|
|
|
MeetBot conveniently tells us where all of the logs are stored. You
|
|
can look at the `logs`_ and `minutes`_ online.
|
|
|
|
.. _logs: http://rkd
|
|
.. _minutes: http://rkd
|
|
|
|
|
|
|
|
|
|
User reference
|
|
==============
|
|
|
|
Commands
|
|
--------
|
|
|
|
All commands are case-insensitive, and use the ``#`` prefix
|
|
character. Not all commands have output. This might be confusing,
|
|
because you don't know if it's been acted on or not. However, this is
|
|
a conscious design decision to try to keep out of the way and not
|
|
distract from the real people. If something goes wrong, you can
|
|
adjust and have MeetBot re-process the logs later.
|
|
|
|
#startmeeting
|
|
Starts a meeting. The calling nick becomes the chair. If any text
|
|
is given on the rest of the line, this becomes the meeting topic,
|
|
see ``#meetingtopic`` above.
|
|
|
|
#endmeeting
|
|
End a meeting, save logs, restore previous topic, give links to
|
|
logs. You know the drill. (Chairs only.)
|
|
|
|
#topic
|
|
Set the current topic of discussion. MeetBot changes the topic in
|
|
the channel (saving the original topic to be restored at the end of
|
|
the meeting). (Chairs only.)
|
|
|
|
#agreed (alias #agree)
|
|
Mark something as agreed on. The rest of the line is the details.
|
|
(Chairs only.)
|
|
|
|
#chair and #unchair
|
|
Add new chairs to the meeting. The rest of the line is a list of
|
|
nicks, separated by commas and/or spaces. The nick which started
|
|
the meeting is the ``owner`` and can't be de-chaired. The command
|
|
replies with a list of the current chairs, for verification (Chairs
|
|
only.) Example::
|
|
|
|
< MrBeige> #chair MrGreen MsAlizarin
|
|
< MeetBot> Current chairs are: MsAlizarin MrBeige MrGreen
|
|
|
|
#action
|
|
|
|
Add an ``ACTION`` item to the minutes. Provide irc nicks of people
|
|
involved, and will be both a complete listing of action items, and a
|
|
listing of action items sorted by nick at the end of the meeting.
|
|
This is very useful for making sure this gets done. Example::
|
|
|
|
< MrBeige> #action MrGreen will read the entire Internet to
|
|
determine why the hive cluster is under attack.
|
|
|
|
If MrGreen has said something during the meeting, this will be
|
|
automatically assigned to him.
|
|
|
|
#info
|
|
Add an ``INFO`` item to the minutes. Example::
|
|
|
|
< MrBeige> #info We need to spawn more overlords before the next
|
|
release.
|
|
|
|
#link
|
|
|
|
Add a link to the minutes. The URL will be properly detected within
|
|
the line in most cases - the URL can't contain spaces. This command
|
|
is automatically detected if the line starts with http:, https:,
|
|
mailto:, and some other common protocols defined in the
|
|
``UrlProtocols`` configuration variable. Examples::
|
|
|
|
< MrBeige> #link http://wiki.debian.org/MeetBot/ is the main page
|
|
< MrBeige> http://wiki.debian.org/MeetBot/ is the main page
|
|
< MrBeige> #link the main page is http://wiki.debian.org/MeetBot/
|
|
so go there
|
|
< MrBeige> the main page is http://wiki.debian.org/MeetBot/ so go
|
|
there. (This will NOT be detected automatically)
|
|
|
|
|
|
|
|
|
|
Less-used commands
|
|
------------------
|
|
|
|
#meetingtopic
|
|
Sets the "meeting topic". This will always appear in the topic in
|
|
the channel, even as the #topic changes. The format of the IRCtopic
|
|
is "<topic> (Meeting Topic: <meeting topic>)". (Chairs only.)
|
|
|
|
#commands
|
|
List recognized supybot commands. This is the actual "help" command.
|
|
|
|
#idea
|
|
Add an ``IDEA`` to the minutes.
|
|
|
|
#help (alias #halp)
|
|
Add a ``HELP`` item to the minutes. Confusingly, this does *not* give
|
|
supybot help. See #commands.
|
|
|
|
#accepted (alias #accept)
|
|
Mark something as accepted. The rest of the line is the details.
|
|
(Chairs only.)
|
|
|
|
#rejected (alias #reject)
|
|
Mark something as rejected. The rest of the line is the details.
|
|
(Chairs only.)
|
|
|
|
#save
|
|
Write out the logs right now. (Chairs only.)
|
|
|
|
#nick
|
|
Make a nick be recognized by supybot, even though it hasn't said
|
|
anything. This is only useful in order to make a list of action
|
|
items be grouped by this nick at the end of the meeting.
|
|
|
|
#undo
|
|
Remove the last item from the meeting minutes. Only applies to
|
|
commands which appear in the final output. (Chairs only.)
|
|
|
|
#restrictlogs
|
|
When logs are saved, remove the permissions specified in the
|
|
configuration variable ``RestrictPerm``. (Chairs only.)
|
|
|
|
#lurk and #unlurk
|
|
When ``lurk`` is set, MeetBot will only passively listen and take
|
|
notes (and save the notes), not reply or change the topic This is
|
|
useful for when you don't want disruptions during the meeting.
|
|
(Chairs only.)
|
|
|
|
#meetingname
|
|
Provide a friendly name which can be used as a variable in the
|
|
filename patterns. For example, you can set
|
|
filenamePattern = '%(channel)s/%%Y/%(meetingname)s.%%F-%%H.%%M'
|
|
to allow #meetingname to categorize multiple types of meeting
|
|
occurring in one channel.
|
|
|
|
All spaces are removed from the rest of the line and the string is
|
|
converted to lowercase. If ``meetingname`` is not provided, it
|
|
defaults to ``channel``. (Chairs only.)
|
|
|
|
|
|
|
|
|
|
Hints on how to run an effective meeting
|
|
----------------------------------------
|
|
|
|
*Please contribute to this section!*
|
|
|
|
* Have an agenda. Think about the agenda beforehand, so that
|
|
attendees are not tempted to jump ahead and discuss future items.
|
|
This will make it very hard to follow.
|
|
* *Liberally* use the ``#action`` command, making sure to include the
|
|
nick of the person responsible. It will produce an easy-to-scan
|
|
list of things to do, as well as a sorted-by-nick version. This
|
|
will make these things more likely to get done.
|
|
* In the same spirit, liberally use ``#info`` on important pieces of
|
|
data. If you think you'll want to refer to it again, ``#info``
|
|
it. Assigning someone to watch the meeting to ``#info`` other
|
|
people's lines (if they forget) usually pays off.
|
|
* Don't be afraid to tell attendees to wait for a future topic to
|
|
discuss something.
|
|
* Delegate where possible and have those interested discuss the
|
|
details after the meeting, where applicable. No need to take
|
|
everyone's time if not everyone needs to decide. (This only
|
|
applies to some types of meetings)
|
|
* Sometimes one chair to manage the topic at hand, and one chair to
|
|
manage all people who are going off-topic, can help.
|
|
|
|
|
|
|
|
|
|
Administrators
|
|
==============
|
|
|
|
Overview
|
|
--------
|
|
|
|
Unfortunately, MeetBot seems a bit complex to configure. In order to
|
|
keep things straight, keep this in mind: MeetBot has two distinct
|
|
pieces. The first (``meeting.py`` and friends) is the meeting parser
|
|
and note/logfile generator. This part can run independently,
|
|
*without* the supybot plugin. The second part interfaces the core
|
|
``meeting.py`` to supybot, to make it usable via IRC.
|
|
|
|
When reading about how to run MeetBot, keep this in mind, and if
|
|
something is applicable to ``meeting.py`` features, just supybot
|
|
features, or both.
|
|
|
|
This design split greatly increases modularity (a "good thing"), and
|
|
also allows the Replay functionality. It should also allow other bot
|
|
plugins to easily be written.
|
|
|
|
|
|
|
|
|
|
Replay functionality
|
|
--------------------
|
|
|
|
Let's say you had a meeting which happened a while ago, and you would
|
|
like to update the logs to a newer format. If supybot was the only
|
|
way to use MeetBot, you'd be out of luck. Luckily, there is an
|
|
independent way to replay meetings::
|
|
|
|
python /path/to/meeting.py replay /path/to/old_meeting.log.txt
|
|
|
|
You run the meeting.py file as a script, giving the subcommand
|
|
``replay`` and then a path to a ``.log.txt`` file from a previous
|
|
meeting (or from some other source of IRC logs, it's essentially the
|
|
irssi/xchat format). It parses it and processes the meeting, and
|
|
outputs all of the usual ``.html``, ``.log.html``, and so on files in
|
|
the directory parallel to the input file.
|
|
|
|
This is useful if you want to upgrade your output formats, MeetBot
|
|
broke and you lost the realtime log and want to generate a summary
|
|
using your own logfiles, remove or change something in the logs that
|
|
was incorrect during the meeting. As such, this is an important
|
|
feature of MeetBot.
|
|
|
|
However, this does make configuration changes harder. Since the
|
|
replay function works *independent* of supybot, any configuration that
|
|
is done in supybot will be invisible to the replay function. Thus, we
|
|
have to have a non-supybot mechanism of configuring MeetBot. There
|
|
was a supybot way of configuring MeetBot added later, which can adjust
|
|
most variables. However, if something is configured here, it won't be
|
|
seen if a file is replayed. This might be OK, or it might not be,
|
|
depending on the variable.
|
|
|
|
|
|
|
|
|
|
Configuration
|
|
-------------
|
|
|
|
meetingLocalConfig.py configuration
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
This is the non-supybot method of configuration, and allows the most
|
|
flexibility. **It works for configuring supybot, too**, but requires
|
|
shell access and a MeetBot reload to change.
|
|
|
|
Configuration is done by creating a file ``meetingLocalConfig.py`` in
|
|
the plugin directory, or somewhere in your PYTHONPATH. It works by
|
|
(automatically, not user-visible) subclassing the Config class.
|
|
|
|
Here is a minimal usage example. You need at *least* this much to
|
|
make it run. Put this in ``meetingLocalConfig.py`` before you first
|
|
start supybot::
|
|
|
|
class Config(object):
|
|
# These two are **required**:
|
|
logFileDir = '/home/richard/meetbot/'
|
|
logUrlPrefix = 'http://rkd.zgib.net/meetbot/'
|
|
|
|
Two other more commonly used options are::
|
|
|
|
filenamePattern = '%(channel)s/%%Y/%(channel)s.%%F-%%H.%%M'
|
|
MeetBotInfoURL = 'http://some_other_side.tld'
|
|
|
|
Place all of the configuration variables inside of the class
|
|
body like this.
|
|
|
|
``meetingLocalConfig.py`` is imported via python, so all the usual
|
|
benefits and caveats of that apply. It causes a subclass of the main
|
|
Config object. Thus, you can do some advanced (or just crazy) things
|
|
like add a new meeting command, meeting agenda item type, or more.
|
|
Some of these ideas are documented under the "Advanced configuration"
|
|
section below.
|
|
|
|
To reload a configuration in a running supybot, you can just reload
|
|
the plugin in supybot --- the module is reloaded. Specifically,
|
|
``/msg YourBotName reload MeetBot``.
|
|
|
|
|
|
|
|
Supybot-based config
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
This is the system that configures MeetBot based on the supybot
|
|
registry system. Thus, it can be adjusted by anyone with the proper
|
|
supybot capabilities. However, the configuration in the supybot
|
|
registry *won't* be used if the ``replay`` functionality is used (see
|
|
above). Thus, for example, if you configure the MediaWiki writer
|
|
using ``supybot.plugins.MeetBot.writer_map``, and then ``replay`` the
|
|
meeting, the MediaWiki output will *not* be updated.
|
|
|
|
To enable this system, first the
|
|
``supybot.plugins.MeetBot.enableSupybotBasedConfig`` variable must be
|
|
set to True. Then the MeetBot plugin must be reloaded::
|
|
|
|
/msg YourBot config supybot.plugins.MeetBot.enableSupybotBasedConfig True
|
|
/msg YourBot reload MeetBot
|
|
|
|
Now you can list the values available for configuration (the list
|
|
below may not be up to date)::
|
|
|
|
/msg YourBot config list supybot.plugins.MeetBot
|
|
----> #endMeetingMessage, #filenamePattern, #input_codec,
|
|
#logFileDir, #logUrlPrefix, #MeetBotInfoURL, #output_codec,
|
|
#pygmentizeStyle, #specialChannelFilenamePattern,
|
|
#startMeetingMessage, #timeZone, #usefulCommands,
|
|
enableSupybotBasedConfig, and public
|
|
|
|
Setting a value for a variable::
|
|
|
|
/msg YourBot config supybot.plugins.MeetBot.logUrlPrefix http://meetings.yoursite.net/
|
|
|
|
Most variables (those with # prepended) can be set on a per-channel
|
|
basis (they are set up as channel-specific variables).
|
|
|
|
|
|
At present, not all variables are exported to supybot. All string and
|
|
boolean variables are, as well certain other variables for which a
|
|
wrapper has been written (``writer_map`` in particular). If a
|
|
variable doesn't appear in the supybot registry, it can't be set via
|
|
the registry.
|
|
|
|
If you want to disable supybot-based config for security reasons, set
|
|
``dontBotConfig`` to True in your custom configuration class in
|
|
``meetingLocalConfig.py``.
|
|
|
|
|
|
|
|
Required or important configuration
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
These variables are set either in ``meetingLocalConfig.py`` (in the
|
|
``Config`` class) or in the supybot registry.
|
|
|
|
``logFileDir``
|
|
The filesystem directory in which the meeting outputs are stored,
|
|
defaulting to ".". **Required**.
|
|
|
|
``logUrlPrefix``
|
|
The URL corresponding to ``logFileDir``. This is prepended to
|
|
filenames when giving end-of-meeting links in the channel.
|
|
**Required** or supybot's URLs will be missing.
|
|
|
|
``filenamePattern``
|
|
This defaults to ``'%(channel)s/%%Y/%(channel)s.%%F-%%H.%%M'``,
|
|
and is the pattern used for replacements to identify the name of
|
|
the file basename (including possible sub-directories) in which to
|
|
store the meeting output files. This is the suffix to
|
|
``logFileDir`` and ``logUrlPrefix``.
|
|
|
|
Variables available for replacement using ``%(name)s`` include:
|
|
``channel``, ``network``, ``meetingname``. Double percent signs
|
|
(e.g.: ``%%Y`` are time formats, from ``time.strftime``.
|
|
|
|
You should *not* include filename extensions here. Those are
|
|
found from the writers, via the variable ``writer_map``.
|
|
|
|
Putting these all together, a set of variables could be:
|
|
1) ``logFileDir = /srv/www/meetings/``
|
|
2) ``%(channel)s/%%Y/%(channel)s.%%F-%%H.%%M``
|
|
3) (``.html``, ``.txt``, etc, extensions come from ``writers_map``)
|
|
|
|
``MeetBotInfoURL``
|
|
This is a URL given in beginning and ending messages and minutes
|
|
files as a "go here for more information" link.
|
|
|
|
|
|
writer_map configuration
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
``writer_map`` tells how we want to output the results of the meeting.
|
|
It is, as you can guess, a mapping from filename extensions
|
|
(``.html``, ``.log.html``, ...) to what we want to output to that file
|
|
(``writers.HTML``, ``writers.HTMLlog``, ...)
|
|
|
|
Using ``meetingLocalConfig.py``, it is python dictionary listing what
|
|
output formats will be used to write our final results to a file,
|
|
along with extensions to use. For example, in
|
|
``meetingLocalConfig.py``::
|
|
|
|
import writers
|
|
|
|
class Config:
|
|
writer_map = {
|
|
'.log.html':writers.HTMLlog,
|
|
'.html': writers.HTML,
|
|
'.txt': writers.RST,
|
|
'.mw':writers.MediaWiki,
|
|
}
|
|
|
|
If an extension begins in ``.none`` the output will *not* be written
|
|
to a file. Note that you can't have the same extension multiple times
|
|
due to the way python dictionaries work: use ``.none1``, ``.none2``,
|
|
etc.
|
|
|
|
This *can* be configured through supybot. To do this, set
|
|
``supybot.plugins.MeetBot.writer_map`` to a space-separated list of
|
|
``WriterName:.extension`` pairs (note the different ordering from the
|
|
python dictionary). For example, to list the current setting (in
|
|
private message with the bot)::
|
|
|
|
<MrBeige> config plugins.MeetBot.writer_map
|
|
<MeetBot> HTML2:.html MediaWiki:.mw HTMLlog2:.log.html Text:.txt
|
|
|
|
And to set it (again, in private message with the bot)::
|
|
|
|
<MrBeige> config plugins.MeetBot.writer_map HTML2:.html MediaWiki:.mw HTMLlog2:.log.html Text:.txt
|
|
|
|
There is a special way to pass arguments to writers. Learn by
|
|
example::
|
|
|
|
writer_map = {
|
|
'.mw|mwsite=http://site.net|mwpath=Meetings':writers.MediaWiki,
|
|
}
|
|
|
|
or via supybot::
|
|
|
|
config plugins.MeetBot.writer_map MediaWiki:.mw|mwsite=http://site.net|mwpath=Meetings
|
|
|
|
|
|
|
|
|
|
|
|
The available writers are (with default extensions, if enabled by
|
|
default):
|
|
|
|
``TextLog`` (``.log.txt``)
|
|
Plain-text logs suitable for replaying. This does **not** have to
|
|
be explicitly enabled listed-- it is automatically enabled
|
|
whenever it is needed (currently, only when a meeting comes
|
|
realtime from supybot, not when being replayed)
|
|
|
|
``HTMLlog`` (``.log.html``)
|
|
Alias for the current default HTML-pretty logs output format,
|
|
currently ``HTMLlog2``.
|
|
|
|
``HTMLlog2``
|
|
Writes the logs in a HTML-pretty, CSS-customizable way (see section
|
|
below).
|
|
|
|
``HTML`` (``.html``)
|
|
Alias for the current default HTML output format for the meeting
|
|
notes, currently ``HTML2``.
|
|
|
|
``HTML2``
|
|
Meeting notes, in a numbered list HTML output format.
|
|
Configurable via CSS (see section below).
|
|
|
|
``Text`` (``.txt``)
|
|
A meeting notes format, as a plain text file
|
|
|
|
``MediaWiki``
|
|
MediaWiki output.
|
|
|
|
The MediaWiki writer has the
|
|
ability to upload to a MediaWiki site directly. You use the
|
|
custom variables ``mwsite``: site name to upload to, ``mwpath``:
|
|
subpage to upload to (final location is
|
|
``%(mwpath)/%(file_basename)), ``mwusername`` and ``mwpassword``:
|
|
username and password to log in as.
|
|
|
|
An upload is attempted if ``mwsite`` is given. A login is
|
|
attempted if ``mwusername`` is given. An example configuration::
|
|
|
|
writer_map = {
|
|
'.mw|mwsite=http://site.net|mwpath=Meetings':writers.MediaWiki,
|
|
}
|
|
|
|
``PmWiki``
|
|
PmWiki output. This doesn't upload *to* a PmWiki instance,
|
|
but that could be added later.
|
|
|
|
``Template``
|
|
This writer allows a user-defined template to used to output the
|
|
meeting logs. This allows complete control of the output by
|
|
embedding special tags into templates. This writer depends on the
|
|
`Genshi templating engine`_. For information on how the
|
|
templating engine works, please see its website or the example
|
|
templates provided.
|
|
|
|
.. _`Genshi templating engine`: http://genshi.edgewall.org/
|
|
|
|
To use the templating engine, you must specify the template file
|
|
to use. This is done via a special argument syntax. Instead of
|
|
an file extension name, the extension should be specified as
|
|
``.EXTENSION_NAME|template=TEMPLATE_FILE``, with the metavariables
|
|
explaining what the parts do. For example, in
|
|
``meetingLocalConfig.py`` one would do::
|
|
|
|
class Config:
|
|
writer_map = {
|
|
...
|
|
'.tmpl.txt|template=+template.txt' = writers.Template,
|
|
}
|
|
|
|
When setting a template writer by the suybot registry, one would do::
|
|
|
|
/msg YourBot config plugins.MeetBot.writer_map <other writers> Template:.EXTENSION_NAME|template=TEMPLATE_FILE ...
|
|
|
|
``TEMPLATE_FILE`` is an absolute or relative filename. As a
|
|
special case, ``+TEMPLATE_NAME`` can be used to specify a path
|
|
relative to the MeetBot source directory. This is used to include
|
|
the default templates: ``+template.html`` or ``+template.txt`` .
|
|
|
|
|
|
Obsolete writers are:
|
|
|
|
``HTMLlog1``
|
|
Old HTML writer. This one requires the Python module ``pygments``
|
|
to be installed. HTMLlog2 was written to remove this dependency.
|
|
HTMLlog2 is just as pretty as this is, and HTMLlog2 is
|
|
configurable via CSS.
|
|
|
|
``HTML1``
|
|
Old, table-based HTML writer.
|
|
|
|
``ReST``
|
|
ReStructured Text output. Since ReStructured Text is a bit strict
|
|
in it's parser, user input from the IRC meeting will often mess up
|
|
the conversion, and thus this isn't recommended for true use until
|
|
better escape functions can be written. (There is no security
|
|
risk from this plugin, ReST is run in secure mode).
|
|
|
|
``HTMLfromReST``
|
|
This runs the ReStructured Text writer, and uses ``docutils`` to
|
|
convert it to HTML. This requires the ``docutils`` package of
|
|
Python to be installed.
|
|
|
|
|
|
|
|
Other config variables
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
These variables are set either in ``meetingLocalConfig.py`` (in the
|
|
``Config`` class) or in the supybot registry.
|
|
|
|
``RestrictPerm``
|
|
An int listing which permissions to remove when using the
|
|
``#restrictlogs`` command. It is best to use the python ``stat``
|
|
module to set it::
|
|
|
|
RestrictPerm = stat.S_IRWXO|stat.S_IRWXG
|
|
|
|
``specialChannels`` and ``specialChannelFilenamePattern``
|
|
When you are doing MeetBot testing, you would rather not have
|
|
nonstop different filenames each time you do a test meeting.
|
|
If a channel is in ``specialChannels``, it will use
|
|
``specialChannelFilenamePattern`` instead of ``filenamePattern``
|
|
when storing logs. ``specialChannels`` is a tuple listing channel
|
|
names. Example: the defaults are ``("#meetbot-test",
|
|
"#meetbot-test2")`` and ``'%(channel)s/%(channel)s'`` (note that
|
|
there is no time-dependence in the name).
|
|
|
|
``UrlProtocols``
|
|
Tuple of protocols to use to automatically detect link. Example:
|
|
the default tuple is ``('http:', 'https:', 'irc:', 'ftp:',
|
|
'mailto:', 'ssh:')``.
|
|
|
|
``command_RE``
|
|
How commands are detected. See code.
|
|
|
|
``pygmentizeStyle``
|
|
Style for the Pygments module to use to colorize the IRC logs.
|
|
The default is ``"friendly"``.
|
|
|
|
``timeZone``
|
|
Timezone used in the bot. Note: This will not yet work on a
|
|
per-channel basis. The default is ``"UTC"``
|
|
|
|
``update_realtime``
|
|
If this is set to true (default false), then upon each line being
|
|
input, the ``Text`` writer will rewrite the data. This means that
|
|
people joining the meeting late can catch up on what they have
|
|
missed. It doesn't play will with the #meetingname command, since
|
|
the filename would then change during the meeting, and it doesn't
|
|
delete the old filename(s).
|
|
|
|
``startMeetingMessage``
|
|
|
|
``endMeetingMessage``
|
|
Message printed at the beginning/end of the meetings. Some
|
|
``%(name)s`` replacements are available: ``chair``, ``starttime``,
|
|
``timeZone``, ``endtime``, ``MeetBotInfoURL``, ``urlBasename``.
|
|
|
|
``input_codec``
|
|
|
|
``output_codec``
|
|
Input and output character set encodings.
|
|
|
|
``writer_map``
|
|
See the description in the section above.
|
|
|
|
``cssFile_minutes`` and ``cssFile_log``
|
|
|
|
If given, this is a file containing CSS for the .html and
|
|
.log.html outputs (HTML2 and HTMLlog2 writers). Embedding control
|
|
is described below.
|
|
|
|
If this value is the null string or 'default', then the default
|
|
CSS is used (see css-\*-default.css in the MeetBot distribution).
|
|
If this value is 'none', then no stylesheet information is written
|
|
whatsoever.
|
|
|
|
Note that for when embedded (see below), ``cssFile`` should be a
|
|
filesystem path readable locally. When you are *not* embedding,
|
|
``cssFile`` should be the URL to the stylesheet, and this value
|
|
given is included literally to the output.
|
|
|
|
``cssEmbed_minutes`` and ``cssEmbed_log``
|
|
|
|
If these are True, then the contents of ``cssFile`` (above) are
|
|
read and embedded into the HTML document. If these are False,
|
|
then a stylesheet link is written.
|
|
|
|
|
|
|
|
Advanced configuration
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
This gives a few examples of things you can do via
|
|
``meetingLocalConfig.py``. Most people probably won't need these
|
|
things, and they aren't thoroughly explained here.
|
|
|
|
You can make a per-channel config::
|
|
|
|
class Config(object):
|
|
def init_hook(self):
|
|
if self.M.channel == '#some-channel':
|
|
self.logFileDir = '/some/directory'
|
|
else:
|
|
self.logFileDir = '/some/other/directory'
|
|
|
|
Make a per-channel writer_map (note that you shouldn't change
|
|
writer_map in place)::
|
|
|
|
import writers
|
|
class Config(object):
|
|
def init_hook(self):
|
|
if self.M.channel == '#some-channel':
|
|
self.writer_map = self.writer_map.copy()
|
|
self.writer_map['.mw'] = writers.MediaWiki
|
|
|
|
|
|
The display styles (in html writers) can be modified also, by using
|
|
the starthtml and endhtml attributes (put this in
|
|
meetingLocalConfig.py::
|
|
|
|
import items
|
|
items.Agreed.starthtml = '<font color="red">'
|
|
items.Agreed.endhtml = '</font>'
|
|
|
|
|
|
Adding a new custom command via ``meetingLocalConfig.py``. (This
|
|
likely won't make sense unless you examine the code a bit and know
|
|
esoteric things about python method types)::
|
|
|
|
import types
|
|
class Config(object):
|
|
def init(self):
|
|
def do_party(self, nick, time_, **kwargs):
|
|
self.reply("We're having a party in this code!")
|
|
self.reply(("Owner, Chairs: %s %s"%(
|
|
self.owner,sorted(self.chairs.keys()))))
|
|
self.M.do_party = types.MethodType(
|
|
do_party, self.M, self.M.__class__)
|
|
|
|
|
|
Make a command alias. Make ``#weagree`` an alias for ``#agreed``::
|
|
|
|
class Config(object):
|
|
def init(self):
|
|
self.M.do_weagree = self.M.do_agreed
|
|
|
|
|
|
|
|
|
|
Supybot admin commands
|
|
----------------------
|
|
|
|
These commands are for the bot owners to manage all meetings served by
|
|
their bot. The expected use of these commands is when the bot is on
|
|
many channels as a public service, and the bot owner sometimes needs
|
|
to be able to monitor and adjust the overall situation, even if she is
|
|
not the chair of a meeting.
|
|
|
|
All of these are regular supybot commands (as opposed to the commands
|
|
above). That means that the supybot capability system applies, and
|
|
they can be given either in any channel, either by direct address
|
|
(``BotName: <command> <args> ...``) or with the bot prefix character
|
|
(e.g. ``@<commandname> <args> ...``). If there are commands with the
|
|
same name in multiple plugins, you need to prefix the command with the
|
|
plugin name (for example, ``BotName: meetbot recent`` instead of
|
|
``BotName: recent``)
|
|
|
|
These are restricted to anyone with the ``admin`` capability on the
|
|
bot.
|
|
|
|
``listmeetings``
|
|
List all meetings.
|
|
|
|
``savemeetings``
|
|
Saves all active meetings on all channels and all networks.
|
|
|
|
``addchair <channel> <network> <nick>``
|
|
Forcibly adds this nick as a chair on the giver channel on the given
|
|
network, if a meeting is active there.
|
|
|
|
``deletemeeting <channel> <network> <saveit=True>``
|
|
Delete a meeting from the cache. If save is given, save the meeting
|
|
first. The default value of ``save`` is True. This is useful for
|
|
when MeetBot becomes broken and is unable to properly save a
|
|
meeting, rendering the ``#endmeeting`` command non-functional.
|
|
|
|
``recent``
|
|
Display the last ten or so started meetings, along with their
|
|
channels. This is useful if you are the bot admin and want to see
|
|
just who all is using your bot, for example to better communicate
|
|
with those channels.
|
|
|
|
To connect to multiple IRC networks, use the supybot ``Network``
|
|
plugin to manage them. First, load the ``Network`` plugin, then use
|
|
the ``connect`` command to connect to the other network. Finally, you
|
|
need to tell supybot to join channels on the new. To do
|
|
that, you can use ``network command <other_network> join <channel>``.
|
|
(Alternatively, you can /msg the bot through the other network, but
|
|
you'll have to register your nick to it on the other network in order
|
|
for it to accept commands from you.)
|
|
|
|
|
|
|
|
|
|
Developers
|
|
==========
|
|
|
|
To speak with other developers and users, please join ``#meetbot`` on
|
|
*irc.oftc.net*.
|
|
|
|
Code contributions to MeetBot are encouraged, but you probably want to
|
|
check with others in #meetbot first to discuss general plans.
|
|
|
|
Architecture
|
|
------------
|
|
|
|
MeetBot is primarily used as a supybot plugin, however, it is designed
|
|
to not be limited to use with supybot. Thus, there are some design
|
|
choices which are slightly more complicated.
|
|
|
|
``meeting.py`` contains the core of the MeetBot code. Most meeting
|
|
functionality modifications would begin here.
|
|
|
|
* The ``Meeting`` and ``MeetingCommands`` are the core of the meeting
|
|
loop.
|
|
* The ``Config`` class stores all of the local configuration
|
|
information. An implicit subclass of this done for local
|
|
configuration. A proxy is set up for the ``Config`` class to engage
|
|
in the supybot-based configuration (``supybotconfig.py``).
|
|
|
|
``items.py`` contains MeetingItem objects of different classes. These
|
|
hold data about different #commands, most importantly their formatting
|
|
information.
|
|
|
|
``writers.py`` contains the code to write the output files. It
|
|
depends on the objects in ``items.py`` to be able to format
|
|
themselves, and the various classes in here
|
|
|
|
``plugin.py``, ``config.py``, ``test.py``, ``__init__.py`` are all
|
|
supybot based files. (yes, the supybot/not-supybot split is not as
|
|
rigorous as it should be). All of the supybot commands to interact
|
|
with the meeting and send lines to the ``Meeting`` object are in
|
|
``plugin.py``. If you want to add a *supybot*-based feature, this
|
|
would be the place to start.
|
|
|
|
|
|
Source control
|
|
--------------
|
|
|
|
To get a copy of the repo, the first time, use the **get** command::
|
|
|
|
darcs get http://code.zgib.net/MeetBot/ # dev
|
|
darcs get http://darcs.debian.org/darcs/collab-maint/MeetBot/ # stable
|
|
|
|
After that, to get code updates, use the **pull** command::
|
|
|
|
darcs get http://code.zgib.net/MeetBot/ # dev
|
|
darcs get http://darcs.debian.org/darcs/collab-maint/MeetBot/ # stable
|
|
|
|
Darcs truly supports "cherry-picking": you can pull patches from
|
|
either branch at will (They will be kept synchronized enough so that
|
|
this works). You may skip any patches you do not desire, and pull any
|
|
later patches as long as you have all earlier dependencies.
|
|
|
|
To send code back, you can use ``darcs diff -u`` for a simple
|
|
strategy, or you may record and send actual darcs patches. To
|
|
**record** darcs patches at first::
|
|
|
|
darcs record # 1) interactively select the group of changes
|
|
# (y/n questions)
|
|
# 2) Enter a patch name. Say yes for entering a
|
|
# long coment
|
|
# 3) Enter in a descriptive comment. See other
|
|
# patches for a model, but I tend to use a
|
|
# bulleted list.
|
|
|
|
The **send** command will send a patch to the developers via a HTTP
|
|
POST::
|
|
|
|
darcs send http://code.zgib.net/MeetBot/
|
|
|
|
If it is not signed with an authorized PGP key, it will be forwarded
|
|
to the developers, and the developers can manually approve and apply
|
|
the patch. Developers can have their PGP key added.
|
|
|
|
There are many other useful darcs commands. Discuss on ``#meetbot``
|
|
if you would like to find out more.
|
|
|
|
The darcs **push** command is the counterpart to ``pull``, and used
|
|
to move changes around when you have direct write access to the remote
|
|
repository.
|
|
|
|
|
|
|
|
Help and support
|
|
================
|
|
|
|
The channel ``#meetbot`` on *irc.oftc.net* is the best place to go.
|