kronk 1.9.4 → 1.9.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3131792c5cada686c4716bf66fb3396d68aa9392
4
+ data.tar.gz: 46d2628088e25d5cde756984b8ec41b82d0c774b
5
+ SHA512:
6
+ metadata.gz: f673287a126de6374adbe41de49327d75f9a1c364afc07763ea186101bd02015546c99842b1658eaa037a856a124a8c2e2ba2f8c733206e40194dad5f8b3a1e5
7
+ data.tar.gz: 68f4e60ed01cad9b558d9e72674f8c2803d3f3d424c1e9c2110f1085168b93c2e8e5b2c065529188d7538041fd303ef3b3f50a219e0a257776a6a1df2d1fdd8d
@@ -4,9 +4,12 @@ Manifest.txt
4
4
  README.rdoc
5
5
  Rakefile
6
6
  bin/kronk
7
+ bin/kronk-oauth
7
8
  lib/kronk.rb
9
+ lib/kronk/oauth_config.rb
8
10
  lib/kronk/buffered_io.rb
9
11
  lib/kronk/cmd.rb
12
+ lib/kronk/cmd/oauth.rb
10
13
  lib/kronk/constants.rb
11
14
  lib/kronk/data_string.rb
12
15
  lib/kronk/diff.rb
data/TODO.rdoc CHANGED
@@ -1,5 +1,8 @@
1
1
  = TODO
2
2
 
3
+ * Support for using oauth keys in kronk command
4
+
5
+
3
6
  == Maybe Later
4
7
 
5
8
  * Investigate streaming and Yajl.
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.join(File.dirname(__FILE__), "../lib") if $0 == "bin/kronk-oauth"
4
+
5
+ require 'kronk/cmd/oauth'
6
+ Kronk::Cmd::OAuth.run
@@ -16,7 +16,7 @@ require 'yaml'
16
16
  class Kronk
17
17
 
18
18
  # This gem's version.
19
- VERSION = '1.9.4'
19
+ VERSION = '1.9.5'
20
20
 
21
21
  require 'kronk/constants'
22
22
  require 'kronk/queue_runner'
@@ -36,7 +36,8 @@ class Kronk
36
36
  require 'kronk/http'
37
37
  require 'kronk/buffered_io'
38
38
  require 'kronk/multipart'
39
- require 'kronk/multipart_io'
39
+ require 'kronk/multipart_io'
40
+ require 'kronk/oauth_config'
40
41
  require 'kronk/request'
41
42
  require 'kronk/response'
42
43
  require 'kronk/plist_parser'
@@ -52,6 +53,14 @@ class Kronk
52
53
  end
53
54
 
54
55
 
56
+ ##
57
+ # Returns the Kronk::OAuthConfig instance
58
+
59
+ def self.oauth_config
60
+ @oauth_config ||= Kronk::OAuthConfig.new
61
+ end
62
+
63
+
55
64
  ##
56
65
  # Load a config file and apply to Kronk.config.
57
66
 
@@ -78,6 +87,8 @@ class Kronk
78
87
  self.config[skey] = value
79
88
  end
80
89
  end
90
+
91
+ @oauth_config = Kronk::OAuthConfig.load_file(DEFAULT_OAUTH_FILE)
81
92
  end
82
93
 
83
94
 
@@ -281,9 +292,8 @@ class Kronk
281
292
  # :http_method:: Symbol - the http method to use; defaults to :get
282
293
  # :user_agent:: String - user agent string or alias; defaults to 'kronk'
283
294
  # :auth:: Hash - must contain :username and :password; defaults to nil
284
- # :oauth:: Hash - :consumer_key, :token, :consumer_secret, :token_secret
295
+ # :oauth:: Hash - :consumer_key, :token :consumer_secret, :token_secret
285
296
  # :proxy:: Hash/String - http proxy to use; defaults to nil
286
- # :keep_indicies:: Boolean - indicies of modified arrays display as hashes
287
297
  # :show_headers:: Boolean/String/Array - which headers to show in output
288
298
  # :parser:: Object/String - the parser to use for the body; default nil
289
299
  # :raw:: Boolean - run diff on raw strings
@@ -366,6 +376,9 @@ class Kronk
366
376
  rescue Errno::ENOENT => e
367
377
  raise NotFoundError, e.message
368
378
 
379
+ rescue OpenSSL::SSL::SSLError
380
+ raise InvalidCertificate, "The remote SSL certificate could not be trusted"
381
+
369
382
  rescue SocketError, Errno::ECONNREFUSED => e
370
383
  raise NotFoundError, "#{uri} could not be found (#{e.class})"
371
384
 
@@ -403,6 +416,16 @@ class Kronk
403
416
  end
404
417
 
405
418
 
419
+ ##
420
+ # Returns oauth config for the given uri
421
+
422
+ def oauth_options_for_uri uri
423
+ uri = "http://#{uri}" unless uri.start_with?("http")
424
+ uri_host = URI.parse(uri.to_s).host
425
+ return self.class.oauth_config.get_active_for_host(uri_host)
426
+ end
427
+
428
+
406
429
  ##
407
430
  # Returns merged config-defined options for a given uri.
408
431
  # Values in cmd_opts take precedence.
@@ -466,6 +489,11 @@ class Kronk
466
489
  end
467
490
  end
468
491
 
492
+ if !out_opts[:oauth]
493
+ oauth = oauth_options_for_uri(uri)
494
+ out_opts[:oauth] = oauth if oauth
495
+ end
496
+
469
497
  out_opts
470
498
  end
471
499
  end
@@ -425,6 +425,11 @@ Parse and run diffs against data from live and cached http responses.
425
425
  end
426
426
 
427
427
 
428
+ opt.on('-k', '--insecure', 'Allow insecure SSL connections') do
429
+ options[:insecure_ssl] = true
430
+ end
431
+
432
+
428
433
  opt.on('-L', '--location [NUM]', Integer,
429
434
  'Follow the location header always or num times') do |value|
430
435
  options[:follow_redirects] = value || true
@@ -449,8 +454,8 @@ Parse and run diffs against data from live and cached http responses.
449
454
  end
450
455
 
451
456
 
452
- opt.on('--oauth', String, 'Yaml file with Oauth credentials') do |file|
453
- options[:oauth] = YAML.load_file file
457
+ opt.on('--oauth [NAME]', String, 'OAuth config name - see kronk-oauth') do |name|
458
+ options[:oauth_config] = name
454
459
  end
455
460
 
456
461
 
@@ -541,6 +546,10 @@ Parse and run diffs against data from live and cached http responses.
541
546
  options[:uris] << Kronk.config[:cache_file]
542
547
  end
543
548
 
549
+ if options[:oauth_config]
550
+ options[:oauth] = load_oauth_profile(options.delete(:oauth_config))
551
+ end
552
+
544
553
  argv.clear
545
554
 
546
555
  raise "You must enter at least one URI" if options[:uris].empty? &&
@@ -590,6 +599,17 @@ Parse and run diffs against data from live and cached http responses.
590
599
  end
591
600
 
592
601
 
602
+ ##
603
+ # Retrieve the config for the given oauth profile
604
+
605
+ def self.load_oauth_profile profile
606
+ host, name = profile.split("@", 2).reverse
607
+ config = OAuthConfig.load_file(Kronk::DEFAULT_OAUTH_FILE)
608
+ return unless config.has_name_for_host?(name, host)
609
+ return config.get_symbolized(name, host)
610
+ end
611
+
612
+
593
613
  ##
594
614
  # Determine the cmd-given path's action and Path representation.
595
615
 
@@ -0,0 +1,337 @@
1
+ require 'kronk/cmd'
2
+ require 'yaml'
3
+
4
+ class Kronk::Cmd::OAuth
5
+
6
+ TWITTER_HOST = 'api.twitter.com'
7
+
8
+ ##
9
+ # Parse ARGV into options and Kronk config.
10
+
11
+ def self.parse_args argv
12
+ options = {}
13
+
14
+ opts = OptionParser.new do |opt|
15
+ opt.program_name = File.basename $0
16
+ opt.version = Kronk::VERSION
17
+ opt.release = nil
18
+
19
+ opt.banner = <<-STR
20
+
21
+ #{opt.program_name} #{opt.version}
22
+
23
+ Manage OAuth configs for kronk.
24
+
25
+ Usage:
26
+ #{opt.program_name} --help
27
+ #{opt.program_name} --version
28
+ #{opt.program_name} [options]
29
+
30
+ Examples:
31
+ #{opt.program_name} --list
32
+ #{opt.program_name} --list api.twitter.com
33
+ #{opt.program_name} --add api.twitter.com
34
+ #{opt.program_name} --remove my-config-name@api.twitter.com
35
+
36
+ Option targets may be a in the form of a host or user@host.
37
+
38
+ Options:
39
+ STR
40
+
41
+ opt.on('-l', '--list [TARGET]', 'List OAuth configs for an optional target') do |target|
42
+ return :list_config, *parse_target(target)
43
+ end
44
+
45
+ opt.on('-a', '--add TARGET', 'Add a new OAuth config for a given target') do |target|
46
+ return :add_config, *parse_target(target)
47
+ end
48
+
49
+ opt.on('-r', '--remove TARGET', 'Remove an OAuth config for a given target') do |target|
50
+ return :remove_config, *parse_target(target)
51
+ end
52
+
53
+ opt.on('-s', '--select TARGET', 'Set default OAuth config for a given target') do |target|
54
+ return :select_config, *parse_target(target)
55
+ end
56
+
57
+ opt.on('-d', '--disable HOST', 'Stop using OAuth config for a given host') do |host|
58
+ return :disable_config, host
59
+ end
60
+
61
+ opt.on('-n', '--rename TARGET', 'Rename an OAuth config for a given host') do |target|
62
+ return :rename_config, *parse_target(target)
63
+ end
64
+
65
+ opt.on('--twurl [FILE]', 'Import twurl configs') do |file|
66
+ return :import_twurl, file
67
+ end
68
+
69
+ opt.on('-h', '--help', 'Print this help screen') do
70
+ puts opt
71
+ exit
72
+ end
73
+
74
+ opt.on('-v', '--version', 'Output Kronk version and exit') do
75
+ puts Kronk::VERSION
76
+ exit
77
+ end
78
+
79
+ opt.separator nil
80
+ end
81
+
82
+ opts.parse! argv
83
+
84
+ puts opts.to_s
85
+ exit 0
86
+
87
+ rescue OptionParser::ParseError => e
88
+ $stderr.puts("\nError: #{e.message}")
89
+ $stderr.puts("See 'kronk-oauth --help' for usage\n\n")
90
+ exit 1
91
+ end
92
+
93
+
94
+ def self.parse_target target
95
+ return unless target
96
+ target.split("@", 2).reverse
97
+ end
98
+
99
+
100
+ def self.run argv=ARGV
101
+ trap 'INT' do
102
+ puts "\n"
103
+ exit 2
104
+ end
105
+
106
+ new(Kronk::DEFAULT_OAUTH_FILE).send(*parse_args(argv))
107
+ end
108
+
109
+
110
+ attr_accessor :file
111
+
112
+ def initialize file
113
+ @file = file
114
+ @config = File.file?(@file) ? Kronk::OAuthConfig.load_file( @file ) : Kronk::OAuthConfig.new
115
+ end
116
+
117
+
118
+ def save_file!
119
+ @config.save_file(@file)
120
+
121
+ autocomplete = []
122
+ @config.each do |host, name, config|
123
+ autocomplete << "#{name}@#{host}"
124
+ end
125
+
126
+ autocomplete.concat(@config.hosts)
127
+
128
+ File.open(Kronk::DEFAULT_OAUTH_LIST_FILE, "w+") {|f| f.write( autocomplete.join("\n") << "\n" ) }
129
+ end
130
+
131
+
132
+ def assert_has_name_for_host! name, host
133
+ if !@config.has_name_for_host?(name, host)
134
+ $stderr.puts("No config for #{name}@#{host}")
135
+ exit 1
136
+ end
137
+ end
138
+
139
+
140
+ def assert_has_host! host
141
+ if !@config.has_host?(host)
142
+ $stderr.puts("No config for host #{host}")
143
+ exit 1
144
+ end
145
+ end
146
+
147
+
148
+ def validate_name name, host
149
+ while @config.has_name_for_host?(name, host)
150
+ confirm = query("Override existing #{name}@#{host}? (y/n) ", true) == 'y'
151
+ break if confirm
152
+ name = query_name(host)
153
+ end
154
+
155
+ return name
156
+ end
157
+
158
+
159
+ def query_name host
160
+ return query("Config name for #{host}: ")
161
+ end
162
+
163
+
164
+ def query prompt, allow_blank=false
165
+ $stderr << prompt
166
+ value = $stdin.gets.chomp
167
+ return value.empty? && !allow_blank ? query(prompt) : value
168
+ end
169
+
170
+
171
+ def select_name host, allow_all=false
172
+ names = @config.names_for_host(host).sort
173
+ names.each_with_index do |name, i|
174
+ mark = name == @config.active_name_for_host(host) ? "* " : " "
175
+ $stderr.puts("#{i+1}) #{mark}#{name}")
176
+ end
177
+ $stderr.puts("#{names.length+1}) All") if allow_all
178
+
179
+ num = 0
180
+ len = names.length + (allow_all ? 1 : 0)
181
+ until num > 0 && num <= len
182
+ num = query("Enter number: ").to_i
183
+ end
184
+
185
+ return names[num-1]
186
+ end
187
+
188
+
189
+ def add_config host, name=nil
190
+ name ||= query_name(host)
191
+ name = validate_name(name, host)
192
+
193
+ config = {
194
+ 'consumer_key' => query("Consumer Key: "),
195
+ 'consumer_secret' => query("Consumer Secret: "),
196
+ 'token' => query("Token: "),
197
+ 'token_secret' => query("Token Secret: ")
198
+ }
199
+
200
+ @config.set(name, host, config)
201
+
202
+ save_file!
203
+
204
+ $stderr.puts("Added config for #{name}@#{host}")
205
+ end
206
+
207
+
208
+ def remove_config host, name=nil
209
+ assert_has_host!(host)
210
+ name ||= select_name(host, true)
211
+
212
+ @config.remove(host, name)
213
+
214
+ save_file!
215
+
216
+ $stderr.puts("Removed config #{name && "#{name}@"}#{host}")
217
+ end
218
+
219
+
220
+ def list_config host=nil, name=nil
221
+ if host && name
222
+ assert_has_name_for_host!(name, host)
223
+ $stdout.puts(@config.get(name, host).to_yaml)
224
+
225
+ elsif host
226
+ assert_has_host!(host)
227
+ $stdout.puts(host)
228
+ @config.names_for_host(host).sort.each do |config_name|
229
+ mark = config_name == @config.active_name_for_host(host) ? "* " : " "
230
+ $stdout.puts " #{mark}#{config_name}\n"
231
+ end
232
+ $stdout.puts("\n")
233
+
234
+ elsif @config.empty?
235
+ $stderr.puts("No config to display")
236
+
237
+ else
238
+ @config.hosts.sort.each do |h|
239
+ $stdout.puts(h)
240
+ @config.names_for_host(h).sort.each do |config_name|
241
+ mark = config_name == @config.active_name_for_host(h) ? "* " : " "
242
+ $stdout.puts " #{mark}#{config_name}\n"
243
+ end
244
+ $stdout.puts("\n")
245
+ end
246
+ end
247
+ end
248
+
249
+
250
+ def select_config host, name=nil
251
+ assert_has_host!(host)
252
+ assert_has_name_for_host!(name, host) if name
253
+ name ||= select_name(host)
254
+
255
+ @config.set_active_for_host(name, host)
256
+ save_file!
257
+
258
+ $stderr.puts("Set active config #{name}@#{host}")
259
+ end
260
+
261
+
262
+ def disable_config host
263
+ assert_has_host!(host)
264
+ name = @config.active_name_for_host(host)
265
+
266
+ if !name
267
+ $stderr.puts("No active account for #{host}")
268
+ exit 0
269
+ end
270
+
271
+ @config.set_active_for_host(nil, host)
272
+ save_file!
273
+
274
+ $stderr.puts("Disabled config #{name}@#{host}")
275
+ end
276
+
277
+
278
+ def rename_config host, name=nil
279
+ assert_has_host!(host)
280
+ name ||= select_name(host)
281
+
282
+ new_name = query("Enter new name: ")
283
+
284
+ @config.rename(host, name, new_name)
285
+
286
+ save_file!
287
+
288
+ $stderr.puts("Renamed #{name}@#{host} to #{new_name}@#{host}")
289
+ end
290
+
291
+
292
+ def import_twurl file=nil
293
+ file ||= File.expand_path('~/.twurlrc')
294
+
295
+ if !File.file?( file )
296
+ $stderr.puts("Could not find file: #{file}")
297
+ exit 1
298
+ end
299
+
300
+ config = YAML.load_file(file) rescue nil
301
+
302
+ is_valid = Hash === config &&
303
+ config['profiles'] &&
304
+ Hash === config['profiles']
305
+
306
+ unless is_valid
307
+ $stderr.puts("Invalid file format: #{file}")
308
+ exit 1
309
+ end
310
+
311
+ host = 'api.twitter.com'
312
+ profiles = config['profiles']
313
+
314
+ profiles.each do |name, consumers|
315
+ name = "#{name}-twurl" if @config.has_name_for_host?(name, TWITTER_HOST)
316
+ if consumers.length == 1
317
+ add_twurl_config(name, consumers[consumers.keys.first])
318
+ else
319
+ consumers.each do |key, config|
320
+ add_twurl_config("#{name}-#{key}", config)
321
+ end
322
+ end
323
+ end
324
+
325
+ save_file!
326
+
327
+ $stderr.puts("Successfully imported twurl config")
328
+ end
329
+
330
+
331
+ def add_twurl_config name, config
332
+ config.delete('username')
333
+ config['token_secret'] = config.delete('secret')
334
+
335
+ @config.set(name, TWITTER_HOST, config)
336
+ end
337
+ end
@@ -9,6 +9,9 @@ class Kronk
9
9
  # Raised when the URI was not resolvable.
10
10
  class NotFoundError < Error; end
11
11
 
12
+ # Raised when SSL fails.
13
+ class InvalidCertificate < Error; end
14
+
12
15
  # Raised when HTTP times out.
13
16
  class TimeoutError < Error; end
14
17
 
@@ -31,6 +34,12 @@ class Kronk
31
34
  # Default file with history of unique URIs. (Used for autocomplete)
32
35
  DEFAULT_HISTORY_FILE = File.join CONFIG_DIR, "history"
33
36
 
37
+ # Default file where oauth credentials are stored.
38
+ DEFAULT_OAUTH_FILE = File.join CONFIG_DIR, "oauth"
39
+
40
+ # Default file of oauth names. (Used for autocomplete)
41
+ DEFAULT_OAUTH_LIST_FILE = File.join CONFIG_DIR, "oauth-list"
42
+
34
43
 
35
44
  # Default Content-Type header to parser mapping.
36
45
  DEFAULT_CONTENT_TYPES = {
@@ -0,0 +1,134 @@
1
+ require 'yaml'
2
+
3
+ class Kronk::OAuthConfig
4
+
5
+ SELECTED_KEY = 'selected'
6
+ ACCOUNTS_KEY = 'accounts'
7
+
8
+ def self.load_file yaml_file
9
+ new( YAML.load_file(yaml_file) )
10
+ end
11
+
12
+
13
+ def initialize config=nil
14
+ @config = config || {}
15
+ end
16
+
17
+
18
+ def has_name_for_host? name, host
19
+ !!get(name, host)
20
+ end
21
+
22
+
23
+ def has_host? host
24
+ !!config_for_host(host)
25
+ end
26
+
27
+
28
+ def get name, host
29
+ config = config_for_host(host)
30
+ config && config[ACCOUNTS_KEY] && config[ACCOUNTS_KEY][name] && config[ACCOUNTS_KEY][name].dup
31
+ end
32
+
33
+
34
+ def get_symbolized name, host
35
+ data = get(name, host)
36
+ return unless data
37
+
38
+ data[:consumer_key] = data.delete('consumer_key')
39
+ data[:consumer_secret] = data.delete('consumer_secret')
40
+ data[:token] = data.delete('token')
41
+ data[:token_secret] = data.delete('token_secret')
42
+ return data
43
+ end
44
+
45
+
46
+ def set name, host, config
47
+ @config[host] ||= {SELECTED_KEY => name, ACCOUNTS_KEY => {}}
48
+ @config[host][ACCOUNTS_KEY][name] = config
49
+ end
50
+
51
+
52
+ def remove host, name=nil
53
+ if name
54
+ config = config_for_host(host)
55
+ config[ACCOUNTS_KEY].delete(name)
56
+ if config[ACCOUNTS_KEY].empty?
57
+ @config.delete(host)
58
+ elsif config[SELECTED_KEY] == name
59
+ config[SELECTED_KEY] = nil
60
+ end
61
+
62
+ else
63
+ @config.delete(host)
64
+ end
65
+ end
66
+
67
+
68
+ def rename host, name, new_name
69
+ selected = active_name_for_host(host) == name
70
+ config = get(name, host)
71
+ remove(host, name)
72
+ set(new_name, host, config)
73
+ set_active_for_host(new_name, host) if selected
74
+ end
75
+
76
+
77
+ def get_active_for_host host
78
+ name = active_name_for_host(host)
79
+ return get_symbolized(name, host)
80
+ end
81
+
82
+
83
+ def set_active_for_host name, host
84
+ config = config_for_host(host)
85
+ return false unless config
86
+ return false unless config[ACCOUNTS_KEY] && config[ACCOUNTS_KEY][name] || name.nil?
87
+
88
+ config[SELECTED_KEY] = name
89
+ return true
90
+ end
91
+
92
+
93
+ def active_name_for_host host
94
+ config = config_for_host(host)
95
+ return unless config
96
+
97
+ return config[SELECTED_KEY]
98
+ end
99
+
100
+
101
+ def names_for_host host
102
+ @config[host] && @config[host][ACCOUNTS_KEY] && @config[host][ACCOUNTS_KEY].keys || []
103
+ end
104
+
105
+
106
+ def hosts
107
+ @config.keys
108
+ end
109
+
110
+
111
+ def config_for_host host
112
+ @config[host]
113
+ end
114
+
115
+
116
+ def empty?
117
+ @config.empty?
118
+ end
119
+
120
+
121
+ def save_file yaml_file
122
+ File.open(yaml_file, "w+") {|f| f.write @config.to_yaml }
123
+ end
124
+
125
+
126
+ def each &block
127
+ @config.each do |host, data|
128
+ configs = data[ACCOUNTS_KEY]
129
+ configs.each do |name, config|
130
+ block.call(host, name, config)
131
+ end
132
+ end
133
+ end
134
+ end
@@ -38,6 +38,7 @@ class Kronk
38
38
  $stdout << "#{"%X" % output.length}\r\n"
39
39
  $stdout << output
40
40
  $stdout << "\r\n"
41
+ $stdout.flush
41
42
  end
42
43
 
43
44
  output
@@ -212,7 +212,7 @@ class Kronk
212
212
  self.multipart_boundary = 'AaB03x'
213
213
 
214
214
 
215
- attr_accessor :headers, :response, :timeout
215
+ attr_accessor :headers, :response, :timeout, :insecure_ssl
216
216
 
217
217
  attr_reader :body, :http_method, :proxy, :uri, :use_cookies
218
218
 
@@ -230,6 +230,7 @@ class Kronk
230
230
  # :http_method:: Symbol - the http method to use; defaults to :get
231
231
  # :proxy:: Hash/String - http proxy to use; defaults to {}
232
232
  # :accept_encoding:: Array/String - list of encodings the server can return
233
+ # :insecure_ssl:: Boolean - Allow SSL for sites with bad or missing certs
233
234
  #
234
235
  # Note: if no http method is specified and data is given, will default
235
236
  # to using a post request.
@@ -254,6 +255,8 @@ class Kronk
254
255
 
255
256
  @timeout = opts[:timeout] || Kronk.config[:timeout]
256
257
 
258
+ @insecure_ssl = opts[:insecure_ssl]
259
+
257
260
  @uri = self.class.build_uri uri, opts
258
261
 
259
262
  self.proxy = opts[:proxy]
@@ -355,6 +358,9 @@ class Kronk
355
358
  :proxy => self.proxy,
356
359
  :ssl => !!(@uri.scheme =~ /^https$/)
357
360
 
361
+ conn.verify_mode = OpenSSL::SSL::VERIFY_NONE if
362
+ conn.use_ssl? && @insecure_ssl
363
+
358
364
  conn.open_timeout = conn.read_timeout = @timeout if @timeout
359
365
 
360
366
  conn
@@ -4,9 +4,15 @@ export COMP_WORDBREAKS=${COMP_WORDBREAKS/\:/}
4
4
 
5
5
  _kronk()
6
6
  {
7
- local cur kronk_keys kronk_words
7
+ local cur prev kronk_keys kronk_words
8
8
 
9
9
  cur="${COMP_WORDS[COMP_CWORD]}"
10
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
11
+
12
+ if [[ $prev == "--oauth" ]]; then
13
+ _kronk_oauth
14
+ return $?
15
+ fi
10
16
 
11
17
  kronk_keys="$HOME/.kronk/history"
12
18
  test -f "$kronk_keys" || kronk_keys="$HOME/.kronk_history"
@@ -27,4 +33,24 @@ $(echo "$kronk_words")"
27
33
  return 1
28
34
  }
29
35
 
36
+ _kronk_oauth()
37
+ {
38
+ local cur prev matcher kronk_keys kronk_words
39
+
40
+ cur="${COMP_WORDS[COMP_CWORD]}"
41
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
42
+ matcher="^(--?[lrsdn]|--oauth)"
43
+
44
+ kronk_keys="$HOME/.kronk/oauth-list"
45
+ kronk_words="$(cat $kronk_keys)"
46
+
47
+ if [[ -f "$kronk_keys" && $prev =~ $matcher ]]; then
48
+ COMPREPLY=( $(compgen -W "$kronk_words" -- ${cur}) )
49
+ return 0
50
+ fi
51
+
52
+ return 1
53
+ }
54
+
30
55
  complete -o default -F _kronk kronk
56
+ complete -o default -F _kronk_oauth kronk-oauth
@@ -183,6 +183,7 @@ def expect_request req_method, url, opts={}
183
183
  headers['User-Agent'] ||= Kronk::DEFAULT_USER_AGENT
184
184
  headers['Connection'] ||= 'Keep-Alive'
185
185
 
186
+ http.stubs(:use_ssl?).returns false
186
187
  http.expects(:started?).returns false
187
188
  http.expects(:start)
188
189
  req.expects(:body=).with(data)
metadata CHANGED
@@ -1,191 +1,168 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kronk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.4
5
- prerelease:
4
+ version: 1.9.5
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jeremie Castagna
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-09-06 00:00:00.000000000 Z
11
+ date: 2014-08-20 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: json
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.5'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '1.5'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: cookiejar
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: 0.3.0
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: 0.3.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: ruby-path
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
47
  version: 1.0.0
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
54
  version: 1.0.0
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: mime-types
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ~>
59
+ - - "~>"
68
60
  - !ruby/object:Gem::Version
69
61
  version: 1.18.0
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ~>
66
+ - - "~>"
76
67
  - !ruby/object:Gem::Version
77
68
  version: 1.18.0
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: simple_oauth
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ~>
73
+ - - "~>"
84
74
  - !ruby/object:Gem::Version
85
75
  version: 0.1.9
86
76
  type: :runtime
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ~>
80
+ - - "~>"
92
81
  - !ruby/object:Gem::Version
93
82
  version: 0.1.9
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: rdoc
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ~>
87
+ - - "~>"
100
88
  - !ruby/object:Gem::Version
101
- version: '3.10'
89
+ version: '4.0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ~>
94
+ - - "~>"
108
95
  - !ruby/object:Gem::Version
109
- version: '3.10'
96
+ version: '4.0'
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: plist
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - ~>
101
+ - - "~>"
116
102
  - !ruby/object:Gem::Version
117
103
  version: 3.1.0
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - ~>
108
+ - - "~>"
124
109
  - !ruby/object:Gem::Version
125
110
  version: 3.1.0
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: nokogiri
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
- - - ~>
115
+ - - "~>"
132
116
  - !ruby/object:Gem::Version
133
117
  version: '1.4'
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
- - - ~>
122
+ - - "~>"
140
123
  - !ruby/object:Gem::Version
141
124
  version: '1.4'
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: mocha
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
- - - ~>
129
+ - - "~>"
148
130
  - !ruby/object:Gem::Version
149
131
  version: 0.9.12
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
- - - ~>
136
+ - - "~>"
156
137
  - !ruby/object:Gem::Version
157
138
  version: 0.9.12
158
139
  - !ruby/object:Gem::Dependency
159
140
  name: hoe
160
141
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
142
  requirements:
163
- - - ~>
143
+ - - "~>"
164
144
  - !ruby/object:Gem::Version
165
- version: '3.0'
145
+ version: '3.12'
166
146
  type: :development
167
147
  prerelease: false
168
148
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
149
  requirements:
171
- - - ~>
150
+ - - "~>"
172
151
  - !ruby/object:Gem::Version
173
- version: '3.0'
174
- description: ! 'Kronk is a command line swiss-army-knife for HTTP services.
175
-
152
+ version: '3.12'
153
+ description: |-
154
+ Kronk is a command line swiss-army-knife for HTTP services.
176
155
 
177
156
  With Kronk, you easily parse and segregate data, run diffs between
178
-
179
157
  the parsed data from different queries, and easily replay logs and loadtest
180
-
181
158
  your HTTP applications.
182
159
 
183
-
184
- Kronk was made possible by the sponsoring of YP.com.'
160
+ Kronk was made possible by the sponsoring of YP.com.
185
161
  email:
186
162
  - yaksnrainbows@gmail.com
187
163
  executables:
188
164
  - kronk
165
+ - kronk-oauth
189
166
  extensions: []
190
167
  extra_rdoc_files:
191
168
  - History.rdoc
@@ -193,15 +170,19 @@ extra_rdoc_files:
193
170
  - README.rdoc
194
171
  - TODO.rdoc
195
172
  files:
196
- - .autotest
173
+ - ".autotest"
174
+ - ".gemtest"
197
175
  - History.rdoc
198
176
  - Manifest.txt
199
177
  - README.rdoc
200
178
  - Rakefile
179
+ - TODO.rdoc
201
180
  - bin/kronk
181
+ - bin/kronk-oauth
202
182
  - lib/kronk.rb
203
183
  - lib/kronk/buffered_io.rb
204
184
  - lib/kronk/cmd.rb
185
+ - lib/kronk/cmd/oauth.rb
205
186
  - lib/kronk/constants.rb
206
187
  - lib/kronk/data_string.rb
207
188
  - lib/kronk/diff.rb
@@ -211,13 +192,14 @@ files:
211
192
  - lib/kronk/http.rb
212
193
  - lib/kronk/multipart.rb
213
194
  - lib/kronk/multipart_io.rb
195
+ - lib/kronk/oauth_config.rb
214
196
  - lib/kronk/player.rb
215
197
  - lib/kronk/player/benchmark.rb
216
198
  - lib/kronk/player/download.rb
217
199
  - lib/kronk/player/input_reader.rb
218
200
  - lib/kronk/player/request_parser.rb
219
- - lib/kronk/player/suite.rb
220
201
  - lib/kronk/player/stream.rb
202
+ - lib/kronk/player/suite.rb
221
203
  - lib/kronk/player/tsv.rb
222
204
  - lib/kronk/plist_parser.rb
223
205
  - lib/kronk/queue_runner.rb
@@ -255,33 +237,31 @@ files:
255
237
  - test/test_request_parser.rb
256
238
  - test/test_response.rb
257
239
  - test/test_xml_parser.rb
258
- - TODO.rdoc
259
- - .gemtest
260
240
  homepage: http://kronk.me
261
- licenses: []
241
+ licenses:
242
+ - MIT
243
+ metadata: {}
262
244
  post_install_message:
263
245
  rdoc_options:
264
- - --main
246
+ - "--main"
265
247
  - README.rdoc
266
248
  require_paths:
267
249
  - lib
268
250
  required_ruby_version: !ruby/object:Gem::Requirement
269
- none: false
270
251
  requirements:
271
- - - ! '>='
252
+ - - ">="
272
253
  - !ruby/object:Gem::Version
273
254
  version: '0'
274
255
  required_rubygems_version: !ruby/object:Gem::Requirement
275
- none: false
276
256
  requirements:
277
- - - ! '>='
257
+ - - ">="
278
258
  - !ruby/object:Gem::Version
279
259
  version: '0'
280
260
  requirements: []
281
- rubyforge_project: kronk
282
- rubygems_version: 1.8.24
261
+ rubyforge_project:
262
+ rubygems_version: 2.2.2
283
263
  signing_key:
284
- specification_version: 3
264
+ specification_version: 4
285
265
  summary: Kronk is a command line swiss-army-knife for HTTP services
286
266
  test_files:
287
267
  - test/test_assertions.rb