Skip to content
This repository has been archived by the owner on Feb 5, 2019. It is now read-only.

Transitioning to Autumn 2.0

RISCfuture edited this page Sep 13, 2010 · 5 revisions

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!

Stems and Leaves

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).

Separation of Bots and IRC Connections

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.

The Death of One-Leaf, One-Stem

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 relevant Stem as the first parameter. The signature of these methods has changed in other ways; see the Leaf 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 call stems.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 call join_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 a nick parameter now have a sender parameter that is a sender hash (see the Leaf 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 the nick_generator attribute (see the Stem docs for more).
  • Other “response” hooks, such as no_such_nick, have also been removed. To handle these responses, implement methods as specified by the Stem.add_listener docs.

Support for Different IRC Server Daemons

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.

Data Store

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.

Performing Operations

Rake Tasks

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.

Helper Scripts

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 Changes

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.

Autumn-Provided Options

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.

Leaf Changes

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.

Helper Modules

Autumn now supports multiple support modules for a single leaf. To accomplish this, your support module code must meet the following requirements:

  1. 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.
  2. Each support module must be of the form {bot name}{helper name}Helper. So, for our QuoteBot example, valid helper names include QuoteBotDatabaseHelper, QuoteBotNetworkHelper, and QuoteBotHelper.

You can still use the old support-module system, placing your helper module in support/quote_bot.rb.

Other Refactoring

Colorizing and formatting text

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.

CTCP support

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.

Other Internal Changes

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.

Organization

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

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.

Bootstrapping

The way in which leaves are initialized and run has been completely redone. Bootstrapping the environment is now handled by the Genesis class.

Documentation

Many classes in the Autumn module have had their documentation suppressed to increase usability of the API docs.