Class: Spunk::Bot

Inherits:
Object
  • Object
show all
Defined in:
lib/spunk/bot.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Bot

Returns a new instance of Bot.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/spunk/bot.rb', line 9

def initialize(options = {})
  options.each do |option, value|
    instance_variable_set("@#{option}", value)
  end
  @token = options[:token] || nil
  @ssl = options[:ssl] || false
  @processors =  []
  @request_processors = []
  @response_processors = []
  @joined_rooms = []
  @hostname = Socket.gethostname
  @server ||= { :hostname => options[:hostname] || "localhost", :port => options[:port] || 6667 }
  add_request_processor(Spunk::Processor::Ping.new)
  add_request_processor(Spunk::Processor::Base.new)
  @rooms = options[:rooms] ||= []
end

Instance Attribute Details

#hostnameObject (readonly)

Returns the value of attribute hostname.



7
8
9
# File 'lib/spunk/bot.rb', line 7

def hostname
  @hostname
end

#joined_roomsObject

Returns the value of attribute joined_rooms.



6
7
8
# File 'lib/spunk/bot.rb', line 6

def joined_rooms
  @joined_rooms
end

#nicknameObject

Returns the value of attribute nickname.



6
7
8
# File 'lib/spunk/bot.rb', line 6

def nickname
  @nickname
end

#processorsObject (readonly)

Returns the value of attribute processors.



7
8
9
# File 'lib/spunk/bot.rb', line 7

def processors
  @processors
end

#request_processorsObject (readonly)

Returns the value of attribute request_processors.



7
8
9
# File 'lib/spunk/bot.rb', line 7

def request_processors
  @request_processors
end

#response_processorsObject (readonly)

Returns the value of attribute response_processors.



7
8
9
# File 'lib/spunk/bot.rb', line 7

def response_processors
  @response_processors
end

#roomsObject

Returns the value of attribute rooms.



6
7
8
# File 'lib/spunk/bot.rb', line 6

def rooms
  @rooms
end

#serverObject

Returns the value of attribute server.



6
7
8
# File 'lib/spunk/bot.rb', line 6

def server
  @server
end

#sslObject

Returns the value of attribute ssl.



6
7
8
# File 'lib/spunk/bot.rb', line 6

def ssl
  @ssl
end

#tokenObject

Returns the value of attribute token.



6
7
8
# File 'lib/spunk/bot.rb', line 6

def token
  @token
end

Instance Method Details

#add_processor(processor = nil, &block) ⇒ Object



113
114
115
# File 'lib/spunk/bot.rb', line 113

def add_processor(processor = nil, &block)
  @processors << (processor || block)
end

#add_request_processor(processor = nil, &block) ⇒ Object



105
106
107
# File 'lib/spunk/bot.rb', line 105

def add_request_processor(processor = nil, &block)
  @request_processors << (processor || block)
end

#add_response_processor(processor = nil, &block) ⇒ Object



109
110
111
# File 'lib/spunk/bot.rb', line 109

def add_response_processor(processor = nil, &block)
  @response_processors << (processor || block)
end

#authenticateObject



134
135
136
137
138
139
140
# File 'lib/spunk/bot.rb', line 134

def authenticate
  unless @token.nil?
    send_message "PASS #{@token}"
  end
  send_message "NICK #{@nickname}"
  send_message "USER #{@username} #{@hostname} bla :#{@fullname}"
end

#connectObject



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/spunk/bot.rb', line 117

def connect
  @socket = TCPSocket.new(@server[:hostname], @server[:port])
  if @ssl == true
    @ssl_context = OpenSSL::SSL::SSLContext.new()
    @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
    @socket = OpenSSL::SSL::SSLSocket.new(@socket, @ssl_context)
    @socket.sync_close = true
    @socket.connect
  end
  trap("INT") do
    @socket.close
  end
  trap("KILL") do
    @socket.close
  end
end

#join_room(room, password = nil) ⇒ Object



142
143
144
145
146
# File 'lib/spunk/bot.rb', line 142

def join_room(room, password = nil)
  @joined_rooms << room
  @joined_rooms.uniq!
  send_message("JOIN #{room}" + (password ? " #{password}" : ""))
end

#originObject



101
102
103
# File 'lib/spunk/bot.rb', line 101

def origin
  @origin ||= Origin.new("#{@nickname}!#{@username}@#{@hostname}")
end

#parse_message(message) ⇒ Object



63
64
65
66
67
68
69
70
71
72
# File 'lib/spunk/bot.rb', line 63

def parse_message(message)
  prefix, message = if message =~ /^\:([^\ ]*) (.*)/
    message.scan(/^\:([^\ ]*) (.*)/)[0]
  else
    [ nil, message ]
  end

  command, parameters = message.split(/\:/, 2)
  [ prefix, command, parameters ].map! { |s| s && s.strip }
end

#process_request(prefix, command, parameters) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/spunk/bot.rb', line 74

def process_request(prefix, command, parameters)
  origin = if !prefix.nil? && prefix != ""
    Origin.new(prefix)
  end

  (@request_processors + @processors).each do |processor|
    begin
      processor.call(self, origin, command, parameters)
    rescue => e
      puts e.class.name + ": " + e.message
      puts e.backtrace.join("\n")
    end
  end
end

#process_response(origin, command, parameters) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/spunk/bot.rb', line 89

def process_response(origin, command, parameters)
  (@response_processors + @processors).each do |processor|
    begin
      processor.call(self, origin, command, parameters)
    rescue => e
      puts e.class.name + ": " + e.message
      puts e.backtrace.join("\n")
    end
  end
  @socket.print("#{command} :#{parameters}\r\n")
end

#runObject



58
59
60
61
# File 'lib/spunk/bot.rb', line 58

def run
  setup_connection
  start
end

#say(to, message) ⇒ Object



148
149
150
# File 'lib/spunk/bot.rb', line 148

def say(to, message)
  send_message "PRIVMSG #{to} :#{message}"
end

#send_message(message) ⇒ Object



152
153
154
155
# File 'lib/spunk/bot.rb', line 152

def send_message(message)
  command, parameters = message.strip.split(/\:/, 2)
  process_response(origin, command.to_s.strip, parameters)
end

#setup_connectionObject



52
53
54
55
56
# File 'lib/spunk/bot.rb', line 52

def setup_connection
  connect
  authenticate
  @rooms.each { |room| join_room room }
end

#startObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/spunk/bot.rb', line 26

def start
  loop do
    @buffer ||= ""
    if @ssl
      @buffer += @socket.gets
    else
      @buffer += @socket.recv(1024)
    end
    messages = @buffer.split(/\r|\n/).collect { |s| s != "" && !s.nil? ? s : nil }.compact
    if messages.any?
      last_character = @buffer[-1..-1]
      @buffer = if ["\n", "\r"].include?(last_character)
        ""
      else
        messages.pop.to_s
      end

      messages.each do |message|
        message.strip!
        process_request(*parse_message(message))
      end
    end
    sleep 0.25
  end
end