Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/doc/Manual.txt
blob: 3b3665a19abe3fdc093f90ab4797f8e3ae2f269a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
====================================================
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 must be the first thing on the
  line, separated by a space from the rest of the line, and it will be
  properly hyperlinked.  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

  Both of these two examples are equivalent, and will hyperlink
  properly.  The first example below won't hyperlink properly, the
  second one won't be automatically detected::

    < MrBeige> #link the main page is http://wiki.debian.org/MeetBot/
    < MrBeige> the main page is http://wiki.debian.org/MeetBot/




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``, ``meetingname``.  Double percent signs (e.g.: ``%%Y``
    are time formats, from ``time.strftime``.

    This filename does *not* include extensions.  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,
            }


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




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.  This doesn't upload *to* a MediaWiki instance,
    but that could be added later.

``PmWiki``
    PmWiki output.  This doesn't upload *to* a PmWiki instance,
    but that could be added later.

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.