ghtorrent 0.6 → 0.7.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.
@@ -0,0 +1,31 @@
1
+ require 'sequel'
2
+
3
+ require 'ghtorrent/migrations/mysql_defaults'
4
+
5
+ Sequel.migration do
6
+ up do
7
+
8
+ puts "Adding column forked_from in table projects"
9
+ alter_table :projects do
10
+ add_foreign_key :forked_from, :projects, :null => true
11
+ end
12
+
13
+ puts "Migrating data from forks to project(forked_from)"
14
+ DB.transaction(:rollback => :reraise, :isolation => :committed) do
15
+ DB[:projects].each do |p|
16
+ fork = DB[:forks].first(:forked_project_id => p[:id])
17
+ unless fork.nil?
18
+ source = DB[:projects].first(:id => fork[:forked_from_id])
19
+ DB[:projects].filter(:id => p[:id]).update(:forked_from => source[:id])
20
+ puts "#{p[:owner_id]}/#{p[:name]} is forked from #{source[:owner_id]}/#{source[:name]}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ down do
27
+ alter_table :projects do
28
+ drop_column :forked_from
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,39 @@
1
+ require 'sequel'
2
+
3
+ require 'ghtorrent/migrations/mysql_defaults'
4
+
5
+ Sequel.migration do
6
+ up do
7
+
8
+ puts "Adding column merged in table pull_requests"
9
+ add_column :pull_requests, :merged, TrueClass, :null => false,
10
+ :default => false
11
+
12
+ puts "Updating pull_requests.merged"
13
+ DB.transaction(:rollback => :reraise, :isolation => :committed) do
14
+ DB << "update pull_requests pr
15
+ set pr.merged = true
16
+ where exists (select *
17
+ from pull_request_commits prc, project_commits pc
18
+ where prc.commit_id = pc.commit_id
19
+ and prc.pull_request_id = pr.id
20
+ and pc.project_id = pr.base_repo_id
21
+ and pr.base_repo_id <> pr.head_repo_id)"
22
+ DB << "update pull_requests pr
23
+ set pr.merged = true
24
+ where exists(
25
+ select prh.created_at
26
+ from pull_request_history prh
27
+ where prh.action='merged' and prh.pull_request_id=pr.id)"
28
+ end
29
+
30
+ puts "Correcting intra_branch field"
31
+ DB.transaction(:rollback => :reraise, :isolation => :committed) do
32
+ DB << "update pull_requests set intra_branch = true where base_repo_id = head_repo_id"
33
+ end
34
+ end
35
+
36
+ down do
37
+ drop_column :pull_requests, :merged
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ require 'sequel'
2
+
3
+ require 'ghtorrent/migrations/mysql_defaults'
4
+
5
+ Sequel.migration do
6
+ up do
7
+
8
+ puts 'Adding column deleted in table projects'
9
+ add_column :projects, :deleted, TrueClass, :null => false,
10
+ :default => false
11
+
12
+ puts 'Field deleted added'
13
+ puts 'Remember to run the fixes/update_deleted.rb script to mark deleted projects'
14
+ end
15
+
16
+ down do
17
+ alter_table :projects do
18
+ drop_column :deleted
19
+ end
20
+ end
21
+ end
@@ -1,4 +1,5 @@
1
1
  require 'uri'
2
+ require 'cgi'
2
3
 
3
4
  require 'ghtorrent/api_client'
4
5
  require 'ghtorrent/settings'
@@ -43,20 +44,46 @@ module GHTorrent
43
44
  end
44
45
 
45
46
  # Try Github user search by email. This is optional info, so
46
- # it may not return any data.
47
+ # it may not return any data. If this fails, try searching by name
47
48
  # http://developer.github.com/v3/search/#email-search
48
49
  def retrieve_user_byemail(email, name)
49
- url = ghurl("legacy/user/email/#{URI.escape(email)}")
50
- r = api_request(url)
50
+ url = ghurl("legacy/user/email/#{CGI.escape(email)}")
51
+ byemail = api_request(url)
51
52
 
52
- unless r.empty? or r['user']['login'].nil?
53
- info "Retriever: User #{r['user']['login']} retrieved by email #{email}"
54
- retrieve_user_byusername(r['user']['login'])
55
- else
56
- if r.empty?
53
+ if byemail.empty?
54
+ # Only search by name if name param looks like a proper name
55
+ byname = if not name.nil? and name.split(/ /).size > 1
56
+ url = ghurl("legacy/user/search/#{CGI.escape(name)}")
57
+ api_request(url)
58
+ end
59
+
60
+ if byname.nil? or byname['users'].nil? or byname['users'].empty?
57
61
  nil
58
62
  else
59
- u = r['user']
63
+ user = byname['users'].find do |u|
64
+ u['name'] == name and
65
+ not u['login'].nil? and
66
+ not retrieve_user_byusername(u['login']).nil?
67
+ end
68
+
69
+ unless user.nil?
70
+ # Make extra sure that if we got an email it matches that
71
+ # of the retrieved user
72
+ if not email.nil? and user['email'] == email
73
+ user
74
+ else
75
+ nil
76
+ end
77
+ else
78
+ nil
79
+ end
80
+ end
81
+ else
82
+ unless byemail['user']['login'].nil?
83
+ info "Retriever: User #{byemail['user']['login']} retrieved by email #{email}"
84
+ retrieve_user_byusername(byemail['user']['login'])
85
+ else
86
+ u = byemail['user']
60
87
  unq = persister.store(:users, u)
61
88
  u[ext_uniq] = unq
62
89
  what = user_type(u['type'])
@@ -264,13 +291,13 @@ module GHTorrent
264
291
  'login')
265
292
  end
266
293
 
267
- def retrieve_pull_requests(user, repo)
294
+ def retrieve_pull_requests(user, repo, refr = false)
268
295
  open = "repos/#{user}/#{repo}/pulls"
269
296
  closed = "repos/#{user}/#{repo}/pulls?state=closed"
270
297
  repo_bound_items(user, repo, :pull_requests,
271
298
  [open, closed],
272
299
  {'repo' => repo, 'owner' => user},
273
- 'number')
300
+ 'number', item = nil, refresh = refr)
274
301
  end
275
302
 
276
303
  def retrieve_pull_request(user, repo, pullreq_id)
@@ -298,15 +325,27 @@ module GHTorrent
298
325
  end
299
326
 
300
327
  def retrieve_pull_req_commits(user, repo, pullreq_id)
301
- is_intra_branch = Proc.new do |req|
302
- req['head']['repo'].nil?
328
+ def is_intra_branch(req)
329
+ return false if req['head'].nil? or req['head']['repo'].nil?
330
+ req['head']['repo']['owner']['login'] ==
331
+ req['base']['repo']['owner']['login'] and
332
+ req['head']['repo']['full_name'] == req['base']['repo']['full_name']
303
333
  end
304
334
 
305
335
  pull_req = retrieve_pull_request(user, repo, pullreq_id)
306
336
 
307
- unless is_intra_branch.call(pull_req)
308
- head_user = pull_req['head']['repo']['owner']['login']
309
- head_repo = pull_req['head']['repo']['name']
337
+ unless is_intra_branch(pull_req)
338
+
339
+ # Head repo has been deleted
340
+ unless pull_req['head']['repo'].nil?
341
+ head_user = pull_req['head']['repo']['owner']['login']
342
+ head_repo = pull_req['head']['repo']['name']
343
+ else
344
+ # Try to find the commits in the base repo, in case the pull req
345
+ # has been merged
346
+ head_user = pull_req['base']['repo']['owner']['login']
347
+ head_repo = pull_req['base']['repo']['name']
348
+ end
310
349
 
311
350
  commits = paged_api_request(ghurl "repos/#{user}/#{repo}/pulls/#{pullreq_id}/commits")
312
351
  commits.map { |x|
@@ -370,13 +409,13 @@ module GHTorrent
370
409
  end
371
410
  end
372
411
 
373
- def retrieve_issues(user, repo)
412
+ def retrieve_issues(user, repo, refr = false)
374
413
  open = "repos/#{user}/#{repo}/issues"
375
414
  closed = "repos/#{user}/#{repo}/issues?state=closed"
376
415
  repo_bound_items(user, repo, :issues,
377
416
  [open, closed],
378
417
  {'repo' => repo, 'owner' => user},
379
- 'number')
418
+ 'number', item = nil, refresh = refr)
380
419
  end
381
420
 
382
421
  def retrieve_issue(user, repo, issue_id)
@@ -512,7 +551,7 @@ module GHTorrent
512
551
  private
513
552
 
514
553
  def repo_bound_items(user, repo, entity, urls, selector, descriminator,
515
- item_id = nil)
554
+ item_id = nil, refresh = false)
516
555
 
517
556
  items = if urls.class == Array
518
557
  urls.map { |url| paged_api_request(ghurl url) }.flatten
@@ -524,14 +563,31 @@ module GHTorrent
524
563
  x['repo'] = repo
525
564
  x['owner'] = user
526
565
 
527
- exists = !repo_bound_instance(entity, selector,
528
- descriminator, x[descriminator]).empty?
566
+ instances = repo_bound_instance(entity, selector,
567
+ descriminator, x[descriminator])
568
+ exists = !instances.empty?
529
569
 
530
- if not exists
570
+ unless exists
531
571
  persister.store(entity, x)
532
572
  info "Retriever: Added #{entity} #{user}/#{repo} -> #{x[descriminator]}"
533
573
  else
534
- debug "Retriever: #{entity} #{user}/#{repo} -> #{x[descriminator]} exists"
574
+ if refresh
575
+ instances.each do |i|
576
+
577
+ id = if i[descriminator].to_i.to_s != i[descriminator]
578
+ i[descriminator] # item_id is int
579
+ else
580
+ i[descriminator].to_i # convert to int
581
+ end
582
+
583
+ instance_selector = selector.merge({descriminator => id})
584
+ persister.del(entity, instance_selector)
585
+ persister.store(entity, x)
586
+ debug "Retriever: Refreshing #{entity} #{user}/#{repo} -> #{x[descriminator]}"
587
+ end
588
+ else
589
+ debug "Retriever: #{entity} #{user}/#{repo} -> #{x[descriminator]} exists"
590
+ end
535
591
  end
536
592
  end
537
593
 
@@ -556,13 +612,22 @@ module GHTorrent
556
612
  def repo_bound_instance(entity, selector, descriminator, item_id)
557
613
 
558
614
  id = if item_id.to_i.to_s != item_id
559
- item_id # item_id is string
615
+ item_id # item_id is int
560
616
  else
561
617
  item_id.to_i # convert to int
562
618
  end
563
619
 
564
620
  instance_selector = selector.merge({descriminator => id})
565
- persister.find(entity, instance_selector)
621
+ result = persister.find(entity, instance_selector)
622
+ if result.empty?
623
+ # Try without type conversions. Useful when the descriminator type
624
+ # is string and an item_id that can be converted to int is passed.
625
+ # Having no types sucks occasionaly...
626
+ instance_selector = selector.merge({descriminator => item_id})
627
+ persister.find(entity, instance_selector)
628
+ else
629
+ result
630
+ end
566
631
  end
567
632
 
568
633
  def ghurl(path)
@@ -1,4 +1,5 @@
1
1
  require 'yaml'
2
+ require 'tmpdir'
2
3
 
3
4
  require 'ghtorrent/utils'
4
5
 
@@ -18,13 +19,12 @@ module GHTorrent
18
19
  :sql_url => "sql.url",
19
20
 
20
21
  :mirror_urlbase => "mirror.urlbase",
21
- :mirror_urlbase_v2 => "mirror.urlbase_v2",
22
- :mirror_reqrate => "mirror.reqrate",
23
22
  :mirror_pollevery => "mirror.pollevery",
24
23
  :mirror_persister => "mirror.persister",
25
24
  :mirror_commit_pages_new_repo => "mirror.commit_pages_new_repo",
26
-
25
+ :mirror_history_pages_back => "mirror.history_pages_back",
27
26
  :uniq_id => "mirror.uniq_id",
27
+ :user_agent => "mirror.user_agent",
28
28
 
29
29
  :cache_mode => "mirror.cache_mode",
30
30
  :cache_dir => "mirror.cache_dir",
@@ -38,8 +38,46 @@ module GHTorrent
38
38
  :attach_ip => "mirror.attach_ip"
39
39
  }
40
40
 
41
- def config(key)
42
- read_value(settings, CONFIGKEYS[key])
41
+ DEFAULTS = {
42
+ :amqp_host => "localhost",
43
+ :amqp_port => 5672,
44
+ :amqp_username => "github",
45
+ :amqp_password => "github",
46
+ :amqp_exchange => "github",
47
+ :amqp_prefetch => 1,
48
+
49
+ :sql_url => "sqlite://github.db",
50
+
51
+ :mirror_urlbase => "https://api.github.com/",
52
+ :mirror_pollevery => "mirror.pollevery",
53
+ :mirror_persister => "no-op",
54
+ :mirror_commit_pages_new_repo => 3,
55
+ :mirror_history_pages_back => 1,
56
+ :uniq_id => "ext_ref_id",
57
+ :user_agent => "ghtorrent",
58
+
59
+ :cache_mode => "dev",
60
+ :cache_dir => Dir::tmpdir + File::SEPARATOR + "ghtorrent",
61
+ :cache_stale_age => 604800,
62
+
63
+ :github_username => "foo",
64
+ :github_passwd => "bar",
65
+
66
+ :respect_api_ratelimit => "true",
67
+
68
+ :attach_ip => "0.0.0.0"
69
+ }
70
+
71
+ def config(key, use_default = true)
72
+ begin
73
+ read_value(settings, CONFIGKEYS[key])
74
+ rescue Exception => e
75
+ if use_default
76
+ DEFAULTS[key]
77
+ else
78
+ raise e
79
+ end
80
+ end
43
81
  end
44
82
 
45
83
  def merge(more_keys)
@@ -57,4 +95,4 @@ module GHTorrent
57
95
  end
58
96
 
59
97
  end
60
- end
98
+ end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module GHTorrent
2
2
 
3
- VERSION = '0.6'
3
+ VERSION = '0.7.1'
4
4
 
5
- end
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ghtorrent
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.6'
4
+ version: 0.7.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,136 +10,104 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-11-08 00:00:00.000000000 Z
13
+ date: 2013-05-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: amqp
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
- - - ! '>='
20
+ - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: '0.9'
22
+ version: 1.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  none: false
27
27
  requirements:
28
- - - ! '>='
28
+ - - ~>
29
29
  - !ruby/object:Gem::Version
30
- version: '0.9'
30
+ version: 1.0.0
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: mongo
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  none: false
35
35
  requirements:
36
- - - ! '>='
36
+ - - ~>
37
37
  - !ruby/object:Gem::Version
38
- version: '1.6'
38
+ version: 1.8.0
39
39
  type: :runtime
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
- - - ! '>='
44
+ - - ~>
45
45
  - !ruby/object:Gem::Version
46
- version: '1.6'
46
+ version: 1.8.0
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bson_ext
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
- - - ! '>='
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: '1.6'
54
+ version: 1.8.0
55
55
  type: :runtime
56
56
  prerelease: false
57
57
  version_requirements: !ruby/object:Gem::Requirement
58
58
  none: false
59
59
  requirements:
60
- - - ! '>='
60
+ - - ~>
61
61
  - !ruby/object:Gem::Version
62
- version: '1.6'
63
- - !ruby/object:Gem::Dependency
64
- name: json
65
- requirement: !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
68
- - - ! '>='
69
- - !ruby/object:Gem::Version
70
- version: '1.6'
71
- type: :runtime
72
- prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
- requirements:
76
- - - ! '>='
77
- - !ruby/object:Gem::Version
78
- version: '1.6'
62
+ version: 1.8.0
79
63
  - !ruby/object:Gem::Dependency
80
64
  name: trollop
81
65
  requirement: !ruby/object:Gem::Requirement
82
66
  none: false
83
67
  requirements:
84
- - - ! '>='
68
+ - - ~>
85
69
  - !ruby/object:Gem::Version
86
- version: '1.16'
70
+ version: 2.0.0
87
71
  type: :runtime
88
72
  prerelease: false
89
73
  version_requirements: !ruby/object:Gem::Requirement
90
74
  none: false
91
75
  requirements:
92
- - - ! '>='
76
+ - - ~>
93
77
  - !ruby/object:Gem::Version
94
- version: '1.16'
78
+ version: 2.0.0
95
79
  - !ruby/object:Gem::Dependency
96
80
  name: sequel
97
81
  requirement: !ruby/object:Gem::Requirement
98
82
  none: false
99
83
  requirements:
100
- - - ! '>='
101
- - !ruby/object:Gem::Version
102
- version: '3.35'
103
- type: :runtime
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- none: false
107
- requirements:
108
- - - ! '>='
109
- - !ruby/object:Gem::Version
110
- version: '3.35'
111
- - !ruby/object:Gem::Dependency
112
- name: sqlite3-ruby
113
- requirement: !ruby/object:Gem::Requirement
114
- none: false
115
- requirements:
116
- - - ! '>='
84
+ - - ~>
117
85
  - !ruby/object:Gem::Version
118
- version: 1.3.2
86
+ version: '3.47'
119
87
  type: :runtime
120
88
  prerelease: false
121
89
  version_requirements: !ruby/object:Gem::Requirement
122
90
  none: false
123
91
  requirements:
124
- - - ! '>='
92
+ - - ~>
125
93
  - !ruby/object:Gem::Version
126
- version: 1.3.2
94
+ version: '3.47'
127
95
  - !ruby/object:Gem::Dependency
128
96
  name: daemons
129
97
  requirement: !ruby/object:Gem::Requirement
130
98
  none: false
131
99
  requirements:
132
- - - ! '>='
100
+ - - ~>
133
101
  - !ruby/object:Gem::Version
134
- version: 1.1.8
102
+ version: 1.1.0
135
103
  type: :runtime
136
104
  prerelease: false
137
105
  version_requirements: !ruby/object:Gem::Requirement
138
106
  none: false
139
107
  requirements:
140
- - - ! '>='
108
+ - - ~>
141
109
  - !ruby/object:Gem::Version
142
- version: 1.1.8
110
+ version: 1.1.0
143
111
  description: ! "A library and a collection of associated programs\n to
144
112
  mirror and process Github data"
145
113
  email: gousiosg@gmail.com
@@ -150,6 +118,8 @@ executables:
150
118
  - ght-rm-dupl
151
119
  - ght-process-event
152
120
  - ght-get-more-commits
121
+ - ght-retrieve-repo
122
+ - ght-retrieve-user
153
123
  extensions: []
154
124
  extra_rdoc_files: []
155
125
  files:
@@ -165,6 +135,7 @@ files:
165
135
  - lib/ghtorrent/commands/ght_load.rb
166
136
  - lib/ghtorrent/commands/ght_mirror_events.rb
167
137
  - lib/ghtorrent/commands/ght_retrieve_repo.rb
138
+ - lib/ghtorrent/commands/ght_retrieve_user.rb
168
139
  - lib/ghtorrent/commands/ght_rm_dupl.rb
169
140
  - lib/ghtorrent/gh_torrent_exception.rb
170
141
  - lib/ghtorrent/ghtorrent.rb
@@ -181,6 +152,9 @@ files:
181
152
  - lib/ghtorrent/migrations/009_add_project_commit.rb
182
153
  - lib/ghtorrent/migrations/010_add_forks.rb
183
154
  - lib/ghtorrent/migrations/011_add_issues.rb
155
+ - lib/ghtorrent/migrations/012_add_forks_to_projects.rb
156
+ - lib/ghtorrent/migrations/013_add_merged_to_pullreqs.rb
157
+ - lib/ghtorrent/migrations/014_add_deleted_to_projects.rb
184
158
  - lib/ghtorrent/migrations/mysql_defaults.rb
185
159
  - lib/ghtorrent/persister.rb
186
160
  - lib/ghtorrent/retriever.rb
@@ -193,43 +167,37 @@ files:
193
167
  - bin/ght-get-more-commits
194
168
  - bin/ght-load
195
169
  - bin/ght-mirror-events
196
- - bin/ght-periodic-dump
197
170
  - bin/ght-process-event
198
171
  - bin/ght-retrieve-repo
172
+ - bin/ght-retrieve-user
199
173
  - bin/ght-rm-dupl
200
- - bin/ght-torrent-index
201
174
  - CHANGELOG
202
175
  - Gemfile
203
176
  - Gemfile.lock
204
177
  - LICENSE
205
178
  - Rakefile
206
179
  - README.md
207
- - test/callstack_test.rb
208
180
  homepage: https://github.com/gousiosg/github-mirror
209
181
  licenses: []
210
182
  post_install_message: !binary |-
211
- WxtbMzJtVmVyc2lvbiAwLjYbWzBtXSBTdXBwb3J0IHJldHJpZXZhbCBvZiBp
212
- c3N1ZXMsIGlzc3VlIGV2ZW50cyBhbmQgaXNzdWUgaGlzdG9yeQpbG1szMm1W
213
- ZXJzaW9uIDAuNhtbMG1dIFN1cHBvcnQgZm9yIHNldHRpbmcgdXNlcm5hbWUv
214
- cGFzc3dvcmQgZm9yIHBlcmZvcm1pbmcgcmVxdWVzdHMKWxtbMzJtVmVyc2lv
215
- biAwLjYbWzBtXSBSZXNwZWN0IGJ5IGRlZmF1bHQgR2l0aHViJ3MgeC1yYXRl
216
- bGltaXQtcmVtYWluaW5nIGhlYWRlcgpbG1szMm1WZXJzaW9uIDAuNhtbMG1d
217
- IFNlbGVjdGl2ZSBwcm9jZXNzaW5nIG9mIGV2ZW50cyBmb3IgdXNlci1zcGVj
218
- aWZpZWQgcmVwb3MKWxtbMzJtVmVyc2lvbiAwLjYbWzBtXSBOZXcgdG9vbCAo
219
- Z2h0LWdldC1tb3JlLWNvbW1pdHMpIHRvIHJldHJpZXZlIGFsbCBjb21taXRz
220
- IGZvciBhIHJlcG9zaXRvcnkKWxtbMzJtVmVyc2lvbiAwLjYbWzBtXSBOZXcg
221
- dG9vbCAoZ2h0LXByb2Nlc3MtZXZlbnRzKSB0byBwcm9jZXNzIGp1c3Qgb25l
222
- IGV2ZW50IGJ5IGlkClsbWzMybVZlcnNpb24gMC42G1swbV0gUmV0cmlldmUg
223
- MTAwIGl0ZW1zIGF0IG9uY2UgYnkgZGVmYXVsdCBvbiBtdWx0aXBhZ2UgcmVx
224
- dWVzdHMKWxtbMzJtVmVyc2lvbiAwLjYbWzBtXSBSZW5hbWUgd2F0Y2hlcnMg
225
- LT4gc3RhcmdhemVycywgYXMgcGVyIEdpdGh1YiBBUEkgY2hhbmdlClsbWzMy
226
- bVZlcnNpb24gMC42G1swbV0gRml4ZXMgdG8gYnVncyB0aGF0IHBlcm1pdHRl
227
- ZCBlZmZpY2llbnQgcHJvY2Vzc2luZyBvZiBtdWx0aXBhZ2UgcmVxdWVzdHMK
228
- WxtbMzJtVmVyc2lvbiAwLjYbWzBtXSBTZXZlcmFsIGZpeGVzIG9uIGhvdyBw
229
- dWxsIHJlcXVlc3RzIGFyZSBiZWluZyBwcm9jZXNzZWQKWxtbMzJtVmVyc2lv
230
- biAwLjYbWzBtXSBVc2VycyB3aXRoIGludmFsaWQgZ2l0IHNldHVwcyBhcmUg
231
- bm93IGFsbG93ZWQKWxtbMzJtVmVyc2lvbiAwLjYbWzBtXSBDb21wYXRpYmls
232
- aXR5IHdpdGggUnVieSAxLjggcmVzdG9yZWQK
183
+ WxtbMzJtVmVyc2lvbiAwLjcbWzBtXSBGdWxsIHN1cHBvcnQgZm9yIGlzc3Vl
184
+ cyAoY29tbWVudHMsIGxhYmVscyBldGMpIGFuZCBwdWxsIHJlcXVlc3RzClsb
185
+ WzMybVZlcnNpb24gMC43G1swbV0gQ2xlYW5lZCB1cCByZXRyaWV2YWwgb2Yg
186
+ cHVsbCByZXF1ZXN0IGNvbW1pdHMKWxtbMzJtVmVyc2lvbiAwLjcbWzBtXSBD
187
+ bGVhbmVkIHVwIGFzc29jaWF0aW9uIG9mIGNvbW1pdHMgd2l0aCByZXBvc2l0
188
+ b3JpZXMuClsbWzMybVZlcnNpb24gMC43G1swbV0gUmVtb3ZlZCB0aGUgZm9y
189
+ a3MgdGFibGUuIEZvcmtzIGFyZSBub3cgdHJhY2tlZCBieSB0aGUgZm9ya2Vk
190
+ X2Zyb20gZmllbGQgaW4gcHJvamVjdHMKWxtbMzJtVmVyc2lvbiAwLjcbWzBt
191
+ XSBVc2UgR2l0aHViJ3MgSFRUUCBoZWFkZXJzIGZvciByZXF1ZXN0IHRocm90
192
+ dGxpbmcKWxtbMzJtVmVyc2lvbiAwLjcbWzBtXSBTdXBwb3J0IGZvciBzZXR0
193
+ aW5nIHVzZXIgYWdlbnQgaGVhZGVyIGFzIHBlciBHaXRodWIgQVBJIHJlcXVp
194
+ cmVtZW50cwpbG1szMm1WZXJzaW9uIDAuNxtbMG1dIFN1cHBvcnQgZm9yIG1h
195
+ cmtpbmcgcHJvamVjdHMgYXMgZGVsZXRlZCAocnVuIGZpeGVzL3VwZGF0ZV9k
196
+ ZWxldGVkLnJiKQpbG1szMm1WZXJzaW9uIDAuNxtbMG1dIE5ldyB0b29sIChn
197
+ aHQtcmV0cmlldmUtdXNlcikgdG8gcmV0cmlldmUgYWxsIGRhdGEgZm9yIGEg
198
+ c2luZ2xlIHVzZXIgClsbWzMybVZlcnNpb24gMC43G1swbV0gU3VwcG9ydCBm
199
+ b3IgcnVubmluZyB3aXRob3V0IGEgY29uZmlnLnlhbWwgZmlsZQpbG1szMm1W
200
+ ZXJzaW9uIDAuNxtbMG1dIFRlY2huaWNhbCByZXBvcnQgaW4gZG9jLwo=
233
201
  rdoc_options:
234
202
  - --charset=UTF-8
235
203
  require_paths:
@@ -248,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
248
216
  version: '0'
249
217
  requirements: []
250
218
  rubyforge_project:
251
- rubygems_version: 1.8.24
219
+ rubygems_version: 1.8.25
252
220
  signing_key:
253
221
  specification_version: 3
254
222
  summary: Mirror and process Github data