hubba 0.2.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 483d4813ac93c23eaf300404342fb8883712449a
4
- data.tar.gz: 897633ce5908ead11844d5421dd495e087440747
3
+ metadata.gz: 8362d3b3f03aadf2fb3708be499e3daeccfe343d
4
+ data.tar.gz: ce865016b107b78fbd72d3817364040551d61596
5
5
  SHA512:
6
- metadata.gz: e33ee3954c0a131e05cd3ca92c0359be2b27cafa59541ad2e76a6338ef64b35e618b74c5b335177f77ffddf85604f6be4fc72d314ab39293e66e901eedd8ab81
7
- data.tar.gz: d4a32cd4fd90fb3d7da117f7a25b04cfb13dc5a0049134255edcbc53753604af4a5916ba7223ef86454c1b8331a03f7b2b4f753907ea3ea6ddcd41379c796d93
6
+ metadata.gz: 37c9ed873b55c67f5db957ea663222f3a6c0bb9ee8e4b5c58ca52917159407e1cf88e2bba9f86bcf63d42431a531dc09c0954bd9e9f1c66a0b4dab724c34534d
7
+ data.tar.gz: 9fbb4951feade4506e5721c9cb635856227f346def9f11d50557048f8acb41e1e927901617de5177d9c8363c2513b9bfa3b354b7bc5f532c77f1b53e6d0dd525
File without changes
@@ -1,4 +1,4 @@
1
- HISTORY.md
1
+ CHANGELOG.md
2
2
  Manifest.txt
3
3
  README.md
4
4
  Rakefile
@@ -11,6 +11,11 @@ lib/hubba/version.rb
11
11
  test/cache/users~geraldb~orgs.json
12
12
  test/cache/users~geraldb~repos.json
13
13
  test/helper.rb
14
+ test/stats/jekyll~minima.json
15
+ test/stats/openblockchains~awesome-blockchains.json
16
+ test/stats/opendatajson~factbook.json.json
17
+ test/stats/poole~hyde.json
14
18
  test/test_cache.rb
15
19
  test/test_config.rb
16
20
  test/test_stats.rb
21
+ test/test_stats_tmp.rb
data/README.md CHANGED
@@ -1,20 +1,20 @@
1
- # hubba
2
-
3
- hubba gem - (yet) another (lite) GitHub HTTP API client / library
4
-
5
- * home :: [github.com/rubylibs/hubba](https://github.com/rubylibs/hubba)
6
- * bugs :: [github.com/rubylibs/hubba/issues](https://github.com/rubylibs/hubba/issues)
7
- * gem :: [rubygems.org/gems/hubba](https://rubygems.org/gems/hubba)
8
- * rdoc :: [rubydoc.info/gems/hubba](http://rubydoc.info/gems/hubba)
9
-
10
-
11
- ## Usage
12
-
13
- TBD
14
-
15
-
16
- ## License
17
-
18
- The `hubba` scripts are dedicated to the public domain.
19
- Use it as you please with no restrictions whatsoever.
20
-
1
+ # hubba
2
+
3
+ hubba gem - (yet) another (lite) GitHub HTTP API client / library
4
+
5
+ * home :: [github.com/rubycoco/git](https://github.com/rubycoco/git)
6
+ * bugs :: [github.com/rubycoco/git/issues](https://github.com/rubycoco/git/issues)
7
+ * gem :: [rubygems.org/gems/hubba](https://rubygems.org/gems/hubba)
8
+ * rdoc :: [rubydoc.info/gems/hubba](http://rubydoc.info/gems/hubba)
9
+
10
+
11
+ ## Usage
12
+
13
+ TBD
14
+
15
+
16
+
17
+ ## License
18
+
19
+ The `hubba` scripts are dedicated to the public domain.
20
+ Use it as you please with no restrictions whatsoever.
data/Rakefile CHANGED
@@ -5,26 +5,26 @@ Hoe.spec 'hubba' do
5
5
 
6
6
  self.version = Hubba::VERSION
7
7
 
8
- self.summary = 'hubba - (yet) another (lite) GitHub HTTP API client / library'
8
+ self.summary = 'hubba - (yet) another (lite) GitHub HTTP API client / library'
9
9
  self.description = summary
10
10
 
11
- self.urls = ['https://github.com/rubylibs/hubba']
11
+ self.urls = { home: 'https://github.com/rubycoco/git' }
12
12
 
13
13
  self.author = 'Gerald Bauer'
14
14
  self.email = 'ruby-talk@ruby-lang.org'
15
15
 
16
16
  # switch extension to .markdown for gihub formatting
17
17
  self.readme_file = 'README.md'
18
- self.history_file = 'HISTORY.md'
18
+ self.history_file = 'CHANGELOG.md'
19
19
 
20
20
  self.extra_deps = [
21
- ['logutils' ],
21
+ ['webclient', '>= 0.1.1']
22
22
  ]
23
23
 
24
24
  self.licenses = ['Public Domain']
25
25
 
26
26
  self.spec_extras = {
27
- required_ruby_version: '>= 1.9.2'
27
+ required_ruby_version: '>= 2.2.2'
28
28
  }
29
29
 
30
30
  end
@@ -1,17 +1,5 @@
1
- # encoding: utf-8
2
-
3
- require 'net/http'
4
- require "net/https"
5
- require 'uri'
6
-
7
- require 'pp'
8
- require 'json'
9
- require 'yaml'
10
- require 'time'
11
-
12
-
13
- # 3rd party gems/libs
14
- require 'logutils'
1
+ # 3rd party (our own)
2
+ require 'webclient'
15
3
 
16
4
  # our own code
17
5
  require 'hubba/version' # note: let version always go first
@@ -22,4 +10,4 @@ require 'hubba/stats'
22
10
 
23
11
 
24
12
  # say hello
25
- puts Hubba.banner if defined?($RUBYLIBS_DEBUG)
13
+ puts Hubba.banner if defined?($RUBYCOCO_DEBUG)
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Hubba
4
2
 
5
3
  class Cache ## lets you work with GitHub api "offline" using just a local cache of stored json
@@ -14,7 +12,7 @@ class Cache ## lets you work with GitHub api "offline" using just a local ca
14
12
  basename = request_uri_to_basename( request_uri )
15
13
  path = "#{@dir}/#{basename}.json"
16
14
  if File.exist?( path )
17
- text = File.read( path ) ## todo/fix: use File.read_utf8
15
+ text = File.open( path, 'r:utf-8') { |f| f.read }
18
16
  json = JSON.parse( text )
19
17
  json
20
18
  else
@@ -32,8 +30,8 @@ class Cache ## lets you work with GitHub api "offline" using just a local ca
32
30
  data = obj # assume Hash or Array -- todo: add support for String - why? why not??
33
31
  end
34
32
 
35
- File.open( path, 'w' ) do |f|
36
- f.write JSON.pretty_generate( data )
33
+ File.open( path, 'w:utf-8' ) do |f|
34
+ f.write( JSON.pretty_generate( data ))
37
35
  end
38
36
  end
39
37
 
@@ -42,6 +40,7 @@ class Cache ## lets you work with GitHub api "offline" using just a local ca
42
40
  ## 1) cut off leading /
43
41
  ## 2) convert / to ~
44
42
  ## 3) remove (optional) query string (for now) - why? why not?
43
+ ## e.g. /users/#{name}/orgs?per_page=100 or such
45
44
  ##
46
45
  ## e.g.
47
46
  ## '/users/geraldb' => 'users~geraldb',
@@ -1,53 +1,79 @@
1
- # encoding: utf-8
2
-
3
1
  module Hubba
4
2
 
5
3
 
6
4
  class Client
7
5
 
8
- def initialize( user: nil, password: nil )
9
- uri = URI.parse( "https://api.github.com" )
10
- @http = Net::HTTP.new(uri.host, uri.port)
11
- @http.use_ssl = true
12
- @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
6
+ BASE_URL = 'https://api.github.com'
7
+
8
+
9
+ def initialize( token: nil,
10
+ user: nil, password: nil )
11
+ ## add support for (personal access) token
12
+ @token = token
13
13
 
14
14
  ## add support for basic auth - defaults to no auth (nil/nil)
15
+ ## remove - deprecated (use token) - why? why not?
15
16
  @user = user ## use login like Oktokit - why? why not?
16
17
  @password = password
17
18
  end # method initialize
18
19
 
20
+
21
+
19
22
  def get( request_uri )
20
23
  puts "GET #{request_uri}"
21
24
 
22
- req = Net::HTTP::Get.new( request_uri )
23
- ## req = Net::HTTP::Get.new( "/users/geraldb" )
24
- ## req = Net::HTTP::Get.new( "/users/geraldb/repos" )
25
- req["User-Agent"] = "ruby/hubba" ## required by GitHub API
26
- req["Accept" ] = "application/vnd.github.v3+json" ## recommend by GitHub API
25
+ ## note: request_uri ALWAYS starts with leading /, thus use + for now!!!
26
+ # e.g. /users/geraldb
27
+ # /users/geraldb/repos
28
+ url = BASE_URL + request_uri
29
+
30
+ headers = {}
31
+ headers['User-Agent'] = 'ruby/hubba' ## required by GitHub API
32
+ headers['Accept'] = 'application/vnd.github.v3+json' ## recommend by GitHub API
27
33
 
34
+ auth = []
28
35
  ## check if credentials (user/password) present - if yes, use basic auth
29
- if @user && @password
36
+ if @token
37
+ puts " using (personal access) token - starting with: #{@token[0..6]}**********"
38
+ headers['Authorization'] = "token #{@token}"
39
+ ## token works like:
40
+ ## curl -H 'Authorization: token my_access_token' https://api.github.com/user/repos
41
+ elsif @user && @password
30
42
  puts " using basic auth - user: #{@user}, password: ***"
31
- req.basic_auth( @user, @password )
43
+ ## use credential auth "tuple" (that is, array with two string items) for now
44
+ ## or use Webclient::HttpBasicAuth or something - why? why not?
45
+ auth = [@user, @password]
46
+ # req.basic_auth( @user, @password )
47
+ else
48
+ puts " using no credentials (no token, no user/password)"
32
49
  end
33
50
 
34
- res = @http.request(req)
51
+ res = Webclient.get( url,
52
+ headers: headers,
53
+ auth: auth )
35
54
 
36
55
  # Get specific header
37
56
  # response["content-type"]
38
57
  # => "text/html; charset=UTF-8"
39
58
 
40
59
  # Iterate all response headers.
41
- res.each_header do |key, value|
42
- p "#{key} => #{value}"
60
+ puts "HTTP HEADERS:"
61
+ res.headers.each do |key, value|
62
+ puts " #{key}: >#{value}<"
43
63
  end
64
+ puts
65
+
44
66
  # => "location => http://www.google.com/"
45
67
  # => "content-type => text/html; charset=UTF-8"
46
68
  # ...
47
69
 
48
- json = JSON.parse( res.body )
49
- ## pp json
50
- json
70
+ if res.status.ok?
71
+ res.json
72
+ else
73
+ puts "!! HTTP ERROR: #{res.status.code} #{res.status.message}:"
74
+ pp res.raw
75
+ exit 1
76
+ end
51
77
  end # methdo get
52
78
 
53
79
  end ## class Client
@@ -1,13 +1,15 @@
1
- # encoding: utf-8
2
-
3
1
  module Hubba
4
2
 
5
3
  class Configuration
4
+ attr_accessor :token
5
+
6
6
  attr_accessor :user
7
7
  attr_accessor :password
8
8
 
9
9
  def initialize
10
10
  # try default setup via ENV variables
11
+ @token = ENV[ 'HUBBA_TOKEN' ]
12
+
11
13
  @user = ENV[ 'HUBBA_USER' ] ## use HUBBA_LOGIN - why? why not?
12
14
  @password = ENV[ 'HUBBA_PASSWORD' ]
13
15
  end
@@ -15,6 +17,8 @@ end
15
17
 
16
18
  ## lets you use
17
19
  ## Hubba.configure do |config|
20
+ ## config.token = 'secret'
21
+ ## #-or-
18
22
  ## config.user = 'testdada'
19
23
  ## config.password = 'secret'
20
24
  ## end
@@ -53,6 +57,7 @@ class Orgs < Resource
53
57
  ## sort by name
54
58
  data.map { |item| item['login'] }.sort
55
59
  end
60
+ alias_method :names, :logins ## add name alias - why? why not?
56
61
  end
57
62
 
58
63
 
@@ -61,8 +66,16 @@ class Github
61
66
 
62
67
  def initialize( cache_dir: './cache' )
63
68
  @cache = Cache.new( cache_dir )
64
- @client = Client.new( user: Hubba.configuration.user,
65
- password: Hubba.configuration.password )
69
+
70
+ @client = if Hubba.configuration.token
71
+ Client.new( token: Hubba.configuration.token )
72
+ elsif Hubba.configuration.user &&
73
+ Hubba.configuration.password
74
+ Client.new( user: Hubba.configuration.user,
75
+ password: Hubba.configuration.password )
76
+ else
77
+ Client.new
78
+ end
66
79
 
67
80
  @offline = false
68
81
  end
@@ -125,4 +138,9 @@ end
125
138
 
126
139
  end # class Github
127
140
 
141
+ ############
142
+ # add convenience alias for alternate spelling - why? why not?
143
+ GitHub = Github
144
+
145
+
128
146
  end # module Hubba
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Hubba
4
2
 
5
3
  ####
@@ -14,32 +12,206 @@ module Hubba
14
12
  @data['full_name'] = full_name # e.g. poole/hyde etc.
15
13
  end
16
14
 
17
- def full_name() @data['full_name']; end
15
+
16
+ def full_name() @full_name ||= @data['full_name']; end
17
+
18
+ ## note: return datetime objects (NOT strings); if not present/available return nil/null
19
+ def created_at() @created_at ||= @data['created_at'] ? DateTime.strptime( @data['created_at'], '%Y-%m-%dT%H:%M:%S') : nil; end
20
+ def updated_at() @updated_at ||= @data['updated_at'] ? DateTime.strptime( @data['updated_at'], '%Y-%m-%dT%H:%M:%S') : nil; end
21
+ def pushed_at() @pushed_at ||= @data['pushed_at'] ? DateTime.strptime( @data['pushed_at'], '%Y-%m-%dT%H:%M:%S') : nil; end
22
+
23
+ ## date (only) versions
24
+ def created() @created ||= @data['created_at'] ? Date.strptime( @data['created_at'], '%Y-%m-%d') : nil; end
25
+ def updated() @updated ||= @data['updated_at'] ? Date.strptime( @data['updated_at'], '%Y-%m-%d') : nil; end
26
+ def pushed() @pushed ||= @data['pushed_at'] ? Date.strptime( @data['pushed_at'], '%Y-%m-%d') : nil; end
27
+
18
28
 
19
29
 
30
+ def history() @history ||= @data['history'] ? build_history( @data['history'] ) : nil; end
31
+
20
32
  def size
21
33
  # size of repo in kb (as reported by github api)
22
- @data['size'] || 0 ## return 0 if not found - why? why not? (return nil - why? why not??)
34
+ @size ||= @data['size'] || 0 ## return 0 if not found - why? why not? (return nil - why? why not??)
23
35
  end
24
36
 
25
37
  def stars
26
38
  ## return last stargazers_count entry (as number; 0 if not found)
27
- t1 = 0
39
+ @stars ||= history ? history[0].stars : 0
40
+ end
41
+
42
+
43
+ def commits() @data['commits']; end
44
+
45
+ def last_commit() ## convenience shortcut; get first/last commit (use [0]) or nil
46
+ if @data['commits'] && @data['commits'][0]
47
+ @data['commits'][0]
48
+ else
49
+ nil
50
+ end
51
+ end
52
+
53
+ def committed() ## last commit date (from author NOT committer)
54
+ @committed ||= last_commit ? Date.strptime( last_commit['author']['date'], '%Y-%m-%d') : nil
55
+ end
56
+
57
+ def committed_at() ## last commit date (from author NOT committer)
58
+ @committed_at ||= last_commit ? DateTime.strptime( last_commit['author']['date'], '%Y-%m-%dT%H:%M:%S') : nil
59
+ end
60
+
61
+
62
+ def last_commit_message() ## convenience shortcut; last commit message
63
+ h = last_commit
64
+
65
+ committer_name = h['committer']['name']
66
+ author_name = h['author']['name']
67
+ message = h['message']
68
+
69
+ buf = ""
70
+ buf << message
71
+ buf << " by #{author_name}"
72
+
73
+ if committer_name != author_name
74
+ buf << " w/ #{committer_name}"
75
+ end
76
+ end # method commit_message
77
+
78
+
79
+
80
+ def reset_cache
81
+ ## reset (invalidate) cached values from data hash
82
+ ## use after reading or fetching
83
+ @full_name = nil
84
+ @created_at = @updated_at = @pushed_at = nil
85
+ @created = @updated = @pused = nil
86
+ @history = nil
87
+ @size = nil
88
+ @stars = nil
89
+
90
+ @committed_at = nil
91
+ @committed = nil
92
+ end
93
+
94
+
95
+ ########
96
+ ## build history items (structs)
97
+
98
+ class HistoryItem
99
+
100
+ attr_reader :date, :stars ## read-only attributes
101
+ attr_accessor :prev, :next ## read/write attributes (for double linked list/nodes/items)
102
+
103
+ def initialize( date:, stars: )
104
+ @date = date
105
+ @stars = stars
106
+ @next = nil
107
+ end
108
+
109
+ ## link items (append item at the end/tail)
110
+ def append( item )
111
+ @next = item
112
+ item.prev = self
113
+ end
114
+
115
+ def diff_days
116
+ if @next
117
+ ## note: use jd=julian days for calculation
118
+ @date.jd - @next.date.jd
119
+ else
120
+ nil ## last item (tail)
121
+ end
122
+ end
123
+
124
+ def diff_stars
125
+ if @next
126
+ @stars - @next.stars
127
+ else
128
+ nil ## last item (tail)
129
+ end
130
+ end
131
+ end ## class HistoryItem
132
+
133
+
134
+ def build_history( timeseries )
135
+ items = []
136
+
137
+ keys = timeseries.keys.sort.reverse ## newest (latest) items first
138
+ keys.each do |key|
139
+ h = timeseries[ key ]
140
+
141
+ item = HistoryItem.new(
142
+ date: Date.strptime( key, '%Y-%m-%d' ),
143
+ stars: h['stargazers_count'] || 0 )
144
+
145
+ ## link items
146
+ last_item = items[-1]
147
+ last_item.append( item ) if last_item ## if not nil? append (note first item has no prev item)
148
+
149
+ items << item
150
+ end
151
+
152
+ ## todo/check: return [] for empty items array (items.empty?) - why?? why not??
153
+ if items.empty?
154
+ nil
155
+ else
156
+ items
157
+ end
158
+ end ## method build_history
159
+
28
160
 
29
- history = @data['history']
30
- if history
31
- history_keys = @data['history'].keys.sort.reverse
32
- ## todo/fix: for now assumes one entry per week
33
- ## simple case [0] and [1] for a week later
34
- ## check actual date - why? why not?
35
- stats_t1 = history_keys[0] ? history[ history_keys[0] ] : nil
36
- if stats_t1
37
- t1 = stats_t1['stargazers_count'] || 0
38
- end
39
- end
40
- t1
41
- end # method stars
42
161
 
162
+ def calc_diff_stars( samples: 3, days: 30 )
163
+ ## samples: use n history item samples e.g. 3 samples
164
+ ## days e.g. 7 days (per week), 30 days (per month)
165
+
166
+ if history.nil?
167
+ nil ## todo/check: return 0.0 too - why? why not?
168
+ elsif history.size == 1
169
+ ## just one item; CANNOT calc diff; return zero
170
+ 0.0
171
+ else
172
+ idx = [history.size, samples].min ## calc last index
173
+ last = history[idx-1]
174
+ first = history[0]
175
+
176
+ diff_days = first.date.jd - last.date.jd
177
+ diff_stars = first.stars - last.stars
178
+
179
+ ## note: use factor 1000 for fixed integer division
180
+ ## converts to float at the end
181
+
182
+ ## todo: check for better way (convert to float upfront - why? why not?)
183
+
184
+ diff = (diff_stars * days * 1000) / diff_days
185
+ puts "diff=#{diff}:#{diff.class.name}" ## check if it's a float
186
+ (diff.to_f/1000.0)
187
+ end
188
+ end
189
+
190
+ def history_str
191
+ ## returns "pretty printed" history as string buffer
192
+ buf = ''
193
+ buf << "[#{history.size}]: "
194
+
195
+ history.each do |item|
196
+ buf << "#{item.stars}"
197
+
198
+ diff_stars = item.diff_stars
199
+ diff_days = item.diff_days
200
+ if diff_stars && diff_days ## note: last item has no diffs
201
+ if diff_stars > 0 || diff_stars < 0
202
+ if diff_stars > 0
203
+ buf << " (+#{diff_stars}"
204
+ else
205
+ buf << " (#{diff_stars}"
206
+ end
207
+ buf << " in #{diff_days}d) "
208
+ else ## diff_stars == 0
209
+ buf << " (#{diff_days}d) "
210
+ end
211
+ end
212
+ end
213
+ buf
214
+ end # method history_str
43
215
 
44
216
 
45
217
  ###############################
@@ -52,6 +224,9 @@ module Hubba
52
224
  ## e.g. 2015-05-11T20:21:43Z
53
225
  ## puts Time.iso8601( repo.data['created_at'] )
54
226
  @data['created_at'] = repo.data['created_at']
227
+ @data['updated_at'] = repo.data['updated_at']
228
+ @data['pushed_at'] = repo.data['pushed_at']
229
+
55
230
  @data['size'] = repo.data['size'] # size in kb (kilobyte)
56
231
 
57
232
  rec = {}
@@ -77,34 +252,47 @@ module Hubba
77
252
  'date' => commits.data[0]['commit']['committer']['date'],
78
253
  'name' => commits.data[0]['commit']['committer']['name']
79
254
  },
255
+ 'author' => {
256
+ 'date' => commits.data[0]['commit']['author']['date'],
257
+ 'name' => commits.data[0]['commit']['author']['name']
258
+ },
80
259
  'message' => commits.data[0]['commit']['message']
81
260
  }
82
261
 
83
262
  ## for now store only the latest commit (e.g. a single commit in an array)
84
- @data[ 'commits'] = [commit]
263
+ @data[ 'commits' ] = [commit]
85
264
 
86
265
  pp @data
266
+
267
+ reset_cache
268
+ self ## return self for (easy chaining)
87
269
  end
88
270
 
271
+
272
+
89
273
  def write( data_dir: './data' )
90
274
  basename = full_name.gsub( '/', '~' ) ## e.g. poole/hyde become poole~hyde
91
- puts "writing (saving) to #{basename}..."
275
+ puts "writing stats to #{basename}..."
92
276
  File.open( "#{data_dir}/#{basename}.json", 'w:utf-8' ) do |f|
93
277
  f.write JSON.pretty_generate( data )
94
278
  end
279
+ self ## return self for (easy chaining)
95
280
  end
96
281
 
97
- def read( data_dir: './data' ) ## note: use read instead of load (load is kind of keyword for loading code)
282
+
283
+ def read( data_dir: './data' )
98
284
  ## note: skip reading if file not present
99
285
  basename = full_name.gsub( '/', '~' ) ## e.g. poole/hyde become poole~hyde
100
286
  filename = "#{data_dir}/#{basename}.json"
101
287
  if File.exist?( filename )
102
- puts "reading (loading) from #{basename}..."
288
+ puts "reading stats from #{basename}..."
103
289
  json = File.open( filename, 'r:utf-8' ) { |file| file.read } ## todo/fix: use read_utf8
104
290
  @data = JSON.parse( json )
291
+ reset_cache
105
292
  else
106
- puts "skipping reading (loading) from #{basename} -- file not found"
293
+ puts "skipping reading stats from #{basename} -- file not found"
107
294
  end
295
+ self ## return self for (easy chaining)
108
296
  end
109
297
 
110
298
  end # class Stats
@@ -1,9 +1,7 @@
1
- # encoding: utf-8
2
-
3
1
  module Hubba
4
2
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
5
- MINOR = 2
6
- PATCH = 0
3
+ MINOR = 5
4
+ PATCH = 2
7
5
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
6
 
9
7
  def self.version
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  # minitest setup
4
2
  require 'minitest/autorun'
5
3
 
@@ -0,0 +1,25 @@
1
+ {
2
+ "full_name": "jekyll/minima",
3
+ "created_at": "2016-05-20T23:07:56Z",
4
+ "updated_at": "2018-02-11T16:13:33Z",
5
+ "pushed_at": "2018-02-07T22:14:11Z",
6
+ "size": 321,
7
+ "history": {
8
+ "2018-02-12": {
9
+ "stargazers_count": 717
10
+ }
11
+ },
12
+ "commits": [
13
+ {
14
+ "author": {
15
+ "name": "ashmaroli",
16
+ "date": "2018-02-21T19:35:59Z"
17
+ },
18
+ "committer": {
19
+ "name": "Frank Taillandier",
20
+ "date": "2018-02-21T19:35:59Z"
21
+ },
22
+ "message": "social icons should resolve baseurl properly (#201)"
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "full_name": "openblockchains/awesome-blockchains",
3
+ "created_at": "2017-09-13T22:33:56Z",
4
+ "size": 1620,
5
+ "history": {
6
+ "2017-12-10": {
7
+ "stargazers_count": 1084
8
+ },
9
+ "2018-01-28": {
10
+ "stargazers_count": 1411
11
+ },
12
+ "2018-02-08": {
13
+ "stargazers_count": 1526
14
+ }
15
+ },
16
+ "commits": [
17
+ {
18
+ "committer": {
19
+ "date": "2018-02-08T09:33:28Z",
20
+ "name": "Gerald Bauer"
21
+ },
22
+ "message": "Update README.md\n\nJust a little typo cryto -> crypto."
23
+ }
24
+ ],
25
+ "updated_at": "2018-02-08T19:26:35Z",
26
+ "pushed_at": "2018-02-08T09:33:29Z"
27
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "full_name": "opendatajson/factbook.json",
3
+ "created_at": "2014-07-12T12:43:52Z",
4
+ "history": {
5
+ "2017-02-11": {
6
+ "stargazers_count": 457
7
+ },
8
+ "2017-02-12": {
9
+ "stargazers_count": 457
10
+ },
11
+ "2017-06-18": {
12
+ "stargazers_count": 505
13
+ },
14
+ "2017-07-28": {
15
+ "stargazers_count": 512
16
+ },
17
+ "2017-12-10": {
18
+ "stargazers_count": 533
19
+ },
20
+ "2018-01-28": {
21
+ "stargazers_count": 536
22
+ },
23
+ "2018-02-08": {
24
+ "stargazers_count": 539
25
+ }
26
+ },
27
+ "commits": [
28
+ {
29
+ "committer": {
30
+ "date": "2017-03-29T17:23:29Z",
31
+ "name": "GitHub"
32
+ },
33
+ "message": "Update MONGO.md"
34
+ }
35
+ ],
36
+ "size": 7355,
37
+ "updated_at": "2018-02-01T12:35:19Z",
38
+ "pushed_at": "2017-03-29T17:23:30Z"
39
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "full_name": "poole/hyde",
3
+ "created_at": "2013-02-07T07:01:38Z",
4
+ "updated_at": "2018-02-12T05:44:07Z",
5
+ "pushed_at": "2018-01-14T02:41:16Z",
6
+ "size": 28428,
7
+ "history": {
8
+ "2018-02-12": {
9
+ "stargazers_count": 2125
10
+ }
11
+ },
12
+ "commits": [
13
+ {
14
+ "committer": {
15
+ "date": "2015-05-11T20:21:43Z",
16
+ "name": "Mark Otto"
17
+ },
18
+ "message": "Merge pull request #91 from pborreli/patch-1\n\nFixed typo"
19
+ }
20
+ ]
21
+ }
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  ###
4
2
  # to run use
5
3
  # ruby -I ./lib -I ./test test/test_cache.rb
@@ -32,15 +30,14 @@ class TestCache < MiniTest::Test
32
30
  def test_cache
33
31
  orgs = @cache.get( '/users/geraldb/orgs' )
34
32
  assert_equal 4, orgs.size
35
-
33
+
36
34
  repos = @cache.get( '/users/geraldb/repos' )
37
35
  assert_equal 3, repos.size
38
36
  end # method test_cache
39
37
 
40
38
  def test_cache_miss
41
- assert_equal nil, @cache.get( '/test/hello' )
42
- assert_equal nil, @cache.get( '/test/hola' )
39
+ assert_nil @cache.get( '/test/hello' )
40
+ assert_nil @cache.get( '/test/hola' )
43
41
  end # method test_cache_miss
44
42
 
45
43
  end # class TestCache
46
-
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  ###
4
2
  # to run use
5
3
  # ruby -I ./lib -I ./test test/test_config.rb
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  ###
4
2
  # to run use
5
3
  # ruby -I ./lib -I ./test test/test_stats.rb
@@ -10,31 +8,115 @@ require 'helper'
10
8
 
11
9
  class TestStats < MiniTest::Test
12
10
 
13
- def setup
14
- @gh = Hubba::Github.new( cache_dir: "#{Hubba.root}/test/cache" )
11
+
12
+ def test_jekyll_minima
13
+
14
+ stats = Hubba::Stats.new( 'jekyll/minima' )
15
+
16
+ assert_equal 0, stats.size
17
+ assert_equal 0, stats.stars
18
+ assert_nil stats.history
19
+
20
+ stats.read( data_dir: "#{Hubba.root}/test/stats" )
21
+
22
+ assert_equal 321, stats.size
23
+ assert_equal 717, stats.stars
24
+ assert_equal 717, stats.history[0].stars
25
+ assert_equal 1, stats.history.size
26
+
27
+ assert_equal Date.new(2018, 2, 12 ), stats.history[0].date
28
+
29
+ assert_nil stats.history[0].diff_days
30
+
31
+ assert_equal Date.new(2018, 2, 21 ), stats.committed
32
+ assert_equal Date.new(2016, 5, 20 ), stats.created
33
+ assert_equal Date.new(2018, 2, 11 ), stats.updated
34
+ assert_equal Date.new(2018, 2, 7 ), stats.pushed
35
+
36
+ assert_equal DateTime.new(2018, 2, 21, 19, 35, 59 ), stats.committed_at
37
+ assert_equal DateTime.new(2016, 5, 20, 23, 7, 56 ), stats.created_at
38
+ assert_equal DateTime.new(2018, 2, 11, 16, 13, 33 ), stats.updated_at
39
+ assert_equal DateTime.new(2018, 2, 7, 22, 14, 11 ), stats.pushed_at
40
+
41
+
42
+ pp stats.last_commit
43
+ pp stats.last_commit_message
44
+ pp stats.history_str ## pp history pretty printed to string (buffer)
15
45
  end
16
46
 
17
- def test_stats
18
- repos = [
19
- 'henrythemes/jekyll-starter-theme',
20
- 'poole/hyde',
21
- 'jekyll/minima'
22
- ]
23
47
 
24
- repos.each do |repo|
25
- stats = Hubba::Stats.new( repo )
26
- stats.read( data_dir: './tmp' )
27
48
 
28
- puts "stars before fetch: #{stats.stars}"
29
- puts "size before fetch: #{stats.size} kb"
30
- stats.fetch( @gh )
31
- puts "stars after fetch: #{stats.stars}"
32
- puts "size after fetch: #{stats.size} kb"
49
+ def test_awesome_blockchains
50
+
51
+ stats = Hubba::Stats.new( 'openblockchains/awesome-blockchains' )
52
+
53
+ assert_equal 0, stats.size
54
+ assert_equal 0, stats.stars
55
+ assert_nil stats.history
56
+
57
+ stats.read( data_dir: "#{Hubba.root}/test/stats" )
58
+
59
+ assert_equal 1620, stats.size
60
+ assert_equal 1526, stats.stars
61
+ assert_equal 1526, stats.history[0].stars
62
+ assert_equal 1411, stats.history[1].stars
63
+ assert_equal 1084, stats.history[2].stars
64
+ assert_equal 1084, stats.history[-1].stars
65
+ assert_equal 3, stats.history.size
66
+
67
+ assert_equal Date.new(2018, 2, 8 ), stats.history[0].date
68
+ assert_equal Date.new(2018, 1, 28 ), stats.history[1].date
69
+ assert_equal Date.new(2017, 12, 10 ), stats.history[2].date
70
+
71
+ assert_equal 11, stats.history[0].diff_days
72
+ assert_equal 49, stats.history[1].diff_days
73
+ assert_nil stats.history[2].diff_days
74
+
75
+ assert_equal 115, stats.history[0].diff_stars
76
+ assert_equal 327, stats.history[1].diff_stars
77
+ assert_nil stats.history[2].diff_stars
78
+
79
+ assert_equal 221.0, stats.calc_diff_stars ## defaults to samples: 3, days: 30
80
+ assert_equal 51.566, stats.calc_diff_stars( samples: 5, days: 7 )
81
+
82
+ pp stats.history_str ## pp history pretty printed to string (buffer)
83
+ end
84
+
85
+
86
+ def test_factbook_json
87
+
88
+ stats = Hubba::Stats.new( 'opendatajson/factbook.json' )
89
+
90
+ assert_equal 0, stats.size
91
+ assert_equal 0, stats.stars
92
+ assert_nil stats.history
93
+
94
+ stats.read( data_dir: "#{Hubba.root}/test/stats" )
95
+
96
+ assert_equal 7355, stats.size
97
+ assert_equal 539, stats.stars
98
+ assert_equal 539, stats.history[0].stars
99
+ assert_equal 536, stats.history[1].stars
100
+ assert_equal 533, stats.history[2].stars
101
+ assert_equal 457, stats.history[-1].stars
102
+ assert_equal 7, stats.history.size
103
+
104
+ assert_equal Date.new(2018, 2, 8 ), stats.history[0].date
105
+ assert_equal Date.new(2018, 1, 28 ), stats.history[1].date
106
+ assert_equal Date.new(2017, 12, 10 ), stats.history[2].date
107
+
108
+ assert_equal 11, stats.history[0].diff_days
109
+ assert_equal 49, stats.history[1].diff_days
110
+ assert_nil stats.history[-1].diff_days
111
+
112
+ assert_equal 3, stats.history[0].diff_stars
113
+ assert_equal 3, stats.history[1].diff_stars
114
+ assert_nil stats.history[-1].diff_stars
33
115
 
34
- stats.write( data_dir: './tmp' )
35
- end
116
+ assert_equal 3.0, stats.calc_diff_stars ## defaults to samples: 3, days: 30
117
+ assert_equal 1.012, stats.calc_diff_stars( samples: 5, days: 7 )
36
118
 
37
- assert true # for now everything ok if we get here
119
+ pp stats.history_str ## pp history pretty printed to string (buffer)
38
120
  end
39
121
 
40
122
  end # class TestStats
@@ -0,0 +1,41 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_stats_tmp.rb
4
+
5
+
6
+ require 'helper'
7
+
8
+
9
+ class TestStatsTmp < MiniTest::Test
10
+
11
+ def setup
12
+ @gh = Hubba::Github.new( cache_dir: "#{Hubba.root}/test/cache" )
13
+ end
14
+
15
+ def test_stats
16
+ repos = [
17
+ 'poole/hyde',
18
+ 'jekyll/minima'
19
+ ]
20
+
21
+ repos.each do |repo|
22
+ stats = Hubba::Stats.new( repo )
23
+ # stats.read( data_dir: './tmp' )
24
+ stats.read( data_dir: "#{Hubba.root}/test/stats" )
25
+
26
+ puts "stars before fetch: #{stats.stars}"
27
+ puts "size before fetch: #{stats.size} kb"
28
+
29
+ ## note/todo: enable for "live" online testing
30
+ ## stats.fetch( @gh )
31
+
32
+ puts "stars after fetch: #{stats.stars}"
33
+ puts "size after fetch: #{stats.size} kb"
34
+
35
+ stats.write( data_dir: './tmp' )
36
+ end
37
+
38
+ assert true # for now everything ok if we get here
39
+ end
40
+
41
+ end # class TestStatsTmp
metadata CHANGED
@@ -1,67 +1,73 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hubba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-12 00:00:00.000000000 Z
11
+ date: 2020-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: logutils
14
+ name: webclient
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.1.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.1.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rdoc
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '4.0'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '7'
34
37
  type: :development
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
- - - "~>"
41
+ - - ">="
39
42
  - !ruby/object:Gem::Version
40
43
  version: '4.0'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '7'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: hoe
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '3.15'
53
+ version: '3.22'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '3.15'
55
- description: hubba - (yet) another (lite) GitHub HTTP API client / library
60
+ version: '3.22'
61
+ description: hubba - (yet) another (lite) GitHub HTTP API client / library
56
62
  email: ruby-talk@ruby-lang.org
57
63
  executables: []
58
64
  extensions: []
59
65
  extra_rdoc_files:
60
- - HISTORY.md
66
+ - CHANGELOG.md
61
67
  - Manifest.txt
62
68
  - README.md
63
69
  files:
64
- - HISTORY.md
70
+ - CHANGELOG.md
65
71
  - Manifest.txt
66
72
  - README.md
67
73
  - Rakefile
@@ -74,10 +80,15 @@ files:
74
80
  - test/cache/users~geraldb~orgs.json
75
81
  - test/cache/users~geraldb~repos.json
76
82
  - test/helper.rb
83
+ - test/stats/jekyll~minima.json
84
+ - test/stats/openblockchains~awesome-blockchains.json
85
+ - test/stats/opendatajson~factbook.json.json
86
+ - test/stats/poole~hyde.json
77
87
  - test/test_cache.rb
78
88
  - test/test_config.rb
79
89
  - test/test_stats.rb
80
- homepage: https://github.com/rubylibs/hubba
90
+ - test/test_stats_tmp.rb
91
+ homepage: https://github.com/rubycoco/git
81
92
  licenses:
82
93
  - Public Domain
83
94
  metadata: {}
@@ -91,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
102
  requirements:
92
103
  - - ">="
93
104
  - !ruby/object:Gem::Version
94
- version: 1.9.2
105
+ version: 2.2.2
95
106
  required_rubygems_version: !ruby/object:Gem::Requirement
96
107
  requirements:
97
108
  - - ">="
@@ -99,8 +110,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
110
  version: '0'
100
111
  requirements: []
101
112
  rubyforge_project:
102
- rubygems_version: 2.6.7
113
+ rubygems_version: 2.5.2
103
114
  signing_key:
104
115
  specification_version: 4
105
- summary: hubba - (yet) another (lite) GitHub HTTP API client / library
116
+ summary: hubba - (yet) another (lite) GitHub HTTP API client / library
106
117
  test_files: []