hubba 0.7.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/hubba/github.rb CHANGED
@@ -1,210 +1,210 @@
1
- module Hubba
2
-
3
-
4
- class Github
5
- BASE_URL = 'https://api.github.com'
6
-
7
- ###############
8
- ## (nested) classes for "wrapped" response (parsed json body)
9
- class Resource
10
- attr_reader :data
11
- def initialize( data )
12
- @data = data
13
- end
14
- end
15
-
16
- class Repos < Resource
17
- def names
18
- ## sort by name
19
- data.map { |item| item['name'] }.sort
20
- end
21
- end
22
-
23
- class Orgs < Resource
24
- def logins
25
- ## sort by name
26
- data.map { |item| item['login'] }.sort
27
- end
28
- alias_method :names, :logins ## add name alias - why? why not?
29
- end
30
-
31
-
32
-
33
- def initialize( token: nil,
34
- user: nil,
35
- password: nil )
36
- @token = nil
37
- @user = nil
38
- @password = nil
39
-
40
- if token ## 1a) give preference to passed in token
41
- @token = token
42
- elsif user && password ## 1b) or passed in user/password credentials
43
- @user = user
44
- @password = password
45
- elsif Hubba.config.token ## 2a) followed by configured (or env) token
46
- @token = Hubba.config.token
47
- elsif Hubba.config.user && Hubba.config.password ## 2b)
48
- @user = Hubba.config.user
49
- @password = Hubba.config.password
50
- else ## 3)
51
- ## no token or credentials passed in or configured
52
- end
53
- end
54
-
55
-
56
-
57
- def user( name )
58
- Resource.new( get "/users/#{name}" )
59
- end
60
-
61
-
62
- def user_repos( name )
63
- Repos.new( get "/users/#{name}/repos" ) ## add ?per_page=100 - why? why not?
64
- end
65
-
66
-
67
- ##
68
- # note: pagination
69
- # requests that return multiple items will be paginated to 30 items by default.
70
- # You can specify further pages with the ?page parameter.
71
- # For some resources, you can also set a custom page size up to 100
72
- # with the ?per_page=100 parameter
73
-
74
- def user_orgs( name )
75
- Orgs.new( get "/users/#{name}/orgs?per_page=100" )
76
- end
77
-
78
-
79
-
80
- def org( name )
81
- Resource.new( get "/orgs/#{name}" )
82
- end
83
-
84
- def org_repos( name )
85
- Repos.new( get "/orgs/#{name}/repos?per_page=100" )
86
- end
87
-
88
-
89
-
90
- def repo( full_name ) ## full_name (handle) e.g. henrythemes/jekyll-starter-theme
91
- Resource.new( get "/repos/#{full_name}" )
92
- end
93
-
94
- def repo_languages( full_name )
95
- Resource.new( get "/repos/#{full_name}/languages" )
96
- end
97
-
98
- def repo_topics( full_name )
99
- ## note: requires "api preview" accept headers (overwrites default v3+json)
100
- ## e.g. application/vnd.github.mercy-preview+json
101
- Resource.new( get( "/repos/#{full_name}/topics", preview: 'mercy' ) )
102
- end
103
-
104
-
105
- def repo_commits( full_name )
106
- Resource.new( get "/repos/#{full_name}/commits" )
107
- end
108
-
109
-
110
- def repo_traffic_clones( full_name )
111
- # Get repository clones
112
- # Get the total number of clones and breakdown per day or week
113
- # for the last 14 days.
114
- # Timestamps are aligned to UTC midnight of the beginning of the day or week.
115
- # Week begins on Monday.
116
- Resource.new( get "/repos/#{full_name}/traffic/clones" )
117
- end
118
-
119
- def repo_traffic_views( full_name )
120
- # Get page views
121
- # Get the total number of views and breakdown per day or week
122
- # for the last 14 days.
123
- # Timestamps are aligned to UTC midnight of the beginning of the day or week.
124
- # Week begins on Monday.
125
- Resource.new( get "/repos/#{full_name}/traffic/views" )
126
- end
127
-
128
-
129
- def repo_traffic_popular_paths( full_name )
130
- # Get top referral paths
131
- # Get the top 10 popular contents over the last 14 days.
132
- Resource.new( get "/repos/#{full_name}/traffic/popular/paths" )
133
- end
134
-
135
- def repo_traffic_popular_referrers( full_name )
136
- # Get top referral sources
137
- # Get the top 10 referrers over the last 14 days.
138
- Resource.new( get "/repos/#{full_name}/traffic/popular/referrers" )
139
- end
140
-
141
-
142
-
143
-
144
- private
145
- def get( request_uri, preview: nil )
146
-
147
- puts "GET #{request_uri}"
148
-
149
- ## note: request_uri ALWAYS starts with leading /, thus use + for now!!!
150
- # e.g. /users/geraldb
151
- # /users/geraldb/repos
152
- url = BASE_URL + request_uri
153
-
154
-
155
- headers = {}
156
- ## add default headers if nothing (custom) set / passed-in
157
- headers['User-Agent'] = "ruby/hubba v#{VERSION}" ## required by GitHub API
158
- headers['Accept'] = if preview # e.g. mercy or ???
159
- "application/vnd.github.#{preview}-preview+json"
160
- else
161
- 'application/vnd.github.v3+json' ## default - recommend by GitHub API
162
- end
163
-
164
- auth = []
165
- ## check if credentials (user/password) present - if yes, use basic auth
166
- if @token
167
- puts " using (personal access) token - starting with: #{@token[0..6]}**********"
168
- headers['Authorization'] = "token #{@token}"
169
- ## token works like:
170
- ## curl -H 'Authorization: token my_access_token' https://api.github.com/user/repos
171
- elsif @user && @password
172
- puts " using basic auth - user: #{@user}, password: ***"
173
- ## use credential auth "tuple" (that is, array with two string items) for now
174
- ## or use Webclient::HttpBasicAuth or something - why? why not?
175
- auth = [@user, @password]
176
- # req.basic_auth( @user, @password )
177
- else
178
- puts " using no credentials (no token, no user/password)"
179
- end
180
-
181
- res = Webclient.get( url,
182
- headers: headers,
183
- auth: auth )
184
-
185
- # Get specific header
186
- # response["content-type"]
187
- # => "text/html; charset=UTF-8"
188
-
189
- # Iterate all response headers.
190
- # puts "HTTP HEADERS:"
191
- # res.headers.each do |key, value|
192
- # puts " #{key}: >#{value}<"
193
- # end
194
- # puts
195
-
196
- # => "location => http://www.google.com/"
197
- # => "content-type => text/html; charset=UTF-8"
198
- # ...
199
-
200
- if res.status.ok?
201
- res.json
202
- else
203
- puts "!! HTTP ERROR: #{res.status.code} #{res.status.message}:"
204
- pp res.raw
205
- exit 1
206
- end
207
- end # method get
208
-
209
- end # class Github
210
- end # module Hubba
1
+ module Hubba
2
+
3
+
4
+ class Github
5
+ BASE_URL = 'https://api.github.com'
6
+
7
+ ###############
8
+ ## (nested) classes for "wrapped" response (parsed json body)
9
+ class Resource
10
+ attr_reader :data
11
+ def initialize( data )
12
+ @data = data
13
+ end
14
+ end
15
+
16
+ class Repos < Resource
17
+ def names
18
+ ## sort by name
19
+ data.map { |item| item['name'] }.sort
20
+ end
21
+ end
22
+
23
+ class Orgs < Resource
24
+ def logins
25
+ ## sort by name
26
+ data.map { |item| item['login'] }.sort
27
+ end
28
+ alias_method :names, :logins ## add name alias - why? why not?
29
+ end
30
+
31
+
32
+
33
+ def initialize( token: nil,
34
+ user: nil,
35
+ password: nil )
36
+ @token = nil
37
+ @user = nil
38
+ @password = nil
39
+
40
+ if token ## 1a) give preference to passed in token
41
+ @token = token
42
+ elsif user && password ## 1b) or passed in user/password credentials
43
+ @user = user
44
+ @password = password
45
+ elsif Hubba.config.token ## 2a) followed by configured (or env) token
46
+ @token = Hubba.config.token
47
+ elsif Hubba.config.user && Hubba.config.password ## 2b)
48
+ @user = Hubba.config.user
49
+ @password = Hubba.config.password
50
+ else ## 3)
51
+ ## no token or credentials passed in or configured
52
+ end
53
+ end
54
+
55
+
56
+
57
+ def user( name )
58
+ Resource.new( get "/users/#{name}" )
59
+ end
60
+
61
+
62
+ def user_repos( name )
63
+ Repos.new( get "/users/#{name}/repos" ) ## add ?per_page=100 - why? why not?
64
+ end
65
+
66
+
67
+ ##
68
+ # note: pagination
69
+ # requests that return multiple items will be paginated to 30 items by default.
70
+ # You can specify further pages with the ?page parameter.
71
+ # For some resources, you can also set a custom page size up to 100
72
+ # with the ?per_page=100 parameter
73
+
74
+ def user_orgs( name )
75
+ Orgs.new( get "/users/#{name}/orgs?per_page=100" )
76
+ end
77
+
78
+
79
+
80
+ def org( name )
81
+ Resource.new( get "/orgs/#{name}" )
82
+ end
83
+
84
+ def org_repos( name )
85
+ Repos.new( get "/orgs/#{name}/repos?per_page=100" )
86
+ end
87
+
88
+
89
+
90
+ def repo( full_name ) ## full_name (handle) e.g. henrythemes/jekyll-starter-theme
91
+ Resource.new( get "/repos/#{full_name}" )
92
+ end
93
+
94
+ def repo_languages( full_name )
95
+ Resource.new( get "/repos/#{full_name}/languages" )
96
+ end
97
+
98
+ def repo_topics( full_name )
99
+ ## note: requires "api preview" accept headers (overwrites default v3+json)
100
+ ## e.g. application/vnd.github.mercy-preview+json
101
+ Resource.new( get( "/repos/#{full_name}/topics", preview: 'mercy' ) )
102
+ end
103
+
104
+
105
+ def repo_commits( full_name )
106
+ Resource.new( get "/repos/#{full_name}/commits" )
107
+ end
108
+
109
+
110
+ def repo_traffic_clones( full_name )
111
+ # Get repository clones
112
+ # Get the total number of clones and breakdown per day or week
113
+ # for the last 14 days.
114
+ # Timestamps are aligned to UTC midnight of the beginning of the day or week.
115
+ # Week begins on Monday.
116
+ Resource.new( get "/repos/#{full_name}/traffic/clones" )
117
+ end
118
+
119
+ def repo_traffic_views( full_name )
120
+ # Get page views
121
+ # Get the total number of views and breakdown per day or week
122
+ # for the last 14 days.
123
+ # Timestamps are aligned to UTC midnight of the beginning of the day or week.
124
+ # Week begins on Monday.
125
+ Resource.new( get "/repos/#{full_name}/traffic/views" )
126
+ end
127
+
128
+
129
+ def repo_traffic_popular_paths( full_name )
130
+ # Get top referral paths
131
+ # Get the top 10 popular contents over the last 14 days.
132
+ Resource.new( get "/repos/#{full_name}/traffic/popular/paths" )
133
+ end
134
+
135
+ def repo_traffic_popular_referrers( full_name )
136
+ # Get top referral sources
137
+ # Get the top 10 referrers over the last 14 days.
138
+ Resource.new( get "/repos/#{full_name}/traffic/popular/referrers" )
139
+ end
140
+
141
+
142
+
143
+
144
+ private
145
+ def get( request_uri, preview: nil )
146
+
147
+ puts "GET #{request_uri}"
148
+
149
+ ## note: request_uri ALWAYS starts with leading /, thus use + for now!!!
150
+ # e.g. /users/geraldb
151
+ # /users/geraldb/repos
152
+ url = BASE_URL + request_uri
153
+
154
+
155
+ headers = {}
156
+ ## add default headers if nothing (custom) set / passed-in
157
+ headers['User-Agent'] = "ruby/hubba v#{VERSION}" ## required by GitHub API
158
+ headers['Accept'] = if preview # e.g. mercy or ???
159
+ "application/vnd.github.#{preview}-preview+json"
160
+ else
161
+ 'application/vnd.github.v3+json' ## default - recommend by GitHub API
162
+ end
163
+
164
+ auth = []
165
+ ## check if credentials (user/password) present - if yes, use basic auth
166
+ if @token
167
+ puts " using (personal access) token - starting with: #{@token[0..6]}**********"
168
+ headers['Authorization'] = "token #{@token}"
169
+ ## token works like:
170
+ ## curl -H 'Authorization: token my_access_token' https://api.github.com/user/repos
171
+ elsif @user && @password
172
+ puts " using basic auth - user: #{@user}, password: ***"
173
+ ## use credential auth "tuple" (that is, array with two string items) for now
174
+ ## or use Webclient::HttpBasicAuth or something - why? why not?
175
+ auth = [@user, @password]
176
+ # req.basic_auth( @user, @password )
177
+ else
178
+ puts " using no credentials (no token, no user/password)"
179
+ end
180
+
181
+ res = Webclient.get( url,
182
+ headers: headers,
183
+ auth: auth )
184
+
185
+ # Get specific header
186
+ # response["content-type"]
187
+ # => "text/html; charset=UTF-8"
188
+
189
+ # Iterate all response headers.
190
+ # puts "HTTP HEADERS:"
191
+ # res.headers.each do |key, value|
192
+ # puts " #{key}: >#{value}<"
193
+ # end
194
+ # puts
195
+
196
+ # => "location => http://www.google.com/"
197
+ # => "content-type => text/html; charset=UTF-8"
198
+ # ...
199
+
200
+ if res.status.ok?
201
+ res.json
202
+ else
203
+ puts "!! HTTP ERROR: #{res.status.code} #{res.status.message}:"
204
+ pp res.raw
205
+ exit 1
206
+ end
207
+ end # method get
208
+
209
+ end # class Github
210
+ end # module Hubba
data/lib/hubba/reposet.rb CHANGED
@@ -1,83 +1,83 @@
1
- module Hubba
2
-
3
-
4
- ## orgs - include repos form org(anizations) too
5
- ## cache - save json response to cache_dir - change to/use debug/tmp_dir? - why? why not?
6
- def self.reposet( *users, orgs: true,
7
- cache: false )
8
- # users = [users] if users.is_a?( String ) ### wrap in array if single user
9
-
10
- gh = Github.new
11
-
12
- forks = []
13
-
14
- h = {}
15
- users.each do |user|
16
- res = gh.user_repos( user )
17
- save_json( "#{config.cache_dir}/users~#{user}~repos.json", res.data ) if cache
18
-
19
- repos = []
20
- ####
21
- # check for forked repos (auto-exclude personal by default)
22
- # note: forked repos in orgs get NOT auto-excluded!!!
23
- res.data.each do |repo|
24
- fork = repo['fork']
25
- if fork
26
- print "FORK "
27
- forks << "#{repo['full_name']} (AUTO-EXCLUDED)"
28
- else
29
- print " "
30
- repos << repo['name']
31
- end
32
- print repo['full_name']
33
- print "\n"
34
- end
35
-
36
-
37
- h[ "#{user} (#{repos.size})" ] = repos.sort
38
- end
39
-
40
-
41
- ## all repos from orgs
42
- ## note: for now only use first (primary user) - why? why not?
43
- if orgs
44
- user = users[0]
45
- res = gh.user_orgs( user )
46
- save_json( "#{config.cache_dir}/users~#{user}~orgs.json", res.data ) if cache
47
-
48
-
49
- logins = res.logins.each do |login|
50
- ## next if ['xxx'].include?( login ) ## add orgs here to skip
51
-
52
- res = gh.org_repos( login )
53
- save_json( "#{config.cache_dir}/orgs~#{login}~repos.json", res.data ) if cache
54
-
55
- repos = []
56
- res.data.each do |repo|
57
- fork = repo['fork']
58
- if fork
59
- print "FORK "
60
- forks << repo['full_name']
61
- repos << repo['name']
62
- else
63
- print " "
64
- repos << repo['name']
65
- end
66
- print repo['full_name']
67
- print "\n"
68
- end
69
-
70
- h[ "#{login} (#{repos.size})" ] = repos.sort
71
- end
72
- end
73
-
74
- if forks.size > 0
75
- puts
76
- puts "#{forks.size} fork(s):"
77
- puts forks
78
- end
79
-
80
- h
81
- end ## method reposet
82
-
83
- end # module Hubba
1
+ module Hubba
2
+
3
+
4
+ ## orgs - include repos form org(anizations) too
5
+ ## cache - save json response to cache_dir - change to/use debug/tmp_dir? - why? why not?
6
+ def self.reposet( *users, orgs: true,
7
+ cache: false )
8
+ # users = [users] if users.is_a?( String ) ### wrap in array if single user
9
+
10
+ gh = Github.new
11
+
12
+ forks = []
13
+
14
+ h = {}
15
+ users.each do |user|
16
+ res = gh.user_repos( user )
17
+ save_json( "#{config.cache_dir}/users~#{user}~repos.json", res.data ) if cache
18
+
19
+ repos = []
20
+ ####
21
+ # check for forked repos (auto-exclude personal by default)
22
+ # note: forked repos in orgs get NOT auto-excluded!!!
23
+ res.data.each do |repo|
24
+ fork = repo['fork']
25
+ if fork
26
+ print "FORK "
27
+ forks << "#{repo['full_name']} (AUTO-EXCLUDED)"
28
+ else
29
+ print " "
30
+ repos << repo['name']
31
+ end
32
+ print repo['full_name']
33
+ print "\n"
34
+ end
35
+
36
+
37
+ h[ "#{user} (#{repos.size})" ] = repos.sort
38
+ end
39
+
40
+
41
+ ## all repos from orgs
42
+ ## note: for now only use first (primary user) - why? why not?
43
+ if orgs
44
+ user = users[0]
45
+ res = gh.user_orgs( user )
46
+ save_json( "#{config.cache_dir}/users~#{user}~orgs.json", res.data ) if cache
47
+
48
+
49
+ logins = res.logins.each do |login|
50
+ ## next if ['xxx'].include?( login ) ## add orgs here to skip
51
+
52
+ res = gh.org_repos( login )
53
+ save_json( "#{config.cache_dir}/orgs~#{login}~repos.json", res.data ) if cache
54
+
55
+ repos = []
56
+ res.data.each do |repo|
57
+ fork = repo['fork']
58
+ if fork
59
+ print "FORK "
60
+ forks << repo['full_name']
61
+ repos << repo['name']
62
+ else
63
+ print " "
64
+ repos << repo['name']
65
+ end
66
+ print repo['full_name']
67
+ print "\n"
68
+ end
69
+
70
+ h[ "#{login} (#{repos.size})" ] = repos.sort
71
+ end
72
+ end
73
+
74
+ if forks.size > 0
75
+ puts
76
+ puts "#{forks.size} fork(s):"
77
+ puts forks
78
+ end
79
+
80
+ h
81
+ end ## method reposet
82
+
83
+ end # module Hubba