Class: Dragoon::Bot

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Color
Defined in:
lib/dragoon.rb

Constant Summary collapse

SAMPLE_CONFIG =
File.expand_path("#{File.dirname(__FILE__)}/../sample_config")
CONFIG_FILE =
File.expand_path("~/.dragoon")

Constants included from Color

Color::COLORED_REGEXP, Color::COLOR_LIST

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Color

#colorize, #highlight, #highlight_keywords, #next_color

Constructor Details

#initializeBot

Returns a new instance of Bot.



30
31
32
33
34
# File 'lib/dragoon.rb', line 30

def initialize
  @event_manager = EventManager.new
  load_config
  init_callbacks
end

Instance Attribute Details

#keywordsObject

Returns the value of attribute keywords.



23
24
25
# File 'lib/dragoon.rb', line 23

def keywords
  @keywords
end

#networksObject

Returns the value of attribute networks.



23
24
25
# File 'lib/dragoon.rb', line 23

def networks
  @networks
end

#nicknameObject

Returns the value of attribute nickname.



23
24
25
# File 'lib/dragoon.rb', line 23

def nickname
  @nickname
end

Instance Method Details

#connect(network) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/dragoon.rb', line 146

def connect(network)
  log "*** Connecting to #{network.name} on port #{network.port}"
  TCPSocket.new(network.name, network.port)
rescue => e
  log "#{e.class} Cannot connect to #{network.name} at port #{network.port}".red
  raise
end

#init_callbacksObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/dragoon.rb', line 59

def init_callbacks
  on :startup do |msg, source|
    log msg.text
    if msg.text =~ /.*Found your hostname.*/
      # login
      source.socket.write "PASS #{@password}\r\n" if !@password.empty?
      source.socket.write "USER #{@nickname} #{@hostname} #{@servername} #{@nickname}\r\n"
      source.socket.write "NICK #{@nickname}\r\n"
    end
  end

  on :ping do |msg, source|
    source.socket.write "PONG #{msg.server}\r\n" # keep alive
  end

  on :welcome do |msg, source|
    log "*** Logged in on #{source.name} as #{msg.nickname}"

    source.channels.each do |channel|
      source.socket.write "JOIN #{channel}\r\n"
    end
  end

  on :join do |msg, source|
    log "*** Listening on channel #{colorize(msg.channel)}" if @nickname == msg.nickname
  end

  on :err do |msg, source|
    unless ['470', '422'].include?(msg.error_code) # ignore channel forwarding + motd file missing
      $stderr.puts msg.text.red
    end

    if msg.error_code == '433' # nick already in use
      print("Enter another nickname: ")
      @nickname = gets.chomp
      print("Enter password (optional): ")
      @password = gets.chomp
      source.socket.write "PASS #{@password}\r\n" if !@password.empty?
      source.socket.write "USER #{@nickname} #{@hostname} #{@servername} #{@nickname}\r\n"
      source.socket.write "NICK #{@nickname}\r\n"
    end
  end

  on :privmsg do |msg, source|
    if growlnotify_supported? && growl_running?
      if keyword = @keywords.detect { |keyword| msg.text.include?(keyword) }
        system("growlnotify " +
               "-t \"#{msg.receiver} - #{keyword}\" " +
               "-m \"#{msg.privmsg.escape_double_quotes}\"")
      end
    end
    log "#{colorize(msg.receiver)}  <#{msg.nickname}>  #{highlight_keywords(msg.privmsg,@keywords)}"
  end
end

#listen(sockets) ⇒ Object

should pass an array of sockets



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/dragoon.rb', line 132

def listen(sockets)
  read_fds, write_fds, error_fds = IO.select(sockets, nil, nil, nil)
  read_fds.each do |socket|
    line = socket.gets
    @event = Event.parse(line)
    dispatch(@event,
      @networks.select{ |n|
        n.server == socket.peeraddr[2] &&
        n.port == socket.peeraddr[1]
      }.first
    )
  end
end

#load_configObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/dragoon.rb', line 36

def load_config
  begin
    if File.exist?(CONFIG_FILE)
      log("*** Loading config file #{CONFIG_FILE}")
      config = HashWithIndifferentAccess.new JSON.parse(File.read(CONFIG_FILE))
      @nickname = config[:nickname]
      @password = config[:password]
      @hostname = config[:hostname]
      @servername = config[:servername]
      @networks = config[:networks].map { |n| Network.new(n) }
      @keywords = config[:keywords]
    else
      File.open(CONFIG_FILE,'w+') {|f| f.write(File.read(SAMPLE_CONFIG)) }
      log("Config file does not exist...created a default one at #{CONFIG_FILE}".red)
      log("Please modify it according to your preference".red)
      exit 1
    end
  rescue => e
    $stderr.puts e.message
    exit 1
  end
end

#runObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/dragoon.rb', line 114

def run
  log "*** Press Ctrl + c to stop the program"
  sockets = []
  @networks.each do |network|
    socket = connect(network)
    network.server = socket.peeraddr[2]
    network.socket = socket
    sockets << socket
  end

  begin
    while true; listen(sockets); end
  rescue Interrupt
    stop
  end
end

#stopObject



154
155
156
157
158
159
# File 'lib/dragoon.rb', line 154

def stop
  puts
  log "*** Program stopped"
  @networks.each { |network| network.socket.close }
  exit
end