ghtorrent 0.3.1 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +23 -0
- data/bin/ght-data-retrieval +34 -39
- data/bin/ght-load +0 -33
- data/bin/ght-mirror-events +0 -30
- data/bin/ght-rm-dupl +0 -32
- data/bin/ght-torrent-index +0 -30
- data/lib/ghtorrent.rb +21 -3
- data/lib/ghtorrent/adapters/base_adapter.rb +1 -29
- data/lib/ghtorrent/adapters/mongo_persister.rb +10 -30
- data/lib/ghtorrent/adapters/noop_persister.rb +0 -28
- data/lib/ghtorrent/api_client.rb +1 -28
- data/lib/ghtorrent/call_stack.rb +0 -28
- data/lib/ghtorrent/command.rb +0 -28
- data/lib/ghtorrent/ghtorrent.rb +260 -94
- data/lib/ghtorrent/logging.rb +0 -28
- data/lib/ghtorrent/migrations/005_add_repo_collaborators.rb +23 -0
- data/lib/ghtorrent/migrations/006_add_watchers.rb +23 -0
- data/lib/ghtorrent/persister.rb +0 -28
- data/lib/ghtorrent/retriever.rb +111 -92
- data/lib/ghtorrent/settings.rb +1 -29
- data/lib/ghtorrent/utils.rb +0 -28
- metadata +7 -5
data/lib/ghtorrent/api_client.rb
CHANGED
@@ -1,31 +1,3 @@
|
|
1
|
-
# Copyright 2012 Georgios Gousios <gousiosg@gmail.com>
|
2
|
-
#
|
3
|
-
# Redistribution and use in source and binary forms, with or
|
4
|
-
# without modification, are permitted provided that the following
|
5
|
-
# conditions are met:
|
6
|
-
#
|
7
|
-
# 1. Redistributions of source code must retain the above
|
8
|
-
# copyright notice, this list of conditions and the following
|
9
|
-
# disclaimer.
|
10
|
-
#
|
11
|
-
# 2. Redistributions in binary form must reproduce the above
|
12
|
-
# copyright notice, this list of conditions and the following
|
13
|
-
# disclaimer in the documentation and/or other materials
|
14
|
-
# provided with the distribution.
|
15
|
-
#
|
16
|
-
# THIS SOFTWARE IS PROVIDED BY BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17
|
-
# AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
18
|
-
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19
|
-
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
|
20
|
-
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21
|
-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22
|
-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23
|
-
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24
|
-
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25
|
-
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26
|
-
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
-
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
-
|
29
1
|
require 'net/http'
|
30
2
|
require 'set'
|
31
3
|
require 'open-uri'
|
@@ -132,6 +104,7 @@ module GHTorrent
|
|
132
104
|
STDERR.puts "#{url}: #{e.io.status[1]}"
|
133
105
|
return nil
|
134
106
|
else # Server error or HTTP conditions that Github does not report
|
107
|
+
STDERR.puts "#{url}"
|
135
108
|
raise e
|
136
109
|
end
|
137
110
|
end
|
data/lib/ghtorrent/call_stack.rb
CHANGED
@@ -1,31 +1,3 @@
|
|
1
|
-
# Copyright 2012 Georgios Gousios <gousiosg@gmail.com>
|
2
|
-
#
|
3
|
-
# Redistribution and use in source and binary forms, with or
|
4
|
-
# without modification, are permitted provided that the following
|
5
|
-
# conditions are met:
|
6
|
-
#
|
7
|
-
# 1. Redistributions of source code must retain the above
|
8
|
-
# copyright notice, this list of conditions and the following
|
9
|
-
# disclaimer.
|
10
|
-
#
|
11
|
-
# 2. Redistributions in binary form must reproduce the above
|
12
|
-
# copyright notice, this list of conditions and the following
|
13
|
-
# disclaimer in the documentation and/or other materials
|
14
|
-
# provided with the distribution.
|
15
|
-
#
|
16
|
-
# THIS SOFTWARE IS PROVIDED BY BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17
|
-
# AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
18
|
-
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19
|
-
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
|
20
|
-
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21
|
-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22
|
-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23
|
-
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24
|
-
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25
|
-
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26
|
-
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
-
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
-
|
29
1
|
module GHTorrent
|
30
2
|
class CallStack
|
31
3
|
|
data/lib/ghtorrent/command.rb
CHANGED
@@ -1,31 +1,3 @@
|
|
1
|
-
# Copyright 2012 Georgios Gousios <gousiosg@gmail.com>
|
2
|
-
#
|
3
|
-
# Redistribution and use in source and binary forms, with or
|
4
|
-
# without modification, are permitted provided that the following
|
5
|
-
# conditions are met:
|
6
|
-
#
|
7
|
-
# 1. Redistributions of source code must retain the above
|
8
|
-
# copyright notice, this list of conditions and the following
|
9
|
-
# disclaimer.
|
10
|
-
#
|
11
|
-
# 2. Redistributions in binary form must reproduce the above
|
12
|
-
# copyright notice, this list of conditions and the following
|
13
|
-
# disclaimer in the documentation and/or other materials
|
14
|
-
# provided with the distribution.
|
15
|
-
#
|
16
|
-
# THIS SOFTWARE IS PROVIDED BY BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17
|
-
# AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
18
|
-
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19
|
-
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
|
20
|
-
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21
|
-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22
|
-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23
|
-
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24
|
-
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25
|
-
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26
|
-
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
-
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
-
|
29
1
|
require 'rubygems'
|
30
2
|
require 'trollop'
|
31
3
|
require 'daemons'
|
data/lib/ghtorrent/ghtorrent.rb
CHANGED
@@ -1,31 +1,3 @@
|
|
1
|
-
# Copyright 2012 Georgios Gousios <gousiosg@gmail.com>
|
2
|
-
#
|
3
|
-
# Redistribution and use in source and binary forms, with or
|
4
|
-
# without modification, are permitted provided that the following
|
5
|
-
# conditions are met:
|
6
|
-
#
|
7
|
-
# 1. Redistributions of source code must retain the above
|
8
|
-
# copyright notice, this list of conditions and the following
|
9
|
-
# disclaimer.
|
10
|
-
#
|
11
|
-
# 2. Redistributions in binary form must reproduce the above
|
12
|
-
# copyright notice, this list of conditions and the following
|
13
|
-
# disclaimer in the documentation and/or other materials
|
14
|
-
# provided with the distribution.
|
15
|
-
#
|
16
|
-
# THIS SOFTWARE IS PROVIDED BY BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17
|
-
# AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
18
|
-
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19
|
-
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
|
20
|
-
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21
|
-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22
|
-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23
|
-
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24
|
-
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25
|
-
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26
|
-
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
-
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
-
|
29
1
|
require 'sequel'
|
30
2
|
|
31
3
|
module GHTorrent
|
@@ -65,12 +37,7 @@ module GHTorrent
|
|
65
37
|
##
|
66
38
|
# Ensure that a user exists, or fetch its latest state from Github
|
67
39
|
# ==Parameters:
|
68
|
-
# user
|
69
|
-
# The email or login name to lookup the user by
|
70
|
-
#
|
71
|
-
# == Returns:
|
72
|
-
# If the user can be retrieved, it is returned as a Hash. Otherwise,
|
73
|
-
# the result is nil
|
40
|
+
# [user] The email or login name to lookup the user by
|
74
41
|
def get_commit(user, repo, sha)
|
75
42
|
|
76
43
|
unless sha.match(/[a-f0-9]{40}$/)
|
@@ -84,14 +51,71 @@ module GHTorrent
|
|
84
51
|
end
|
85
52
|
end
|
86
53
|
|
54
|
+
##
|
55
|
+
# Add a user as member to a project
|
56
|
+
# ==Parameters:
|
57
|
+
# [owner] The login of the repository owner
|
58
|
+
# [repo] The name of the repository
|
59
|
+
# [new_member] The login of the member to add
|
60
|
+
# [date_added] The timestamp that the add event took place
|
61
|
+
def get_project_member(owner, repo, new_member, date_added)
|
62
|
+
transaction do
|
63
|
+
ensure_repo(owner, repo)
|
64
|
+
ensure_project_member(owner, repo, new_member, date_added)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Add a commit comment to a commit
|
70
|
+
# ==Parameters:
|
71
|
+
# [user] The login of the repository owner
|
72
|
+
# [repo] The name of the repository
|
73
|
+
# [comment_id] The login of the member to add
|
74
|
+
# [date_added] The timestamp that the add event took place
|
75
|
+
def get_commit_comment(user, repo, comment_id, date_added)
|
76
|
+
transaction do
|
77
|
+
ensure_repo(user, repo)
|
78
|
+
ensure_commit_comment(user, repo, comment_id, date_added)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Add a watcher to a repository
|
84
|
+
# ==Parameters:
|
85
|
+
# [owner] The login of the repository owner
|
86
|
+
# [repo] The name of the repository
|
87
|
+
# [watcher] The login of the member to add
|
88
|
+
# [date_added] The timestamp that the add event took place
|
89
|
+
def get_watcher(owner, repo, watcher, date_added)
|
90
|
+
transaction do
|
91
|
+
ensure_repo(owner, repo)
|
92
|
+
ensure_watcher(owner, repo, watcher, date_added)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Add a follower to user
|
98
|
+
# ==Parameters:
|
99
|
+
# [follower] The login of the repository owner
|
100
|
+
# [followed] The name of the repository
|
101
|
+
# [date_added] The timestamp that the add event took place
|
102
|
+
def get_follower(follower, followed, date_added)
|
103
|
+
transaction do
|
104
|
+
ensure_user(follower, false, false)
|
105
|
+
ensure_user(followed, false, false)
|
106
|
+
ensure_user_followers(followed, date_added)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
87
110
|
##
|
88
111
|
# Make sure a commit exists
|
89
|
-
|
112
|
+
#
|
113
|
+
def ensure_commit(repo, sha, user, comments = true)
|
90
114
|
c = retrieve_commit(repo, sha, user)
|
91
|
-
store_commit(c, repo, user)
|
92
|
-
ensure_commit_comments(user, repo, sha)
|
115
|
+
stored = store_commit(c, repo, user)
|
93
116
|
ensure_parents(c)
|
94
|
-
|
117
|
+
ensure_commit_comments(user, repo, sha) if comments
|
118
|
+
stored
|
95
119
|
end
|
96
120
|
|
97
121
|
##
|
@@ -235,6 +259,7 @@ module GHTorrent
|
|
235
259
|
return u
|
236
260
|
end
|
237
261
|
|
262
|
+
|
238
263
|
##
|
239
264
|
# Ensure that a user exists, or fetch its latest state from Github
|
240
265
|
# ==Parameters:
|
@@ -258,19 +283,49 @@ module GHTorrent
|
|
258
283
|
end
|
259
284
|
end
|
260
285
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
286
|
+
if not email.nil?
|
287
|
+
# Check whether a user has been added by email before
|
288
|
+
byemail = users.first(:email => email)
|
289
|
+
unless byemail.nil?
|
290
|
+
users.filter(:email => email).update(:login => u['login'],
|
291
|
+
:name => u['name'],
|
292
|
+
:company => u['company'],
|
293
|
+
:hireable => boolean(u['hirable']),
|
294
|
+
:bio => u['bio'],
|
295
|
+
:location => u['location'],
|
296
|
+
:type => user_type(u['type']),
|
297
|
+
:created_at => date(u['created_at']),
|
298
|
+
:ext_ref_id => u[@ext_uniq]
|
299
|
+
)
|
300
|
+
info "GHTorrent: Updating user #{user} (email #{email})"
|
301
|
+
else
|
302
|
+
users.insert(:login => u['login'],
|
303
|
+
:name => u['name'],
|
304
|
+
:company => u['company'],
|
305
|
+
:email => email,
|
306
|
+
:hireable => boolean(u['hirable']),
|
307
|
+
:bio => u['bio'],
|
308
|
+
:location => u['location'],
|
309
|
+
:type => user_type(u['type']),
|
310
|
+
:created_at => date(u['created_at']),
|
311
|
+
:ext_ref_id => u[@ext_uniq])
|
312
|
+
|
313
|
+
info "GHTorrent: New user #{user}"
|
314
|
+
end
|
315
|
+
else
|
316
|
+
users.insert(:login => u['login'],
|
317
|
+
:name => u['name'],
|
318
|
+
:company => u['company'],
|
319
|
+
:email => email,
|
320
|
+
:hireable => boolean(u['hirable']),
|
321
|
+
:bio => u['bio'],
|
322
|
+
:location => u['location'],
|
323
|
+
:type => user_type(u['type']),
|
324
|
+
:created_at => date(u['created_at']),
|
325
|
+
:ext_ref_id => u[@ext_uniq])
|
273
326
|
|
327
|
+
info "GHTorrent: New user #{user}"
|
328
|
+
end
|
274
329
|
users.first(:login => user)
|
275
330
|
else
|
276
331
|
debug "GHTorrent: User #{user} exists"
|
@@ -285,34 +340,42 @@ module GHTorrent
|
|
285
340
|
#
|
286
341
|
# ==Parameters:
|
287
342
|
# [user] The user login to find followers by
|
288
|
-
def ensure_user_followers(user,
|
343
|
+
def ensure_user_followers(user, date_added = nil)
|
344
|
+
followers = @db[:followers]
|
345
|
+
userid = @db[:users].first(:login => user)[:id]
|
289
346
|
|
290
|
-
|
291
|
-
|
347
|
+
retrieved = retrieve_user_followers(user)
|
348
|
+
retrieved.each { |f|
|
292
349
|
follower = f['login']
|
293
350
|
ensure_user(user, false, false)
|
294
351
|
ensure_user(follower, false, false)
|
295
352
|
|
296
|
-
|
297
|
-
|
298
|
-
followers = @db[:followers]
|
353
|
+
followerid = @db[:users].first(:login => follower)[:id]
|
354
|
+
|
299
355
|
|
300
356
|
if followers.first(:user_id => userid, :follower_id => followerid).nil?
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
357
|
+
added = if date_added.nil? then Time.now else date_added end
|
358
|
+
followers.insert(:user_id => userid,
|
359
|
+
:follower_id => followerid,
|
360
|
+
:created_at => added,
|
361
|
+
:ext_ref_id => f[@ext_uniq]
|
305
362
|
)
|
306
363
|
info "GHTorrent: User #{follower} follows #{user}"
|
307
364
|
else
|
308
|
-
|
365
|
+
unless date_added.nil?
|
366
|
+
followers.filter(:user_id => userid,
|
367
|
+
:follower_id => followerid).\
|
368
|
+
update(:created_at => date(date_added))
|
369
|
+
info "GHTorrent: Updated follower #{follower} -> #{user}"
|
370
|
+
end
|
371
|
+
debug "GHTorrent: User #{follower} already follows #{user}"
|
309
372
|
end
|
310
373
|
}
|
311
374
|
end
|
312
375
|
|
313
376
|
##
|
314
377
|
# Try to retrieve a user by email. Search the DB first, fall back to
|
315
|
-
# Github API
|
378
|
+
# Github search API if unsuccessful.
|
316
379
|
#
|
317
380
|
# ==Parameters:
|
318
381
|
# [email] The email to lookup the user by
|
@@ -330,7 +393,7 @@ module GHTorrent
|
|
330
393
|
u = retrieve_user_byemail(email, name)
|
331
394
|
|
332
395
|
if u.nil? or u['user'].nil? or u['user']['login'].nil?
|
333
|
-
debug "GHTorrent: Cannot find #{email} through API
|
396
|
+
debug "GHTorrent: Cannot find #{email} through search API query"
|
334
397
|
users.insert(:email => email,
|
335
398
|
:name => name,
|
336
399
|
:login => (0...8).map { 65.+(rand(25)).chr }.join,
|
@@ -348,7 +411,7 @@ module GHTorrent
|
|
348
411
|
:location => u['user']['location'],
|
349
412
|
:created_at => date(u['user']['created_at']),
|
350
413
|
:ext_ref_id => u[@ext_uniq])
|
351
|
-
debug "GHTorrent: Found #{email} through API
|
414
|
+
debug "GHTorrent: Found #{email} through search API query"
|
352
415
|
users.first(:email => email)
|
353
416
|
end
|
354
417
|
else
|
@@ -371,7 +434,8 @@ module GHTorrent
|
|
371
434
|
|
372
435
|
ensure_user(user, true, true)
|
373
436
|
repos = @db[:projects]
|
374
|
-
|
437
|
+
curuser = @db[:users].first(:login => user)
|
438
|
+
currepo = repos.first(:owner_id => curuser[:id], :name => repo)
|
375
439
|
|
376
440
|
if currepo.nil?
|
377
441
|
r = retrieve_repo(user, repo)
|
@@ -385,13 +449,63 @@ module GHTorrent
|
|
385
449
|
|
386
450
|
info "GHTorrent: New repo #{repo}"
|
387
451
|
ensure_commits(user, repo)
|
388
|
-
|
452
|
+
ensure_project_members(user, repo)
|
453
|
+
ensure_watchers(user, repo)
|
454
|
+
repos.first(:owner_id => curuser[:id], :name => repo)
|
389
455
|
else
|
390
456
|
debug "GHTorrent: Repo #{repo} exists"
|
391
457
|
currepo
|
392
458
|
end
|
393
459
|
end
|
394
460
|
|
461
|
+
##
|
462
|
+
# Make sure that a project has all the registered members defined
|
463
|
+
def ensure_project_members(user, repo)
|
464
|
+
curuser = @db[:users].first(:login => user)
|
465
|
+
currepo = @db[:projects].first(:owner_id => curuser[:id], :name => repo)
|
466
|
+
project_members = @db[:project_members].filter(:user_id => curuser[:id],
|
467
|
+
:repo_id => currepo[:id])
|
468
|
+
|
469
|
+
retrieve_repo_collaborators(user, repo).reduce([]) do |acc, x|
|
470
|
+
if project_members.find { |y| y[:login] == x['login'] }.nil?
|
471
|
+
acc << x
|
472
|
+
else
|
473
|
+
acc
|
474
|
+
end
|
475
|
+
end.map { |x| ensure_project_member(user, repo, x['login'], nil) }
|
476
|
+
end
|
477
|
+
|
478
|
+
##
|
479
|
+
# Make sure that a project member exists in a project
|
480
|
+
def ensure_project_member(owner, repo, new_member, date_added)
|
481
|
+
pr_members = @db[:project_members]
|
482
|
+
new_user = ensure_user(new_member, false, false)
|
483
|
+
owner_id = @db[:users].first(:login => owner)[:id]
|
484
|
+
project = @db[:projects].first(:owner_id => owner_id, :name => repo)
|
485
|
+
|
486
|
+
memb_exist = pr_members.first(:user_id => new_user[:id],
|
487
|
+
:repo_id => project[:id])
|
488
|
+
|
489
|
+
if memb_exist.nil?
|
490
|
+
added = if date_added.nil? then Time.now else date_added end
|
491
|
+
retrieved = retrieve_repo_collaborator(owner, repo, new_member)
|
492
|
+
pr_members.insert(
|
493
|
+
:user_id => new_user[:id],
|
494
|
+
:repo_id => project[:id],
|
495
|
+
:created_at => date(added),
|
496
|
+
:ext_ref_id => retrieved[@ext_uniq]
|
497
|
+
)
|
498
|
+
info "GHTorrent: Added project member #{repo} -> #{new_member}"
|
499
|
+
else
|
500
|
+
unless date_added.nil?
|
501
|
+
pr_members.filter(:user_id => new_user[:id],
|
502
|
+
:repo_id => project[:id])\
|
503
|
+
.update(:created_at => date(date_added))
|
504
|
+
info "GHTorrent: Updating #{repo} -> #{new_member}"
|
505
|
+
end
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
395
509
|
##
|
396
510
|
# Make sure that the organizations the user participates into exist
|
397
511
|
#
|
@@ -404,7 +518,7 @@ module GHTorrent
|
|
404
518
|
end
|
405
519
|
|
406
520
|
##
|
407
|
-
# Make sure that a user
|
521
|
+
# Make sure that a user participates to the provided organization
|
408
522
|
#
|
409
523
|
# ==Parameters:
|
410
524
|
# [user] The login name of the user to check the organizations for
|
@@ -434,7 +548,7 @@ module GHTorrent
|
|
434
548
|
# Make sure that an organization exists
|
435
549
|
#
|
436
550
|
# ==Parameters:
|
437
|
-
# [
|
551
|
+
# [organization] The login name of the organization
|
438
552
|
#
|
439
553
|
def ensure_org(organization)
|
440
554
|
org = @db[:users].find(:login => organization, :type => 'org')
|
@@ -447,39 +561,28 @@ module GHTorrent
|
|
447
561
|
end
|
448
562
|
end
|
449
563
|
|
450
|
-
|
451
564
|
##
|
452
565
|
# Get all comments for a commit
|
453
566
|
#
|
454
567
|
# ==Parameters:
|
455
568
|
# [user] The login name of the organization
|
569
|
+
# [user] The repository containing the commit whose comments will be retrieved
|
570
|
+
# [sha] The commit sha to retrieve comments for
|
456
571
|
def ensure_commit_comments(user, repo, sha)
|
457
|
-
commit_id = @db[:commits].first(:sha => sha)
|
458
|
-
stored_comments = @db[:commit_comments].
|
459
|
-
|
460
|
-
user_id = @db[:users].first(:login => user)[:id]
|
572
|
+
commit_id = @db[:commits].first(:sha => sha)[:id]
|
573
|
+
stored_comments = @db[:commit_comments].filter(:commit_id => commit_id)
|
574
|
+
commit_comments = retrieve_commit_comments(user, repo, sha)
|
575
|
+
#user_id = @db[:users].first(:login => user)[:id]
|
461
576
|
|
462
|
-
not_saved =
|
463
|
-
if stored_comments.find{|y| y[:comment_id] == x['
|
577
|
+
not_saved = commit_comments.reduce([]) do |acc, x|
|
578
|
+
if stored_comments.find{|y| y[:comment_id] == x['id']}.nil?
|
464
579
|
acc << x
|
465
580
|
else
|
466
581
|
acc
|
467
582
|
end
|
468
583
|
end
|
469
584
|
|
470
|
-
not_saved.
|
471
|
-
@db[:commit_comments].insert(
|
472
|
-
:commit_id => commit_id,
|
473
|
-
:user_id => user_id,
|
474
|
-
:body => c['body'],
|
475
|
-
:line => c['line'],
|
476
|
-
:position => c['position'],
|
477
|
-
:comment_id => c['id'],
|
478
|
-
:ext_ref_id => c['ext_ref_id'],
|
479
|
-
:created_at => date(c['created_at'])
|
480
|
-
)
|
481
|
-
info "GHTorrent: Added commit comment #{sha} -> #{user}"
|
482
|
-
end
|
585
|
+
not_saved.map{|x| ensure_commit_comment(user, repo, x['id'], nil)}
|
483
586
|
end
|
484
587
|
|
485
588
|
##
|
@@ -487,12 +590,21 @@ module GHTorrent
|
|
487
590
|
#
|
488
591
|
# ==Parameters:
|
489
592
|
# [user] The login name of the organization
|
490
|
-
|
593
|
+
# [repo] The repository containing the commit whose comment will be retrieved
|
594
|
+
# [id] The comment id to retrieve
|
595
|
+
# [created_at] The timestamp that the comment was made.
|
596
|
+
def ensure_commit_comment(user, repo, id, created_at)
|
491
597
|
stored_comment = @db[:commit_comments].first(:comment_id => id)
|
492
598
|
|
493
599
|
if stored_comment.nil?
|
494
600
|
retrieved = retrieve_commit_comment(user, repo, id)
|
495
|
-
|
601
|
+
|
602
|
+
if retrieved.nil?
|
603
|
+
debug "GHTorrent: Commit comment #{id} deleted"
|
604
|
+
return
|
605
|
+
end
|
606
|
+
|
607
|
+
commit = ensure_commit(repo, retrieved['commit_id'], user, comments = false)
|
496
608
|
user = ensure_user(user, false, false)
|
497
609
|
@db[:commit_comments].insert(
|
498
610
|
:commit_id => commit[:id],
|
@@ -501,17 +613,66 @@ module GHTorrent
|
|
501
613
|
:line => retrieved['line'],
|
502
614
|
:position => retrieved['position'],
|
503
615
|
:comment_id => retrieved['id'],
|
504
|
-
:ext_ref_id => retrieved[
|
616
|
+
:ext_ref_id => retrieved[@ext_uniq],
|
505
617
|
:created_at => date(retrieved['created_at'])
|
506
618
|
)
|
619
|
+
info "GHTorrent: Added commit comment #{commit[:sha]} -> #{user[:login]}"
|
507
620
|
@db[:commit_comments].first(:comment_id => id)
|
508
|
-
info "GHTorrent: Added commit comment #{commit[:sha]} -> #{user}"
|
509
621
|
else
|
510
622
|
info "GHTorrent: Commit comment #{id} exists"
|
511
623
|
stored_comment
|
512
624
|
end
|
513
625
|
end
|
514
626
|
|
627
|
+
##
|
628
|
+
# Make sure that
|
629
|
+
def ensure_watchers(owner, repo)
|
630
|
+
curuser = @db[:users].first(:login => owner)
|
631
|
+
currepo = @db[:projects].first(:owner_id => curuser[:id],
|
632
|
+
:name => repo)
|
633
|
+
watchers = @db[:watchers].filter(:user_id => curuser[:id],
|
634
|
+
:repo_id => currepo[:id])
|
635
|
+
|
636
|
+
retrieve_watchers(owner, repo).reduce([]) do |acc, x|
|
637
|
+
if watchers.find { |y| y[:login] == x['login'] }.nil?
|
638
|
+
acc << x
|
639
|
+
else
|
640
|
+
acc
|
641
|
+
end
|
642
|
+
end.map { |x| ensure_watcher(owner, repo, x['login']) }
|
643
|
+
end
|
644
|
+
|
645
|
+
##
|
646
|
+
# Make sure that a project member exists in a project
|
647
|
+
def ensure_watcher(owner, repo, watcher, date_added = nil)
|
648
|
+
watchers = @db[:watchers]
|
649
|
+
new_watcher = ensure_user(watcher, false, false)
|
650
|
+
owner_id = @db[:users].first(:login => owner)[:id]
|
651
|
+
project = @db[:projects].first(:owner_id => owner_id, :name => repo)
|
652
|
+
|
653
|
+
memb_exist = watchers.first(:user_id => new_watcher[:id],
|
654
|
+
:repo_id => project[:id])
|
655
|
+
|
656
|
+
if memb_exist.nil?
|
657
|
+
added = if date_added.nil? then Time.now else date_added end
|
658
|
+
retrieved = retrieve_watcher(owner, repo, watcher)
|
659
|
+
watchers.insert(
|
660
|
+
:user_id => new_watcher[:id],
|
661
|
+
:repo_id => project[:id],
|
662
|
+
:created_at => date(added),
|
663
|
+
:ext_ref_id => retrieved[@ext_uniq]
|
664
|
+
)
|
665
|
+
info "GHTorrent: Added watcher #{repo} -> #{watcher}"
|
666
|
+
else
|
667
|
+
unless date_added.nil?
|
668
|
+
watchers.filter(:user_id => new_watcher[:id],
|
669
|
+
:repo_id => project[:id])\
|
670
|
+
.update(:created_at => date(date_added))
|
671
|
+
info "GHTorrent: Updating #{repo} -> #{watcher}"
|
672
|
+
end
|
673
|
+
end
|
674
|
+
end
|
675
|
+
|
515
676
|
private
|
516
677
|
|
517
678
|
# Store a commit contained in a hash. First check whether the commit exists.
|
@@ -523,7 +684,6 @@ module GHTorrent
|
|
523
684
|
author = commit_user(c['author'], c['commit']['author'])
|
524
685
|
commiter = commit_user(c['committer'], c['commit']['committer'])
|
525
686
|
|
526
|
-
|
527
687
|
userid = @db[:users].filter(:login => user).first[:id]
|
528
688
|
repoid = @db[:projects].filter(:owner_id => userid,
|
529
689
|
:name => repo).first[:id]
|
@@ -535,9 +695,11 @@ module GHTorrent
|
|
535
695
|
:created_at => date(c['commit']['author']['date']),
|
536
696
|
:ext_ref_id => c[@ext_uniq]
|
537
697
|
)
|
698
|
+
commits.first(:sha => c['sha'])
|
538
699
|
debug "GHTorrent: New commit #{repo} -> #{c['sha']} "
|
539
700
|
else
|
540
701
|
debug "GHTorrent: Commit #{repo} -> #{c['sha']} exists"
|
702
|
+
commit
|
541
703
|
end
|
542
704
|
end
|
543
705
|
|
@@ -569,7 +731,11 @@ module GHTorrent
|
|
569
731
|
# - yyyy-mm-ddThh:mm:ssZ
|
570
732
|
# - yyyy/mm/dd hh:mm:ss {+/-}hhmm
|
571
733
|
def date(arg)
|
572
|
-
Time
|
734
|
+
if arg.class != Time
|
735
|
+
Time.parse(arg)#.to_i
|
736
|
+
else
|
737
|
+
arg
|
738
|
+
end
|
573
739
|
end
|
574
740
|
|
575
741
|
def is_valid_email(email)
|