diff --git a/docs/DocBook/capabilities.sgml b/docs/DocBook/capabilities.sgml
index e161cfb63..a8c6ef6e7 100644
--- a/docs/DocBook/capabilities.sgml
+++ b/docs/DocBook/capabilities.sgml
@@ -1,4 +1,4 @@
-
+
@@ -18,7 +18,7 @@
0.1
18 Feb 2004
- Initial revision
+ Initial Docbook translation
@@ -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 o
flag, are instead able to check if a user has the
- owner capability. At this point such a
+ owner 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.
@@ -68,49 +68,49 @@
“anticapability” for that command. An anticapability is
a capability that, instead of saying “what a user can
do”, says what a user cannot do. It's
- formed rather simply by adding a dash (“-”) to the
- beginning of a capability; rot13 is a
- capability, and -rot13 is an anticapability.
- Anyway, when a user issues the bot a command, perhaps
- calc or help the bot
- first checks to make sure the user doesn't have the
- -calc or the -help
- capabilities before even considering responding to the user. So
- commands can be turned on or off on a per
- user basis, offering finegrained control not often (if
- at all!) seen in other bots.
+ formed rather simply by adding a dash (“-”) to the
+ beginning of a capability; rot13 is a
+ capability, and -rot13 is an
+ anticapability. Anyway, when a user issues the bot a command,
+ perhaps calc or
+ help, the bot first checks to make sure
+ the user doesn't have the -calc or the
+ -help capabilities before even
+ considering responding to the user. So commands can be turned on
+ or off on a per user basis, offering
+ finegrained control not often (if at all!) seen in other bots.
Channel capabilities
But that's not all! The capabilities system also supports
Channel capabilities, which are
- capabilities that only apply to a specific channel; they're of
- the form #channel.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 in that
- channel 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
- individual user, we can now turn commands on or off for an
- individual user on an individual channel!
+ capabilities that only apply to a specific channel; they're of
+ the form #channel.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 in that
+ channel 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
+ individual user, we can now turn commands on or off for an
+ individual user on an individual channel!
- So when a user foo sends a command
- bar to the bot on channel
- #baz, first the bot checks to see if the
- user has the anticapability for the command by itself,
- -bar. 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,
- #baz.-bar. 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.
+ So when a user foo sends a command
+ bar to the bot on channel
+ #baz, first the bot checks to see if the
+ user has the anticapability for the command by itself,
+ -bar. 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,
+ #baz.-bar. 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.
@@ -148,14 +148,14 @@
Hard-coded supybot capabilities
There are several default capabilities the bot uses. The most
- important of these is the owner capability.
- This capability allows the person having it to use
- any command. It's best to keep this
- capability reserved to people who actually have access to the
- shell the bot is running on.
+ important of these is the owner
+ capability. This capability allows the person having it to use
+ any command. It's best to keep this
+ capability reserved to people who actually have access to the
+ shell the bot is running on.
- There is also the admin capability for
+ There is also the admin 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
@@ -164,40 +164,41 @@
people with the next capability.
- People who are to administer channels with the bot should have the
- #channel.op capability -- whatever channel they
- are to administrate, they should have that channel capability for
- op. For example, since I want
- inkedmn to be an administrator in
- #supybot, I'll give him the
- #supybot.op capability. This is in addition to
- his admin capability, since the
- admin capability doesn't give the person having
- it control over channels. #channel.op 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 #channel.op
- capability is also basically the equivalent of the owner
- capability for capabilities involving #channel
- – basically anyone with the #channel.op
- capability is considered to have all positive capabilities and no
- negative capabilities for #channel.
+ People who are to administer channels with the bot should have the
+ #channel.op capability -- whatever
+ channel they are to administrate, they should have that channel
+ capability for op. For example, since I
+ want inkedmn to be an administrator in
+ #supybot, I'll give him the
+ #supybot.op capability. This is in
+ addition to his admin capability, since
+ the admin capability doesn't give the
+ person having it control over channels.
+ #channel.op 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 #channel.op capability
+ is also basically the equivalent of the owner capability for
+ capabilities involving #channel –
+ basically anyone with the #channel.op
+ capability is considered to have all positive capabilities and no
+ negative capabilities for #channel.
- One other globally important capability exists:
- trusted. 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
- Math.icalc, 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 Utilties.re, 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
- take exponential time to process). Consider what would happen if
- the someone gave the bot the command re [strjoin "" s/./
- [dict go] /] [dict go].
+ One other globally important capability exists:
+ trusted. 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
+ Math.icalc, 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 Utilties.re, 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
+ take exponential time to process). Consider what would happen if
+ the someone gave the bot the command re [strjoin "" s/./
+ [dict go] /] [dict go].
diff --git a/docs/DocBook/configuration.sgml b/docs/DocBook/configuration.sgml
new file mode 100644
index 000000000..e719dac76
--- /dev/null
+++ b/docs/DocBook/configuration.sgml
@@ -0,0 +1,311 @@
+
+
+
+
+
+
+ Jeremiah
+ Fincher
+
+
+ Daniel
+ DiPaolo
+
+
+ Daniel
+ DiPaolo
+ DocBook translator
+
+
+ Supybot configuration system explanation
+
+
+ 0.1
+ 18 Feb 2004
+ Initial Docbook translation
+
+
+ 0.2
+ 26 Feb 2004
+ Conversion to Supybot DTD
+
+
+
+
+ Introduction
+
+ 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.
+
+
+ Configuration of Supybot is handled via the
+ Config plugin, which controls runtime access to
+ Supybot's registry (the configuration file generated by the
+ program you ran). The
+ Config 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: get,
+ set, list, and
+ help. If you don't know how to get help on
+ those commands, go ahead and read our
+ GETTING_STARTED document before this one.
+
+
+
+ Supybot's registry
+
+ 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
+ supybot.reply; variables having to
+ do with the way a plugin works all start with
+ supybot.plugins.Plugin (where
+ 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.
+
+
+ Some of the more important configuration values are located
+ directly under the base group,
+ supybot. 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: plugins (where all
+ the plugin-specific configuration is held),
+ reply (where variables affecting
+ the way a Supybot makes its replies resides),
+ replies (where all the specific
+ standard replies are kept), and
+ directories (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.
+
+
+ Config plugin commands
+
+ Listing registry contents
+
+ Using the Config 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 supybot (the base
+ group) hierarchy. You would simply issue this command:
+
+
+<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
+
+
+ These are all the configuration values you can set which
+ are under the base supybot
+ 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.
+
+
+ Now, to see all of the available configuration groups
+ under the base supybot
+ group, we simply use the --groups flag to
+ config list:
+
+
+<jemfinch|lambda> @config list --groups supybot
+<supybot> jemfinch|lambda: commands, databases, directories, drivers,
+ log, plugins, replies, and reply
+
+
+ These are all the subgroups of
+ supybot. Again, the full
+ name of these would have “supybot.” prepended
+ to them. So really, we have
+ supybot.commands,
+ supybot.databases, etc.
+
+
+
+ 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.
+
+
+
+
+ Dealing with registry values
+
+ Okay, now that you've used the Config
+ plugin to list configuration variables, it's time that we
+ start looking at individual variables and their values.
+
+
+ Built-in help for registry values
+
+ 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 config help. To see the
+ help string for any value or group, simply use the
+ config help command. For
+ example, to see what this
+ supybot.prefixChars
+ configuration variable is all about, we'd do this:
+
+
+<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.
+
+
+ Pretty simple, eh?
+
+
+
+ Getting/setting registry values
+
+ Now, if you're curious what the current value of a
+ configuration variable is, you'll use the
+ config command with one
+ argument, the name of the variable you want to see the
+ value of:
+
+
+<jemfinch|lambda> @config supybot.prefixChars
+<supybot> jemfinch|lambda: '@'
+
+
+ To set this value, just stick an extra argument after
+ the name:
+
+
+<jemfinch|lambda> @config supybot.prefixChars @$
+<supybot> jemfinch|lambda: The operation succeeded.
+
+
+ Now, check this out:
+
+
+<jemfinch|lambda> $config supybot.prefixChars
+<supybot> jemfinch|lambda: '@$'
+
+
+ Note that we used $ as our prefix
+ character, and that the value of the configuration
+ variable changed. If I were to use the
+ flush 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
+
+ Ctrl
+ C
+
+ in the terminal the bot was running in). Instead,
+ I'll revert the change:
+
+
+<jemfinch|lambda> $config supybot.prefixChars @
+<supybot> jemfinch|lambda: The operation succeeded.
+<jemfinch|lambda> $note that this makes no response.
+
+
+ If you're ever curious what the default for a given
+ configuration variable is, use the config
+ default command:
+
+
+<jemfinch|lambda> @config default supybot.prefixChars
+<supybot> jemfinch|lambda: ''
+
+
+ Thus, to reset a configuration variable to its default
+ value, you can simply say:
+
+
+<jemfinch|lambda> @config supybot.prefixChars [config default
+ supybot.prefixChars]
+<supybot> jemfinch|lambda: The operation succeeded.
+<jemfinch|lambda> @note that this does nothing
+
+
+ Simple, eh?
+
+
+
+
+ Searching the registry
+
+ 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 config
+ search command. Check this out:
+
+
+<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
+
+
+ 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.
+
+
+ Some people might like editing their registry file
+ directly rather than manipulating all these things through
+ the bot. For those people, we offer the
+ config reload command, which
+ reloads both registry configuration and
+ user/channel/ignore database configuration. Just edit the
+ interesting files and then give the bot the
+ config reload 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 supybot.flush value to
+ Off, and no automatic flushing will
+ occur.
+
+
+
+
+
+ All done!
+
+ Anyway, that's about it for configuration. Have fun, and enjoy
+ your configurable bot!
+
+
+
+
+
diff --git a/docs/DocBook/example.sgml b/docs/DocBook/example.sgml
index 95789a757..8f0987c84 100644
--- a/docs/DocBook/example.sgml
+++ b/docs/DocBook/example.sgml
@@ -1,4 +1,4 @@
-
+
@@ -32,6 +32,11 @@
Updated to match EXAMPLE included with 0.75.0
+
+ 0.4
+ 26 Feb 2004
+ Converted to use Supybot DTD
+
@@ -56,13 +61,12 @@
Creating your own plugin
- Using scripts/newplugin.py
+ Using
- First, the easiest way to start writing a module is to use the
- wizard provided,
- scripts/newplugin.py. Here's an
- example session:
+ First, the easiest way to start writing a module is to use the
+ wizard provided, .
+ Here's an example session:
functor% scripts/newplugin.py
@@ -169,7 +173,7 @@ Class = Random
Describe what you want the plugin to do in the docstring.
- This is used in scripts/setup.py in
+ This is used in 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."
- Then there are the imports. The callbacks
+ Then there are the imports. The
+ callbacks
module is used (the class you're given subclasses
- callbacks.Privmsg) but the
- privmsgs module isn't used. That's
+ callbacks.Privmsg) but the
+ privmsgs 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.
Then you see a configure function. This
the function that's called when users decide to add your
- module in scripts/setup.py. You'll
+ module in . You'll
note that by default it simply adds "load
Example" (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
What you're given is a skeleton: a simple subclass of
- callbacks.Privmsg for you to start with.
- Now let's add a command.
+ callbacks.Privmsg for you to start
+ with. Now let's add a command.
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 random module, the
+ packaged up in Python's random module, the
Random object. So the first thing we're
going to have to do is give our plugin a
Random object.
@@ -225,8 +230,8 @@ Class = Random
be careful of is that you call the superclass
__init__ method at the end of your own
__init__. So to add this
- random.Random object to our plugin, we can
- replace the pass statement with
+ random.Random object to our plugin, we
+ can replace the pass statement with
this:
@@ -285,40 +290,40 @@ def __init__(self):
And that's it! Pretty simple, huh? Anyway, you're probably
wondering what all that means. We'll
- start with the def statement:
+ start with the def statement:
def random(self, irc, msg, args):
- What that does is define a command
- random. You can call it by saying
- "@random" (or whatever prefix character your specific bot
- uses). The arguments are a bit less obvious.
- self is self-evident (hah!).
- irc is the Irc object
- passed to the command; msg is the original
- IrcMsg object. But you're really not going
- to have to deal with either of these too much (with the
- exception of calling irc.reply or
- irc.error). What you're
- really interested in is the
- args 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 Irc object in
- irclib.py (you won't find
- .reply or .error
- there, though, because you're actually getting an
- IrcObjectProxy, but that's beyond the level
- we want to describe here :)). You can read about the
- msg object in
- ircmsgs.py. But again, aside from
- calling irc.reply or
- irc.error, you'll very rarely be using
- these objects.
+ What that does is define a command
+ random. You can call it by saying
+ "@random" (or whatever prefix character your specific bot
+ uses). The arguments are a bit less obvious.
+ self is self-evident (hah!).
+ irc is the Irc
+ object passed to the command; msg is the
+ original IrcMsg object. But you're
+ really not going to have to deal with either of these too much
+ (with the exception of calling irc.reply
+ or irc.error). What you're
+ really interested in is the
+ args 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 Irc object in
+ irclib.py (you won't find
+ .reply or .error
+ there, though, because you're actually getting an
+ IrcObjectProxy, but that's beyond the
+ level we want to describe here :)). You can read about the
+ msg object in
+ ircmsgs.py. But again, aside from
+ calling irc.reply or
+ irc.error, you'll very rarely be using
+ these objects.
(In case you're curious, the answer is yes, you
@@ -342,13 +347,13 @@ def __init__(self):
is the help! Given the above docstring,
this is what a supybot does:
-
+
<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.
-
+
'help <command>' replies with the command name followed
by the first line of the command's docstring; there should be
@@ -361,21 +366,22 @@ def __init__(self):
irc.reply(msg, str(self.rng.random()))
- irc.reply takes two arguments, an
- IrcMsg (like the one passed into your
- function) and a string. The IrcMsg 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 irc.reply 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
- irc.reply a string.
+ irc.reply takes two arguments, an
+ IrcMsg (like the one passed into your
+ function) and a string. The IrcMsg 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
+ irc.reply 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
+ irc.reply a string.
Anyway, now that we have an RNG, we have a need for seed! Of
@@ -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 IndexError from
+ we've got to catch the IndexError from
args[0] and complain to the user about it.
privmsgs.getArgs, 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 return here; otherwise,
+ remember this return 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.
- The Random object we're using offers us a
- "sample" method that takes a sequence and a number (we'll call
- it N) and returns a list of
+ The Random object we're using offers us
+ a "sample" method that takes a sequence and a number (we'll
+ call it N) and returns a list of
N items taken randomly from the sequence.
So I'll show you an example that takes advantage of multiple
arguments but doesn't use
@@ -542,13 +548,13 @@ 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
privmsgs.getArgs. So what do we do? We
- raise callbacks.ArgumentError! That's the
- secret juju that privmsgs.getArgs 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
- .pop(0) fails, we weren't given enough
- arguments and thus need to tell the user how to call us.
+ raise callbacks.ArgumentError! That's
+ the secret juju that privmsgs.getArgs 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
+ .pop(0) fails, we weren't given enough
+ arguments and thus need to tell the user how to call us.
So we have the args, we have the number, we do a simple call
@@ -607,22 +613,22 @@ def __init__(self):
Later, though, you'll see something other than
irc.reply. This is
- irc.queueMsg, the general interface for
- sending messages to the server. It's what
- irc.reply is using under the covers. It
- takes an IrcMsg object. Fortunately,
- that's exactly what's returned by
- ircmsgs.action. An action message, just
- in case you don't know, is a /me kind of message.
- ircmsgs.action 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 IrcMsg object.
- ircutils.replyTo simply takes an
- IrcMsg 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.
+ irc.queueMsg, the general interface for
+ sending messages to the server. It's what
+ irc.reply is using under the covers. It
+ takes an IrcMsg object. Fortunately,
+ that's exactly what's returned by
+ ircmsgs.action. An action message, just
+ in case you don't know, is a /me kind of message.
+ ircmsgs.action 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 IrcMsg object.
+ ircutils.replyTo simply takes an
+ IrcMsg 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.
At the end, you might be surprised by the "raise
@@ -646,7 +652,7 @@ def __init__(self):
Finishing touches
Let's take a look at that configure
- function scripts/newplugin.py made
+ function made
for us. Here it is, in case you've forgotten:
@@ -660,10 +666,10 @@ def configure(onStart, afterConnect, advanced):
You remember when you first started running supybot and ran
- scripts/setup.py and it asked you
+ 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
- Random plugin, it might be nice to offer
+ Random 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)
- As you can see, what the questions module
+ As you can see, what the questions module
does is fairly self-evident: yn returns
either 'y' or 'n'; something returns
something (but not nothing; for nothing,
@@ -694,12 +700,12 @@ def configure(onStart, afterConnect, advanced):
onStart 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
- scripts/setup.py creates for the bot.
+ creates for the bot.
We've written our own plugin from scratch (well, from the
boilerplate that we got from
- scripts/newplugin.py :)) and
+ :)) and
survived! Now go write more plugins for supybot, and send
them to me so I can use them too :)
diff --git a/docs/DocBook/faq.sgml b/docs/DocBook/faq.sgml
new file mode 100644
index 000000000..caa6247c5
--- /dev/null
+++ b/docs/DocBook/faq.sgml
@@ -0,0 +1,284 @@
+
+
+
+
+
+ Jeremiah
+ Fincher
+
+
+ Daniel
+ DiPaolo
+ DocBook translator
+
+
+ Supybot Frequently Asked Questions
+
+
+ 0.1
+ 18 Feb 2004
+ Initial Docbook translation
+
+
+ 0.2
+ 26 Feb 2004
+ Changed to Supybot DTD
+
+
+
+
+
+
+
+ Why does my bot not recognize me or tell me that I don't
+ have the owner capability?
+
+
+
+
+ Because you're not given it anything to recognize you
+ from! You'll need to identify with the bot
+ (help identify to see how that
+ works) or add your hostmask to your user record
+ (help addhostmask to see how that
+ works) for it to know that you're you. You may wish to
+ note that addhostmask can accept
+ a password; rather than identify, you can send the command
+ addhostmask myOwnerUser [hostmask]
+ myOwnerUserPassword and the bot will add your
+ current hostmask to your owner user (of course, you should
+ change myOwnerUser and
+ myOwnerUserPassword appropriately for
+ your bot).
+
+
+
+
+
+
+ How do I make Supybot op my users?
+
+
+
+
+ First, you'll have to make sure that your users register
+ with the bot. They can do this with the
+ register command. After they do
+ so, you'll want to add the
+ #channel,op capability to their
+ user. Use the channel
+ addcapability command to do this. After
+ that, your users should be able to use the
+ op command to get ops.
+
+
+ If you want your users to be auto-opped when they join the
+ channel, you'll need to load the Enforcer
+ plugin and turn its autoOp
+ configuration variable on. Use the
+ config command to do so. Here's
+ an example of how to do these steps:
+
+
+ <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 :)
+
+
+
+
+
+
+ Can users with the admin
+ capability change configuration variables?
+
+
+
+
+ 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
+ owner 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
+ admin capability instead of the
+ owner capability, and if we agree
+ with you, we'll change it for the next release.
+
+
+
+
+
+
+ How do I make my Supybot connect to multiple servers?
+
+
+
+
+ You'll need to use the Relay plugin. As
+ long as you don't call the relay
+ join 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 relay
+ start command, followed by the
+ relay connect 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.
+
+
+
+
+
+
+ Can Supybot do factoids?
+
+
+
+
+ Supybot most certainly can! In fact, we offer two
+ full-fledged factoids-related plugins!
+
+
+ Factoids (written by
+ jemfinch) 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.
+ Factoids 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.
+
+
+ MoobotFactoids (written by
+ Strike) 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. MoobotFactoids uses a global
+ database, so the factoids are the same for all channels.
+
+
+ In the future, we plan to have a compatibility plugin for
+ Infobot, but as of present we've not yet written one.
+
+
+
+
+
+
+ Can I import my Infobot/Blootbot/Moobot factoids into
+ Supybot?
+
+
+
+
+ As of present, we have no automated way to do so.
+ Strike has written a few scripts for
+ importing a Moobot database into
+ MoobotFactoids, 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.
+
+
+
+
+
+
+ I found a bug, what do I do?
+
+
+
+
+ Submit it on Sourceforge through our Sourceforge project
+ page:
+
+ http://sourceforge.net/tracker/?group_id=58965&atid=489447
+ . 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
+
+ http://forums.supybot.org/
+ . If that doesn't work, email
+ supybot-bugs@lists.sourceforge.net. If
+ that doesn't work, email
+ jemfinch@supybot.org. If that doesn't
+ work, find yourself some carrier pigeons and … hah!
+ You thought I was serious!
+
+
+ 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.
+
+
+
+
+
+
+ Karma doesn't seem to work for me.
+
+
+
+
+ Karma 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
+ Karma acknowledge karma updates, change
+ the
+ supybot.plugins.Karma.response
+ configuration variable to On.
+
+
+
+
+
+
+
diff --git a/docs/DocBook/getting_started.sgml b/docs/DocBook/getting_started.sgml
new file mode 100644
index 000000000..27d029730
--- /dev/null
+++ b/docs/DocBook/getting_started.sgml
@@ -0,0 +1,297 @@
+
+
+
+
+
+
+ Jeremiah
+ Fincher
+
+
+ Daniel
+ DiPaolo
+ DocBook translator
+
+
+ Getting started with Supybot
+
+
+ 0.1
+ 18 Feb 2004
+ Initial Docbook translation
+
+
+
+
+ Introduction
+
+ 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 :)
+
+
+ First things first: Supybot requires 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, we're
+ Python developers and we like banana splits.
+
+
+
+ Installing the bot and its utilities
+
+ So what do you do? First thing you'll want to do is run (with
+ root/admin privileges) python setup.py
+ install. This will install Supybot globally. If
+ you need to install locally for whatever reason, see this forum post on how to do so.
+ You'll then have several new programs installed where Python
+ scripts are normally installed on your system
+ (/usr/bin or
+ /usr/local/bin are common on UNIX systems;
+ C:\Python23\Scripts is a common place on
+ Windows; and (watch out, this is a long one :))
+ /System/Library/Frameworks/Python.framework/Versions/2.3/bin
+ is a common place on MacOS X.). The two that might be of
+ particular interest to you, the new user, are
+ and
+ The former
+ ( is the script to run an actual
+ bot; the latter ( 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
+ , 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.
+
+
+
+ Firing up the bot for the first time
+
+ 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
+ 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.
+
+
+
+ Your first interactions with the bot
+
+ 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 supybot (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 (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:
+
+
+supybot: list
+
+
+ Replacing supybot 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
+ Admin, Channel,
+ Config, Misc,
+ Owner, and User should be
+ there; if you used to
+ create your configuration file you may have many more plugins
+ loaded. The list command can also be used to
+ list the commands in a given plugin:
+
+
+supybot: list Misc
+
+
+ Will list all the commands in the Misc plugin.
+
+
+ Accessing the bot's online help
+
+ If you want to see the help for any command, just use
+ the help command:
+
+
+supybot: help help
+supybot: help list
+supybot: help load
+
+
+
+ Dealing with ambiguous commands
+
+ Sometimes more than one plugin will have a given command; for
+ instance, the list command exists in both
+ the Misc and Config
+ plugins (both loaded by default). List, in
+ this case, defaults to the Misc plugin, but
+ you may want to get the help for the
+ list
+ command in the Config plugin. In that
+ case, you'll want to give your command like this:
+
+
+supybot: help config list
+
+
+ Anytime your bot tells you that a given command is defined in
+ several plugins, you'll want to use this syntax
+ (plugin command) to disambiguate which
+ plugin's command you wish to call. For instance, if you
+ wanted to call the Config plugin's
+ list command, then you'd need to say:
+
+
+supybot: config list
+
+
+ Rather than just list.
+
+
+
+ Loading plugins
+
+ 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
+ , though, you might
+ do well to try it before playing around with loading plugins
+ yourself: each plugin has its own
+ configure function that the wizard uses
+ to setup the appropriate registry entries if the plugin
+ requires any.
+
+
+ Identifying yourself as the bot owner
+
+ Now, if you do want to play around with loading plugins,
+ you're going to need to have the
+ owner
+ 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. You'll
+ want to run it while the bot is not running (otherwise it
+ could overwrite
+ '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 owner capability
+ (without the quotes), restart the bot and you'll be ready
+ to load some plugins!
+
+
+ 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:
+
+
+help identify
+
+
+ And follow the instructions; the command you send will
+ probably look like this, with your owner user and password
+ replaced:
+
+
+identify myowneruser myuserpassword
+
+
+ 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 Owner and Admin
+ plugins, which you may want to take a look at (using the
+ list and
+ help
+ commands, of course). One command in particular that you
+ might want to use (it's from the User
+ plugin) is the addhostmask 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 help command to see how this
+ command works. Here's how I often use it:
+
+
+addhostmask myuser [hostmask] mypassword
+
+
+ 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
+ Misc 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
+ mypassword if I'm not already
+ identified with the bot.
+
+
+
+
+ The more command
+
+ Another command you might find yourself needing somewhat often
+ is the more 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:
+
+
+<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)
+
+
+ Now, to see the rest of the output, simply give the command
+ more, and it will show you the rest:
+
+
+<jemfinch> more
+<supybot> httpPeekSize, and defaultSocketTimeout
+
+
+
+
+ You're ready!
+
+ 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!
+
+
+
+
+
diff --git a/docs/DocBook/interfaces.sgml b/docs/DocBook/interfaces.sgml
new file mode 100644
index 000000000..9251ea214
--- /dev/null
+++ b/docs/DocBook/interfaces.sgml
@@ -0,0 +1,585 @@
+
+
+
+
+
+
+ Jeremiah
+ Fincher
+
+
+ Daniel
+ DiPaolo
+ DocBook translator
+
+
+ Supybot developer interfaces
+
+
+ 0.1
+ 19 Feb 2004
+ Initial Docbook translation
+
+
+ 0.2
+ 26 Feb 2004
+ Converted to Supybot DTD
+
+
+
+
+ Available interfaces
+
+ These are the interfaces for some of the objects you'll deal with
+ if you code for Supybot.
+
+
+ ircmsgs.IrcMsg
+
+ 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 is
+ hashable, and thus cannot be modified.
+ Do not change any attributes; any code that modifies an IRC
+ message is broken and should not exist.
+
+
+ Interesting methods
+
+ __init__
+
+
+ One of the more complex initializers in a class.
+ It can be used in three different ways:
+
+
+
+
+ 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.
+
+
+
+
+ It can be given a command, some (optional)
+ arguments, and a (optional) prefix, and
+ will instantiate the class with those
+ components as attributes.
+
+
+
+
+ It can be given, in addition to any of the
+ above arguments, a msg
+ 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.
+
+
+
+
+
+
+ __str__
+
+
+ This returns the message in a string form suitable
+ for sending to a server.
+
+
+
+
+ __repr__
+
+
+ This returns the message in a form suitable for
+ eval(), assuming the name
+ IrcMsg is in your namespace and
+ is bound to this class.
+
+
+
+
+
+ The following attributes are the meat of this class. These
+ are generally what you'll be looking at with
+ IrcMsgs.
+
+
+ Interesting attributes
+
+ command
+
+
+ This is the command of the
+ IrcMsg –
+ PRIVMSG,
+ NOTICE,
+ WHOIS,
+ etc.
+
+
+
+
+ args
+
+
+ This is a tuple of the arguments to the
+ IrcMsg. Some messages have
+ arguments, some don't, depending on what command
+ they are. You are, of course, always assured that
+ args exists and is a tuple,
+ though it might be empty.
+
+
+
+
+ prefix
+
+
+ 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
+ nick/user/host
+ attributes, which are probably more useful to
+ check for many purposes.
+
+
+
+
+ nick
+
+
+ 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
+ calvino.freenode.net or
+ similar).
+
+
+
+
+ user
+
+
+ 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.
+
+
+
+
+ host
+
+
+ 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 :))
+
+
+
+
+
+
+ irclib.Irc
+
+ This is the object to handle everything about IRC except the
+ actual connection to the server itself.
+ (NOTE that the object actually received
+ by commands in subclasses of
+ callbacks.Privmsg is an
+ IrcObjectProxy, which is described
+ later. It augments the following interface with several
+ methods of its own to help plugin authors.)
+
+
+ Interesting methods
+
+ queueMsg
+
+
+ Queues a message for sending to the server. The
+ queue is generally FIFO, but it does prioritize
+ messages based on their command.
+
+
+
+
+ sendMsg
+
+
+ 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.
+
+
+
+
+
+ feedMsg
+
+
+ Feeds the Irc object a message
+ for it handle appropriately, as well as passing it
+ on to callbacks.
+
+
+
+
+ takeMsg
+
+
+ If the Irc object has a message
+ it's ready to send to the server, this will return
+ it. Otherwise, it will return
+ None.
+
+
+
+
+
+ addCallback
+
+
+ Takes a callback to add to the list of callbacks
+ in the Irc object. See the
+ interface for IrcCallback for
+ more information.
+
+
+
+
+ getCallback
+
+
+ Gets a callback by name, if it is in the
+ Irc object's list of callbacks.
+ If it it isn't, returns None.
+
+
+
+
+ removeCallback
+
+
+ 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.
+
+
+
+
+ __init__
+
+
+ Requires a nick. Optional
+ arguments include user and
+ ident, which default to the
+ nick given, password, which
+ defaults to the empty password, and
+ callbacks, a list of callbacks
+ (which defaults to nothing, an empty list).
+
+
+
+
+ reset
+
+
+ Resets the Irc object to its
+ original state, as well as sends a
+ reset() to every callbacks.
+
+
+
+
+ die
+
+
+ Kills the IRC object and all its callbacks.
+
+
+
+
+
+ Interesting attributes
+
+ nick
+
+
+ The current nick of the bot.
+
+
+
+
+ prefix
+
+
+ The current prefix of the bot.
+
+
+
+
+ server
+
+
+ The current server the bot is connected to.
+
+
+
+
+ network
+
+
+ The current network name the bot is connected to.
+
+
+
+
+ afterConnect
+
+
+ False until the bot has
+ received a command sent after the connection is
+ finished – 376, 377, or 422.
+
+
+
+
+ state
+
+
+ An IrcState object for this
+ particular connection. See the interface for the
+ IrcState object for more
+ information.
+
+
+
+
+
+
+ irclib.IrcCallback
+
+ Interesting Methods
+
+ name
+
+
+ Returns the name of the callback. The default
+ implementation simply returns the name of the
+ class.
+
+
+
+
+ __call__
+
+
+ Called by the Irc object with
+ itself and the message whenever a message is fed
+ to the Irc object. Nothing is
+ done with the return value.
+
+
+
+
+ inFilter
+
+
+ Called by the Irc object with
+ itself and the message whenever a message is fed
+ to the Irc object. The return
+ value should be an IrcMsg
+ object to be passed to the next callback in the
+ Irc's list of callbacks. If
+ None is returned, all
+ processing stops. This gives callbacks an
+ oppurtunity to "filter" incoming messages before
+ general callbacks are given them.
+
+
+
+
+ outFilter
+
+
+ Basically equivalent to
+ inFilter, except instead of
+ being called on messages as they enter the
+ Irc object, it's called on
+ messages as they leave the Irc
+ object.
+
+
+
+
+ die
+
+
+ Called when the parent Irc is
+ told to die. This gives callbacks an oppurtunity
+ to close open files, network connections, or
+ databases before they're deleted.
+
+
+
+
+ reset
+
+
+ Called when the parent Irc is
+ told to reset (which is generally when
+ reconnecting to the server). Most callbacks don't
+ need to define this.
+
+
+
+
+
+ Interesting attributes
+
+ priority
+
+
+ Determines the priority of the callback in the
+ Irc object's list of callbacks.
+ Defaults to 99; the valid range
+ includes 0 through
+ sys.maxint-1 (don't use
+ sys.maxint itself, that's
+ reserved for the Misc plugin).
+ The lower the number, the higher the priority.
+ High priority callbacks are called earlier in the
+ inFilter cycle, earlier in the
+ __call__ cycle, and later in
+ the outFilter cycle –
+ basically, they're given the first chances on the
+ way in and the last chances on the way out.
+
+
+
+
+
+
+ callbacks.IrcObjectProxy
+
+ IrcObjectProxy is a proxy for an
+ irclib.Irc 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 doCommand methods
+ (the kind you read about in the interface description of
+ irclib.IrcCallback) you'll be dealing
+ with plain old irclib.Irc objects.
+
+
+ Interesting methods
+
+ reply
+
+
+ Called to reply to the current message with a
+ string that is to be the reply. Uses the
+ queueMsg command discussed in
+ the irclib.Irc section.
+
+
+
+
+ replySuccess
+ replyError
+
+
+ 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.
+
+
+
+
+ error
+
+
+ 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 :)
+
+
+
+
+ errorNoCapability
+
+
+ Like error, 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.
+
+
+
+
+ errorPossibleBug
+ errorNotRegistered
+ errorNoUser
+ errorRequiresPrivacy
+
+
+ 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.
+
+
+
+
+ getRealIrc
+
+
+ Returns the actual Irc
+ object being proxied for.
+
+
+
+
+
+
+
+
+
diff --git a/docs/DocBook/supybot-html.dsl b/docs/DocBook/supybot-html.dsl
new file mode 100644
index 000000000..821a61be8
--- /dev/null
+++ b/docs/DocBook/supybot-html.dsl
@@ -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)))
diff --git a/docs/DocBook/supybot-print.dsl b/docs/DocBook/supybot-print.dsl
new file mode 100644
index 000000000..56280546b
--- /dev/null
+++ b/docs/DocBook/supybot-print.dsl
@@ -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))
+
diff --git a/docs/DocBook/supybot.dsl b/docs/DocBook/supybot.dsl
new file mode 100644
index 000000000..08cbed3e3
--- /dev/null
+++ b/docs/DocBook/supybot.dsl
@@ -0,0 +1,23 @@
+
+
+
+
+]>
+
+
+
+
+ &supybot-print;
+
+
+
+
+ &supybot-html;
+
+
+
+
+
diff --git a/docs/DocBook/supybot.dtd b/docs/DocBook/supybot.dtd
new file mode 100644
index 000000000..ba04c8016
--- /dev/null
+++ b/docs/DocBook/supybot.dtd
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%DocBookDTD;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+