git_multicast 0.0.5 → 0.0.6

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +11 -0
  3. data/Gemfile.lock +17 -1
  4. data/README.md +3 -3
  5. data/git_multicast.gemspec +29 -18
  6. data/lib/git_multicast/.rubocop.yml +11 -0
  7. data/lib/git_multicast/adapters/bitbucket.rb +35 -0
  8. data/lib/git_multicast/adapters/github.rb +17 -0
  9. data/lib/git_multicast/adapters.rb +5 -0
  10. data/lib/git_multicast/cli.rb +9 -2
  11. data/lib/git_multicast/cloner.rb +3 -3
  12. data/lib/git_multicast/output_formatter.rb +12 -10
  13. data/lib/git_multicast/repository_fetcher/bitbucket.rb +34 -0
  14. data/lib/git_multicast/repository_fetcher/github.rb +25 -0
  15. data/lib/git_multicast/repository_fetcher.rb +33 -14
  16. data/lib/git_multicast/version.rb +1 -1
  17. data/lib/git_multicast.rb +1 -3
  18. data/spec/fixtures/vcr_cassettes/bitbucket_all_user_repos.yml +170 -0
  19. data/spec/fixtures/vcr_cassettes/bitbucket_repo.yml +79 -0
  20. data/spec/fixtures/vcr_cassettes/github_all_user_repos.yml +107 -0
  21. data/spec/fixtures/vcr_cassettes/github_repo.yml +77 -0
  22. data/spec/fixtures/vcr_cassettes/github_repo_parent.yml +79 -0
  23. data/spec/fixtures/vcr_cassettes/repos_from_all_services.yml +274 -0
  24. data/spec/git_multicast/adapters/bitbucket_spec.rb +25 -0
  25. data/spec/git_multicast/puller_spec.rb +4 -0
  26. data/spec/git_multicast/repository_fetcher/bitbucket_spec.rb +80 -0
  27. data/spec/git_multicast/repository_fetcher/github_spec.rb +81 -0
  28. data/spec/git_multicast/repository_fetcher_spec.rb +101 -18
  29. data/spec/spec_helper.rb +5 -3
  30. metadata +76 -9
  31. data/lib/git_multicast/bitbucket_adapter.rb +0 -33
  32. data/lib/git_multicast/bitbucket_fetcher.rb +0 -36
  33. data/lib/git_multicast/github_fetcher.rb +0 -31
  34. data/spec/git_multicast/bitbucket_adapter_spec.rb +0 -25
  35. data/spec/git_multicast/bitbucket_fetcher_spec.rb +0 -97
  36. data/spec/git_multicast/github_fetcher_spec.rb +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5eca79b00b499527dc9359976cad0a78a1afbbf9
4
- data.tar.gz: a1acf00d101c7da203d4eabf3698efdec8388e7e
3
+ metadata.gz: 5a9ce770391d551120cec8646c9960fc45aa7471
4
+ data.tar.gz: ed4ac6bd223ad655bd0d83ed0ce3bd6576329354
5
5
  SHA512:
6
- metadata.gz: 6831a8e7da65b6fd156ccb81266296ae5c3f3b7a452e0e3a5388ceca4bd8c443dd0598ab4aeabc82a49a8a3dcac3324e5fe9646cfd07d97cedfdde6a46bfe073
7
- data.tar.gz: 88140e231eb521a6d9fac0450cf015f0a7d91d9c1e799037e4b196228be0b5faf2d73f363d59f781f595f7c44aee7aa5a1ab643700964c6164393cd5109b9d5f
6
+ metadata.gz: 56165a2911f3039b28111770c85bcc90445f622bc2ec1d24eb6fbb69b4f92f6dd4b6cf93865c94ef9bfab2c62d86755b7e7c991a3048d45831d53149ba1cb642
7
+ data.tar.gz: fe5b862932a72ef2a505187d44f9ed51480abb60e55d4f7ee48765652983cd4471c4d2033562c1582c8d55bf68a742bb1761986d8e4cca9d7d9356027b4eedca
data/.rubocop.yml ADDED
@@ -0,0 +1,11 @@
1
+ Documentation:
2
+ Enabled: false
3
+
4
+ AllCops:
5
+ # Include gemspec and Rakefile
6
+ Include:
7
+ - '**/*.gemspec'
8
+ - '**/Rakefile'
9
+
10
+ Style/Encoding:
11
+ Enabled: false
data/Gemfile.lock CHANGED
@@ -1,20 +1,26 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- git_multicast (0.0.4.pre)
4
+ git_multicast (0.0.6.pre)
5
5
  recursive-open-struct (~> 0.5.0)
6
6
  thor (~> 0.19)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
+ addressable (2.3.6)
11
12
  coderay (1.1.0)
13
+ crack (0.4.2)
14
+ safe_yaml (~> 1.0.0)
12
15
  diff-lcs (1.2.5)
13
16
  method_source (0.8.2)
14
17
  pry (0.10.1)
15
18
  coderay (~> 1.1.0)
16
19
  method_source (~> 0.8.1)
17
20
  slop (~> 3.4)
21
+ pry-doc (0.6.0)
22
+ pry (~> 0.9)
23
+ yard (~> 0.8)
18
24
  rake (10.3.2)
19
25
  recursive-open-struct (0.5.0)
20
26
  rspec (3.0.0)
@@ -29,8 +35,14 @@ GEM
29
35
  rspec-mocks (3.0.4)
30
36
  rspec-support (~> 3.0.0)
31
37
  rspec-support (3.0.4)
38
+ safe_yaml (1.0.3)
32
39
  slop (3.6.0)
33
40
  thor (0.19.1)
41
+ vcr (2.9.3)
42
+ webmock (1.18.0)
43
+ addressable (>= 2.3.6)
44
+ crack (>= 0.3.2)
45
+ yard (0.8.7.4)
34
46
 
35
47
  PLATFORMS
36
48
  ruby
@@ -38,6 +50,10 @@ PLATFORMS
38
50
  DEPENDENCIES
39
51
  bundler (~> 1.7)
40
52
  git_multicast!
53
+ method_source
41
54
  pry
55
+ pry-doc
42
56
  rake (~> 10.0)
43
57
  rspec (~> 3.0)
58
+ vcr
59
+ webmock
data/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  Have you ever need to clone a whole bunch of repositories? Have you forgot to pull remote changes?
4
4
 
5
- ### GitMassDo to the rescue!
5
+ ### git_multicast to the rescue!
6
6
 
7
- `git_mass_do` is a ruby gem that provides a simple `cli` for issuing commands to
7
+ `git_multicast` is a ruby gem that provides a simple `cli` for issuing commands to
8
8
  multiple git repositories, much like a multicast sends data to multiple
9
9
  recipients.
10
10
 
11
- `git_mass_do` executes actions in parallel, so cloning 30 repositories will take
11
+ `git_multicast` executes actions in parallel, so cloning 30 repositories will take
12
12
  just as long as cloning the biggest one, and nothing more.
13
13
 
14
14
  Actions currently supported:
@@ -1,23 +1,34 @@
1
- Gem::Specification.new do |s|
2
- s.name = 'git_multicast'
3
- s.version = '0.0.5'
4
- s.required_ruby_version = '~>2.0'
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
3
 
6
- s.summary = 'Execute mass actions on git repositories concurrently'
7
- s.authors = ['Renan Ranelli']
8
- s.email = ['renanranelli@gmail.com']
9
- s.homepage = 'http://github.com/rranelli/git_multicast'
10
- s.license = 'MIT'
4
+ require 'git_multicast/version'
11
5
 
12
- s.files = `git ls-files -z`.split("\x0")
13
- s.executables = s.files.grep(/^bin\//) { |f| File.basename(f) }
14
- s.require_paths = ['lib']
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'git_multicast'
8
+ spec.version = GitMulticast::VERSION
9
+ spec.required_ruby_version = '~>2.0'
15
10
 
16
- s.add_dependency 'recursive-open-struct', '~> 0.5.0'
17
- s.add_dependency 'thor', '~> 0.19'
11
+ spec.summary = 'Execute mass actions on git repositories concurrently'
12
+ spec.authors = ['Renan Ranelli']
13
+ spec.email = ['renanranelli@gmail.com']
14
+ spec.homepage = 'http://github.com/rranelli/git_multicast'
15
+ spec.license = 'DWTF'
18
16
 
19
- s.add_development_dependency 'bundler', '~> 1.7'
20
- s.add_development_dependency 'rspec', '~> 3.0'
21
- s.add_development_dependency 'rake', '~> 10.0'
22
- s.add_development_dependency 'pry'
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'recursive-open-struct', '~> 0.5.0'
22
+ spec.add_dependency 'thor', '~> 0.19'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.7'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'vcr'
28
+ spec.add_development_dependency 'webmock'
29
+
30
+ # these gems are required by emacs' robe-package
31
+ spec.add_development_dependency 'pry'
32
+ spec.add_development_dependency 'pry-doc'
33
+ spec.add_development_dependency 'method_source'
23
34
  end
@@ -0,0 +1,11 @@
1
+ Documentation:
2
+ Enabled: false
3
+
4
+ AllCops:
5
+ # Include gemspec and Rakefile
6
+ Include:
7
+ - '**/*.gemspec'
8
+ - '**/Rakefile'
9
+
10
+ Style/Encoding:
11
+ Enabled: false
@@ -0,0 +1,35 @@
1
+ module GitMulticast
2
+ module Adapters
3
+ class Bitbucket
4
+ def initialize(repo)
5
+ @repo = repo
6
+ end
7
+
8
+ def adapt
9
+ make_struct(repo_hash)
10
+ end
11
+
12
+ protected
13
+
14
+ attr_reader :repo
15
+
16
+ def repo_hash
17
+ @repo_hash ||= make_repo_hash
18
+ end
19
+
20
+ def make_repo_hash
21
+ {
22
+ fork: !repo.parent.nil?,
23
+ ssh_url: repo.links._clone.last.href,
24
+ url: repo.links.self.href,
25
+ parent: nil,
26
+ name: repo.name
27
+ }
28
+ end
29
+
30
+ def make_struct(hash)
31
+ RecursiveOpenStruct.new(hash, recurse_over_arrays: true)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ module GitMulticast
2
+ module Adapters
3
+ class Github
4
+ def initialize(repo)
5
+ @repo = repo
6
+ end
7
+
8
+ def adapt
9
+ repo
10
+ end
11
+
12
+ protected
13
+
14
+ attr_reader :repo
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ require_relative 'adapters/bitbucket'
2
+ require_relative 'adapters/github'
3
+
4
+ module Adapters
5
+ end
@@ -4,14 +4,21 @@ require_relative '../git_multicast'
4
4
 
5
5
  module GitMulticast
6
6
  class Cli < Thor
7
- desc 'git_multicast pull', 'Git pulls all repositories contained in current directory.'
7
+ desc 'git_multicast pull', 'Git pulls all repositories contained in\
8
+ current directory.'
8
9
  def pull
9
10
  Puller.new(Dir.pwd).pull
10
11
  end
11
12
 
12
- desc 'git_multicast clone :username', 'Git pulls all repositories contained in current directory.'
13
+ desc 'git_multicast clone :username', 'Git pulls all repositories\
14
+ contained in current directory.'
13
15
  def clone(username)
14
16
  Cloner.new(username, Dir.pwd).clone!
15
17
  end
18
+
19
+ desc 'git_multicast version', 'Shows currently installed version'
20
+ def version
21
+ puts GitMulticast::VERSION
22
+ end
16
23
  end
17
24
  end
@@ -32,11 +32,11 @@ module GitMulticast
32
32
  def make_command(repo)
33
33
  if repo.fork
34
34
  parent_repo = RepositoryFetcher.get_repo_parent(repo.url)
35
- "git clone #{repo.ssh_url} #{ File.join(dir, repo.name) } && \
36
- git -C \"#{ File.join(dir, repo.name) }\" remote add upstream \
35
+ "git clone #{repo.ssh_url} #{File.join(dir, repo.name)} && \
36
+ git -C \"#{File.join(dir, repo.name)}\" remote add upstream \
37
37
  #{parent_repo.ssh_url} --fetch"
38
38
  else
39
- "git clone #{repo.ssh_url} #{ File.join(dir, repo.name) }"
39
+ "git clone #{repo.ssh_url} #{File.join(dir, repo.name)}"
40
40
  end
41
41
  end
42
42
  end
@@ -1,15 +1,17 @@
1
- class OutputFormatter
2
- def self.format(repos, statuses, start_time = nil)
3
- repo_status_pairs = repos.zip(statuses)
1
+ module GitMulticast
2
+ class OutputFormatter
3
+ def self.format(repos, statuses, start_time = nil)
4
+ repo_status_pairs = repos.zip(statuses)
4
5
 
5
- # get successes and failures
6
- success_pairs = repo_status_pairs.select { |_, status| status.success? }
7
- failure_pairs = repo_status_pairs.reject { |_, status| status.success? }
6
+ # get successes and failures
7
+ success_pairs = repo_status_pairs.select { |_, status| status.success? }
8
+ failure_pairs = repo_status_pairs.reject { |_, status| status.success? }
8
9
 
9
- success_pairs.each { |repo, _| puts "#{repo.name} cloned successfully." }
10
- failure_pairs.each { |repo, _| puts "failure to clone #{repo.name}." }
10
+ success_pairs.each { |repo, _| puts "#{repo.name} cloned successfully." }
11
+ failure_pairs.each { |repo, _| puts "failure to clone #{repo.name}." }
11
12
 
12
- puts '=========================================='
13
- puts "Finished in #{Time.now - start_time} seconds." if start_time
13
+ puts '=========================================='
14
+ puts "Finished in #{Time.now - start_time} seconds." if start_time
15
+ end
14
16
  end
15
17
  end
@@ -0,0 +1,34 @@
1
+ module GitMulticast
2
+ class RepositoryFetcher
3
+ class Bitbucket < RepositoryFetcher
4
+ REPOS_URI = 'https://bitbucket.org/api/2.0/repositories/%{username}'
5
+
6
+ def self.get_all_repos_from_user(username)
7
+ uri_str = REPOS_URI % { username: username }
8
+ uri = URI(uri_str)
9
+
10
+ response = Net::HTTP.get_response(uri)
11
+ response_json = JSON.parse(response.body)
12
+
13
+ # Damn...
14
+ response_json['values'].each do |repo|
15
+ repo['links']['_clone'] = repo['links']['clone']
16
+ end
17
+
18
+ response_json['values'].map { |hash| make_struct(hash) }
19
+ end
20
+
21
+ def self.get_repo(url)
22
+ response = Net::HTTP.get_response(URI(url))
23
+ response_json = JSON.parse(response.body)
24
+ response_json['links']['_clone'] = response_json['links']['clone']
25
+
26
+ make_struct(response_json)
27
+ end
28
+
29
+ def self.make_struct(hash)
30
+ RecursiveOpenStruct.new(hash, recurse_over_arrays: true)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ require 'recursive-open-struct'
2
+ require 'json'
3
+
4
+ module GitMulticast
5
+ class RepositoryFetcher
6
+ class Github < RepositoryFetcher
7
+ REPOS_URI = 'https://api.github.com/users/%{username}/repos'
8
+
9
+ def self.get_all_repos_from_user(username)
10
+ uri_str = REPOS_URI % { username: username }
11
+ uri = URI(uri_str)
12
+
13
+ response = Net::HTTP.get_response(uri)
14
+ repos = JSON.parse(response.body)
15
+
16
+ repos.map { |hash| make_struct(hash) }
17
+ end
18
+
19
+ def self.get_repo(url)
20
+ response = Net::HTTP.get_response(URI(url))
21
+ make_struct(JSON.parse(response.body))
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,33 +1,52 @@
1
+ require_relative 'repository_fetcher/github'
2
+ require_relative 'repository_fetcher/bitbucket'
3
+
1
4
  module GitMulticast
2
5
  class RepositoryFetcher
3
- FETCHERS = [
4
- GitMulticast::GithubFetcher,
5
- GitMulticast::BitbucketFetcher
6
+ FETCHER_ADAPTER_ZIP = [
7
+ [Bitbucket, Adapters::Bitbucket],
8
+ [Github, Adapters::Github]
6
9
  ]
7
10
 
11
+ FETCHERS, ADAPTERS = FETCHER_ADAPTER_ZIP.transpose
12
+
8
13
  def self.get_all_repos_from_user(username)
9
- multicast(FETCHERS, :get_all_repos_from_user, username).flatten
14
+ FETCHER_ADAPTER_ZIP.map do |fetcher, adapter|
15
+ raw_repos = fetcher.get_all_repos_from_user(username)
16
+
17
+ raw_repos.map { |raw_repo| adapter.new(raw_repo).adapt }
18
+ end.flatten
19
+ end
20
+
21
+ def self.get_repo(url)
22
+ raw_repo = fetcher_by_url(url).get_repo(url)
23
+ adapter_by_url(url).new(raw_repo).adapt
10
24
  end
11
25
 
12
26
  def self.get_repo_parent(url)
13
- fetcher_by_url(url).get_repo_parent(url)
27
+ get_repo(url).parent
14
28
  end
15
29
 
16
- def self.fetcher_by_url(url)
30
+ def self.zip_by_url(url)
17
31
  fetchers_names = FETCHERS.map do |fetcher|
18
- match = fetcher.to_s.match(/::(.*)$/)
19
- match[1].gsub('Fetcher', '').downcase if match
32
+ match = fetcher.to_s.match(/Fetcher::(.*)$/)
33
+ match[1].downcase if match
20
34
  end
21
35
 
22
- triples = ([url] * FETCHERS.count).zip(fetchers_names, FETCHERS)
36
+ triples = ([url] * FETCHERS.size).zip(fetchers_names, FETCHER_ADAPTER_ZIP)
37
+ triples.find { |u, name, _| u.match name }.last
38
+ end
23
39
 
24
- triples.select { |u, name, _| u.match name }.first.last
40
+ def self.fetcher_by_url(url)
41
+ zip_by_url(url).first
25
42
  end
26
43
 
27
- def self.multicast(list, method, *args)
28
- list.map do |e|
29
- e.send(method, *args)
30
- end
44
+ def self.adapter_by_url(url)
45
+ zip_by_url(url).last
46
+ end
47
+
48
+ def self.make_struct(hash)
49
+ RecursiveOpenStruct.new(hash, recurse_over_arrays: true)
31
50
  end
32
51
  end
33
52
  end
@@ -1,3 +1,3 @@
1
1
  module GitMulticast
2
- VERSION = '0.0.0'
2
+ VERSION = '0.0.6'
3
3
  end
data/lib/git_multicast.rb CHANGED
@@ -2,10 +2,8 @@ require_relative 'git_multicast/version'
2
2
  require_relative 'git_multicast/cloner'
3
3
  require_relative 'git_multicast/puller'
4
4
  require_relative 'git_multicast/output_formatter'
5
- require_relative 'git_multicast/bitbucket_adapter'
6
5
 
7
- require_relative 'git_multicast/github_fetcher'
8
- require_relative 'git_multicast/bitbucket_fetcher'
6
+ require_relative 'git_multicast/adapters'
9
7
  require_relative 'git_multicast/repository_fetcher'
10
8
 
11
9
  module GitMulticast
@@ -0,0 +1,170 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://bitbucket.org/api/2.0/repositories/rranelli
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Host:
17
+ - bitbucket.org
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Server:
24
+ - nginx/1.5.10
25
+ Date:
26
+ - Wed, 10 Sep 2014 06:04:39 GMT
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - keep-alive
33
+ X-Served-By:
34
+ - app22
35
+ X-Render-Time:
36
+ - '0.0394489765167'
37
+ Content-Language:
38
+ - en
39
+ X-Static-Version:
40
+ - a47fb0d97df3
41
+ Expires:
42
+ - Wed, 10 Sep 2014 06:19:39 GMT
43
+ Vary:
44
+ - Authorization, Accept-Language, Cookie
45
+ Last-Modified:
46
+ - Wed, 10 Sep 2014 06:04:39 GMT
47
+ X-Version:
48
+ - a47fb0d97df3
49
+ X-Request-Count:
50
+ - '210'
51
+ Cache-Control:
52
+ - max-age=900
53
+ X-Frame-Options:
54
+ - SAMEORIGIN
55
+ Strict-Transport-Security:
56
+ - max-age=31536000
57
+ X-Content-Type-Options:
58
+ - nosniff
59
+ body:
60
+ encoding: ASCII-8BIT
61
+ string: !binary |-
62
+ eyJwYWdlbGVuIjogMTAsICJ2YWx1ZXMiOiBbeyJzY20iOiAiZ2l0IiwgImhh
63
+ c193aWtpIjogdHJ1ZSwgImRlc2NyaXB0aW9uIjogIkVzdGUgw6kgbyByZXBv
64
+ c2l0w7NyaW8gZG8gQ1BOTTIsIHVtYSBmZXJyYW1lbnRhIHBhcmEgZ2VzdMOj
65
+ byBlIGF1dG9tYcOnw6NvIGRlIGRvY3VtZW50b3MgZGUgZW5nZW5oYXJpYS4i
66
+ LCAibGlua3MiOiB7IndhdGNoZXJzIjogeyJocmVmIjogImh0dHBzOi8vYml0
67
+ YnVja2V0Lm9yZy9hcGkvMi4wL3JlcG9zaXRvcmllcy9ycmFuZWxsaS9jcG5t
68
+ djIvd2F0Y2hlcnMifSwgImNvbW1pdHMiOiB7ImhyZWYiOiAiaHR0cHM6Ly9i
69
+ aXRidWNrZXQub3JnL2FwaS8yLjAvcmVwb3NpdG9yaWVzL3JyYW5lbGxpL2Nw
70
+ bm12Mi9jb21taXRzIn0sICJzZWxmIjogeyJocmVmIjogImh0dHBzOi8vYml0
71
+ YnVja2V0Lm9yZy9hcGkvMi4wL3JlcG9zaXRvcmllcy9ycmFuZWxsaS9jcG5t
72
+ djIifSwgImh0bWwiOiB7ImhyZWYiOiAiaHR0cHM6Ly9iaXRidWNrZXQub3Jn
73
+ L3JyYW5lbGxpL2Nwbm12MiJ9LCAiYXZhdGFyIjogeyJocmVmIjogImh0dHBz
74
+ Oi8vZDNvYXhjNHE1azJkNnEuY2xvdWRmcm9udC5uZXQvbS9hNDdmYjBkOTdk
75
+ ZjMvaW1nL2xhbmd1YWdlLWF2YXRhcnMvY19zaGFycF8xNi5wbmcifSwgImZv
76
+ cmtzIjogeyJocmVmIjogImh0dHBzOi8vYml0YnVja2V0Lm9yZy9hcGkvMi4w
77
+ L3JlcG9zaXRvcmllcy9ycmFuZWxsaS9jcG5tdjIvZm9ya3MifSwgImNsb25l
78
+ IjogW3siaHJlZiI6ICJodHRwczovL2JpdGJ1Y2tldC5vcmcvcnJhbmVsbGkv
79
+ Y3BubXYyLmdpdCIsICJuYW1lIjogImh0dHBzIn0sIHsiaHJlZiI6ICJzc2g6
80
+ Ly9naXRAYml0YnVja2V0Lm9yZy9ycmFuZWxsaS9jcG5tdjIuZ2l0IiwgIm5h
81
+ bWUiOiAic3NoIn1dLCAicHVsbHJlcXVlc3RzIjogeyJocmVmIjogImh0dHBz
82
+ Oi8vYml0YnVja2V0Lm9yZy9hcGkvMi4wL3JlcG9zaXRvcmllcy9ycmFuZWxs
83
+ aS9jcG5tdjIvcHVsbHJlcXVlc3RzIn19LCAiZm9ya19wb2xpY3kiOiAiYWxs
84
+ b3dfZm9ya3MiLCAibGFuZ3VhZ2UiOiAiYyMiLCAiY3JlYXRlZF9vbiI6ICIy
85
+ MDEzLTA2LTA1VDA3OjA3OjM4LjI5MDQxOCswMDowMCIsICJmdWxsX25hbWUi
86
+ OiAicnJhbmVsbGkvY3BubXYyIiwgImhhc19pc3N1ZXMiOiB0cnVlLCAib3du
87
+ ZXIiOiB7InVzZXJuYW1lIjogInJyYW5lbGxpIiwgImRpc3BsYXlfbmFtZSI6
88
+ ICJyZW5hbiByYW5lbGxpIiwgImxpbmtzIjogeyJzZWxmIjogeyJocmVmIjog
89
+ Imh0dHBzOi8vYml0YnVja2V0Lm9yZy9hcGkvMi4wL3VzZXJzL3JyYW5lbGxp
90
+ In0sICJodG1sIjogeyJocmVmIjogImh0dHBzOi8vYml0YnVja2V0Lm9yZy9y
91
+ cmFuZWxsaSJ9LCAiYXZhdGFyIjogeyJocmVmIjogImh0dHBzOi8vc2VjdXJl
92
+ LmdyYXZhdGFyLmNvbS9hdmF0YXIvNDU2OWFlYzAwY2IyMjNiM2ZiZjQ4NGY5
93
+ ZTdiYTEyNTY/ZD1odHRwcyUzQSUyRiUyRmQzb2F4YzRxNWsyZDZxLmNsb3Vk
94
+ ZnJvbnQubmV0JTJGbSUyRmE0N2ZiMGQ5N2RmMyUyRmltZyUyRmRlZmF1bHRf
95
+ YXZhdGFyJTJGMzIlMkZ1c2VyX2JsdWUucG5nJnM9MzIifX19LCAidXBkYXRl
96
+ ZF9vbiI6ICIyMDE0LTA0LTIzVDAzOjIxOjE0LjY4NjE3NyswMDowMCIsICJz
97
+ aXplIjogMTQ5Nzg4NjgsICJpc19wcml2YXRlIjogZmFsc2UsICJuYW1lIjog
98
+ IkNQTk12MiJ9LCB7InNjbSI6ICJnaXQiLCAiaGFzX3dpa2kiOiBmYWxzZSwg
99
+ ImRlc2NyaXB0aW9uIjogIiIsICJsaW5rcyI6IHsid2F0Y2hlcnMiOiB7Imhy
100
+ ZWYiOiAiaHR0cHM6Ly9iaXRidWNrZXQub3JnL2FwaS8yLjAvcmVwb3NpdG9y
101
+ aWVzL3JyYW5lbGxpL2Nyb25vZmFrZXIvd2F0Y2hlcnMifSwgImNvbW1pdHMi
102
+ OiB7ImhyZWYiOiAiaHR0cHM6Ly9iaXRidWNrZXQub3JnL2FwaS8yLjAvcmVw
103
+ b3NpdG9yaWVzL3JyYW5lbGxpL2Nyb25vZmFrZXIvY29tbWl0cyJ9LCAic2Vs
104
+ ZiI6IHsiaHJlZiI6ICJodHRwczovL2JpdGJ1Y2tldC5vcmcvYXBpLzIuMC9y
105
+ ZXBvc2l0b3JpZXMvcnJhbmVsbGkvY3Jvbm9mYWtlciJ9LCAiaHRtbCI6IHsi
106
+ aHJlZiI6ICJodHRwczovL2JpdGJ1Y2tldC5vcmcvcnJhbmVsbGkvY3Jvbm9m
107
+ YWtlciJ9LCAiYXZhdGFyIjogeyJocmVmIjogImh0dHBzOi8vZDNvYXhjNHE1
108
+ azJkNnEuY2xvdWRmcm9udC5uZXQvbS9hNDdmYjBkOTdkZjMvaW1nL2xhbmd1
109
+ YWdlLWF2YXRhcnMvZGVmYXVsdF8xNi5wbmcifSwgImZvcmtzIjogeyJocmVm
110
+ IjogImh0dHBzOi8vYml0YnVja2V0Lm9yZy9hcGkvMi4wL3JlcG9zaXRvcmll
111
+ cy9ycmFuZWxsaS9jcm9ub2Zha2VyL2ZvcmtzIn0sICJjbG9uZSI6IFt7Imhy
112
+ ZWYiOiAiaHR0cHM6Ly9iaXRidWNrZXQub3JnL3JyYW5lbGxpL2Nyb25vZmFr
113
+ ZXIuZ2l0IiwgIm5hbWUiOiAiaHR0cHMifSwgeyJocmVmIjogInNzaDovL2dp
114
+ dEBiaXRidWNrZXQub3JnL3JyYW5lbGxpL2Nyb25vZmFrZXIuZ2l0IiwgIm5h
115
+ bWUiOiAic3NoIn1dLCAicHVsbHJlcXVlc3RzIjogeyJocmVmIjogImh0dHBz
116
+ Oi8vYml0YnVja2V0Lm9yZy9hcGkvMi4wL3JlcG9zaXRvcmllcy9ycmFuZWxs
117
+ aS9jcm9ub2Zha2VyL3B1bGxyZXF1ZXN0cyJ9fSwgImZvcmtfcG9saWN5Ijog
118
+ ImFsbG93X2ZvcmtzIiwgImxhbmd1YWdlIjogIiIsICJjcmVhdGVkX29uIjog
119
+ IjIwMTQtMDEtMjBUMDQ6MjM6MTcuNzkwODM3KzAwOjAwIiwgImZ1bGxfbmFt
120
+ ZSI6ICJycmFuZWxsaS9jcm9ub2Zha2VyIiwgImhhc19pc3N1ZXMiOiBmYWxz
121
+ ZSwgIm93bmVyIjogeyJ1c2VybmFtZSI6ICJycmFuZWxsaSIsICJkaXNwbGF5
122
+ X25hbWUiOiAicmVuYW4gcmFuZWxsaSIsICJsaW5rcyI6IHsic2VsZiI6IHsi
123
+ aHJlZiI6ICJodHRwczovL2JpdGJ1Y2tldC5vcmcvYXBpLzIuMC91c2Vycy9y
124
+ cmFuZWxsaSJ9LCAiaHRtbCI6IHsiaHJlZiI6ICJodHRwczovL2JpdGJ1Y2tl
125
+ dC5vcmcvcnJhbmVsbGkifSwgImF2YXRhciI6IHsiaHJlZiI6ICJodHRwczov
126
+ L3NlY3VyZS5ncmF2YXRhci5jb20vYXZhdGFyLzQ1NjlhZWMwMGNiMjIzYjNm
127
+ YmY0ODRmOWU3YmExMjU2P2Q9aHR0cHMlM0ElMkYlMkZkM29heGM0cTVrMmQ2
128
+ cS5jbG91ZGZyb250Lm5ldCUyRm0lMkZhNDdmYjBkOTdkZjMlMkZpbWclMkZk
129
+ ZWZhdWx0X2F2YXRhciUyRjMyJTJGdXNlcl9ibHVlLnBuZyZzPTMyIn19fSwg
130
+ InVwZGF0ZWRfb24iOiAiMjAxNC0wNC0yM1QwMzoxODo0NC42NDAyNjQrMDA6
131
+ MDAiLCAic2l6ZSI6IDQ5NjQ1ODc2LCAiaXNfcHJpdmF0ZSI6IGZhbHNlLCAi
132
+ bmFtZSI6ICJDcm9ub0Zha2VyIn0sIHsic2NtIjogImdpdCIsICJoYXNfd2lr
133
+ aSI6IGZhbHNlLCAiZGVzY3JpcHRpb24iOiAiIiwgImxpbmtzIjogeyJ3YXRj
134
+ aGVycyI6IHsiaHJlZiI6ICJodHRwczovL2JpdGJ1Y2tldC5vcmcvYXBpLzIu
135
+ MC9yZXBvc2l0b3JpZXMvcnJhbmVsbGkvcnJ3ZWJhcHBhcmNoL3dhdGNoZXJz
136
+ In0sICJjb21taXRzIjogeyJocmVmIjogImh0dHBzOi8vYml0YnVja2V0Lm9y
137
+ Zy9hcGkvMi4wL3JlcG9zaXRvcmllcy9ycmFuZWxsaS9ycndlYmFwcGFyY2gv
138
+ Y29tbWl0cyJ9LCAic2VsZiI6IHsiaHJlZiI6ICJodHRwczovL2JpdGJ1Y2tl
139
+ dC5vcmcvYXBpLzIuMC9yZXBvc2l0b3JpZXMvcnJhbmVsbGkvcnJ3ZWJhcHBh
140
+ cmNoIn0sICJodG1sIjogeyJocmVmIjogImh0dHBzOi8vYml0YnVja2V0Lm9y
141
+ Zy9ycmFuZWxsaS9ycndlYmFwcGFyY2gifSwgImF2YXRhciI6IHsiaHJlZiI6
142
+ ICJodHRwczovL2Qzb2F4YzRxNWsyZDZxLmNsb3VkZnJvbnQubmV0L20vYTQ3
143
+ ZmIwZDk3ZGYzL2ltZy9sYW5ndWFnZS1hdmF0YXJzL3J1YnlfMTYucG5nIn0s
144
+ ICJmb3JrcyI6IHsiaHJlZiI6ICJodHRwczovL2JpdGJ1Y2tldC5vcmcvYXBp
145
+ LzIuMC9yZXBvc2l0b3JpZXMvcnJhbmVsbGkvcnJ3ZWJhcHBhcmNoL2Zvcmtz
146
+ In0sICJjbG9uZSI6IFt7ImhyZWYiOiAiaHR0cHM6Ly9iaXRidWNrZXQub3Jn
147
+ L3JyYW5lbGxpL3Jyd2ViYXBwYXJjaC5naXQiLCAibmFtZSI6ICJodHRwcyJ9
148
+ LCB7ImhyZWYiOiAic3NoOi8vZ2l0QGJpdGJ1Y2tldC5vcmcvcnJhbmVsbGkv
149
+ cnJ3ZWJhcHBhcmNoLmdpdCIsICJuYW1lIjogInNzaCJ9XSwgInB1bGxyZXF1
150
+ ZXN0cyI6IHsiaHJlZiI6ICJodHRwczovL2JpdGJ1Y2tldC5vcmcvYXBpLzIu
151
+ MC9yZXBvc2l0b3JpZXMvcnJhbmVsbGkvcnJ3ZWJhcHBhcmNoL3B1bGxyZXF1
152
+ ZXN0cyJ9fSwgImZvcmtfcG9saWN5IjogImFsbG93X2ZvcmtzIiwgImxhbmd1
153
+ YWdlIjogInJ1YnkiLCAiY3JlYXRlZF9vbiI6ICIyMDE0LTA0LTA2VDE3OjMz
154
+ OjM5LjI3OTE2NSswMDowMCIsICJmdWxsX25hbWUiOiAicnJhbmVsbGkvcnJ3
155
+ ZWJhcHBhcmNoIiwgImhhc19pc3N1ZXMiOiBmYWxzZSwgIm93bmVyIjogeyJ1
156
+ c2VybmFtZSI6ICJycmFuZWxsaSIsICJkaXNwbGF5X25hbWUiOiAicmVuYW4g
157
+ cmFuZWxsaSIsICJsaW5rcyI6IHsic2VsZiI6IHsiaHJlZiI6ICJodHRwczov
158
+ L2JpdGJ1Y2tldC5vcmcvYXBpLzIuMC91c2Vycy9ycmFuZWxsaSJ9LCAiaHRt
159
+ bCI6IHsiaHJlZiI6ICJodHRwczovL2JpdGJ1Y2tldC5vcmcvcnJhbmVsbGki
160
+ fSwgImF2YXRhciI6IHsiaHJlZiI6ICJodHRwczovL3NlY3VyZS5ncmF2YXRh
161
+ ci5jb20vYXZhdGFyLzQ1NjlhZWMwMGNiMjIzYjNmYmY0ODRmOWU3YmExMjU2
162
+ P2Q9aHR0cHMlM0ElMkYlMkZkM29heGM0cTVrMmQ2cS5jbG91ZGZyb250Lm5l
163
+ dCUyRm0lMkZhNDdmYjBkOTdkZjMlMkZpbWclMkZkZWZhdWx0X2F2YXRhciUy
164
+ RjMyJTJGdXNlcl9ibHVlLnBuZyZzPTMyIn19fSwgInVwZGF0ZWRfb24iOiAi
165
+ MjAxNC0wNC0yM1QwMToyMzo0OC4xNjAwMDArMDA6MDAiLCAic2l6ZSI6IDE5
166
+ MTk2MSwgImlzX3ByaXZhdGUiOiBmYWxzZSwgIm5hbWUiOiAiUlJXZWJBcHBB
167
+ cmNoIn1dLCAicGFnZSI6IDEsICJzaXplIjogM30=
168
+ http_version:
169
+ recorded_at: Wed, 10 Sep 2014 06:04:39 GMT
170
+ recorded_with: VCR 2.9.3