govkit-ca 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +44 -0
- data/Rakefile +9 -0
- data/USAGE +1 -0
- data/govkit-ca.gemspec +27 -0
- data/lib/data/rid_to_edid.yml +309 -0
- data/lib/gov_kit-ca.rb +18 -0
- data/lib/gov_kit-ca/postal_code.rb +68 -0
- data/lib/gov_kit-ca/postal_code/strategy.rb +45 -0
- data/lib/gov_kit-ca/postal_code/strategy/base.rb +45 -0
- data/lib/gov_kit-ca/postal_code/strategy/cbc-ca.rb +46 -0
- data/lib/gov_kit-ca/postal_code/strategy/conservative-ca.rb +29 -0
- data/lib/gov_kit-ca/postal_code/strategy/digital_copyright-ca.rb +27 -0
- data/lib/gov_kit-ca/postal_code/strategy/elections-ca.rb +30 -0
- data/lib/gov_kit-ca/postal_code/strategy/liberal-ca.rb +27 -0
- data/lib/gov_kit-ca/postal_code/strategy/ndp-ca.rb +29 -0
- data/lib/gov_kit-ca/postal_code/strategy/parl-gc-ca.rb +29 -0
- data/lib/gov_kit-ca/version.rb +5 -0
- data/lib/govkit-ca.rb +1 -0
- data/spec/postal_code_spec.rb +3 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +3 -0
- data/tasks/rid_to_edid.rb +136 -0
- metadata +148 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 James McKinney
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# GovKit-CA
|
2
|
+
|
3
|
+
GovKit-CA is a Ruby gem that provides easy access to Canadian civic data around the web. It currently provides an API for free postal code to electoral district lookups, using the following sources:
|
4
|
+
|
5
|
+
* [elections.ca](http://elections.ca/)
|
6
|
+
* [cbc.ca](http://www.cbc.ca/)
|
7
|
+
* [ndp.ca](http://www.ndp.ca/)
|
8
|
+
* [digital-copyright.ca](http://www.digital-copyright.ca/)
|
9
|
+
* [liberal.ca](http://www.liberal.ca/)
|
10
|
+
|
11
|
+
GovKit-CA follows from [Participatory Politics Foundation](http://www.participatorypolitics.org/)'s [GovKit](https://github.com/opengovernment/govkit) gem. GovKit-CA is not affiliated with the Participatory Politics Foundation or GovKit.
|
12
|
+
|
13
|
+
# Installation
|
14
|
+
|
15
|
+
gem install govkit
|
16
|
+
|
17
|
+
# Examples
|
18
|
+
|
19
|
+
>> require 'govkit-ca'
|
20
|
+
|
21
|
+
>> GovKit::CA::PostalCode.find_electoral_districts_by_postal_code('A1A1A1')
|
22
|
+
=> [10007]
|
23
|
+
>> GovKit::CA::PostalCode.find_electoral_districts_by_postal_code('K0A1K0')
|
24
|
+
=> [35087, 35025, 35052, 35012, 35040, 35063, 35064]
|
25
|
+
|
26
|
+
>> GovKit::CA::PostalCode.find_province_by_postal_code('A1A1A1')
|
27
|
+
=> "Newfoundland and Labrador"
|
28
|
+
>> GovKit::CA::PostalCode.find_province_by_postal_code('K0A1K0')
|
29
|
+
=> "Ontario"
|
30
|
+
|
31
|
+
Postal codes may contain lowercase letters. Spaces and non-alphanumeric characters are removed before processing.
|
32
|
+
|
33
|
+
GovKit-CA will raise GovKit::CA::ResourceNotFound if the electoral districts within a postal code cannot be determined.
|
34
|
+
|
35
|
+
# Bugs? Questions?
|
36
|
+
|
37
|
+
Govkit-CA's main repository is on GitHub: [http://github.com/jpmckinney/govkit-ca](http://github.com/jpmckinney/govkit-ca), where your contributions, forks, bug reports, feature requests, and feedback are greatly welcomed.
|
38
|
+
|
39
|
+
# TODOs
|
40
|
+
|
41
|
+
* Write tests
|
42
|
+
* Add a `ElectoralDistrict` class to convert IDs to English and french names.
|
43
|
+
|
44
|
+
Copyright (c) 2011 James McKinney, released under the MIT license
|
data/Rakefile
ADDED
data/USAGE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
See README.md for full usage details.
|
data/govkit-ca.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "gov_kit-ca/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "govkit-ca"
|
7
|
+
s.version = GovKit::CA::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["James McKinney"]
|
10
|
+
s.email = ["james@slashpoundbang.com"]
|
11
|
+
s.homepage = "http://github.com/jpmckinney/govkit-ca"
|
12
|
+
s.summary = %q{Easy access to Canadian civic data around the web}
|
13
|
+
s.description = %q{GovKit-CA lets you quickly get encapsulated Ruby objects for Canadian civic data.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "govkit-ca"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
#s.add_runtime_dependency('graticule', '>= 0.2.8')
|
23
|
+
s.add_runtime_dependency('httparty', '>= 0.6.1')
|
24
|
+
s.add_runtime_dependency('nokogiri', '>= 1.4.4')
|
25
|
+
s.add_runtime_dependency('yajl-ruby', '>= 0.7.8')
|
26
|
+
s.add_development_dependency('rspec', '>= 2')
|
27
|
+
end
|
@@ -0,0 +1,309 @@
|
|
1
|
+
---
|
2
|
+
1: 10001
|
3
|
+
2: 10002
|
4
|
+
3: 10003
|
5
|
+
4: 10004
|
6
|
+
5: 10005
|
7
|
+
6: 10006
|
8
|
+
7: 10007
|
9
|
+
8: 11001
|
10
|
+
9: 11002
|
11
|
+
10: 11003
|
12
|
+
11: 11004
|
13
|
+
12: 12001
|
14
|
+
13: 12002
|
15
|
+
14: 12007
|
16
|
+
15: 12003
|
17
|
+
16: 12004
|
18
|
+
17: 12005
|
19
|
+
18: 12006
|
20
|
+
19: 12008
|
21
|
+
20: 12009
|
22
|
+
21: 12010
|
23
|
+
22: 12011
|
24
|
+
23: 13001
|
25
|
+
24: 13002
|
26
|
+
25: 13003
|
27
|
+
26: 13004
|
28
|
+
27: 13005
|
29
|
+
28: 13006
|
30
|
+
29: 13007
|
31
|
+
30: 13008
|
32
|
+
31: 13009
|
33
|
+
32: 13010
|
34
|
+
33: 24046
|
35
|
+
34: 24001
|
36
|
+
35: 24002
|
37
|
+
36: 24003
|
38
|
+
37: 24004
|
39
|
+
38: 24054
|
40
|
+
39: 24005
|
41
|
+
40: 24006
|
42
|
+
41: 24007
|
43
|
+
42: 24008
|
44
|
+
43: 24009
|
45
|
+
44: 24010
|
46
|
+
45: 24011
|
47
|
+
46: 24012
|
48
|
+
47: 24013
|
49
|
+
48: 24015
|
50
|
+
49: 24016
|
51
|
+
50: 24017
|
52
|
+
51: 24018
|
53
|
+
52: 24019
|
54
|
+
53: 24020
|
55
|
+
54: 24041
|
56
|
+
55: 24021
|
57
|
+
56: 24022
|
58
|
+
57: 24023
|
59
|
+
58: 24024
|
60
|
+
59: 24025
|
61
|
+
60: 24026
|
62
|
+
61: 24027
|
63
|
+
62: 24028
|
64
|
+
63: 24029
|
65
|
+
64: 24030
|
66
|
+
65: 24031
|
67
|
+
66: 24032
|
68
|
+
67: 24033
|
69
|
+
68: 24034
|
70
|
+
69: 24035
|
71
|
+
70: 24036
|
72
|
+
71: 24037
|
73
|
+
72: 24038
|
74
|
+
73: 24039
|
75
|
+
74: 24040
|
76
|
+
75: 24042
|
77
|
+
76: 24043
|
78
|
+
77: 24058
|
79
|
+
78: 24014
|
80
|
+
79: 24044
|
81
|
+
80: 24045
|
82
|
+
81: 24047
|
83
|
+
82: 24048
|
84
|
+
83: 24049
|
85
|
+
84: 24050
|
86
|
+
85: 24051
|
87
|
+
86: 24052
|
88
|
+
87: 24053
|
89
|
+
88: 24055
|
90
|
+
89: 24056
|
91
|
+
90: 24057
|
92
|
+
91: 24059
|
93
|
+
92: 24060
|
94
|
+
93: 24061
|
95
|
+
94: 24062
|
96
|
+
95: 24063
|
97
|
+
96: 24064
|
98
|
+
97: 24065
|
99
|
+
98: 24066
|
100
|
+
99: 24067
|
101
|
+
100: 24068
|
102
|
+
101: 24069
|
103
|
+
102: 24070
|
104
|
+
103: 24071
|
105
|
+
104: 24072
|
106
|
+
105: 24073
|
107
|
+
106: 24074
|
108
|
+
107: 24075
|
109
|
+
108: 35001
|
110
|
+
109: 35002
|
111
|
+
110: 35003
|
112
|
+
111: 35004
|
113
|
+
112: 35005
|
114
|
+
113: 35006
|
115
|
+
114: 35007
|
116
|
+
115: 35008
|
117
|
+
116: 35009
|
118
|
+
117: 35026
|
119
|
+
118: 35010
|
120
|
+
119: 35011
|
121
|
+
120: 35012
|
122
|
+
121: 35013
|
123
|
+
122: 35015
|
124
|
+
123: 35016
|
125
|
+
124: 35017
|
126
|
+
125: 35018
|
127
|
+
126: 35014
|
128
|
+
127: 35019
|
129
|
+
128: 35020
|
130
|
+
129: 35021
|
131
|
+
130: 35022
|
132
|
+
131: 35023
|
133
|
+
132: 35024
|
134
|
+
133: 35025
|
135
|
+
134: 35027
|
136
|
+
135: 35028
|
137
|
+
136: 35029
|
138
|
+
137: 35030
|
139
|
+
138: 35031
|
140
|
+
139: 35032
|
141
|
+
140: 35033
|
142
|
+
141: 35034
|
143
|
+
142: 35035
|
144
|
+
143: 35036
|
145
|
+
144: 35037
|
146
|
+
145: 35038
|
147
|
+
146: 35039
|
148
|
+
147: 35046
|
149
|
+
148: 35040
|
150
|
+
149: 35041
|
151
|
+
150: 35042
|
152
|
+
151: 35043
|
153
|
+
152: 35044
|
154
|
+
153: 35045
|
155
|
+
154: 35047
|
156
|
+
155: 35048
|
157
|
+
156: 35049
|
158
|
+
157: 35050
|
159
|
+
158: 35051
|
160
|
+
159: 35052
|
161
|
+
160: 35053
|
162
|
+
161: 35054
|
163
|
+
162: 35055
|
164
|
+
163: 35056
|
165
|
+
164: 35057
|
166
|
+
165: 35058
|
167
|
+
166: 35059
|
168
|
+
167: 35060
|
169
|
+
168: 35061
|
170
|
+
169: 35062
|
171
|
+
170: 35063
|
172
|
+
171: 35064
|
173
|
+
172: 35065
|
174
|
+
173: 35066
|
175
|
+
174: 35067
|
176
|
+
175: 35068
|
177
|
+
176: 35069
|
178
|
+
177: 35070
|
179
|
+
178: 35071
|
180
|
+
179: 35072
|
181
|
+
180: 35073
|
182
|
+
181: 35074
|
183
|
+
182: 35075
|
184
|
+
183: 35076
|
185
|
+
184: 35077
|
186
|
+
185: 35078
|
187
|
+
186: 35079
|
188
|
+
187: 35080
|
189
|
+
188: 35081
|
190
|
+
189: 35082
|
191
|
+
190: 35083
|
192
|
+
191: 35084
|
193
|
+
192: 35085
|
194
|
+
193: 35086
|
195
|
+
194: 35087
|
196
|
+
195: 35088
|
197
|
+
196: 35089
|
198
|
+
197: 35090
|
199
|
+
198: 35091
|
200
|
+
199: 35092
|
201
|
+
200: 35093
|
202
|
+
201: 35094
|
203
|
+
202: 35095
|
204
|
+
203: 35096
|
205
|
+
204: 35097
|
206
|
+
205: 35098
|
207
|
+
206: 35099
|
208
|
+
207: 35100
|
209
|
+
208: 35101
|
210
|
+
209: 35102
|
211
|
+
210: 35103
|
212
|
+
211: 35104
|
213
|
+
212: 35105
|
214
|
+
213: 35106
|
215
|
+
214: 46001
|
216
|
+
215: 46002
|
217
|
+
216: 46003
|
218
|
+
217: 46004
|
219
|
+
218: 46005
|
220
|
+
219: 46006
|
221
|
+
220: 46007
|
222
|
+
221: 46008
|
223
|
+
222: 46009
|
224
|
+
223: 46010
|
225
|
+
224: 46011
|
226
|
+
225: 46012
|
227
|
+
226: 46013
|
228
|
+
227: 46014
|
229
|
+
228: 47001
|
230
|
+
229: 47002
|
231
|
+
230: 47004
|
232
|
+
231: 47003
|
233
|
+
232: 47005
|
234
|
+
233: 47006
|
235
|
+
234: 47007
|
236
|
+
235: 47008
|
237
|
+
236: 47009
|
238
|
+
237: 47010
|
239
|
+
238: 47011
|
240
|
+
239: 47012
|
241
|
+
240: 47013
|
242
|
+
241: 47014
|
243
|
+
242: 48006
|
244
|
+
243: 48003
|
245
|
+
244: 48002
|
246
|
+
245: 48004
|
247
|
+
246: 48005
|
248
|
+
247: 48007
|
249
|
+
248: 48008
|
250
|
+
249: 48009
|
251
|
+
250: 48010
|
252
|
+
251: 48012
|
253
|
+
252: 48013
|
254
|
+
253: 48014
|
255
|
+
254: 48011
|
256
|
+
255: 48015
|
257
|
+
256: 48016
|
258
|
+
257: 48017
|
259
|
+
258: 48018
|
260
|
+
259: 48001
|
261
|
+
260: 48019
|
262
|
+
261: 48020
|
263
|
+
262: 48021
|
264
|
+
263: 48022
|
265
|
+
264: 48023
|
266
|
+
265: 48024
|
267
|
+
266: 48025
|
268
|
+
267: 48026
|
269
|
+
268: 48027
|
270
|
+
269: 48028
|
271
|
+
270: 59001
|
272
|
+
271: 59026
|
273
|
+
272: 59002
|
274
|
+
273: 59003
|
275
|
+
274: 59004
|
276
|
+
275: 59005
|
277
|
+
276: 59006
|
278
|
+
277: 59008
|
279
|
+
278: 59009
|
280
|
+
279: 59010
|
281
|
+
280: 59011
|
282
|
+
281: 59012
|
283
|
+
282: 59013
|
284
|
+
283: 59014
|
285
|
+
284: 59015
|
286
|
+
285: 59016
|
287
|
+
286: 59017
|
288
|
+
287: 59019
|
289
|
+
288: 59020
|
290
|
+
289: 59018
|
291
|
+
290: 59007
|
292
|
+
291: 59021
|
293
|
+
292: 59022
|
294
|
+
293: 59023
|
295
|
+
294: 59024
|
296
|
+
295: 59025
|
297
|
+
296: 59027
|
298
|
+
297: 59028
|
299
|
+
298: 59029
|
300
|
+
299: 59030
|
301
|
+
300: 59031
|
302
|
+
301: 59032
|
303
|
+
302: 59033
|
304
|
+
303: 59034
|
305
|
+
304: 59035
|
306
|
+
305: 59036
|
307
|
+
306: 60001
|
308
|
+
307: 61001
|
309
|
+
308: 62001
|
data/lib/gov_kit-ca.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
#require 'graticule'
|
7
|
+
require 'httparty'
|
8
|
+
require 'nokogiri'
|
9
|
+
require 'yajl'
|
10
|
+
|
11
|
+
module GovKit
|
12
|
+
module CA
|
13
|
+
autoload :PostalCode, 'gov_kit-ca/postal_code'
|
14
|
+
|
15
|
+
class GovKitError < StandardError; end
|
16
|
+
class ResourceNotFound < GovKitError; end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'gov_kit-ca/postal_code/strategy'
|
2
|
+
|
3
|
+
module GovKit
|
4
|
+
module CA
|
5
|
+
# A collection of postal code helpers.
|
6
|
+
# @see http://en.wikipedia.org/wiki/Postal_codes_in_Canada Postal codes in Canada
|
7
|
+
module PostalCode
|
8
|
+
# Returns the electoral districts within a postal code.
|
9
|
+
#
|
10
|
+
# Statistics Canada charges for its Postal Codes by Federal Ridings File
|
11
|
+
# (PCFRF). A free alternative requires scraping data from other sources.
|
12
|
+
#
|
13
|
+
# @param [String] postal_code a postal code
|
14
|
+
# @return [Array<Fixnum>] the electoral districts within the postal code
|
15
|
+
# @raise [ResourceNotFound] if the electoral districts cannot be determined
|
16
|
+
# @see http://www.statcan.gc.ca/bsolc/olc-cel/olc-cel?lang=eng&catno=92F0193X Statistics Canada's product page for the Postal Codes by Federal Ridings File (PCFRF)
|
17
|
+
def self.find_electoral_districts_by_postal_code(postal_code)
|
18
|
+
StrategySet.run format_postal_code(postal_code)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the province that a postal code belongs to.
|
22
|
+
# @param [String] postal_code a postal code
|
23
|
+
# @return [String] the province that the postal code belongs to
|
24
|
+
# @raise [ResourceNotFound] if the province cannot be determined
|
25
|
+
# @see http://en.wikipedia.org/wiki/List_of_postal_codes_in_Canada List of postal codes in Canada
|
26
|
+
def self.find_province_by_postal_code(postal_code)
|
27
|
+
case format_postal_code(postal_code)
|
28
|
+
when /\AA/
|
29
|
+
'Newfoundland and Labrador'
|
30
|
+
when /\AB/
|
31
|
+
'Nova Scotia'
|
32
|
+
when /\AC/
|
33
|
+
'Prince Edward Island'
|
34
|
+
when /\AE/
|
35
|
+
'New Brunswick'
|
36
|
+
when /\A[GHJ]/
|
37
|
+
'Quebec'
|
38
|
+
when /\A[KLMNP]/
|
39
|
+
'Ontario'
|
40
|
+
when /\AR/
|
41
|
+
'Manitoba'
|
42
|
+
when /\AS/
|
43
|
+
'Saskatchewan'
|
44
|
+
when /\AT/
|
45
|
+
'Alberta'
|
46
|
+
when /\AV/
|
47
|
+
'British Columbia'
|
48
|
+
# http://en.wikipedia.org/wiki/List_of_X_postal_codes_of_Canada
|
49
|
+
when /\AX0[ABC]/
|
50
|
+
'Nunavut'
|
51
|
+
when /\AX0[EG]/, /\AX1A/
|
52
|
+
'Northwest Territories'
|
53
|
+
when /\AY/
|
54
|
+
'Yukon'
|
55
|
+
else
|
56
|
+
raise ResourceNotFound, "The province cannot be determined from the postal code"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Formats a postal code as A1A1A1. Removes non-alphanumeric characters.
|
61
|
+
# @param [String] postal_code a postal code
|
62
|
+
# @return [String] a formatted postal code
|
63
|
+
def self.format_postal_code(postal_code)
|
64
|
+
postal_code.upcase.gsub(/[^A-Z0-9]/, '')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
# The set of postal code to electoral district strategies.
|
5
|
+
class StrategySet
|
6
|
+
# Stores the strategy set.
|
7
|
+
# @return [Array<Strategy::Base>] the strategy set
|
8
|
+
def self.strategies
|
9
|
+
@@strategies ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
# Adds a strategy to the strategy set.
|
13
|
+
# @param [Strategy::Base] strategy a strategy
|
14
|
+
# @return [Array<Strategy::Base>] the strategy set
|
15
|
+
def self.register(strategy)
|
16
|
+
strategies << strategy
|
17
|
+
end
|
18
|
+
|
19
|
+
# Runs through the strategies in order of registration. Returns the
|
20
|
+
# output of the first strategy to successfully determine electoral
|
21
|
+
# districts from a postal code.
|
22
|
+
# @param [String] postal_code a postal code
|
23
|
+
# @return [Array<Fixnum>] the electoral districts within the postal code
|
24
|
+
# @raise [ResourceNotFound] if no strategy succeeds
|
25
|
+
def self.run(postal_code)
|
26
|
+
strategies.each do |strategy|
|
27
|
+
electoral_districts = strategy.new(postal_code).electoral_districts
|
28
|
+
return electoral_districts if electoral_districts
|
29
|
+
end
|
30
|
+
|
31
|
+
raise ResourceNotFound
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
require 'gov_kit-ca/postal_code/strategy/base'
|
39
|
+
require 'gov_kit-ca/postal_code/strategy/elections-ca'
|
40
|
+
require 'gov_kit-ca/postal_code/strategy/cbc-ca'
|
41
|
+
require 'gov_kit-ca/postal_code/strategy/ndp-ca'
|
42
|
+
require 'gov_kit-ca/postal_code/strategy/digital_copyright-ca'
|
43
|
+
require 'gov_kit-ca/postal_code/strategy/liberal-ca'
|
44
|
+
#require 'gov_kit-ca/postal_code/strategy/parl-gc-ca'
|
45
|
+
#require 'gov_kit-ca/postal_code/strategy/conservative-ca'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# Abstract class for implementing postal code to electoral district
|
6
|
+
# strategies.
|
7
|
+
#
|
8
|
+
# The following methods must be implemented in sub-classes:
|
9
|
+
#
|
10
|
+
# * `electoral_districts!`
|
11
|
+
class Base
|
12
|
+
include HTTParty
|
13
|
+
follow_redirects false
|
14
|
+
headers 'User-Agent' => 'GovKit-CA +http://govkit.org'
|
15
|
+
|
16
|
+
# Creates a new postal code to electoral district strategy.
|
17
|
+
# @param [String] postal_code a postal code
|
18
|
+
def initialize(postal_code)
|
19
|
+
@postal_code = postal_code
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the electoral districts within a postal code.
|
23
|
+
# @return [Array<Fixnum>] the electoral districts within the postal code
|
24
|
+
def electoral_districts
|
25
|
+
valid? && electoral_districts!.map(&:to_i)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Returns the electoral districts within a postal code, without
|
31
|
+
# passing validation first.
|
32
|
+
# @return [Array<Fixnum>] the electoral districts within the postal code
|
33
|
+
def electoral_districts!
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Boolean] whether the electoral districts can be determined
|
38
|
+
def valid?
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# cbc.ca ought to be a reliable source. It is unknown if its database
|
6
|
+
# is kept up-to-date between elections, however.
|
7
|
+
# @see https://github.com/danielharan/pc_scraper
|
8
|
+
class CbcCa < Base
|
9
|
+
base_uri 'www.cbc.ca'
|
10
|
+
|
11
|
+
def initialize(postal_code)
|
12
|
+
@fsa, @letter, @ldu = postal_code.downcase.match(/\A((.).{2})(.{3})\Z/)[1..3]
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def json_response # Yajl barfs on bad encoding
|
17
|
+
Yajl::Parser.parse(response.parsed_response) rescue JSON.parse(response.parsed_response)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def electoral_districts!
|
23
|
+
json_response.map{|x| self.class.rid_to_edid[x['rid']]}
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid?
|
27
|
+
!!response.headers['expires']
|
28
|
+
end
|
29
|
+
|
30
|
+
def response
|
31
|
+
@response ||= self.class.get "/news/canadavotes/myriding/postalcodes/#{@letter}/#{@fsa}/#{@ldu}.html"
|
32
|
+
end
|
33
|
+
|
34
|
+
# cbc.ca uses an internal riding ID, which must be matched to a
|
35
|
+
# canonical electoral district ID.
|
36
|
+
# @return [Hash] a map of cbc.ca riding ID to electoral district ID
|
37
|
+
def self.rid_to_edid
|
38
|
+
@@yml ||= YAML.load_file(File.expand_path('../../../../data/rid_to_edid.yml', __FILE__))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
StrategySet.register CbcCa
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# conservative.ca seems unreliable. In the case of B0J2L0, for example,
|
6
|
+
# it does not return three ridings like other sources.
|
7
|
+
class ConservativeCa < Base
|
8
|
+
base_uri 'www.conservative.ca'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def electoral_districts!
|
13
|
+
# TODO returns HTML with electoral district names only
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
# TODO
|
18
|
+
end
|
19
|
+
|
20
|
+
def response
|
21
|
+
@response ||= self.class.get "/?section_id=1051&postal_code=#{@postal_code}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
StrategySet.register ConservativeCa
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
class DigitalCopyrightCa < Base
|
6
|
+
base_uri 'www.digital-copyright.ca'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def electoral_districts!
|
11
|
+
Nokogiri::HTML(response.parsed_response).css('.node .content a').map{|a| a[:href][/\d+\Z/]}
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
!response.parsed_response.match /\binvalid postal code\b/
|
16
|
+
end
|
17
|
+
|
18
|
+
def response
|
19
|
+
@response ||= self.class.get "/edid/postal?postalcode=#{@postal_code}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
StrategySet.register DigitalCopyrightCa
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# elections.ca is a reliable source, but it does not return electoral
|
6
|
+
# districts for postal codes that contain multiple electoral districts.
|
7
|
+
# @see https://github.com/danielharan/postal_code_to_edid_webservice
|
8
|
+
class ElectionsCa < Base
|
9
|
+
base_uri 'elections.ca'
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def electoral_districts!
|
14
|
+
[ response.headers['location'][/&ED=(\d{5})&/, 1] ]
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
!!response.headers['location']
|
19
|
+
end
|
20
|
+
|
21
|
+
def response
|
22
|
+
@response ||= self.class.head "/scripts/pss/FindED.aspx?PC=#{@postal_code}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
StrategySet.register ElectionsCa
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
class LiberalCa < Base
|
6
|
+
base_uri 'www.liberal.ca'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def electoral_districts!
|
11
|
+
Nokogiri::HTML(response.parsed_response).css('img.RidingListImage').map{|img| img[:src][/\d{5}/]}
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
!response.parsed_response.match /\bOopsies!/
|
16
|
+
end
|
17
|
+
|
18
|
+
def response
|
19
|
+
@response ||= self.class.get "/riding/postal/#{@postal_code}/"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
StrategySet.register LiberalCa
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# ndp.ca does not return electoral districts for postal codes that
|
6
|
+
# contain multiple electoral districts.
|
7
|
+
class NDPCa < Base
|
8
|
+
base_uri 'www.ndp.ca'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def electoral_districts!
|
13
|
+
[ response.headers['location'][/\d+\Z/] ]
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
response.headers['location'] != 'http://www.ndp.ca/'
|
18
|
+
end
|
19
|
+
|
20
|
+
def response
|
21
|
+
@response ||= self.class.head "http://www.ndp.ca/riding/#{@postal_code}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
StrategySet.register NDPCa
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# parl.gc.ca seems unreliable. In the case of K0A1K0, for example, it
|
6
|
+
# does not return seven ridings like other sources.
|
7
|
+
class ParlGcCa < Base
|
8
|
+
base_uri 'www2.parl.gc.ca'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def electoral_districts!
|
13
|
+
# TODO returns HTML with electoral district names only
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
# TODO
|
18
|
+
end
|
19
|
+
|
20
|
+
def response
|
21
|
+
@response ||= self.class.get "/parlinfo/Compilations/HouseOfCommons/MemberByPostalCode.aspx?PostalCode=#{@postal_code}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
StrategySet.register ParlGcCa
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/govkit-ca.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'gov_kit-ca'
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'open-uri'
|
3
|
+
require File.expand_path('../../lib/gov_kit-ca', __FILE__)
|
4
|
+
|
5
|
+
# http://www.digital-copyright.ca/pcfrf/pcfrf.tgz contains
|
6
|
+
# `postal-code-for-districts.csv`, "which is 308 postal codes that should
|
7
|
+
# map to each of the 308 different electoral districts." However, six of the
|
8
|
+
# postal codes are invalid (G0A2C0, J8M1R8, J0W1B0, J0B1H0, L0J1B0, N2A1A3),
|
9
|
+
# 14 are duplicate, and the remaining 294 map to 246 electoral districts.
|
10
|
+
desc "Picks the set cover for postal codes to cbc.ca riding IDs"
|
11
|
+
task :trim_postal_codes do |t,args|
|
12
|
+
abort "Usage: rake #{t.name} file=postal-codes-for-districts.csv" unless args[:file]
|
13
|
+
|
14
|
+
# Get the riding IDs that each postal code covers
|
15
|
+
postal_to_rid = {}
|
16
|
+
File.read(args[:file]).split("\n").uniq.each do |postal_code| # Remove duplicate postal codes
|
17
|
+
begin
|
18
|
+
postal_to_rid[postal_code] = GovKit::CA::PostalCode::Strategy::CbcCa.new(postal_code).json_response.map{|hash| hash['rid'].to_i}
|
19
|
+
rescue JSON::ParserError => e # Ignore invalid postal codes
|
20
|
+
puts "ERROR: #{postal_code} is invalid"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get the minimum number of postal codes to cover all riding IDs. This is an
|
25
|
+
# instance of the set cover problem, which is NP-complete. We use the greedy
|
26
|
+
# algorithm, which is the best-possible polynomial time approximation
|
27
|
+
# algorithm for set cover. http://en.wikipedia.org/wiki/Set_cover_problem
|
28
|
+
postal_codes = []
|
29
|
+
until postal_to_rid.empty?
|
30
|
+
postal_code, rids = postal_to_rid.find{|k,v| v.size == postal_to_rid.map{|k,v| v.size}.max}
|
31
|
+
postal_to_rid.each{|k,v| postal_to_rid[k] -= rids}
|
32
|
+
postal_to_rid.reject!{|k,v| v.empty?}
|
33
|
+
postal_codes << postal_code
|
34
|
+
end
|
35
|
+
|
36
|
+
puts postal_codes.sort
|
37
|
+
end
|
38
|
+
|
39
|
+
# Use https://github.com/danielharan/pc_scraper/raw/master/data/index.csv and
|
40
|
+
# https://github.com/danielharan/canadian-postal-code-to-electoral-districts/raw/master/pc_edid.yml
|
41
|
+
# The YAML file may contain invalid postal codes, e.g. M5V1L6, and does not
|
42
|
+
# contain every electoral district, e.g. 35061. 35061 corresponds to riding ID
|
43
|
+
# 168, which contains the postal code L1H1X8.
|
44
|
+
desc "Generates postal codes within the given list of cbc.ca riding IDs"
|
45
|
+
task :riding_id_to_postal_code do |t,args|
|
46
|
+
abort "Usage: rake #{t.name} file=riding-ids.csv csv=index.csv yml=pc_edid.yml" unless args[:file] && args[:csv] && args[:yml]
|
47
|
+
|
48
|
+
# The YML file maps postal codes to electoral districts
|
49
|
+
yml = YAML.load_file(args[:yml])
|
50
|
+
|
51
|
+
# Get an old map of riding IDs to electoral districts
|
52
|
+
rid_to_edid = {}
|
53
|
+
CSV.foreach(args[:csv]) do |row|
|
54
|
+
rid_to_edid[row[1]] = row[0]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Map riding IDs to postal codes
|
58
|
+
rid_to_postal = {}
|
59
|
+
File.read(args[:file]).split("\n").each do |riding_id|
|
60
|
+
match = yml.find{|k,v| v == rid_to_edid[riding_id]}
|
61
|
+
if match
|
62
|
+
rid_to_postal[riding_id] = match[0]
|
63
|
+
else
|
64
|
+
puts "ERROR: No postal code for riding ID #{riding_id}, electoral district #{rid_to_edid[riding_id]}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
puts rid_to_postal.values.sort
|
69
|
+
end
|
70
|
+
|
71
|
+
# Pass postal-code-for-districts.csv from http://www.digital-copyright.ca/pcfrf/pcfrf.tgz
|
72
|
+
# through `rake trim_postal_codes`. This rake task will print a list of riding
|
73
|
+
# IDs which none of the given postal codes belong to. Pass this list through
|
74
|
+
# `rake riding_id_to_postal_code` to get a list of postal codes belonging to
|
75
|
+
# those riding IDs. Manually add postal codes for any remaining riding IDs.
|
76
|
+
desc "Generates YAML mapping cbc.ca riding IDs to electoral districts"
|
77
|
+
task :riding_id_to_electoral_district do |t,args|
|
78
|
+
abort "Usage: rake #{t.name} file=postal-codes-for-districts.csv" unless args[:file]
|
79
|
+
|
80
|
+
def transliterate_elections_ca(string)
|
81
|
+
{
|
82
|
+
/\342\200\223/ => '-',
|
83
|
+
/\303\242/ => 'a',
|
84
|
+
/\303[\251\250]/ => 'e',
|
85
|
+
/\303\264/ => 'o',
|
86
|
+
/\303\211/ => 'E',
|
87
|
+
/\303\216/ => 'I',
|
88
|
+
}.reduce(string) do |string,map|
|
89
|
+
string.gsub(map[0], map[1])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Map electoral district names to electoral district IDs
|
94
|
+
name_to_edid = {}
|
95
|
+
doc = Nokogiri::HTML(open("http://www.elections.ca/content.aspx?section=res&dir=cir/list&document=index&lang=e").read)
|
96
|
+
doc.css('sup').remove
|
97
|
+
edids = doc.css('table[summary^="List"] th.normal').map{|x| x.text.to_i}
|
98
|
+
doc.css('table[summary^="List"] th.normal + td').map{|x| x.text.gsub(/\s+/, ' ').strip}.each_with_index do |name,index|
|
99
|
+
name_to_edid[transliterate_elections_ca(name)] = edids[index]
|
100
|
+
end
|
101
|
+
|
102
|
+
def transliterate_cbc_ca(string)
|
103
|
+
{
|
104
|
+
/ - / => '-',
|
105
|
+
/\342/ => 'a',
|
106
|
+
/[\350\351]/ => 'e',
|
107
|
+
/\364/ => 'o',
|
108
|
+
/\311/ => 'E',
|
109
|
+
/\316/ => 'I',
|
110
|
+
}.reduce(string) do |string,map|
|
111
|
+
string.gsub(map[0], map[1])
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Map electoral district names to riding IDs
|
116
|
+
name_to_rid = {}
|
117
|
+
File.read(args[:file]).split("\n").each do |postal_code|
|
118
|
+
GovKit::CA::PostalCode::Strategy::CbcCa.new(postal_code).json_response.each do |hash|
|
119
|
+
name_to_rid[transliterate_cbc_ca(hash['name'])] = hash['rid'].to_i
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Can we generate a complete mapping?
|
124
|
+
missing = name_to_edid.keys - name_to_rid.keys
|
125
|
+
unless missing.empty?
|
126
|
+
abort "The postal codes in #{args[:file]} do not cover #{missing.size} electoral districts:\n#{missing.sort.join("\n")}\n\nThe missing cbc.ca riding IDs are:\n#{([*1..308] - name_to_rid.map{|k,v| v}.flatten).sort.join("\n")}"
|
127
|
+
end
|
128
|
+
|
129
|
+
# Map riding IDs to electoral districts
|
130
|
+
rid_to_edid = {}
|
131
|
+
name_to_edid.keys.each do |name|
|
132
|
+
rid_to_edid[name_to_rid[name]] = name_to_edid[name]
|
133
|
+
end
|
134
|
+
|
135
|
+
puts rid_to_edid.to_yaml
|
136
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: govkit-ca
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- James McKinney
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-03-01 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: httparty
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 6
|
31
|
+
- 1
|
32
|
+
version: 0.6.1
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: nokogiri
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 1
|
45
|
+
- 4
|
46
|
+
- 4
|
47
|
+
version: 1.4.4
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: yajl-ruby
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
- 7
|
61
|
+
- 8
|
62
|
+
version: 0.7.8
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: rspec
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 2
|
75
|
+
version: "2"
|
76
|
+
type: :development
|
77
|
+
version_requirements: *id004
|
78
|
+
description: GovKit-CA lets you quickly get encapsulated Ruby objects for Canadian civic data.
|
79
|
+
email:
|
80
|
+
- james@slashpoundbang.com
|
81
|
+
executables: []
|
82
|
+
|
83
|
+
extensions: []
|
84
|
+
|
85
|
+
extra_rdoc_files: []
|
86
|
+
|
87
|
+
files:
|
88
|
+
- .gitignore
|
89
|
+
- Gemfile
|
90
|
+
- LICENSE
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- USAGE
|
94
|
+
- govkit-ca.gemspec
|
95
|
+
- lib/data/rid_to_edid.yml
|
96
|
+
- lib/gov_kit-ca.rb
|
97
|
+
- lib/gov_kit-ca/postal_code.rb
|
98
|
+
- lib/gov_kit-ca/postal_code/strategy.rb
|
99
|
+
- lib/gov_kit-ca/postal_code/strategy/base.rb
|
100
|
+
- lib/gov_kit-ca/postal_code/strategy/cbc-ca.rb
|
101
|
+
- lib/gov_kit-ca/postal_code/strategy/conservative-ca.rb
|
102
|
+
- lib/gov_kit-ca/postal_code/strategy/digital_copyright-ca.rb
|
103
|
+
- lib/gov_kit-ca/postal_code/strategy/elections-ca.rb
|
104
|
+
- lib/gov_kit-ca/postal_code/strategy/liberal-ca.rb
|
105
|
+
- lib/gov_kit-ca/postal_code/strategy/ndp-ca.rb
|
106
|
+
- lib/gov_kit-ca/postal_code/strategy/parl-gc-ca.rb
|
107
|
+
- lib/gov_kit-ca/version.rb
|
108
|
+
- lib/govkit-ca.rb
|
109
|
+
- spec/postal_code_spec.rb
|
110
|
+
- spec/spec.opts
|
111
|
+
- spec/spec_helper.rb
|
112
|
+
- tasks/rid_to_edid.rb
|
113
|
+
has_rdoc: true
|
114
|
+
homepage: http://github.com/jpmckinney/govkit-ca
|
115
|
+
licenses: []
|
116
|
+
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
version: "0"
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
version: "0"
|
138
|
+
requirements: []
|
139
|
+
|
140
|
+
rubyforge_project: govkit-ca
|
141
|
+
rubygems_version: 1.3.7
|
142
|
+
signing_key:
|
143
|
+
specification_version: 3
|
144
|
+
summary: Easy access to Canadian civic data around the web
|
145
|
+
test_files:
|
146
|
+
- spec/postal_code_spec.rb
|
147
|
+
- spec/spec.opts
|
148
|
+
- spec/spec_helper.rb
|