From: "Ara.T.Howard" Date: 2005-11-04T14:27:49+09:00 Subject: [SCRIPT] auto rubyforge releasing this is one of the ugliest, but most useful, things i've written in a while. thought someone else might enjoy it too. save the attachment to a file named 'rubyforge'. you can then do rubyforge login rubyforge create_package package_name rubyforge add_release package_id release_name file.ext for example, i just relased a new traits lib using rubyforge login rubyforge create_package traits rubyforge add_release traits 0.8.0 traits-0.8.0.tgz rubyforge add_release traits 0.8.0 traits-0.8.0.gem you will need to customize the config section to contain your username, password, main group_id, and shortcuts for your package_ids so you can reference them by name. there are no docs and no help, but it's pretty easy reading. i'd like to do more with it but probably won't for quite a while - so, if anyone is itching for a head start on writing a rubyforge interface ;-) file: rubyforge #! /usr/bin/env ruby # # libs # $VERBOSE = nil require "getoptlong" require "enumerator" require "http-access2" # # config # config = { "username" => "username", # this must be your username "password" => "password", # this must be your password "group_id" => 1024, # this is codeforpeople. it's just a default... "package_ids" => { # configure shortcuts for your packages here "traits" => 1241, "lockfile" => 1242, }, "uri" => "http://rubyforge.org", "cookie_jar" => File::join(File::expand_path("~"), ".rubyforge.cookie_jar"), } opts = GetoptLong::new( [ "--username" , "-u" , GetoptLong::REQUIRED_ARGUMENT ] , [ "--password" , "-p" , GetoptLong::REQUIRED_ARGUMENT ] , [ "--cookie_jar" , "-c" , GetoptLong::REQUIRED_ARGUMENT ] ).enum_for.inject({}){|h,kv| h.update Hash[*kv]} username = opts['username'] || config['username'] password = opts['password'] || config['password'] cookie_jar = opts["cookie_jar"] || config['cookie_jar'] # # setup # mode = ARGV.shift abort "#{ $0 } [login|create_package (package_name)|add_package (package_id release_name release.ext)]" unless mode page, form, method = nil extheader = {} case mode when %r/login/ page = "/account/login.php" method = "post_content" form = { "return_to" => "", "form_loginname" => username, "form_pw" => password, "login" => "Login" } when %r/create_package/ page = "/frs/admin/index.php" method = "post_content" opts = GetoptLong::new( [ "--group_id" , "-g" , GetoptLong::REQUIRED_ARGUMENT ] , [ "--is_private" , "-P" , GetoptLong::REQUIRED_ARGUMENT ] ).enum_for.inject({}){|h,kv| h.update Hash[*kv]} package_name = ARGV.shift abort "#{ $0 } package_name" unless package_name group_id = opts["group_id"] || config["group_id"] is_public = opts["is_private"] ? 0 : 1 form = { "group_id" => group_id, "package_name" => package_name, "func" => "add_package", "is_public" => is_public, "submit" => "Create This Package", } when %r/add_release/ page = "/frs/admin/qrs.php" method = "post_content" opts = GetoptLong::new( [ "--group_id" , "-g" , GetoptLong::REQUIRED_ARGUMENT ] , [ "--release_date" , "-r" , GetoptLong::REQUIRED_ARGUMENT ] , [ "--type_id" , "-t" , GetoptLong::REQUIRED_ARGUMENT ] , [ "--processor_id" , "-P" , GetoptLong::REQUIRED_ARGUMENT ] , [ "--release_nots" , "-n" , GetoptLong::REQUIRED_ARGUMENT ] , [ "--release_changes" , "-a" , GetoptLong::REQUIRED_ARGUMENT ] ).enum_for.inject({}){|h,kv| h.update Hash[*kv]} package_id, release_name, userfile, ignored = ARGV abort "#{ $0 } package_name" unless package_id and release_name and userfile package_id = config["package_ids"][package_id] unless package_id =~ %r/^\d+$/ group_id = opts["group_id"] || config["group_id"] release_date = opts["release_date"] || Time::now.strftime('%Y-%m-%d %H:%M') type_id = opts['type_id'] || userfile[%r|\.[^\./]+$|] type_id = { ".deb" => 1000, ".rpm" => 2000, ".zip" => 3000, ".bz2" => 3100, ".gz" => 3110, ".src.zip" => 5000, ".src.bz2" => 5010, ".src.gz" => 5020, ".src.rpm" => 5100, ".src" => 5900, ".jpg" => 8000, ".txt" => 8100, ".text" => 8100, ".htm" => 8200, ".html" => 8200, ".pdf" => 8300, ".oth" => 9999, ".ebuild" => 1300, ".exe" => 1100, ".dmg" => 1200, ".tar.gz" => 5000, ".tgz" => 5000, ".gem" => 1400, ".pgp" => 8150, ".sig" => 8150, }[type_id] processor_id = opts['processor_id'] || 'Any' processor_id = { "i386" => 1000, "IA64" => 6000, "Alpha" => 7000, "Any" => 8000, "PPC" => 2000, "MIPS" => 3000, "Sparc" => 4000, "UltraSparc" => 5000, "Other" => 9999, }[processor_id] release_notes = opts['release_notes'] || nil release_notes = open(release_notes) if release_notes release_changes = opts['release_changes'] || nil release_changes = open(release_changes) if release_changes userfile = open(userfile) preformatted = '1' form = { "group_id" => group_id, "package_id" => package_id, "release_name" => release_name, "release_date" => release_date, "type_id" => type_id, "processor_id" => processor_id, "preformatted" => preformatted, "userfile" => userfile, "submit" => "Release File" } boundary = Array::new(8){ "%2.2d" % rand(42) }.join('__') extheader['content-type'] = "multipart/form-data; boundary=___#{ boundary }___" else abort "#{ $0 } login create_package add_release" end # # http transaction # client = HTTPAccess2::Client::new ENV['HTTP_PROXY'] client.debug_dev = STDERR if ENV['DEBUG'] client.set_cookie_store cookie_jar # fixes http-access2 bug client.redirect_uri_callback = lambda do |res| page = res.header['location'].first page = page =~ %r/http/ ? page : "#{ config['uri'] }/#{ page }" page end response = client.send "#{ method }", "#{ config['uri'] }/#{ page }", form, extheader client.save_cookie_store # fixes http-access2 bug BEGIN { require "http-access2" module WebAgent::CookieUtils def domain_match(host, domain) case domain when /\d+\.\d+\.\d+\.\d+/ return (host == domain) when '.' return true when /^\./ #return tail_match?(domain, host) return tail_match?(host, domain) else return (host == domain) end end end } enjoy. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | anything that contradicts experience and logic should be abandoned. | -- h.h. the 14th dalai lama ===============================================================================