raibo 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ Botfile
data/Gemfile CHANGED
@@ -2,3 +2,6 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in raibo.gemspec
4
4
  gemspec
5
+
6
+ # Development dependencies
7
+ gem 'rspec'
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'raibo'
5
+
6
+ botfile = ARGV.shift || 'Botfile'
7
+
8
+ if Dir[botfile].empty?
9
+ puts "Usage: raibo [botfile]"
10
+ end
11
+
12
+ b = Raibo::Bot.new('irc.he.net', :nick => 'raibot', :port => 6667, :verbose => true)
13
+ b.instance_eval(File.read(botfile))
14
+ b.run
@@ -0,0 +1,25 @@
1
+ # This is a simple example of a module that could be used with Raibo.
2
+ # An associated Botfile might look like this:
3
+ #
4
+ # require_relative 'example/test_module'
5
+ # use ExampleModule.new(/hello/, 'goodbye')
6
+ # use ExampleModule.new(/goodbye/, 'hello')
7
+ #
8
+ # This will run a bot that responds to a message containing "hello"
9
+ # by saying "goodbye", and vice versa.
10
+ #
11
+ # Bots can maintain whatever state they want to. The only requirement
12
+ # is that they respond to a #call method with a Raibo::Connection as
13
+ # the first parameter and Raibo::Message as the second.
14
+
15
+ class ExampleModule
16
+ def initialize(regexp, response)
17
+ @regexp, @response = regexp, response
18
+ end
19
+
20
+ def call(c, message)
21
+ if message.body =~ @regexp
22
+ c.say @response
23
+ end
24
+ end
25
+ end
@@ -5,3 +5,5 @@ require 'socket'
5
5
 
6
6
  require 'raibo/version'
7
7
  require 'raibo/connection'
8
+ require 'raibo/bot'
9
+ require 'raibo/message'
@@ -0,0 +1,66 @@
1
+ module Raibo
2
+ class Bot
3
+ def initialize(*args)
4
+ @handlers = []
5
+
6
+ if args.first.is_a?(Raibo::Connection)
7
+ @connection = args.shift
8
+ else
9
+ @connection = Raibo::Connection.new(*args)
10
+ end
11
+ end
12
+
13
+ def use(handler=nil, &block)
14
+ @handlers.push(handler || block)
15
+ end
16
+
17
+ def match(regexp, &block)
18
+ use do |msg|
19
+ if msg.body =~ regexp
20
+ exec_with_var_arity($~, msg, &block)
21
+ end
22
+ end
23
+ end
24
+
25
+ def run(async=false)
26
+ if async
27
+ @thread = Thread.new { run_sync }
28
+ @thread.abort_on_exception = true
29
+ else
30
+ run_sync
31
+ end
32
+ end
33
+
34
+ def stop
35
+ @thread.kill if @thread
36
+ @connection.close
37
+ end
38
+
39
+ def alive?
40
+ @thread.alive? if @thread
41
+ end
42
+
43
+ private
44
+ def run_sync
45
+ @connection.open
46
+ @connection.handle_lines do |line|
47
+ begin
48
+ message = Raibo::Message.new(line)
49
+ rescue => e
50
+ if @connection.verbose
51
+ puts "Error parsing line:"
52
+ puts " #{line}"
53
+ puts " #{e.backtrace}"
54
+ end
55
+ end
56
+ @handlers.each do |handler|
57
+ if handler.is_a?(Proc)
58
+ break if @connection.instance_exec(message, &handler)
59
+ else
60
+ break if handler.call(@connection, message)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -3,23 +3,23 @@ module Raibo
3
3
  attr_accessor :server, :port, :nick, :channel
4
4
 
5
5
  def initialize(server, opts={})
6
- @server = server
7
- @port = opts[:port] || 6667
8
- @nick = opts[:nick] || 'Raibo'
9
- @channel = opts[:channel] || '#raibo'
10
- @verbose = !!opts[:verbose]
6
+ @server = server
7
+ @port = opts[:port] || 6667
8
+ @nick = opts[:nick] || 'Raibo'
9
+ @channel = opts[:channel] || '#raibo'
10
+ @verbose = !!opts[:verbose]
11
11
  end
12
12
 
13
13
  def open
14
14
  @connection = TCPSocket.new(@server, @port)
15
- send "USER #{@nick} 0 * :Hi"
15
+ send "USER #{@nick} 0 * :Hello"
16
16
  nick @nick
17
17
 
18
18
  handle_lines do |line|
19
19
  case line
20
- when /:Nickname is already in use./
21
- @nick = "#{@nick}_"
22
- nick @nick
20
+ when /:Nickname is already in use/
21
+ @connection.close
22
+ raise "Connection error: Nickname is already in use."
23
23
  when /001/
24
24
  join @channel
25
25
  break
@@ -41,6 +41,8 @@ module Raibo
41
41
  yield line
42
42
  end
43
43
  end
44
+ rescue IOError
45
+ close
44
46
  end
45
47
 
46
48
  def nick(nick)
@@ -67,5 +69,14 @@ module Raibo
67
69
  puts "<-- #{str}" if @verbose
68
70
  @connection.puts(str)
69
71
  end
72
+
73
+ def exec_with_var_arity(*args, &block)
74
+ arity = block.arity
75
+ if arity <= 0
76
+ instance_eval(&block)
77
+ else
78
+ instance_exec(*args.take(block.arity), &block)
79
+ end
80
+ end
70
81
  end
71
82
  end
@@ -0,0 +1,63 @@
1
+ module Raibo
2
+ class Message
3
+ # Readers for the components of the actual IRC protocol line.
4
+ attr_reader :prefix, :type, :middle, :trailing
5
+
6
+ # Readers for higher-level attributes of the message.
7
+ attr_reader :kind, :from, :to, :body
8
+
9
+ def initialize(line)
10
+ @prefix, @type, @middle, @trailing = parse_line(line)
11
+
12
+ @kind = get_kind
13
+ @from = get_from
14
+ @to = get_to
15
+ @body = get_body
16
+ end
17
+
18
+ private
19
+ def parse_line(line)
20
+ prefix, type, params = line.match(/:(\S+) (\S+) (.*)/).captures
21
+ if params
22
+ middle, _, trailing = params.partition(':')
23
+ middle = middle.split
24
+ trailing.chomp!
25
+ end
26
+ [prefix, type, middle, trailing]
27
+ end
28
+
29
+ def get_kind
30
+ case type
31
+ when 'PRIVMSG'
32
+ if trailing =~ /^\001ACTION/
33
+ :emote
34
+ else
35
+ :message
36
+ end
37
+ when 'JOIN'
38
+ :join
39
+ when 'PART'
40
+ :part
41
+ end
42
+ end
43
+
44
+ def get_from
45
+ prefix[/^([^!@ ]*)/, 1]
46
+ end
47
+
48
+ def get_to
49
+ if [:message, :emote].include?(kind)
50
+ middle.first
51
+ end
52
+ end
53
+
54
+ def get_body
55
+ case kind
56
+ when :message
57
+ trailing
58
+ when :emote
59
+ trailing[/\001ACTION ([^\001]*)/, 1]
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,3 +1,3 @@
1
1
  module Raibo
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module Raibo
4
+ describe Message do
5
+ it 'parses a message' do
6
+ m = Raibo::Message.new(":someone!someone@Nightstar-251832d1.snfc22.example.com PRIVMSG #raibo :foo bar baz")
7
+
8
+ m.kind.should == :message
9
+ m.from.should == 'someone'
10
+ m.to.should == '#raibo'
11
+ m.body.should == 'foo bar baz'
12
+ end
13
+
14
+ it 'parses an emote' do
15
+ m = Raibo::Message.new(":someone!someone@Nightstar-251832d1.snfc22.example.com PRIVMSG #raibo :\001ACTION foo bar baz\001")
16
+
17
+ m.kind.should == :emote
18
+ m.from.should == 'someone'
19
+ m.to.should == '#raibo'
20
+ m.body.should == 'foo bar baz'
21
+ end
22
+
23
+ it 'parses a join' do
24
+ m = Raibo::Message.new(":someone!someone@Nightstar-251832d1.snfc22.example.com JOIN :#raibo")
25
+
26
+ m.kind.should == :join
27
+ m.from.should == 'someone'
28
+ m.to.should == nil
29
+ m.body.should == nil
30
+ end
31
+
32
+ it 'parses a part' do
33
+ m = Raibo::Message.new(":someone!someone@Nightstar-251832d1.snfc22.example.com PART #raibo")
34
+
35
+ m.kind.should == :part
36
+ m.from.should == 'someone'
37
+ m.to.should == nil
38
+ m.body.should == nil
39
+ end
40
+
41
+ it 'parses an arbitrary line' do
42
+ m = Raibo::Message.new(":Deepthought.NY.US.Nightstar.Net 255 Raibo :I have 83 clients and 1 servers")
43
+ m.kind.should == nil
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,2 @@
1
+ require 'rubygems'
2
+ require 'raibo'
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raibo
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
5
+ version: 0.0.2
11
6
  platform: ruby
12
7
  authors:
13
8
  - Ryan Fitzgerald
@@ -15,15 +10,15 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-07-12 00:00:00 -07:00
13
+ date: 2011-07-17 00:00:00 -07:00
19
14
  default_executable:
20
15
  dependencies: []
21
16
 
22
17
  description: ""
23
18
  email:
24
19
  - rwfitzge@gmail.com
25
- executables: []
26
-
20
+ executables:
21
+ - raibo
27
22
  extensions: []
28
23
 
29
24
  extra_rdoc_files: []
@@ -32,10 +27,16 @@ files:
32
27
  - .gitignore
33
28
  - Gemfile
34
29
  - Rakefile
30
+ - bin/raibo
31
+ - example/example_module.rb
35
32
  - lib/raibo.rb
33
+ - lib/raibo/bot.rb
36
34
  - lib/raibo/connection.rb
35
+ - lib/raibo/message.rb
37
36
  - lib/raibo/version.rb
38
37
  - raibo.gemspec
38
+ - spec/message_spec.rb
39
+ - spec/spec_helper.rb
39
40
  has_rdoc: true
40
41
  homepage: ""
41
42
  licenses: []
@@ -50,25 +51,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
50
51
  requirements:
51
52
  - - ">="
52
53
  - !ruby/object:Gem::Version
53
- hash: 3
54
- segments:
55
- - 0
56
54
  version: "0"
57
55
  required_rubygems_version: !ruby/object:Gem::Requirement
58
56
  none: false
59
57
  requirements:
60
58
  - - ">="
61
59
  - !ruby/object:Gem::Version
62
- hash: 3
63
- segments:
64
- - 0
65
60
  version: "0"
66
61
  requirements: []
67
62
 
68
63
  rubyforge_project: raibo
69
- rubygems_version: 1.5.1
64
+ rubygems_version: 1.5.2
70
65
  signing_key:
71
66
  specification_version: 3
72
67
  summary: A simple IRC library
73
- test_files: []
74
-
68
+ test_files:
69
+ - spec/message_spec.rb
70
+ - spec/spec_helper.rb