hubba 0.4.0 → 0.6.1

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: e3e04406b046b751a5eb400e8955417ae99498e7
4
- data.tar.gz: 57752bfd47aea766d3db5c467659876216a644a0
3
+ metadata.gz: 122527cdc3cddb68e2c54a6e51fcfb77c2c91c0c
4
+ data.tar.gz: 6bb52baff0536f55ad969885fc8500b031457e44
5
5
  SHA512:
6
- metadata.gz: f96d7fa167b0e7cf8b685674aa80d19eca790ad237a9ea43cd40650d1c799448ce5827b009bb84b9d14c774b991693e1b0570735bf6573f64ed2c0a9e46c1c1f
7
- data.tar.gz: 5cbdcd4a949763f19ba6275cec64cc1f3cfda6b05abe02950721befac8df17b1a5a1d64d1e41ae8048d23c06b93f41436d69bde91338e81313aa6e19af89236a
6
+ metadata.gz: df4e036a205be30371ec9de85e8085717235922fcc21e22f9f516cc40481a2a8cf6a9b0edd0a37cb24759059a08b5ea74957f41f89139bf9e1a860ed20029e3b
7
+ data.tar.gz: 698fc0d240aa6c6f8b125d1ae004beacf5ae97c220eb42d4fd542a49a656ece101e3a9fd9e740eaefb63e7f03c132458872f4ea5949cd30e2eceb9ccc3bb9e54
File without changes
@@ -1,21 +1,20 @@
1
- HISTORY.md
1
+ CHANGELOG.md
2
2
  Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/hubba.rb
6
- lib/hubba/cache.rb
7
6
  lib/hubba/client.rb
7
+ lib/hubba/config.rb
8
8
  lib/hubba/github.rb
9
+ lib/hubba/reports.rb
10
+ lib/hubba/reposet.rb
9
11
  lib/hubba/stats.rb
10
12
  lib/hubba/version.rb
11
- test/cache/users~geraldb~orgs.json
12
- test/cache/users~geraldb~repos.json
13
13
  test/helper.rb
14
14
  test/stats/jekyll~minima.json
15
15
  test/stats/openblockchains~awesome-blockchains.json
16
16
  test/stats/opendatajson~factbook.json.json
17
17
  test/stats/poole~hyde.json
18
- test/test_cache.rb
19
18
  test/test_config.rb
20
19
  test/test_stats.rb
21
20
  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/gittiscripts/hubba](https://github.com/gittiscripts/hubba)
6
- * bugs :: [github.com/gittiscripts/hubba/issues](https://github.com/gittiscripts/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
-
17
- ## License
18
-
19
- The `hubba` scripts are dedicated to the public domain.
20
- Use it as you please with no restrictions whatsoever.
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
@@ -8,23 +8,23 @@ Hoe.spec 'hubba' do
8
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/gittiscripts/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: '>= 2.3'
27
+ required_ruby_version: '>= 2.2.2'
28
28
  }
29
29
 
30
30
  end
@@ -1,25 +1,43 @@
1
- # encoding: utf-8
1
+ # 3rd party (our own)
2
+ require 'webclient'
2
3
 
3
- require 'net/http'
4
- require "net/https"
5
- require 'uri'
6
4
 
7
- require 'pp'
8
- require 'json'
9
- require 'yaml'
10
- require 'time'
5
+ ###############
6
+ ## helpers
7
+
8
+ def save_json( path, data ) ## data - hash or array
9
+ File.open( path, 'w:utf-8' ) do |f|
10
+ f.write( JSON.pretty_generate( data ))
11
+ end
12
+ end
13
+
14
+ def save_yaml( path, data )
15
+ File.open( path, 'w:utf-8' ) do |f|
16
+ f.write( data.to_yaml )
17
+ end
18
+ end
11
19
 
12
20
 
13
- # 3rd party gems/libs
14
- require 'logutils'
15
21
 
16
22
  # our own code
17
23
  require 'hubba/version' # note: let version always go first
18
- require 'hubba/cache'
24
+ require 'hubba/config'
19
25
  require 'hubba/client'
20
26
  require 'hubba/github'
21
27
  require 'hubba/stats'
22
28
 
29
+ ## "higher level" porcelain services / helpers for easy (re)use
30
+ require 'hubba/reposet'
31
+
32
+ require 'hubba/reports'
33
+
34
+
35
+ ############
36
+ # add convenience alias for alternate spelling - why? why not?
37
+ module Hubba
38
+ GitHub = Github
39
+ end
40
+
23
41
 
24
42
  # say hello
25
- puts Hubba.banner if defined?($RUBYLIBS_DEBUG)
43
+ puts Hubba.banner if defined?($RUBYCOCO_DEBUG)
@@ -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
27
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
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}"
43
- end
60
+ # puts "HTTP HEADERS:"
61
+ # res.headers.each do |key, value|
62
+ # puts " #{key}: >#{value}<"
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
@@ -0,0 +1,51 @@
1
+ module Hubba
2
+
3
+ class Configuration
4
+ def data_dir() @data_dir || './data'; end
5
+ def data_dir=( value ) @data_dir = value; end
6
+
7
+ ### todo/check: rename to/use tmp_dir - why? why not?
8
+ def cache_dir() @cache_dir || './cache'; end
9
+ def cache_dir=( value ) @cache_dir = value; end
10
+
11
+
12
+ # try default setup via ENV variables
13
+ def token() @token || ENV[ 'HUBBA_TOKEN' ]; end
14
+ def token=( value ) @token = value; end
15
+
16
+ # todo/check: use HUBBA_LOGIN - why? why not?
17
+ def user() @user || ENV[ 'HUBBA_USER' ]; end
18
+ def password() @password || ENV[ 'HUBBA_PASSWORD' ]; end
19
+ def user=( value ) @user = value; end
20
+ def password=( value ) @password = value; end
21
+
22
+ end # class Configuration
23
+
24
+
25
+ ## lets you use
26
+ ## Hubba.configure do |config|
27
+ ## config.token = 'secret'
28
+ ## -or-
29
+ ## config.user = 'testdada'
30
+ ## config.password = 'secret'
31
+ ## end
32
+ ##
33
+ ## move configure block to GitHub class - why? why not?
34
+ ## e.g. GitHub.configure do |config|
35
+ ## ...
36
+ ## end
37
+
38
+
39
+ def self.configuration
40
+ @configuration ||= Configuration.new
41
+ end
42
+ class << self
43
+ alias_method :config, :configuration
44
+ end
45
+
46
+
47
+ def self.configure
48
+ yield( configuration )
49
+ end
50
+
51
+ end # module Hubba
@@ -1,38 +1,5 @@
1
- # encoding: utf-8
2
-
3
1
  module Hubba
4
2
 
5
- class Configuration
6
- attr_accessor :user
7
- attr_accessor :password
8
-
9
- def initialize
10
- # try default setup via ENV variables
11
- @user = ENV[ 'HUBBA_USER' ] ## use HUBBA_LOGIN - why? why not?
12
- @password = ENV[ 'HUBBA_PASSWORD' ]
13
- end
14
- end
15
-
16
- ## lets you use
17
- ## Hubba.configure do |config|
18
- ## config.user = 'testdada'
19
- ## config.password = 'secret'
20
- ## end
21
- ##
22
- ## move configure block to GitHub class - why? why not?
23
- ## e.g. GitHub.configure do |config|
24
- ## ...
25
- ## end
26
-
27
-
28
- def self.configuration
29
- @configuration ||= Configuration.new
30
- end
31
-
32
- def self.configure
33
- yield( configuration )
34
- end
35
-
36
3
 
37
4
  class Resource
38
5
  attr_reader :data
@@ -53,25 +20,25 @@ class Orgs < Resource
53
20
  ## sort by name
54
21
  data.map { |item| item['login'] }.sort
55
22
  end
23
+ alias_method :names, :logins ## add name alias - why? why not?
56
24
  end
57
25
 
58
26
 
59
27
 
60
28
  class Github
61
29
 
62
- def initialize( cache_dir: './cache' )
63
- @cache = Cache.new( cache_dir )
64
- @client = Client.new( user: Hubba.configuration.user,
65
- password: Hubba.configuration.password )
66
-
67
- @offline = false
30
+ def initialize
31
+ @client = if Hubba.configuration.token
32
+ Client.new( token: Hubba.configuration.token )
33
+ elsif Hubba.configuration.user &&
34
+ Hubba.configuration.password
35
+ Client.new( user: Hubba.configuration.user,
36
+ password: Hubba.configuration.password )
37
+ else
38
+ Client.new
39
+ end
68
40
  end
69
41
 
70
- def offline!() @offline = true; end ## switch to offline - todo: find a "better" way - why? why not?
71
- def online!() @offline = false; end
72
- def offline?() @offline == true; end
73
- def online?() @offline == false; end
74
-
75
42
 
76
43
  def user( name )
77
44
  Resource.new( get "/users/#{name}" )
@@ -95,6 +62,7 @@ def user_orgs( name )
95
62
  end
96
63
 
97
64
 
65
+
98
66
  def org( name )
99
67
  Resource.new( get "/orgs/#{name}" )
100
68
  end
@@ -114,15 +82,56 @@ def repo_commits( full_name )
114
82
  end
115
83
 
116
84
 
117
- private
118
- def get( request_uri )
119
- if offline?
120
- @cache.get( request_uri )
85
+
86
+ ####
87
+ # more
88
+ def update( obj )
89
+ if obj.is_a?( Stats )
90
+ stats = obj
91
+ full_name = stats.full_name
92
+ puts "[update 1/2] fetching repo >#{full_name}<..."
93
+ repo = repo( full_name )
94
+ puts "[update 2/2] fetching repo >#{full_name}< commits ..."
95
+ commits = repo_commits( full_name )
96
+
97
+ stats.update( repo, commits )
121
98
  else
122
- @client.get( request_uri )
99
+ raise ArgumentError, "unknown source object passed in - expected Hubba::Stats; got #{obj.class.name}"
123
100
  end
124
101
  end
125
102
 
126
- end # class Github
127
103
 
128
- end # module Hubba
104
+ def update_stats( h ) ## todo/fix: change to Reposet - why? why not???
105
+ h.each do |org_with_counter,names|
106
+
107
+ ## remove optional number from key e.g.
108
+ ## mrhydescripts (3) => mrhydescripts
109
+ ## footballjs (4) => footballjs
110
+ ## etc.
111
+
112
+ org = org_with_counter.sub( /\([0-9]+\)/, '' ).strip
113
+
114
+ ## puts " -- #{key_with_counter} [#{key}] --"
115
+
116
+ names.each do |name|
117
+ full_name = "#{org}/#{name}"
118
+
119
+ ## puts " fetching stats #{count+1}/#{repo_count} - >#{full_name}<..."
120
+ stats = Stats.new( full_name )
121
+ stats.read
122
+
123
+ update( stats ) ## fetch & update stats
124
+
125
+ stats.write
126
+ end
127
+ end
128
+ end
129
+
130
+
131
+ private
132
+ def get( request_uri )
133
+ @client.get( request_uri )
134
+ end
135
+
136
+ end # class Github
137
+ end # module Hubba