ghtorrent 0.6 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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