aweplug 1.0.0.a9 → 1.0.0.a10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,230 +0,0 @@
1
- module Aweplug
2
- module Extensions
3
- module Identity
4
- module GitHub
5
- CONTRIBUTORS_URL_TEMPLATE = 'https://api.github.com/repos/%s/%s/contributors'
6
- TEAM_MEMBERS_URL_TEMPLATE = 'https://api.github.com/teams/%s/members'
7
- USER_URL_TEMPLATE = 'https://api.github.com/users/%s'
8
-
9
- # It appears that all github users have a gravatar_id
10
- AVATAR_URL_TEMPLATE = 'http://gravatar.com/avatar/%s?s=%i'
11
- # TODO make the default avatar configurable
12
- FALLBACK_AVATAR_URL_TEMPLATE = 'https://community.jboss.org/people/sbs-default-avatar/avatar/%i.png'
13
- module IdentityHelper
14
- def avatar_url(size = 48)
15
- if !self.gravatar_id.nil?
16
- AVATAR_URL_TEMPLATE % [self.gravatar_id, size]
17
- else
18
- FALLBACK_URL_TEMPLATE % size
19
- end
20
- end
21
- end
22
-
23
- class Collector
24
-
25
- def initialize(opts = {})
26
- @repositories = []
27
- @match_filters = []
28
- @teams = opts[:teams]
29
- @auth_file = opts[:auth_file]
30
- @credentials = nil
31
- end
32
-
33
- def add_repository(repository)
34
- @repositories << repository
35
- end
36
-
37
- def add_match_filter(match_filter)
38
- @match_filters << match_filter
39
- #File.open('/tmp/committers.yml', 'w') do |out|
40
- # YAML.dump(match_filter, out)
41
- #end
42
- end
43
-
44
- def collect(identities)
45
- visited = []
46
- @repositories.each do |r|
47
- url = CONTRIBUTORS_URL_TEMPLATE % [r.owner, r.path]
48
- contributors = RestClient.get url, :accept => 'application/json'
49
- contributors.each do |acct|
50
- github_id = acct['login'].downcase
51
- author = nil
52
- @match_filters.each do |filter|
53
- author = filter.values.find { |candidate| candidate.github_id.eql? github_id }
54
- break unless author.nil?
55
- end
56
- if author.nil?
57
- #puts "Skipping non-Arquillian contributor #{github_id} in repository #{r.owner}/#{r.path}"
58
- next
59
- end
60
- identity = identities.lookup_by_github_id(github_id, true)
61
- github_acct_to_identity(acct, author, identity)
62
- visited << github_id
63
- end
64
- end
65
-
66
- # github doesn't keep perfect records of contributors, so handle those omitted contributors
67
- @match_filters.each do |filter|
68
- filter.values.select { |author| !author.github_id.nil? and !visited.include? author.github_id }.each do |author|
69
- github_id = author.github_id
70
- puts "Manually adding #{author.name} (#{github_id}) as a contributor"
71
- url = USER_URL_TEMPLATE % [github_id]
72
- user = RestClient.get url, :accept => 'application/json'
73
- identity = identities.lookup_by_github_id(github_id, true)
74
- github_acct_to_identity(user, author, identity)
75
- end
76
- end
77
-
78
- if !@teams.nil?
79
- get_credentials()
80
- if @credentials
81
- @teams.each do |team|
82
- url = TEAM_MEMBERS_URL_TEMPLATE % team[:id]
83
- url = url.gsub(/^(https?:\/\/)/, '\1' + @credentials.chomp + '@')
84
- members = RestClient.get(url, :accept => 'application/json')
85
- members.each do |m|
86
- github_id = m['login']
87
- identity = identities.lookup_by_github_id(github_id)
88
- # identity should not be null, mostly for testing
89
- if !identity.nil?
90
- identity.send(team[:name] + '=', true)
91
- identity.teams = [] if identity.teams.nil?
92
- identity.teams << team[:name]
93
- end
94
- end
95
- end
96
- end
97
- end
98
- end
99
-
100
- def github_acct_to_identity(acct, author, identity)
101
- # setup if first visit
102
- if identity.github.nil? or identity.github.contributions.nil?
103
- identity.github = OpenStruct.new if identity.github.nil?
104
- identity.github.contributions = acct.has_key?('contributions') ? acct['contributions'] : 0
105
- identity.github_url = acct['url'].downcase
106
- identity.gravatar_id = acct['gravatar_id']
107
- # author contains the commits we counted from analyzing the repositories
108
- identity.contributor = author
109
- identity.email = author.emails.first if identity.email.nil?
110
- identity.emails ||= []
111
- identity.emails |= [identity.email, author.emails.first]
112
- # alias for convenience
113
- identity.commits = author.commits
114
- # assume they want their commit name as the preferred name (unless it's an email)
115
- if identity.name.nil? and author.name.index('@').nil?
116
- if !author.name.index(' ').nil?
117
- # FIXME this could be made into a smarter utility function
118
- identity.name = author.name.split(' ').map { |n| n.capitalize }.join(' ')
119
- # special exception for Lincoln :)
120
- identity.name.gsub!('Iii', 'III')
121
- else
122
- identity.name = author.name.capitalize
123
- end
124
- end
125
- # if been there, just add contributions according to github
126
- else
127
- identity.github.contributions += acct.has_key?('contributions') ? acct['contributions'] : 0
128
- end
129
- end
130
-
131
- def get_credentials()
132
- if @credentials.nil?
133
- @credentials = false
134
- if !@auth_file.nil?
135
- if File.exist? @auth_file
136
- @credentials = File.read(@auth_file)
137
- elsif Pathname.new(@auth_file).relative? and File.exist? File.join(ENV['HOME'], @auth_file)
138
- @credentials = File.read(File.join(ENV['HOME'], @auth_file))
139
- end
140
- end
141
- end
142
- end
143
- end
144
-
145
- class Crawler
146
-
147
- def initialize(opts = {})
148
- @auth_file = opts[:auth_file]
149
- @credentials = nil
150
- end
151
-
152
- PROFILE_URL_TEMPLATE = 'https://api.github.com/users/%s'
153
-
154
- def enhance(identity)
155
- identity.extend(IdentityHelper)
156
- end
157
-
158
- def get_credentials()
159
- if @credentials.nil?
160
- @credentials = false
161
- if !@auth_file.nil?
162
- if File.exist? @auth_file
163
- @credentials = File.read(@auth_file)
164
- elsif Pathname.new(@auth_file).relative? and File.exist? File.join(ENV['HOME'], @auth_file)
165
- @credentials = File.read(File.join(ENV['HOME'], @auth_file))
166
- end
167
- end
168
- end
169
- end
170
-
171
- def crawl(identity)
172
- url = identity.github_url
173
- if url.nil?
174
- if !identity.github_id.nil?
175
- url = PROFILE_URL_TEMPLATE % identity.github_id
176
- end
177
- end
178
-
179
- # can't find user, give up (no github id or explicit url)
180
- if url.nil?
181
- return
182
- end
183
-
184
- get_credentials()
185
- url = url.gsub(/^(https?:\/\/)/, '\1' + @credentials.chomp + '@')
186
- data = RestClient.get url, :accept => 'application/json'
187
- identity.github_id = data['login'].downcase
188
- identity.username = identity.github_id
189
- identity.github = OpenStruct.new if identity.github.nil?
190
- identity.github.merge!(OpenStruct.new({
191
- :id => data['id'],
192
- :created => data['created_at'],
193
- :username => identity.username,
194
- :profile_url => data['html_url'].downcase
195
- }))
196
- # only overwrite name if it's longer than the one already there
197
- if !data['name'].nil? and (identity.name.nil? or data['name'].length > identity.name.length)
198
- identity.name = data['name'].titleize
199
- end
200
- identity.emails ||= []
201
- identity.emails |= [identity.email].compact
202
- keys_to_identity = ['email', 'gravatar_id', 'blog', 'location', 'bio', 'company']
203
- # merge keys, overwriting duplicates
204
- identity.merge!(OpenStruct.new(data.select { |k, v|
205
- !v.to_s.strip.empty? and keys_to_identity.include? k
206
- }))
207
- if identity.email
208
- identity.email = identity.email.downcase
209
- end
210
- # append email if we got a new one
211
- identity.emails |= [identity.email]
212
- # fix blog urls missing http:// prefix
213
- if !identity.blog.nil? and identity.blog !~ /^https?:\/\//
214
- identity.blog = 'http://' + identity.blog
215
- end
216
-
217
- # manually credited commits
218
- if identity.commits and !identity.contributor
219
- identity.contributor = OpenStruct.new({
220
- :commits => identity.commits,
221
- :emails => [identity.email],
222
- :name => identity.name
223
- })
224
- end
225
- end
226
- end
227
- end
228
- end
229
- end
230
- end
@@ -1,117 +0,0 @@
1
- require 'digest/md5'
2
-
3
- module Aweplug
4
- module Extensions
5
- module Identity
6
- module Gravatar
7
- class Crawler
8
- API_URL_TEMPLATE = 'http://en.gravatar.com/%s.json'
9
- LANYRD_PROFILE_URL_TEMPLATE = 'http://lanyrd.com/profile/%s'
10
-
11
- def enhance(identity)
12
- #identity.extend(IdentityHelper)
13
- end
14
-
15
- def crawl(identity)
16
- hash = identity.gravatar_id
17
- if hash.nil?
18
- hash = Digest::MD5.new().update(identity.email.downcase).hexdigest
19
- end
20
- url = API_URL_TEMPLATE % hash
21
- response = RestClient.get(url, :user_agent => "rest-client") do |rsp, req, res, &blk|
22
- if rsp.code.eql? 404
23
- #rsp = RestClient::Response.create('{}', rsp.net_http_res, rsp.args)
24
- rsp.instance_variable_set(:@code, 200)
25
- rsp
26
- else
27
- rsp.return!(req, res, &blk)
28
- end
29
- end
30
-
31
- data = JSON.parse response
32
-
33
- if data.empty?
34
- return
35
- end
36
-
37
- entry = data['entry'].first
38
-
39
- keys_to_gravatar = {
40
- 'id' => 'id',
41
- 'hash' => 'hash',
42
- 'profileUrl' => 'profile_url'
43
- }
44
- identity.gravatar = OpenStruct.new(entry.select { |k, v|
45
- !v.to_s.strip.empty? and keys_to_gravatar.has_key? k
46
- }.inject({}) { |h, (k, v)| h.store(keys_to_gravatar[k], v); h })
47
-
48
- keys_to_identity = {
49
- 'preferredUsername' => 'preferred_username',
50
- 'displayName' => 'name_cloak',
51
- 'aboutMe' => 'bio',
52
- 'currentLocation' => 'location'
53
- }
54
- identity.merge!(OpenStruct.new(entry.select { |k, v|
55
- !v.to_s.strip.empty? and keys_to_identity.has_key? k
56
- }.inject({}) { |h, (k, v)| h.store(keys_to_identity[k], v); h }), false)
57
-
58
- # TODO check if we need a merge here
59
- if entry.has_key? 'name' and !entry['name'].to_s.strip.empty?
60
- if identity.names.nil?
61
- identity.names = OpenStruct.new(entry['name'])
62
- end
63
- if identity.name.nil?
64
- identity.name = identity.names.formatted
65
- end
66
- end
67
-
68
- if entry.has_key? 'email' and !entry['email'].to_s.strip.empty?
69
- email = entry['email'].downcase
70
- identity.email = email if identity.email.nil?
71
- identity.emails ||= []
72
- identity.emails |= [identity.email, email]
73
- end
74
-
75
- (entry['accounts'] || []).each do |a|
76
- astruct = OpenStruct.new(a)
77
- if identity.send(a['shortname']).nil?
78
- identity.send(a['shortname'] + '=', astruct)
79
- else
80
- identity.send(a['shortname']).merge!(astruct)
81
- end
82
- end
83
-
84
- # grab twitter usernames supplied by _config/identity.yml
85
- if identity.twitter.nil? and !identity.twitter_username.nil?
86
- identity.twitter = OpenStruct.new({
87
- :username => identity.twitter_username,
88
- :url => 'http://twitter.com/' + identity.twitter_username
89
- })
90
- end
91
-
92
- # QUESTION do we need the speaker flag check?
93
- if identity.speaker and !identity.twitter.nil? and identity.lanyrd.nil?
94
- identity.lanyrd = OpenStruct.new({
95
- :username => identity.twitter.username,
96
- :profile_url => LANYRD_PROFILE_URL_TEMPLATE % identity.twitter.username
97
- })
98
- end
99
-
100
- # FIXME either map url to profile_url, or change everywhere else
101
- (entry['urls'] || []).each do |u|
102
- identity.urls = [] if identity.urls.nil?
103
- identity.urls << OpenStruct.new(u)
104
- if identity.blog.to_s.empty? and u['title'] =~ /blog/i
105
- identity.blog = u['value']
106
- end
107
- if identity.homepage.to_s.empty? and u['title'] =~ /personal/i
108
- identity.homepage = u['value']
109
- end
110
- end
111
- end
112
- end
113
- end
114
- end
115
- end
116
- end
117
-
@@ -1,35 +0,0 @@
1
- module Aweplug
2
- module Extensions
3
- module Identity
4
- module JBossCommunity
5
- class Crawler
6
- PROFILE_URL_TEMPLATE = 'https://community.jboss.org/people/%s'
7
-
8
- def crawl(identity)
9
- if !identity.jboss_username.nil?
10
- identity.jbosscommunity = OpenStruct.new({
11
- :username => identity.jboss_username,
12
- :profile_url => PROFILE_URL_TEMPLATE % identity.jboss_username
13
- })
14
- end
15
-
16
- if identity.jbosscommunity.nil? and !identity.urls.nil?
17
- identity.urls.each do |u|
18
- if u.title =~ /jboss community/i
19
- identity.jbosscommunity = OpenStruct.new({
20
- :username => u.value.split('/').last,
21
- :profile_url => u.value
22
- })
23
- identity.jboss_username = identity.jbosscommunity.username
24
- break
25
- end
26
- end
27
- end
28
- # TODO actually rip data from community.jboss.org
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
35
-
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Identity Collector' do
4
-
5
- it 'may have one or more crawlers' do
6
- pending "Not implemented"
7
- end
8
-
9
- it 'must have one storage' do
10
- pending "Not implemented"
11
- end
12
-
13
- it 'may be configurable via a block' do
14
- pending "Not implemented"
15
- end
16
-
17
- it 'may be configured via method calls' do
18
- pending "Not implemented"
19
- end
20
-
21
- it 'must respond to execute(site)' do
22
- pending "Not implemented"
23
- end
24
- end
@@ -1,7 +0,0 @@
1
- require 'spec_helper'
2
- require 'aweplug/extensions/identity/github'
3
-
4
- describe 'Github Crawler' do
5
- let(:crawler) { Aweplug::Extensions::Identity::GitHub::Crawler.new }
6
- it_should_behave_like 'a crawler'
7
- end
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Storage' do
4
-
5
- it 'must respond to write' do
6
- pending "Not implemented"
7
- end
8
-
9
- it 'must respond to read' do
10
- pending "Not implemented"
11
- end
12
-
13
- it 'must respond to fetch' do
14
- pending "Not implemented"
15
- end
16
-
17
- it 'must respond to exist' do
18
- pending "Not implemented"
19
- end
20
-
21
- it 'must respond to delete' do
22
- pending "Not implemented"
23
- end
24
- end
@@ -1,13 +0,0 @@
1
- shared_examples_for 'a crawler' do
2
- it 'may require authentication' do
3
- if crawler.respond_to? :authenticate_using, false
4
- expect { crawler.crawl }.to raise_error
5
- else
6
- expect { crawler.crawl }.to_not raise_error
7
- end
8
- end
9
-
10
- it 'must respond to crawl' do
11
- should respond_to(:crawl)
12
- end
13
- end