Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

212 lines (187 sloc) 6.461 kb
# require
require 'rubygems'
#### INLINE: fixed version of https://github.com/github/upload ####
require 'tempfile'
require 'nokogiri'
require 'httpclient'
require 'stringio'
require 'json'
require 'faster_xml_simple'
module Net
module GitHub
class Upload
VERSION = '0.0.5'
def initialize params=nil
@login = params[:login]
@token = params[:token]
if @login.empty? or @token.empty?
raise "login or token is empty"
end
end
def upload info
unless info[:repos]
raise "required repository name"
end
info[:repos] = @login + '/' + info[:repos] unless info[:repos].include? '/'
if info[:file]
file = info[:file]
unless File.exist?(file) && File.readable?(file)
raise "file does not exsits or readable"
end
info[:name] ||= File.basename(file)
end
unless info[:file] || info[:data]
raise "required file or data parameter to upload"
end
unless info[:name]
raise "required name parameter for filename with data parameter"
end
if info[:replace]
list_files(info[:repos]).each { |obj|
next unless obj[:name] == info[:name]
delete info[:repos], obj[:id]
}
elsif list_files(info[:repos]).any?{|obj| obj[:name] == info[:name]}
raise "file '#{info[:name]}' is already uploaded. please try different name"
end
info[:content_type] ||= 'application/octet-stream'
stat = HTTPClient.post("https://github.com/#{info[:repos]}/downloads", {
"file_size" => info[:file] ? File.stat(info[:file]).size : info[:data].size,
"content_type" => info[:content_type],
"file_name" => info[:name],
"description" => info[:description] || '',
"login" => @login,
"token" => @token
})
unless stat.code == 200
raise "Failed to post file info"
end
upload_info = JSON.parse(stat.content)
if info[:file]
f = File.open(info[:file], 'rb')
else
f = Tempfile.open('net-github-upload')
f << info[:data]
f.flush
end
stat = HTTPClient.post("http://github.s3.amazonaws.com/", [
['Filename', info[:name]],
['policy', upload_info['policy']],
['success_action_status', 201],
['key', upload_info['path']],
['AWSAccessKeyId', upload_info['accesskeyid']],
['Content-Type', upload_info['content_type'] || 'application/octet-stream'],
['signature', upload_info['signature']],
['acl', upload_info['acl']],
['file', f]
])
f.close
if stat.code == 201
return FasterXmlSimple.xml_in(stat.content)['PostResponse']['Location']
else
raise 'Failed to upload' + extract_error_message(stat)
end
end
def replace info
upload info.merge( :replace => true )
end
def delete_all repos
unless repos
raise "required repository name"
end
repos = @login + '/' + repos unless repos.include? '/'
list_files(repos).each { |obj|
delete repos, obj[:id]
}
end
private
def extract_error_message(stat)
# @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/ErrorResponses.html
error = FasterXmlSimple.xml_in(stat.content)['Error']
" due to #{error['Code']} (#{error['Message']})"
rescue
''
end
def delete repos, id
HTTPClient.post("https://github.com/#{repos}/downloads/#{id.gsub( "download_", '')}", {
"_method" => "delete",
"login" => @login,
"token" => @token
})
end
def list_files repos
raise "required repository name" unless repos
res = HTTPClient.get_content("https://github.com/#{repos}/downloads", {
"login" => @login,
"token" => @token
})
Nokogiri::HTML(res).xpath('id("manual_downloads")/li').map do |fileinfo|
obj = {
:description => fileinfo.at_xpath('descendant::h4').text,
:date => fileinfo.at_xpath('descendant::p/time').attribute('title').text,
:size => fileinfo.at_xpath('descendant::p/strong').text,
:id => /\d+$/.match(fileinfo.at_xpath('a').attribute('href').text)[0]
}
anchor = fileinfo.at_xpath('descendant::h4/a')
obj[:link] = anchor.attribute('href').text
obj[:name] = anchor.text
obj
end
end
end
end
end
#### END INLINE ####
# setup
login = `git config github.user`.chomp # your login for github
token = `git config github.token`.chomp # your token for github
repos = 'KentBeck/junit' # your repos name (like 'taberareloo')
gh = Net::GitHub::Upload.new(
:login => login,
:token => token
)
version = ARGV[0]
def upload(gh, version, repos, filename, description)
gh.upload(:repos => repos,
:file => "junit#{version}/#{filename}",
:description => description)
end
upload(gh, version, repos, "junit-#{version}-src.jar", 'Source jar')
upload(gh, version, repos, "junit-#{version}.jar", 'Basic jar')
upload(gh, version, repos, "junit-dep-#{version}.jar", 'Jar without hamcrest')
upload(gh, version, repos, "junit#{version}.zip", 'Source zip')
# # file upload
# direct_link = gh.upload(
# :repos => repos,
# :file => 'test/test',
# :description => "test file"
# )
# # direct link is link to Amazon S3.
# # Because GitHub refrection for file changing is async,
# # if you get changed file synchronously, you use this "direct_link"
#
# # data upload
# # you can define content_type => Amazon S3 Content-Type
# time = Time.now.to_i
# direct_link = gh.upload(
# :repos => repos,
# :data => 'test',
# :name => "test_#{time}.txt",
# :content_type => 'text/plain',
# :description => "test file2"
# )
#
# # replace file or data
# # thx id:rngtng !
# direct_link = gh.replace(
# :repos => repos,
# :file => 'test/test',
# :description => "test file"
# )
# direct_link = gh.replace(
# :repos => repos,
# :data => 'test',
# :name => "test_#{time}.txt",
# :content_type => 'text/plain',
# :description => "test file2"
# )
Jump to Line
Something went wrong with that request. Please try again.