Created
October 10, 2008 00:40
-
-
Save francois/15953 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Released to the public domain. | |
# Original implementation by François Beausoleil <[email protected]> | |
# Use at your own risks. | |
# This script will close ALL cases that match a certain criteria. | |
# Look below for CUSTOMIZE to see what needs changing. | |
# If you didn't know, this is Ruby, and was written when 1.8.6/1.8.7 was current. | |
# This script uses curl to do it's requesting, because Ruby cannot validate FogBugz's certificate. | |
require "uri" | |
require "cgi" | |
require "rexml/document" | |
require "rexml/xpath" | |
def get(uri) | |
$last_url = " > #{uri}" | |
xml = `curl -s '#{uri}'` | |
$last_doc = REXML::Document.new(xml) | |
end | |
def first(*args) | |
REXML::XPath.first(*args) | |
end | |
def each(*args, &block) | |
REXML::XPath.each(*args, &block) | |
end | |
def match(*args) | |
REXML::XPath.match(*args) | |
end | |
class Hash | |
def to_params | |
inject([]) do |memo, (k, v)| | |
memo << "#{CGI::escape(k.to_s)}=#{CGI::escape(v.to_s)}" | |
end.join("&") | |
end | |
end | |
def request(cmd, params) | |
uri = $uri.dup | |
uri.query = params.merge("cmd" => cmd).to_params | |
get(uri) | |
end | |
# CUSTOMIZE: Set your base URL here. | |
$uri = URI.parse("https://fogbugz.com/api.xml") | |
doc = get($uri) | |
$uri = $uri.merge(first(doc.root, "//url").text) | |
puts "Real API URI: #{$uri}" | |
# CUSTOMIZE: Set your username/password here | |
token = first(request(:logon, :email => "[email protected]", :password => "BigMac").root, "//token").text | |
puts "Logon Token: #{token}" | |
begin | |
loop do | |
requested = 200 | |
count = closed = skipped = 0 | |
# CUSTOMIZE: Make a search in the UI to find exactly the cases you want, then paste the search as the :q parameter. | |
puts "\nRequesting #{requested} new cases to examine..." | |
each(request(:search, :q => "NoMethodError status:active", :max => requested, :cols => "sTitle", :token => token).root, "//case") do |bug| | |
count += 1 | |
id = bug.attribute("ixBug") | |
# CUSTOMIZE: Some of the cases that matched the first criteria were not supposed to be closed. | |
# So I filter them out here. | |
if first(bug, "//sTitle").text[/v:\d+$/] then | |
skipped += 1 | |
puts "Skipping case #{id}: #{first(bug, "//sTitle").text}" | |
else | |
# CUSTOMIZE: ixStatus 2 is "Resolved (Fixed)" | |
doc = request(:resolve, :ixBug => id, :ixStatus => "2", :token => token) | |
if first(doc.root, "//case").attribute("operations").value["close"] then | |
doc = request(:close, :ixBug => id, :sEvent => "Auto-closing case", :cols => "fOpen,sStatus", :token => token) | |
if first(doc.root, "//fOpen").text == "false" then | |
closed += 1 | |
puts "Closed case #{id}" | |
else | |
puts "Could not close case #{id}:\n#{doc}" | |
end | |
else | |
puts "Could not resolve case #{id}:\n#{doc}" | |
end | |
end | |
end | |
if skipped == count then | |
raise "Cannot continue: I had to skip all the cases before I hit a case I could close" | |
elsif closed == 0 then | |
raise "Cannot continue: I could not close any cases this time around" | |
end | |
end | |
rescue | |
$stderr.puts | |
$stderr.puts $!.message | |
$stderr.puts $!.backtrace | |
$stderr.puts "> #{$last_url}" | |
$stderr.puts $last_doc | |
ensure | |
request(:logoff, :token => token) | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment