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.
@@ -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.client
8
- @client ||= WorldBank::Client.new
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
- client.query[:dirs] = ['incomeLevels', id.to_s]
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']
@@ -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
- def self.client
7
- @client ||= WorldBank::Client.new
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.all(client)
11
- client.query[:dirs] = ['indicators']
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
- client.query[:dirs] = ['indicators', id]
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.client
8
- @client ||= WorldBank::Client.new
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
- client.query[:dirs] = ['lendingTypes', id.to_s]
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
@@ -1,107 +1,211 @@
1
1
  module WorldBank
2
2
 
3
- module Query
4
-
5
- class Base
6
-
7
- def initialize(model)
8
- @model = model
9
- @client = WorldBank::Client.new
10
- @client.query[:dirs] << @model.type
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
- # the date param is expressed as a range 'StartDate:EndDate'
15
- # Date may be year & month, year & quarter, or just year
16
- # Date will convert any Date/Time object to an apporpriate year & month
17
- #
18
- def dates(date_range)
19
- if date_range.is_a? String
20
- @client.query[:params][:date] = date_range
21
- elsif date_range.is_a? Range
22
- start = date_range.first
23
- last = date_range.last
24
- @client.query[:params][:date] = "#{start.strftime("%YM%m")}:#{last.strftime("%YM%m")}"
25
- end
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
- def format(format, prefix=nil)
30
- @client.query[:params][:format] = format
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
- def id(id)
35
- @client.query[:params][:id] = id
36
- self
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
- # Most Recent Values param hs two optional params
41
- # Gap fill will specify how many items to add if there isn't enough data for you query
42
- # Frequency sets how frequent the data sets are...
43
- # An example is best to explain this:
44
- # I want the 5 most recent yearly values between 2000 and 2010,
45
- # but I need at least three data sets to continue. My query would look like this:
46
- # .dates('2000:2010').most_recent_values(:gap_fill => 3, :frequency => 'Y')
47
- #
48
- def most_recent_values(num, options={})
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
- def per_page(num)
56
- @client.query[:params][:perPage] = num
57
- self
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
- def page(num)
61
- @client.query[:params][:page] = num
62
- self
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
- def language(lang)
66
- @client.query[:dirs] << lang.to_s.downcase
67
- self
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
- class Countries
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
- def lending_types(lend_type)
79
- parsed_array = lend_type.is_a?(Array) ? lend_type.map(&:id).join(';') : lend_type.id
80
- @client.query[:params][:lendingTypes] = parsed_array
81
- self
82
- end
83
-
84
- def income_levels(income_levels)
85
- parsed_array = income_levels.is_a?(Array) ? income_levels.map(&:id).join(';') : income_levels.id
86
- @client.query[:params][:incomeLevels] = parsed_array
87
- self
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
- def region(region)
91
- parsed_array = region.map(&:id).join(';')
92
- @client.query[:params][:region] = parsed_array
93
- self
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
- class Indicators
97
-
98
- def countries(countries)
99
- parsed_array = countries.map(&:id).join(';')
100
- @client.query[:params][:countries] = parsed_array
101
- self
102
- end
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
+