hubba 0.6.2 → 0.7.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.
- checksums.yaml +4 -4
- data/Manifest.txt +1 -9
- data/README.md +12 -133
- data/lib/hubba.rb +7 -6
- data/lib/hubba/{hubba.rb → reposet.rb} +0 -14
- data/lib/hubba/stats.rb +15 -224
- data/lib/hubba/version.rb +2 -2
- metadata +3 -11
- data/lib/hubba/folio.rb +0 -60
- data/lib/hubba/reports.rb +0 -249
- data/test/stats/jekyll~minima.json +0 -25
- data/test/stats/openblockchains~awesome-blockchains.json +0 -27
- data/test/stats/opendatajson~factbook.json.json +0 -39
- data/test/stats/poole~hyde.json +0 -21
- data/test/test_stats.rb +0 -125
- data/test/test_stats_tmp.rb +0 -44
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6dfdf158420e74f4a2810c18e46cab065aa2dcce
|
|
4
|
+
data.tar.gz: 51357a2974422d2e9c4c0bb7b961d08ee43297bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7388e0646b07392b35ad13ea738c440b49f37cca283b4abf380071069ce48ef22bbe2d9fe293e266056ee1c7c386c92547740bb84a74cf3c03651a1f48ac48b2
|
|
7
|
+
data.tar.gz: 4ffbc0a84814db71694e6f0d750c7269916ae30f46a64ca79679976de222e06cbb63918b73b47c679ef8b92fa4fc9abce86f2cc3128903c1e2c8da634cfd96e2
|
data/Manifest.txt
CHANGED
|
@@ -4,19 +4,11 @@ README.md
|
|
|
4
4
|
Rakefile
|
|
5
5
|
lib/hubba.rb
|
|
6
6
|
lib/hubba/config.rb
|
|
7
|
-
lib/hubba/folio.rb
|
|
8
7
|
lib/hubba/github.rb
|
|
9
|
-
lib/hubba/
|
|
10
|
-
lib/hubba/reports.rb
|
|
8
|
+
lib/hubba/reposet.rb
|
|
11
9
|
lib/hubba/stats.rb
|
|
12
10
|
lib/hubba/update.rb
|
|
13
11
|
lib/hubba/update_traffic.rb
|
|
14
12
|
lib/hubba/version.rb
|
|
15
13
|
test/helper.rb
|
|
16
|
-
test/stats/jekyll~minima.json
|
|
17
|
-
test/stats/openblockchains~awesome-blockchains.json
|
|
18
|
-
test/stats/opendatajson~factbook.json.json
|
|
19
|
-
test/stats/poole~hyde.json
|
|
20
14
|
test/test_config.rb
|
|
21
|
-
test/test_stats.rb
|
|
22
|
-
test/test_stats_tmp.rb
|
data/README.md
CHANGED
|
@@ -87,6 +87,8 @@ account that are forks get auto-excluded.
|
|
|
87
87
|
### Step 2: Update repo statistics (daily / weekly / monthly)
|
|
88
88
|
|
|
89
89
|
|
|
90
|
+
#### Basics (commits, stars, forks, topics, etc.)
|
|
91
|
+
|
|
90
92
|
Use `update_stats` to
|
|
91
93
|
to get the latest commit, star count and more for all your repos
|
|
92
94
|
listed in `./repos.yml` via the GitHub API:
|
|
@@ -99,150 +101,27 @@ Note: By default the datafiles (one per repo)
|
|
|
99
101
|
get stored in the `./data` directory.
|
|
100
102
|
|
|
101
103
|
|
|
104
|
+
#### Traffic (page views, clones, referrers, etc.)
|
|
102
105
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
Hubba has four built-in reports (for now):
|
|
108
|
-
|
|
109
|
-
- `ReportSummary` - A-Z list of your repos by orgs with stars and size in kb
|
|
110
|
-
- `ReportStars` - your repos ranked by stars
|
|
111
|
-
- `ReportTimeline` - your repos in reverse chronological order by creation
|
|
112
|
-
- `ReportUpdates` - your repos in reverse chronological order by last commit
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
If you only generate a single report, use:
|
|
116
|
-
|
|
117
|
-
``` ruby
|
|
118
|
-
report = Hubba::ReportSummary.new( './repos.yml' )
|
|
119
|
-
report.save( './SUMMARY.md' )
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
If you generate more reports, (re)use the in-memory statistics cache / object:
|
|
106
|
+
Use `update_traffic` to
|
|
107
|
+
to get the latest traffic stats (page views, clones, referrers, etc.)
|
|
108
|
+
for all your repos listed in `./repos.yml` via the GitHub API.
|
|
124
109
|
|
|
125
110
|
``` ruby
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
report = Hubba::ReportSummary.new( stats )
|
|
129
|
-
report.save( './SUMMARY.md' )
|
|
130
|
-
|
|
131
|
-
report = Hubba::ReportStars.new( stats )
|
|
132
|
-
report.save( './STARS.md' )
|
|
133
|
-
|
|
134
|
-
report = Hubba::ReportTimeline.new( stats )
|
|
135
|
-
report.save( './TIMELINE.md' )
|
|
136
|
-
|
|
137
|
-
report = Hubba::ReportUpdates.new( stats )
|
|
138
|
-
report.save( './UPDATES.md' )
|
|
111
|
+
Hubba.update_traffic( './repos.yml' )
|
|
139
112
|
```
|
|
140
113
|
|
|
114
|
+
Note: Access to traffic statistics via the GitHub API
|
|
115
|
+
requires push access for your GitHub (personal access) token.
|
|
141
116
|
|
|
142
|
-
### Report Examples
|
|
143
|
-
|
|
144
|
-
#### Report Example - Summary
|
|
145
|
-
|
|
146
|
-
A-Z list of your repos by orgs with stars and size in kb.
|
|
147
|
-
Results in:
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
> 593 repos @ 83 orgs
|
|
152
|
-
>
|
|
153
|
-
> ### geraldb _(11)_
|
|
154
|
-
>
|
|
155
|
-
> **austria** ★1 (552 kb) · **catalog** ★3 (156 kb) · **chelitas** ★1 (168 kb) · **geraldb.github.io** ★1 (520 kb) · **logos** ★1 (363 kb) · **sandbox** ★2 (529 kb) · **talks** ★200 (16203 kb) · **web-proxy-win** ★8 (152 kb) · **webcomponents** ★1 (164 kb) · **webpub-reader** ★3 (11 kb) · **wine.db.tools** ★1 (252 kb)
|
|
156
|
-
>
|
|
157
|
-
> ...
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
(Live Example - [`SUMMARY.md`](https://github.com/yorobot/backup/blob/master/SUMMARY.md))
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
#### Report Example - Stars
|
|
165
|
-
|
|
166
|
-
Your repos ranked by stars. Results in:
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
> 593 repos @ 83 orgs
|
|
171
|
-
>
|
|
172
|
-
> 1. ★2936 **openblockchains/awesome-blockchains** (2514 kb)
|
|
173
|
-
> 2. ★851 **planetjekyll/awesome-jekyll-plugins** (148 kb)
|
|
174
|
-
> 3. ★604 **factbook/factbook.json** (7355 kb)
|
|
175
|
-
> 4. ★593 **openfootball/football.json** (2135 kb)
|
|
176
|
-
> 5. ★570 **openmundi/world.db** (1088 kb)
|
|
177
|
-
> 6. ★552 **openblockchains/programming-blockchains** (552 kb)
|
|
178
|
-
> 7. ★547 **mundimark/awesome-markdown** (83 kb)
|
|
179
|
-
> 8. ★532 **planetjekyll/awesome-jekyll** (110 kb)
|
|
180
|
-
> 9. ★489 **cryptocopycats/awesome-cryptokitties** (4154 kb)
|
|
181
|
-
> 10. ★445 **openfootball/world-cup** (638 kb)
|
|
182
|
-
>
|
|
183
|
-
> ...
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
(Live Example: [`STARS.md`](https://github.com/yorobot/backup/blob/master/STARS.md))
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
#### Report Example - Timeline
|
|
191
|
-
|
|
192
|
-
Your repos in reverse chronological order by creation.
|
|
193
|
-
Results in:
|
|
194
|
-
|
|
195
|
-
---
|
|
196
|
-
|
|
197
|
-
> 593 repos @ 83 orgs
|
|
198
|
-
>
|
|
199
|
-
> ## 2020
|
|
200
|
-
>
|
|
201
|
-
> ### 9
|
|
202
|
-
>
|
|
203
|
-
> - 2020-09-18 ★1 **yorobot/workflow** (83 kb)
|
|
204
|
-
>
|
|
205
|
-
> ### 6
|
|
206
|
-
>
|
|
207
|
-
> - 2020-06-27 ★2 **yorobot/sport.db.more** (80 kb)
|
|
208
|
-
> - 2020-06-24 ★1 **yorobot/stage** (554 kb)
|
|
209
|
-
> - 2020-06-11 ★1 **yorobot/cache.csv** (336 kb)
|
|
210
|
-
>
|
|
211
|
-
> ...
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
(Live Example: [`TIMELINE.md`](https://github.com/yorobot/backup/blob/master/TIMELINE.md))
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
#### Report Example - Updates
|
|
220
117
|
|
|
221
|
-
Your repos in reverse chronological order by last commit. Results in:
|
|
222
118
|
|
|
223
|
-
---
|
|
224
119
|
|
|
225
|
-
|
|
226
|
-
>
|
|
227
|
-
> committed / pushed / updated / created
|
|
228
|
-
>
|
|
229
|
-
> - (1d) **yorobot/backup** ★4 - 2020-10-08 (=/=) / 2020-10-08 (=) / 2020-10-08 / 2015-04-04 - ‹› (1595 kb)
|
|
230
|
-
> - (1d) **yorobot/logs** ★1 - 2020-10-08 (=/=) / 2020-10-08 (=) / 2020-10-08 / 2016-09-13 - ‹› (172 kb)
|
|
231
|
-
> - (1d) **rubycoco/git** ★9 - 2020-10-08 (=/=) / 2020-10-08 (=) / 2020-10-08 / 2015-11-16 - ‹› (88 kb)
|
|
232
|
-
> - (1d) **openfootball/football.json** ★593 - 2020-10-08 (=/=) / 2020-10-08 (=) / 2020-10-08 / 2015-09-17 - ‹› (2135 kb)
|
|
233
|
-
> - (2d) **yorobot/workflow** ★1 - 2020-10-07 (=/=) / 2020-10-07 (=) / 2020-10-07 / 2020-09-18 - ‹› (83 kb)
|
|
234
|
-
> - (2d) **rubycoco/webclient** ★5 - 2020-10-07 (=/=) / 2020-10-07 (=) / 2020-10-07 / 2012-06-02 - ‹› (39 kb)
|
|
235
|
-
> - (3d) **footballcsv/belgium** ★1 - 2020-10-06 (=/=) / 2020-10-06 (=) / 2020-10-06 / 2014-07-25 - ‹› (314 kb)
|
|
236
|
-
> - (3d) **footballcsv/england** ★105 - 2020-10-06 (=/=) / 2020-10-06 (=) / 2020-10-06 / 2014-07-23 - ‹› (8666 kb)
|
|
237
|
-
> - (3d) **footballcsv/austria** ★1 - 2020-10-06 (=/=) / 2020-10-06 (=) / 2020-10-06 / 2018-07-16 - ‹› (91 kb)
|
|
238
|
-
> - (3d) **footballcsv/espana** ★15 - 2020-10-06 (=/=) / 2020-10-06 (=) / 2020-10-06 / 2014-07-23 - ‹› (1107 kb)
|
|
239
|
-
> - (3d) **footballcsv/deutschland** ★5 - 2020-10-06 (=/=) / 2020-10-06 (=) / 2020-10-06 / 2014-07-25 - ‹› (1343 kb)
|
|
240
|
-
>
|
|
241
|
-
> ...
|
|
120
|
+
### Step 3: Generate some statistics / analytics reports
|
|
242
121
|
|
|
243
|
-
---
|
|
244
122
|
|
|
245
|
-
|
|
123
|
+
See the [hubba-reports gem](https://github.com/rubycoco/git/tree/master/hubba-reports) on how to use pre-built/pre-packaged ready-to-use
|
|
124
|
+
github statistics / analytics reports.
|
|
246
125
|
|
|
247
126
|
|
|
248
127
|
|
data/lib/hubba.rb
CHANGED
|
@@ -23,15 +23,14 @@ end
|
|
|
23
23
|
require 'hubba/version' # note: let version always go first
|
|
24
24
|
require 'hubba/config'
|
|
25
25
|
require 'hubba/github'
|
|
26
|
-
require 'hubba/
|
|
26
|
+
require 'hubba/reposet'
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
require 'hubba/
|
|
30
|
-
require 'hubba/hubba'
|
|
28
|
+
### update stats (github data) machinery
|
|
29
|
+
require 'hubba/stats'
|
|
31
30
|
require 'hubba/update'
|
|
32
31
|
require 'hubba/update_traffic'
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
|
|
35
34
|
|
|
36
35
|
|
|
37
36
|
############
|
|
@@ -42,4 +41,6 @@ end
|
|
|
42
41
|
|
|
43
42
|
|
|
44
43
|
# say hello
|
|
45
|
-
puts Hubba.banner
|
|
44
|
+
puts Hubba.banner
|
|
45
|
+
|
|
46
|
+
|
|
@@ -80,18 +80,4 @@ def self.reposet( *users, orgs: true,
|
|
|
80
80
|
h
|
|
81
81
|
end ## method reposet
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
def self.stats( hash_or_path='./repos.yml' ) ## use read_stats or such - why? why not?
|
|
85
|
-
h = if hash_or_path.is_a?( String ) ## assume it is a file path!!!
|
|
86
|
-
path = hash_or_path
|
|
87
|
-
YAML.load_file( path )
|
|
88
|
-
else
|
|
89
|
-
hash_or_path # assume its a hash / reposet already!!!
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
Folio.new( h ) ## wrap in "easy-access" facade / wrapper
|
|
93
|
-
end ## method stats
|
|
94
|
-
|
|
95
|
-
|
|
96
83
|
end # module Hubba
|
|
97
|
-
|
data/lib/hubba/stats.rb
CHANGED
|
@@ -5,227 +5,16 @@ module Hubba
|
|
|
5
5
|
|
|
6
6
|
class Stats ## todo/check: rename to GithubRepoStats or RepoStats - why? why not?
|
|
7
7
|
|
|
8
|
-
attr_reader :data
|
|
9
|
-
|
|
10
8
|
def initialize( full_name )
|
|
11
9
|
@data = {}
|
|
12
10
|
@data['full_name'] = full_name # e.g. poole/hyde etc.
|
|
13
11
|
|
|
14
|
-
@cache = {}
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def full_name() @data['full_name']; end
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
## note: return datetime objects (NOT strings); if not present/available return nil/null
|
|
22
|
-
def created_at() @cache['created_at'] ||= parse_datetime( @data['created_at'] ); end
|
|
23
|
-
def updated_at() @cache['updated_at'] ||= parse_datetime( @data['updated_at'] ); end
|
|
24
|
-
def pushed_at() @cache['pushed_at'] ||= parse_datetime( @data['pushed_at'] ); end
|
|
25
|
-
|
|
26
|
-
## date (only) versions
|
|
27
|
-
def created() @cache['created'] ||= parse_date( @data['created_at'] ); end
|
|
28
|
-
def updated() @cache['updated'] ||= parse_date( @data['updated_at'] ); end
|
|
29
|
-
def pushed() @cache['pushed'] ||= parse_date( @data['pushed_at'] ); end
|
|
30
|
-
|
|
31
|
-
def size
|
|
32
|
-
# size of repo in kb (as reported by github api)
|
|
33
|
-
@data['size'] || 0 ## return 0 if not found - why? why not? (return nil - why? why not??)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def history
|
|
38
|
-
@cache['history'] ||= begin
|
|
39
|
-
if @data['history']
|
|
40
|
-
build_history( @data['history'] )
|
|
41
|
-
else
|
|
42
|
-
nil
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def stars
|
|
49
|
-
## return last stargazers_count entry (as number; 0 if not found)
|
|
50
|
-
@cache['stars'] ||= history ? history[0].stars : 0
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def commits() @data['commits']; end
|
|
55
|
-
|
|
56
|
-
def last_commit ## convenience shortcut; get first/last commit (use [0]) or nil
|
|
57
|
-
if @data['commits'] && @data['commits'][0]
|
|
58
|
-
@data['commits'][0]
|
|
59
|
-
else
|
|
60
|
-
nil
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def committed ## last commit date (from author NOT committer)
|
|
66
|
-
@cache['committed'] ||= parse_date( last_commit_author_date )
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def committed_at() ## last commit date (from author NOT committer)
|
|
70
|
-
@cache['committed_at'] ||= parse_datetime( last_commit_author_date )
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def last_commit_author_date
|
|
74
|
-
h = last_commit
|
|
75
|
-
h ? h['author']['date'] : nil
|
|
12
|
+
@cache = {} ## keep a lookup cache - why? why not?
|
|
76
13
|
end
|
|
77
14
|
|
|
78
15
|
|
|
79
|
-
def last_commit_message ## convenience shortcut; last commit message
|
|
80
|
-
h = last_commit
|
|
81
|
-
|
|
82
|
-
committer_name = h['committer']['name']
|
|
83
|
-
author_name = h['author']['name']
|
|
84
|
-
message = h['message']
|
|
85
|
-
|
|
86
|
-
buf = ""
|
|
87
|
-
buf << message
|
|
88
|
-
buf << " by #{author_name}"
|
|
89
|
-
|
|
90
|
-
if committer_name != author_name
|
|
91
|
-
buf << " w/ #{committer_name}"
|
|
92
|
-
end
|
|
93
|
-
end # method commit_message
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
###
|
|
98
|
-
# helpers
|
|
99
|
-
def parse_datetime( str ) str ? DateTime.strptime( str, '%Y-%m-%dT%H:%M:%S') : nil; end
|
|
100
|
-
def parse_date( str ) str ? Date.strptime( str, '%Y-%m-%d') : nil; end
|
|
101
|
-
|
|
102
|
-
########
|
|
103
|
-
## build history items (structs)
|
|
104
|
-
|
|
105
|
-
class HistoryItem
|
|
106
|
-
|
|
107
|
-
attr_reader :date, :stars ## read-only attributes
|
|
108
|
-
attr_accessor :prev, :next ## read/write attributes (for double linked list/nodes/items)
|
|
109
|
-
|
|
110
|
-
def initialize( date:, stars: )
|
|
111
|
-
@date = date
|
|
112
|
-
@stars = stars
|
|
113
|
-
@next = nil
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
## link items (append item at the end/tail)
|
|
117
|
-
def append( item )
|
|
118
|
-
@next = item
|
|
119
|
-
item.prev = self
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def diff_days
|
|
123
|
-
if @next
|
|
124
|
-
## note: use jd=julian days for calculation
|
|
125
|
-
@date.jd - @next.date.jd
|
|
126
|
-
else
|
|
127
|
-
nil ## last item (tail)
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def diff_stars
|
|
132
|
-
if @next
|
|
133
|
-
@stars - @next.stars
|
|
134
|
-
else
|
|
135
|
-
nil ## last item (tail)
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
end ## class HistoryItem
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def build_history( timeseries )
|
|
142
|
-
items = []
|
|
143
|
-
|
|
144
|
-
keys = timeseries.keys.sort.reverse ## newest (latest) items first
|
|
145
|
-
keys.each do |key|
|
|
146
|
-
h = timeseries[ key ]
|
|
147
|
-
|
|
148
|
-
item = HistoryItem.new(
|
|
149
|
-
date: Date.strptime( key, '%Y-%m-%d' ),
|
|
150
|
-
stars: h['stargazers_count'] || 0 )
|
|
151
|
-
|
|
152
|
-
## link items
|
|
153
|
-
last_item = items[-1]
|
|
154
|
-
last_item.append( item ) if last_item ## if not nil? append (note first item has no prev item)
|
|
155
|
-
|
|
156
|
-
items << item
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
## todo/check: return [] for empty items array (items.empty?) - why?? why not??
|
|
160
|
-
if items.empty?
|
|
161
|
-
nil
|
|
162
|
-
else
|
|
163
|
-
items
|
|
164
|
-
end
|
|
165
|
-
end ## method build_history
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def calc_diff_stars( samples: 3, days: 30 )
|
|
170
|
-
## samples: use n history item samples e.g. 3 samples
|
|
171
|
-
## days e.g. 7 days (per week), 30 days (per month)
|
|
172
|
-
|
|
173
|
-
if history.nil?
|
|
174
|
-
nil ## todo/check: return 0.0 too - why? why not?
|
|
175
|
-
elsif history.size == 1
|
|
176
|
-
## just one item; CANNOT calc diff; return zero
|
|
177
|
-
0.0
|
|
178
|
-
else
|
|
179
|
-
idx = [history.size, samples].min ## calc last index
|
|
180
|
-
last = history[idx-1]
|
|
181
|
-
first = history[0]
|
|
182
|
-
|
|
183
|
-
diff_days = first.date.jd - last.date.jd
|
|
184
|
-
diff_stars = first.stars - last.stars
|
|
185
|
-
|
|
186
|
-
## note: use factor 1000 for fixed integer division
|
|
187
|
-
## converts to float at the end
|
|
188
|
-
|
|
189
|
-
## todo: check for better way (convert to float upfront - why? why not?)
|
|
190
|
-
|
|
191
|
-
diff = (diff_stars * days * 1000) / diff_days
|
|
192
|
-
## puts "diff=#{diff}:#{diff.class.name}" ## check if it's a float
|
|
193
|
-
(diff.to_f/1000.0)
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
def history_str ## todo/check: rename/change to format_history or fmt_history - why? why not?
|
|
199
|
-
## returns "pretty printed" history as string buffer
|
|
200
|
-
buf = ''
|
|
201
|
-
buf << "[#{history.size}]: "
|
|
202
|
-
|
|
203
|
-
history.each do |item|
|
|
204
|
-
buf << "#{item.stars}"
|
|
205
|
-
|
|
206
|
-
diff_stars = item.diff_stars
|
|
207
|
-
diff_days = item.diff_days
|
|
208
|
-
if diff_stars && diff_days ## note: last item has no diffs
|
|
209
|
-
if diff_stars > 0 || diff_stars < 0
|
|
210
|
-
if diff_stars > 0
|
|
211
|
-
buf << " (+#{diff_stars}"
|
|
212
|
-
else
|
|
213
|
-
buf << " (#{diff_stars}"
|
|
214
|
-
end
|
|
215
|
-
buf << " in #{diff_days}d) "
|
|
216
|
-
else ## diff_stars == 0
|
|
217
|
-
buf << " (#{diff_days}d) "
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
buf
|
|
222
|
-
end # method history_str
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
16
|
##################
|
|
227
17
|
## update
|
|
228
|
-
|
|
229
18
|
def update_traffic( clones: nil,
|
|
230
19
|
views: nil,
|
|
231
20
|
paths: nil,
|
|
@@ -415,25 +204,28 @@ end # method update_traffic
|
|
|
415
204
|
|
|
416
205
|
########################################
|
|
417
206
|
## read / write methods / helpers
|
|
418
|
-
|
|
419
207
|
def write
|
|
420
|
-
basename = full_name.gsub( '/', '~' ) ## e.g. poole/hyde become poole~hyde
|
|
421
|
-
|
|
208
|
+
basename = @data['full_name'].gsub( '/', '~' ) ## e.g. poole/hyde become poole~hyde
|
|
209
|
+
letter = basename[0] ## use first letter as index dir e.g. p/poole~hyde
|
|
210
|
+
data_dir = "#{Hubba.config.data_dir}/#{letter}"
|
|
211
|
+
path = "#{data_dir}/#{basename}.json"
|
|
212
|
+
|
|
422
213
|
puts " writing stats to #{basename} (#{data_dir})..."
|
|
423
214
|
|
|
424
|
-
##
|
|
425
|
-
File.open(
|
|
426
|
-
f.write JSON.pretty_generate( data )
|
|
215
|
+
FileUtils.mkdir_p( File.dirname( path )) ## make sure path exists
|
|
216
|
+
File.open( path, 'w:utf-8' ) do |f|
|
|
217
|
+
f.write( JSON.pretty_generate( @data ))
|
|
427
218
|
end
|
|
428
219
|
self ## return self for (easy chaining)
|
|
429
|
-
end
|
|
220
|
+
end # method write
|
|
430
221
|
|
|
431
222
|
|
|
432
223
|
def read
|
|
433
224
|
## note: skip reading if file not present
|
|
434
|
-
basename = full_name.gsub( '/', '~' ) ## e.g. poole/hyde become poole~hyde
|
|
435
|
-
|
|
436
|
-
|
|
225
|
+
basename = @data['full_name'].gsub( '/', '~' ) ## e.g. poole/hyde become poole~hyde
|
|
226
|
+
letter = basename[0] ## use first letter as index dir e.g. p/poole~hyde
|
|
227
|
+
data_dir = "#{Hubba.config.data_dir}/#{letter}"
|
|
228
|
+
path = "#{data_dir}/#{basename}.json"
|
|
437
229
|
|
|
438
230
|
if File.exist?( path )
|
|
439
231
|
puts " reading stats from #{basename} (#{data_dir})..."
|
|
@@ -447,8 +239,7 @@ end # method update_traffic
|
|
|
447
239
|
puts "!! WARN: - skipping reading stats from #{basename} -- file not found"
|
|
448
240
|
end
|
|
449
241
|
self ## return self for (easy chaining)
|
|
450
|
-
end
|
|
451
|
-
|
|
242
|
+
end # method read
|
|
452
243
|
end # class Stats
|
|
453
244
|
|
|
454
245
|
|
data/lib/hubba/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hubba
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gerald Bauer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-10-
|
|
11
|
+
date: 2020-10-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: webclient
|
|
@@ -73,22 +73,14 @@ files:
|
|
|
73
73
|
- Rakefile
|
|
74
74
|
- lib/hubba.rb
|
|
75
75
|
- lib/hubba/config.rb
|
|
76
|
-
- lib/hubba/folio.rb
|
|
77
76
|
- lib/hubba/github.rb
|
|
78
|
-
- lib/hubba/
|
|
79
|
-
- lib/hubba/reports.rb
|
|
77
|
+
- lib/hubba/reposet.rb
|
|
80
78
|
- lib/hubba/stats.rb
|
|
81
79
|
- lib/hubba/update.rb
|
|
82
80
|
- lib/hubba/update_traffic.rb
|
|
83
81
|
- lib/hubba/version.rb
|
|
84
82
|
- test/helper.rb
|
|
85
|
-
- test/stats/jekyll~minima.json
|
|
86
|
-
- test/stats/openblockchains~awesome-blockchains.json
|
|
87
|
-
- test/stats/opendatajson~factbook.json.json
|
|
88
|
-
- test/stats/poole~hyde.json
|
|
89
83
|
- test/test_config.rb
|
|
90
|
-
- test/test_stats.rb
|
|
91
|
-
- test/test_stats_tmp.rb
|
|
92
84
|
homepage: https://github.com/rubycoco/git
|
|
93
85
|
licenses:
|
|
94
86
|
- Public Domain
|
data/lib/hubba/folio.rb
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
module Hubba
|
|
2
|
-
|
|
3
|
-
class Folio # todo/check: use a different name e.g (Port)Folio, Cache, Summary, (Data)Base, Census, Catalog, Collection, Index, Register or such???
|
|
4
|
-
class Repo ## (nested) class
|
|
5
|
-
|
|
6
|
-
attr_reader :owner,
|
|
7
|
-
:name
|
|
8
|
-
|
|
9
|
-
def initialize( owner, name )
|
|
10
|
-
@owner = owner ## rename to login, username - why? why not?
|
|
11
|
-
@name = name ## rename to reponame ??
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def full_name() "#{owner}/#{name}"; end
|
|
15
|
-
|
|
16
|
-
def stats
|
|
17
|
-
## note: load stats on demand only (first access) for now - why? why not?
|
|
18
|
-
@stats ||= begin
|
|
19
|
-
stats = Stats.new( full_name )
|
|
20
|
-
stats.read
|
|
21
|
-
stats
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def diff
|
|
26
|
-
@diff ||= stats.calc_diff_stars( samples: 3, days: 30 )
|
|
27
|
-
end
|
|
28
|
-
end # (nested) class Repo
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
attr_reader :orgs, :repos
|
|
32
|
-
|
|
33
|
-
def initialize( h )
|
|
34
|
-
@orgs = [] # orgs and users -todo/check: use better name - logins or owners? why? why not?
|
|
35
|
-
@repos = []
|
|
36
|
-
add( h )
|
|
37
|
-
|
|
38
|
-
puts "#{@repos.size} repos @ #{@orgs.size} orgs"
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
#############
|
|
42
|
-
## private helpes
|
|
43
|
-
def add( h ) ## add repos.yml set
|
|
44
|
-
h.each do |org_with_counter, names|
|
|
45
|
-
## remove optional number from key e.g.
|
|
46
|
-
## mrhydescripts (3) => mrhydescripts
|
|
47
|
-
## footballjs (4) => footballjs
|
|
48
|
-
## etc.
|
|
49
|
-
org = org_with_counter.sub( /\([0-9]+\)/, '' ).strip
|
|
50
|
-
repos = []
|
|
51
|
-
names.each do |name|
|
|
52
|
-
repo = Repo.new( org, name )
|
|
53
|
-
repos << repo
|
|
54
|
-
end
|
|
55
|
-
@orgs << [org, repos]
|
|
56
|
-
@repos += repos
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end # class Folio
|
|
60
|
-
end # module Hubba
|
data/lib/hubba/reports.rb
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
module Hubba
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class Report
|
|
5
|
-
def initialize( stats_or_hash_or_path=Hubba.stats )
|
|
6
|
-
## puts "[debug] Report#initialize:"
|
|
7
|
-
## pp stats_or_hash_or_path if stats_or_hash_or_path.is_a?( String )
|
|
8
|
-
|
|
9
|
-
@stats = if stats_or_hash_or_path.is_a?( String ) ||
|
|
10
|
-
stats_or_hash_or_path.is_a?( Hash )
|
|
11
|
-
hash_or_path = stats_or_hash_or_path
|
|
12
|
-
Hubba.stats( hash_or_path )
|
|
13
|
-
else
|
|
14
|
-
stats_or_hash_or_path ## assume Summary/Stats - todo/fix: double check!!!
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def save( path )
|
|
19
|
-
buf = build
|
|
20
|
-
puts "writing report >#{path}< ..."
|
|
21
|
-
File.open( path, "w:utf-8" ) do |f|
|
|
22
|
-
f.write( buf )
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end ## class Report
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class ReportSummary < Report
|
|
30
|
-
|
|
31
|
-
def build
|
|
32
|
-
## create a (summary report)
|
|
33
|
-
##
|
|
34
|
-
## add stars, last_updates, etc.
|
|
35
|
-
## org description etc??
|
|
36
|
-
|
|
37
|
-
## note: orgs is orgs+users e.g. geraldb, yorobot etc
|
|
38
|
-
buf = String.new('')
|
|
39
|
-
buf << "# #{@stats.repos.size} repos @ #{@stats.orgs.size} orgs\n"
|
|
40
|
-
buf << "\n"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@stats.orgs.each do |org|
|
|
44
|
-
name = org[0]
|
|
45
|
-
repos = org[1]
|
|
46
|
-
buf << "### #{name} _(#{repos.size})_\n"
|
|
47
|
-
buf << "\n"
|
|
48
|
-
|
|
49
|
-
### add stats for repos
|
|
50
|
-
entries = []
|
|
51
|
-
repos.each do |repo|
|
|
52
|
-
entries << "**#{repo.name}** ★#{repo.stats.stars} (#{repo.stats.size} kb)"
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
buf << entries.join( ' · ' ) ## use interpunct? - was: • (bullet)
|
|
56
|
-
buf << "\n"
|
|
57
|
-
buf << "\n"
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
buf
|
|
61
|
-
end # method build
|
|
62
|
-
end # class ReportSummary
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
class ReportStars < Report
|
|
67
|
-
|
|
68
|
-
def build
|
|
69
|
-
|
|
70
|
-
## add stars, last_updates, etc.
|
|
71
|
-
## org description etc??
|
|
72
|
-
|
|
73
|
-
## note: orgs is orgs+users e.g. geraldb, yorobot etc
|
|
74
|
-
buf = String.new('')
|
|
75
|
-
buf << "# #{@stats.repos.size} repos @ #{@stats.orgs.size} orgs\n"
|
|
76
|
-
buf << "\n"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
repos = @stats.repos.sort do |l,r|
|
|
80
|
-
## note: use reverse sort (right,left) - e.g. most stars first
|
|
81
|
-
r.stats.stars <=> l.stats.stars
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
## pp repos
|
|
85
|
-
|
|
86
|
-
repos.each_with_index do |repo,i|
|
|
87
|
-
buf << "#{i+1}. ★#{repo.stats.stars} **#{repo.full_name}** (#{repo.stats.size} kb)\n"
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
buf
|
|
91
|
-
end # method build
|
|
92
|
-
end # class ReportStars
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
class ReportTimeline < Report
|
|
97
|
-
|
|
98
|
-
def build
|
|
99
|
-
## create a (timeline report)
|
|
100
|
-
|
|
101
|
-
## note: orgs is orgs+users e.g. geraldb, yorobot etc
|
|
102
|
-
buf = String.new('')
|
|
103
|
-
buf << "# #{@stats.repos.size} repos @ #{@stats.orgs.size} orgs\n"
|
|
104
|
-
buf << "\n"
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
repos = @stats.repos.sort do |l,r|
|
|
108
|
-
## note: use reverse sort (right,left) - e.g. most stars first
|
|
109
|
-
## r[:stars] <=> l[:stars]
|
|
110
|
-
|
|
111
|
-
## sort by created_at (use julian days)
|
|
112
|
-
r.stats.created.jd <=> l.stats.created.jd
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
## pp repos
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
last_year = -1
|
|
120
|
-
last_month = -1
|
|
121
|
-
|
|
122
|
-
repos.each_with_index do |repo,i|
|
|
123
|
-
year = repo.stats.created.year
|
|
124
|
-
month = repo.stats.created.month
|
|
125
|
-
|
|
126
|
-
if last_year != year
|
|
127
|
-
buf << "\n## #{year}\n\n"
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
if last_month != month
|
|
131
|
-
buf << "\n### #{month}\n\n"
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
last_year = year
|
|
135
|
-
last_month = month
|
|
136
|
-
|
|
137
|
-
buf << "- #{repo.stats.created_at.strftime('%Y-%m-%d')} ★#{repo.stats.stars} **#{repo.full_name}** (#{repo.stats.size} kb)\n"
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
buf
|
|
141
|
-
end # method build
|
|
142
|
-
end # class ReportTimeline
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
class ReportTrending < Report
|
|
147
|
-
|
|
148
|
-
def build
|
|
149
|
-
|
|
150
|
-
## note: orgs is orgs+users e.g. geraldb, yorobot etc
|
|
151
|
-
buf = String.new('')
|
|
152
|
-
buf << "# #{@stats.repos.size} repos @ #{@stats.orgs.size} orgs\n"
|
|
153
|
-
buf << "\n"
|
|
154
|
-
|
|
155
|
-
###
|
|
156
|
-
## todo:
|
|
157
|
-
## use calc per month (days: 30)
|
|
158
|
-
## per week is too optimistic (e.g. less than one star/week e.g. 0.6 or something)
|
|
159
|
-
|
|
160
|
-
repos = @stats.repos.sort do |l,r|
|
|
161
|
-
## note: use reverse sort (right,left) - e.g. most stars first
|
|
162
|
-
## r[:stars] <=> l[:stars]
|
|
163
|
-
|
|
164
|
-
## sort by created_at (use julian days)
|
|
165
|
-
## r[:created_at].to_date.jd <=> l[:created_at].to_date.jd
|
|
166
|
-
|
|
167
|
-
res = r.diff <=> l.diff
|
|
168
|
-
res = r.stats.stars <=> l.stats.stars if res == 0
|
|
169
|
-
res = r.stats.created.jd <=> l.stats.created.jd if res == 0
|
|
170
|
-
res
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
## pp repos
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
repos.each_with_index do |repo,i|
|
|
178
|
-
if repo.diff == 0
|
|
179
|
-
buf << "- -/- "
|
|
180
|
-
else
|
|
181
|
-
buf << "- #{repo.diff}/month "
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
buf << " ★#{repo.stats.stars} **#{repo.full_name}** (#{repo.stats.size} kb) - "
|
|
185
|
-
buf << "#{repo.stats.history_str}\n"
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
buf
|
|
190
|
-
end # method build
|
|
191
|
-
end # class ReportTrending
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
class ReportUpdates < Report
|
|
196
|
-
|
|
197
|
-
def build
|
|
198
|
-
|
|
199
|
-
## note: orgs is orgs+users e.g. geraldb, yorobot etc
|
|
200
|
-
buf = String.new('')
|
|
201
|
-
buf << "# #{@stats.repos.size} repos @ #{@stats.orgs.size} orgs\n"
|
|
202
|
-
buf << "\n"
|
|
203
|
-
|
|
204
|
-
repos = @stats.repos.sort do |l,r|
|
|
205
|
-
r.stats.committed.jd <=> l.stats.committed.jd
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
## pp repos
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
buf << "committed / pushed / updated / created\n\n"
|
|
212
|
-
|
|
213
|
-
today = Date.today
|
|
214
|
-
|
|
215
|
-
repos.each_with_index do |repo,i|
|
|
216
|
-
|
|
217
|
-
days_ago = today.jd - repo.stats.committed.jd
|
|
218
|
-
|
|
219
|
-
diff1 = repo.stats.committed.jd - repo.stats.pushed.jd
|
|
220
|
-
diff2 = repo.stats.committed.jd - repo.stats.updated.jd
|
|
221
|
-
diff3 = repo.stats.pushed.jd - repo.stats.updated.jd
|
|
222
|
-
|
|
223
|
-
buf << "- (#{days_ago}d) **#{repo.full_name}** ★#{repo.stats.stars} - "
|
|
224
|
-
buf << "#{repo.stats.committed} "
|
|
225
|
-
buf << "("
|
|
226
|
-
buf << (diff1==0 ? '=' : "#{diff1}d")
|
|
227
|
-
buf << "/"
|
|
228
|
-
buf << (diff2==0 ? '=' : "#{diff2}d")
|
|
229
|
-
buf << ")"
|
|
230
|
-
buf << " / "
|
|
231
|
-
buf << "#{repo.stats.pushed} "
|
|
232
|
-
buf << "("
|
|
233
|
-
buf << (diff3==0 ? '=' : "#{diff3}d")
|
|
234
|
-
buf << ")"
|
|
235
|
-
buf << " / "
|
|
236
|
-
buf << "#{repo.stats.updated} / "
|
|
237
|
-
buf << "#{repo.stats.created} - "
|
|
238
|
-
buf << "‹#{repo.stats.last_commit_message}›"
|
|
239
|
-
buf << " (#{repo.stats.size} kb)"
|
|
240
|
-
buf << "\n"
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
buf
|
|
245
|
-
end # method build
|
|
246
|
-
end # class ReportUpdates
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
end # module Hubba
|
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
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
|
-
}
|
data/test/stats/poole~hyde.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
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
|
-
}
|
data/test/test_stats.rb
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
###
|
|
2
|
-
# to run use
|
|
3
|
-
# ruby -I ./lib -I ./test test/test_stats.rb
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
require 'helper'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TestStats < MiniTest::Test
|
|
10
|
-
|
|
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
|
-
Hubba.config.data_dir = "#{Hubba.root}/test/stats"
|
|
21
|
-
stats.read
|
|
22
|
-
|
|
23
|
-
assert_equal 321, stats.size
|
|
24
|
-
assert_equal 717, stats.stars
|
|
25
|
-
assert_equal 717, stats.history[0].stars
|
|
26
|
-
assert_equal 1, stats.history.size
|
|
27
|
-
|
|
28
|
-
assert_equal Date.new(2018, 2, 12 ), stats.history[0].date
|
|
29
|
-
|
|
30
|
-
assert_nil stats.history[0].diff_days
|
|
31
|
-
|
|
32
|
-
assert_equal Date.new(2018, 2, 21 ), stats.committed
|
|
33
|
-
assert_equal Date.new(2016, 5, 20 ), stats.created
|
|
34
|
-
assert_equal Date.new(2018, 2, 11 ), stats.updated
|
|
35
|
-
assert_equal Date.new(2018, 2, 7 ), stats.pushed
|
|
36
|
-
|
|
37
|
-
assert_equal DateTime.new(2018, 2, 21, 19, 35, 59 ), stats.committed_at
|
|
38
|
-
assert_equal DateTime.new(2016, 5, 20, 23, 7, 56 ), stats.created_at
|
|
39
|
-
assert_equal DateTime.new(2018, 2, 11, 16, 13, 33 ), stats.updated_at
|
|
40
|
-
assert_equal DateTime.new(2018, 2, 7, 22, 14, 11 ), stats.pushed_at
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
pp stats.last_commit
|
|
44
|
-
pp stats.last_commit_message
|
|
45
|
-
pp stats.history_str ## pp history pretty printed to string (buffer)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def test_awesome_blockchains
|
|
51
|
-
|
|
52
|
-
stats = Hubba::Stats.new( 'openblockchains/awesome-blockchains' )
|
|
53
|
-
|
|
54
|
-
assert_equal 0, stats.size
|
|
55
|
-
assert_equal 0, stats.stars
|
|
56
|
-
assert_nil stats.history
|
|
57
|
-
|
|
58
|
-
Hubba.config.data_dir = "#{Hubba.root}/test/stats"
|
|
59
|
-
stats.read
|
|
60
|
-
|
|
61
|
-
assert_equal 1620, stats.size
|
|
62
|
-
assert_equal 1526, stats.stars
|
|
63
|
-
assert_equal 1526, stats.history[0].stars
|
|
64
|
-
assert_equal 1411, stats.history[1].stars
|
|
65
|
-
assert_equal 1084, stats.history[2].stars
|
|
66
|
-
assert_equal 1084, stats.history[-1].stars
|
|
67
|
-
assert_equal 3, stats.history.size
|
|
68
|
-
|
|
69
|
-
assert_equal Date.new(2018, 2, 8 ), stats.history[0].date
|
|
70
|
-
assert_equal Date.new(2018, 1, 28 ), stats.history[1].date
|
|
71
|
-
assert_equal Date.new(2017, 12, 10 ), stats.history[2].date
|
|
72
|
-
|
|
73
|
-
assert_equal 11, stats.history[0].diff_days
|
|
74
|
-
assert_equal 49, stats.history[1].diff_days
|
|
75
|
-
assert_nil stats.history[2].diff_days
|
|
76
|
-
|
|
77
|
-
assert_equal 115, stats.history[0].diff_stars
|
|
78
|
-
assert_equal 327, stats.history[1].diff_stars
|
|
79
|
-
assert_nil stats.history[2].diff_stars
|
|
80
|
-
|
|
81
|
-
assert_equal 221.0, stats.calc_diff_stars ## defaults to samples: 3, days: 30
|
|
82
|
-
assert_equal 51.566, stats.calc_diff_stars( samples: 5, days: 7 )
|
|
83
|
-
|
|
84
|
-
pp stats.history_str ## pp history pretty printed to string (buffer)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def test_factbook_json
|
|
89
|
-
|
|
90
|
-
stats = Hubba::Stats.new( 'opendatajson/factbook.json' )
|
|
91
|
-
|
|
92
|
-
assert_equal 0, stats.size
|
|
93
|
-
assert_equal 0, stats.stars
|
|
94
|
-
assert_nil stats.history
|
|
95
|
-
|
|
96
|
-
Hubba.config.data_dir = "#{Hubba.root}/test/stats"
|
|
97
|
-
stats.read
|
|
98
|
-
|
|
99
|
-
assert_equal 7355, stats.size
|
|
100
|
-
assert_equal 539, stats.stars
|
|
101
|
-
assert_equal 539, stats.history[0].stars
|
|
102
|
-
assert_equal 536, stats.history[1].stars
|
|
103
|
-
assert_equal 533, stats.history[2].stars
|
|
104
|
-
assert_equal 457, stats.history[-1].stars
|
|
105
|
-
assert_equal 7, stats.history.size
|
|
106
|
-
|
|
107
|
-
assert_equal Date.new(2018, 2, 8 ), stats.history[0].date
|
|
108
|
-
assert_equal Date.new(2018, 1, 28 ), stats.history[1].date
|
|
109
|
-
assert_equal Date.new(2017, 12, 10 ), stats.history[2].date
|
|
110
|
-
|
|
111
|
-
assert_equal 11, stats.history[0].diff_days
|
|
112
|
-
assert_equal 49, stats.history[1].diff_days
|
|
113
|
-
assert_nil stats.history[-1].diff_days
|
|
114
|
-
|
|
115
|
-
assert_equal 3, stats.history[0].diff_stars
|
|
116
|
-
assert_equal 3, stats.history[1].diff_stars
|
|
117
|
-
assert_nil stats.history[-1].diff_stars
|
|
118
|
-
|
|
119
|
-
assert_equal 3.0, stats.calc_diff_stars ## defaults to samples: 3, days: 30
|
|
120
|
-
assert_equal 1.012, stats.calc_diff_stars( samples: 5, days: 7 )
|
|
121
|
-
|
|
122
|
-
pp stats.history_str ## pp history pretty printed to string (buffer)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
end # class TestStats
|
data/test/test_stats_tmp.rb
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
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
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def test_stats
|
|
16
|
-
repos = [
|
|
17
|
-
'poole/hyde',
|
|
18
|
-
'jekyll/minima'
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
repos.each do |repo|
|
|
23
|
-
stats = Hubba::Stats.new( repo )
|
|
24
|
-
|
|
25
|
-
Hubba.config.data_dir = "#{Hubba.root}/test/stats"
|
|
26
|
-
stats.read()
|
|
27
|
-
|
|
28
|
-
puts "stars before fetch: #{stats.stars}"
|
|
29
|
-
puts "size before fetch: #{stats.size} kb"
|
|
30
|
-
|
|
31
|
-
## note/todo: enable for "live" online testing
|
|
32
|
-
## @gh.update( stats )
|
|
33
|
-
|
|
34
|
-
puts "stars after fetch: #{stats.stars}"
|
|
35
|
-
puts "size after fetch: #{stats.size} kb"
|
|
36
|
-
|
|
37
|
-
Hubba.config.data_dir = './tmp'
|
|
38
|
-
stats.write()
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
assert true # for now everything ok if we get here
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
end # class TestStatsTmp
|