twfy 1.0.1 → 1.1.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/lib/twfy.rb CHANGED
@@ -1,183 +1,20 @@
1
- require 'rubygems'
2
- require 'open-uri'
3
- require 'json'
4
- require 'cgi'
5
- require 'ostruct'
6
- require 'logger'
7
-
8
- require File.join(File.dirname(__FILE__), 'data_element')
1
+ require 'uri'
9
2
 
10
3
  module Twfy
11
-
12
- VERSION = '1.0.1'
13
- BASE = URI.parse('http://www.theyworkforyou.com/api/')
14
-
15
- API_VERSION = '1.0.0'
16
-
17
- class Client
18
-
19
- class Error < ::StandardError; end
20
- class ServiceArgumentError < ::ArgumentError; end
21
- class APIError < ::StandardError; end
22
-
23
- def initialize(api_key, log_to=$stderr)
24
- @api_key = api_key
25
- @logger = Logger.new(log_to)
26
- end
27
-
28
- def log(message, level=:info)
29
- @logger.send(level, message) if $DEBUG
30
- end
31
-
32
- def convert_url(params={})
33
- service :convertURL, validate(params, :require => :url) do |value|
34
- URI.parse(value['url'])
35
- end
36
- end
37
-
38
- def constituency(params={})
39
- service :getConstituency, validate(params, :require => :postcode), Constituency
40
- end
41
-
42
- def constituencies(params={})
43
- service :getConstituencies, validate(params, :allow => [:date, :search, :longitude, :latitude, :distance]), Constituency
44
- end
45
-
46
- def mp(params={})
47
- service :getMP, validate(params, :allow => [:postcode, :constituency, :id, :always_return]), MP
48
- end
49
4
 
50
- def mp_info(params={})
51
- service :getMPInfo, validate(params, :require => :id)
52
- end
53
-
54
- def mps(params={})
55
- service :getMPs, validate(params, :allow => [:date, :search]), MP
56
- end
57
-
58
- def lord(params={})
59
- service :getLord, validate(params, :require => :id)
60
- end
61
-
62
- def lords(params={})
63
- service :getLords, validate(params, :allow => [:date, :search])
64
- end
65
-
66
- def mlas(params={})
67
- service :getMLAs, validate(params, :allow => [:date, :party, :search])
68
- end
5
+ BASE = URI.parse('http://www.theyworkforyou.com/api/')
6
+ API_VERSION = '1.0.0'
69
7
 
70
- def msps(params={})
71
- service :getMSPs, validate(params, :allow => [:date, :party, :search])
72
- end
8
+ autoload :VERSION, 'twfy/version'
9
+ autoload :Client, 'twfy/client'
10
+ autoload :Validation, 'twfy/validation'
73
11
 
74
- def geometry(params={})
75
- service :getGeometry, validate(params, :allow => :name), Geometry
76
- end
12
+ autoload :DataElement, 'twfy/data_element'
13
+ autoload :Constituency, 'twfy/constituency'
14
+ autoload :Geometry, 'twfy/geometry'
15
+ autoload :MP, 'twfy/mp'
77
16
 
78
- def committee(params={})
79
- service :getCommittee, validate(params, :require => :name, :allow => :date)
80
- end
17
+ autoload :Commands, 'twfy/commands'
18
+ autoload :API, 'twfy/api'
81
19
 
82
- def debates(params={})
83
- service :getDebates, validate(params, :require => :type, :require_one_of => [:date, :person, :search, :gid], :allow_dependencies => {
84
- :search => [:order, :page, :num],
85
- :person => [:order, :page, :num]
86
- })
87
- end
88
-
89
- def wrans(params={})
90
- service :getWrans, validate(params, :require_one_of => [:date, :person, :search, :gid], :allow_dependencies => {
91
- :search => [:order, :page, :num],
92
- :person => [:order, :page, :num]
93
- } )
94
- end
95
-
96
- def wms(params={})
97
- service :getWMS, validate(params, :require_one_of => [:date, :person, :search, :gid], :allow_dependencies => {
98
- :search => [:order, :page, :num],
99
- :person => [:order, :page, :num]
100
- } )
101
- end
102
-
103
- def comments(params={})
104
- service :getComments, validate(params, :allow => [:date, :search, :user_id, :pid, :page, :num])
105
- end
106
-
107
- def service(name, params={}, target=OpenStruct, &block)
108
- log "Calling service #{name}"
109
- url = BASE + name.to_s
110
- url.query = build_query(params)
111
- result = JSON.parse(url.read)
112
- log result.inspect
113
- unless result.kind_of?(Enumerable)
114
- raise Error, "Could not handle result: #{result.inspect}"
115
- end
116
- if result.kind_of?(Hash) && result['error']
117
- raise APIError, result['error'].to_s
118
- else
119
- structure result, block || target
120
- end
121
- end
122
-
123
- #######
124
- private
125
- #######
126
-
127
- def validate(params, against)
128
- requirements = against[:require].kind_of?(Array) ? against[:require] : [against[:require]].compact
129
- allowed = against[:allow].kind_of?(Array) ? against[:allow] : [against[:allow]].compact
130
- require_one = against[:require_one_of].kind_of?(Array) ? against[:require_one_of] : [against[:require_one_of]].compact
131
- allow_dependencies = against[:allow_dependencies] || {}
132
- provided_keys = params.keys.map{|k| k.to_sym }
133
-
134
- # Add allowed dependencies
135
- allow_dependencies.each do |key,dependent_keys|
136
- dependent_keys = dependent_keys.kind_of?(Array) ? dependent_keys : [dependent_keys].compact
137
- allowed += dependent_keys if provided_keys.include?(key)
138
- end
139
-
140
- if (missing = requirements.select{|r| !provided_keys.include? r }).any?
141
- raise ServiceArgumentError, "Missing required params #{missing.inspect}"
142
- end
143
-
144
- if require_one.any?
145
- if (count = provided_keys.inject(0){|count,item| count + (require_one.include?(item) ? 1 : 0) }) < 1
146
- raise ServiceArgumentError, "Need exactly one of #{require_one.inspect}"
147
- elsif count > 1
148
- raise ServiceArgumentError, "Only one of #{require_one.inspect} allowed"
149
- end
150
- end
151
-
152
- unless (extra = provided_keys - (requirements + allowed + require_one)).empty?
153
- raise ServiceArgumentError, "Unknown params #{extra.inspect}"
154
- end
155
-
156
- params
157
- end
158
-
159
- def structure(value, target)
160
- case value
161
- when Array
162
- value.map{|r| structure(r, target) }
163
- when Hash
164
- if target.kind_of?(Proc)
165
- target.call(value)
166
- elsif target == Hash
167
- value
168
- else
169
- target.ancestors.include?(DataElement) ? target.new(self,value) : target.new(value)
170
- end
171
- else
172
- result
173
- end
174
- end
175
-
176
- def build_query(params)
177
- params.update(:key=>@api_key, :version=>API_VERSION)
178
- params.map{|set| set.map{|i| CGI.escape(i.to_s)}.join('=') }.join('&')
179
- end
180
-
181
- end
182
-
183
20
  end