silent_fetcher 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a66a1d3468c26c27472a7d49376ec09fb7c9dc8c
4
+ data.tar.gz: 26f4f27d56355dfab4f3f6451b37542f4d6ba88e
5
+ SHA512:
6
+ metadata.gz: 9f45900a0856655f886e74d17dbe86a0c6fb878c388e11fdd01729d830efb10fa0cc245edb36a9f3e879d73fad32a4118adef3114e2baebb9f2cee780c26a298
7
+ data.tar.gz: 32dfef7e1137d222401379b4d61dfa3109480487cf5296701f4e23cee3478dc09db910fbeaa8c10fed469a602b0b92ad8442ebf0882d292e0a3c7b2a77764c51
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ vendor/bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in silent_fetcher.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Takashi Chiba
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # SilentFetcher
2
+
3
+ SilentFetcher aims to reduce that programmers write common error handling several times.
4
+
5
+ It ignores errors which are commonly handled (and often be ignored) when fetching URL and has also an ability to parse HTML/RSS, using [nokogiri](https://github.com/sparklemotion/nokogiri) and [feedjira](https://github.com/feedjira/feedjira).
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'silent_fetcher'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install silent_fetcher
20
+
21
+ ## Usage
22
+
23
+ ```rb
24
+ # You have to configure before using this.
25
+ SilentFetcher.configure do |config|
26
+ config.user_agent = "YOUR AGENT NAME"
27
+ end
28
+
29
+ url = "https://news.ycombinator.com/rss"
30
+
31
+ response_body = SilentFetcher.fetch(url)
32
+ #=> <rss version=\"2.0\"><channel><title>Hacker News</title><link>https: ...
33
+
34
+ response = SilentFetcher.parse_feed(url)
35
+ #=> #<Feedjira::Parser::RSS:0x007ffe7c1d7dd8 @version="2.0", @title="Hacker News", @url="https://news.ycombinator.com/", ...
36
+
37
+ url = "https://www.google.co.jp"
38
+
39
+ response = SilentFetcher.parse_html(url)
40
+ #=> #<Nokogiri::HTML::Document:0x3ff86d00cbc0 name="document" children=[#<Nokogiri::XML::DTD:0x3ff86d00c0e4 name="html">, ...
41
+ ```
42
+
43
+ ## Contributing
44
+
45
+ 1. Fork it ( https://github.com/tachiba/silent_fetcher/fork )
46
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
47
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
48
+ 4. Push to the branch (`git push origin my-new-feature`)
49
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ end
8
+
9
+ task :default => :test
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'timeout'
4
+ require 'open-uri'
5
+ require 'resolv-replace'
6
+ require 'uri'
7
+ require 'httparty'
8
+ require 'feedjira'
9
+
10
+ require 'silent_fetcher/configuration'
11
+ require 'silent_fetcher/version'
12
+
13
+ module SilentFetcher
14
+ class ExpectedError < StandardError; end
15
+
16
+ DEFAULT_CHARSET = 'UTF-8'
17
+ DEFAULT_RETRY_COUNT = 3
18
+ DEFAULT_TIMEOUT = 60
19
+
20
+ EXPECTED_ERRORS = {
21
+ 'URI::InvalidURIError' => [/the scheme http does not accept registry part/, /bad URI/],
22
+ 'ArgumentError' => [/invalid byte sequence/],
23
+ 'SocketError' => [/Hostname not known/],
24
+ 'RuntimeError' => [/HTTP redirection loop/],
25
+ 'EOFError' => [/end of file reached/],
26
+ 'Errno::EHOSTUNREACH' => [/No route to host/],
27
+ 'Errno::ECONNRESET' => [/Connection reset by peer/],
28
+ 'Errno::ECONNREFUSED' => [/Connection refused/],
29
+ 'Errno::ENETUNREACH' => [/Network is unreachable/],
30
+ 'Errno::ETIMEDOUT' => [],
31
+ 'HTTParty::RedirectionTooDeep' => [],
32
+ 'OpenURI::HTTPError' => [],
33
+ 'OpenSSL::SSL::SSLError' => [/SSL_connect returned=1 errno=0 state=SSLv3/]
34
+ }
35
+ RETRYABLE_ERRORS = [Net::OpenTimeout, Net::ReadTimeout]
36
+
37
+ class << self
38
+ attr_accessor :configuration
39
+
40
+ def parse_html(url, charset: DEFAULT_CHARSET)
41
+ Nokogiri::HTML(fetch(url), nil, charset)
42
+ end
43
+
44
+ def parse_feed(url)
45
+ Feedjira::Feed.parse(
46
+ fetch(url)
47
+ )
48
+ end
49
+
50
+ def fetch(url, retry_count: DEFAULT_RETRY_COUNT, allow_no_response: false)
51
+ response = HTTParty.get(url, fetch_options)
52
+
53
+ if response.body.size == 0 && !allow_no_response
54
+ raise SilentFetcher::ExpectedError, "response.body.size == 0: #{url}"
55
+ end
56
+
57
+ response.body
58
+
59
+ rescue *RETRYABLE_ERRORS => e
60
+ if retry_count > 0
61
+ retry_count -= 1
62
+ retry
63
+ else
64
+ raise SilentFetcher::ExpectedError, "#{e.message}: #{url}"
65
+ end
66
+
67
+ rescue => e
68
+ class_string = e.class.to_s
69
+
70
+ if EXPECTED_ERRORS[class_string] &&
71
+ (EXPECTED_ERRORS[class_string].none? || EXPECTED_ERRORS[class_string].any? {|m| e.message =~ m })
72
+ raise SilentFetcher::ExpectedError, "#{e.class}: #{e.message} by #{url}"
73
+ else
74
+ raise e
75
+ end
76
+ end
77
+
78
+ def configure
79
+ self.configuration ||= Configuration.new
80
+ yield(configuration)
81
+ end
82
+
83
+ def expected_error_classes
84
+ EXPECTED_ERRORS.keys.map(&:constantize)
85
+ end
86
+
87
+ private
88
+
89
+ def fetch_options
90
+ {
91
+ headers: {
92
+ 'User-Agent' => configuration.user_agent
93
+ },
94
+ timeout: DEFAULT_TIMEOUT
95
+ }
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SilentFetcher
4
+ class Configuration
5
+ attr_accessor :user_agent
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SilentFetcher
4
+ VERSION = "0.0.3"
5
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'silent_fetcher/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "silent_fetcher"
8
+ spec.version = SilentFetcher::VERSION
9
+ spec.authors = ["Takashi Chiba"]
10
+ spec.email = ["contact@takashi.me"]
11
+ spec.summary = %q{Fetch response silently}
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency 'httparty', '~> 0.13'
21
+ spec.add_dependency 'nokogiri', '~> 1.6'
22
+ spec.add_dependency 'feedjira', '~> 1.3'
23
+
24
+ spec.add_development_dependency 'minitest', '~> 5.3.3'
25
+ spec.add_development_dependency 'bundler', '~> 1.6'
26
+ spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'vcr', '~> 2.9'
28
+ spec.add_development_dependency 'webmock', '~> 1.18'
29
+ end
@@ -0,0 +1,13 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require 'vcr'
4
+
5
+ require 'nokogiri'
6
+ require 'feedjira'
7
+
8
+ VCR.configure do |c|
9
+ c.cassette_library_dir = 'test/vcr'
10
+ c.hook_into :webmock
11
+ end
12
+
13
+ require 'silent_fetcher'
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ class SilentFetcherTest < Minitest::Test
4
+ USER_AGENT = "SilentFetcher/#{SilentFetcher::VERSION}"
5
+
6
+ def setup
7
+ SilentFetcher.configure do |config|
8
+ config.user_agent = USER_AGENT
9
+ end
10
+ end
11
+
12
+ def test_fetch
13
+ VCR.use_cassette('yahoo') do
14
+ assert SilentFetcher.fetch('http://www.yahoo.co.jp/')
15
+ end
16
+ end
17
+
18
+ def test_parse_html
19
+ VCR.use_cassette('yahoo') do
20
+ response = SilentFetcher.parse_html('http://www.yahoo.co.jp/')
21
+
22
+ assert_instance_of Nokogiri::HTML::Document, response
23
+ end
24
+ end
25
+
26
+ def test_parse_feed
27
+ VCR.use_cassette('livedoor_rss') do
28
+ response = SilentFetcher.parse_feed('http://news.livedoor.com/topics/rss/top.xml')
29
+
30
+ assert_instance_of Feedjira::Parser::RSS, response
31
+ end
32
+ end
33
+
34
+ def test_fetch_options
35
+ fetch_options = SilentFetcher.send(:fetch_options)
36
+
37
+ assert_equal USER_AGENT, fetch_options[:headers]['User-Agent']
38
+ end
39
+ end
@@ -0,0 +1,231 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://news.livedoor.com/topics/rss/top.xml
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML,
12
+ like Gecko) Chrome/27.0.1453.110 Safari/537.36
13
+ response:
14
+ status:
15
+ code: 200
16
+ message: OK
17
+ headers:
18
+ Date:
19
+ - Sun, 22 Jun 2014 12:35:38 GMT
20
+ Server:
21
+ - Apache
22
+ Set-Cookie:
23
+ - ldsuid=115.165.102.229.1403440538009698; path=/; expires=Sat, 20-Sep-14 12:35:38
24
+ GMT
25
+ Last-Modified:
26
+ - Sun, 22 Jun 2014 12:30:33 GMT
27
+ Etag:
28
+ - '"20db-4fc6be48d2c40"'
29
+ Accept-Ranges:
30
+ - bytes
31
+ Content-Length:
32
+ - '8411'
33
+ Vary:
34
+ - Accept-Encoding,User-Agent
35
+ Connection:
36
+ - close
37
+ Content-Type:
38
+ - application/xml
39
+ body:
40
+ encoding: ASCII-8BIT
41
+ string: !binary |-
42
+ PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHJzcyB2
43
+ ZXJzaW9uPSIyLjAiIHhtbG5zOmF0b209Imh0dHA6Ly93d3cudzMub3JnLzIw
44
+ MDUvQXRvbSIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50
45
+ cy8xLjEvIj4KPGNoYW5uZWw+CjxhdG9tOmxpbmsgaHJlZj0iaHR0cDovL25l
46
+ d3MubGl2ZWRvb3IuY29tL3Jzcy90b3BpY3MvdG9wLnhtbCIgcmVsPSJzZWxm
47
+ IiB0eXBlPSJhcHBsaWNhdGlvbi9yc3MreG1sIiAvPgo8bGFuZ3VhZ2U+amE8
48
+ L2xhbmd1YWdlPgo8dGl0bGU+44Op44Kk44OW44OJ44Ki44OL44Ol44O844K5
49
+ IC0g5Li76KaB44OI44OU44OD44Kv44K5PC90aXRsZT4KPGxpbms+aHR0cDov
50
+ L25ld3MubGl2ZWRvb3IuY29tPC9saW5rPgo8Z2VuZXJhdG9yPmh0dHA6Ly9u
51
+ ZXdzLmxpdmVkb29yLmNvbTwvZ2VuZXJhdG9yPgo8ZGVzY3JpcHRpb24+44Op
52
+ 44Kk44OW44OJ44Ki44OL44Ol44O844K5IC0g5Li76KaB44OI44OU44OD44Kv
53
+ 44K5PC9kZXNjcmlwdGlvbj4KPGxhc3RCdWlsZERhdGU+U3VuLCAyMiBKdW4g
54
+ MjAxNCAyMToxOTowNiArMDkwMDwvbGFzdEJ1aWxkRGF0ZT4KPGl0ZW0+CiAg
55
+ ICA8dGl0bGU+44OQ44Kk44OI5L2c5qWt5ZOh44GM6aCt44KS5q6044KJ44KM
56
+ 5q275LqhPC90aXRsZT4KICAgIDxsaW5rPmh0dHA6Ly9uZXdzLmxpdmVkb29y
57
+ LmNvbS9hcnRpY2xlL2RldGFpbC84OTY1MzUyLzwvbGluaz4KICAgIDxkZXNj
58
+ cmlwdGlvbj4KICAgICZsdDthIGhyZWY9JnF1b3Q7aHR0cDovL25ld3MubGl2
59
+ ZWRvb3IuY29tL2FydGljbGUvZGV0YWlsLzg5NjUzNTIvJnF1b3Q7Jmd0O+io
60
+ mOS6i+OCkuiqreOCgCZsdDsvYSZndDsKICAgIDwvZGVzY3JpcHRpb24+CiAg
61
+ ICA8bW9iaWxlPjA8L21vYmlsZT4KICAgIDxwdWJEYXRlPlN1biwgMjIgSnVu
62
+ IDIwMTQgMjA6NDk6MDAgKzA5MDA8L3B1YkRhdGU+CiAgICA8Z3VpZD5odHRw
63
+ Oi8vbmV3cy5saXZlZG9vci5jb20vYXJ0aWNsZS9kZXRhaWwvODk2NTM1Mi88
64
+ L2d1aWQ+CjwvaXRlbT4KPGl0ZW0+CiAgICA8dGl0bGU+5pC65biv44GP44GP
65
+ 44KL4oCm5Lit5Zu944Gn6YKm5Lq644GM55uX5pKuPC90aXRsZT4KICAgIDxs
66
+ aW5rPmh0dHA6Ly9uZXdzLmxpdmVkb29yLmNvbS9hcnRpY2xlL2RldGFpbC84
67
+ OTY1MzUwLzwvbGluaz4KICAgIDxkZXNjcmlwdGlvbj4KICAgIOOBluOBo+OB
68
+ j+OCiuiogOOBhuOBqAogICAgJmx0O2JyIC8mZ3Q7CiAgICAgICZsdDt1bCZn
69
+ dDsKICAgICAgICAmbHQ7bGkmZ3Q75Lit5Zu944GnMjHml6XjgIHlpbPmgKfj
70
+ ga7jgrnjgqvjg7zjg4jjga7kuK3jgpLnm5fmkq7jgZfjgZ/jgajjgZfjgabm
71
+ l6XmnKzkurrjga7nlLfjgYzpgK7mjZXjgZXjgozjgZ8mbHQ7L2xpJmd0Owog
72
+ ICAgICAgICZsdDtsaSZndDvooqvlrrPlpbPmgKfjga7pgJrloLHjgafnlLfj
73
+ ga/pgK7mjZXjgZXjgozjgIHotrPjgavmkLrluK/pm7voqbHjgpLjgY/jgY/j
74
+ gorjgaTjgZHjgabjgYTjgZ/jgajnmbroppombHQ7L2xpJmd0OwogICAgICAg
75
+ ICZsdDtsaSZndDvnlLfjga/ml6XmnKzkvIHmpa3jga7pp5DlnKjlk6Hjgafj
76
+ gIEz44Kr5pyI5YmN44Gr54++5Zyw44Gr6LW05Lu744GX44Gm44GN44Gf44Gw
77
+ 44GL44KK44Gg44Gj44GfDSZsdDsvbGkmZ3Q7CiAgICAgICZsdDsvdWwmZ3Q7
78
+ CiAgICAmbHQ7YSBocmVmPSZxdW90O2h0dHA6Ly9uZXdzLmxpdmVkb29yLmNv
79
+ bS9hcnRpY2xlL2RldGFpbC84OTY1MzUwLyZxdW90OyZndDvoqJjkuovjgpLo
80
+ qq3jgoAmbHQ7L2EmZ3Q7CiAgICA8L2Rlc2NyaXB0aW9uPgogICAgPG1vYmls
81
+ ZT4wPC9tb2JpbGU+CiAgICA8cHViRGF0ZT5TdW4sIDIyIEp1biAyMDE0IDIw
82
+ OjMyOjAwICswOTAwPC9wdWJEYXRlPgogICAgPGd1aWQ+aHR0cDovL25ld3Mu
83
+ bGl2ZWRvb3IuY29tL2FydGljbGUvZGV0YWlsLzg5NjUzNTAvPC9ndWlkPgo8
84
+ L2l0ZW0+CjxpdGVtPgogICAgPHRpdGxlPumAhuS4iuOBl+OBpuiyoeW4g+aK
85
+ leOBkuOBn+aXpeacrOS6uuOBjOmAgeaknDwvdGl0bGU+CiAgICA8bGluaz5o
86
+ dHRwOi8vbmV3cy5saXZlZG9vci5jb20vYXJ0aWNsZS9kZXRhaWwvODk2NTA4
87
+ NS88L2xpbms+CiAgICA8ZGVzY3JpcHRpb24+CiAgICDjgZbjgaPjgY/jgoro
88
+ qIDjgYbjgagKICAgICZsdDticiAvJmd0OwogICAgICAmbHQ7dWwmZ3Q7CiAg
89
+ ICAgICAgJmx0O2xpJmd0O+WPsOa5vuOBruepuua4r+OBpzIw5pel44CB6YCG
90
+ 5LiK44GX44Gm6LKh5biD44KS5oqV44GS44Gf5pel5pys5Lq644GM6YCB5qSc
91
+ 44GV44KM44GfJmx0Oy9saSZndDsKICAgICAgICAmbHQ7bGkmZ3Q75omL6I23
92
+ 54mp5qSc5p+744KS5Y+X44GR44Gf6Zqb44CB6KaP5a6a5pWw5Lul5LiK44Gu
93
+ 44Op44Kk44K/44O844Gu5oyB44Gh6L6844G/44KS5oyH5pGY44GV44KM6YCG
94
+ 5LiKJmx0Oy9saSZndDsKICAgICAgICAmbHQ7bGkmZ3Q76I2354mp44Gu5Lit
95
+ 44KS56K66KqN44GX44KI44GG44Go44GX44Gf5aWz5oCn6IG35ZOh44Gr6LKh
96
+ 5biD44KS5oqV44GS44Gk44GR44CB6LKg5YK344GV44Gb44GfJmx0Oy9saSZn
97
+ dDsKICAgICAgJmx0Oy91bCZndDsKICAgICZsdDthIGhyZWY9JnF1b3Q7aHR0
98
+ cDovL25ld3MubGl2ZWRvb3IuY29tL2FydGljbGUvZGV0YWlsLzg5NjUwODUv
99
+ JnF1b3Q7Jmd0O+iomOS6i+OCkuiqreOCgCZsdDsvYSZndDsKICAgIDwvZGVz
100
+ Y3JpcHRpb24+CiAgICA8bW9iaWxlPjE8L21vYmlsZT4KICAgIDxwdWJEYXRl
101
+ PlN1biwgMjIgSnVuIDIwMTQgMTY6NTg6NTAgKzA5MDA8L3B1YkRhdGU+CiAg
102
+ ICA8Z3VpZD5odHRwOi8vbmV3cy5saXZlZG9vci5jb20vYXJ0aWNsZS9kZXRh
103
+ aWwvODk2NTA4NS88L2d1aWQ+CjwvaXRlbT4KPGl0ZW0+CiAgICA8dGl0bGU+
104
+ 44K544K344Ot44O844CBMzDlkajlubToqJjlv7XjgafpmZDlrprnm5vjgoo8
105
+ L3RpdGxlPgogICAgPGxpbms+aHR0cDovL25ld3MubGl2ZWRvb3IuY29tL2Fy
106
+ dGljbGUvZGV0YWlsLzg5NjUzNDUvPC9saW5rPgogICAgPGRlc2NyaXB0aW9u
107
+ PgogICAg44GW44Gj44GP44KK6KiA44GG44GoCiAgICAmbHQ7YnIgLyZndDsK
108
+ ICAgICAgJmx0O3VsJmd0OwogICAgICAgICZsdDtsaSZndDvjgrnjgrfjg63j
109
+ g7zjga/nj77lnKjjgIEzMOWRqOW5tOOCkuiomOW/teOBl+OBpumZkOWumuOD
110
+ oeODi+ODpeODvOOCkuiyqeWjsuOBl+OBpuOBhOOCiyZsdDsvbGkmZ3Q7CiAg
111
+ ICAgICAgJmx0O2xpJmd0O+mAmuW4uOacn+OBp+OBr+Wun+ePvuS4jeWPr+iD
112
+ veOBquOAjOi0heayojPosqvnm5vjgorjgI3jgarjganjgpLjg6njgqTjg7Pj
113
+ g4rjg4Pjg5cmbHQ7L2xpJmd0OwogICAgICAgICZsdDtsaSZndDvjgIzjgrnj
114
+ grfjg63jg7zjga7nm7TnkIPjgZnjgZfjgI3jgafjga/jgIHnj77lnKjjgIHj
115
+ gIzlpKfliIfjgorjgbPjgpPjgajjgo3jgI3jgpLosqnlo7LkuK0mbHQ7L2xp
116
+ Jmd0OwogICAgICAmbHQ7L3VsJmd0OwogICAgJmx0O2EgaHJlZj0mcXVvdDto
117
+ dHRwOi8vbmV3cy5saXZlZG9vci5jb20vYXJ0aWNsZS9kZXRhaWwvODk2NTM0
118
+ NS8mcXVvdDsmZ3Q76KiY5LqL44KS6Kqt44KAJmx0Oy9hJmd0OwogICAgPC9k
119
+ ZXNjcmlwdGlvbj4KICAgIDxtb2JpbGU+MTwvbW9iaWxlPgogICAgPHB1YkRh
120
+ dGU+U3VuLCAyMiBKdW4gMjAxNCAyMDozMTozMiArMDkwMDwvcHViRGF0ZT4K
121
+ ICAgIDxndWlkPmh0dHA6Ly9uZXdzLmxpdmVkb29yLmNvbS9hcnRpY2xlL2Rl
122
+ dGFpbC84OTY1MzQ1LzwvZ3VpZD4KPC9pdGVtPgo8aXRlbT4KICAgIDx0aXRs
123
+ ZT7jg6TjgrjllY/poYzjgIHov73msYLorbDlk6HjgavljZHliqPjgapGQVg8
124
+ L3RpdGxlPgogICAgPGxpbms+aHR0cDovL25ld3MubGl2ZWRvb3IuY29tL2Fy
125
+ dGljbGUvZGV0YWlsLzg5NjUwNTYvPC9saW5rPgogICAgPGRlc2NyaXB0aW9u
126
+ PgogICAg44GW44Gj44GP44KK6KiA44GG44GoCiAgICAmbHQ7YnIgLyZndDsK
127
+ ICAgICAgJmx0O3VsJmd0OwogICAgICAgICZsdDtsaSZndDsxOOaXpeOBrumD
128
+ veitsOS8muOBp+OAgeWls+aAp+itsOWToeOBq+WvvuOBl+OCu+OCr+ODj+OD
129
+ qeOBqOOCguOBqOOCjOOCi+ODpOOCuOOBjOmjm+OCk+OBoOWVj+mhjCZsdDsv
130
+ bGkmZ3Q7CiAgICAgICAgJmx0O2xpJmd0O+WVj+mhjOOCkui/veWPiuOBmeOC
131
+ i+OBiuOBqOOBjeOBn+mDveitsOOBq+OAgeOAjOS4reWCt+ODu+W8t+i/q+OA
132
+ jeODleOCoeOCr+OCueOBjOWxiuOBhOOBpuOBhOOBn+OBqOWIpOaYjiZsdDsv
133
+ bGkmZ3Q7CiAgICAgICAgJmx0O2xpJmd0O+aWh+mdouOBq+OBr+OAgeOAjOat
134
+ u+OCk+OBp+ipq+OBs+OCi+immuaCn+OAjeOBquOBqeOBruepj+OChOOBi+OB
135
+ p+OBquOBhOihqOePvuOCguOBguOBo+OBn+OBqOOBhOOBhiZsdDsvbGkmZ3Q7
136
+ CiAgICAgICZsdDsvdWwmZ3Q7CiAgICAmbHQ7YSBocmVmPSZxdW90O2h0dHA6
137
+ Ly9uZXdzLmxpdmVkb29yLmNvbS9hcnRpY2xlL2RldGFpbC84OTY1MDU2LyZx
138
+ dW90OyZndDvoqJjkuovjgpLoqq3jgoAmbHQ7L2EmZ3Q7CiAgICA8L2Rlc2Ny
139
+ aXB0aW9uPgogICAgPG1vYmlsZT4xPC9tb2JpbGU+CiAgICA8cHViRGF0ZT5T
140
+ dW4sIDIyIEp1biAyMDE0IDE3OjM2OjM3ICswOTAwPC9wdWJEYXRlPgogICAg
141
+ PGd1aWQ+aHR0cDovL25ld3MubGl2ZWRvb3IuY29tL2FydGljbGUvZGV0YWls
142
+ Lzg5NjUwNTYvPC9ndWlkPgo8L2l0ZW0+CjxpdGVtPgogICAgPHRpdGxlPuW9
143
+ vOawj+OBq+OBr+iogOOBiOOBquOBhD8g5aWz5oCn44Gu44OV44Kn44OBPC90
144
+ aXRsZT4KICAgIDxsaW5rPmh0dHA6Ly9uZXdzLmxpdmVkb29yLmNvbS9hcnRp
145
+ Y2xlL2RldGFpbC84OTY0NDMwLzwvbGluaz4KICAgIDxkZXNjcmlwdGlvbj4K
146
+ ICAgIOOBluOBo+OBj+OCiuiogOOBhuOBqAogICAgJmx0O2JyIC8mZ3Q7CiAg
147
+ ICAgICZsdDt1bCZndDsKICAgICAgICAmbHQ7bGkmZ3Q75YON44GP5aWz5oCn
148
+ 44KS5a++6LGh44Gr44CB5b285rCP44Gr44Gv44GE44GI44Gq44GE44OV44Kn
149
+ 44OB44KS44Ki44Oz44Kx44O844OI6Kq/5p+744GX44GfJmx0Oy9saSZndDsK
150
+ ICAgICAgICAmbHQ7bGkmZ3Q744G344Gr44G344Gr44GX44Gf55S35oCn44GM
151
+ 44KI44GE44Go44GE44GG5aWz5oCn44KE44CB55S35oCn44Gu5rex54iq44GM
152
+ 44KI44GE44Go44GE44GG5aWz5oCnJmx0Oy9saSZndDsKICAgICAgICAmbHQ7
153
+ bGkmZ3Q76Ieq5YiG44GM6Ium5omL44Gq55CG57O75YiG6YeO44Gr6Kmz44GX
154
+ 44GE5Lq644Gr5byx44GE44CB44Go44GE44GG5aWz5oCn44KC44GE44GfDSZs
155
+ dDsvbGkmZ3Q7CiAgICAgICZsdDsvdWwmZ3Q7CiAgICAmbHQ7YSBocmVmPSZx
156
+ dW90O2h0dHA6Ly9uZXdzLmxpdmVkb29yLmNvbS9hcnRpY2xlL2RldGFpbC84
157
+ OTY0NDMwLyZxdW90OyZndDvoqJjkuovjgpLoqq3jgoAmbHQ7L2EmZ3Q7CiAg
158
+ ICA8L2Rlc2NyaXB0aW9uPgogICAgPG1vYmlsZT4xPC9tb2JpbGU+CiAgICA8
159
+ cHViRGF0ZT5TdW4sIDIyIEp1biAyMDE0IDEyOjAwOjExICswOTAwPC9wdWJE
160
+ YXRlPgogICAgPGd1aWQ+aHR0cDovL25ld3MubGl2ZWRvb3IuY29tL2FydGlj
161
+ bGUvZGV0YWlsLzg5NjQ0MzAvPC9ndWlkPgo8L2l0ZW0+CjxpdGVtPgogICAg
162
+ PHRpdGxlPuatpuS6leWjruOAgemZuOS4iuOBp+OAjOOCouOCuOOCouaWsOio
163
+ mOmMsuOAjTwvdGl0bGU+CiAgICA8bGluaz5odHRwOi8vbmV3cy5saXZlZG9v
164
+ ci5jb20vYXJ0aWNsZS9kZXRhaWwvODk2NTI2MS88L2xpbms+CiAgICA8ZGVz
165
+ Y3JpcHRpb24+CiAgICDjgZbjgaPjgY/jgoroqIDjgYbjgagKICAgICZsdDti
166
+ ciAvJmd0OwogICAgICAmbHQ7dWwmZ3Q7CiAgICAgICAgJmx0O2xpJmd0O+at
167
+ puS6leWjruOBjDIy5pel44CB44Oe44K544K/44O844K66Zm45LiK56u25oqA
168
+ 6YG45omL5qip5aSn5Lya44Gn44Ki44K444Ki6KiY6Yyy44KS5pu05paw44GX
169
+ 44GfJmx0Oy9saSZndDsKICAgICAgICAmbHQ7bGkmZ3Q7TTQw44Kv44Op44K5
170
+ 77yINDDvvZ40NOats++8ieOBrjTDlzEwMG3jg6rjg6zjg7zjgafjgIE0Mi4y
171
+ NeenkuOCkuiomOmMsiZsdDsvbGkmZ3Q7CiAgICAgICAgJmx0O2xpJmd0OzEw
172
+ MG3jga7jg57jgrnjgr/jg7zjgrrjgqLjgrjjgqLoqJjpjLLjg5vjg6vjg4Dj
173
+ g7zjga7orZzkuYXph4zmrabjgZXjgpPjgok05Lq644Gn44CB5Ye65aC044GX
174
+ 44GfJmx0Oy9saSZndDsKICAgICAgJmx0Oy91bCZndDsKICAgICZsdDthIGhy
175
+ ZWY9JnF1b3Q7aHR0cDovL25ld3MubGl2ZWRvb3IuY29tL2FydGljbGUvZGV0
176
+ YWlsLzg5NjUyNjEvJnF1b3Q7Jmd0O+iomOS6i+OCkuiqreOCgCZsdDsvYSZn
177
+ dDsKICAgIDwvZGVzY3JpcHRpb24+CiAgICA8bW9iaWxlPjA8L21vYmlsZT4K
178
+ ICAgIDxwdWJEYXRlPlN1biwgMjIgSnVuIDIwMTQgMTk6NDk6MDAgKzA5MDA8
179
+ L3B1YkRhdGU+CiAgICA8Z3VpZD5odHRwOi8vbmV3cy5saXZlZG9vci5jb20v
180
+ YXJ0aWNsZS9kZXRhaWwvODk2NTI2MS88L2d1aWQ+CjwvaXRlbT4KPGl0ZW0+
181
+ CiAgICA8dGl0bGU+5pyA6L+R6KaL44GL44GR44Gq44GP44Gq44Gj44Gf5aWz
182
+ 5oCn6Iq46IO95Lq6PC90aXRsZT4KICAgIDxsaW5rPmh0dHA6Ly9uZXdzLmxp
183
+ dmVkb29yLmNvbS9hcnRpY2xlL2RldGFpbC84OTY0MzM2LzwvbGluaz4KICAg
184
+ IDxkZXNjcmlwdGlvbj4KICAgIOOBluOBo+OBj+OCiuiogOOBhuOBqAogICAg
185
+ Jmx0O2JyIC8mZ3Q7CiAgICAgICZsdDt1bCZndDsKICAgICAgICAmbHQ7bGkm
186
+ Z3Q75YWD44OK44Oz44OQ44O844Ov44Oz44Ob44K544OG44K544Gu56We5a6k
187
+ 6Iie6KGj44GM44CB6L+36LWw44GX44Gm44GE44KL44Go44GE44GGJmx0Oy9s
188
+ aSZndDsKICAgICAgICAmbHQ7bGkmZ3Q744Gd44Gu576O6LKM44Gn5LiA6LqN
189
+ 44OW44Os44O844Kv44GX44Gf44GM44CB5pyA6L+R44Gn44Gv44Oh44OH44Kj
190
+ 44Ki6Zyy5Ye644GM5r+A5ribJmx0Oy9saSZndDsKICAgICAgICAmbHQ7bGkm
191
+ Z3Q744CM5pyf5b6F44Gu5paw5Lq644CN44Go44GX44Gm44Gv44CB44GZ44Gn
192
+ 44Gr57WC44KP44Gj44Gf5oSf44GZ44KJ5ryC44GE5aeL44KB44Gm44GE44KL
193
+ Jmx0Oy9saSZndDsKICAgICAgJmx0Oy91bCZndDsKICAgICZsdDthIGhyZWY9
194
+ JnF1b3Q7aHR0cDovL25ld3MubGl2ZWRvb3IuY29tL2FydGljbGUvZGV0YWls
195
+ Lzg5NjQzMzYvJnF1b3Q7Jmd0O+iomOS6i+OCkuiqreOCgCZsdDsvYSZndDsK
196
+ ICAgIDwvZGVzY3JpcHRpb24+CiAgICA8bW9iaWxlPjA8L21vYmlsZT4KICAg
197
+ IDxwdWJEYXRlPlN1biwgMjIgSnVuIDIwMTQgMTE6MDA6MDAgKzA5MDA8L3B1
198
+ YkRhdGU+CiAgICA8Z3VpZD5odHRwOi8vbmV3cy5saXZlZG9vci5jb20vYXJ0
199
+ aWNsZS9kZXRhaWwvODk2NDMzNi88L2d1aWQ+CjwvaXRlbT4KPGl0ZW0+CiAg
200
+ ICA8dGl0bGU+44CM55yf5aSP44Gu5pa556iL5byP44CN6ISH5b255aWz5YSq
201
+ 44Gr5Y+N6Z+/PC90aXRsZT4KICAgIDxsaW5rPmh0dHA6Ly9uZXdzLmxpdmVk
202
+ b29yLmNvbS9hcnRpY2xlL2RldGFpbC84OTY1MzIwLzwvbGluaz4KICAgIDxk
203
+ ZXNjcmlwdGlvbj4KICAgIOOBluOBo+OBj+OCiuiogOOBhuOBqAogICAgJmx0
204
+ O2JyIC8mZ3Q7CiAgICAgICZsdDt1bCZndDsKICAgICAgICAmbHQ7bGkmZ3Q7
205
+ MjHml6Xjgavjg5Xjgrjjg4bjg6zjg5PjgafmmKDnlLvjgIznnJ/lpI/jga7m
206
+ lrnnqIvlvI/jgI3jgYzmlL7mmKDjgZXjgozjgZ8mbHQ7L2xpJmd0OwogICAg
207
+ ICAgICZsdDtsaSZndDvmrrrkurrkuovku7bjga7ooqvlrrPogIXjgpLmvJTj
208
+ gZjjgZ/opb/nlLDlsJrnvo7jgavjgIHjg43jg4Pjg4jjgaflj43pn7/jgYzl
209
+ r4TjgZvjgonjgozjgabjgYTjgosmbHQ7L2xpJmd0OwogICAgICAgICZsdDts
210
+ aSZndDtOSEvjga7jgrPjg7Pjg4jnlarntYTjgavlh7rmvJTjgZfjgabjgYTj
211
+ govjgZPjgajjgoLjgIHoqZXkvqHjgavjgaTjgarjgYzjgaPjgabjgYTjgovj
212
+ gonjgZfjgYQmbHQ7L2xpJmd0OwogICAgICAmbHQ7L3VsJmd0OwogICAgJmx0
213
+ O2EgaHJlZj0mcXVvdDtodHRwOi8vbmV3cy5saXZlZG9vci5jb20vYXJ0aWNs
214
+ ZS9kZXRhaWwvODk2NTMyMC8mcXVvdDsmZ3Q76KiY5LqL44KS6Kqt44KAJmx0
215
+ Oy9hJmd0OwogICAgPC9kZXNjcmlwdGlvbj4KICAgIDxtb2JpbGU+MTwvbW9i
216
+ aWxlPgogICAgPHB1YkRhdGU+U3VuLCAyMiBKdW4gMjAxNCAyMDowMDowMCAr
217
+ MDkwMDwvcHViRGF0ZT4KICAgIDxndWlkPmh0dHA6Ly9uZXdzLmxpdmVkb29y
218
+ LmNvbS9hcnRpY2xlL2RldGFpbC84OTY1MzIwLzwvZ3VpZD4KPC9pdGVtPgo8
219
+ aXRlbT4KICAgIDx0aXRsZT7pm6LlqZrpqJLli5Xjga7luIPlt53jg7vjgaTj
220
+ gaHjgoTjgIHmsbrnnYA8L3RpdGxlPgogICAgPGxpbms+aHR0cDovL25ld3Mu
221
+ bGl2ZWRvb3IuY29tL2FydGljbGUvZGV0YWlsLzg5NjUzNTkvPC9saW5rPgog
222
+ ICAgPGRlc2NyaXB0aW9uPgogICAgJmx0O2EgaHJlZj0mcXVvdDtodHRwOi8v
223
+ bmV3cy5saXZlZG9vci5jb20vYXJ0aWNsZS9kZXRhaWwvODk2NTM1OS8mcXVv
224
+ dDsmZ3Q76KiY5LqL44KS6Kqt44KAJmx0Oy9hJmd0OwogICAgPC9kZXNjcmlw
225
+ dGlvbj4KICAgIDxtb2JpbGU+MDwvbW9iaWxlPgogICAgPHB1YkRhdGU+U3Vu
226
+ LCAyMiBKdW4gMjAxNCAyMDo1ODoyOCArMDkwMDwvcHViRGF0ZT4KICAgIDxn
227
+ dWlkPmh0dHA6Ly9uZXdzLmxpdmVkb29yLmNvbS9hcnRpY2xlL2RldGFpbC84
228
+ OTY1MzU5LzwvZ3VpZD4KPC9pdGVtPgo8L2NoYW5uZWw+CjwvcnNzPgo=
229
+ http_version:
230
+ recorded_at: Sun, 22 Jun 2014 12:35:37 GMT
231
+ recorded_with: VCR 2.9.2