jist 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/jist +45 -18
  2. data/lib/jist.rb +72 -20
  3. metadata +4 -4
data/bin/jist CHANGED
@@ -11,44 +11,71 @@ options = {}
11
11
  opts = OptionParser.new do |opts|
12
12
  executable_name = File.split($0)[1]
13
13
  opts.banner = <<-EOS
14
- Jist is a simple command that let's you create new gists from the terminal.
14
+ Jist (v#{Jist::VERSION}) let's you upload to https://gist.github.com/
15
+
16
+ Usage: #{executable_name} [-p] [-d DESC] [-t TOKEN] [-f FILENAME] [FILE]
17
+ #{executable_name} --login
18
+
19
+ When used with no arguments, jist creates an Anonymous, private, gist, with
20
+ no description. The FILENAME defaults to "a.rb" and we read the contents of
21
+ STDIN.
22
+
23
+ If you'd like your gists to be associated with your github account, so that
24
+ you can edit them, and find them in future, first use `jist --login` to obtain
25
+ an Oauth2 access token. This is stored and used for all future uses of jist.
26
+
27
+ If you're calling jist from another program that already has an access_token
28
+ with the "gist" scope, then pass it using `jist -t`.
29
+
30
+ If you specify a FILE on the command line, then jist will use that as the
31
+ default value for FILENAME too. If not, jist will assume that the file you
32
+ provide on STDIN is called "a.rb". The FILENAME is mostly important for
33
+ determining which language to use for syntax highlighting.
34
+
35
+ Making a gist public causes it to have a prettier, guessable url. And adding
36
+ a description can provide useful context to people who stumble across your
37
+ gist.
15
38
 
16
- Usage: #{executable_name} [options] file
17
39
  EOS
18
-
19
- opts.on("-a", "--auth USERNAME,PASSWORD", Array, "Provide a USERNAME and PASSWORD to log in and post an authenticated gist") do |one,two|
20
- options[:username] = one
21
- options[:password] = two
40
+
41
+ opts.on("--login", "Authenticate jist on this computer.") do
42
+ Jist.login!
43
+ exit
22
44
  end
23
45
 
24
- opts.on("-f", "--filename [NAME.EXTENSION]", Array,"Change the syntax highlighting (default is a.rb)") do |filename,b|
46
+ opts.on("-f", "--filename [NAME.EXTENSION]", "Sets the filename and syntax type.") do |filename|
25
47
  options[:filename] = filename
26
- options[:derp] = b
27
48
  end
28
49
 
29
- opts.on("-p", "--public", "Add this flag you want your gist to have a guessable url") do |public|
50
+ opts.on("-p", "--public", "Makes your gist public.") do |public|
30
51
  options[:public] = public
31
52
  end
32
53
 
33
- opts.on("-d", "--description DESCRIPTION", "Adds a description to your gist") do |description|
54
+ opts.on("-d", "--description DESCRIPTION", "Adds a description to your gist.") do |description|
34
55
  options[:description] = description
35
56
  end
36
-
37
- opts.on_tail("-h","--help", "Show this message") do
38
- $stdout.puts opts
57
+
58
+ opts.on("-t", "--token OAUTH_TOKEN", "The OAuth2 access_token to use.") do |token|
59
+ options[:access_token] = token
60
+ end
61
+
62
+ opts.on_tail("-h","--help", "Show this message.") do
63
+ puts opts
39
64
  exit
40
65
  end
41
66
 
42
- opts.on_tail("-v", "--version") do
43
- puts "jist v#{Jist::VERSION}" # hardcoded for now
67
+ opts.on_tail("-v", "--version", "Print the version.") do
68
+ puts "jist v#{Jist::VERSION}"
44
69
  exit
45
70
  end
46
71
 
47
72
  end
48
73
  opts.parse!
49
74
 
50
- if ARGV.empty?
51
- $stdout << opts.help
75
+ if ARGV.size == 0
76
+ puts Jist.gist(ARGF.read, options)['html_url']
77
+ elsif ARGV.size == 1
78
+ puts Jist.gist(File.read(File.expand_path(ARGV[0])), {:filename => File.basename(ARGV[0])}.merge(options))['html_url']
52
79
  else
53
- $stdout.puts Jist.gist(ARGF.read, options)["html_url"]
80
+ puts opts
54
81
  end
@@ -1,24 +1,27 @@
1
1
  require 'net/https'
2
+ require 'cgi'
2
3
  require 'multi_json'
3
4
 
4
5
  # It just gists.
5
6
  module Jist
6
7
 
7
- VERSION = '0.2'
8
+ VERSION = '0.3'
8
9
 
9
10
  module_function
10
- # Upload a gist to https://gist.github.com/
11
+ # Upload a gist to https://gist.github.com
11
12
  #
12
- # @param content the code you'd like to gist
13
+ # @param [String] content the code you'd like to gist
14
+ # @param [Hash] options more detailed options
13
15
  #
14
- # @option :description the description
15
- # @option :filename the filename (default 'a.rb')
16
- # @option :public to make it a public gist (default private)
17
- # @option :username if you wish to log in to github
18
- # @option :password (required if username is set)
16
+ # @option options [String] :description the description
17
+ # @option options [String] :filename ('a.rb') the filename
18
+ # @option options [Boolean] :public (false) is this gist public
19
+ # @option options [String] :access_token (`File.read("~/.jist")`) The OAuth2 access token.
19
20
  #
20
- # @return Hash the decoded JSON response from the server
21
- # @raise Exception if something went wrong
21
+ # @return [Hash] the decoded JSON response from the server
22
+ # @raise [Exception] if something went wrong
23
+ #
24
+ # @see http://developer.github.com/v3/gists/
22
25
  def gist(content, options={})
23
26
  json = {}
24
27
 
@@ -33,25 +36,74 @@ module Jist
33
36
  }
34
37
  }
35
38
 
36
- connection = Net::HTTP.new("api.github.com", 443)
37
- connection.use_ssl = true
38
- connection.read_timeout = 10
39
+ access_token = (options[:access_token] || File.read(File.expand_path("~/.jist")) rescue nil)
39
40
 
40
- request = Net::HTTP::Post.new("/gists")
41
+ url = "/gists"
42
+ url << "?access_token=" << CGI.escape(access_token) if access_token.to_s != ''
43
+
44
+ request = Net::HTTP::Post.new(url)
41
45
  request.body = MultiJson.encode(json)
42
46
 
43
- if options[:username]
44
- request.basic_auth(options[:username], options[:password])
47
+ response = http(request)
48
+
49
+ if Net::HTTPCreated === response
50
+ MultiJson.decode(response.body)
51
+ else
52
+ raise RuntimeError.new "Got #{response.class} from gist: #{response.body}"
45
53
  end
54
+ end
46
55
 
47
- response = connection.start do |http|
48
- http.request(request)
49
- end
56
+ # Log the user into jist.
57
+ #
58
+ # This method asks the user for a username and password, and tries to obtain
59
+ # and OAuth2 access token, which is then stored in ~/.jist
60
+ def login!
61
+ puts "Obtaining OAuth2 access_token from github."
62
+ print "Github username: "
63
+ username = gets.strip
64
+ print "Github password: "
65
+ password = begin
66
+ `stty -echo 2>/dev/null`
67
+ gets.strip
68
+ ensure
69
+ `stty echo 2>/dev/null`
70
+ end
71
+ puts ""
72
+
73
+ request = Net::HTTP::Post.new("/authorizations")
74
+ request.body = MultiJson.encode({
75
+ :scopes => [:gist],
76
+ :note => "The jist gem",
77
+ :note_url => "https://github.com/ConradIrwin/jist"
78
+ })
79
+ request.basic_auth(username, password)
80
+
81
+ response = http(request)
50
82
 
51
83
  if Net::HTTPCreated === response
52
- MultiJson.decode(response.body)
84
+ File.open(File.expand_path("~/.jist"), 'w') do |f|
85
+ f.write MultiJson.decode(response.body)['token']
86
+ end
87
+ puts "Success! https://github.com/settings/applications"
53
88
  else
54
89
  raise RuntimeError.new "Got #{response.class} from gist: #{response.body}"
55
90
  end
56
91
  end
92
+
93
+ private
94
+
95
+ module_function
96
+ # Run an HTTP operation against api.github.com
97
+ #
98
+ # @param [Net::HTTP::Request]
99
+ # @return [Net::HTTP::Response]
100
+ def http(request)
101
+ connection = Net::HTTP.new("api.github.com", 443)
102
+ connection.use_ssl = true
103
+ connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
104
+ connection.read_timeout = 10
105
+ connection.start do |http|
106
+ http.request request
107
+ end
108
+ end
57
109
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jist
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- version: "0.2"
8
+ - 3
9
+ version: "0.3"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Conrad Irwin
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2012-06-22 00:00:00 Z
17
+ date: 2012-06-23 00:00:00 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: multi_json