README.textile in Sutto-marvin-0.2.1 vs README.textile in Sutto-marvin-0.2.2

- old
+ new

@@ -1,183 +1,105 @@ h1. Marvin -Marvin is a simple IRC Framework for Rails suitable for building things -such as simple IRC bots. Extracted from real use - we'd originally used -a heavily modified version of MatzBot - it's been built to service a -particular need. +Marvin is a ruby irc framework / library built on top of event machine. +It's been build from scratch to be evented - you build "handlers" which +are called whenever an event occurs. -h2. Background +A single client instance can handle multiple IRC connections (and will +automatically reconnect in the case that a connection is lost). Distributed +support (e.g. 1 client => multiple handler backends) is built in out of +the box on top of DRb. -The library is designed to be event driven in that it: - - # Uses the EventMachine library for all network connections - # It uses an architecture based on event listeners - called 'handlers' +h2. Getting Started -It's been heavily influenced by rack in terms of design, making it easy -to do things like chain handlers, write your own functionality and most -of all making it easy to implement. +Starting out with Marvin is simple. You can either go the "edge" route - +cloning from the GitHub repository (in this case, [here](http://github.com/sutto/marvin)) +and then running the following: -h2. Getting Started + $ rake gemspec + $ gem build marvin.gemspec + $ sudo gem install marvin.gem -The easiest way to get started with Marvin is by installing the Marvin gem. To -do this, make sure Github is added to your gem sources (and you are using -rubygems >= 1.2.0) (by default, substitute username for Sutto): +Or, for a generally more stable release you can install it from the GitHub gem +server (requiring Rubygems >= 1.2.0 with the GitHub sources added), by running +the following: - $ gem sources -a http://gems.github.com - $ sudo gem install username-marvin + $ sudo gem install Sutto-marvin +Installing the gem will make available a new executable - "+marvin+" - which is +used as an easy way to do a variety of tasks. To get started, you can create +a project located at given path using the following command: -Once you have installed the gem, you should have access to the "marvin" command: + $ marvin create path-to-my-bot + +Once that's done, you'll have a blank slate loaded with the default marvin handlers - ++HelloWorld+ (which will respond to any addressed "hello"'s) and an empty debug handler +which you can use for generic debugging. To run the new app, you can use either of the +following: - $ marvin --help + $ cd path-to-my-bot && script/client -You can create a new marvin folder: +or, alternatively, - $ marvin create my_marvin_project + $ marvin client path-to-my-bot -Then simply edit your settings in the +config/settings.yml+ +There are a couple of options available for the client (as well as the marvin library), +Each of which can be found by appending the "--help" option to the command. - default: - name: Marvin - use_logging: false - datastore_location: tmp/datastore.json - development: - user: MarvinBot - name: MarvinBot - nick: Marvin +Once your client has been started (assuming the name wasn't taken / it could connect), +simply join the chat room your bot was instructed to join and say the following (substiting +BotNick for the nick name your bot connected with): -You can use the defaults or configure it. The datastore location -specifies a relative path where a simple json-backed key value -store will store persistent information for your client (if chosen). -Once that's been done, you'll want to setup some connections by editing -+config/connections.yml+, using the following format: + BotNick: hello + +Or even easier, by PM'ing the bot with: - "server-address": - post: 6667 # Defaults to 6667 - channels: - - "#marvin-testing" - - "#relayrelay" - nicks: - - List - - Of - - Alternative - - Nicks - "another-server-address": - post: 6667 # Defaults to 6667 - channels: - - "#helloworld" - -Which will let marvin connect to multiple servers - autojoining the specific rooms. -Next, to get started you can simply type: - - $ ./script/client - -The bot should join the specified channel and will respond to some simple -commands by default: - - *YourName*: MarvinBot3000: hello - *MarvinBot3000*: YourName: Hola! + hello -As defined in handlers/hello_world.rb +Assuming all went well, your bot should reply back with something akin to (where YourNick) +if the nickname you connected with): -h2. Thanks + YourNick: Hola from process with pid 12342 -Thanks goes out to the following people / projects: +h2. Distributed Bots -* Jeff Rafter - contributed code and doc changes, now one of the co-developers. -* epitron / halogrium - For the ragel state machine used in Marvin::Parsers::RagelParser -* The creator of Ruby-IRCD - the server component is heavily influenced by / part derivative of said work. +One of the relatively unique features of Marvin is the ability to write bots +which use DRb and Rinda which can grow with relative ease. -h2. Marvin::Base - A handler starting point +It's important to keep in mind that keeping state is discouraged in this case +as it can not be ensured that clients are still active or that you will always +get messages from the same client. -The first, Marvin::Base provides a base set of methods (e.g. say, -reply etc etc.) which make writing a client easier. You can simply -inherit from Marvin::Base, write some logic and then use the class -method on_event to define responses to events. The passed in meta -data for each event is then usable via options.attribute_name - an -openstruct version of the details. e.g. +For a start, take a look at the default +config/setup.rb+ file which contains +an example of registering handlers on a distributed client as well as setting +up the distributed handler which needs to be setup on the main client. - class NinjaStuff < Marvin::Base - on_event :incoming_message do - do_something - end - def do_something - reply options.message # Will echo back the message - end - end - -Or the like. Also, the halt! method can be called in any subclass to -halt the handler callback chain. +By default, the messages will be dispatched to the first discovered tuple +space (using Rinda::RingFinger) and will be of the format: -You also get access to the class method +on_numeric+ which makes -it relatively easy to respond to a specific numeric reply. - -h2. Marvin::CommandHandler - Ridiculously easy Bots - -With Marvin::CommandHandler, you get to define seriously -simple classes which can act as a simple bot. It takes -great inspiration from "MatzBot":http://github.com/defunkt/matzbot/tree/master -to make it as easy as possible to make a simple bot - -To write a CommandHandler, you simply create a subclass -(ala ActiveRecord::Base), define a few methods and then -just use the "exposes" class method. e.g. - - class MySecondExample < Marvin::CommandHandler - exposes :hello - def hello(data) - reply "Hello!" - end - end - -Where data is an array of parameters. exposed methods will be called -when they match the following pattern: - - Botname: *exposed-method* *space-seperated-list-meaning-data* + [:marvin_format, :your_namespace, :message_name, {:message => "options"}, client_reference] -i.e., the above handler could be called in IRC as such: +You can change the namespace (which defaults to +:default+) by setting +Marvin::Settings.distributed_namespace+ - YourBotsName: hello - -or, even easier, by PM'ing the bot with: - - hello +Running a distributed client requires three things: -h2. Marvin::MiddleMan - Introducing middleware +* 1 Ring server instance (+script/ring_server+ or +marvin ring_server+ or +marvin rs+) +* 1+ Client instances (+script/client+ or +marvin client+ or +marvin cl+) +* 1+ Distributed Client instances (+script/distributed_client+ or +marvin distributed_client+ or +marvin dc+) -Marvin::MiddleMan lets you insert middleware between handlers -and you're client - letting you do things such as translating -all messages on the fly. It's build to be extensible and is -relatively simple to use. On any Marvin::Base subclass (baring -the MiddleMan itself), using a middle man is easy - you simply -call the register! class method with an option argument. e.g: +Each of which takes the default options of: +* -v - Be verbose and print to STDOUT if not daemonized +* -level=something - set level, defaults to info +* -d - daemonize the process +* -k - kill all daemonized instances of this specific kind - HelloWorld.register! Marvin::MiddleMan +h2. Example Bots -h2. Marvin::DataStore - A dead simple persistent hash store +Coming soon. -Want to save data between when you stop and start your IRC -Client? With Marvin, it's really, really simple - Marvin::DataStore -offers a simple syntax for persistent data stores. +h2. Thanks -New datastores can be created with Marvin::DataStore.new("global-store-key"). -From there, you have a hash to do whatever the hell you want. Just -make sure the data you store is JSON-serializable. +Thanks go to: -When you start - stop a server (via Marvin::Loader.run! and Marvin::Loader.stop!) -you're data will be loaded from and written to disk accordingly. - -If you're inside a Marvin::Base subclass it's even easier. You can get a cattr_access -style accessor for free - just use the "uses_datastore" method. e.g: - - class X < Marvin::Base - uses_datastore "datastore-global-key", :something - end - -Then, self.something will point to the data store - letting you do -things like: - - def hello(data) - (self.something[from] ||= 0) += 1 - end - -which will persist the count between each session. +* Jeff Rafter - contributed code and doc changes, now one of the co-developers. +* epitron / halogrium - For the ragel state machine used in Marvin::Parsers::RagelParser +* The creator of Ruby-IRCD - the server component is heavily influenced by / part derivative of said work. \ No newline at end of file