world_bank 0.0.1 → 0.9.0
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/Changelog +6 -0
- data/lib/world_bank.rb +6 -4
- data/lib/world_bank/client.rb +27 -54
- data/lib/world_bank/country.rb +337 -11
- data/lib/world_bank/data.rb +73 -0
- data/lib/world_bank/data_query.rb +64 -0
- data/lib/world_bank/income_level.rb +5 -12
- data/lib/world_bank/indicator.rb +52 -11
- data/lib/world_bank/lending_type.rb +4 -11
- data/lib/world_bank/param_query.rb +51 -0
- data/lib/world_bank/query.rb +189 -85
- data/lib/world_bank/region.rb +4 -11
- data/lib/world_bank/source.rb +5 -11
- data/lib/world_bank/topic.rb +8 -15
- data/lib/world_bank/version.rb +1 -1
- data/spec/world_bank/client_spec.rb +6 -74
- data/spec/world_bank/country_spec.rb +24 -39
- data/spec/world_bank/data_query_spec.rb +38 -0
- data/spec/world_bank/income_level_spec.rb +2 -9
- data/spec/world_bank/indicator_spec.rb +2 -2
- data/spec/world_bank/lending_type_spec.rb +2 -8
- data/spec/world_bank/param_query_spec.rb +45 -0
- data/spec/world_bank/query_spec.rb +44 -84
- data/spec/world_bank/region_spec.rb +2 -2
- data/spec/world_bank/source_spec.rb +2 -8
- data/spec/world_bank/topic_spec.rb +11 -17
- data/spec/world_bank_spec.rb +1 -1
- data/world_bank.gemspec +2 -2
- metadata +111 -137
- data/country_aliases +0 -257
- data/notes +0 -33
- data/notes_part_2 +0 -108
- data/projects_notes +0 -11
@@ -0,0 +1,73 @@
|
|
1
|
+
module WorldBank
|
2
|
+
|
3
|
+
class Data
|
4
|
+
|
5
|
+
attr_reader :raw, :name, :id, :value, :date, :others
|
6
|
+
|
7
|
+
def self.format(arg)
|
8
|
+
find('all').format(arg)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.id(arg)
|
12
|
+
find('all').id(arg)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.raw
|
16
|
+
find('all').raw
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.most_recent_values(arg)
|
20
|
+
find('all').most_recent_values(arg)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.page(arg)
|
24
|
+
find('all').page(arg)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.per_page
|
28
|
+
find('all').per_page(arg)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.language(arg)
|
32
|
+
find('all').language(arg)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.income_level(arg)
|
36
|
+
find('all').income_level(arg)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.lending_type(arg)
|
40
|
+
find('all').lending_type(arg)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.region(arg)
|
44
|
+
find('all').region(arg)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.country(arg)
|
48
|
+
find('all').country(arg)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.fetch(arg)
|
52
|
+
find(arg).fetch
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.all
|
56
|
+
find('all')
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.find(id)
|
60
|
+
WorldBank::DataQuery.new('indicators', id, self)
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize(values={})
|
64
|
+
@raw = values
|
65
|
+
@name = values['indicator'].delete('value')
|
66
|
+
@id = values['indicator'].delete('id')
|
67
|
+
@value = values.delete('value')
|
68
|
+
@date = values.delete('date')
|
69
|
+
values.delete('indicator')
|
70
|
+
@others = values
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module WorldBank
|
2
|
+
|
3
|
+
class DataQuery < Query
|
4
|
+
|
5
|
+
def initialize(name, id, model)
|
6
|
+
super
|
7
|
+
@param_dir = []
|
8
|
+
@params_filled = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def lending_type(lending_type)
|
12
|
+
ensure_unconflicting_qualifiers
|
13
|
+
parsed = indifferent_number lending_type
|
14
|
+
@param_dir = ['lendingTypes', parsed]
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def income_level(income_level)
|
19
|
+
ensure_unconflicting_qualifiers
|
20
|
+
parsed = indifferent_number income_level
|
21
|
+
@param_dir = ['incomeLevels', parsed]
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def region(regions)
|
26
|
+
ensure_unconflicting_qualifiers
|
27
|
+
parsed = indifferent_number regions
|
28
|
+
@param_dir = ['countries', parsed]
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def country(country)
|
33
|
+
ensure_unconflicting_qualifiers
|
34
|
+
parsed = indifferent_type country
|
35
|
+
parsed = ensure_country_id parsed
|
36
|
+
@param_dir = ['countries', parsed]
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def indicator(indicators)
|
41
|
+
parsed = indifferent_number indicators
|
42
|
+
@id = parsed
|
43
|
+
self
|
44
|
+
end
|
45
|
+
alias_method(:find, :indicator)
|
46
|
+
|
47
|
+
def source(sources)
|
48
|
+
ensure_unconflicting_qualifiers
|
49
|
+
parsed = indifferent_number sources
|
50
|
+
@param_dir = ['sources', parsed]
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def ensure_unconflicting_qualifiers
|
57
|
+
if @params_filled
|
58
|
+
raise ArgumentError,
|
59
|
+
"Only one of 'income_level', 'lending_type', 'country', or 'source' can be called on the same query"
|
60
|
+
end
|
61
|
+
@params_filled = true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,24 +1,17 @@
|
|
1
1
|
module WorldBank
|
2
2
|
|
3
3
|
class IncomeLevel
|
4
|
-
|
4
|
+
|
5
5
|
attr_reader :raw, :id, :name, :type
|
6
6
|
|
7
|
-
def self.
|
8
|
-
|
7
|
+
def self.all
|
8
|
+
find('all')
|
9
9
|
end
|
10
10
|
|
11
|
-
def self.all(client)
|
12
|
-
client.query[:dirs] = ['incomeLevels']
|
13
|
-
client.get_query
|
14
|
-
end
|
15
|
-
|
16
11
|
def self.find(id)
|
17
|
-
|
18
|
-
result = client.get_query
|
19
|
-
new(result[1][0])
|
12
|
+
WorldBank::ParamQuery.new('incomeLevels', id, self)
|
20
13
|
end
|
21
|
-
|
14
|
+
|
22
15
|
def initialize(values={})
|
23
16
|
@raw = values
|
24
17
|
@id = values['id']
|
data/lib/world_bank/indicator.rb
CHANGED
@@ -1,21 +1,63 @@
|
|
1
1
|
module WorldBank
|
2
2
|
|
3
3
|
class Indicator
|
4
|
-
|
4
|
+
|
5
5
|
attr_reader :raw, :id, :name, :source, :note, :organization, :topics, :type
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
def self.format(arg)
|
8
|
+
find('all').format(arg)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.id(arg)
|
12
|
+
find('all').id(arg)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.most_recent_values(arg)
|
16
|
+
find('all').most_recent_values(arg)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.page(arg)
|
20
|
+
find('all').page(arg)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.per_page
|
24
|
+
find('all').per_page(arg)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.language(arg)
|
28
|
+
find('all').language(arg)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.income_level(arg)
|
32
|
+
find('all').income_level(arg)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.lending_type(arg)
|
36
|
+
find('all').lending_type(arg)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.region(arg)
|
40
|
+
find('all').region(arg)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.country
|
44
|
+
find('all').country(arg)
|
8
45
|
end
|
9
46
|
|
10
|
-
def self.
|
11
|
-
|
12
|
-
client.get_query
|
47
|
+
def self.fetch(arg)
|
48
|
+
find(arg).fetch
|
13
49
|
end
|
14
|
-
|
50
|
+
|
51
|
+
def self.featured
|
52
|
+
find('all').featured_indicators
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.all
|
56
|
+
find('all')
|
57
|
+
end
|
58
|
+
|
15
59
|
def self.find(id)
|
16
|
-
|
17
|
-
result = client.get_query
|
18
|
-
new(result[1][0])
|
60
|
+
WorldBank::ParamQuery.new('indicators', id, self)
|
19
61
|
end
|
20
62
|
|
21
63
|
def initialize(values={})
|
@@ -32,5 +74,4 @@ module WorldBank
|
|
32
74
|
@type = 'indicators'
|
33
75
|
end
|
34
76
|
end
|
35
|
-
|
36
77
|
end
|
@@ -1,22 +1,15 @@
|
|
1
1
|
module WorldBank
|
2
2
|
|
3
3
|
class LendingType
|
4
|
-
|
4
|
+
|
5
5
|
attr_reader :raw, :id, :name, :type
|
6
6
|
|
7
|
-
def self.
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.all(client)
|
12
|
-
client.query[:dirs] = ['lendingTypes']
|
13
|
-
client.get_query
|
7
|
+
def self.all
|
8
|
+
find('all')
|
14
9
|
end
|
15
10
|
|
16
11
|
def self.find(id)
|
17
|
-
|
18
|
-
result = client.get_query
|
19
|
-
new(result[1][0])
|
12
|
+
WorldBank::ParamQuery.new('lendingTypes', id, self)
|
20
13
|
end
|
21
14
|
|
22
15
|
def initialize(values={})
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module WorldBank
|
2
|
+
|
3
|
+
class ParamQuery < Query
|
4
|
+
|
5
|
+
def initialize(name, id, model)
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def lending_type(lending_type)
|
10
|
+
parsed = indifferent_number lending_type
|
11
|
+
@query[:params].merge!({:lendingTypes => parsed})
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def income_level(income_levels)
|
16
|
+
parsed = indifferent_number income_levels
|
17
|
+
@query[:params].merge!({:incomeLevels => parsed})
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def region(regions)
|
22
|
+
parsed = indifferent_number regions
|
23
|
+
@query[:params].merge!({:countries => parsed})
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def country(country)
|
28
|
+
parsed = indifferent_type country
|
29
|
+
parsed = ensure_country_id parsed
|
30
|
+
@query[:params].merge!({:countries => parsed})
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def indicator(indicators)
|
35
|
+
parsed = indifferent_number indicators
|
36
|
+
@query[:params].merge!({:indicators => parsed})
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def featured_indicators
|
41
|
+
@query[:params].merge!({:featured => 1})
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def source(sources)
|
46
|
+
parsed = indifferent_number sources
|
47
|
+
@query[:params].merge!({:sources => parsed})
|
48
|
+
self
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/world_bank/query.rb
CHANGED
@@ -1,107 +1,211 @@
|
|
1
1
|
module WorldBank
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
class Query
|
4
|
+
|
5
|
+
attr_reader :pages, :total
|
6
|
+
|
7
|
+
def initialize(name, id, model)
|
8
|
+
@model = model
|
9
|
+
@name = name
|
10
|
+
@id = id
|
11
|
+
@lang = false
|
12
|
+
@raw = false
|
13
|
+
@new = true
|
14
|
+
@query = {:params => {:format => :json}, :dirs => []}
|
15
|
+
@param_dir = []
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# the date param is expressed as a range 'StartDate:EndDate'
|
20
|
+
# Date may be year & month, year & quarter, or just year
|
21
|
+
# Date will convert any Date/Time object to an apporpriate year & month
|
22
|
+
#
|
23
|
+
def dates(date_range)
|
24
|
+
if date_range.is_a? String
|
25
|
+
|
26
|
+
# assume the user knows what she is doing if passed a string
|
27
|
+
@query[:params][:date] = date_range
|
28
|
+
elsif date_range.is_a? Range
|
29
|
+
start = date_range.first
|
30
|
+
last = date_range.last
|
31
|
+
@query[:params][:date] = "#{start.strftime("%YM%m")}:#{last.strftime("%YM%m")}"
|
11
32
|
end
|
33
|
+
self
|
34
|
+
end
|
12
35
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
36
|
+
def format(format)
|
37
|
+
@query[:params][:format] = format
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def raw
|
42
|
+
@raw = true
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def id(id)
|
47
|
+
@query[:params][:id] = id
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Most Recent Values param has two optional params
|
53
|
+
# Gap fill will specify how many items to add if there isn't enough data for you query
|
54
|
+
# Frequency sets how frequent the data sets are...
|
55
|
+
# An example is best to explain this:
|
56
|
+
# I want the 5 most recent yearly values between 2000 and 2010,
|
57
|
+
# but I need at least three data sets to continue. My query would look like this:
|
58
|
+
# .dates('2000:2010').most_recent_values(:gap_fill => 3, :frequency => 'Y')
|
59
|
+
#
|
60
|
+
def most_recent_values(num, options={})
|
61
|
+
@query[:params][:gapFill] = options[:gap_fill] if options[:gap_fill]
|
62
|
+
@query[:params][:frequency] = options[:frequency] if options[:frequency]
|
63
|
+
@query[:params][:MRV] = num
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def per_page(num=false)
|
68
|
+
if num
|
69
|
+
@query[:params][:perPage] = num
|
26
70
|
self
|
71
|
+
else
|
72
|
+
@per_page || @query[:params][:per_page] || 50
|
27
73
|
end
|
74
|
+
end
|
28
75
|
|
29
|
-
|
30
|
-
|
76
|
+
def page(num=false)
|
77
|
+
if num
|
78
|
+
@query[:params][:page] = num
|
31
79
|
self
|
80
|
+
else
|
81
|
+
@page || @query[:params][:page] || 1
|
32
82
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
83
|
+
end
|
84
|
+
|
85
|
+
def next
|
86
|
+
if @query[:params][:page].nil?
|
87
|
+
@query[:params][:page] = 2
|
88
|
+
else
|
89
|
+
@query[:params][:page] += 1
|
37
90
|
end
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
@client.query[:params][:gapFill] = options[:gap_fill] if options[:gap_fill]
|
50
|
-
@client.query[:params][:frequency] = options[:frequency] if options[:frequency]
|
51
|
-
@client.query[:params][:MRV] = num
|
52
|
-
self
|
91
|
+
self
|
92
|
+
end
|
93
|
+
|
94
|
+
def language(lang)
|
95
|
+
if lang.to_s.length == 2
|
96
|
+
@lang = lang.to_s.downcase
|
97
|
+
else
|
98
|
+
@lang = [ ['french', 'fr'],
|
99
|
+
['spanish', 'es'],
|
100
|
+
['english', 'en'],
|
101
|
+
['arabic', 'ar'] ].assoc(lang.to_s.downcase)[1]
|
53
102
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
def cycle
|
107
|
+
@cycle_results = @pages.nil? ? fetch : []
|
108
|
+
(@pages - self.page).times do
|
109
|
+
@cycle_results += self.next.fetch
|
58
110
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
111
|
+
@cycle_results
|
112
|
+
end
|
113
|
+
|
114
|
+
def fetch
|
115
|
+
if @new
|
116
|
+
@query[:dirs].push @name
|
117
|
+
@query[:dirs].push @id
|
118
|
+
@query[:dirs].unshift @lang if @lang
|
119
|
+
@query[:params][:format] ||= :json
|
120
|
+
@new = false
|
63
121
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
122
|
+
@query[:dirs] = @param_dir + @query[:dirs] unless @param_dir.empty?
|
123
|
+
client = WorldBank::Client.new(@query, @raw)
|
124
|
+
results = client.get_query
|
125
|
+
results = parse results unless @raw
|
126
|
+
results
|
127
|
+
end
|
128
|
+
|
129
|
+
protected
|
130
|
+
|
131
|
+
def parse(results)
|
132
|
+
update_fetch_info(results[0])
|
133
|
+
if @id =~ /all/ || @model == WorldBank::Data
|
134
|
+
results = results[1].map { |result| @model.new result }
|
135
|
+
else
|
136
|
+
results = @model.new results[1][0]
|
68
137
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
def initialize(model)
|
73
|
-
@model = model
|
74
|
-
@client = WorldBank::Client.new
|
75
|
-
@client.query[:dirs] << 'countries'
|
76
|
-
end
|
138
|
+
results
|
139
|
+
end
|
77
140
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
141
|
+
def update_fetch_info(meta_info)
|
142
|
+
@page = meta_info['page'].to_i
|
143
|
+
@per_page = meta_info['per_page'].to_i
|
144
|
+
@pages = meta_info['pages'].to_i
|
145
|
+
@total = meta_info['total'].to_i
|
146
|
+
end
|
147
|
+
|
148
|
+
def indifferent_number(possibly_multiple_args)
|
149
|
+
parsed = if possibly_multiple_args.is_a?(Array)
|
150
|
+
arr = possibly_multiple_args.map do |arg|
|
151
|
+
indifferent_type(arg)
|
88
152
|
end
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
153
|
+
arr.join(';')
|
154
|
+
else
|
155
|
+
indifferent_type(possibly_multiple_args)
|
156
|
+
end
|
157
|
+
parsed
|
158
|
+
end
|
159
|
+
|
160
|
+
def indifferent_type(arg)
|
161
|
+
parsed = ''
|
162
|
+
unless arg.is_a?(String) || arg.is_a?(Numeric)
|
163
|
+
parsed = arg.id
|
164
|
+
else
|
165
|
+
parsed = arg
|
166
|
+
end
|
167
|
+
parsed
|
168
|
+
end
|
169
|
+
|
170
|
+
def ensure_country_id(id)
|
171
|
+
@country_id = id
|
172
|
+
if @country_id.length > 3
|
173
|
+
@matching = WorldBank::Country.country_aliases.select do |country|
|
174
|
+
country[2] =~ Regexp.new(@country_id)
|
94
175
|
end
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
176
|
+
if @matching.length > 1
|
177
|
+
raise ArgumentError,
|
178
|
+
"More than one country code matched '#{@country_id}'. Perhaps you meant one of #{@matching.join(', ')}?",
|
179
|
+
caller
|
180
|
+
elsif @matching.length == 0
|
181
|
+
raise ArgumentError,
|
182
|
+
"No countries matched '#{@country_id}', please try again.",
|
183
|
+
caller
|
184
|
+
else
|
185
|
+
@country_id = @matching[0][0]
|
103
186
|
end
|
104
187
|
end
|
188
|
+
@country_id
|
189
|
+
end
|
190
|
+
|
191
|
+
def indifferent_nums(args)
|
192
|
+
parsed = ''
|
193
|
+
if args.is_a? Array
|
194
|
+
parsed = args.map! do |arg|
|
195
|
+
arg = normalize_country_id arg
|
196
|
+
arg = ensure_country_id arg
|
197
|
+
end.join(';')
|
198
|
+
else
|
199
|
+
args = normalize_country_id args
|
200
|
+
parsed = ensure_country_id args
|
201
|
+
end
|
202
|
+
parsed
|
203
|
+
end
|
204
|
+
|
205
|
+
def normalize_country_id(id)
|
206
|
+
id.gsub!(/[ -]/, '_')
|
207
|
+
id.downcase
|
105
208
|
end
|
106
209
|
end
|
107
210
|
end
|
211
|
+
|