Files
2025-06-29 19:05:15 +02:00

150 lines
4.2 KiB
Ruby
Executable File

#!/usr/bin/env ruby
require "ircinch"
require "sinatra"
require "yaml"
require "json"
require "net/http"
config_file = ARGV.shift || "config.yml"
if not File.exists? config_file
puts "Can't find config file #{config_file}"
puts "Either create it or specify another config file with: #{File.basename $0} [filename]"
exit
end
$config = YAML.load_file config_file
$secret = $config["env"]["secret"]
$bot = Cinch::Bot.new do
configure do |c|
c.nick = $config["irc"]["nick"]
c.user = "Scummette"
c.realname = "Razor"
c.server = $config["irc"]["server"]
c.port = $config["irc"]["port"]
c.password = $config["irc"]["password"]
c.channels = $config["irc"]["channels"]
c.ping_interval = 120
c.timeouts.read = 480
end
end
Thread.new do
$bot.start
end
def verify_signature(payload_body, github_signature)
signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), $secret, payload_body)
github_signature = "" if github_signature.nil?
return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, github_signature)
end
def say(repo,msg)
$config["irc"]["channels"].each do |chan|
unless $config["filters"].include? chan and not $config["filters"][chan].include? repo
$bot.Channel(chan).send msg
end
end
end
def join()
$config["irc"]["channels"].each do |chan|
unless $config["filters"].include? chan and not $config["filters"][chan].include? repo
$bot.join(chan)
end
end
end
def part()
$config["irc"]["channels"].each do |chan|
unless $config["filters"].include? chan and not $config["filters"][chan].include? repo
$bot.part(chan)
end
end
end
configure do
set :bind, $config["http"]["host"]
set :port, $config["http"]["port"]
set :host_authorization, { permitted_hosts: [] }
set :logging, false
set :lock, true
end
get "/" do
"GitBot lives here. Direct your hooks to /github."
end
post "/github" do
request.body.rewind
payload_body = request.body.read
verify_signature(payload_body, request.env['HTTP_X_HUB_SIGNATURE'])
$bot.nick = $config["irc"]["nick"]
eventType = request.env['HTTP_X_GITHUB_EVENT']
push = JSON.parse(params[:payload])
repo = push["repository"]["name"]
sender = push["sender"]["login"]
case eventType
when "pull_request"
return halt 200 unless ["opened", "closed", "reopened"].include?(push["action"])
res = Net::HTTP.post_form(URI('https://is.gd/create.php'), { 'format' => 'simple', 'url' => push["pull_request"]["html_url"] })
case res
when Net::HTTPSuccess, Net::HTTPRedirection
url = res.body
say repo, "[%s] %s %s pull request #%s: %s (%s) %s" % [
$bot.Format(:purple, repo),
sender,
$bot.Format(:bold, push["action"]),
$bot.Format(:bold, push["number"].to_s),
push["pull_request"]["title"],
$bot.Format(:purple, "%s...%s" % [
push["pull_request"]["base"]["ref"],
push["pull_request"]["head"]["ref"]
]),
$bot.Format(:aqua, $bot.Format(:underline, url))
]
else
# Post Failed i.e. 502
# FIXME: do say with error message? i.e. res.value
end
when "push"
res = Net::HTTP.post_form(URI('https://is.gd/create.php'), { 'format' => 'simple', 'url' => push["compare"] })
case res
when Net::HTTPSuccess, Net::HTTPRedirection
url = res.body
branch = push["ref"].gsub(/^refs\/heads\//,"")
numberOfCommits = push["commits"].length
forced = push["forced"]
say repo, "[%s] %s %s %s new commits to %s: %s" % [
$bot.Format(:purple, repo),
sender,
forced ? "force pushed" : "pushed",
$bot.Format(:bold, numberOfCommits.to_s),
$bot.Format(:purple, branch),
$bot.Format(:aqua, $bot.Format(:underline, url))
]
push["commits"][0..2].each do |c|
say repo, "%s/%s %s %s: %s" % [
$bot.Format(:purple, repo),
$bot.Format(:purple, branch),
$bot.Format(:grey, c["id"].slice(0..6)),
c["author"]["username"],
c["message"].split("\n")[0]
]
end
else
# Post Failed i.e. 502
# FIXME: do say with error message? i.e. res.value
end
end
push.inspect
end