ghtorrent 0.3.1 → 0.4
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/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)
|