Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

typos, also fix reading

  • Loading branch information...
commit 528ebb27f1d27688f52da74cae57e35ab3e80e53 1 parent 30613ab
Ross Boucher authored March 19, 2012
102  gist
@@ -86,14 +86,18 @@ require 'open-uri'
86 86
 require 'net/https'
87 87
 require 'optparse'
88 88
 
  89
+require 'rubygems'
  90
+require 'json'
  91
+require 'base64'
  92
+
89 93
 require 'gist/manpage' unless defined?(Gist::Manpage)
90 94
 require 'gist/version' unless defined?(Gist::Version)
91 95
 
92 96
 module Gist
93 97
   extend self
94 98
 
95  
-  GIST_URL   = 'https://gist.github.com/%s.txt'
96  
-  CREATE_URL = 'https://gist.github.com/gists'
  99
+  GIST_URL   = 'https://api.github.com/gists/%s'
  100
+  CREATE_URL = 'https://api.github.com/gists'
97 101
 
98 102
   if ENV['HTTPS_PROXY']
99 103
     PROXY = URI(ENV['HTTPS_PROXY'])
@@ -110,7 +114,7 @@ module Gist
110 114
     gist_filename = nil
111 115
     gist_extension = defaults["extension"]
112 116
     browse_enabled = defaults["browse"]
113  
-    copy = defaults["copy"]
  117
+    description = nil
114 118
 
115 119
     opts = OptionParser.new do |opts|
116 120
       opts.banner = "Usage: gist [options] [filename or stdin] [filename] ...\n" +
@@ -125,6 +129,10 @@ module Gist
125 129
         gist_extension = '.' + extension
126 130
       end
127 131
 
  132
+      opts.on('-d','--description DESCRIPTION', 'Set description of the new gist') do |d|
  133
+        description = d
  134
+      end
  135
+
128 136
       opts.on('-o','--[no-]open', 'Open gist in browser') do |o|
129 137
         browse_enabled = o
130 138
       end
@@ -142,15 +150,12 @@ module Gist
142 150
         puts opts
143 151
         exit
144 152
       end
145  
-
146  
-      opts.on('-c', '--[no-]copy', 'Copy gist URL to clipboard automatically') do |c|
147  
-        copy = c
148  
-      end
149 153
     end
150 154
 
151  
-    opts.parse!(args)
152  
-
153 155
     begin
  156
+
  157
+      opts.parse!(args)
  158
+
154 159
       if $stdin.tty? && args[0] != '-'
155 160
 
156 161
         if args.empty?
@@ -163,7 +168,7 @@ module Gist
163 168
 
164 169
           files.push({
165 170
             :input     => File.read(file),
166  
-            :filename  => File.basename(file),
  171
+            :filename  => file,
167 172
             :extension => (File.extname(file) if file.include?('.'))
168 173
           })
169 174
         end
@@ -173,17 +178,16 @@ module Gist
173 178
         files = [{:input => input, :extension => gist_extension}]
174 179
       end
175 180
 
176  
-      url = write(files, private_gist)
  181
+      url = write(files, private_gist, description)
177 182
       browse(url) if browse_enabled
178  
-      copy(url) if copy
179  
-      $stdout.tty? ? puts(url) : print(url)
  183
+      puts copy(url)
180 184
     rescue => e
181 185
       warn e
182 186
       puts opts
183 187
     end
184 188
   end
185 189
 
186  
-  def write(files, private_gist = false)
  190
+  def write(files, private_gist = false, description = nil)
187 191
     url = URI.parse(CREATE_URL)
188 192
 
189 193
     if PROXY_HOST
@@ -198,25 +202,34 @@ module Gist
198 202
     http.ca_file = ca_cert
199 203
 
200 204
     req = Net::HTTP::Post.new(url.path)
201  
-    req.form_data = data(files, private_gist)
  205
+    req.body = JSON.generate(data(files, private_gist, description))
  206
+    p req.body
  207
+
  208
+    if auth_header = auth()
  209
+      req.add_field('Authorization', auth_header)
  210
+    end
202 211
 
203 212
     response = http.start{|h| h.request(req) }
204 213
     case response
205  
-    when Net::HTTPRedirection
206  
-      response['Location']
  214
+    when Net::HTTPCreated
  215
+      JSON.parse(response.body)['html_url']
207 216
     else
  217
+      p response.body
208 218
       puts "Creating gist failed: #{response.code} #{response.message}"
209 219
       exit(false)
210 220
     end
211 221
   end
212 222
 
213 223
   def read(gist_id)
214  
-    open(GIST_URL % gist_id).read
  224
+    data = JSON.parse(open(GIST_URL % gist_id).read)
  225
+    data["files"].map{|name, content| content['content'] }.join("\n\n")
215 226
   end
216 227
 
217 228
   def browse(url)
218 229
     if RUBY_PLATFORM =~ /darwin/
219 230
       `open #{url}`
  231
+    elsif RUBY_PLATFORM =~ /linux/
  232
+       `#{ENV['BROWSER']} #{url}`
220 233
     elsif ENV['OS'] == 'Windows_NT' or
221 234
       RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw|wince/i
222 235
       `start "" "#{url}"`
@@ -241,51 +254,46 @@ module Gist
241 254
   end
242 255
 
243 256
 private
244  
-  def data(files, private_gist)
245  
-    data = {}
  257
+  def data(files, private_gist, description)
  258
+    i = 0
  259
+    file_data = {}
246 260
     files.each do |file|
247  
-      i = data.size + 1
248  
-      data["file_ext[gistfile#{i}]"]      = file[:extension] ? file[:extension] : '.txt'
249  
-      data["file_name[gistfile#{i}]"]     = file[:filename]
250  
-      data["file_contents[gistfile#{i}]"] = file[:input]
  261
+      i = i + 1
  262
+      filename = file[:filename] ? file[:filename] : "gistfile#{i}"
  263
+      file_data[filename] = {:content => file[:input]}
251 264
     end
252  
-    data.merge(private_gist ? { 'action_button' => 'private' } : {}).merge(auth)
  265
+
  266
+    data = {"files" => file_data}
  267
+    data.merge!({ 'description' => description }) unless description.nil?
  268
+    data.merge!({ 'public' => false }) if private_gist
  269
+    data
253 270
   end
254 271
 
255 272
   def auth
256 273
     user  = config("github.user")
257  
-    token = config("github.token")
  274
+    password = config("github.password")
258 275
 
259  
-    if user.to_s.empty? || token.to_s.empty?
260  
-      {}
  276
+    if user.to_s.empty? || password.to_s.empty?
  277
+      nil
261 278
     else
262  
-      { :login => user, :token => token }
  279
+      auth_str = Base64.encode64("#{user}:#{password}")
  280
+      "Basic #{auth_str}"
263 281
     end
264 282
   end
265 283
 
266 284
   def defaults
267 285
     extension = config("gist.extension")
268  
-    extension = nil if extension && extension.empty?
269  
-    
270  
-    copy = config("gist.copy")
271  
-    if copy.nil?
272  
-      copy = true
273  
-    else
274  
-      # match optparse boolean true states
275  
-      copy = copy =~ /^(true)|(on)|(\+)/
276  
-    end
277 286
 
278 287
     return {
279 288
       "private"   => config("gist.private"),
280 289
       "browse"    => config("gist.browse"),
281  
-      "extension" => extension,
282  
-      "copy"      => copy,
  290
+      "extension" => extension
283 291
     }
284 292
   end
285 293
 
286 294
   def config(key)
287 295
     env_key = ENV[key.upcase.gsub(/\./, '_')]
288  
-    return env_key if env_key and not env_key.empty?
  296
+    return env_key if env_key and not env_key.strip.empty?
289 297
 
290 298
     str_to_bool `git config --global #{key}`.strip
291 299
   end
@@ -330,7 +338,7 @@ __END__
330 338
 .\" generated with Ronn/v0.7.3
331 339
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
332 340
 .
333  
-.TH "GIST" "1" "April 2011" "GITHUB" "Gist Manual"
  341
+.TH "GIST" "1" "June 2011" "GITHUB" "Gist Manual"
334 342
 .
335 343
 .SH "NAME"
336 344
 \fBgist\fR \- gist on the command line
@@ -348,7 +356,7 @@ If standard input is supplied, it will be used as the content of the new gist\.
348 356
 Once your gist is successfully created, the URL will be copied to your clipboard\. If you are on OS X, \fBgist\fR will open the gist in your browser, too\.
349 357
 .
350 358
 .SH "OPTIONS"
351  
-\fBgist\fR\'s default mode of operation is to read content from standard input and create a public, text gist from it, tied to your GitHub account if you user and token are provided (see \fBCONFIGURATION\fR)\.
  359
+\fBgist\fR\'s default mode of operation is to read content from standard input and create a public, text gist without description from it, tied to your GitHub account if you user and token are provided (see \fBCONFIGURATION\fR)\.
352 360
 .
353 361
 .P
354 362
 These options can be used to change this behavior:
@@ -359,7 +367,11 @@ Create a private gist instead of a public gist\.
359 367
 .
360 368
 .TP
361 369
 \fB\-t\fR, \fB\-\-type\fR
362  
-Set the file extension explicitly\. Passing a type of \fBrb\fR ensure the gist is created as a Ruby file\.
  370
+Set the file extension explicitly\. Passing a type of \fBrb\fR ensures the gist is created as a Ruby file\.
  371
+.
  372
+.TP
  373
+\fB\-d\fR, \fB\-\-description\fR
  374
+Set a description\.
363 375
 .
364 376
 .TP
365 377
 \fB\-o\fR, \fB\-\-[no\-]open\fR
@@ -380,7 +392,7 @@ Display this man page\.
380 392
 There are two ways to set GitHub user and token info:
381 393
 .
382 394
 .IP "\(bu" 4
383  
-Using env vars GITHUB_USER and GITHUB_TOKEN
  395
+Using environment vars GITHUB_USER and GITHUB_TOKEN
384 396
 .
385 397
 .IP
386 398
 $ export GITHUB_USER=johndoe
19  lib/gist.rb
... ...
@@ -1,6 +1,8 @@
1 1
 require 'open-uri'
2 2
 require 'net/https'
3 3
 require 'optparse'
  4
+
  5
+require 'rubygems'
4 6
 require 'json'
5 7
 require 'base64'
6 8
 
@@ -141,6 +143,7 @@ def write(files, private_gist = false, description = nil)
141 143
 
142 144
     if auth_header = auth()
143 145
       req.add_field('Authorization', auth_header)
  146
+    end
144 147
 
145 148
     response = http.start{|h| h.request(req) }
146 149
     case response
@@ -154,7 +157,8 @@ def write(files, private_gist = false, description = nil)
154 157
 
155 158
   # Given a gist id, returns its content.
156 159
   def read(gist_id)
157  
-    open(GIST_URL % gist_id).read
  160
+    data = JSON.parse(open(GIST_URL % gist_id).read)
  161
+    data["files"].map{|name, content| content['content'] }.join("\n\n")
158 162
   end
159 163
 
160 164
   # Given a url, tries to open it in your browser.
@@ -193,14 +197,17 @@ def copy(content)
193 197
   # an appropriate payload for POSTing to gist.github.com
194 198
   def data(files, private_gist, description)
195 199
     i = 0
196  
-    data = {}
197  
-    data["files"] = files.map do |file|
  200
+    file_data = {}
  201
+    files.each do |file|
198 202
       i = i + 1
199 203
       filename = file[:filename] ? file[:filename] : "gistfile#{i}"
200  
-      {filename => {:content => file[:input]}}
  204
+      file_data[filename] = {:content => file[:input]}
201 205
     end
  206
+
  207
+    data = {"files" => file_data}
202 208
     data.merge!({ 'description' => description }) unless description.nil?
203  
-    data.merge(private_gist ? { 'public' => false } : {})
  209
+    data.merge!({ 'public' => false }) if private_gist
  210
+    data
204 211
   end
205 212
 
206 213
   # Returns a basic auth string of the user's GitHub credentials if set.
@@ -209,7 +216,7 @@ def auth
209 216
     user  = config("github.user")
210 217
     password = config("github.password")
211 218
 
212  
-    if user.to_s.empty? || token.to_s.empty?
  219
+    if user.to_s.empty? || password.to_s.empty?
213 220
       nil
214 221
     else
215 222
       auth_str = Base64.encode64("#{user}:#{password}")
2  man/gist.1
... ...
@@ -1,7 +1,7 @@
1 1
 .\" generated with Ronn/v0.7.3
2 2
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
3 3
 .
4  
-.TH "GIST" "1" "June 2011" "GITHUB" "Gist Manual"
  4
+.TH "GIST" "1" "March 2012" "GITHUB" "Gist Manual"
5 5
 .
6 6
 .SH "NAME"
7 7
 \fBgist\fR \- gist on the command line
4  man/gist.1.html
@@ -152,7 +152,7 @@ <h2 id="AUTHENTICATION">AUTHENTICATION</h2>
152 152
 <h2 id="CONFIGURATION">CONFIGURATION</h2>
153 153
 
154 154
 <p>You can set a few options in your git config (using <span class="man-ref">git-config<span class="s">(1)</span></span>) to
155  
-control the default behavior of <a class="man-ref" href="gist.1.ron.html">gist<span class="s">(1)</span></a>.</p>
  155
+control the default behavior of <a href="gist.1.ron.html" class="man-ref">gist<span class="s">(1)</span></a>.</p>
156 156
 
157 157
 <ul>
158 158
 <li><p>gist.private - boolean (yes or no) - Determines whether to make a gist
@@ -200,7 +200,7 @@ <h2 id="SEE-ALSO">SEE ALSO</h2>
200 200
 
201 201
   <ol class='man-decor man-foot man foot'>
202 202
     <li class='tl'>GITHUB</li>
203  
-    <li class='tc'>June 2011</li>
  203
+    <li class='tc'>March 2012</li>
204 204
     <li class='tr'>gist(1)</li>
205 205
   </ol>
206 206
 

3 notes on commit 528ebb2

Adam Vandenberg

Is json a new external dependency now?

Adam Vandenberg

I thought require 'rubygems' was bad practice.

Ross Boucher

Yup

Chris Wanstrath
Owner

It is.

Fernando Ortiz

Do we now have to provide a password? What happened to the token?

Ross Boucher
Chris Wanstrath
Owner

json external dependency has been removed as of 3.1.0

Please sign in to comment.
Something went wrong with that request. Please try again.