|
read -d '' RUBY_SCRIPT <<"EOF" |
|
require 'socket' |
|
require 'open-uri' |
|
require 'json' |
|
|
|
Channel = Struct.new(:name, :key) |
|
|
|
# YOU MAY EDIT BELOW # |
|
|
|
EVENTS = %w(successful failed) |
|
IRC_INFO = { |
|
server: 'irc.example.com', |
|
port: 6667, |
|
nickname: 'MyBotName', |
|
password: nil, |
|
username: nil, |
|
ircname: nil |
|
} |
|
IRC_OPTIONS = { |
|
join_channels: [ |
|
Channel.new('#somechannel', nil) # (name, key) leave key as nil if none |
|
], |
|
send_channels: %w(#somechannel #otherchannel), |
|
notice: false # Send notices instead of privmsgs |
|
} |
|
|
|
# YOU MAY NOT EDIT BELOW # |
|
|
|
IRC_COLORS = { |
|
bold: "\\x02", |
|
blue: "\\x0302", |
|
green: "\\x0303", |
|
red: "\\x0304", |
|
reset: "\\x03" |
|
} |
|
|
|
STATE_COLORS = { |
|
successful: IRC_COLORS[:green], |
|
failed: IRC_COLORS[:red], |
|
unknown: IRC_COLORS[:blue] |
|
} |
|
|
|
class Client |
|
@socket = nil |
|
|
|
def initialize(hostname: raise(ArgumentError), port: raise(ArgumentError), nickname: raise(ArgumentError), username: nil, password: nil) |
|
# noinspection RubyResolve |
|
@socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM) |
|
@socket.connect(Socket.pack_sockaddr_in(port, hostname)) |
|
unless password.nil? |
|
self.send_line("PASS #{password}") |
|
end |
|
self.send_line("NICK #{nickname}") |
|
self.send_line("USER #{username.nil? ? nickname : username} localhost #{hostname} #{nickname}") |
|
self.wait_for([375, 422]) |
|
end |
|
|
|
def wait_for(codes) |
|
while true |
|
split = self.recv_line.split(' ') |
|
break if split.size > 1 && self.is_numeric(split[1]) && codes.include?(Integer(split[1])) |
|
end |
|
end |
|
|
|
def recv_line |
|
line = '' |
|
while line.length < 1 || line[-1] != "\\n" |
|
line += @socket.read(1) |
|
end |
|
line |
|
end |
|
|
|
def join(target, key: nil) |
|
self.send_line("JOIN #{target}#{key == nil ? '' : ' ' + key}") |
|
self.wait_for([331, 332, 353, 366, 461, 474, 473, 475, 471, 476, 403, 405]) |
|
end |
|
|
|
def privmsg(target, message) |
|
self.send_line("PRIVMSG #{target} :#{message}") |
|
end |
|
|
|
def notice(target, message) |
|
self.send_line("NOTICE #{target} :#{message}") |
|
end |
|
|
|
def quit(message: '') |
|
self.send_line("QUIT#{message == '' ? message : ' ' + message}") |
|
sleep(1) |
|
end |
|
|
|
def send_line(line) |
|
return unless line.is_a?(String) |
|
line += "\\r\\n" |
|
@socket.write(line) |
|
end |
|
|
|
def close |
|
@socket.close |
|
end |
|
|
|
def is_numeric(thing) |
|
true if Integer(thing) rescue false |
|
end |
|
end |
|
|
|
def get_state_color(state) |
|
state = state.downcase.to_sym |
|
STATE_COLORS.include?(state) ? STATE_COLORS[state] : '' |
|
end |
|
|
|
def shorten_link(link) |
|
open("http://is.gd/create.php?format=simple&url=#{URI::encode(link)}").read.sub(/\\r?\\n/, '') |
|
end |
|
|
|
if ARGV.size < 2 |
|
puts 'You have set up the IRC notification script wrong.' |
|
exit 1 |
|
end |
|
|
|
RESULTS_URL = ARGV[0] |
|
API_URL = RESULTS_URL.sub('/browse/', '/rest/api/latest/result/') |
|
PLAN_KEY = ARGV[1] |
|
BUILD_NUMBER = API_URL.split('-')[-1] |
|
BUILD_URL = RESULTS_URL.split('/')[0..-2].join('/') + "/#{PLAN_KEY}-#{BUILD_NUMBER}" |
|
SHORTENED_BUILD_URL = shorten_link(BUILD_URL) |
|
|
|
info_url = API_URL.split('/')[0..-2].join('/') + "/#{PLAN_KEY}-#{BUILD_NUMBER}?expand=stages" |
|
j = JSON.parse(open(info_url, 'Accept' => 'application/json').read) |
|
exit 1 unless j.include?('stages') |
|
stages = j['stages'] |
|
size = stages['size'] - 1 |
|
exit 1 if size < 1 |
|
|
|
messages = [ |
|
"Plan #{IRC_COLORS[:bold]}#{j['planName']}#{IRC_COLORS[:bold]} build results – #{SHORTENED_BUILD_URL}" |
|
] |
|
|
|
(0..size - 1).each { |i| |
|
stage = stages['stage'][i] |
|
next unless EVENTS.include?(stage['state'].downcase) |
|
sc = get_state_color(stage['state']) |
|
messages.push("Stage #{IRC_COLORS[:bold]}#{stage['name']}#{IRC_COLORS[:bold]} finished with status #{sc}#{stage['state']}#{IRC_COLORS[:reset]}.") |
|
} |
|
c = Client.new(hostname: IRC_INFO[:server], port: IRC_INFO[:port], nickname: IRC_INFO[:nickname], password: IRC_INFO[:password]) |
|
IRC_OPTIONS[:join_channels].each { |ch| |
|
c.join(ch.name, key: ch.key) |
|
} |
|
IRC_OPTIONS[:send_channels].each { |ch| |
|
messages.each { |msg| |
|
if IRC_OPTIONS[:notice] |
|
c.notice(ch, msg) |
|
else |
|
c.privmsg(ch, msg) |
|
end |
|
} |
|
} |
|
c.quit(message: 'Bamboo IRC') |
|
c.close |
|
EOF |
|
|
|
/usr/local/bin/ruby -e "${RUBY_SCRIPT}" $@ |