Class: Kronk
- Inherits:
-
Object
- Object
- Kronk
- Defined in:
- lib/kronk.rb,
lib/kronk/cmd.rb,
lib/kronk/diff.rb,
lib/kronk/http.rb,
lib/kronk/test.rb,
lib/kronk/player.rb,
lib/kronk/request.rb,
lib/kronk/response.rb,
lib/kronk/constants.rb,
lib/kronk/multipart.rb,
lib/kronk/player/tsv.rb,
lib/kronk/xml_parser.rb,
lib/kronk/buffered_io.rb,
lib/kronk/data_string.rb,
lib/kronk/yaml_parser.rb,
lib/kronk/multipart_io.rb,
lib/kronk/player/suite.rb,
lib/kronk/plist_parser.rb,
lib/kronk/queue_runner.rb,
lib/kronk/player/stream.rb,
lib/kronk/player/download.rb,
lib/kronk/test/assertions.rb,
lib/kronk/player/benchmark.rb,
lib/kronk/diff/ascii_format.rb,
lib/kronk/diff/color_format.rb,
lib/kronk/player/input_reader.rb,
lib/kronk/test/helper_methods.rb,
lib/kronk/player/request_parser.rb
Defined Under Namespace
Modules: Test Classes: BufferedIO, Cmd, DataString, Diff, Error, HTTP, HTTPBadResponse, InvalidCertificate, MissingDependency, Multipart, MultipartIO, NotFoundError, OAuthConfig, ParserError, Player, PlistParser, QueueRunner, Request, Response, TimeoutError, XMLParser, YamlParser
Constant Summary collapse
- VERSION =
This gem’s version.
'1.9.6'
- CONFIG_DIR =
Config directory.
File. "~/.kronk"
- DEFAULT_CONFIG_FILE =
Default config file to load. Defaults to ~/.kronk.
File.join CONFIG_DIR, "rc"
- DEFAULT_CACHE_FILE =
Default cache file.
File.join CONFIG_DIR, "cache"
- DEFAULT_COOKIES_FILE =
Default cookies file.
File.join CONFIG_DIR, "cookies"
- DEFAULT_HISTORY_FILE =
Default file with history of unique URIs. (Used for autocomplete)
File.join CONFIG_DIR, "history"
- DEFAULT_OAUTH_FILE =
Default file where oauth credentials are stored.
File.join CONFIG_DIR, "oauth"
- DEFAULT_OAUTH_LIST_FILE =
Default file of oauth names. (Used for autocomplete)
File.join CONFIG_DIR, "oauth-list"
- DEFAULT_CONTENT_TYPES =
Default Content-Type header to parser mapping.
{ 'js' => 'JSON', 'json' => 'JSON', 'plist' => 'PlistParser', 'xml' => 'XMLParser', 'yaml' => 'YamlParser', 'yml' => 'YamlParser' }
- DEEP_MERGE =
Recursive Hash merge proc.
proc do |key,v1,v2| Hash === v1 && Hash === v2 ? v1.merge(v2,&DEEP_MERGE) : v2 end
- RUBY_ENGINE =
'ruby'
- DEFAULT_USER_AGENT =
The default Kronk user agent.
"Kronk/#{VERSION} (#{RUBY_PLATFORM}; U; en-US; http://jcasts.me/kronk) \ #{RUBY_ENGINE}/#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
- USER_AGENTS =
Aliases for various user-agents. Thanks Mechanize! :)
{ 'iphone' => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C28 Safari/419.3", 'linux_firefox' => "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.1) Gecko/20100122 firefox/3.6.1", 'linux_mozilla' => "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624", 'mac_mozilla' => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4a) Gecko/20030401", 'linux_konqueror' => "Mozilla/5.0 (compatible; Konqueror/3; Linux)", 'mac_firefox' => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6", 'mac_safari' => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; de-at) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10", 'win_ie6' => "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)", 'win_ie7' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", 'win_mozilla' => "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4b) Gecko/20030516 Mozilla Firebird/0.6" }
- DEFAULT_CONFIG =
Default config to use.
{ :content_types => DEFAULT_CONTENT_TYPES.dup, :cache_file => DEFAULT_CACHE_FILE, :color_data => true, :context => 3, :cookies_file => DEFAULT_COOKIES_FILE, :default_host => "http://localhost:3000", :diff_format => 'color', :history_file => DEFAULT_HISTORY_FILE, :indentation => 1, :max_history => 100, :requires => [], :show_lines => false, :uri_options => {}, :use_cookies => true, :user_agents => USER_AGENTS.dup }
- RESCUABLE =
Errors to rescue from the Cmd or from Player.
[ Kronk::Error, Timeout::Error, SocketError, SystemCallError, URI::InvalidURIError ]
Instance Attribute Summary collapse
-
#diff ⇒ Object
Returns the value of attribute diff.
-
#options ⇒ Object
Returns the value of attribute options.
-
#response ⇒ Object
Returns the value of attribute response.
-
#responses ⇒ Object
Returns the value of attribute responses.
Class Method Summary collapse
-
.clear_cookies! ⇒ Object
Deletes all cookies from the runtime.
-
.compare(uri1, uri2, opts = {}) ⇒ Object
See Kronk#compare.
-
.config ⇒ Object
Read the Kronk config hash.
-
.cookie_jar ⇒ Object
Returns the kronk cookie jar.
-
.find_const(name_or_file, case_insensitive = false) ⇒ Object
Find a fully qualified ruby namespace/constant.
-
.history ⇒ Object
Returns the Kronk history array of accessed URLs.
-
.load_config(filepath = DEFAULT_CONFIG_FILE) ⇒ Object
Load a config file and apply to Kronk.config.
-
.load_cookie_jar(file = nil) ⇒ Object
Load the saved cookies file.
-
.middleware ⇒ Object
Returns an array of middleware to use around requests.
-
.oauth_config ⇒ Object
Returns the Kronk::OAuthConfig instance.
-
.parser_for(content_type) ⇒ Object
Returns the config-defined parser class for a given content type.
-
.request(uri, opts = {}) ⇒ Object
See Kronk#request.
-
.save_cookie_jar(file = nil) ⇒ Object
Save the cookie jar to file.
-
.save_history ⇒ Object
Writes the URL history to the history file.
-
.use(mware) ⇒ Object
Assign middleware to use.
Instance Method Summary collapse
-
#compare(uri1, uri2) ⇒ Object
Make requests, parse the responses and compare the data.
-
#initialize(opts = {}) ⇒ Kronk
constructor
Create a Kronk instance to keep references to all request, response, and diff data.
-
#oauth_options_for_uri(uri) ⇒ Object
Returns oauth config for the given uri.
-
#options_for_uri(uri) ⇒ Object
Returns merged config-defined options for a given uri.
-
#request(uri) ⇒ Object
Returns a Response instance from a url, file, or IO as a String.
-
#request_explicit(opts) ⇒ Object
Request without autofilling options.
Constructor Details
#initialize(opts = {}) ⇒ Kronk
Create a Kronk instance to keep references to all request, response, and diff data.
Supports the following options:
- :data
-
Hash/String - the data to pass to the http request
- :query
-
Hash/String - the data to append to the http request path
- :follow_redirects
-
Integer/Boolean - number of times to follow redirects
- :headers
-
Hash - extra headers to pass to the request
- :http_method
-
Symbol - the http method to use; defaults to :get
- :user_agent
-
String - user agent string or alias; defaults to ‘kronk’
- :auth
-
Hash - must contain :username and :password; defaults to nil
- :oauth
-
Hash - :consumer_key, :token :consumer_secret, :token_secret
- :proxy
-
Hash/String - http proxy to use; defaults to nil
- :show_headers
-
Boolean/String/Array - which headers to show in output
- :parser
-
Object/String - the parser to use for the body; default nil
- :raw
-
Boolean - run diff on raw strings
- :transform
-
Array - Action/path(s) pairs to modify data.
Deprecated Options:
- :ignore_data
-
String/Array - Removes the data from given data paths
- :only_data
-
String/Array - Extracts the data from given data paths
306 307 308 309 310 311 312 313 314 |
# File 'lib/kronk.rb', line 306 def initialize opts={} @options = opts @diff = nil @responses = [] @response = nil meth = method(:request_explicit) @app = Kronk.middleware.inject(meth){|app, mware| mware.new(app) } end |
Instance Attribute Details
#diff ⇒ Object
Returns the value of attribute diff.
280 281 282 |
# File 'lib/kronk.rb', line 280 def diff @diff end |
#options ⇒ Object
Returns the value of attribute options.
280 281 282 |
# File 'lib/kronk.rb', line 280 def @options end |
#response ⇒ Object
Returns the value of attribute response.
280 281 282 |
# File 'lib/kronk.rb', line 280 def response @response end |
#responses ⇒ Object
Returns the value of attribute responses.
280 281 282 |
# File 'lib/kronk.rb', line 280 def responses @responses end |
Class Method Details
.clear_cookies! ⇒ Object
Deletes all cookies from the runtime. If Kronk.run is in use, will write the change to the cookies file as well.
187 188 189 |
# File 'lib/kronk.rb', line 187 def self. @cookie_jar = CookieJar::Jar.new end |
.compare(uri1, uri2, opts = {}) ⇒ Object
266 267 268 |
# File 'lib/kronk.rb', line 266 def self.compare uri1, uri2, opts={} new(opts).compare uri1, uri2 end |
.config ⇒ Object
Read the Kronk config hash.
51 52 53 |
# File 'lib/kronk.rb', line 51 def self.config @config ||= DEFAULT_CONFIG end |
.cookie_jar ⇒ Object
Returns the kronk cookie jar.
195 196 197 |
# File 'lib/kronk.rb', line 195 def self. @cookie_jar ||= end |
.find_const(name_or_file, case_insensitive = false) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/kronk.rb', line 107 def self.find_const name_or_file, case_insensitive=false return name_or_file unless String === name_or_file if name_or_file =~ /[^:]:([^:]+)$/ req_file = $1 i = $1.length + 2 const = name_or_file[0..-i] begin require req_file rescue LoadError require File.(req_file) end find_const const elsif name_or_file.include? File::SEPARATOR begin require name_or_file rescue LoadError require File.(name_or_file) end namespace = File.basename name_or_file, ".rb" consts = File.dirname(name_or_file).split(File::SEPARATOR) consts << namespace name = "" until consts.empty? name = "::" << consts.pop.to_s << name const = find_const name, true rescue nil return const if const end raise NameError, "no constant match for #{name_or_file}" else consts = name_or_file.to_s.split "::" curr = self until consts.empty? do const = consts.shift next if const.to_s.empty? if case_insensitive const.gsub!(/(^|[\-_.]+)([a-z0-9])/i){|m| m[-1,1].upcase} const = (curr.constants | Object.constants).find do |c| c.to_s.downcase == const.to_s.downcase end end curr = curr.const_get const.to_s end curr end end |
.history ⇒ Object
Returns the Kronk history array of accessed URLs.
226 227 228 229 230 231 |
# File 'lib/kronk.rb', line 226 def self.history path = self.config[:history_file] @history ||= File.read(path).split($/) if File.file?(path) @history ||= [] @history end |
.load_config(filepath = DEFAULT_CONFIG_FILE) ⇒ Object
Load a config file and apply to Kronk.config.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/kronk.rb', line 67 def self.load_config filepath=DEFAULT_CONFIG_FILE conf = YAML.load_file filepath conf.each do |key, value| skey = key.to_sym case skey when :content_types, :user_agents conf[key].each{|k,v| self.config[skey][k.to_s] = v } when :requires self.config[skey].concat Array(value) when :uri_options conf[key].each do |matcher, opts| self.config[skey][matcher.to_s] = opts opts.keys.each{|k| opts[k.to_sym] = opts.delete(k) if String === k} end else self.config[skey] = value end end @oauth_config = Kronk::OAuthConfig.load_file(DEFAULT_OAUTH_FILE) if File.file?(DEFAULT_OAUTH_FILE) end |
.load_cookie_jar(file = nil) ⇒ Object
Load the saved cookies file. Defaults to Kronk::config.
203 204 205 206 207 208 209 |
# File 'lib/kronk.rb', line 203 def self. file=nil file ||= config[:cookies_file] @cookie_jar = YAML.load_file file if File.file? file @cookie_jar ||= CookieJar::Jar.new @cookie_jar. @cookie_jar end |
.middleware ⇒ Object
Returns an array of middleware to use around requests.
249 250 251 |
# File 'lib/kronk.rb', line 249 def self.middleware @middleware ||= [] end |
.oauth_config ⇒ Object
Returns the Kronk::OAuthConfig instance
59 60 61 |
# File 'lib/kronk.rb', line 59 def self.oauth_config @oauth_config ||= Kronk::OAuthConfig.new end |
.parser_for(content_type) ⇒ Object
Returns the config-defined parser class for a given content type.
169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/kronk.rb', line 169 def self.parser_for content_type parser_pair = config[:content_types].select do |key, value| (content_type =~ %r{#{key}([^\w]|$)}) && value end.to_a return if parser_pair.empty? parser = parser_pair[0][1] parser = find_const parser if String === parser || Symbol === parser parser end |
.request(uri, opts = {}) ⇒ Object
275 276 277 |
# File 'lib/kronk.rb', line 275 def self.request uri, opts={} new(opts).request uri end |
.save_cookie_jar(file = nil) ⇒ Object
Save the cookie jar to file.
215 216 217 218 219 220 |
# File 'lib/kronk.rb', line 215 def self. file=nil file ||= config[:cookies_file] File.open(file, "w") do |f| f.write @cookie_jar.to_yaml end end |
.save_history ⇒ Object
Writes the URL history to the history file.
237 238 239 240 241 242 243 |
# File 'lib/kronk.rb', line 237 def self.save_history history_str = self.history.uniq[0..self.config[:max_history]].join($/) File.open self.config[:history_file], "w" do |file| file.write history_str end end |
.use(mware) ⇒ Object
Assign middleware to use.
257 258 259 |
# File 'lib/kronk.rb', line 257 def self.use mware self.middleware.unshift mware end |
Instance Method Details
#compare(uri1, uri2) ⇒ Object
Make requests, parse the responses and compare the data. Query arguments may be set to the special value :cache to use the last live http response retrieved.
Assigns @response, @responses, @diff. Returns the Diff instance.
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/kronk.rb', line 324 def compare uri1, uri2 str1 = str2 = "" res1 = res2 = nil t1 = Thread.new do res1 = request uri1 str1 = res1.stringify end t2 = Thread.new do res2 = request uri2 str2 = res2.stringify end t1.join t2.join @responses = [res1, res2] @response = res2 opts = {:labels => [res1.uri, res2.uri]}.merge @options @diff = Diff.new str1, str2, opts end |
#oauth_options_for_uri(uri) ⇒ Object
Returns oauth config for the given uri
422 423 424 425 426 |
# File 'lib/kronk.rb', line 422 def uri uri = "http://#{uri}" unless uri.start_with?("http") uri_host = URI.parse(uri.to_s).host return self.class.oauth_config.get_active_for_host(uri_host) end |
#options_for_uri(uri) ⇒ Object
Returns merged config-defined options for a given uri. Values in cmd_opts take precedence. Returns cmd_opts Hash if none found.
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
# File 'lib/kronk.rb', line 434 def uri out_opts = @options.dup Kronk.config[:uri_options].each do |matcher, opts| next unless (uri == matcher || uri =~ %r{#{matcher}}) && Hash === opts opts.each do |key, val| if out_opts[key].nil? out_opts[key] = val next end case key # Hash or uri query String when :data, :query, :form, :form_upload val = Request.parse_nested_query val if String === val out_opts[key] = Request.parse_nested_query out_opts[key] if String === out_opts[key] out_opts[key] = val.merge out_opts[key], &DEEP_MERGE # Hashes when :headers, :auth, :oauth out_opts[key] = val.merge out_opts[key] # Proxy hash or String when :proxy if Hash === val && Hash === out_opts[key] out_opts[key] = val.merge out_opts[key] elsif Hash === val && String === out_opts[key] val[:address] = out_opts[key] out_opts[key] = val elsif String === val && Hash === out_opts[key] out_opts[key][:address] ||= val end # Response headers - Boolean, String, or Array when :show_headers next if out_opts.has_key?(key) && (out_opts[key].class != Array || val == true || val == false) out_opts[key] = (val == true || val == false) ? val : Array(out_opts[key]) | Array(val) # String or Array when :only_data, :ignore_data out_opts[key] = Array(out_opts[key]) | Array(val) # Array concatination when :transform out_opts[key] = Array(val).concat Array(out_opts[key]) end end end if !out_opts[:oauth] oauth = (uri) out_opts[:oauth] = oauth if oauth end out_opts end |
#request(uri) ⇒ Object
Returns a Response instance from a url, file, or IO as a String. Assigns @response, @responses, @diff.
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
# File 'lib/kronk.rb', line 353 def request uri = Kronk.config[:no_uri_options] ? @options : (uri) .merge!(:uri => uri) resp = @app.call rdir = [:follow_redirects] while resp.redirect? && (rdir == true || rdir.to_s.to_i > 0) uri = resp.location Cmd.verbose "Following redirect to #{resp.location}" if defined?(Cmd) resp = resp.follow_redirect (resp.location) rdir = rdir - 1 if Fixnum === rdir end resp.parser = [:parser] if [:parser] resp.stringify_opts = @responses = [resp] @response = resp @diff = nil resp rescue Errno::ENOENT => e raise NotFoundError, e. rescue OpenSSL::SSL::SSLError raise InvalidCertificate, "The remote SSL certificate could not be trusted" rescue SocketError, Errno::ECONNREFUSED => e raise NotFoundError, "#{uri} could not be found (#{e.class})" rescue Timeout::Error raise TimeoutError, "#{uri} took too long to respond" end |
#request_explicit(opts) ⇒ Object
Request without autofilling options.
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/kronk.rb', line 393 def request_explicit opts uri = opts.delete(:uri) if IO === uri || StringIO === uri || BufferedIO === uri Cmd.verbose "Reading IO #{uri}" if defined?(Cmd) Response.new uri, opts elsif File.file? uri.to_s Cmd.verbose "Reading file: #{uri}\n" if defined?(Cmd) Response.read_file uri, opts else req = Request.new uri, opts Cmd.verbose "Retrieving URL: #{req.uri}\n" if defined?(Cmd) resp = req.stream opts hist_uri = req.uri.to_s[0..-req.uri.request_uri.length] hist_uri = hist_uri[(req.uri.scheme.length + 3)..-1] Kronk.history << hist_uri resp end end |