kronk 1.9.4 → 1.9.5

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.
@@ -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