gitnetworkitis 0.2.0 → 0.4.0

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 (73) hide show
  1. data/Gemfile +6 -5
  2. data/Gemfile.lock +26 -20
  3. data/VERSION +1 -1
  4. data/get_token.rb +40 -0
  5. data/gitnetworkitis.gemspec +41 -76
  6. data/lib/gitnetworkitis/base.rb +10 -40
  7. data/lib/gitnetworkitis/batch_response.rb +24 -0
  8. data/lib/gitnetworkitis/branch.rb +10 -31
  9. data/lib/gitnetworkitis/commit.rb +2 -5
  10. data/lib/gitnetworkitis/commit_getter.rb +50 -0
  11. data/lib/gitnetworkitis/getter.rb +64 -0
  12. data/lib/gitnetworkitis/json_helper.rb +24 -0
  13. data/lib/gitnetworkitis/repository.rb +11 -30
  14. data/lib/gitnetworkitis.rb +10 -5
  15. data/spec/base_spec.rb +13 -20
  16. data/spec/branch_spec.rb +63 -19
  17. data/spec/getter_spec.rb +36 -0
  18. data/spec/github_config.yml.example +2 -0
  19. data/spec/repository_spec.rb +27 -39
  20. data/spec/spec_helper.rb +3 -64
  21. data/spec/support/vcr_setup.rb +8 -0
  22. data/spec/vcr_cassettes/all_branches.json +67 -0
  23. data/spec/vcr_cassettes/all_repos.json +67 -0
  24. data/spec/vcr_cassettes/bad_creds.json +58 -0
  25. data/spec/vcr_cassettes/find_repo.json +67 -0
  26. data/spec/vcr_cassettes/spec-branch-1_commits.json +2277 -0
  27. data/spec/vcr_cassettes/spec-branch-1_since_date.json +1 -0
  28. data/spec/vcr_cassettes/spec-branch-1_since_sha.json +67 -0
  29. data/spec/vcr_cassettes/spec-branch-2_commits.json +70 -0
  30. data/spec/vcr_cassettes/spec-branch-3_commits.json +67 -0
  31. metadata +84 -124
  32. data/lib/gitnetworkitis/network_data.rb +0 -66
  33. data/lib/gitnetworkitis/network_meta.rb +0 -17
  34. data/spec/commit_spec.rb +0 -8
  35. data/spec/network_data_spec.rb +0 -153
  36. data/spec/network_meta_spec.rb +0 -59
  37. data/spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=0.json +0 -1
  38. data/spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=1.json +0 -1
  39. data/spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=2.json +0 -1
  40. data/spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=3.json +0 -1
  41. data/spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=4.json +0 -1
  42. data/spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=5.json +0 -1
  43. data/spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=0.json +0 -1
  44. data/spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=1.json +0 -1
  45. data/spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=2.json +0 -1
  46. data/spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=3.json +0 -1
  47. data/spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=4.json +0 -1
  48. data/spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=0.json +0 -1
  49. data/spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=1.json +0 -1
  50. data/spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=2.json +0 -1
  51. data/spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=3.json +0 -1
  52. data/spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=4.json +0 -1
  53. data/spec/responses/girlambition/0-500.json +0 -1
  54. data/spec/responses/girlambition/1002-1502.json +0 -1
  55. data/spec/responses/girlambition/1503-2003.json +0 -1
  56. data/spec/responses/girlambition/2004-2504.json +0 -1
  57. data/spec/responses/girlambition/2505-3005.json +0 -1
  58. data/spec/responses/girlambition/3006-3506.json +0 -1
  59. data/spec/responses/girlambition/3507-4007.json +0 -1
  60. data/spec/responses/girlambition/4008-4508.json +0 -1
  61. data/spec/responses/girlambition/4509-4999.json +0 -1
  62. data/spec/responses/girlambition/501-1001.json +0 -1
  63. data/spec/responses/girlambition/repos_show_turingstudio_website-girlambition_branches.json +0 -1
  64. data/spec/responses/girlambition/turingstudio_website-girlambition_network_meta.json +0 -1
  65. data/spec/responses/loupe/repos_show_turingstudio_loupe.json +0 -1
  66. data/spec/responses/loupe/repos_show_turingstudio_loupe_branches.json +0 -1
  67. data/spec/responses/loupe/turingstudio_loupe_068161e2c05a6b8029a7eb410dd27b1dfa531338?start=1&end=5.json +0 -1
  68. data/spec/responses/loupe/turingstudio_loupe_068161e2c05a6b8029a7eb410dd27b1dfa531338?start=130.json +0 -1
  69. data/spec/responses/loupe/turingstudio_loupe_branch.json +0 -1
  70. data/spec/responses/loupe/turingstudio_loupe_network_data.json +0 -1
  71. data/spec/responses/loupe/turingstudio_loupe_network_meta.json +0 -1
  72. data/spec/responses/repos_show_jcoutu.json +0 -1
  73. data/spec/responses/repos_watched_jcoutu.json +0 -1
data/Gemfile CHANGED
@@ -2,14 +2,15 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
- gem "httparty"
5
+ gem "httparty", ">= 0.8.1"
6
6
 
7
7
  # Add dependencies to develop your gem here.
8
8
  # Include everything needed to run rake, tests, features, etc.
9
9
  group :development do
10
- gem "rspec", "~> 2.1.0"
11
- gem "bundler", "~> 1.0.0"
12
- gem "jeweler", "~> 1.5.1"
13
- gem "rcov", ">= 0"
10
+ gem "rspec", "~> 2.8.0"
11
+ gem "bundler"#, "~> 1.0.0"
12
+ gem "jeweler"#, "~> 1.5.1"
13
+ #gem "rcov", ">= 0"
14
14
  gem "fakeweb"
15
+ gem "vcr", "~> 2.0.1"
15
16
  end
data/Gemfile.lock CHANGED
@@ -1,34 +1,40 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- crack (0.1.8)
5
- diff-lcs (1.1.2)
4
+ diff-lcs (1.1.3)
6
5
  fakeweb (1.3.0)
7
6
  git (1.2.5)
8
- httparty (0.6.1)
9
- crack (= 0.1.8)
10
- jeweler (1.5.1)
11
- bundler (~> 1.0.0)
7
+ httparty (0.8.2)
8
+ multi_json
9
+ multi_xml
10
+ jeweler (1.8.3)
11
+ bundler (~> 1.0)
12
12
  git (>= 1.2.5)
13
13
  rake
14
- rake (0.8.7)
15
- rcov (0.9.9)
16
- rspec (2.1.0)
17
- rspec-core (~> 2.1.0)
18
- rspec-expectations (~> 2.1.0)
19
- rspec-mocks (~> 2.1.0)
20
- rspec-core (2.1.0)
21
- rspec-expectations (2.1.0)
14
+ rdoc
15
+ json (1.6.6)
16
+ multi_json (1.3.2)
17
+ multi_xml (0.4.4)
18
+ rake (0.9.2.2)
19
+ rdoc (3.12)
20
+ json (~> 1.4)
21
+ rspec (2.8.0)
22
+ rspec-core (~> 2.8.0)
23
+ rspec-expectations (~> 2.8.0)
24
+ rspec-mocks (~> 2.8.0)
25
+ rspec-core (2.8.0)
26
+ rspec-expectations (2.8.0)
22
27
  diff-lcs (~> 1.1.2)
23
- rspec-mocks (2.1.0)
28
+ rspec-mocks (2.8.0)
29
+ vcr (2.0.1)
24
30
 
25
31
  PLATFORMS
26
32
  ruby
27
33
 
28
34
  DEPENDENCIES
29
- bundler (~> 1.0.0)
35
+ bundler
30
36
  fakeweb
31
- httparty
32
- jeweler (~> 1.5.1)
33
- rcov
34
- rspec (~> 2.1.0)
37
+ httparty (>= 0.8.1)
38
+ jeweler
39
+ rspec (~> 2.8.0)
40
+ vcr (~> 2.0.1)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.4.0
data/get_token.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+ require 'oauth2' # ~> 0.5.0
4
+ require 'json'
5
+
6
+ def client
7
+ OAuth2::Client.new('CLIENT ID', 'SECRET',
8
+ :ssl => {:ca_file => '/etc/ssl/ca-bundle.pem'},
9
+ :site => 'https://api.github.com',
10
+ :authorize_url => 'https://github.com/login/oauth/authorize',
11
+ :token_url => 'https://github.com/login/oauth/access_token')
12
+ end
13
+
14
+ get "/" do
15
+ %(<p>Update the <code>#new_client</code> method in the sinatra app and <a href="/auth/github">try to authorize</a>.</p>)
16
+ end
17
+
18
+ get '/auth/github' do
19
+ url = client.auth_code.authorize_url(:redirect_uri => redirect_uri, :scope => 'user')
20
+ puts "Redirecting to URL: #{url.inspect}"
21
+ redirect url
22
+ end
23
+
24
+ get '/auth/github/callback' do
25
+ puts params[:code]
26
+ begin
27
+ access_token = client.auth_code.get_token(params[:code], :redirect_uri => redirect_uri)
28
+ user = JSON.parse(access_token.get('/user').body)
29
+ "<p>Your OAuth access token: #{access_token.token}</p><p>Your extended profile data:\n#{user.inspect}</p>"
30
+ rescue OAuth2::Error => e
31
+ %(<p>Outdated ?code=#{params[:code]}:</p><p>#{$!}</p><p><a href="/auth/github">Retry</a></p>)
32
+ end
33
+ end
34
+
35
+ def redirect_uri(path = '/auth/github/callback', query = nil)
36
+ uri = URI.parse(request.url)
37
+ uri.path = path
38
+ uri.query = query
39
+ uri.to_s
40
+ end
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{gitnetworkitis}
8
- s.version = "0.2.0"
7
+ s.name = "gitnetworkitis"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Julian Coutu"]
12
- s.date = %q{2011-05-26}
13
- s.description = %q{Git API Gem utilizing the Network API}
14
- s.email = %q{jcoutu@phaseiiicreations.com}
12
+ s.date = "2012-04-20"
13
+ s.description = "Git API Gem utilizing the Network API"
14
+ s.email = "jcoutu@phaseiiicreations.com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
17
  "README.rdoc"
@@ -26,102 +26,67 @@ Gem::Specification.new do |s|
26
26
  "README.rdoc",
27
27
  "Rakefile",
28
28
  "VERSION",
29
+ "get_token.rb",
29
30
  "gitnetworkitis-0.1.0.gem",
30
31
  "gitnetworkitis.gemspec",
31
32
  "lib/gitnetworkitis.rb",
32
33
  "lib/gitnetworkitis/base.rb",
34
+ "lib/gitnetworkitis/batch_response.rb",
33
35
  "lib/gitnetworkitis/branch.rb",
34
36
  "lib/gitnetworkitis/commit.rb",
35
- "lib/gitnetworkitis/network_data.rb",
36
- "lib/gitnetworkitis/network_meta.rb",
37
+ "lib/gitnetworkitis/commit_getter.rb",
38
+ "lib/gitnetworkitis/getter.rb",
39
+ "lib/gitnetworkitis/json_helper.rb",
37
40
  "lib/gitnetworkitis/repository.rb",
38
41
  "spec/base_spec.rb",
39
42
  "spec/branch_spec.rb",
40
- "spec/commit_spec.rb",
43
+ "spec/getter_spec.rb",
44
+ "spec/github_config.yml.example",
41
45
  "spec/gitnetworkitis_spec.rb",
42
- "spec/network_data_spec.rb",
43
- "spec/network_meta_spec.rb",
44
46
  "spec/repository_spec.rb",
45
- "spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=0.json",
46
- "spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=1.json",
47
- "spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=2.json",
48
- "spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=3.json",
49
- "spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=4.json",
50
- "spec/responses/branch_pages/turingstudio_loupe_51ac36280d2dfe16c37b66ef344859c9c714c8e1?page=5.json",
51
- "spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=0.json",
52
- "spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=1.json",
53
- "spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=2.json",
54
- "spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=3.json",
55
- "spec/responses/branch_pages/turingstudio_loupe_bec7b23dc57b14d89fa2829e8c32a108a18e7248?page=4.json",
56
- "spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=0.json",
57
- "spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=1.json",
58
- "spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=2.json",
59
- "spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=3.json",
60
- "spec/responses/branch_pages/turingstudio_loupe_c3aeb61e37f94bbb67c4f14b52c23b8e54d30d0e?page=4.json",
61
- "spec/responses/girlambition/0-500.json",
62
- "spec/responses/girlambition/1002-1502.json",
63
- "spec/responses/girlambition/1503-2003.json",
64
- "spec/responses/girlambition/2004-2504.json",
65
- "spec/responses/girlambition/2505-3005.json",
66
- "spec/responses/girlambition/3006-3506.json",
67
- "spec/responses/girlambition/3507-4007.json",
68
- "spec/responses/girlambition/4008-4508.json",
69
- "spec/responses/girlambition/4509-4999.json",
70
- "spec/responses/girlambition/501-1001.json",
71
- "spec/responses/girlambition/repos_show_turingstudio_website-girlambition_branches.json",
72
- "spec/responses/girlambition/turingstudio_website-girlambition_network_meta.json",
73
- "spec/responses/loupe/repos_show_turingstudio_loupe.json",
74
- "spec/responses/loupe/repos_show_turingstudio_loupe_branches.json",
75
- "spec/responses/loupe/turingstudio_loupe_068161e2c05a6b8029a7eb410dd27b1dfa531338?start=1&end=5.json",
76
- "spec/responses/loupe/turingstudio_loupe_068161e2c05a6b8029a7eb410dd27b1dfa531338?start=130.json",
77
- "spec/responses/loupe/turingstudio_loupe_branch.json",
78
- "spec/responses/loupe/turingstudio_loupe_network_data.json",
79
- "spec/responses/loupe/turingstudio_loupe_network_meta.json",
80
- "spec/responses/repos_show_jcoutu.json",
81
- "spec/responses/repos_watched_jcoutu.json",
82
- "spec/spec_helper.rb"
47
+ "spec/spec_helper.rb",
48
+ "spec/support/vcr_setup.rb",
49
+ "spec/vcr_cassettes/all_branches.json",
50
+ "spec/vcr_cassettes/all_repos.json",
51
+ "spec/vcr_cassettes/bad_creds.json",
52
+ "spec/vcr_cassettes/find_repo.json",
53
+ "spec/vcr_cassettes/spec-branch-1_commits.json",
54
+ "spec/vcr_cassettes/spec-branch-1_since_date.json",
55
+ "spec/vcr_cassettes/spec-branch-1_since_sha.json",
56
+ "spec/vcr_cassettes/spec-branch-2_commits.json",
57
+ "spec/vcr_cassettes/spec-branch-3_commits.json"
83
58
  ]
84
- s.homepage = %q{http://github.com/jcoutu/gitnetworkitis}
59
+ s.homepage = "http://github.com/jcoutu/gitnetworkitis"
85
60
  s.licenses = ["MIT"]
86
61
  s.require_paths = ["lib"]
87
- s.rubygems_version = %q{1.5.2}
88
- s.summary = %q{Git API Gem utilizing the Network API}
89
- s.test_files = [
90
- "spec/base_spec.rb",
91
- "spec/branch_spec.rb",
92
- "spec/commit_spec.rb",
93
- "spec/gitnetworkitis_spec.rb",
94
- "spec/network_data_spec.rb",
95
- "spec/network_meta_spec.rb",
96
- "spec/repository_spec.rb",
97
- "spec/spec_helper.rb"
98
- ]
62
+ s.rubygems_version = "1.8.15"
63
+ s.summary = "Git API Gem utilizing the Network API"
99
64
 
100
65
  if s.respond_to? :specification_version then
101
66
  s.specification_version = 3
102
67
 
103
68
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
104
- s.add_runtime_dependency(%q<httparty>, [">= 0"])
105
- s.add_development_dependency(%q<rspec>, ["~> 2.1.0"])
106
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
107
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
108
- s.add_development_dependency(%q<rcov>, [">= 0"])
69
+ s.add_runtime_dependency(%q<httparty>, [">= 0.8.1"])
70
+ s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
71
+ s.add_development_dependency(%q<bundler>, [">= 0"])
72
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
109
73
  s.add_development_dependency(%q<fakeweb>, [">= 0"])
74
+ s.add_development_dependency(%q<vcr>, ["~> 2.0.1"])
110
75
  else
111
- s.add_dependency(%q<httparty>, [">= 0"])
112
- s.add_dependency(%q<rspec>, ["~> 2.1.0"])
113
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
114
- s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
115
- s.add_dependency(%q<rcov>, [">= 0"])
76
+ s.add_dependency(%q<httparty>, [">= 0.8.1"])
77
+ s.add_dependency(%q<rspec>, ["~> 2.8.0"])
78
+ s.add_dependency(%q<bundler>, [">= 0"])
79
+ s.add_dependency(%q<jeweler>, [">= 0"])
116
80
  s.add_dependency(%q<fakeweb>, [">= 0"])
81
+ s.add_dependency(%q<vcr>, ["~> 2.0.1"])
117
82
  end
118
83
  else
119
- s.add_dependency(%q<httparty>, [">= 0"])
120
- s.add_dependency(%q<rspec>, ["~> 2.1.0"])
121
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
122
- s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
123
- s.add_dependency(%q<rcov>, [">= 0"])
84
+ s.add_dependency(%q<httparty>, [">= 0.8.1"])
85
+ s.add_dependency(%q<rspec>, ["~> 2.8.0"])
86
+ s.add_dependency(%q<bundler>, [">= 0"])
87
+ s.add_dependency(%q<jeweler>, [">= 0"])
124
88
  s.add_dependency(%q<fakeweb>, [">= 0"])
89
+ s.add_dependency(%q<vcr>, ["~> 2.0.1"])
125
90
  end
126
91
  end
127
92
 
@@ -1,51 +1,21 @@
1
1
  module GitNetworkitis
2
2
  class Base
3
- include HTTParty
4
- attr_accessor :username, :token
3
+ include JSONHelper
4
+ attr_accessor :token
5
5
 
6
- def initialize(username, token, options={})
7
- @username = username
6
+ # token is an oauth2 token
7
+ def initialize(token, options={})
8
8
  @token = token
9
- self.class.basic_auth "#{username}/token", token
10
9
  options.each do |key, value|
11
10
  method = "#{key}="
12
11
  self.send(method, value) if respond_to? method
13
12
  end
14
13
  end
15
14
 
16
- def get url
17
- ret = self.class.get(url)
18
- if ret.response.code == "200"
19
- return ret
20
- else
21
- raise "Unable to find Github Repository"
22
- end
23
- end
24
-
25
- def parse_json json
26
- begin
27
- return JSON.parse(escape_json(json))
28
- rescue => e
29
- raise "Unable to parse JSON result" #{e.message}
30
- end
31
- end
32
-
33
-
34
- private
35
- def parse_attributes(json, object)
36
- json.each do |key, value|
37
- method = "#{key}="
38
- if object.respond_to? method
39
- object.send(method, value)
40
- end
41
- end
42
- object
43
- end
44
-
45
- #This is for parsing bad json returned from github
46
- def escape_json(json)
47
- json.gsub(/(....\[31m)./, '')
48
- end
49
-
15
+ # see Getter for options
16
+ def get(url, options={})
17
+ opts = {access_token: token}.merge options
18
+ Getter.new(url, opts).get
50
19
  end
51
- end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module GitNetworkitis
2
+ # This class serves as a sort of proxy for HTTParty::Response. When a
3
+ # Base#batched_get is performed, a BatchResponse object is returned,
4
+ # with a #body made up of the concatenation of its responses'. This
5
+ # way, paged responses (like for commits) can appear as a single
6
+ # response body to the code that handles it. This is necessary
7
+ # because HTTParty::Response has no setter on its #body attribute,
8
+ # and sets it directly from its #response on #initialize.
9
+ class BatchResponse
10
+
11
+ attr_reader :responses, :body
12
+
13
+ def initialize responses
14
+ @responses = responses
15
+
16
+ # Since we're combining response bodies, we have a series of JSON
17
+ # arrays that need to be joined (hence the gsub).
18
+ @body = responses.map {|r| r.body.to_s }.
19
+ join('').
20
+ gsub(/\]\[/, ', ')
21
+ end
22
+
23
+ end
24
+ end
@@ -1,42 +1,21 @@
1
1
  module GitNetworkitis
2
2
  class Branch < Base
3
- base_uri 'https://github.com/api/v2/json/'
4
-
5
- attr_accessor :name, :id, :owner, :repo
3
+ attr_accessor :commit, :name, :owner, :repo
6
4
 
7
5
  #Retrieves all branches based on a specific repo.
8
6
  def find_all(options={})
9
- if options.has_key?(:owner) & options.has_key?(:repo)
10
- resp = get("/repos/show/#{options[:owner]}/#{options[:repo]}/branches")
11
- json_result = parse_json(escape_json(resp.body.to_s))
12
- result = Array.new
13
- json_result["branches"].each do |branch|
14
- result.push Branch.new(self.username, self.token, {:name =>branch[0], :id => branch[1], :owner => options[:owner], :repo => options[:repo]})
7
+ if options.has_key?(:owner) & options.has_key?(:repo)
8
+ resp = get("/repos/#{options[:owner]}/#{options[:repo]}/branches")
9
+ parse_json(escape_json(resp.body.to_s)).inject([]) do |branches, branch|
10
+ branches << parse_attributes(branch, Branch.new(token, :owner => options[:owner], :repo => options[:repo]))
15
11
  end
16
- return result
17
12
  end
18
13
  end
19
14
 
20
-
21
- #Loops pages and returns all commits specific to a branch
22
- def commits
23
- pages = true
24
- counter = 0
25
- result = Array.new
26
- while pages do
27
- resp = self.get("/commits/list/#{self.owner}/#{self.repo}/#{self.id}?page=#{counter}")
28
- json_result = parse_json(escape_json(resp.body.to_s))
29
- if !json_result.has_key?("error")
30
- json_result["commits"].each do |commit|
31
- temp_commit = parse_attributes(commit, Commit.new(self.username, self.token))
32
- result.push temp_commit
33
- end
34
- else
35
- pages = false
36
- end
37
- counter = counter+1
38
- end
39
- result
15
+ def commits(options={})
16
+ opts = {access_token: token, per_page: 100, batch: true}.merge options
17
+ CommitGetter.new("/repos/#{owner}/#{repo}/commits?sha=#{commit['sha']}", opts).get
40
18
  end
19
+
41
20
  end
42
- end
21
+ end
@@ -1,8 +1,5 @@
1
1
  module GitNetworkitis
2
2
  class Commit < Base
3
- base_uri 'https://github.com/'
4
-
5
- attr_accessor :parents, :author, :time, :id, :date, :gravatar, :space, :message, :login
6
-
3
+ attr_accessor :sha, :url, :author, :committer, :message, :tree, :parents
7
4
  end
8
- end
5
+ end
@@ -0,0 +1,50 @@
1
+ module GitNetworkitis
2
+ #NOTE tested via the Branch specs
3
+ class CommitGetter < Getter
4
+ def get
5
+ if local_options[:since]
6
+ since_commits
7
+ else
8
+ response = super
9
+ build_commits response
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def since_commits
16
+ since_date = DateTime.parse local_options[:since]
17
+ batched_since_commits {|c| c.committer['date'] }
18
+ rescue ArgumentError => e
19
+ batched_since_commits &:sha
20
+ end
21
+
22
+ def batched_since_commits &block
23
+ links = {next: url}
24
+ results = []
25
+ while links[:next] do
26
+ self.url = links[:next]
27
+ resp = single_get
28
+ staged_commits = build_commits resp
29
+ since_index = staged_commits.find_index {|c| yield(c) == local_options[:since] }
30
+ if since_index
31
+ results += staged_commits.first(since_index)
32
+ links = {}
33
+ else
34
+ results << staged_commits
35
+ links = build_links_from_headers resp.headers['link']
36
+ end
37
+ end
38
+ results
39
+ end
40
+
41
+ def build_commits(response)
42
+ parse_json(escape_json(response.body.to_s)).inject([]) do |commits, commit|
43
+ commit_attrs = commit['commit'].merge('sha' => commit['sha'], 'parents' => commit['parents'])
44
+ parsed_commit = parse_attributes(commit_attrs, Commit.new(query_options[:access_token]))
45
+ commits << parsed_commit
46
+ end
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,64 @@
1
+ module GitNetworkitis
2
+ class Getter
3
+ include HTTParty
4
+ include JSONHelper
5
+ base_uri 'https://api.github.com'
6
+
7
+ attr_accessor :url, :local_options, :query_options
8
+
9
+ LOCAL_KEYS = [:batch, :since, :branch]
10
+
11
+ def initialize(url, options={})
12
+ @url = url
13
+ scrub_local_options options
14
+ @query_options = options
15
+ end
16
+
17
+ def get
18
+ local_options[:batch] ? batched_get : single_get
19
+ end
20
+
21
+ private
22
+ def scrub_local_options(options={})
23
+ @local_options = LOCAL_KEYS.inject({}) {|opts, key| opts[key] = options.delete(key); opts }
24
+ @local_options[:batch] = true unless @local_options[:since].nil?
25
+ end
26
+
27
+ def single_get(use_query_options=true)
28
+ ret = use_query_options ? Getter.get(url, query: query_options) : Getter.get(url)
29
+ if ret.response.code == "200"
30
+ return ret
31
+ else
32
+ raise "Unable to find Github Repository"
33
+ end
34
+ end
35
+
36
+ def batched_get
37
+ resps = []
38
+ links = {next: url}
39
+ first_batch = true
40
+ while links[:next] do
41
+ self.url = links[:next]
42
+ resp = single_get first_batch
43
+ resps << resp
44
+ first_batch = false
45
+ links = build_links_from_headers resp.headers['link']
46
+ end
47
+ BatchResponse.new resps
48
+ end
49
+
50
+ # see the json files in spec/vcr_cassettes for examples of what the link headers look like
51
+ def build_links_from_headers(headers)
52
+ return {} if headers.nil?
53
+
54
+ links = headers.split(',')
55
+ links.inject({}) do |rel, link|
56
+ l = link.strip.split(';')
57
+ next_link = l.first[1...-1] # [1...-1] because the actual link is enclosed within '<' '>' tags
58
+ rel_command = l.last.strip.match(/rel=\"(.*)\"/).captures.first.to_sym # e.g. "rel=\"next\"" #=> :next
59
+ rel.tap {|r| r[rel_command] = next_link }
60
+ end
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,24 @@
1
+ module GitNetworkitis
2
+ module JSONHelper
3
+ def parse_json(json)
4
+ return JSON.parse(escape_json(json))
5
+ rescue => e
6
+ raise "Unable to parse JSON result" #{e.message}
7
+ end
8
+
9
+ #This is for parsing bad json returned from github
10
+ def escape_json(json)
11
+ json.gsub(/(....\[31m)./, '')
12
+ end
13
+
14
+ def parse_attributes(json, object)
15
+ json.each do |key, value|
16
+ method = "#{key}="
17
+ if object.respond_to? method
18
+ object.send(method, value)
19
+ end
20
+ end
21
+ object
22
+ end
23
+ end
24
+ end
@@ -1,44 +1,25 @@
1
1
  module GitNetworkitis
2
2
  class Repository < Base
3
- base_uri 'https://github.com/api/v2/json/'
3
+ attr_accessor :watchers, :homepage, :has_downloads, :forks, :url, :has_wiki, :size, :private
4
+ attr_accessor :owner, :name, :description, :open_issues
4
5
 
5
- attr_accessor :description, :has_wiki, :url, :forks, :open_issues, :forks, :name, :homepage, :watchers, :owner, :private, :pledgie, :size, :has_downloads
6
-
7
- def find_all_watched
8
- result = Array.new
9
- unless !self.username && !self.token
10
- resp = get("/repos/watched/#{self.username}")
11
- json_result = self.parse_json(resp.body.to_s)
12
- json_result["repositories"].each do |repo|
13
- result.push parse_attributes(repo, Repository.new(self.username, self.token))
14
- end
15
- end
16
- return result
17
- end
18
-
19
- def find_all_owned
20
- result = Array.new
21
- unless !self.username && !self.token
22
- resp = get("/repos/show/#{self.username}")
23
- json_result = parse_json(resp.body.to_s)
24
- json_result["repositories"].each do |repo|
25
- result.push parse_attributes(repo, Repository.new(self.username, self.token))
26
- end
6
+ #TODO use options to handle the optional filter params that github v3 supports
7
+ def find_all(options={})
8
+ resp = get("/user/repos", type: (options[:type] || 'all'))
9
+ parse_json(resp.body.to_s).inject([]) do |repos, repo|
10
+ repos << parse_attributes(repo, Repository.new(token))
27
11
  end
28
- return result
29
12
  end
30
13
 
31
14
  def find(options={})
32
- result = Array.new
33
- if options.has_key?(:owner) & options.has_key?(:repo)
34
- resp = get("/repos/show/#{options[:owner]}/#{options[:repo]}")
35
- json_result = parse_json(resp.body.to_s)
36
- parse_attributes(json_result["repository"], Repository.new(self.username, self.token))
15
+ if options.has_key?(:owner) & options.has_key?(:repo)
16
+ resp = get("/repos/#{options[:owner]}/#{options[:repo]}")
17
+ parse_attributes(parse_json(resp.body.to_s), Repository.new(token))
37
18
  end
38
19
  end
39
20
 
40
21
  def remote_id
41
- return "#{self.owner}/#{self.name}"
22
+ return "#{self.owner['login']}/#{self.name}"
42
23
  end
43
24
 
44
25
  end
@@ -1,11 +1,16 @@
1
1
  require 'httparty'
2
2
  require 'json'
3
3
 
4
- # GitNetworkitis stuff
5
- # By sorting them we ensure that api and base are loaded first on all sane operating systems
6
- Dir[File.join(File.dirname(__FILE__), "gitnetworkitis/*.rb")].sort.each { |f| require f }
4
+ ['gitnetworkitis/json_helper',
5
+ 'gitnetworkitis/base',
6
+ 'gitnetworkitis/commit',
7
+ 'gitnetworkitis/repository',
8
+ 'gitnetworkitis/branch',
9
+ 'gitnetworkitis/getter',
10
+ 'gitnetworkitis/commit_getter',
11
+ 'gitnetworkitis/batch_response'].each {|f| require File.join(File.dirname(__FILE__), f) }
7
12
 
8
13
  module GitNetworkitis
9
14
 
10
-
11
- end
15
+
16
+ end