hubtime 0.0.1
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.
- data/.gitignore +4 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +56 -0
- data/MIT-LICENSE +20 -0
- data/README.md +109 -0
- data/bin/hubtime +199 -0
- data/hubtime.gemspec +28 -0
- data/lib/hubtime.rb +16 -0
- data/lib/hubtime/activity.rb +494 -0
- data/lib/hubtime/cacher.rb +48 -0
- data/lib/hubtime/charts/graph.erb +92 -0
- data/lib/hubtime/charts/impact.erb +90 -0
- data/lib/hubtime/charts/pie.erb +51 -0
- data/lib/hubtime/commit.rb +42 -0
- data/lib/hubtime/github.rb +67 -0
- data/lib/hubtime/hub_config.rb +122 -0
- data/lib/hubtime/repo.rb +174 -0
- data/lib/hubtime/version.rb +3 -0
- data/readme/graph.png +0 -0
- data/readme/impact.png +0 -0
- data/readme/pie.png +0 -0
- data/readme/stacked.png +0 -0
- metadata +196 -0
data/lib/hubtime/repo.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
|
5
|
+
module Hubtime
|
6
|
+
class Repo
|
7
|
+
attr_reader :cacher, :mutex, :thread_count
|
8
|
+
attr_reader :repo_name, :username, :start_time, :end_time
|
9
|
+
def initialize(repo_name, username, start_time, end_time)
|
10
|
+
@repo_name = repo_name
|
11
|
+
@username = username
|
12
|
+
@cacher = Cacher.new("#{repo_name}")
|
13
|
+
@mutex = Mutex.new
|
14
|
+
@thread_count = HubConfig.threads
|
15
|
+
|
16
|
+
if end_time < start_time
|
17
|
+
@start_time = end_time
|
18
|
+
@end_time = start_time
|
19
|
+
else
|
20
|
+
@start_time = start_time
|
21
|
+
@end_time = end_time
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def auto_client
|
26
|
+
@auto_client ||= Octokit::Client.new(:login => HubConfig.user, :password => HubConfig.password, :auto_traversal => true)
|
27
|
+
end
|
28
|
+
|
29
|
+
def single_client
|
30
|
+
@single_client ||= Octokit::Client.new(:login => HubConfig.user, :password => HubConfig.password)
|
31
|
+
end
|
32
|
+
|
33
|
+
def commits(&block)
|
34
|
+
queue = self.sha_list.dup
|
35
|
+
|
36
|
+
if self.thread_count == 1
|
37
|
+
work_sha_queue(queue, block)
|
38
|
+
else
|
39
|
+
self.thread_count.times.map {
|
40
|
+
Thread.new do
|
41
|
+
work_sha_queue(queue, block)
|
42
|
+
end
|
43
|
+
}.each(&:join)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def generate_sha_windows
|
51
|
+
|
52
|
+
diff = end_time.to_i - start_time.to_i
|
53
|
+
thread_time = diff / self.thread_count
|
54
|
+
|
55
|
+
# seeing this issue https://gist.github.com/4256275
|
56
|
+
# when fixed, we can bump these up and remove single_window_check
|
57
|
+
max_window_time = 3.days
|
58
|
+
min_window_time = 1.day
|
59
|
+
|
60
|
+
between = thread_time
|
61
|
+
between = max_window_time if between > max_window_time
|
62
|
+
between = min_window_time if between < min_window_time
|
63
|
+
|
64
|
+
windows = []
|
65
|
+
until_time = end_time
|
66
|
+
while until_time >= start_time
|
67
|
+
since_time = until_time - between
|
68
|
+
since_time = start_time if since_time < start_time
|
69
|
+
|
70
|
+
windows << [since_time, until_time]
|
71
|
+
|
72
|
+
until_time = since_time - 1.second
|
73
|
+
end
|
74
|
+
|
75
|
+
windows
|
76
|
+
end
|
77
|
+
|
78
|
+
def single_window_check
|
79
|
+
# pagination doesn't work, see if there are even 100 over the whole window
|
80
|
+
options = { :author => username }
|
81
|
+
options[:since] = start_time.iso8601
|
82
|
+
options[:until] = end_time.iso8601
|
83
|
+
options[:per_page] = 100
|
84
|
+
options[:page] = 1
|
85
|
+
|
86
|
+
commits = single_client.commits(repo_name, "master", options)
|
87
|
+
return if commits.size >= 100 # go slower
|
88
|
+
|
89
|
+
result = []
|
90
|
+
commits.each do |hash|
|
91
|
+
next unless hash.is_a?(Hashie::Mash)
|
92
|
+
next unless hash.sha
|
93
|
+
result << hash.sha
|
94
|
+
end
|
95
|
+
|
96
|
+
result
|
97
|
+
end
|
98
|
+
|
99
|
+
def sha_list
|
100
|
+
cache_key = "#{username}/#{start_time.to_i}-#{end_time.to_i}"
|
101
|
+
# puts "sha_list: #{cache_key}\n"
|
102
|
+
if cached = cacher.read(cache_key)
|
103
|
+
return cached
|
104
|
+
end
|
105
|
+
|
106
|
+
result = single_window_check
|
107
|
+
|
108
|
+
if result.nil?
|
109
|
+
queue = self.generate_sha_windows
|
110
|
+
result = []
|
111
|
+
|
112
|
+
if self.thread_count == 1
|
113
|
+
work_window_queue(queue, result)
|
114
|
+
else
|
115
|
+
self.thread_count.times.map {
|
116
|
+
Thread.new do
|
117
|
+
work_window_queue(queue, result)
|
118
|
+
end
|
119
|
+
}.each(&:join)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
cacher.write(cache_key, result)
|
124
|
+
end
|
125
|
+
|
126
|
+
def work_window_queue(queue, result)
|
127
|
+
while window = mutex.synchronize { queue.shift }
|
128
|
+
since_time, until_time = window
|
129
|
+
list = commits_window(since_time, until_time)
|
130
|
+
mutex.synchronize { result.concat list }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def commits_window(since_time, until_time)
|
135
|
+
cache_key = "#{username}/#{since_time.to_i}-#{until_time.to_i}"
|
136
|
+
#puts "commits_window: #{cache_key}\n"
|
137
|
+
if cached = cacher.read(cache_key)
|
138
|
+
return cached
|
139
|
+
end
|
140
|
+
|
141
|
+
options = { :author => username }
|
142
|
+
options[:since] = since_time.iso8601
|
143
|
+
options[:until] = until_time.iso8601
|
144
|
+
|
145
|
+
result = []
|
146
|
+
commits = auto_client.commits(repo_name, "master", options)
|
147
|
+
commits.each do |hash|
|
148
|
+
next unless hash.is_a?(Hashie::Mash)
|
149
|
+
next unless hash.sha
|
150
|
+
result << hash.sha
|
151
|
+
end
|
152
|
+
|
153
|
+
cacher.write(cache_key, result.uniq)
|
154
|
+
end
|
155
|
+
|
156
|
+
def work_sha_queue(queue, block)
|
157
|
+
while sha = mutex.synchronize { queue.shift }
|
158
|
+
hash = fetch_sha(sha)
|
159
|
+
next unless hash.is_a?(Hashie::Mash)
|
160
|
+
next unless hash.sha
|
161
|
+
commit = Commit.new(hash, repo_name, username)
|
162
|
+
mutex.synchronize { block.call commit }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def fetch_sha(sha)
|
167
|
+
cache_key = "shas/#{sha}"
|
168
|
+
hashie = cacher.read(cache_key)
|
169
|
+
return hashie if hashie
|
170
|
+
hashie = single_client.commit(repo_name, sha)
|
171
|
+
cacher.write(cache_key, hashie)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
data/readme/graph.png
ADDED
Binary file
|
data/readme/impact.png
ADDED
Binary file
|
data/readme/pie.png
ADDED
Binary file
|
data/readme/stacked.png
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hubtime
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brian Leonard
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: active_support
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: commander
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '4.1'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '4.1'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: i18n
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.6'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.6'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: tzinfo
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.3'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.3'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: octokit
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '1.20'
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.20'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: terminal-table
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '1.4'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '1.4'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: erubis
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.7'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '2.7'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: hashie
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '1.2'
|
134
|
+
type: :runtime
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '1.2'
|
142
|
+
description: Visualization of your Github activity over the past year via Github API
|
143
|
+
with visualizations like table, graph, stacked graph and pie chart.
|
144
|
+
email: contact@plataformatec.com.br
|
145
|
+
executables:
|
146
|
+
- hubtime
|
147
|
+
extensions: []
|
148
|
+
extra_rdoc_files: []
|
149
|
+
files:
|
150
|
+
- .gitignore
|
151
|
+
- Gemfile
|
152
|
+
- Gemfile.lock
|
153
|
+
- MIT-LICENSE
|
154
|
+
- README.md
|
155
|
+
- bin/hubtime
|
156
|
+
- hubtime.gemspec
|
157
|
+
- lib/hubtime.rb
|
158
|
+
- lib/hubtime/activity.rb
|
159
|
+
- lib/hubtime/cacher.rb
|
160
|
+
- lib/hubtime/charts/graph.erb
|
161
|
+
- lib/hubtime/charts/impact.erb
|
162
|
+
- lib/hubtime/charts/pie.erb
|
163
|
+
- lib/hubtime/commit.rb
|
164
|
+
- lib/hubtime/github.rb
|
165
|
+
- lib/hubtime/hub_config.rb
|
166
|
+
- lib/hubtime/repo.rb
|
167
|
+
- lib/hubtime/version.rb
|
168
|
+
- readme/graph.png
|
169
|
+
- readme/impact.png
|
170
|
+
- readme/pie.png
|
171
|
+
- readme/stacked.png
|
172
|
+
homepage: http://github.com/bleonard/hubtime
|
173
|
+
licenses: []
|
174
|
+
post_install_message:
|
175
|
+
rdoc_options: []
|
176
|
+
require_paths:
|
177
|
+
- lib
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
+
none: false
|
180
|
+
requirements:
|
181
|
+
- - ! '>='
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
requirements: []
|
191
|
+
rubyforge_project: hubtime
|
192
|
+
rubygems_version: 1.8.24
|
193
|
+
signing_key:
|
194
|
+
specification_version: 3
|
195
|
+
summary: Visualization of your Github activity over the past year via Github API.
|
196
|
+
test_files: []
|