Skip to content

Commit 0bbc6c8

Browse files
committed
up
1 parent b6eae4e commit 0bbc6c8

File tree

16 files changed

+1457
-1173
lines changed

16 files changed

+1457
-1173
lines changed

gemverse/.gitignore

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
*.gem
2+
*.rbc
3+
/.config
4+
/coverage/
5+
/InstalledFiles
6+
/pkg/
7+
/spec/reports/
8+
/test/tmp/
9+
/test/version_tmp/
10+
/tmp/
11+
12+
## Specific to RubyMotion:
13+
.dat*
14+
.repl_history
15+
build/
16+
17+
## Documentation cache and generated files:
18+
/.yardoc/
19+
/_yardoc/
20+
/doc/
21+
/rdoc/
22+
23+
## Environment normalisation:
24+
/.bundle/
25+
/vendor/bundle
26+
/lib/bundler/man/
27+
28+
# for a library or gem, you might want to ignore these files since the code is
29+
# intended to run in multiple environments; otherwise, check them in:
30+
# Gemfile.lock
31+
# .ruby-version
32+
# .ruby-gemset
33+
34+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35+
.rvmrc
36+
37+
38+
####
39+
## add cache for gems api requests
40+
cache/
41+

gemverse/NOTES.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@
33
## Gem Gems In Ruby
44

55

6+
### Gem Stats & More
7+
8+
**whatthegem** && **any_good** see
9+
- <https://github.com/zverok/whatthegem>
10+
- <https://github.com/zverok/any_good>
11+
612

713

814
### Gem API Wrappers / Calls
915

10-
**Gems** see <https://github.com/rubygems/gems>
16+
**gems** see
17+
- <https://github.com/rubygems/gems>

gemverse/gems/README.md

+879-845
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name, version, created, downloads
2-
ethlite-contracts, 0.1.4, 2023-01-16, 108
3-
ethlite-contracts, 0.1.3, 2023-01-15, 108
4-
ethlite-contracts, 0.1.2, 2023-01-15, 75
5-
ethlite-contracts, 0.1.1, 2023-01-13, 126
6-
ethlite-contracts, 0.1.0, 2023-01-12, 380
2+
ethlite-contracts, 0.1.4, 2023-01-16, 111
3+
ethlite-contracts, 0.1.3, 2023-01-15, 109
4+
ethlite-contracts, 0.1.2, 2023-01-15, 76
5+
ethlite-contracts, 0.1.1, 2023-01-13, 127
6+
ethlite-contracts, 0.1.0, 2023-01-12, 420
77
ethlite-contracts, 0.0.1, 2023-01-09, 160

gemverse/gems/eventdb/versions.csv

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
name, version, created, downloads
2-
eventdb, 1.1.2, 2023-01-18, 40
3-
eventdb, 1.1.1, 2019-12-08, 2036
4-
eventdb, 1.1.0, 2019-12-08, 1440
5-
eventdb, 1.0.0, 2019-12-06, 1475
6-
eventdb, 0.7.1, 2019-12-05, 1470
7-
eventdb, 0.7.0, 2015-07-12, 2664
8-
eventdb, 0.6.1, 2015-07-10, 2061
9-
eventdb, 0.6.0, 2015-06-24, 2075
10-
eventdb, 0.5.0, 2015-06-23, 2068
11-
eventdb, 0.4.0, 2015-06-23, 2039
12-
eventdb, 0.3.0, 2015-06-22, 2065
13-
eventdb, 0.2.0, 2015-06-21, 2059
14-
eventdb, 0.1.0, 2015-06-21, 2034
15-
eventdb, 0.0.1, 2015-06-21, 2036
2+
eventdb, 1.1.2, 2023-01-18, 99
3+
eventdb, 1.1.1, 2019-12-08, 2037
4+
eventdb, 1.1.0, 2019-12-08, 1441
5+
eventdb, 1.0.0, 2019-12-06, 1476
6+
eventdb, 0.7.1, 2019-12-05, 1471
7+
eventdb, 0.7.0, 2015-07-12, 2665
8+
eventdb, 0.6.1, 2015-07-10, 2062
9+
eventdb, 0.6.0, 2015-06-24, 2076
10+
eventdb, 0.5.0, 2015-06-23, 2069
11+
eventdb, 0.4.0, 2015-06-23, 2040
12+
eventdb, 0.3.0, 2015-06-22, 2066
13+
eventdb, 0.2.0, 2015-06-21, 2060
14+
eventdb, 0.1.0, 2015-06-21, 2035
15+
eventdb, 0.0.1, 2015-06-21, 2037

gemverse/gems/markdown/versions.csv

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name, version, created, downloads
2-
markdown, 1.2.0, 2014-12-06, 72682
2+
markdown, 1.2.0, 2014-12-06, 72717
33
markdown, 1.1.1, 2013-05-25, 50614
44
markdown, 1.1.0, 2013-05-24, 3038
55
markdown, 1.0.0, 2012-06-23, 81896

gemverse/gems/whatson/versions.csv

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name, version, created, downloads
2-
whatson, 2023.0.0, 2023-01-18, 37
2+
whatson, 2023.0.0, 2023-01-18, 96
33
whatson, 1.1.0, 2019-12-08, 1890
44
whatson, 1.0.0, 2019-12-06, 1337
55
whatson, 0.1.0, 2015-06-23, 2720

gemverse/lib/gemverse.rb

+72-25
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,95 @@
11
require 'cocos'
22

33

4+
## move to cocos - upstream - why? why not?
5+
def write_csv( path, recs )
6+
buf = String.new
7+
buf << recs[0].join( ', ' )
8+
buf << "\n"
9+
recs[1..-1].each do |values|
10+
buf << values.join( ', ' )
11+
buf << "\n"
12+
end
13+
write_text( path, buf )
14+
end
415

5-
module Gems
616

7-
def self.gems_by( handle )
8-
src = "#{BASE}/owners/#{handle}/gems.json"
9-
call( src )
10-
end
1117

12-
def self.versions( name )
1318

14-
## note: will NOT include yanked versions
15-
## check if there's a query parameter ???
1619

1720

18-
src = "#{BASE}/versions/#{name}.json"
19-
call( src )
20-
end
21+
require_relative 'gemverse/api'
22+
require_relative 'gemverse/gems'
23+
require_relative 'gemverse/cache'
2124

25+
require_relative 'gemverse/timeline' ## timeline report
2226

2327

24-
BASE = 'https://rubygems.org/api/v1'
2528

29+
module Gems
30+
31+
###
32+
## "high-level" finders
33+
34+
def self.find_by( owner: ) ## todo/check: use
2635

27-
def self.call( src ) ## get response as (parsed) json (hash table)
36+
rows = API.gems_by( owner )
37+
# pp data
38+
puts " #{rows.size} record(s) founds"
2839

29-
headers = {
30-
# 'User-Agent' => "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
31-
'User-Agent' => "ruby v#{RUBY_VERSION}",
32-
}
40+
## write "raw respone" to cache for debugging
41+
write_json( "./cache/gems_#{owner}.json", rows )
3342

34-
response = Webclient.get( src, headers: headers )
3543

36-
if response.status.ok?
37-
puts "#{response.status.code} #{response.status.message} - content_type: #{response.content_type}, content_length: #{response.content_length}"
3844

39-
response.json
40-
else
41-
puts "!! HTTP ERROR:"
42-
puts "#{response.status.code} #{response.status.message}"
43-
exit 1
45+
recs = []
46+
rows.each do |row|
47+
recs << Gem.create( row )
4448
end
49+
50+
## sort by
51+
## 1) (latest) version created and
52+
## 2) name
53+
recs = recs.sort do |l,r|
54+
res = r.version_created <=> l.version_created
55+
res = l.name <=> r.name if res == 0
56+
res
57+
end
58+
59+
GemDataset.new( recs )
60+
end
61+
62+
63+
64+
def self.read_csv( path )
65+
## note: requires Kernel:: otherwise stackoverflow endlessly calling read_csv
66+
rows = Kernel::read_csv( path )
67+
puts " #{rows.size} record(s) founds"
68+
69+
recs = []
70+
rows.each do |row|
71+
kwargs = {
72+
version: row['version'].empty? ? nil : row['version'],
73+
version_downloads: row['version_downloads'].empty? ? nil : row['version_downloads'].to_i,
74+
version_created: row['version_created'].empty? ? nil : Date.strptime( row['version_created'], '%Y-%m-%d' ),
75+
homepage: row['homepage'].empty? ? nil : row['homepage'],
76+
runtime: row['dependencies'].empty? ? [] : row['dependencies'].split('|').map {|dep| dep.strip },
77+
}
78+
recs << Gem.new( name: row['name'], **kwargs )
79+
end
80+
81+
## sort by
82+
## 1) (latest) version created and
83+
## 2) name
84+
recs = recs.sort do |l,r|
85+
res = r.version_created <=> l.version_created
86+
res = l.name <=> r.name if res == 0
87+
res
88+
end
89+
90+
GemDataset.new( recs )
4591
end
4692

4793

4894
end # module Gems
95+

gemverse/lib/gemverse/api.rb

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
module Gems
3+
module API
4+
5+
BASE = 'https://rubygems.org/api/v1'
6+
7+
def self.gems_by( owner )
8+
src = "#{BASE}/owners/#{owner}/gems.json"
9+
call( src )
10+
end
11+
12+
13+
def self.versions( name )
14+
## note: will NOT include yanked versions
15+
## check if there's a query parameter ???
16+
src = "#{BASE}/versions/#{name}.json"
17+
call( src )
18+
end
19+
20+
21+
def self.call( src ) ## get response as (parsed) json (hash table)
22+
23+
headers = {
24+
# 'User-Agent' => "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
25+
'User-Agent' => "ruby v#{RUBY_VERSION}",
26+
}
27+
28+
response = Webclient.get( src, headers: headers )
29+
30+
if response.status.ok?
31+
puts "#{response.status.code} #{response.status.message} - content_type: #{response.content_type}, content_length: #{response.content_length}"
32+
33+
response.json
34+
else
35+
puts "!! HTTP ERROR:"
36+
puts "#{response.status.code} #{response.status.message}"
37+
exit 1
38+
end
39+
end
40+
41+
end # module API
42+
end # module Gems

gemverse/lib/gemverse/cache.rb

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
2+
3+
module Gems
4+
class Cache
5+
def initialize( basedir='./gems' )
6+
@basedir = basedir
7+
end
8+
9+
10+
def update_versions( gems: [] )
11+
12+
delay_in_s = 0.5
13+
14+
gems.each_with_index do |gem,i|
15+
16+
name = if gem.is_a?( String )
17+
gem
18+
elsif gem.is_a?( Hash )
19+
gem['name']
20+
else ## assume our own Gem struct/class for now
21+
gem.name
22+
end
23+
24+
puts "==> #{i+1}/#{gems.size} #{name}..."
25+
26+
## update versions info
27+
puts " sleeping #{delay_in_s} second(s)"
28+
sleep( delay_in_s )
29+
30+
data = Gems::API.versions( name )
31+
puts " #{data.size} version record(s) found"
32+
33+
headers = ['name',
34+
'version',
35+
'created',
36+
'downloads']
37+
recs = []
38+
data.each do |h|
39+
## only use year/month/day for now now hours etc.
40+
created = Date.strptime( h['created_at'], '%Y-%m-%d' )
41+
42+
rec = [
43+
name,
44+
h['number'],
45+
created.strftime( '%Y-%m-%d' ),
46+
h['downloads_count'].to_s,
47+
]
48+
recs << rec
49+
end
50+
write_csv( "#{@basedir}/#{name}/versions.csv", [headers]+recs )
51+
end
52+
end
53+
54+
55+
56+
def read_versions( gems: [] )
57+
## read in and merge all version records
58+
versions = []
59+
60+
## if no gems passed in - get all versions.csv datasets in basedir
61+
if gems.empty?
62+
paths = Dir.glob( "#{@basedir}/*/versions.csv" )
63+
gems = paths.map { |path| File.basename(File.dirname(path)) }
64+
end
65+
66+
gems.each_with_index do |gem,i|
67+
68+
name = if gem.is_a?( String )
69+
gem
70+
elsif gem.is_a?( Hash )
71+
gem['name']
72+
else ## assume our own Gem struct/class for now
73+
gem.name
74+
end
75+
76+
path = "#{@basedir}/#{name}/versions.csv"
77+
puts "==> #{i+1}/#{gems.size} reading #{name}..."
78+
recs = read_csv( path )
79+
recs.reverse.each_with_index do |rec,n|
80+
more = { 'count' => (n+1).to_s } ## auto-add version count(er) e.g. 1,2,3,...
81+
versions << rec.merge( more )
82+
end
83+
puts " #{recs.size} record(s)"
84+
end
85+
86+
## sort by version created and name
87+
versions = versions.sort do |l,r|
88+
res = r['created'] <=> l['created']
89+
res = l['name'] <=> r['name'] if res == 0
90+
res = r['version'] <=> l['version'] if res == 0
91+
res
92+
end
93+
94+
versions
95+
end
96+
97+
98+
99+
end ## class Cache
100+
end ## module Gems

0 commit comments

Comments
 (0)