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.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/spunk/bot.rb', line 10

def initialize(options = {})
  options.each do |option, value|
    instance_variable_set("@#{option}", value)
  end
  @token = options[:token] ||= nil
  @ssl = options[:ssl] ||= false
  if options[:invite_ok].nil?
    options[:invite_ok] = true
  end
  @invite_ok = options[:invite_ok]
  @nickserv_password = options[:nickserv_password]
  @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] ||= []
  if options[:logger].class == String
    @logger = Logger.new(options[:logger])
    @logger.level = Logger::INFO
  elsif options[:logger].nil?
    @logger = Logger.new(STDOUT)
    @logger.level = Logger::INFO
  elsif options[:logger].class == Hash
    @logger = Logger.new(options[:logger][:file])
    @logger.level = options[:logger][:level] ||= Logger::INFO
  elsif options[:logger].class == Logger
    @logger = options[:logger]
  end
end

Instance Attribute Details

#hostnameObject (readonly)

Returns the value of attribute hostname.



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

def hostname
  @hostname
end

#invite_okObject

Returns the value of attribute invite_ok.



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

def invite_ok
  @invite_ok
end

#joined_roomsObject

Returns the value of attribute joined_rooms.



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

def joined_rooms
  @joined_rooms
end

#loggerObject

Returns the value of attribute logger.



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

def logger
  @logger
end

#nicknameObject

Returns the value of attribute nickname.



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

def nickname
  @nickname
end

#nickserv_passwordObject

Returns the value of attribute nickserv_password.



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

def nickserv_password
  @nickserv_password
end

#processorsObject (readonly)

Returns the value of attribute processors.



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

def processors
  @processors
end

#request_processorsObject (readonly)

Returns the value of attribute request_processors.



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

def request_processors
  @request_processors
end

#response_processorsObject (readonly)

Returns the value of attribute response_processors.



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

def response_processors
  @response_processors
end

#roomsObject

Returns the value of attribute rooms.



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

def rooms
  @rooms
end

#serverObject

Returns the value of attribute server.



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

def server
  @server
end

#sslObject

Returns the value of attribute ssl.



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

def ssl
  @ssl
end

#tokenObject

Returns the value of attribute token.



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

def token
  @token
end

Instance Method Details

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



134
135
136
# File 'lib/spunk/bot.rb', line 134

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

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



126
127
128
# File 'lib/spunk/bot.rb', line 126

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

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



130
131
132
# File 'lib/spunk/bot.rb', line 130

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

#authenticateObject



161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/spunk/bot.rb', line 161

def authenticate
  @logger.debug "Starting authentication section"
  unless @token.nil?
    @logger.debug "Token detected.. sending token"
    send_message "PASS #{@token}"
  end
  send_message "NICK #{@nickname}"
  send_message "USER #{@username} #{@hostname} bla :#{@fullname}"
  unless @nickserv_password.nil?
    send_message "PRIVMSG NickServ :identify #{@nickserv_password}"
  end
end

#connectObject



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/spunk/bot.rb', line 138

def connect
  @logger.info "Starting connection to #{@server[:hostname]}:#{@server[:port]}"
  begin
    @socket = TCPSocket.new(@server[:hostname], @server[:port])
  rescue
    raise SpunkException::BotException.new "Unable to establish connection"
  end
  if @ssl == true
    @logger.debug "Detected SSL connection"
    @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



174
175
176
177
178
179
# File 'lib/spunk/bot.rb', line 174

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

#originObject



122
123
124
# File 'lib/spunk/bot.rb', line 122

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

#parse_message(message) ⇒ Object



82
83
84
85
86
87
88
89
90
91
# File 'lib/spunk/bot.rb', line 82

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



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/spunk/bot.rb', line 93

def process_request(prefix, command, parameters)
  origin = if !prefix.nil? && prefix != ""
    Origin.new(prefix)
  end
  hash = Helpers.hashify(self, origin, command, parameters, @logger)
  @logger.debug "Processing request: origin=#{hash[:origin]} :: command=#{hash[:command]} :: parameters=#{hash[:parameters]}"
  (@request_processors + @processors).each do |processor|
    begin
      processor.call(hash)
    rescue => e
      puts e.class.name + ": " + e.message
      puts e.backtrace.join("\n")
    end
  end
end

#process_response(origin, command, parameters) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/spunk/bot.rb', line 109

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

#runObject



77
78
79
80
# File 'lib/spunk/bot.rb', line 77

def run
  setup_connection
  start
end

#say(to, message) ⇒ Object



181
182
183
184
185
186
# File 'lib/spunk/bot.rb', line 181

def say(to, message)
  @logger.debug "saying message: PRIVMSG #{to} :#{message}"
  unless send_message "PRIVMSG #{to} :#{message}"
    raise SpunkException::BotException.new "Unable to send message"
  end
end

#send_message(message) ⇒ Object



188
189
190
191
192
# File 'lib/spunk/bot.rb', line 188

def send_message(message)
  @logger.debug "Sending message: #{message}"
  command, parameters = message.strip.split(/\:/, 2)
  process_response(origin, command.to_s.strip, parameters)
end

#setup_connectionObject



71
72
73
74
75
# File 'lib/spunk/bot.rb', line 71

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

#startObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/spunk/bot.rb', line 44

def start
  @logger.info "Starting Bot"
  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