Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Feature/ruby #5

Merged
merged 45 commits into from over 2 years ago

3 participants

Dave Wilkinson II Lindsey Bieda jackie kircher
Dave Wilkinson II

Sweet.

jackiekircher and others added some commits
jackie kircher jackiekircher gg=G 554b2df
jackie kircher jackiekircher make XOmBot tell jokes!
(ugly implementation)
d9ced1e
jackie kircher jackiekircher add !joke and !answer to !commands and the README 36274c7
Dave Wilkinson II wilkie Initial Ruby rewrite. 8faa4aa
Dave Wilkinson II wilkie Adding better code layout. 2e9a372
Dave Wilkinson II wilkie Adding base plugin class. 793094e
Dave Wilkinson II wilkie Restructure plugin interface to be more flexible. 5728469
Dave Wilkinson II wilkie Automatically load all plugins a153fa5
Dave Wilkinson II wilkie Commands with no help strings need to return empty hashes. 324e583
Dave Wilkinson II wilkie Adding simple coinflip plugin. fe1df8b
Dave Wilkinson II wilkie Adding a URL announcer plugin. afe62e1
Dave Wilkinson II wilkie Adding a seen (when is the last time a user spoke) plugin. 8560ade
Dave Wilkinson II wilkie Adding automated joke plugin. 86c58f5
Dave Wilkinson II wilkie Fixing !commands plugin to gracefully show regular expressions. e9b39d6
Dave Wilkinson II wilkie Adding more sophisticated coinflipping. f105c13
Dave Wilkinson II wilkie No punctuation in help strings. 36932b1
Dave Wilkinson II wilkie Added usage output and truncated commands listing. 609527a
Dave Wilkinson II wilkie Added help command. 856302f
Dave Wilkinson II wilkie Patching Cinch to write out action messages from Message. f9f67ce
Dave Wilkinson II wilkie Adding the emotional center of XOmBot :) e71baa5
Dave Wilkinson II wilkie Let Me Google That For You plugin. a3cfc93
Dave Wilkinson II wilkie Print out regular expression syntax for !help 37cb716
Dave Wilkinson II wilkie Added a dice roller. b46a77a
Dave Wilkinson II wilkie Added usage to !seen f0a186d
Dave Wilkinson II wilkie Adding usage to help, for some reason. ba3a9d7
Dave Wilkinson II wilkie Refactor regex for !coinflip slightly. 7a0ac88
Dave Wilkinson II wilkie Adding better default constants. 26799cf
Dave Wilkinson II wilkie Adding .gitignore 5149e71
Dave Wilkinson II wilkie Adding configuration file. 83036a4
Dave Wilkinson II wilkie Add code to read configuration file. be259f1
Dave Wilkinson II wilkie Fixing up config file reading. 041fd44
Dave Wilkinson II wilkie Fixing issue with getting the name in plugins. f5e74a7
Dave Wilkinson II wilkie Fixing usage of instance variables for configuration. d19af5f
Dave Wilkinson II wilkie Adding more emotive responses to XOmBot. 087442d
Dave Wilkinson II wilkie README to better reflect current behavior 8f8a525
Dave Wilkinson II wilkie Fixing simple bug in emotion plugin. 4719264
Dave Wilkinson II wilkie Sanitizing titles for URLAnnounce. 6a8d608
Dave Wilkinson II wilkie Going to need to get a session with every joke since the cookie will
expire.
c6702e8
Dave Wilkinson II wilkie More brains in joke plugin. 20e6513
Dave Wilkinson II wilkie Jokes are stored per channel. 5e1415c
Dave Wilkinson II wilkie Fixing URLAnnounce plugin to only display titles for webpages. 4f30230
Dave Wilkinson II wilkie Added an ignore command. 6d31090
Dave Wilkinson II wilkie Reciprocate aggression toward XOmBot. 0d91006
Dave Wilkinson II wilkie Adds the LocalTime plugin that queries the local time of a given city. cbc36c5
Dave Wilkinson II wilkie Fixes dice rolls so that bonuses only apply at the end of a roll. a4083f5
Lindsey Bieda LindseyB merged commit a4083f5 into from
Lindsey Bieda LindseyB closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 45 unique commits by 2 authors.

Jan 24, 2012
jackie kircher jackiekircher gg=G 554b2df
jackie kircher jackiekircher make XOmBot tell jokes!
(ugly implementation)
d9ced1e
jackie kircher jackiekircher add !joke and !answer to !commands and the README 36274c7
Feb 05, 2012
Dave Wilkinson II wilkie Initial Ruby rewrite. 8faa4aa
Dave Wilkinson II wilkie Adding better code layout. 2e9a372
Dave Wilkinson II wilkie Adding base plugin class. 793094e
Dave Wilkinson II wilkie Restructure plugin interface to be more flexible. 5728469
Dave Wilkinson II wilkie Automatically load all plugins a153fa5
Dave Wilkinson II wilkie Commands with no help strings need to return empty hashes. 324e583
Dave Wilkinson II wilkie Adding simple coinflip plugin. fe1df8b
Dave Wilkinson II wilkie Adding a URL announcer plugin. afe62e1
Dave Wilkinson II wilkie Adding a seen (when is the last time a user spoke) plugin. 8560ade
Dave Wilkinson II wilkie Adding automated joke plugin. 86c58f5
Dave Wilkinson II wilkie Fixing !commands plugin to gracefully show regular expressions. e9b39d6
Dave Wilkinson II wilkie Adding more sophisticated coinflipping. f105c13
Dave Wilkinson II wilkie No punctuation in help strings. 36932b1
Dave Wilkinson II wilkie Added usage output and truncated commands listing. 609527a
Dave Wilkinson II wilkie Added help command. 856302f
Dave Wilkinson II wilkie Patching Cinch to write out action messages from Message. f9f67ce
Dave Wilkinson II wilkie Adding the emotional center of XOmBot :) e71baa5
Dave Wilkinson II wilkie Let Me Google That For You plugin. a3cfc93
Dave Wilkinson II wilkie Print out regular expression syntax for !help 37cb716
Dave Wilkinson II wilkie Added a dice roller. b46a77a
Dave Wilkinson II wilkie Added usage to !seen f0a186d
Dave Wilkinson II wilkie Adding usage to help, for some reason. ba3a9d7
Dave Wilkinson II wilkie Refactor regex for !coinflip slightly. 7a0ac88
Dave Wilkinson II wilkie Adding better default constants. 26799cf
Dave Wilkinson II wilkie Adding .gitignore 5149e71
Dave Wilkinson II wilkie Adding configuration file. 83036a4
Dave Wilkinson II wilkie Add code to read configuration file. be259f1
Dave Wilkinson II wilkie Fixing up config file reading. 041fd44
Dave Wilkinson II wilkie Fixing issue with getting the name in plugins. f5e74a7
Dave Wilkinson II wilkie Fixing usage of instance variables for configuration. d19af5f
Dave Wilkinson II wilkie Adding more emotive responses to XOmBot. 087442d
Dave Wilkinson II wilkie README to better reflect current behavior 8f8a525
Dave Wilkinson II wilkie Fixing simple bug in emotion plugin. 4719264
Dave Wilkinson II wilkie Sanitizing titles for URLAnnounce. 6a8d608
Feb 07, 2012
Dave Wilkinson II wilkie Going to need to get a session with every joke since the cookie will
expire.
c6702e8
Dave Wilkinson II wilkie More brains in joke plugin. 20e6513
Dave Wilkinson II wilkie Jokes are stored per channel. 5e1415c
Dave Wilkinson II wilkie Fixing URLAnnounce plugin to only display titles for webpages. 4f30230
Feb 08, 2012
Dave Wilkinson II wilkie Added an ignore command. 6d31090
Dave Wilkinson II wilkie Reciprocate aggression toward XOmBot. 0d91006
Feb 23, 2012
Dave Wilkinson II wilkie Adds the LocalTime plugin that queries the local time of a given city. cbc36c5
Dave Wilkinson II wilkie Fixes dice rolls so that bonuses only apply at the end of a roll. a4083f5
This page is out of date. Refresh to see the latest.
2  .gitignore
... ... @@ -0,0 +1,2 @@
  1 +config/config.yml
  2 +*.rbc
3  Gemfile
... ... @@ -0,0 +1,3 @@
  1 +source :rubygems
  2 +gem "cinch"
  3 +gem "mechanize"
28 Gemfile.lock
... ... @@ -0,0 +1,28 @@
  1 +GEM
  2 + remote: http://rubygems.org/
  3 + specs:
  4 + cinch (1.1.3)
  5 + domain_name (0.5.2)
  6 + unf (~> 0.0.3)
  7 + mechanize (2.1.1)
  8 + domain_name (~> 0.5, >= 0.5.1)
  9 + net-http-digest_auth (~> 1.1, >= 1.1.1)
  10 + net-http-persistent (~> 2.4, >= 2.4.1)
  11 + nokogiri (~> 1.4)
  12 + ntlm-http (~> 0.1, >= 0.1.1)
  13 + webrobots (~> 0.0, >= 0.0.9)
  14 + net-http-digest_auth (1.2)
  15 + net-http-persistent (2.4.1)
  16 + nokogiri (1.5.0)
  17 + ntlm-http (0.1.1)
  18 + unf (0.0.4)
  19 + unf_ext
  20 + unf_ext (0.0.4)
  21 + webrobots (0.0.13)
  22 +
  23 +PLATFORMS
  24 + ruby
  25 +
  26 +DEPENDENCIES
  27 + cinch
  28 + mechanize
26 README.rdoc
Source Rendered
... ... @@ -1,29 +1,21 @@
1 1 = XOmBot
2 2 ----
3 3
4   -XOmBot is a simple IRC bot written in perl meant to lurk in #xomb.
  4 +XOmBot is a simple IRC bot written in ruby meant to lurk in #xomb.
5 5 Right now XOmBot accepts the following commands:
6 6
7   -* !wiki [article name]: will attempt to find a XOmB wiki article of that name and provide a definition
8   -* !latest: will provide information for the latest commit
9   -* !commands: will list the commands XOmBot listens for and what they do
10   -* !google [phrase] for [nick]: Sends a lmgtfy.com link to nick
  7 +* !commands: will list the commands XOmBot listens for
  8 +* !help [command]: queries what a command will do
  9 +* !google [phrase] for [nick]: Sends a lmgtfy.com link to nick
11 10 * !coinflip: flips a coin
12 11 * !santa: Asks Santa if the bot has been naught or nice
13   -* !d[n]: rolls a die with n sides
  12 +* !d[n]: rolls a die with n sides
  13 +* !roll [n]d[n][[+|-]n]: rolls several dice with bonuses
  14 +* !joke: hear a funny joke
  15 +* !answer: get the answer to the last funny joke
14 16
15 17 XOmBot has the following behaviours in addition to the commands:
16 18
17   -* announces an applied commit to the main XOmB repo
18   -* informs the channel of the !commands command upon entering a channel
19 19 * says "brains..." when directly refered to (ie: XOmBot: message)
  20 +* responds dumbly to social cues
20 21 * displays the title of any valid http:// urls displayed in the channel
21   -
22   -----
23   -
24   -Requires:
25   -
26   -* Bot::BasicBot
27   -* URI::Title
28   -* URI::Find::Simple
29   -
268 XOmBot.pl
... ... @@ -1,268 +0,0 @@
1   -#!/usr/bin/perl -w
2   -
3   -#################################################################################
4   -# XomBot.pl [nick] #
5   -# #
6   -# Your friendly XOmB bot for #xomb #
7   -# #
8   -# This program is free software. It comes without any warranty, to the extent #
9   -# permitted by applicable law. You can redistribute it and/or modify it under #
10   -# the term of the Do What The Fuck You Want To Public License, Version 2, as #
11   -# published by Sam Hocevar. See http://sam.zoy.org/wtfpl/COPYING for more #
12   -# details #
13   -# #
14   -#################################################################################
15   -
16   -package Bot;
17   -use base qw(Bot::BasicBot);
18   -use warnings;
19   -use strict;
20   -use URI::Title qw( title );
21   -use URI::Find::Simple qw( list_uris );
22   -use LWP 5.64;
23   -
24   -my($businessChannel) = '#xomb';
25   -my($pleasureChannel) = '##l2l';
26   -my $mynick = shift || 'XOmBot';
27   -my $browser = LWP::UserAgent->new;
28   -my $commitid = "";
29   -my $first = 1;
30   -
31   -my $good = 0;
32   -my $bad = 0;
33   -
34   -my ($bot) = Bot->new(
35   - server => "irc.freenode.net",
36   - port => "8001",
37   - channels => [ $businessChannel, $pleasureChannel , "##IwantAkitty", "#rstatus"],
38   - nick => $mynick,
39   - charset => 'utf-8',
40   - );
41   -
42   -$bot->run();
43   -
44   -sub connected {
45   - my $self = shift;
46   - $self->say(channel => $_, body => "$mynick is online. !commands will show what I can do.") for (@{$self->{channels}});
47   -}
48   -
49   -sub tick {
50   - #check_rss();
51   - return 60;
52   -}
53   -
54   -sub said {
55   - my $self = shift;
56   - my $message = shift;
57   - my $body = $message->{body};
58   - my $nick = $message->{who};
59   - my $channel = $message->{channel};
60   - my $address = $message->{address};
61   -
62   - # --- url announce ---
63   - if(my @urls = list_uris($body)){
64   - if($nick ne "github-xombot"){
65   - $self->reply($message, title($_)) for (@urls);
66   - }
67   - }
68   -
69   - # --- command list ---
70   - if($body =~ m/^\!commands/ || $body =~ m/^\!h.lp/i){
71   - # show all the commands that xombot listens to
72   - $self->say(channel => $channel, body => "!wiki [search term] - will search the wiki for the given word or phrase.");
73   - $self->say(channel => $channel, body => "!latest - will show the last commit to the offical XOmB repository.");
74   - $self->say(channel => $channel, body => "!google [phrase] for [nick] - answer questions. More bangs to shoot from the hip.");
75   - $self->say(channel => $channel, body => "!coinflip - ...");
76   - $self->say(channel => $channel, body => "!santa - ask Santa whether $mynick has been naughty or nice.");
77   - $self->say(channel => $channel, body => "!d[n] - rolls die with n sides");
78   - }
79   -
80   - if ($body =~ m/^\!wiki\s*([\w*\s]*)/){
81   - # check if article exists in the wiki
82   - get_wiki_entry($1, $channel);
83   - }
84   -
85   - if($body =~ m/^\!latest/){
86   - # show the latest commit the next loop around
87   - $commitid = "";
88   - }
89   -
90   - if($body =~ m/^\!(!*)google(!*) (.*) for (.*)/){
91   - my($term) = $3;
92   - my($target) = $4;
93   - my($lucky);
94   -
95   - if($1 ne "" || $2 ne ""){
96   - $lucky = "&l=1";
97   - }
98   -
99   - $term =~ s/ /+/g;
100   -
101   - $self->say(channel => $channel, who => $target, address => "1", body => "http://lmgtfy.com/?q=$term$lucky");
102   - }
103   -
104   - if($body =~ m/^\!coinflip/){
105   - my $outcome;
106   -
107   - if($body =~ m/^\!coinflip.* heads (.*) tails (.*)/){
108   - $outcome = $1;
109   - $outcome = $2 if int(rand(2)) == 1;
110   - }else{
111   - $outcome = "heads";
112   - $outcome = "tails" if int(rand(2)) == 1;
113   - }
114   -
115   - #$self->say(channel => $channel, who => $nick, address => "1", body => "$outcome");
116   - $self->say(channel => $channel, body => "$outcome");
117   - }
118   -
119   - # dice roll
120   - if($body =~ m/^\!d(\d+)/){
121   - $self->say(channel => $channel, body => int(rand($1)) + 1);
122   - }
123   -
124   - if($body =~ m/^\!santa/){
125   - if($good >= $bad){
126   - $self->emote(channel => $channel, body => "has been a good little robotic zombie");
127   - }else{
128   - $self->emote(channel => $channel, body => "is getting coal in its metal stocking");
129   - }
130   - }
131   -
132   - # --- miscellaneous behaviors ---
133   -
134   - # annoy duck
135   - if($body eq "hi" and $nick eq "duckinator"){
136   - $self->say(channel => $channel, who => $nick, body => "hi", address => "1");
137   - }
138   -
139   - my($respondedFlag) = 0;
140   -
141   - if ($address || $body =~ m/$mynick/){
142   - my $compliment = $body;
143   -
144   - if($compliment =~ m/good/i || $compliment =~ m/cookie/i || $compliment =~ m/<3/){
145   - $self->emote(channel => $channel, body => "drools");
146   -
147   - $good++;
148   - $respondedFlag = 1;
149   - }elsif($compliment =~ m/bad/i || $compliment =~ m/spank/i){
150   - $self->emote(channel => $channel, body => "cowers");
151   -
152   - $bad++;
153   - $respondedFlag = 1;
154   - }
155   - }
156   -
157   - if($address && !$respondedFlag){
158   - $self->say(channel => $channel, who => $nick, address => "1", body => "brains...");
159   - }
160   -
161   - return undef;
162   -}
163   -
164   -sub check_rss {
165   - my $response = $browser->get("http://github.com/feeds/xomboverlord/commits/xomb/unborn");
166   -
167   - if($response->is_success && $response->content =~ m/<entry>\s*<id>.*\/(\w*)<\/id>/){
168   - my $commiter = "Unknown";
169   - my $commit_msg = "Unspecified";
170   - my $orig_commitid = $commitid;
171   -
172   - #if it's not the last one we announced
173   - if($commitid ne $1){
174   - $commitid = $1;
175   -
176   - # get try to get the info to announce it
177   - if($response->content =~ m/<entry>.*?<title>(.*?)<\/title>/s){
178   - $commit_msg = $1;
179   - }
180   -
181   - # get try to get the author to announce it
182   - if($response->content =~ m/<name>(\w*)<\/name>/){
183   - $commiter = $1;
184   - }
185   -
186   - if($commit_msg ne "Sorry, this commit log is taking too long to generate."){
187   - unless($first){
188   - $bot->say(channel => $businessChannel, body => "Commit made by $commiter: $commit_msg");
189   - $bot->say(channel => $businessChannel, body => "View: http://github.com/xomboverlord/xomb/commit/$commitid");
190   - }else{
191   - $first = 0;
192   - }
193   - }else{
194   - # we don't know if there actually was a new commit
195   - $commitid = $orig_commitid;
196   - }
197   - }
198   - }
199   -}
200   -
201   -
202   -
203   -sub get_wiki_entry {
204   - my $articlename = shift;
205   - my $channel = shift;
206   -
207   - #replace spaces with +
208   - $articlename =~ s/\s/\+/gs;
209   -
210   - # searching for the article rather than going directly to it allows us to ignore the issue of case sensitivity
211   - my $response = $browser->get("http://wiki.xomb.org/index.php?search=$articlename&go=Go");
212   -
213   - #check if article exists
214   - my $exists = 1;
215   - if($response->content =~ m/There is no page titled/)
216   - {
217   - $exists = 0;
218   - }
219   -
220   - my $content = $response->content;
221   -
222   - # remove the html tags
223   - # the following line breaks syntax highlighting in intype :(
224   - $content =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gs;
225   -
226   - #replace + with spaces
227   - $articlename =~ s/\+/ /gs;
228   -
229   - if ($response->is_success && $exists)
230   - {
231   - # try to get a definition
232   - if( $content =~ m/(.*?$articlename.*?\.)/i)
233   - {
234   - $bot->say(channel => $channel, body => $1);
235   - }
236   -
237   - #replace spaces with _
238   - $articlename =~ s/\s/_/gs;
239   -
240   - $bot->say(channel => $channel, body => "Full article here: " . $response->base);
241   - }
242   - else
243   - {
244   - $bot->say(channel => $channel, body => "Sorry, there's no article by that name");
245   - # try to search for similar articles
246   - search_for_article($articlename, $channel);
247   - }
248   -
249   -}
250   -
251   -sub search_for_article {
252   - my $searchterm = shift;
253   - my $channel = shift;
254   -
255   - # replace spaces with +
256   - $searchterm =~ s/\s/\+/gs;
257   -
258   - my $response = $browser->get("http://wiki.xomb.org/index.php?search=$searchterm&go=Go");
259   -
260   - if($response->is_success)
261   - {
262   - if($response->content =~ m/<li><a href="\/index\.php\?title=(\w*)/)
263   - {
264   - $bot->say(channel => $channel, body => "Did you mean $1: http://wiki.xomb.org/index.php?title=$1");
265   - }
266   - }
267   -
268   -}
8 bin/XOmBot
... ... @@ -0,0 +1,8 @@
  1 +#!/usr/bin/env ruby
  2 +
  3 +$: << File.dirname(__FILE__) + '/../lib'
  4 +
  5 +require 'xombot'
  6 +require 'xombot/cli'
  7 +
  8 +XOmBot::CLI.run
5 config/config.yml.example
... ... @@ -0,0 +1,5 @@
  1 +server: irc.freenode.org
  2 +port: 6697
  3 +name: XOmBot-test
  4 +channels: ["#XOmBot"]
  5 +ssl: true
73 lib/xombot.rb
... ... @@ -0,0 +1,73 @@
  1 +require 'bundler'
  2 +Bundler.require
  3 +
  4 +require 'fileutils'
  5 +require 'yaml'
  6 +
  7 +# allow sending of actions
  8 +module Cinch
  9 + class Message
  10 + def emote(m)
  11 + reply "\001ACTION #{m}\001"
  12 + end
  13 + end
  14 +end
  15 +
  16 +require 'xombot/plugin'
  17 +
  18 +# Place all plugins into a module
  19 +Dir[File.dirname(__FILE__) + '/xombot/plugins/*.rb'].each do |file|
  20 + eval "module XOmBot; module Plugins; #{File.read(file)}; end; end"
  21 +end
  22 +
  23 +module XOmBot
  24 + # Default Parameters
  25 + NAME = "XOmBot-test"
  26 + CHANNELS = ["#XOmBot"]
  27 + SERVER = "irc.freenode.org"
  28 + PORT = 6697
  29 + SSL = true
  30 +
  31 + class << self
  32 + attr_reader :plugins
  33 + attr_reader :name
  34 + attr_reader :server
  35 + attr_reader :channels
  36 + attr_reader :port
  37 + attr_reader :ssl
  38 +
  39 + def add_plugin plugin
  40 + @plugins = {} if @plugins.nil?
  41 + @plugins[plugin.class.name] = plugin
  42 + end
  43 +
  44 + def start
  45 + config_path = "#{File.dirname(__FILE__)}/../config"
  46 + if not File.exists?("#{config_path}/config.yml")
  47 + FileUtils.cp("#{config_path}/config.yml.example", "#{config_path}/config.yml")
  48 + end
  49 + config = YAML.load(File.open("#{config_path}/config.yml"))
  50 +
  51 + @name = config["name"] || NAME
  52 + @server = config["server"] || SERVER
  53 + @port = config["port"] || PORT
  54 + @ssl = (config["ssl"] == "true") || SSL
  55 + @channels = config["channels"] || CHANNELS
  56 +
  57 + bot = Cinch::Bot.new do
  58 + configure do |c|
  59 + c.server = XOmBot.server
  60 + c.port = XOmBot.port
  61 + c.ssl.use = XOmBot.ssl
  62 + c.nick = XOmBot.name
  63 + c.channels = XOmBot.channels
  64 + c.plugins.plugins = XOmBot::Plugins.constants.map do |plugin|
  65 + XOmBot::Plugins.const_get(plugin)
  66 + end
  67 + end
  68 + end
  69 +
  70 + bot.start
  71 + end
  72 + end
  73 +end
34 lib/xombot/cli.rb
... ... @@ -0,0 +1,34 @@
  1 +require 'xombot'
  2 +require 'optparse'
  3 +
  4 +module XOmBot
  5 + class CLI
  6 + BANNER = <<-USAGE
  7 + Usage:
  8 + Run with the default parameters:
  9 + xombot
  10 + USAGE
  11 +
  12 + class << self
  13 + def parse_options
  14 + @opts = OptionParser.new do |opts|
  15 + opts.banner = BANNER.gsub(/^\s{4}/, '')
  16 +
  17 + opts.separator ''
  18 + opts.separator 'Options:'
  19 +
  20 + opts.on('-h', '--help', 'Display this help') do
  21 + puts opts
  22 + exit
  23 + end
  24 + end
  25 +
  26 + @opts.parse!
  27 + end
  28 +
  29 + def run
  30 + XOmBot.start
  31 + end
  32 + end
  33 + end
  34 +end
39 lib/xombot/plugin.rb
... ... @@ -0,0 +1,39 @@
  1 +module XOmBot
  2 + class Plugin
  3 + include Cinch::Plugin
  4 +
  5 + def initialize *args
  6 + # Register the plugin with XOmBot
  7 + XOmBot.add_plugin self
  8 + super *args
  9 + end
  10 +
  11 + module ModuleSet
  12 + attr_reader :matches
  13 +
  14 + def match m, *args
  15 + @last_match = m
  16 + super m, *args
  17 + end
  18 +
  19 + def help m, *args
  20 + @matches = {} unless @matches
  21 + @matches[@last_match] = {} unless @matches[@last_match]
  22 + @matches[@last_match][:help] = m
  23 + end
  24 +
  25 + def usage m, *args
  26 + @matches = {} unless @matches
  27 + @matches[@last_match] = {} unless @matches[@last_match]
  28 + @matches[@last_match][:usage] = [] unless @matches[@last_match][:usage]
  29 + @matches[@last_match][:usage] << m
  30 + end
  31 + end
  32 +
  33 + extend ModuleSet
  34 +
  35 + def commands
  36 + self.class.matches || {}
  37 + end
  38 + end
  39 +end
23 lib/xombot/plugins/coinflip.rb
... ... @@ -0,0 +1,23 @@
  1 +class Coinflip < XOmBot::Plugin
  2 + match /coinflip(?: (.+) or (.+))?/
  3 + help "Flips a coin"
  4 + usage "coinflip -- Returns either heads or tails"
  5 + usage "coinflip x or y -- Returns either x or y"
  6 +
  7 + def execute(m, heads = nil, tails = nil)
  8 + result = rand(2)
  9 + if result == 0
  10 + if heads
  11 + m.reply heads
  12 + else
  13 + m.reply "heads"
  14 + end
  15 + else
  16 + if tails
  17 + m.reply tails
  18 + else
  19 + m.reply "tails"
  20 + end
  21 + end
  22 + end
  23 +end
19 lib/xombot/plugins/commands.rb
... ... @@ -0,0 +1,19 @@
  1 +class Commands < XOmBot::Plugin
  2 + match "commands"
  3 + help "Will list all of the available commands"
  4 +
  5 + def execute(m)
  6 + commands = []
  7 + XOmBot.plugins.each do |_,p|
  8 + p.commands.each do |k,v|
  9 + short_name = k.inspect.to_s[1..-2][/\w+/]
  10 + commands << short_name
  11 + if v[:help]
  12 + # m.reply "!#{} -- #{v[:help]}"
  13 + end
  14 + end
  15 + end
  16 +
  17 + m.reply "Commands: #{commands.sort.join(", ")}"
  18 + end
  19 +end
43 lib/xombot/plugins/dice.rb
... ... @@ -0,0 +1,43 @@
  1 +class Dice < XOmBot::Plugin
  2 + match /d(\d+)/, :method => :roll_single
  3 + help "Rolls a single die of the given number of sides"
  4 + usage "d2 -- Flips a coin"
  5 + usage "d6 -- Rolls a traditional 6 sided die"
  6 +
  7 + def roll_single(m, dice_amount)
  8 + dice_amount = dice_amount.to_i
  9 + if dice_amount == 0
  10 + m.reply "Infinite brains..."
  11 + else
  12 + m.reply rand(dice_amount) + 1
  13 + end
  14 + end
  15 +
  16 + # Following is based on a Cinch plugin
  17 + match /roll (?:(?:(\d+)#)?(\d+))?d(\d+)(?:([+-])(\d+))?/, :method => :roll
  18 + help "Rolls a set of dice with an optional offset"
  19 + usage "roll d6 -- Rolls a single, 6-sided die"
  20 + usage "roll 3d6-1 -- Sums the rolls of 3 6-sided dice with a -1 offset"
  21 +
  22 + def roll(m, repeats, rolls, sides, offset_op, offset)
  23 + repeats = repeats.to_i
  24 + repeats = 1 if repeats < 1
  25 + rolls = rolls.to_i
  26 + rolls = 1 if rolls < 1
  27 +
  28 + total = 0
  29 +
  30 + repeats.times do
  31 + rolls.times do
  32 + score = rand(sides.to_i) + 1
  33 + total += score
  34 + end
  35 +
  36 + if offset_op
  37 + total = total.send(offset_op, offset.to_i)
  38 + end
  39 + end
  40 +
  41 + m.reply "dice roll was: #{total}", true
  42 + end
  43 +end
53 lib/xombot/plugins/emotion.rb
... ... @@ -0,0 +1,53 @@
  1 +class Emotion < XOmBot::Plugin
  2 + listen_to :channel
  3 +
  4 + def initialize *args
  5 + super *args
  6 +
  7 + @good = 0
  8 + @bad = 0
  9 + end
  10 +
  11 + def listen(m)
  12 + # Sometimes XOmBot overhears things intended for others
  13 + unless m.message.match /#{XOmBot.name}/i
  14 + if m.message.match /\bhugs\b/
  15 + m.emote "hugs #{m.user.nick}"
  16 + end
  17 +
  18 + return
  19 + end
  20 +
  21 + # XOmBot does not appreciate being looked down upon
  22 + if m.message.match /\bfuck you\b/
  23 + m.reply m.message.gsub(/#{XOmBot.name}/i, m.user.nick).gsub(/fuck you/i, "fuck you too")
  24 + return
  25 + end
  26 +
  27 + # XOmBot responds well to appreciation
  28 + if m.message.match /good|cookie|hugs|cake|nice|awesome|pets|kiss|<3/
  29 + @good = @good + 1
  30 + m.emote "drools"
  31 + return
  32 + end
  33 +
  34 + # XOmBot responds to negative remarks
  35 + if m.message.match /bad|spank|spit|shoot|slap|\:\(/
  36 + @bad = @bad + 1
  37 + m.emote "cowers"
  38 + return
  39 + end
  40 +
  41 + m.emote "brains..."
  42 + end
  43 +
  44 + match "santa"
  45 +
  46 + def execute(m)
  47 + if @good >= @bad
  48 + m.emote "has been a good little robotic zombie"
  49 + else
  50 + m.emote "is getting coal in its metal stocking"
  51 + end
  52 + end
  53 +end
10 lib/xombot/plugins/google.rb
... ... @@ -0,0 +1,10 @@
  1 +class Google < XOmBot::Plugin
  2 + match /google (.+) for (.+?)( dammit)?$/
  3 + help "Links given nick to a google search"
  4 + usage "google llamas for cl0ckw0rk -- Gives cl0ckwork a useful search link"
  5 + usage "google garlic toast for wolfwood dammit -- Ditto, but with more luck"
  6 +
  7 + def execute(m, query, nick, for_real)
  8 + m.reply "#{nick}: http://lmgtfy.com/?q=#{query}#{for_real ? "&l=1" : ""}"
  9 + end
  10 +end
10 lib/xombot/plugins/hello.rb
... ... @@ -0,0 +1,10 @@
  1 +require 'xombot/plugin'
  2 +
  3 +class Hello < XOmBot::Plugin
  4 + match "hello"
  5 + help "This command says hello"
  6 +
  7 + def execute(m)
  8 + m.reply "Hello, #{m.user.nick}"
  9 + end
  10 +end
22 lib/xombot/plugins/help.rb
... ... @@ -0,0 +1,22 @@
  1 +class Help < XOmBot::Plugin
  2 + match /help (.+)/
  3 + help "Displays information on command arguments"
  4 + usage "help seen -- Query information about the seen command"
  5 + usage "help help -- Displays this thing you are reading"
  6 +
  7 + def execute(m, command)
  8 + XOmBot.plugins.each do |_,p|
  9 + idx = p.commands.keys.map{|c| c.inspect.to_s[1..-2][/\w+/]}.index command
  10 + if not idx.nil?
  11 + info = p.commands[p.commands.keys[idx]]
  12 + m.reply "[#{command}] #{info[:help]}"
  13 + m.reply "Invoke as: #{p.commands.keys[idx].inspect.to_s[1..-2]}"
  14 + if info[:usage]
  15 + info[:usage].each do |usage|
  16 + m.reply usage
  17 + end
  18 + end
  19 + end
  20 + end
  21 + end
  22 +end
27 lib/xombot/plugins/ignore.rb
... ... @@ -0,0 +1,27 @@
  1 +class Ignore < XOmBot::Plugin
  2 + match /ignore (.+)/, :method => :ignore
  3 + help "Ignores speech from a particular user"
  4 + usage "ignore wilkie -- XOmBot will not respond to wilkie"
  5 +
  6 + match /unignore (.+)/, :method => :unignore
  7 + help "Reverses decision to ignore speech from a particular user"
  8 + usage "unignore wilkie -- XOmBot will now respond to wilkie"
  9 +
  10 + attr_reader :ignored
  11 +
  12 + def initialize(*args)
  13 + super(*args)
  14 +
  15 + @ignored = []
  16 + end
  17 +
  18 + def ignore(m, nick)
  19 + @ignored << nick
  20 + m.emote "ignores #{nick}'s brains."
  21 + end
  22 +
  23 + def unignore(m, nick)
  24 + @ignored.delete nick
  25 + m.emote "again finds #{nick}'s brains delicious."
  26 + end
  27 +end
49 lib/xombot/plugins/joke.rb
... ... @@ -0,0 +1,49 @@
  1 +class Joke < XOmBot::Plugin
  2 + JOKE_DOMAIN = "http://www.abdn.ac.uk/jokingcomputer/webversion"
  3 + JOKE_ACTIONS = {
  4 + :start => "startFUN.php",
  5 + :new => "getjokeFUN.php?class=any&subject=any",
  6 + :joke => "fulldisplay.php" }
  7 +
  8 + def initialize *args
  9 + @agent = Mechanize.new
  10 + @joke = {}
  11 + @answer = {}
  12 +
  13 + super *args
  14 + end
  15 +
  16 + match "joke", :method => :tell_joke
  17 + help "Tells a funny joke"
  18 +
  19 + match "answer", :method => :tell_answer
  20 + help "Gives you the answer"
  21 +
  22 + def tell_joke(m)
  23 + @agent.get "#{JOKE_DOMAIN}/#{JOKE_ACTIONS[:start]}"
  24 + @agent.get "#{JOKE_DOMAIN}/#{JOKE_ACTIONS[:new]}"
  25 + page = @agent.get "#{JOKE_DOMAIN}/#{JOKE_ACTIONS[:joke]}"
  26 +
  27 + joke_div = page.search '//div[@class="jokermediumtext"]'
  28 + @joke[m.channel] = nil
  29 + @answer[m.channel] = nil
  30 +
  31 + # The joke and answer are separated by <br/>, so just
  32 + # enumerate the text of the div.
  33 + joke_div.first.children.each do |c|
  34 + if c.text?
  35 + if @joke[m.channel].nil?
  36 + @joke[m.channel] = c.content
  37 + else
  38 + @answer[m.channel] = c.content.chop
  39 + end
  40 + end
  41 + end
  42 +
  43 + m.reply @joke[m.channel]
  44 + end
  45 +
  46 + def tell_answer(m)
  47 + m.reply "#{@answer[m.channel]}! Oh ho ho ho... brains."
  48 + end
  49 +end
15 lib/xombot/plugins/local_time.rb
... ... @@ -0,0 +1,15 @@
  1 +class LocalTime < XOmBot::Plugin
  2 + TIME_QUERY_URL = "http://www.timeanddate.com/worldclock/results.html?query="
  3 +
  4 + match /time (.+)/
  5 + help "gives the local time in the given city"
  6 + usage "time Melbourne -- gives the time in Melbourne Australia"
  7 +
  8 + def execute(m, place)
  9 + @agent = Mechanize.new
  10 + page = @agent.get "#{TIME_QUERY_URL}#{place}"
  11 + current_time = page.search '//strong[@id="ct"]'
  12 +
  13 + m.reply "Time in #{place}: #{current_time.first.content}"
  14 + end
  15 +end
10 lib/xombot/plugins/plugins.rb
... ... @@ -0,0 +1,10 @@
  1 +class Plugins < XOmBot::Plugin
  2 + match "plugins"
  3 +
  4 + def execute(m)
  5 + m.reply "Plugins:"
  6 + XOmBot::plugins.keys.each do |p|
  7 + m.reply "-- #{p}"
  8 + end
  9 + end
  10 +end
39 lib/xombot/plugins/seen.rb
... ... @@ -0,0 +1,39 @@
  1 +class Seen < XOmBot::Plugin
  2 + # This plugin is based on a Cinch example
  3 + class SeenStruct < Struct.new(:who, :where, :what, :time)
  4 + def to_s(current_channel = nil)
  5 + ret = "[#{time.asctime}] #{who} was seen"
  6 + if current_channel != where
  7 + ret << " in #{where}"
  8 + end
  9 + ret << " saying #{what}"
  10 + end
  11 + end
  12 +
  13 + listen_to :channel
  14 +
  15 + def initialize(*args)
  16 + @users = {}
  17 + super *args
  18 + end
  19 +
  20 + def listen(m)
  21 + @users[m.user.nick] = SeenStruct.new m.user, m.channel, m.message, Time.now
  22 + end
  23 +
  24 + match /seen (.+)/
  25 + help "Reports the last moment a given person spoke"
  26 + usage "seen wilkie -- Reports the last moment wilkie spoke"
  27 +
  28 + def execute(m, nick)
  29 + if nick == @bot.nick
  30 + m.reply "I'm looking for brains."
  31 + elsif nick == m.user.nick
  32 + m.reply "Can I eat your brains? You aren't using them."
  33 + elsif @users.key? nick
  34 + m.reply @users[nick].to_s(m.channel)
  35 + else
  36 + m.reply "I have not seen #{nick}. Rar."
  37 + end
  38 + end
  39 +end
15 lib/xombot/plugins/url_announce.rb
... ... @@ -0,0 +1,15 @@
  1 +class URLAnnounce < XOmBot::Plugin
  2 + listen_to :channel
  3 +
  4 + def listen(m)
  5 + ignore_plugin = XOmBot.plugins["XOmBot::Plugins::Ignore"]
  6 + return if ignore_plugin and ignore_plugin.ignored.include? m.user.nick
  7 +
  8 + m.message.scan /https?:\/\/[\S]+/ do |url|
  9 + page = Mechanize.new.get url
  10 + if page.is_a? Mechanize::Page
  11 + m.reply "Title: #{page.title.gsub(/\t|\r|\n/, " ").strip}"
  12 + end
  13 + end
  14 + end
  15 +end

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.