ghup 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/README.md +14 -0
  2. data/bin/ghup +113 -0
  3. metadata +64 -0
data/README.md ADDED
@@ -0,0 +1,14 @@
1
+ This is a script which can upload files to github from the commandline.
2
+
3
+ First you need to get a oauth token:
4
+
5
+ curl -X POST -u <github user>:<github password> \
6
+ -d '{"note":"file upload script","scopes":["repo"]}' \
7
+ https://api.github.com/authorizations
8
+
9
+ Copy the token from the response and put it into your git config file:
10
+
11
+ git config --global github.upload-script-token <the token from the response>
12
+
13
+
14
+ Now you can use this script.
data/bin/ghup ADDED
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'json'
4
+ require 'net/https'
5
+ require 'pathname'
6
+
7
+
8
+
9
+ # Extensions
10
+ # ----------
11
+
12
+ # We extend Pathname a bit to get the content type.
13
+ class Pathname
14
+ def type
15
+ flags = RUBY_PLATFORM =~ /darwin/ ? 'Ib' : 'ib'
16
+ `file -#{flags} #{realpath}`.chomp.gsub(/;.*/,'')
17
+ end
18
+ end
19
+
20
+
21
+
22
+ # Helpers
23
+ # -------
24
+
25
+ # Die if something goes wrong.
26
+ def die(msg); puts(msg); exit!(1); end
27
+
28
+ # Do a post to the given url, with the payload and optional basic auth.
29
+ def post(url, token, params, headers)
30
+ uri = URI.parse(url)
31
+
32
+ http = Net::HTTP.new(uri.host, uri.port)
33
+ http.use_ssl = true
34
+
35
+ req = Net::HTTP::Post.new(uri.path, headers)
36
+ req['Authorization'] = "token #{token}" if token
37
+
38
+ return http.request(req, params)
39
+ end
40
+
41
+ def urlencode(str)
42
+ str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0].to_i) }
43
+ end
44
+
45
+ # Yep, ruby net/http doesn't support multipart. Write our own multipart generator.
46
+ # The order of the params is important, the file needs to go as last!
47
+ def build_multipart_content(params)
48
+ parts, boundary = [], "#{rand(1000000)}-we-are-all-doomed-#{rand(1000000)}"
49
+
50
+ params.each do |name, value|
51
+ data = []
52
+ if value.is_a?(Pathname) then
53
+ data << "Content-Disposition: form-data; name=\"#{urlencode(name.to_s)}\"; filename=\"#{value.basename}\""
54
+ data << "Content-Type: #{value.type}"
55
+ data << "Content-Length: #{value.size}"
56
+ data << "Content-Transfer-Encoding: binary"
57
+ data << ""
58
+ data << value.read
59
+ else
60
+ data << "Content-Disposition: form-data; name=\"#{urlencode(name.to_s)}\""
61
+ data << ""
62
+ data << value
63
+ end
64
+
65
+ parts << data.join("\r\n") + "\r\n"
66
+ end
67
+
68
+ [ "--#{boundary}\r\n" + parts.join("--#{boundary}\r\n") + "--#{boundary}--", {
69
+ "Content-Type" => "multipart/form-data; boundary=#{boundary}"
70
+ }]
71
+ end
72
+
73
+
74
+
75
+ # Configuration and setup
76
+ # -----------------------
77
+
78
+ # Get Oauth token for this script.
79
+ token = `git config --get github.upload-script-token`.chomp
80
+
81
+ # The file we want to upload, and repo where to upload it to.
82
+ file = Pathname.new(ARGV[0])
83
+ repo = ARGV[1] || `git config --get remote.origin.url`.match(/git@github.com:(.+?)\.git/)[1]
84
+
85
+
86
+
87
+ # The actual, hard work
88
+ # ---------------------
89
+
90
+ # Register the download at github.
91
+ res = post("https://api.github.com/repos/#{repo}/downloads", token, {
92
+ 'name' => file.basename.to_s, 'size' => file.size.to_s,
93
+ 'content_type' => file.type.gsub(/;.*/, '')
94
+ }.to_json, {})
95
+
96
+ die("File already exists.") if res.class == Net::HTTPClientError
97
+ die("GitHub doens't want us to upload the file.") unless res.class == Net::HTTPCreated
98
+
99
+
100
+ # Parse the body and use the info to upload the file to S3.
101
+ info = JSON.parse(res.body)
102
+ res = post(info['s3_url'], nil, *build_multipart_content({
103
+ 'key' => info['path'], 'acl' => info['acl'], 'success_action_status' => 201,
104
+ 'Filename' => info['name'], 'AWSAccessKeyId' => info['accesskeyid'],
105
+ 'Policy' => info['policy'], 'signature' => info['signature'],
106
+ 'Content-Type' => info['mime_type'], 'file' => file
107
+ }))
108
+
109
+ die("S3 is mean to us.") unless res.class == Net::HTTPCreated
110
+
111
+
112
+ # Print the URL to the file to stdout.
113
+ puts "#{info['s3_url']}#{info['path']}"
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghup
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Tomas Carnecky
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-05-29 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description:
22
+ email:
23
+ - tomas.carnecky@gmail.com
24
+ executables:
25
+ - ghup
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - bin/ghup
32
+ - README.md
33
+ has_rdoc: true
34
+ homepage: https://github.com/wereHamster/ghup
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.6
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Commandline github upload script
63
+ test_files: []
64
+