jist 0.2 → 0.3

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/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