mirror of https://github.com/Mikaela/Limnoria.git
The "DocBook is fun" commit. We now have a whole new DTD and stylesheets to
use, as well as all the docs being in SGML now.
This commit is contained in:
parent
8ea62d2503
commit
151b2f829b
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
|
||||
<!DOCTYPE article SYSTEM "supybot.dtd">
|
||||
|
||||
<article>
|
||||
<articleinfo>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<revision>
|
||||
<revnumber>0.1</revnumber>
|
||||
<date>18 Feb 2004</date>
|
||||
<revremark>Initial revision</revremark>
|
||||
<revremark>Initial Docbook translation</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</articleinfo>
|
||||
|
@ -48,7 +48,7 @@
|
|||
the bot a command. Commands, rather than checking for a user
|
||||
level of 100, or checking if the user has an <varname>o</varname>
|
||||
flag, are instead able to check if a user has the
|
||||
<varname>owner</varname> capability. At this point such a
|
||||
<capability>owner</capability> capability. At this point such a
|
||||
difference might not seem revolutionary, but at least we can
|
||||
already tell that this method is self-documenting, and easier for
|
||||
users and developers to understand what's truly going on.
|
||||
|
@ -69,16 +69,16 @@
|
|||
a capability that, instead of saying “what a user can
|
||||
do”, says what a user <emphasis>cannot</emphasis> do. It's
|
||||
formed rather simply by adding a dash (“-”) to the
|
||||
beginning of a capability; <varname>rot13</varname> is a
|
||||
capability, and <varname>-rot13</varname> is an anticapability.
|
||||
Anyway, when a user issues the bot a command, perhaps
|
||||
<function>calc</function> or <function>help</function> the bot
|
||||
first checks to make sure the user doesn't have the
|
||||
<varname>-calc</varname> or the <varname>-help</varname>
|
||||
capabilities before even considering responding to the user. So
|
||||
commands can be turned on or off on a <emphasis>per
|
||||
user</emphasis> basis, offering finegrained control not often (if
|
||||
at all!) seen in other bots.
|
||||
beginning of a capability; <botcommand>rot13</botcommand> is a
|
||||
capability, and <botcommand>-rot13</botcommand> is an
|
||||
anticapability. Anyway, when a user issues the bot a command,
|
||||
perhaps <botcommand>calc</botcommand> or
|
||||
<botcommand>help</botcommand>, the bot first checks to make sure
|
||||
the user doesn't have the <capability>-calc</capability> or the
|
||||
<capability>-help</capability> capabilities before even
|
||||
considering responding to the user. So commands can be turned on
|
||||
or off on a <emphasis>per user</emphasis> basis, offering
|
||||
finegrained control not often (if at all!) seen in other bots.
|
||||
</para>
|
||||
<sect2>
|
||||
<title>Channel capabilities</title>
|
||||
|
@ -86,10 +86,10 @@
|
|||
But that's not all! The capabilities system also supports
|
||||
<emphasis>Channel</emphasis> capabilities, which are
|
||||
capabilities that only apply to a specific channel; they're of
|
||||
the form <varname>#channel.capability</varname>. Whenever a
|
||||
user issues a command to the bot in a channel, the command
|
||||
dispatcher also checks to make sure the user doesn't have the
|
||||
anticapability for that command <emphasis>in that
|
||||
the form <capability>#channel.capability</capability>.
|
||||
Whenever a user issues a command to the bot in a channel, the
|
||||
command dispatcher also checks to make sure the user doesn't
|
||||
have the anticapability for that command <emphasis>in that
|
||||
channel</emphasis> and if the user does, the bot won't respond
|
||||
to the user in the channel. Thus now, in addition to having
|
||||
the ability to turn individual commands on or off for an
|
||||
|
@ -97,20 +97,20 @@
|
|||
individual user on an individual channel!
|
||||
</para>
|
||||
<para>
|
||||
So when a user <varname>foo</varname> sends a command
|
||||
<function>bar</function> to the bot on channel
|
||||
<varname>#baz</varname>, first the bot checks to see if the
|
||||
So when a user <nick>foo</nick> sends a command
|
||||
<botcommand>bar</botcommand> to the bot on channel
|
||||
<channel>#baz</channel>, first the bot checks to see if the
|
||||
user has the anticapability for the command by itself,
|
||||
<varname>-bar</varname>. If so, it returns right then and
|
||||
there, compltely ignoring the fact that the user issued that
|
||||
command to it. If the user doesn't have that anticapability,
|
||||
then the bot checks to see if the user issued the command over
|
||||
a channel, and if so, checks to see if the user has the
|
||||
antichannelcapability for that command,
|
||||
<varname>#baz.-bar</varname>. If so, again, he returns right
|
||||
then and there and doesn't even think about responding to the
|
||||
bot. If neither of these anticapabilities are present, then
|
||||
the bot just responds to the user like normal.
|
||||
<capability>-bar</capability>. If so, it returns right then
|
||||
and there, compltely ignoring the fact that the user issued
|
||||
that command to it. If the user doesn't have that
|
||||
anticapability, then the bot checks to see if the user issued
|
||||
the command over a channel, and if so, checks to see if the
|
||||
user has the antichannelcapability for that command,
|
||||
<capability>#baz.-bar</capability>. If so, again, he returns
|
||||
right then and there and doesn't even think about responding
|
||||
to the bot. If neither of these anticapabilities are present,
|
||||
then the bot just responds to the user like normal.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
@ -148,14 +148,14 @@
|
|||
<title>Hard-coded supybot capabilities</title>
|
||||
<para>
|
||||
There are several default capabilities the bot uses. The most
|
||||
important of these is the <varname>owner</varname> capability.
|
||||
This capability allows the person having it to use
|
||||
important of these is the <capability>owner</capability>
|
||||
capability. This capability allows the person having it to use
|
||||
<emphasis>any</emphasis> command. It's best to keep this
|
||||
capability reserved to people who actually have access to the
|
||||
shell the bot is running on.
|
||||
</para>
|
||||
<para>
|
||||
There is also the <varname>admin</varname> capability for
|
||||
There is also the <capability>admin</capability> capability for
|
||||
non-owners that are highly trusted to administer the bot
|
||||
appropriately. They can do things such as change the bot's nick,
|
||||
globally enable/disable commands, cause the bot to ignore a given
|
||||
|
@ -165,33 +165,34 @@
|
|||
</para>
|
||||
<para>
|
||||
People who are to administer channels with the bot should have the
|
||||
<varname>#channel.op</varname> capability -- whatever channel they
|
||||
are to administrate, they should have that channel capability for
|
||||
<varname>op</varname>. For example, since I want
|
||||
<varname>inkedmn</varname> to be an administrator in
|
||||
<varname>#supybot</varname>, I'll give him the
|
||||
<varname>#supybot.op</varname> capability. This is in addition to
|
||||
his <varname>admin</varname> capability, since the
|
||||
<varname>admin</varname> capability doesn't give the person having
|
||||
it control over channels. <varname>#channel.op</varname> is used
|
||||
for such things as giving/receiving ops, kickbanning people,
|
||||
lobotomizing the bot, ignoring users in the channel, and managing
|
||||
the channel capabilities. The <varname>#channel.op</varname>
|
||||
capability is also basically the equivalent of the owner
|
||||
capability for capabilities involving <varname>#channel</varname>
|
||||
– basically anyone with the <varname>#channel.op</varname>
|
||||
<capability>#channel.op</capability> capability -- whatever
|
||||
channel they are to administrate, they should have that channel
|
||||
capability for <capability>op</capability>. For example, since I
|
||||
want <nick>inkedmn</nick> to be an administrator in
|
||||
<channel>#supybot</channel>, I'll give him the
|
||||
<capability>#supybot.op</capability> capability. This is in
|
||||
addition to his <capability>admin</capability> capability, since
|
||||
the <capability>admin</capability> capability doesn't give the
|
||||
person having it control over channels.
|
||||
<capability>#channel.op</capability> is used for such things as
|
||||
giving/receiving ops, kickbanning people, lobotomizing the bot,
|
||||
ignoring users in the channel, and managing the channel
|
||||
capabilities. The <capability>#channel.op</capability> capability
|
||||
is also basically the equivalent of the owner capability for
|
||||
capabilities involving <channel>#channel</channel> –
|
||||
basically anyone with the <capability>#channel.op</capability>
|
||||
capability is considered to have all positive capabilities and no
|
||||
negative capabilities for <varname>#channel</varname>.
|
||||
negative capabilities for <channel>#channel</channel>.
|
||||
</para>
|
||||
<para>
|
||||
One other globally important capability exists:
|
||||
<varname>trusted</varname>. This is a command that basically says
|
||||
“This user can be trusted not to try and crash the
|
||||
bot.” It allows users to call commands like
|
||||
<function>Math.icalc</function>, which potentially could cause the
|
||||
<capability>trusted</capability>. This is a command that
|
||||
basically says “This user can be trusted not to try and
|
||||
crash the bot.” It allows users to call commands like
|
||||
<botcommand>Math.icalc</botcommand>, which potentially could cause the
|
||||
bot to begin a calculation that could potentially never return (a
|
||||
calculation like 10**10**10**10). Another command that requires
|
||||
the trusted capability is <function>Utilties.re</function>, which
|
||||
the trusted capability is <botcommand>Utilties.re</botcommand>, which
|
||||
(due to the regular expression implementation in Python (and any
|
||||
other language that uses NFA regular expressions, like Perl or
|
||||
Ruby or Lua or …) which can allow a regular expression to
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
<!DOCTYPE article SYSTEM "supybot.dtd">
|
||||
|
||||
<article>
|
||||
<articleinfo>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Jeremiah</firstname>
|
||||
<surname>Fincher</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Daniel</firstname>
|
||||
<surname>DiPaolo</surname>
|
||||
</author>
|
||||
<editor>
|
||||
<firstname>Daniel</firstname>
|
||||
<surname>DiPaolo</surname>
|
||||
<contrib>DocBook translator</contrib>
|
||||
</editor>
|
||||
</authorgroup>
|
||||
<title>Supybot configuration system explanation</title>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>0.1</revnumber>
|
||||
<date>18 Feb 2004</date>
|
||||
<revremark>Initial Docbook translation</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.2</revnumber>
|
||||
<date>26 Feb 2004</date>
|
||||
<revremark>Conversion to Supybot DTD</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</articleinfo>
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
So you've got your Supybot up and running and there are some
|
||||
things you don't like about it. Fortunately for you, chances are
|
||||
that these things are configurable, and this document is here to
|
||||
tell you how to configure them.
|
||||
</para>
|
||||
<para>
|
||||
Configuration of Supybot is handled via the
|
||||
<plugin>Config</plugin> plugin, which controls runtime access to
|
||||
Supybot's registry (the configuration file generated by the
|
||||
<script>supybot-wizard</script> program you ran). The
|
||||
<plugin>Config</plugin> plugin provides a way to get or set
|
||||
variables, to list the available variables, and even to get help
|
||||
for certain variables. Take a moment now to read the help for
|
||||
each of those commands: <botcommand>get</botcommand>,
|
||||
<botcommand>set</botcommand>, <botcommand>list</botcommand>, and
|
||||
<botcommand>help</botcommand>. If you don't know how to get help on
|
||||
those commands, go ahead and read our
|
||||
<filename>GETTING_STARTED</filename> document before this one.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>Supybot's registry</title>
|
||||
<para>
|
||||
Now, if you're used to the Windows registry, don't worry,
|
||||
Supybot's registry is completely different. For one, it's
|
||||
completely plain text. There's no binary database sensitive to
|
||||
corruption, it's not necessary to use another program to edit it
|
||||
– all you need is a simple text editor. But there is at
|
||||
least one good idea in Windows' registry: hierarchical
|
||||
configuration. Supybot's configuration variables are organized in
|
||||
a hierarchy: variables having to do with the way Supybot makes
|
||||
replies all start with
|
||||
<registrygroup>supybot.reply</registrygroup>; variables having to
|
||||
do with the way a plugin works all start with
|
||||
<registrygroup>supybot.plugins.Plugin</registrygroup> (where
|
||||
<plugin>Plugin</plugin> is the name of the plugin in question).
|
||||
This hierarchy is nice because it means the user isn't inundated
|
||||
with hundreds of unrelated and unsorted configuration variables.
|
||||
</para>
|
||||
<para>
|
||||
Some of the more important configuration values are located
|
||||
directly under the base group,
|
||||
<registrygroup>supybot</registrygroup>. Things like the bot's
|
||||
nick, its ident, etc. Along with these config values are a few
|
||||
subgroups that contain other values. Some of the more prominent
|
||||
subgroups are: <registrygroup>plugins</registrygroup> (where all
|
||||
the plugin-specific configuration is held),
|
||||
<registrygroup>reply</registrygroup> (where variables affecting
|
||||
the way a Supybot makes its replies resides),
|
||||
<registrygroup>replies</registrygroup> (where all the specific
|
||||
standard replies are kept), and
|
||||
<registrygroup>directories</registrygroup> (where all the
|
||||
directories a Supybot uses are defined). There are other
|
||||
subgroups as well, but these are the ones we'll use in our
|
||||
example.
|
||||
</para>
|
||||
<sect2>
|
||||
<title>Config plugin commands</title>
|
||||
<sect3>
|
||||
<title>Listing registry contents</title>
|
||||
<para>
|
||||
Using the <plugin>Config</plugin> plugin, you can list
|
||||
the values in a subgroup and get or set any of the values
|
||||
anywhere in the configuration hierarchy. For example,
|
||||
let's say you wanted to see what configuration values were
|
||||
under the <registrygroup>supybot</registrygroup> (the base
|
||||
group) hierarchy. You would simply issue this command:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> @config list supybot
|
||||
<supybot> jemfinch|lambda: nick, ident, user, server, password,
|
||||
channels, prefixChars, defaultCapabilities, defaultAllow, defaultIgnore,
|
||||
humanTimestampFormat, externalIP, pipeSyntax,
|
||||
followIdentificationThroughNickChanges, alwaysJoinOnInvite,
|
||||
showSimpleSyntax, maxHistoryLength, nickmods, throttleTime,
|
||||
snarfThrottle, threadAllCommands, pingServer, pingInterval,
|
||||
upkeepInterval, flush, httpPeekSize, and defaultSocketTimeout
|
||||
</ircsession>
|
||||
<para>
|
||||
These are all the configuration values you can set which
|
||||
are under the base <registrygroup>supybot</registrygroup>
|
||||
group. Actually, their full names would each have a
|
||||
“supybot.” appended on to the front of them,
|
||||
but it is omitted in the listing in order to shorten the
|
||||
output.
|
||||
</para>
|
||||
<para>
|
||||
Now, to see all of the available configuration groups
|
||||
under the base <registrygroup>supybot</registrygroup>
|
||||
group, we simply use the <flag>--groups</flag> flag to
|
||||
<botcommand>config list</botcommand>:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> @config list --groups supybot
|
||||
<supybot> jemfinch|lambda: commands, databases, directories, drivers,
|
||||
log, plugins, replies, and reply
|
||||
</ircsession>
|
||||
<para>
|
||||
These are all the subgroups of
|
||||
<registrygroup>supybot</registrygroup>. Again, the full
|
||||
name of these would have “supybot.” prepended
|
||||
to them. So really, we have
|
||||
<registrygroup>supybot.commands</registrygroup>,
|
||||
<registrygroup>supybot.databases</registrygroup>, etc.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
An item can show up in both lists if it is a group
|
||||
that itself has a value. For example, all plugins
|
||||
fall under this category, as their value is a boolean
|
||||
value determining whether or not that plugin is to be
|
||||
loaded when the bot is started.
|
||||
</para>
|
||||
</note>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Dealing with registry values</title>
|
||||
<para>
|
||||
Okay, now that you've used the <plugin>Config</plugin>
|
||||
plugin to list configuration variables, it's time that we
|
||||
start looking at individual variables and their values.
|
||||
</para>
|
||||
<sect4>
|
||||
<title>Built-in help for registry values</title>
|
||||
<para>
|
||||
The first (and perhaps most important) thing you
|
||||
should know about each configuration variable is that
|
||||
they all have an associated help string to tell you
|
||||
what they represent. So the first command we'll cover
|
||||
is <botcommand>config help</botcommand>. To see the
|
||||
help string for any value or group, simply use the
|
||||
<botcommand>config help</botcommand> command. For
|
||||
example, to see what this
|
||||
<registrygroup>supybot.prefixChars</registrygroup>
|
||||
configuration variable is all about, we'd do this:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> @config help supybot.prefixChars
|
||||
<supybot> jemfinch|lambda: Determines what prefix characters the bot
|
||||
will reply to. A prefix character is a single character that the bot will
|
||||
use to determine what messages are addressed to it; when there are no
|
||||
prefix characters set, it just uses its nick.
|
||||
</ircsession>
|
||||
<para>
|
||||
Pretty simple, eh?
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4>
|
||||
<title>Getting/setting registry values</title>
|
||||
<para>
|
||||
Now, if you're curious what the current value of a
|
||||
configuration variable is, you'll use the
|
||||
<botcommand>config</botcommand> command with one
|
||||
argument, the name of the variable you want to see the
|
||||
value of:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> @config supybot.prefixChars
|
||||
<supybot> jemfinch|lambda: '@'
|
||||
</ircsession>
|
||||
<para>
|
||||
To set this value, just stick an extra argument after
|
||||
the name:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> @config supybot.prefixChars @$
|
||||
<supybot> jemfinch|lambda: The operation succeeded.
|
||||
</ircsession>
|
||||
<para>
|
||||
Now, check this out:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> $config supybot.prefixChars
|
||||
<supybot> jemfinch|lambda: '@$'
|
||||
</ircsession>
|
||||
<para>
|
||||
Note that we used <literal>$</literal> as our prefix
|
||||
character, and that the value of the configuration
|
||||
variable changed. If I were to use the
|
||||
<botcommand>flush</botcommand> command now, this
|
||||
change would be flushed to the registry file on disk
|
||||
(this would also happen if I made the bot quit, or
|
||||
pressed
|
||||
<keycombo>
|
||||
<keycap>Ctrl</keycap>
|
||||
<keycap>C</keycap>
|
||||
</keycombo>
|
||||
in the terminal the bot was running in). Instead,
|
||||
I'll revert the change:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> $config supybot.prefixChars @
|
||||
<supybot> jemfinch|lambda: The operation succeeded.
|
||||
<jemfinch|lambda> $note that this makes no response.
|
||||
</ircsession>
|
||||
<para>
|
||||
If you're ever curious what the default for a given
|
||||
configuration variable is, use the <botcommand>config
|
||||
default</botcommand> command:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> @config default supybot.prefixChars
|
||||
<supybot> jemfinch|lambda: ''
|
||||
</ircsession>
|
||||
<para>
|
||||
Thus, to reset a configuration variable to its default
|
||||
value, you can simply say:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> @config supybot.prefixChars [config default
|
||||
supybot.prefixChars]
|
||||
<supybot> jemfinch|lambda: The operation succeeded.
|
||||
<jemfinch|lambda> @note that this does nothing
|
||||
</ircsession>
|
||||
<para>
|
||||
Simple, eh?
|
||||
</para>
|
||||
</sect4>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Searching the registry</title>
|
||||
<para>
|
||||
Now, let's say you want to find all configuration
|
||||
variables that might be even remotely related to opping.
|
||||
For that, you'll want the <botcommand>config
|
||||
search</botcommand> command. Check this out:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> @config search op
|
||||
<supybot> jemfinch|lambda: supybot.plugins.Enforcer.autoOp,
|
||||
supybot.plugins.Enforcer.autoOp.#supybot,
|
||||
supybot.plugins.Enforcer.autoHalfop,
|
||||
supybot.plugins.Enforcer.cycleToGetOps, supybot.plugins.Topic,
|
||||
supybot.plugins.Topic.separator, and supybot.plugins.Relay.topicSync
|
||||
</ircsession>
|
||||
<para>
|
||||
Sure, it showed up all the topic-related stuff in there,
|
||||
but it also showed you all the op-related stuff, too. Do
|
||||
note, however, that you can only see configuration
|
||||
variables for plugins that you have loaded or that you
|
||||
loaded in the past; if you've never loaded a plugin,
|
||||
there's no way for the bot to know what configuration
|
||||
variables it registers.
|
||||
</para>
|
||||
<para>
|
||||
Some people might like editing their registry file
|
||||
directly rather than manipulating all these things through
|
||||
the bot. For those people, we offer the
|
||||
<botcommand>config reload</botcommand> command, which
|
||||
reloads both registry configuration and
|
||||
user/channel/ignore database configuration. Just edit the
|
||||
interesting files and then give the bot the
|
||||
<botcommand>config reload</botcommand> command and it'll
|
||||
work as expected. Do note, however, that Supybot flushes
|
||||
his configuration files and databases to disk every hour
|
||||
or so, and if this happens after you've edited your
|
||||
configuration files but before you reload your changes,
|
||||
you could lose the changes you made. To prevent this, set
|
||||
the <registrygroup>supybot.flush</registrygroup> value to
|
||||
<literal>Off</literal>, and no automatic flushing will
|
||||
occur.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>All done!</title>
|
||||
<para>
|
||||
Anyway, that's about it for configuration. Have fun, and enjoy
|
||||
your configurable bot!
|
||||
</para>
|
||||
</sect1>
|
||||
</article>
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
|
||||
<!DOCTYPE article SYSTEM "supybot.dtd">
|
||||
|
||||
<article>
|
||||
<articleinfo>
|
||||
|
@ -32,6 +32,11 @@
|
|||
Updated to match EXAMPLE included with 0.75.0
|
||||
</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.4</revnumber>
|
||||
<date>26 Feb 2004</date>
|
||||
<revremark>Converted to use Supybot DTD</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</articleinfo>
|
||||
<sect1>
|
||||
|
@ -56,13 +61,12 @@
|
|||
<title>Creating your own plugin</title>
|
||||
<sect2>
|
||||
<title>
|
||||
Using <application>scripts/newplugin.py</application>
|
||||
Using <script>scripts/newplugin.py</script>
|
||||
</title>
|
||||
<para>
|
||||
First, the easiest way to start writing a module is to use the
|
||||
wizard provided,
|
||||
<application>scripts/newplugin.py</application>. Here's an
|
||||
example session:
|
||||
wizard provided, <script>scripts/newplugin.py</script>.
|
||||
Here's an example session:
|
||||
</para>
|
||||
<screen>
|
||||
functor% scripts/newplugin.py
|
||||
|
@ -169,7 +173,7 @@ Class = Random
|
|||
</para>
|
||||
<para>
|
||||
Describe what you want the plugin to do in the docstring.
|
||||
This is used in <application>scripts/setup.py</application> in
|
||||
This is used in <script>scripts/setup.py</script> in
|
||||
order to explain to the user the purpose of the module. It's
|
||||
also returned when someone asks the bot for help for a given
|
||||
module (instead of help for a certain command). We'll change
|
||||
|
@ -177,17 +181,18 @@ Class = Random
|
|||
numbers."</literal>
|
||||
</para>
|
||||
<para>
|
||||
Then there are the imports. The <varname>callbacks</varname>
|
||||
Then there are the imports. The
|
||||
<module>callbacks</module>
|
||||
module is used (the class you're given subclasses
|
||||
<varname>callbacks.Privmsg</varname>) but the
|
||||
<varname>privmsgs</varname> module isn't used. That's
|
||||
<classname>callbacks.Privmsg</classname>) but the
|
||||
<module>privmsgs</module> module isn't used. That's
|
||||
alright; we can almost guarantee you'll use it, so we go ahead
|
||||
and add the import to the template.
|
||||
</para>
|
||||
<para>
|
||||
Then you see a <function>configure</function> function. This
|
||||
the function that's called when users decide to add your
|
||||
module in <application>scripts/setup.py</application>. You'll
|
||||
module in <script>scripts/setup.py</script>. You'll
|
||||
note that by default it simply adds <literal>"load
|
||||
Example"</literal> (where 'Example' is the name you provided
|
||||
as the name of your plugin, so in our case it is
|
||||
|
@ -204,8 +209,8 @@ Class = Random
|
|||
</para>
|
||||
<para>
|
||||
What you're given is a skeleton: a simple subclass of
|
||||
<varname>callbacks.Privmsg</varname> for you to start with.
|
||||
Now let's add a command.
|
||||
<classname>callbacks.Privmsg</classname> for you to start
|
||||
with. Now let's add a command.
|
||||
</para>
|
||||
<para>
|
||||
I don't know what you know about random number generators, but
|
||||
|
@ -213,7 +218,7 @@ Class = Random
|
|||
seed) and they continue (via some somewhat
|
||||
complicated/unpredictable algorithm) from there. This seed
|
||||
(and the rest of the sequence, really) is all nice and
|
||||
packaged up in Python's <varname>random</varname> module, the
|
||||
packaged up in Python's <module>random</module> module, the
|
||||
<varname>Random</varname> object. So the first thing we're
|
||||
going to have to do is give our plugin a
|
||||
<varname>Random</varname> object.
|
||||
|
@ -225,8 +230,8 @@ Class = Random
|
|||
be careful of is that you call the superclass
|
||||
<function>__init__</function> method at the end of your own
|
||||
<function>__init__</function>. So to add this
|
||||
<varname>random.Random</varname> object to our plugin, we can
|
||||
replace the <function>pass</function> statement with
|
||||
<classname>random.Random</classname> object to our plugin, we
|
||||
can replace the <keyword>pass</keyword> statement with
|
||||
this:
|
||||
</para>
|
||||
<programlisting>
|
||||
|
@ -285,7 +290,7 @@ def __init__(self):
|
|||
<para>
|
||||
And that's it! Pretty simple, huh? Anyway, you're probably
|
||||
wondering what all that <emphasis>means</emphasis>. We'll
|
||||
start with the <function>def</function> statement:
|
||||
start with the <keyword>def</keyword> statement:
|
||||
</para>
|
||||
<programlisting>
|
||||
def random(self, irc, msg, args):
|
||||
|
@ -296,24 +301,24 @@ def __init__(self):
|
|||
"@random" (or whatever prefix character your specific bot
|
||||
uses). The arguments are a bit less obvious.
|
||||
<varname>self</varname> is self-evident (hah!).
|
||||
<varname>irc</varname> is the <varname>Irc</varname> object
|
||||
passed to the command; <varname>msg</varname> is the original
|
||||
<varname>IrcMsg</varname> object. But you're really not going
|
||||
to have to deal with either of these too much (with the
|
||||
exception of calling <function>irc.reply</function> or
|
||||
<function>irc.error</function>). What you're
|
||||
<varname>irc</varname> is the <classname>Irc</classname>
|
||||
object passed to the command; <varname>msg</varname> is the
|
||||
original <classname>IrcMsg</classname> object. But you're
|
||||
really not going to have to deal with either of these too much
|
||||
(with the exception of calling <function>irc.reply</function>
|
||||
or <function>irc.error</function>). What you're
|
||||
<emphasis>really</emphasis> interested in is the
|
||||
<varname>args</varname> arg. That if a list of all the
|
||||
arguments passed to your command, pre-parsed and already
|
||||
evaluated (i.e., you never have to worry about nested
|
||||
commands, or handling double quoted strings, or splitting on
|
||||
whitespace -- the work has already been done for you). You
|
||||
can read about the <varname>Irc</varname> object in
|
||||
can read about the <classname>Irc</classname> object in
|
||||
<filename>irclib.py</filename> (you won't find
|
||||
<function>.reply</function> or <function>.error</function>
|
||||
there, though, because you're actually getting an
|
||||
<varname>IrcObjectProxy</varname>, but that's beyond the level
|
||||
we want to describe here :)). You can read about the
|
||||
<classname>IrcObjectProxy</classname>, but that's beyond the
|
||||
level we want to describe here :)). You can read about the
|
||||
<varname>msg</varname> object in
|
||||
<filename>ircmsgs.py</filename>. But again, aside from
|
||||
calling <function>irc.reply</function> or
|
||||
|
@ -342,13 +347,13 @@ def __init__(self):
|
|||
<emphasis>is</emphasis> the help! Given the above docstring,
|
||||
this is what a supybot does:
|
||||
</para>
|
||||
<screen>
|
||||
<ircsession>
|
||||
<angryman> jemfinch: random takes no arguments (for more help
|
||||
use the morehelp command)
|
||||
<jemfinch> $morehelp random
|
||||
<angryman> jemfinch: Returns the next random number from the
|
||||
current random number generator.
|
||||
</screen>
|
||||
</ircsession>
|
||||
<para>
|
||||
'help <command>' replies with the command name followed
|
||||
by the first line of the command's docstring; there should be
|
||||
|
@ -362,19 +367,20 @@ def __init__(self):
|
|||
</programlisting>
|
||||
<para>
|
||||
<function>irc.reply</function> takes two arguments, an
|
||||
<varname>IrcMsg</varname> (like the one passed into your
|
||||
function) and a string. The <varname>IrcMsg</varname> is used
|
||||
to determine who the reply should go to and whether or not it
|
||||
should be sent in private message (commands sent in private
|
||||
are replied to in private). The string is the reply to be
|
||||
sent. Don't worry about length restrictions or anything -- if
|
||||
the string you want to send is too big for an IRC message (and
|
||||
oftentimes that turns out to be the case :)) the supybot
|
||||
framework handles that entirely transparently to you. Do make
|
||||
sure, however, that you give <function>irc.reply</function> a
|
||||
string. It doesn't take anything else (sometimes even unicode
|
||||
fails!). That's why we have "str(self.rng.random())" instead
|
||||
of simply "self.rng.random()" -- we had to give
|
||||
<classname>IrcMsg</classname> (like the one passed into your
|
||||
function) and a string. The <classname>IrcMsg</classname> is
|
||||
used to determine who the reply should go to and whether or
|
||||
not it should be sent in private message (commands sent in
|
||||
private are replied to in private). The string is the reply
|
||||
to be sent. Don't worry about length restrictions or anything
|
||||
-- if the string you want to send is too big for an IRC
|
||||
message (and oftentimes that turns out to be the case :)) the
|
||||
supybot framework handles that entirely transparently to you.
|
||||
Do make sure, however, that you give
|
||||
<function>irc.reply</function> a string. It doesn't take
|
||||
anything else (sometimes even unicode fails!). That's why we
|
||||
have "str(self.rng.random())" instead of simply
|
||||
"self.rng.random()" -- we had to give
|
||||
<function>irc.reply</function> a string.
|
||||
</para>
|
||||
<para>
|
||||
|
@ -422,7 +428,7 @@ def __init__(self):
|
|||
arguments are returned in a tuple/list). Yes, we could've
|
||||
just said "seed = args[0]" and gotten the first argument, but
|
||||
what if the user didn't pass us an argument at all? Then
|
||||
we've got to catch the <varname>IndexError</varname> from
|
||||
we've got to catch the <classname>IndexError</classname> from
|
||||
<varname>args[0]</varname> and complain to the user about it.
|
||||
<function>privmsgs.getArgs</function>, on the other hand,
|
||||
handles all that for us. If the user didn't give us enough
|
||||
|
@ -440,7 +446,7 @@ def __init__(self):
|
|||
sure to remind the user that an error has been encountered
|
||||
(currently, that means it puts "Error: " at the beginning of
|
||||
the message). After erroring, we return. It's important to
|
||||
remember this <function>return</function> here; otherwise,
|
||||
remember this <keyword>return</keyword> here; otherwise,
|
||||
we'll just keep going down through the function and try to use
|
||||
this "seed" variable that never got assigned. A good general
|
||||
rule of thumb is that any time you use
|
||||
|
@ -500,9 +506,9 @@ def __init__(self):
|
|||
to.
|
||||
</para>
|
||||
<para>
|
||||
The <varname>Random</varname> object we're using offers us a
|
||||
"sample" method that takes a sequence and a number (we'll call
|
||||
it <varname>N</varname>) and returns a list of
|
||||
The <classname>Random</classname> object we're using offers us
|
||||
a "sample" method that takes a sequence and a number (we'll
|
||||
call it <varname>N</varname>) and returns a list of
|
||||
<varname>N</varname> items taken randomly from the sequence.
|
||||
So I'll show you an example that takes advantage of multiple
|
||||
arguments but doesn't use
|
||||
|
@ -542,8 +548,8 @@ def __init__(self):
|
|||
into a big long string that we'll just have to re-split. But
|
||||
we still want the nice error handling of
|
||||
<function>privmsgs.getArgs</function>. So what do we do? We
|
||||
raise <varname>callbacks.ArgumentError</varname>! That's the
|
||||
secret juju that <function>privmsgs.getArgs</function> is
|
||||
raise <classname>callbacks.ArgumentError</classname>! That's
|
||||
the secret juju that <function>privmsgs.getArgs</function> is
|
||||
doing; now we're just doing it ourself. Someone up our
|
||||
callchain knows how to handle it so a neat error message is
|
||||
returned. So in this function, if
|
||||
|
@ -610,19 +616,19 @@ def __init__(self):
|
|||
<function>irc.queueMsg</function>, the general interface for
|
||||
sending messages to the server. It's what
|
||||
<function>irc.reply</function> is using under the covers. It
|
||||
takes an <varname>IrcMsg</varname> object. Fortunately,
|
||||
takes an <classname>IrcMsg</classname> object. Fortunately,
|
||||
that's exactly what's returned by
|
||||
<function>ircmsgs.action</function>. An action message, just
|
||||
in case you don't know, is a /me kind of message.
|
||||
<function>ircmsgs.action</function> is a helper function that
|
||||
takes a target (a place to send the message, either a channel
|
||||
or a person) and a payload (the thing to /me) and returns the
|
||||
appropriate <varname>IrcMsg</varname> object.
|
||||
appropriate <classname>IrcMsg</classname> object.
|
||||
<function>ircutils.replyTo</function> simply takes an
|
||||
<varname>IrcMsg</varname> and returns where we should reply
|
||||
to; if the message was originally sent to a channel, we'll
|
||||
reply to there, if it was originally sent to us privately,
|
||||
we'll reply in private.
|
||||
<classname>IrcMsg</classname> and returns where we should
|
||||
reply to; if the message was originally sent to a channel,
|
||||
we'll reply to there, if it was originally sent to us
|
||||
privately, we'll reply in private.
|
||||
</para>
|
||||
<para>
|
||||
At the end, you might be surprised by the "raise
|
||||
|
@ -646,7 +652,7 @@ def __init__(self):
|
|||
<title>Finishing touches</title>
|
||||
<para>
|
||||
Let's take a look at that <function>configure</function>
|
||||
function <application>scripts/newplugin.py</application> made
|
||||
function <script>scripts/newplugin.py</script> made
|
||||
for us. Here it is, in case you've forgotten:
|
||||
</para>
|
||||
<programlisting>
|
||||
|
@ -660,10 +666,10 @@ def configure(onStart, afterConnect, advanced):
|
|||
</programlisting>
|
||||
<para>
|
||||
You remember when you first started running supybot and ran
|
||||
<application>scripts/setup.py</application> and it asked you
|
||||
<script>scripts/setup.py</script> and it asked you
|
||||
all those questions? Well, now's your chance to ask other
|
||||
users some questions of your own. In our case, with our
|
||||
<varname>Random</varname> plugin, it might be nice to offer
|
||||
<plugin>Random</plugin> plugin, it might be nice to offer
|
||||
the user the ability to specify a seed to use whenever the
|
||||
plugin is loaded. So let's ask him if he wants to do that,
|
||||
and if so, let's ask him what the seed should be.
|
||||
|
@ -684,7 +690,7 @@ def configure(onStart, afterConnect, advanced):
|
|||
onStart.append('seed %s' % seed)
|
||||
</programlisting>
|
||||
<para>
|
||||
As you can see, what the <varname>questions</varname> module
|
||||
As you can see, what the <module>questions</module> module
|
||||
does is fairly self-evident: <function>yn</function> returns
|
||||
either 'y' or 'n'; <function>something</function> returns
|
||||
<emphasis>something</emphasis> (but not nothing; for nothing,
|
||||
|
@ -694,12 +700,12 @@ def configure(onStart, afterConnect, advanced):
|
|||
<varname>onStart</varname> is a list of the commands to run
|
||||
when the bot starts; we're just throwing our little piece into
|
||||
it. These commands will then be written into the template
|
||||
<application>scripts/setup.py</application> creates for the bot.
|
||||
<script>scripts/setup.py</script> creates for the bot.
|
||||
</para>
|
||||
<para>
|
||||
We've written our own plugin from scratch (well, from the
|
||||
boilerplate that we got from
|
||||
<application>scripts/newplugin.py</application> :)) and
|
||||
<script>scripts/newplugin.py</script> :)) and
|
||||
survived! Now go write more plugins for supybot, and send
|
||||
them to me so I can use them too :)
|
||||
</para>
|
||||
|
|
|
@ -0,0 +1,284 @@
|
|||
<!DOCTYPE article SYSTEM "supybot.dtd">
|
||||
<article class="faq">
|
||||
<articleinfo>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Jeremiah</firstname>
|
||||
<surname>Fincher</surname>
|
||||
</author>
|
||||
<editor>
|
||||
<firstname>Daniel</firstname>
|
||||
<surname>DiPaolo</surname>
|
||||
<contrib>DocBook translator</contrib>
|
||||
</editor>
|
||||
</authorgroup>
|
||||
<title>Supybot Frequently Asked Questions</title>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>0.1</revnumber>
|
||||
<date>18 Feb 2004</date>
|
||||
<revremark>Initial Docbook translation</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.2</revnumber>
|
||||
<date>26 Feb 2004</date>
|
||||
<revremark>Changed to Supybot DTD</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</articleinfo>
|
||||
<qandaset defaultlabel="qanda">
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
Why does my bot not recognize me or tell me that I don't
|
||||
have the <capability>owner</capability> capability?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
Because you're not given it anything to recognize you
|
||||
from! You'll need to identify with the bot
|
||||
(<botcommand>help identify</botcommand> to see how that
|
||||
works) or add your hostmask to your user record
|
||||
(<botcommand>help addhostmask</botcommand> to see how that
|
||||
works) for it to know that you're you. You may wish to
|
||||
note that <botcommand>addhostmask</botcommand> can accept
|
||||
a password; rather than identify, you can send the command
|
||||
<botcommand>addhostmask myOwnerUser [hostmask]
|
||||
myOwnerUserPassword</botcommand> and the bot will add your
|
||||
current hostmask to your owner user (of course, you should
|
||||
change <literal>myOwnerUser</literal> and
|
||||
<literal>myOwnerUserPassword</literal> appropriately for
|
||||
your bot).
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
How do I make Supybot op my users?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
First, you'll have to make sure that your users register
|
||||
with the bot. They can do this with the
|
||||
<botcommand>register</botcommand> command. After they do
|
||||
so, you'll want to add the
|
||||
<capability>#channel,op</capability> capability to their
|
||||
user. Use the <botcommand>channel
|
||||
addcapability</botcommand> command to do this. After
|
||||
that, your users should be able to use the
|
||||
<botcommand>op</botcommand> command to get ops.
|
||||
</para>
|
||||
<para>
|
||||
If you want your users to be auto-opped when they join the
|
||||
channel, you'll need to load the <plugin>Enforcer</plugin>
|
||||
plugin and turn its <registrygroup>autoOp</registrygroup>
|
||||
configuration variable on. Use the
|
||||
<botcommand>config</botcommand> command to do so. Here's
|
||||
an example of how to do these steps:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch|lambda> I'm going to make an example session for giving
|
||||
you auto-ops, for our FAQ.
|
||||
<dunk1> ah ok ;]
|
||||
<jemfinch|lambda> First, I need you to register with supybot, using
|
||||
the "register" command (remember to send it in private).
|
||||
<dunk1> done
|
||||
<jemfinch|lambda> what name are you registered under?
|
||||
<dunk1> dunk1
|
||||
<jemfinch|lambda> ok, cool.
|
||||
<jemfinch|lambda> @channel addcapability dunk1 op
|
||||
<supybot> jemfinch|lambda: The operation succeeded.
|
||||
<jemfinch|lambda> now use the "op" command to get ops.
|
||||
<dunk1> @op
|
||||
— supybot gives channel operator status to dunk1
|
||||
<dunk1> works!
|
||||
<dunk1> ;]
|
||||
<jemfinch|lambda> @load Enforcer
|
||||
<supybot> jemfinch|lambda: The operation succeeded.
|
||||
<jemfinch|lambda> @config supybot.plugins.Enforcer.autoOp.#supybot On
|
||||
<supybot> jemfinch|lambda: The operation succeeded.
|
||||
<jemfinch|lambda> ok, now cycle the channel (part and then rejoin)
|
||||
<– dunk1 (dunker@freebsd.nl) has left #supybot
|
||||
–> dunk1 (dunker@freebsd.nl) has joined #supybot
|
||||
— supybot gives channel operator status to dunk1
|
||||
<jemfinch|lambda> cool, thanks :)
|
||||
</ircsession>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
Can users with the <capability>admin</capability>
|
||||
capability change configuration variables?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
Currently, no. Since this is the first release of Supybot
|
||||
that uses the registry, we wanted to stay on the
|
||||
conservative side and require the
|
||||
<capability>owner</capability> capability for changing all
|
||||
non-channel-related configuration variables. Feel free to
|
||||
make your case to us as to why a certain configuration
|
||||
variable should only require the
|
||||
<capability>admin</capability> capability instead of the
|
||||
<capability>owner</capability> capability, and if we agree
|
||||
with you, we'll change it for the next release.
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
How do I make my Supybot connect to multiple servers?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
You'll need to use the <plugin>Relay</plugin> plugin. As
|
||||
long as you don't call the <botcommand>relay
|
||||
join</botcommand> command, it won't actually do any
|
||||
relaying between channels (even if the bot is on the same
|
||||
channel on different networks). In order to use the Relay
|
||||
plugin, you'll want to first call the <botcommand>relay
|
||||
start</botcommand> command, followed by the
|
||||
<botcommand>relay connect</botcommand> command. These
|
||||
commands are (unfortunately) not persistent at this time,
|
||||
so you'll need to give them to the bot anytime you start
|
||||
it up. We'll probably have this lack of persistence
|
||||
rectified before the next release.
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
Can Supybot do factoids?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
Supybot most certainly can! In fact, we offer two
|
||||
full-fledged factoids-related plugins!
|
||||
</para>
|
||||
<para>
|
||||
<plugin>Factoids</plugin> (written by
|
||||
<nick>jemfinch</nick>) is Supybot's original
|
||||
factoids-related plugin. It offers full integration with
|
||||
Supybot's nested commands as well as a complete 1:n key to
|
||||
factoid ratio, with lookup by individual number.
|
||||
<plugin>Factoids</plugin> also uses a channel-specific
|
||||
database instead of a global database, although in the
|
||||
future it will likely be a configuration option whether to
|
||||
use channel-specific or global databases for such plugins.
|
||||
</para>
|
||||
<para>
|
||||
<plugin>MoobotFactoids</plugin> (written by
|
||||
<nick>Strike</nick>) is much more full-featured, offering
|
||||
users the ability to define factoids in a slightly more
|
||||
user-friendly way, as well as parsing factoids to handle
|
||||
<reply>, <action>, "see", and alternations
|
||||
(defining a factoid "test" as "<reply>(foo|bar|baz)"
|
||||
will make the bot send "foo" or "bar" or "baz" to the
|
||||
channel (without the normal "test is " at the beginning)).
|
||||
If you're accustomed to Moobot's factoids or Blootbot's
|
||||
factoids, then this is the Factoids plugin for you.
|
||||
Unfortunately, due to the more natural definition syntax
|
||||
(required to be compatible with Moobot) you can't define
|
||||
Factoids with nested commands; you'll have to evaluate the
|
||||
command first and then copy the result into your factoid
|
||||
definition. <plugin>MoobotFactoids</plugin> uses a global
|
||||
database, so the factoids are the same for all channels.
|
||||
</para>
|
||||
<para>
|
||||
In the future, we plan to have a compatibility plugin for
|
||||
Infobot, but as of present we've not yet written one.
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
Can I import my Infobot/Blootbot/Moobot factoids into
|
||||
Supybot?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
As of present, we have no automated way to do so.
|
||||
<nick>Strike</nick> has written a few scripts for
|
||||
importing a Moobot database into
|
||||
<plugin>MoobotFactoids</plugin>, however, so you'll want
|
||||
to talk to him about helping you with that. We're
|
||||
certainly happy to help you convert such databases; if you
|
||||
can provide us with such a database exported to a flat
|
||||
file, we can probably do the rest of the work to write a
|
||||
script that imports it into a database for one of our
|
||||
factoids-related plugins.
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
I found a bug, what do I do?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
Submit it on Sourceforge through our Sourceforge project
|
||||
page:
|
||||
<ulink
|
||||
url="http://sourceforge.net/tracker/?group_id=58965&atid=489447">
|
||||
http://sourceforge.net/tracker/?group_id=58965&atid=489447
|
||||
</ulink>. If Sourceforge happens to be down when you try
|
||||
to submit your bug, then post it in the "Supybot Developer
|
||||
Discussion" forum at our forums at
|
||||
<ulink url="http://forums.supybot.org">
|
||||
http://forums.supybot.org/
|
||||
</ulink>. If that doesn't work, email
|
||||
<email>supybot-bugs@lists.sourceforge.net</email>. If
|
||||
that doesn't work, email
|
||||
<email>jemfinch@supybot.org</email>. If that doesn't
|
||||
work, find yourself some carrier pigeons and … hah!
|
||||
You thought I was serious!
|
||||
</para>
|
||||
<para>
|
||||
Anyway, when you submit your bug, we'll need several
|
||||
things. If the bug involved an uncaught exception, we
|
||||
need the traceback (basically the stuff from
|
||||
“Uncaught exception in …” to the next
|
||||
log entry). We'd also like to see the commands that
|
||||
caused the bug, or happened around the time you saw the
|
||||
bug. If the bug involved a database, we'd love to see the
|
||||
database. Remember, it's always worse to send us too much
|
||||
information in a bug report than too little.
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
Karma doesn't seem to work for me.
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
<plugin>Karma</plugin> by default doesn't acknowledge
|
||||
karma updates. If you check the karma of whatever you
|
||||
increased/decreased, you'll note that your increment or
|
||||
decrement still took place. If you'd rather
|
||||
<plugin>Karma</plugin> acknowledge karma updates, change
|
||||
the
|
||||
<registrygroup>supybot.plugins.Karma.response</registrygroup>
|
||||
configuration variable to <literal>On</literal>.
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
</qandaset>
|
||||
</article>
|
||||
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
<!DOCTYPE article SYSTEM "supybot.dtd">
|
||||
|
||||
<article>
|
||||
<articleinfo>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Jeremiah</firstname>
|
||||
<surname>Fincher</surname>
|
||||
</author>
|
||||
<editor>
|
||||
<firstname>Daniel</firstname>
|
||||
<surname>DiPaolo</surname>
|
||||
<contrib>DocBook translator</contrib>
|
||||
</editor>
|
||||
</authorgroup>
|
||||
<title>Getting started with Supybot</title>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>0.1</revnumber>
|
||||
<date>18 Feb 2004</date>
|
||||
<revremark>Initial Docbook translation</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</articleinfo>
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
Ok, so you've decided to try out Supybot. That's great! The more
|
||||
people who use Supybot, the more people can submit bugs and help
|
||||
us to make it the best IRC bot in the world :)
|
||||
</para>
|
||||
<para>
|
||||
First things first: Supybot <emphasis>requires</emphasis> Python
|
||||
2.3. There ain't no getting around it. If you're a Python
|
||||
developer, you probably know how superior 2.3 is to previous
|
||||
incarnations. If you're not, just think about the difference
|
||||
between a bowl of plain vanilla ice cream and a banana split. Or
|
||||
something like that. Either way, <emphasis>we're</emphasis>
|
||||
Python developers and we like banana splits.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>Installing the bot and its utilities</title>
|
||||
<para>
|
||||
So what do you do? First thing you'll want to do is run (with
|
||||
root/admin privileges) <application>python setup.py
|
||||
install</application>. This will install Supybot globally. If
|
||||
you need to install locally for whatever reason, see this <ulink
|
||||
url="http://tinyurl.com/2tb37">forum post</ulink> on how to do so.
|
||||
You'll then have several new programs installed where Python
|
||||
scripts are normally installed on your system
|
||||
(<filename>/usr/bin</filename> or
|
||||
<filename>/usr/local/bin</filename> are common on UNIX systems;
|
||||
<filename>C:\Python23\Scripts</filename> is a common place on
|
||||
Windows; and (watch out, this is a long one :))
|
||||
<filename>/System/Library/Frameworks/Python.framework/Versions/2.3/bin</filename>
|
||||
is a common place on MacOS X.). The two that might be of
|
||||
particular interest to you, the new user, are
|
||||
<script>supybot</script> and
|
||||
<script>supybot-wizard</script> The former
|
||||
(<script>supybot</script> is the script to run an actual
|
||||
bot; the latter (<script>supybot-wizard</script> is an
|
||||
in-depth wizard that provides a nice user interface for creating
|
||||
configuration files for your bot. We'd prefer you to the use
|
||||
<script>supybot-wizard</script>, but if you're in a
|
||||
hurry or don't feel like being asked many questions, just run
|
||||
supybot with no arguments and it'll ask you only the questions
|
||||
necessary ")to run a bot.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>Firing up the bot for the first time</title>
|
||||
<para>
|
||||
So after running either of those two programs, you've got a nice
|
||||
registry file handy. If you're not satisfied with your answers
|
||||
to any of the questions you were asked, feel free to run the
|
||||
program again until you're satisfied with all your answers. Once
|
||||
you're satisfied, though, run the
|
||||
<script>supybot</script> program with the
|
||||
registry file you created as an argument. This will start the
|
||||
bot; unless you turned off logging to stdout, you'll see some nice
|
||||
log messages describing what the bot is doing at any particular
|
||||
moment; it may pause for a significant amount of time after saying
|
||||
"Connecting to ..." while the server tries to check its ident.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>Your first interactions with the bot</title>
|
||||
<para>
|
||||
Ok, so let's assume your bot connected to the server fine and
|
||||
joined the channels you told it to join. For now we'll assume you
|
||||
named your bot <nick>supybot</nick> (you probably didn't,
|
||||
but it'll make it much clearer in the examples that follow to
|
||||
assume that you did). We'll also assume that you told it to join
|
||||
<channel>#channel</channel> (a nice generic name for a channel,
|
||||
isn't it? :)) So what do you do with this bot that you just made
|
||||
to join your channel? Try this in the channel:
|
||||
</para>
|
||||
<ircsession>
|
||||
supybot: list
|
||||
</ircsession>
|
||||
<para>
|
||||
Replacing <nick>supybot</nick> with the actual name you
|
||||
picked for your bot, of course. Your bot should reply with a list
|
||||
of the plugins he currently has loaded. At least
|
||||
<plugin>Admin</plugin>, <plugin>Channel</plugin>,
|
||||
<plugin>Config</plugin>, <plugin>Misc</plugin>,
|
||||
<plugin>Owner</plugin>, and <plugin>User</plugin> should be
|
||||
there; if you used <script>supybot-wizard</script> to
|
||||
create your configuration file you may have many more plugins
|
||||
loaded. The <botcommand>list</botcommand> command can also be used to
|
||||
list the commands in a given plugin:
|
||||
</para>
|
||||
<ircsession>
|
||||
supybot: list Misc
|
||||
</ircsession>
|
||||
<para>
|
||||
Will list all the commands in the <plugin>Misc</plugin> plugin.
|
||||
</para>
|
||||
<sect2>
|
||||
<title>Accessing the bot's online help</title>
|
||||
<para>
|
||||
If you want to see the help for any command, just use
|
||||
the <botcommand>help</botcommand> command:
|
||||
</para>
|
||||
<ircsession>
|
||||
supybot: help help
|
||||
supybot: help list
|
||||
supybot: help load
|
||||
</ircsession>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Dealing with ambiguous commands</title>
|
||||
<para>
|
||||
Sometimes more than one plugin will have a given command; for
|
||||
instance, the <botcommand>list</botcommand> command exists in both
|
||||
the <plugin>Misc</plugin> and <plugin>Config</plugin>
|
||||
plugins (both loaded by default). <plugin>List</plugin>, in
|
||||
this case, defaults to the <plugin>Misc</plugin> plugin, but
|
||||
you may want to get the help for the
|
||||
<botcommand>list</botcommand>
|
||||
command in the <plugin>Config</plugin> plugin. In that
|
||||
case, you'll want to give your command like this:
|
||||
</para>
|
||||
<ircsession>
|
||||
supybot: help config list
|
||||
</ircsession>
|
||||
<para>
|
||||
Anytime your bot tells you that a given command is defined in
|
||||
several plugins, you'll want to use this syntax
|
||||
(<botcommand>plugin command</botcommand>) to disambiguate which
|
||||
plugin's command you wish to call. For instance, if you
|
||||
wanted to call the <plugin>Config</plugin> plugin's
|
||||
<botcommand>list</botcommand> command, then you'd need to say:
|
||||
</para>
|
||||
<ircsession>
|
||||
supybot: config list
|
||||
</ircsession>
|
||||
<para>
|
||||
Rather than just <botcommand>list</botcommand>.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Loading plugins</title>
|
||||
<para>
|
||||
Now that you know how to deal with plugins having commands
|
||||
with the same name, let's take a look at loading other
|
||||
plugins. If you didn't use
|
||||
<script>supybot-wizard</script>, though, you might
|
||||
do well to try it before playing around with loading plugins
|
||||
yourself: each plugin has its own
|
||||
<function>configure</function> function that the wizard uses
|
||||
to setup the appropriate registry entries if the plugin
|
||||
requires any.
|
||||
</para>
|
||||
<sect3>
|
||||
<title>Identifying yourself as the bot owner</title>
|
||||
<para>
|
||||
Now, if you do want to play around with loading plugins,
|
||||
you're going to need to have the
|
||||
<capability>owner</capability>
|
||||
capability. If you ran the wizard, then chances are you
|
||||
already added an owner user for yourself. If not,
|
||||
however, you can add one via the handy-dandy
|
||||
<script>supybot-adduser</script> script. You'll
|
||||
want to run it while the bot is not running (otherwise it
|
||||
could overwrite
|
||||
<script>supybot-adduser</script>'s changes to
|
||||
your user database before you get a chance to reload
|
||||
them). Just follow the prompts, and when it asks if you
|
||||
want to give the user any capabilities, say yes and then
|
||||
give yourself the <capability>owner</capability> capability
|
||||
(without the quotes), restart the bot and you'll be ready
|
||||
to load some plugins!
|
||||
</para>
|
||||
<para>
|
||||
Now, in order for the bot to recognize you as your owner
|
||||
user, you'll have to identify with the bot. Open up a
|
||||
query window in your irc client (/query should do it; if
|
||||
not, just know that you can't identify in a channel
|
||||
because it requires sending your password to the bot).
|
||||
Then type this:
|
||||
</para>
|
||||
<ircsession>
|
||||
help identify
|
||||
</ircsession>
|
||||
<para>
|
||||
And follow the instructions; the command you send will
|
||||
probably look like this, with your owner user and password
|
||||
replaced:
|
||||
</para>
|
||||
<ircsession>
|
||||
identify myowneruser myuserpassword
|
||||
</ircsession>
|
||||
<para>
|
||||
The bot will tell you that “The operation
|
||||
succeeded” if you got the right name and password.
|
||||
Now that you're identified, you can do anything that
|
||||
requires any privilege: that includes all the commands in
|
||||
the <plugin>Owner</plugin> and <plugin>Admin</plugin>
|
||||
plugins, which you may want to take a look at (using the
|
||||
<botcommand>list</botcommand> and
|
||||
<botcommand>help</botcommand>
|
||||
commands, of course). One command in particular that you
|
||||
might want to use (it's from the <plugin>User</plugin>
|
||||
plugin) is the <botcommand>addhostmask</botcommand> command: it
|
||||
lets you add a hostmask to your user record so the bot
|
||||
recognizes you by your hostmask instead of requiring you
|
||||
to always identify with it before it recognizes you. Use
|
||||
the <botcommand>help</botcommand> command to see how this
|
||||
command works. Here's how I often use it:
|
||||
</para>
|
||||
<ircsession>
|
||||
addhostmask myuser [hostmask] mypassword
|
||||
</ircsession>
|
||||
<para>
|
||||
You may not have seen that "[hostmask]" syntax before.
|
||||
Supybot allows nested commands, which means that any
|
||||
command's output can be nested as an argument to another
|
||||
command. The hostmask command from the
|
||||
<plugin>Misc</plugin> plugin returns the hostmask of a
|
||||
given nick, but if given no arguments, it returns the
|
||||
hostmask of the person giving the command. So the command
|
||||
above adds the hostmask I'm currently using to my user's
|
||||
list of recognized hostmasks. I'm only required to give
|
||||
<literal>mypassword</literal> if I'm not already
|
||||
identified with the bot.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>The <botcommand>more</botcommand> command</title>
|
||||
<para>
|
||||
Another command you might find yourself needing somewhat often
|
||||
is the <botcommand>more</botcommand> command. The IRC protocol
|
||||
limits messages to 512 bytes, 60 or so of which must be
|
||||
devoted to some bookkeeping. Sometimes, however, Supybot
|
||||
wants to send a message that's longer than that. What it
|
||||
does, then, is break it into "chunks" and send the first one,
|
||||
following it with "(X more messages)" where X is how many more
|
||||
chunks there are. To get to these chunks, use the more
|
||||
command. One way to try is to look at the listing of
|
||||
configuration groups for the bot (more on this in the
|
||||
CONFIGURATION document) by giving the command "config list
|
||||
supybot". Last I checked, it'll overflow into a second chunk.
|
||||
When you invoke this command, you should see output like:
|
||||
</para>
|
||||
<ircsession>
|
||||
<supybot> nick, ident, user, server, password, channels, prefixChars,
|
||||
defaultCapabilities, defaultAllow, defaultIgnore,
|
||||
humanTimestampFormat, externalIP, bracketSyntax, pipeSyntax,
|
||||
followIdentificationThroughNickChanges, alwaysJoinOnInvite,
|
||||
showSimpleSyntax, maxHistoryLength, nickmods, throttleTime,
|
||||
snarfThrottle, threadAllCommands, pingServer, pingInterval,
|
||||
upkeepInterval, flush, (1 more message)
|
||||
</ircsession>
|
||||
<para>
|
||||
Now, to see the rest of the output, simply give the command
|
||||
<botcommand>more</botcommand>, and it will show you the rest:
|
||||
</para>
|
||||
<ircsession>
|
||||
<jemfinch> more
|
||||
<supybot> httpPeekSize, and defaultSocketTimeout
|
||||
</ircsession>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>You're ready!</title>
|
||||
<para>
|
||||
You should now have a solid foundation for using Supybot. Be sure
|
||||
to check the help that is built-in to the bot itself if you have
|
||||
any questions, and enjoy using Supybot!
|
||||
</para>
|
||||
</sect1>
|
||||
</article>
|
||||
|
||||
|
|
@ -0,0 +1,585 @@
|
|||
<!DOCTYPE article SYSTEM "supybot.dtd">
|
||||
|
||||
<article>
|
||||
<articleinfo>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Jeremiah</firstname>
|
||||
<surname>Fincher</surname>
|
||||
</author>
|
||||
<editor>
|
||||
<firstname>Daniel</firstname>
|
||||
<surname>DiPaolo</surname>
|
||||
<contrib>DocBook translator</contrib>
|
||||
</editor>
|
||||
</authorgroup>
|
||||
<title>Supybot developer interfaces</title>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>0.1</revnumber>
|
||||
<date>19 Feb 2004</date>
|
||||
<revremark>Initial Docbook translation</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.2</revnumber>
|
||||
<date>26 Feb 2004</date>
|
||||
<revremark>Converted to Supybot DTD</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</articleinfo>
|
||||
<sect1>
|
||||
<title>Available interfaces</title>
|
||||
<para>
|
||||
These are the interfaces for some of the objects you'll deal with
|
||||
if you code for Supybot.
|
||||
</para>
|
||||
<sect2>
|
||||
<title><classname>ircmsgs.IrcMsg</classname>
|
||||
<para>
|
||||
This is the object that represents an IRC message. It has
|
||||
several methods and attributes. The most important thing
|
||||
about this class, however, is that it <emphasis>is</emphasis>
|
||||
hashable, and thus <emphasis>cannot</emphasis> be modified.
|
||||
Do not change any attributes; any code that modifies an IRC
|
||||
message is <emphasis>broken</emphasis> and should not exist.
|
||||
</para>
|
||||
<variablelist>
|
||||
<title>Interesting methods</title>
|
||||
<varlistentry>
|
||||
<term>__init__</term>
|
||||
<listitem>
|
||||
<para>
|
||||
One of the more complex initializers in a class.
|
||||
It can be used in three different ways:
|
||||
</para>
|
||||
<orderedlist numeration="arabic" spacing="normal">
|
||||
<listitem>
|
||||
<para>
|
||||
It can be given a string, as one received
|
||||
from the server, which it will then parse
|
||||
into its separate components and
|
||||
instantiate the class with those
|
||||
components as attributes.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
It can be given a command, some (optional)
|
||||
arguments, and a (optional) prefix, and
|
||||
will instantiate the class with those
|
||||
components as attributes.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
It can be given, in addition to any of the
|
||||
above arguments, a <varname>msg</varname>
|
||||
keyword argument that will use the
|
||||
attributes of msg as defaults. This
|
||||
exists to make it easier to copy messages,
|
||||
since the class is immutable.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>__str__</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This returns the message in a string form suitable
|
||||
for sending to a server.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>__repr__</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This returns the message in a form suitable for
|
||||
<function>eval()</function>, assuming the name
|
||||
<varname>IrcMsg</varname> is in your namespace and
|
||||
is bound to this class.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
The following attributes are the meat of this class. These
|
||||
are generally what you'll be looking at with
|
||||
<varname>IrcMsg</varname>s.
|
||||
</para>
|
||||
<variablelist>
|
||||
<title>Interesting attributes</title>
|
||||
<varlistentry>
|
||||
<term>command</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is the command of the
|
||||
<varname>IrcMsg</varname> –
|
||||
<literal>PRIVMSG</literal>,
|
||||
<literal>NOTICE</literal>,
|
||||
<literal>WHOIS</literal>,
|
||||
etc.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>args</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is a tuple of the arguments to the
|
||||
<varname>IrcMsg</varname>. Some messages have
|
||||
arguments, some don't, depending on what command
|
||||
they are. You are, of course, always assured that
|
||||
<varname>args</varname> exists and is a tuple,
|
||||
though it might be empty.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>prefix</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is the hostmask of the person/server the
|
||||
message is from. In general, you won't be setting
|
||||
this on your outgoing messages, but incoming
|
||||
messages will always have one. This is the whole
|
||||
hostmask; if the message was received from a
|
||||
server, it'll be the server's hostmask; if the
|
||||
message was received from a user, it'll be the
|
||||
whole user hostmask. In that case, however, it's
|
||||
also parsed out into the
|
||||
<varname>nick</varname>/<varname>user</varname>/<varname>host</varname>
|
||||
attributes, which are probably more useful to
|
||||
check for many purposes.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>nick</term>
|
||||
<listitem>
|
||||
<para>
|
||||
If the message was sent by a user, this will be
|
||||
the nick of the user. If it was sent by a server,
|
||||
this will be the server's name (something like
|
||||
<literal>calvino.freenode.net</literal> or
|
||||
similar).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>user</term>
|
||||
<listitem>
|
||||
<para>
|
||||
If the message was sent by a user, this will be
|
||||
the user string of the user – what they put
|
||||
into their IRC client for their "full name." If
|
||||
it was sent by a server, it'll be the server's
|
||||
name, again.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>host</term>
|
||||
<listitem>
|
||||
<para>
|
||||
If the message was sent by a user, this will be
|
||||
the host portion of their hostmask. If it was
|
||||
sent by a server, it'll be the server's name (yet
|
||||
again :))
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title><classname>irclib.Irc</classname>
|
||||
<para>
|
||||
This is the object to handle everything about IRC except the
|
||||
actual connection to the server itself.
|
||||
(<emphasis>NOTE</emphasis> that the object actually received
|
||||
by commands in subclasses of
|
||||
<classname>callbacks.Privmsg</classname> is an
|
||||
<classname>IrcObjectProxy</classname>, which is described
|
||||
later. It augments the following interface with several
|
||||
methods of its own to help plugin authors.)
|
||||
</para>
|
||||
<variablelist>
|
||||
<title>Interesting methods</title>
|
||||
<varlistentry>
|
||||
<term>queueMsg</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Queues a message for sending to the server. The
|
||||
queue is generally FIFO, but it does prioritize
|
||||
messages based on their command.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>sendMsg</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Queues a message for sending to the server prior
|
||||
to any messages in the normal queue. This is
|
||||
exactly a FIFO queue, no reordering is done at
|
||||
all.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<!--<note>
|
||||
<para>
|
||||
The following two methods are the most important for
|
||||
people writing new <varname>IrcDriver</varname>s.
|
||||
Otherwise, you really don't need to pay attention to
|
||||
them.
|
||||
</para>
|
||||
</note>-->
|
||||
<varlistentry>
|
||||
<term>feedMsg</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Feeds the <varname>Irc</varname> object a message
|
||||
for it handle appropriately, as well as passing it
|
||||
on to callbacks.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>takeMsg</term>
|
||||
<listitem>
|
||||
<para>
|
||||
If the <varname>Irc</varname> object has a message
|
||||
it's ready to send to the server, this will return
|
||||
it. Otherwise, it will return
|
||||
<literal>None</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<!--<note>
|
||||
<para>
|
||||
The next several methods are of far more marginal
|
||||
utility. But someone may need them, so they're
|
||||
documented here.
|
||||
</para>
|
||||
</note>-->
|
||||
<varlistentry>
|
||||
<term>addCallback</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Takes a callback to add to the list of callbacks
|
||||
in the <varname>Irc</varname> object. See the
|
||||
interface for <varname>IrcCallback</varname> for
|
||||
more information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>getCallback</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Gets a callback by name, if it is in the
|
||||
<varname>Irc</varname> object's list of callbacks.
|
||||
If it it isn't, returns <literal>None</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>removeCallback</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Removes a callback by name. Returns a list of the
|
||||
callbacks removed (since it is technically
|
||||
possible to have multiple callbacks with the same
|
||||
name. This list may be empty.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>__init__</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Requires a <varname>nick</varname>. Optional
|
||||
arguments include <varname>user</varname> and
|
||||
<varname>ident</varname>, which default to the
|
||||
nick given, <varname>password</varname>, which
|
||||
defaults to the empty password, and
|
||||
<varname>callbacks</varname>, a list of callbacks
|
||||
(which defaults to nothing, an empty list).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>reset</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Resets the <varname>Irc</varname> object to its
|
||||
original state, as well as sends a
|
||||
<function>reset()</function> to every callbacks.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>die</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Kills the IRC object and all its callbacks.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<variablelist>
|
||||
<title>Interesting attributes</title>
|
||||
<varlistentry>
|
||||
<term>nick</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The current nick of the bot.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>prefix</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The current prefix of the bot.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>server</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The current server the bot is connected to.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>network</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The current network name the bot is connected to.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>afterConnect</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>False</literal> until the bot has
|
||||
received a command sent after the connection is
|
||||
finished – 376, 377, or 422.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>state</term>
|
||||
<listitem>
|
||||
<para>
|
||||
An <varname>IrcState</varname> object for this
|
||||
particular connection. See the interface for the
|
||||
<varname>IrcState</varname> object for more
|
||||
information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title><classname>irclib.IrcCallback</classname></title>
|
||||
<variablelist>
|
||||
<title>Interesting Methods</title>
|
||||
<varlistentry>
|
||||
<term>name</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Returns the name of the callback. The default
|
||||
implementation simply returns the name of the
|
||||
class.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>__call__</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Called by the <varname>Irc</varname> object with
|
||||
itself and the message whenever a message is fed
|
||||
to the <varname>Irc</varname> object. Nothing is
|
||||
done with the return value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>inFilter</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Called by the <varname>Irc</varname> object with
|
||||
itself and the message whenever a message is fed
|
||||
to the <varname>Irc</varname> object. The return
|
||||
value should be an <varname>IrcMsg</varname>
|
||||
object to be passed to the next callback in the
|
||||
<varname>Irc</varname>'s list of callbacks. If
|
||||
<literal>None</literal> is returned, all
|
||||
processing stops. This gives callbacks an
|
||||
oppurtunity to "filter" incoming messages before
|
||||
general callbacks are given them.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>outFilter</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Basically equivalent to
|
||||
<varname>inFilter</varname>, except instead of
|
||||
being called on messages as they enter the
|
||||
<varname>Irc</varname> object, it's called on
|
||||
messages as they leave the <varname>Irc</varname>
|
||||
object.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>die</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Called when the parent <varname>Irc</varname> is
|
||||
told to die. This gives callbacks an oppurtunity
|
||||
to close open files, network connections, or
|
||||
databases before they're deleted.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>reset</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Called when the parent <varname>Irc</varname> is
|
||||
told to reset (which is generally when
|
||||
reconnecting to the server). Most callbacks don't
|
||||
need to define this.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<variablelist>
|
||||
<title>Interesting attributes</title>
|
||||
<varlistentry>
|
||||
<term>priority</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Determines the priority of the callback in the
|
||||
<varname>Irc</varname> object's list of callbacks.
|
||||
Defaults to <literal>99</literal>; the valid range
|
||||
includes <literal>0</literal> through
|
||||
<literal>sys.maxint-1</literal> (don't use
|
||||
<literal>sys.maxint</literal> itself, that's
|
||||
reserved for the <varname>Misc</varname> plugin).
|
||||
The lower the number, the higher the priority.
|
||||
High priority callbacks are called earlier in the
|
||||
<varname>inFilter</varname> cycle, earlier in the
|
||||
<varname>__call__</varname> cycle, and later in
|
||||
the <varname>outFilter</varname> cycle –
|
||||
basically, they're given the first chances on the
|
||||
way in and the last chances on the way out.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title><classname>callbacks.IrcObjectProxy</classname></title>
|
||||
<para>
|
||||
<classname>IrcObjectProxy</classname> is a proxy for an
|
||||
<classname>irclib.Irc</classname> instance that serves to
|
||||
provide a much fuller interface for handling replies and
|
||||
errors as well as to handle the nesting of commands. This is
|
||||
what you'll be dealing with almost all the time when writing
|
||||
commands; when writing <function>doCommand</function> methods
|
||||
(the kind you read about in the interface description of
|
||||
<classname>irclib.IrcCallback</classname>) you'll be dealing
|
||||
with plain old <classname>irclib.Irc</classname> objects.
|
||||
</para>
|
||||
<variablelist>
|
||||
<title>Interesting methods</title>
|
||||
<varlistentry>
|
||||
<term>reply</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Called to reply to the current message with a
|
||||
string that is to be the reply. Uses the
|
||||
<function>queueMsg</function> command discussed in
|
||||
the <classname>irclib.Irc</classname> section.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>replySuccess</term>
|
||||
<term>replyError</term>
|
||||
<listitem>
|
||||
<para>
|
||||
These reply with the configured responses for
|
||||
success and generic error, respectively. If an
|
||||
additional argument is given, it's (intelligently)
|
||||
appended to the generic message to be more
|
||||
specific.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>error</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Called to send an error reply to the current
|
||||
message; not only does the response indicate an
|
||||
error, but commands that error out break the
|
||||
nested-command chain, which is generally useful
|
||||
for not confusing the user :)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>errorNoCapability</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Like <function>error</function>, except it accepts
|
||||
the capability that's missing and integrates it
|
||||
into the configured error message for such things.
|
||||
Also accepts an additional string for a more
|
||||
descriptive message, if that's what you want.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>errorPossibleBug</term>
|
||||
<term>errorNotRegistered</term>
|
||||
<term>errorNoUser</term>
|
||||
<term>errorRequiresPrivacy</term>
|
||||
<listitem>
|
||||
<para>
|
||||
These methods reply with the appropriate
|
||||
configured error message for the conditions in
|
||||
their names; they all take an additional arguments
|
||||
to be more specific about the conditions they
|
||||
indicate, but this argument is very rarely
|
||||
necessary.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>getRealIrc</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Returns the actual <classname>Irc</classname>
|
||||
object being proxied for.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</article>
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
(define %stylesheet% "../stylesheets/supybot.css")
|
||||
|
||||
(element botcommand
|
||||
(make element gi: "span"
|
||||
attributes: '(("class" "botcommand"))
|
||||
(process-children)))
|
||||
|
||||
(element plugin
|
||||
(make element gi: "span"
|
||||
attributes: '(("class" "plugin"))
|
||||
(process-children)))
|
||||
|
||||
(element flag
|
||||
(make element gi: "span"
|
||||
attributes: '(("class" "flag"))
|
||||
(process-children)))
|
||||
|
||||
(element nick
|
||||
(make element gi: "span"
|
||||
attributes: '(("class" "nick"))
|
||||
(process-children)))
|
||||
|
||||
(element capability
|
||||
(make element gi: "span"
|
||||
attributes: '(("class" "capability"))
|
||||
(process-children)))
|
||||
|
||||
(element registrygroup
|
||||
(make element gi: "span"
|
||||
attributes: '(("class" "registrygroup"))
|
||||
(process-children)))
|
||||
|
||||
(element ircsession
|
||||
(make element gi: "pre"
|
||||
attributes: '(("class" "ircsession"))
|
||||
(process-children)))
|
||||
|
||||
(element script
|
||||
(make element gi: "span"
|
||||
attributes: '(("class" "script"))
|
||||
(process-children)))
|
||||
|
||||
(element channel
|
||||
(make element gi: "span"
|
||||
attributes: '(("class" "channel"))
|
||||
(process-children)))
|
|
@ -0,0 +1,43 @@
|
|||
(define %mono-font-family% "Courier New")
|
||||
|
||||
(element botcommand
|
||||
(make sequence
|
||||
font-family-name: %mono-font-family%))
|
||||
|
||||
(element plugin
|
||||
(make sequence
|
||||
font-weight: 'bold))
|
||||
|
||||
(element flag
|
||||
(make sequence
|
||||
font-posture: 'italic))
|
||||
|
||||
(element nick
|
||||
(make sequence
|
||||
font-family-name: %mono-font-family%))
|
||||
|
||||
(element capability
|
||||
(make sequence
|
||||
font-weight: 'bold))
|
||||
|
||||
(element registrygroup
|
||||
(make sequence
|
||||
font-weight: 'bold))
|
||||
|
||||
(element ircsession
|
||||
(make paragraph
|
||||
font-family-name: %mono-font-family%
|
||||
space-before: 12pt
|
||||
space-after: 12pt
|
||||
start-indent: 6pt
|
||||
lines: 'asis
|
||||
input-whitespace-treatment: 'preserve))
|
||||
|
||||
(element script
|
||||
(make sequence
|
||||
font-family-name: %mono-font-family%))
|
||||
|
||||
(element channel
|
||||
(make sequence
|
||||
font-weight: 'bold))
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
|
||||
<!ENTITY print-ss PUBLIC
|
||||
"-//Norman Walsh//DOCUMENT DocBook Print Stylesheet//EN" CDATA DSSSL>
|
||||
<!ENTITY html-ss PUBLIC
|
||||
"-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
|
||||
<!ENTITY supybot-print SYSTEM "supybot-print.dsl">
|
||||
<!ENTITY supybot-html SYSTEM "supybot-html.dsl">
|
||||
]>
|
||||
|
||||
<style-sheet>
|
||||
<style-specification id="print" use="print-stylesheet">
|
||||
<style-specification-body>
|
||||
&supybot-print;
|
||||
</style-specification-body>
|
||||
</style-specification>
|
||||
<style-specification id="html" use="html-stylesheet">
|
||||
<style-specification-body>
|
||||
&supybot-html;
|
||||
</style-specification-body>
|
||||
</style-specification>
|
||||
<external-specification id="print-stylesheet" document="print-ss">
|
||||
<external-specification id="html-stylesheet" document="html-ss">
|
||||
</style-sheet>
|
|
@ -0,0 +1,137 @@
|
|||
<!-- Segregate all of our stuff into its own class for possible extension
|
||||
later and just because I wanted to write my own class :) -->
|
||||
<!ENTITY % local.supybot.class "">
|
||||
<!ENTITY % supybot.class "BotCommand|Plugin|Flag|Nick|Capability
|
||||
|RegistryGroup|Registry|Script
|
||||
|Channel %local.supybot.class;">
|
||||
|
||||
<!-- Stuff that isn't supybot-specific, but it's python-related and no
|
||||
suitable element exists in the DocBook DTD -->
|
||||
<!ENTITY % local.python.class "">
|
||||
<!ENTITY % python.class "Module|Keyword %local.python.class;">
|
||||
|
||||
<!-- Pretty much all of our stuff fits where stuff in the tech.char class
|
||||
goes, so we simply add our stuff using the local extension -->
|
||||
<!ENTITY % local.tech.char.class "|%supybot.class;|%python.class;">
|
||||
|
||||
<!-- linespecific is the same class as things like screen and programlisting,
|
||||
so it's added here to fit with the DocBook stuff (i.e., so putting an
|
||||
ircsession in where one of those previous two elements would be is a
|
||||
valid operation -->
|
||||
<!ENTITY % local.linespecific.class "|IrcSession">
|
||||
|
||||
<!-- Source the original DocBook DTD -->
|
||||
<!ENTITY % DocBookDTD PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
|
||||
%DocBookDTD;
|
||||
|
||||
<!ELEMENT BotCommand - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.botcommand.attrib "">
|
||||
<!ENTITY % botcommand.role.attrib "%role.attrib;">
|
||||
<!ATTLIST BotCommand
|
||||
%common.attrib;
|
||||
%local.botcommand.attrib;
|
||||
%botcommand.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Plugin - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.plugin.attrib "">
|
||||
<!ENTITY % plugin.role.attrib "%role.attrib;">
|
||||
<!ATTLIST Plugin
|
||||
%common.attrib;
|
||||
%local.plugin.attrib;
|
||||
%plugin.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Flag - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.flag.attrib "">
|
||||
<!ENTITY % flag.role.attrib
|
||||
"
|
||||
flagtype (arg|noarg) #IMPLIED
|
||||
%role.attrib;"
|
||||
>
|
||||
<!ATTLIST Flag
|
||||
%common.attrib;
|
||||
%local.flag.attrib;
|
||||
%flag.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Nick - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.nick.attrib "">
|
||||
<!ENTITY % nick.role.attrib "%role.attrib;">
|
||||
<!ATTLIST Nick
|
||||
%common.attrib;
|
||||
%local.nick.attrib;
|
||||
%nick.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Capability - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.capability.attrib "">
|
||||
<!ENTITY % capability.role.attrib "%role.attrib;">
|
||||
<!ATTLIST Capability
|
||||
%common.attrib;
|
||||
%local.capability.attrib;
|
||||
%capability.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Comment - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.comment.attrib "">
|
||||
<!ENTITY % comment.role.attrib "%role.attrib;">
|
||||
<!ATTLIST Comment
|
||||
%common.attrib;
|
||||
%local.comment.attrib;
|
||||
%comment.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT RegistryGroup - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.registrygroup.attrib "">
|
||||
<!ENTITY % registrygroup.role.attrib "%role.attrib;">
|
||||
<!ATTLIST RegistryGroup
|
||||
%common.attrib;
|
||||
%local.registrygroup.attrib;
|
||||
%registrygroup.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Registry - - ((RegistryGroup|Comment)+)>
|
||||
<!ENTITY % local.registry.attrib "">
|
||||
<!ENTITY % registry.role.attrib "%role.attrib;">
|
||||
<!ATTLIST Registry
|
||||
%common.attrib;
|
||||
%local.registry.attrib;
|
||||
%registry.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT IrcSession - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.ircsession.attrib "">
|
||||
<!ENTITY % ircsession.role.attrib "%role.attrib;">
|
||||
<!ATTLIST IrcSession
|
||||
%common.attrib;
|
||||
%local.ircsession.attrib;
|
||||
%ircsession.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Script - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.script.attrib "">
|
||||
<!ENTITY % script.role.attrib "%role.attrib;">
|
||||
<!ATTLIST Script
|
||||
%common.attrib;
|
||||
%local.script.attrib;
|
||||
%script.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Channel - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.channel.attrib "">
|
||||
<!ENTITY % channel.role.attrib "%role.attrib;">
|
||||
<!ATTLIST Channel
|
||||
%common.attrib;
|
||||
%local.channel.attrib;
|
||||
%channel.role.attrib;
|
||||
>
|
||||
|
||||
<!ELEMENT Module - - ((%smallcptr.char.mix)+)>
|
||||
<!ENTITY % local.module.attrib "">
|
||||
<!ENTITY % module.role.attrib "%role.attrib;">
|
||||
<!ATTLIST Module
|
||||
%common.attrib;
|
||||
%local.module.attrib;
|
||||
%module.role.attrib;
|
||||
>
|
Loading…
Reference in New Issue