Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'feature/ruby' of git://github.com/wilkie/XOmBot into ruby

Conflicts:
	XOmBot.pl
  • Loading branch information...
commit fdcd7978d4616806251b2ee6e7ffb5fb22396cb8 2 parents 33f7ec4 + a4083f5
@LindseyB authored
View
2  .gitignore
@@ -0,0 +1,2 @@
+config/config.yml
+*.rbc
View
3  Gemfile
@@ -0,0 +1,3 @@
+source :rubygems
+gem "cinch"
+gem "mechanize"
View
28 Gemfile.lock
@@ -0,0 +1,28 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ cinch (1.1.3)
+ domain_name (0.5.2)
+ unf (~> 0.0.3)
+ mechanize (2.1.1)
+ domain_name (~> 0.5, >= 0.5.1)
+ net-http-digest_auth (~> 1.1, >= 1.1.1)
+ net-http-persistent (~> 2.4, >= 2.4.1)
+ nokogiri (~> 1.4)
+ ntlm-http (~> 0.1, >= 0.1.1)
+ webrobots (~> 0.0, >= 0.0.9)
+ net-http-digest_auth (1.2)
+ net-http-persistent (2.4.1)
+ nokogiri (1.5.0)
+ ntlm-http (0.1.1)
+ unf (0.0.4)
+ unf_ext
+ unf_ext (0.0.4)
+ webrobots (0.0.13)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ cinch
+ mechanize
View
26 README.rdoc
@@ -1,29 +1,21 @@
= XOmBot
----
-XOmBot is a simple IRC bot written in perl meant to lurk in #xomb.
+XOmBot is a simple IRC bot written in ruby meant to lurk in #xomb.
Right now XOmBot accepts the following commands:
-* !wiki [article name]: will attempt to find a XOmB wiki article of that name and provide a definition
-* !latest: will provide information for the latest commit
-* !commands: will list the commands XOmBot listens for and what they do
-* !google [phrase] for [nick]: Sends a lmgtfy.com link to nick
+* !commands: will list the commands XOmBot listens for
+* !help [command]: queries what a command will do
+* !google [phrase] for [nick]: Sends a lmgtfy.com link to nick
* !coinflip: flips a coin
* !santa: Asks Santa if the bot has been naught or nice
-* !d[n]: rolls a die with n sides
+* !d[n]: rolls a die with n sides
+* !roll [n]d[n][[+|-]n]: rolls several dice with bonuses
+* !joke: hear a funny joke
+* !answer: get the answer to the last funny joke
XOmBot has the following behaviours in addition to the commands:
-* announces an applied commit to the main XOmB repo
-* informs the channel of the !commands command upon entering a channel
* says "brains..." when directly refered to (ie: XOmBot: message)
+* responds dumbly to social cues
* displays the title of any valid http:// urls displayed in the channel
-
-----
-
-Requires:
-
-* Bot::BasicBot
-* URI::Title
-* URI::Find::Simple
-
View
268 XOmBot.pl
@@ -1,268 +0,0 @@
-#!/usr/bin/perl -w
-
-#################################################################################
-# XomBot.pl [nick] #
-# #
-# Your friendly XOmB bot for #xomb #
-# #
-# This program is free software. It comes without any warranty, to the extent #
-# permitted by applicable law. You can redistribute it and/or modify it under #
-# the term of the Do What The Fuck You Want To Public License, Version 2, as #
-# published by Sam Hocevar. See http://sam.zoy.org/wtfpl/COPYING for more #
-# details #
-# #
-#################################################################################
-
-package Bot;
-use base qw(Bot::BasicBot);
-use warnings;
-use strict;
-use URI::Title qw( title );
-use URI::Find::Simple qw( list_uris );
-use LWP 5.64;
-
-my($businessChannel) = '#xomb';
-my($pleasureChannel) = '##l2l';
-my $mynick = shift || 'XOmBot';
-my $browser = LWP::UserAgent->new;
-my $commitid = "";
-my $first = 1;
-
-my $good = 0;
-my $bad = 0;
-
-my ($bot) = Bot->new(
- server => "irc.freenode.net",
- port => "8001",
- channels => [ $businessChannel, $pleasureChannel , "##IwantAkitty", "#rstatus", "#osgcc", "#croc"],
- nick => $mynick,
- charset => 'utf-8',
- );
-
-$bot->run();
-
-sub connected {
- my $self = shift;
- $self->say(channel => $_, body => "$mynick is online. !commands will show what I can do.") for (@{$self->{channels}});
-}
-
-sub tick {
- #check_rss();
- return 60;
-}
-
-sub said {
- my $self = shift;
- my $message = shift;
- my $body = $message->{body};
- my $nick = $message->{who};
- my $channel = $message->{channel};
- my $address = $message->{address};
-
- # --- url announce ---
- if(my @urls = list_uris($body)){
- if($nick ne "github-xombot"){
- $self->reply($message, title($_)) for (@urls);
- }
- }
-
- # --- command list ---
- if($body =~ m/^\!commands/ || $body =~ m/^\!h.lp/i){
- # show all the commands that xombot listens to
- $self->say(channel => $channel, body => "!wiki [search term] - will search the wiki for the given word or phrase.");
- $self->say(channel => $channel, body => "!latest - will show the last commit to the offical XOmB repository.");
- $self->say(channel => $channel, body => "!google [phrase] for [nick] - answer questions. More bangs to shoot from the hip.");
- $self->say(channel => $channel, body => "!coinflip - ...");
- $self->say(channel => $channel, body => "!santa - ask Santa whether $mynick has been naughty or nice.");
- $self->say(channel => $channel, body => "!d[n] - rolls die with n sides");
- }
-
- if ($body =~ m/^\!wiki\s*([\w*\s]*)/){
- # check if article exists in the wiki
- get_wiki_entry($1, $channel);
- }
-
- if($body =~ m/^\!latest/){
- # show the latest commit the next loop around
- $commitid = "";
- }
-
- if($body =~ m/^\!(!*)google(!*) (.*) for (.*)/){
- my($term) = $3;
- my($target) = $4;
- my($lucky);
-
- if($1 ne "" || $2 ne ""){
- $lucky = "&l=1";
- }
-
- $term =~ s/ /+/g;
-
- $self->say(channel => $channel, who => $target, address => "1", body => "http://lmgtfy.com/?q=$term$lucky");
- }
-
- if($body =~ m/^\!coinflip/){
- my $outcome;
-
- if($body =~ m/^\!coinflip.* heads (.*) tails (.*)/){
- $outcome = $1;
- $outcome = $2 if int(rand(2)) == 1;
- }else{
- $outcome = "heads";
- $outcome = "tails" if int(rand(2)) == 1;
- }
-
- #$self->say(channel => $channel, who => $nick, address => "1", body => "$outcome");
- $self->say(channel => $channel, body => "$outcome");
- }
-
- # dice roll
- if($body =~ m/^\!d(\d+)/){
- $self->say(channel => $channel, body => int(rand($1)) + 1);
- }
-
- if($body =~ m/^\!santa/){
- if($good >= $bad){
- $self->emote(channel => $channel, body => "has been a good little robotic zombie");
- }else{
- $self->emote(channel => $channel, body => "is getting coal in its metal stocking");
- }
- }
-
- # --- miscellaneous behaviors ---
-
- # annoy duck
- if($body eq "hi" and $nick eq "duckinator"){
- $self->say(channel => $channel, who => $nick, body => "hi", address => "1");
- }
-
- my($respondedFlag) = 0;
-
- if ($address || $body =~ m/$mynick/){
- my $compliment = $body;
-
- if($compliment =~ m/good/i || $compliment =~ m/cookie/i || $compliment =~ m/<3/){
- $self->emote(channel => $channel, body => "drools");
-
- $good++;
- $respondedFlag = 1;
- }elsif($compliment =~ m/bad/i || $compliment =~ m/spank/i){
- $self->emote(channel => $channel, body => "cowers");
-
- $bad++;
- $respondedFlag = 1;
- }
- }
-
- if($address && !$respondedFlag){
- $self->say(channel => $channel, who => $nick, address => "1", body => "brains...");
- }
-
- return undef;
-}
-
-sub check_rss {
- my $response = $browser->get("http://github.com/feeds/xomboverlord/commits/xomb/unborn");
-
- if($response->is_success && $response->content =~ m/<entry>\s*<id>.*\/(\w*)<\/id>/){
- my $commiter = "Unknown";
- my $commit_msg = "Unspecified";
- my $orig_commitid = $commitid;
-
- #if it's not the last one we announced
- if($commitid ne $1){
- $commitid = $1;
-
- # get try to get the info to announce it
- if($response->content =~ m/<entry>.*?<title>(.*?)<\/title>/s){
- $commit_msg = $1;
- }
-
- # get try to get the author to announce it
- if($response->content =~ m/<name>(\w*)<\/name>/){
- $commiter = $1;
- }
-
- if($commit_msg ne "Sorry, this commit log is taking too long to generate."){
- unless($first){
- $bot->say(channel => $businessChannel, body => "Commit made by $commiter: $commit_msg");
- $bot->say(channel => $businessChannel, body => "View: http://github.com/xomboverlord/xomb/commit/$commitid");
- }else{
- $first = 0;
- }
- }else{
- # we don't know if there actually was a new commit
- $commitid = $orig_commitid;
- }
- }
- }
-}
-
-
-
-sub get_wiki_entry {
- my $articlename = shift;
- my $channel = shift;
-
- #replace spaces with +
- $articlename =~ s/\s/\+/gs;
-
- # searching for the article rather than going directly to it allows us to ignore the issue of case sensitivity
- my $response = $browser->get("http://wiki.xomb.org/index.php?search=$articlename&go=Go");
-
- #check if article exists
- my $exists = 1;
- if($response->content =~ m/There is no page titled/)
- {
- $exists = 0;
- }
-
- my $content = $response->content;
-
- # remove the html tags
- # the following line breaks syntax highlighting in intype :(
- $content =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gs;
-
- #replace + with spaces
- $articlename =~ s/\+/ /gs;
-
- if ($response->is_success && $exists)
- {
- # try to get a definition
- if( $content =~ m/(.*?$articlename.*?\.)/i)
- {
- $bot->say(channel => $channel, body => $1);
- }
-
- #replace spaces with _
- $articlename =~ s/\s/_/gs;
-
- $bot->say(channel => $channel, body => "Full article here: " . $response->base);
- }
- else
- {
- $bot->say(channel => $channel, body => "Sorry, there's no article by that name");
- # try to search for similar articles
- search_for_article($articlename, $channel);
- }
-
-}
-
-sub search_for_article {
- my $searchterm = shift;
- my $channel = shift;
-
- # replace spaces with +
- $searchterm =~ s/\s/\+/gs;
-
- my $response = $browser->get("http://wiki.xomb.org/index.php?search=$searchterm&go=Go");
-
- if($response->is_success)
- {
- if($response->content =~ m/<li><a href="\/index\.php\?title=(\w*)/)
- {
- $bot->say(channel => $channel, body => "Did you mean $1: http://wiki.xomb.org/index.php?title=$1");
- }
- }
-
-}
View
8 bin/XOmBot
@@ -0,0 +1,8 @@
+#!/usr/bin/env ruby
+
+$: << File.dirname(__FILE__) + '/../lib'
+
+require 'xombot'
+require 'xombot/cli'
+
+XOmBot::CLI.run
View
5 config/config.yml.example
@@ -0,0 +1,5 @@
+server: irc.freenode.org
+port: 6697
+name: XOmBot-test
+channels: ["#XOmBot"]
+ssl: true
View
73 lib/xombot.rb
@@ -0,0 +1,73 @@
+require 'bundler'
+Bundler.require
+
+require 'fileutils'
+require 'yaml'
+
+# allow sending of actions
+module Cinch
+ class Message
+ def emote(m)
+ reply "\001ACTION #{m}\001"
+ end
+ end
+end
+
+require 'xombot/plugin'
+
+# Place all plugins into a module
+Dir[File.dirname(__FILE__) + '/xombot/plugins/*.rb'].each do |file|
+ eval "module XOmBot; module Plugins; #{File.read(file)}; end; end"
+end
+
+module XOmBot
+ # Default Parameters
+ NAME = "XOmBot-test"
+ CHANNELS = ["#XOmBot"]
+ SERVER = "irc.freenode.org"
+ PORT = 6697
+ SSL = true
+
+ class << self
+ attr_reader :plugins
+ attr_reader :name
+ attr_reader :server
+ attr_reader :channels
+ attr_reader :port
+ attr_reader :ssl
+
+ def add_plugin plugin
+ @plugins = {} if @plugins.nil?
+ @plugins[plugin.class.name] = plugin
+ end
+
+ def start
+ config_path = "#{File.dirname(__FILE__)}/../config"
+ if not File.exists?("#{config_path}/config.yml")
+ FileUtils.cp("#{config_path}/config.yml.example", "#{config_path}/config.yml")
+ end
+ config = YAML.load(File.open("#{config_path}/config.yml"))
+
+ @name = config["name"] || NAME
+ @server = config["server"] || SERVER
+ @port = config["port"] || PORT
+ @ssl = (config["ssl"] == "true") || SSL
+ @channels = config["channels"] || CHANNELS
+
+ bot = Cinch::Bot.new do
+ configure do |c|
+ c.server = XOmBot.server
+ c.port = XOmBot.port
+ c.ssl.use = XOmBot.ssl
+ c.nick = XOmBot.name
+ c.channels = XOmBot.channels
+ c.plugins.plugins = XOmBot::Plugins.constants.map do |plugin|
+ XOmBot::Plugins.const_get(plugin)
+ end
+ end
+ end
+
+ bot.start
+ end
+ end
+end
View
34 lib/xombot/cli.rb
@@ -0,0 +1,34 @@
+require 'xombot'
+require 'optparse'
+
+module XOmBot
+ class CLI
+ BANNER = <<-USAGE
+ Usage:
+ Run with the default parameters:
+ xombot
+ USAGE
+
+ class << self
+ def parse_options
+ @opts = OptionParser.new do |opts|
+ opts.banner = BANNER.gsub(/^\s{4}/, '')
+
+ opts.separator ''
+ opts.separator 'Options:'
+
+ opts.on('-h', '--help', 'Display this help') do
+ puts opts
+ exit
+ end
+ end
+
+ @opts.parse!
+ end
+
+ def run
+ XOmBot.start
+ end
+ end
+ end
+end
View
39 lib/xombot/plugin.rb
@@ -0,0 +1,39 @@
+module XOmBot
+ class Plugin
+ include Cinch::Plugin
+
+ def initialize *args
+ # Register the plugin with XOmBot
+ XOmBot.add_plugin self
+ super *args
+ end
+
+ module ModuleSet
+ attr_reader :matches
+
+ def match m, *args
+ @last_match = m
+ super m, *args
+ end
+
+ def help m, *args
+ @matches = {} unless @matches
+ @matches[@last_match] = {} unless @matches[@last_match]
+ @matches[@last_match][:help] = m
+ end
+
+ def usage m, *args
+ @matches = {} unless @matches
+ @matches[@last_match] = {} unless @matches[@last_match]
+ @matches[@last_match][:usage] = [] unless @matches[@last_match][:usage]
+ @matches[@last_match][:usage] << m
+ end
+ end
+
+ extend ModuleSet
+
+ def commands
+ self.class.matches || {}
+ end
+ end
+end
View
23 lib/xombot/plugins/coinflip.rb
@@ -0,0 +1,23 @@
+class Coinflip < XOmBot::Plugin
+ match /coinflip(?: (.+) or (.+))?/
+ help "Flips a coin"
+ usage "coinflip -- Returns either heads or tails"
+ usage "coinflip x or y -- Returns either x or y"
+
+ def execute(m, heads = nil, tails = nil)
+ result = rand(2)
+ if result == 0
+ if heads
+ m.reply heads
+ else
+ m.reply "heads"
+ end
+ else
+ if tails
+ m.reply tails
+ else
+ m.reply "tails"
+ end
+ end
+ end
+end
View
19 lib/xombot/plugins/commands.rb
@@ -0,0 +1,19 @@
+class Commands < XOmBot::Plugin
+ match "commands"
+ help "Will list all of the available commands"
+
+ def execute(m)
+ commands = []
+ XOmBot.plugins.each do |_,p|
+ p.commands.each do |k,v|
+ short_name = k.inspect.to_s[1..-2][/\w+/]
+ commands << short_name
+ if v[:help]
+ # m.reply "!#{} -- #{v[:help]}"
+ end
+ end
+ end
+
+ m.reply "Commands: #{commands.sort.join(", ")}"
+ end
+end
View
43 lib/xombot/plugins/dice.rb
@@ -0,0 +1,43 @@
+class Dice < XOmBot::Plugin
+ match /d(\d+)/, :method => :roll_single
+ help "Rolls a single die of the given number of sides"
+ usage "d2 -- Flips a coin"
+ usage "d6 -- Rolls a traditional 6 sided die"
+
+ def roll_single(m, dice_amount)
+ dice_amount = dice_amount.to_i
+ if dice_amount == 0
+ m.reply "Infinite brains..."
+ else
+ m.reply rand(dice_amount) + 1
+ end
+ end
+
+ # Following is based on a Cinch plugin
+ match /roll (?:(?:(\d+)#)?(\d+))?d(\d+)(?:([+-])(\d+))?/, :method => :roll
+ help "Rolls a set of dice with an optional offset"
+ usage "roll d6 -- Rolls a single, 6-sided die"
+ usage "roll 3d6-1 -- Sums the rolls of 3 6-sided dice with a -1 offset"
+
+ def roll(m, repeats, rolls, sides, offset_op, offset)
+ repeats = repeats.to_i
+ repeats = 1 if repeats < 1
+ rolls = rolls.to_i
+ rolls = 1 if rolls < 1
+
+ total = 0
+
+ repeats.times do
+ rolls.times do
+ score = rand(sides.to_i) + 1
+ total += score
+ end
+
+ if offset_op
+ total = total.send(offset_op, offset.to_i)
+ end
+ end
+
+ m.reply "dice roll was: #{total}", true
+ end
+end
View
53 lib/xombot/plugins/emotion.rb
@@ -0,0 +1,53 @@
+class Emotion < XOmBot::Plugin
+ listen_to :channel
+
+ def initialize *args
+ super *args
+
+ @good = 0
+ @bad = 0
+ end
+
+ def listen(m)
+ # Sometimes XOmBot overhears things intended for others
+ unless m.message.match /#{XOmBot.name}/i
+ if m.message.match /\bhugs\b/
+ m.emote "hugs #{m.user.nick}"
+ end
+
+ return
+ end
+
+ # XOmBot does not appreciate being looked down upon
+ if m.message.match /\bfuck you\b/
+ m.reply m.message.gsub(/#{XOmBot.name}/i, m.user.nick).gsub(/fuck you/i, "fuck you too")
+ return
+ end
+
+ # XOmBot responds well to appreciation
+ if m.message.match /good|cookie|hugs|cake|nice|awesome|pets|kiss|<3/
+ @good = @good + 1
+ m.emote "drools"
+ return
+ end
+
+ # XOmBot responds to negative remarks
+ if m.message.match /bad|spank|spit|shoot|slap|\:\(/
+ @bad = @bad + 1
+ m.emote "cowers"
+ return
+ end
+
+ m.emote "brains..."
+ end
+
+ match "santa"
+
+ def execute(m)
+ if @good >= @bad
+ m.emote "has been a good little robotic zombie"
+ else
+ m.emote "is getting coal in its metal stocking"
+ end
+ end
+end
View
10 lib/xombot/plugins/google.rb
@@ -0,0 +1,10 @@
+class Google < XOmBot::Plugin
+ match /google (.+) for (.+?)( dammit)?$/
+ help "Links given nick to a google search"
+ usage "google llamas for cl0ckw0rk -- Gives cl0ckwork a useful search link"
+ usage "google garlic toast for wolfwood dammit -- Ditto, but with more luck"
+
+ def execute(m, query, nick, for_real)
+ m.reply "#{nick}: http://lmgtfy.com/?q=#{query}#{for_real ? "&l=1" : ""}"
+ end
+end
View
10 lib/xombot/plugins/hello.rb
@@ -0,0 +1,10 @@
+require 'xombot/plugin'
+
+class Hello < XOmBot::Plugin
+ match "hello"
+ help "This command says hello"
+
+ def execute(m)
+ m.reply "Hello, #{m.user.nick}"
+ end
+end
View
22 lib/xombot/plugins/help.rb
@@ -0,0 +1,22 @@
+class Help < XOmBot::Plugin
+ match /help (.+)/
+ help "Displays information on command arguments"
+ usage "help seen -- Query information about the seen command"
+ usage "help help -- Displays this thing you are reading"
+
+ def execute(m, command)
+ XOmBot.plugins.each do |_,p|
+ idx = p.commands.keys.map{|c| c.inspect.to_s[1..-2][/\w+/]}.index command
+ if not idx.nil?
+ info = p.commands[p.commands.keys[idx]]
+ m.reply "[#{command}] #{info[:help]}"
+ m.reply "Invoke as: #{p.commands.keys[idx].inspect.to_s[1..-2]}"
+ if info[:usage]
+ info[:usage].each do |usage|
+ m.reply usage
+ end
+ end
+ end
+ end
+ end
+end
View
27 lib/xombot/plugins/ignore.rb
@@ -0,0 +1,27 @@
+class Ignore < XOmBot::Plugin
+ match /ignore (.+)/, :method => :ignore
+ help "Ignores speech from a particular user"
+ usage "ignore wilkie -- XOmBot will not respond to wilkie"
+
+ match /unignore (.+)/, :method => :unignore
+ help "Reverses decision to ignore speech from a particular user"
+ usage "unignore wilkie -- XOmBot will now respond to wilkie"
+
+ attr_reader :ignored
+
+ def initialize(*args)
+ super(*args)
+
+ @ignored = []
+ end
+
+ def ignore(m, nick)
+ @ignored << nick
+ m.emote "ignores #{nick}'s brains."
+ end
+
+ def unignore(m, nick)
+ @ignored.delete nick
+ m.emote "again finds #{nick}'s brains delicious."
+ end
+end
View
49 lib/xombot/plugins/joke.rb
@@ -0,0 +1,49 @@
+class Joke < XOmBot::Plugin
+ JOKE_DOMAIN = "http://www.abdn.ac.uk/jokingcomputer/webversion"
+ JOKE_ACTIONS = {
+ :start => "startFUN.php",
+ :new => "getjokeFUN.php?class=any&subject=any",
+ :joke => "fulldisplay.php" }
+
+ def initialize *args
+ @agent = Mechanize.new
+ @joke = {}
+ @answer = {}
+
+ super *args
+ end
+
+ match "joke", :method => :tell_joke
+ help "Tells a funny joke"
+
+ match "answer", :method => :tell_answer
+ help "Gives you the answer"
+
+ def tell_joke(m)
+ @agent.get "#{JOKE_DOMAIN}/#{JOKE_ACTIONS[:start]}"
+ @agent.get "#{JOKE_DOMAIN}/#{JOKE_ACTIONS[:new]}"
+ page = @agent.get "#{JOKE_DOMAIN}/#{JOKE_ACTIONS[:joke]}"
+
+ joke_div = page.search '//div[@class="jokermediumtext"]'
+ @joke[m.channel] = nil
+ @answer[m.channel] = nil
+
+ # The joke and answer are separated by <br/>, so just
+ # enumerate the text of the div.
+ joke_div.first.children.each do |c|
+ if c.text?
+ if @joke[m.channel].nil?
+ @joke[m.channel] = c.content
+ else
+ @answer[m.channel] = c.content.chop
+ end
+ end
+ end
+
+ m.reply @joke[m.channel]
+ end
+
+ def tell_answer(m)
+ m.reply "#{@answer[m.channel]}! Oh ho ho ho... brains."
+ end
+end
View
15 lib/xombot/plugins/local_time.rb
@@ -0,0 +1,15 @@
+class LocalTime < XOmBot::Plugin
+ TIME_QUERY_URL = "http://www.timeanddate.com/worldclock/results.html?query="
+
+ match /time (.+)/
+ help "gives the local time in the given city"
+ usage "time Melbourne -- gives the time in Melbourne Australia"
+
+ def execute(m, place)
+ @agent = Mechanize.new
+ page = @agent.get "#{TIME_QUERY_URL}#{place}"
+ current_time = page.search '//strong[@id="ct"]'
+
+ m.reply "Time in #{place}: #{current_time.first.content}"
+ end
+end
View
10 lib/xombot/plugins/plugins.rb
@@ -0,0 +1,10 @@
+class Plugins < XOmBot::Plugin
+ match "plugins"
+
+ def execute(m)
+ m.reply "Plugins:"
+ XOmBot::plugins.keys.each do |p|
+ m.reply "-- #{p}"
+ end
+ end
+end
View
39 lib/xombot/plugins/seen.rb
@@ -0,0 +1,39 @@
+class Seen < XOmBot::Plugin
+ # This plugin is based on a Cinch example
+ class SeenStruct < Struct.new(:who, :where, :what, :time)
+ def to_s(current_channel = nil)
+ ret = "[#{time.asctime}] #{who} was seen"
+ if current_channel != where
+ ret << " in #{where}"
+ end
+ ret << " saying #{what}"
+ end
+ end
+
+ listen_to :channel
+
+ def initialize(*args)
+ @users = {}
+ super *args
+ end
+
+ def listen(m)
+ @users[m.user.nick] = SeenStruct.new m.user, m.channel, m.message, Time.now
+ end
+
+ match /seen (.+)/
+ help "Reports the last moment a given person spoke"
+ usage "seen wilkie -- Reports the last moment wilkie spoke"
+
+ def execute(m, nick)
+ if nick == @bot.nick
+ m.reply "I'm looking for brains."
+ elsif nick == m.user.nick
+ m.reply "Can I eat your brains? You aren't using them."
+ elsif @users.key? nick
+ m.reply @users[nick].to_s(m.channel)
+ else
+ m.reply "I have not seen #{nick}. Rar."
+ end
+ end
+end
View
15 lib/xombot/plugins/url_announce.rb
@@ -0,0 +1,15 @@
+class URLAnnounce < XOmBot::Plugin
+ listen_to :channel
+
+ def listen(m)
+ ignore_plugin = XOmBot.plugins["XOmBot::Plugins::Ignore"]
+ return if ignore_plugin and ignore_plugin.ignored.include? m.user.nick
+
+ m.message.scan /https?:\/\/[\S]+/ do |url|
+ page = Mechanize.new.get url
+ if page.is_a? Mechanize::Page
+ m.reply "Title: #{page.title.gsub(/\t|\r|\n/, " ").strip}"
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.