Transitioning to Autumn 2.0
This soul-shatteringly long wiki is here to help you migrate your leaves to Autumn 2.0. Those who dare navigate its twisted annals will be rewarded with a much better framework for writing fresh, easy, and fun IRC bots.
If it hasn’t dawned on you already, a lot has changed in Autumn 2.0. If you’re wondering why you should bother moving to version 2.0, just remember — there’s something for everyone in this huge upgrade. I can say with a good amount of certainty that there’s got to be some new feature that will make your bot better.
So, for those that dare undertake this grand adventure, allow me to show you how to turn your old and busted version 1.0 bot into a shiny newfangled version 2.0 beauty!
To help clarity, Autumn Leaves has been renamed to Autumn, and all Autumn classes are contained in the Autumn
module. So whereas once you would subclass AutumnLeaf
, now you subclass Autumn::Leaf
. Likewise, classes like Foliater
are now Autumn::Foliater
. This should help clarify the difference between Autumn (the IRC framework) and Autumn Leaf (the bot framework).
In Autumn Leaves, a “leaf” was both an IRC bot and its connection to an IRC server (using the EyeAreSee library). In Autumn, these two concepts have been separated into two separate objects.
A Stem
is a connection to an IRC server. It is initialized with a server address and a nick. It listens for IRC messages and sends IRC commands. Generally you will not instantiate or work with stems directly while writing bots, as the Leaf
class handles that for you.
A Leaf
is an IRC bot. It is initialized with one or more stems. It uses the stem to send and receive IRC messages. You subclass Leaf
to make your bot.
Because of this new distinction, each season now has, along with a leaves.yml file, a stems.yml file as well. The stems.yml file will take the server-specific options (such as server, port, nick, SSL, etc.), and the leaves.yml file will contain leaf-specific options (such as respond_to_private_messages
). See the example config files to get started.
In Autumn Leaves 1.0, one bot had one IRC connection. This made things nice and simple, but also reduced functionality. Now one bot can have many IRC connections, and one IRC connection can be running many bots. Because of this, you must keep in mind a few changes in Autumn 2.0:
Most IRC commands have been moved from the Leaf
class to the Stem
class. In ye olde Autumn Leaves, if you wanted your bot to join a channel, you just called join_channel
and that was that. Now, join_channel
is a method of the Stem
class, so you will need to know which of your leaf’s stems to use. (This is a programmer’s way of saying, “the bot has to know which server to join the channel on.”) To make this easier for all but the most complex cases, some changes have been made to the Autumn leaf class:
-
[word]_command
-type methods now receive the relevantStem
as the first parameter. The signature of these methods has changed in other ways; see theLeaf
docs. -
[word]_command
-type methods can now return a string value, which will automatically be transmitted to the channel on which the command was received. - You can make method calls to the
stems
attribute; these calls will be forwarded to every stem for the leaf. For instance, to message every channel of every server of a leaf, you can callstems.message "Ready for orders!"
. - For leaves that are only running on one stem (the vast majority of leaves), you can call the stem’s methods directly from the leaf. So, instead of calling
stems.first.join_channel
, you can calljoin_channel
directly. This will dramatically help backwards compatibility with one-stem leaves.
This change also effected some other changes in the Leaf
class:
- All hook methods now include a
stem
parameter. Many hook methods that formerly had anick
parameter now have asender
parameter that is a sender hash (see theLeaf
class docs). - Filter methods now require a different signature, as they take a
Stem
instance as well. - The
nickname_in_use
hook has been removed. To specify a custom nick substitution behavior, set thenick_generator
attribute (see theStem
docs for more). - Other “response” hooks, such as
no_such_nick
, have also been removed. To handle these responses, implement methods as specified by theStem.add_listener
docs.
IRC is not a homogenous protocol: Every server daemon has a slightly different implementation of IRC. To encapsulate this, the Daemon
class has been introduced. This class keeps track of things that vary from server daemon to server daemon, such as reply codes, channel prefixes, and usermodes.
The most important part of this is that certain symbols have changed, which may break parts of your code. If, for instance, you had a method that checked if a user was :op
status or not, well, that has been renamed to :operator
. You’d see this by opening the resources/daemons/RFC1459.yml file and seeing that under privilege
and user_prefix
, the symbol is named :operator
.
The reason for this, incidentally, is that these files are auto-generated from an IRC reference site, and I’d prefer to have to change :op
to :operator
once in my leaf, rather than change :operator
to :op
every time the website updates its table.
When you create a new stem, it tries to determine automatically which Daemon
instance to use. Failing that, it uses a default Daemon
instance that covers most IRC servers.
Autumn 2.0 does away with the flat-file storage, and instead uses DataMapper, a Ruby gem. To use a persistent data store for your leaf, you must now install DataMapper, as per the instructions on the website.
Leaves can no longer store persistent data using the record
method. If you would like flat-file storage for your leaf, I would recommend using the SQLite adapter.
DataMapper works very similarly to ActiveRecord in Ruby on Rails. Please visit the DataMapper website for more information on how to use it (though if you are already familiar with ActiveRecord, you will quickly adapt to DataMapper). See the README for more information on how to use DataMapper in Autumn.
Operation of Autumn is now completely rolled into the Rakefile. Please type rake --tasks
at the command line for a full list of changes. The daemon control script (formerly big-switch.rb) is now script/daemon, and the bootstrap script (formerly genesis.rb) is now script/server. Both can be executed from the command line, though you must be in the root Autumn directory.
In addition to script/daemon and script/server (discussed above), there is also script/generate and script/destroy, in the tradition of Rails. They create templates and destroy files for your Autumn objects, respectively. Run each with the --help
option for more information.
Configuration in Autumn 2.0 is now handled by a dedicated Speciator
instance, which manages global-, season-, and leaf-specific configurations. Speciator
is a replacement for $AL_ENV
and @options
. Every Leaf
instance can retrieve its configuration with the options
method. You can retrieve options just as you would a hash:
nick_pass = options[:password]
Note that you no longer need the @ sigil before options
. The other major change is that options
also allows access to global and season configurations. Whereas once you would write code like such:
root = $AL_ENV['root']
logging = $AL_ENV['season_config']['logging']
You would now write:
root = options[:root]
logging = options[:logging]
Two points to note here: 1) All option keys are symbols, not strings, and 2) there is no distinction between the scope of different options. Season-specific options override global options, as opposed to being stored separately from them. Likewise, stem or leaf options override season-specific options. Leaf and stem options are independent of each other, however, since leaves and stems share a many-to-many relationship.
Options are managed by the Speciator
singleton. See its docs for more information.
The system-level logger is now available using the :system_logger
config key. The root directory (what was once $AL_ENV['root']
) is now available with the :root
config key or the AL_ROOT
global constant.
Aside from the structural changes listed above, there have been some other notable alterations to Leaf
.
Many methods, including the [word]_command
and filter methods, now receive a stem
argument, so you have the Stem
instance to respond using. The sender
argument in many cases has been changed from the user’s nick to a hash with the keys nick
, user
, and host
. See the Leaf
docs for more information.
The [word]_command
and [word]_filter
methods now take a reply_to
parameter with the name of the channel or nick that you would generally send the response to. For commands that were typed into a channel, this parameter contains the channel name. For commands that were sent privately to the bot, this parameter contains the sender’s nick.
To check if a command was invoked because of a private message or a channel message, simply determine if the reply_to
parameter is equal to the sender[:nick]
parameter. If they are equal, it was a private message.
did_receive_channel_message
is now called for all channel messages, even those that look like bot commands.
Autumn now supports multiple support modules for a single leaf. To accomplish this, your support module code must meet the following requirements:
- Each .rb file must be in a directory named after your leaf class in the support directory. So, for a leaf subclass
QuoteBot
, you must place your support files in the support/quote_bot directory. - Each support module must be of the form
{bot name}{helper name}Helper
. So, for ourQuoteBot
example, valid helper names includeQuoteBotDatabaseHelper
,QuoteBotNetworkHelper
, andQuoteBotHelper
.
You can still use the old support-module system, placing your helper module in support/quote_bot.rb.
Since colorization and formatting is client-specific, and more than one protocol exists for this purpose, the colorization and formatting of text has been moved to a separate module. If you wish to use mIRC colorization for your leaf (the most common kind and the kind that Autumn Leaves 1.0 used), you should see the Autumn::Formatting::Mirc
module. Other modules in Formatting
colorize using other standards.
The method signature and usage of the color
method has been changed. Please see the color
method docs.
Autumn 2.0 now supports CTCP! CTCP is implemented as a listener plugin, a special kind of stem listener that bestows its powers upon other listeners for that stem. CTCP is included in all stems and leaves by default. For more information on how to use it, see the CTCP
class docs.
The following are changes which should generally not affect your bots, as they do not expose any new or altered functionality to the Autumn API. However, if your bot uses some nitty-gritty Autumn features, or you are simply interested in what’s under the hood, read on.
Additional classes have been added to facilitate the template system. These classes are Coder
, TemplateCoder
, Generator
, and Script
, and exist in the Autumn
module. They are not used in runtime, only by scripts in the script directory.
Many classes have had their Ruby files renamed, to increase clarity. In Autumn Leaves, Ruby files were named after the class’s function, whereas classes had a picturesque name in the “autumn” metaphor. Autumn classes and files share the same name (and yes, it’s the metaphor allegorical name … sorry to those that hate that).
Logging has been overhauled in Autumn. In Autumn, stems and leaves both log to the same file, but they use separate facades. To separate the distinction between an object’s logger and a destination log file, a facade over Ruby’s Logger
class was created.
LogFacade
is a facade for Logger
that adds additional information about the stem and leaf associated with the facade to every log message. The facade works exactly like the ObservantSquirrel
class of Autumn Leaves. Therefore, for the purpose of writing bots, you can assume no external API changes were made to the logging system. Log messages given to the facade will be prepended with the name and type of the Autumn object doing the logging before being passed to the Logger
instance.
ObservantSquirrel
as a class name is no more. I realize that that name was a bit of a stretch, even for Autumn.
The way in which leaves are initialized and run has been completely redone. Bootstrapping the environment is now handled by the Genesis
class.
Many classes in the Autumn
module have had their documentation suppressed to increase usability of the API docs.