silent_fetcher 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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