parliament-ruby 0.6.3 → 0.7.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/lib/parliament/builder/base_response_builder.rb +13 -0
- data/lib/parliament/builder/ntriple_response_builder.rb +25 -0
- data/lib/parliament/builder/open_search_response_builder.rb +17 -0
- data/lib/parliament/builder.rb +5 -0
- data/lib/parliament/decorator/constituency_group.rb +2 -2
- data/lib/parliament/decorator/house_incumbency.rb +3 -5
- data/lib/parliament/decorator/incumbency.rb +3 -5
- data/lib/parliament/decorator/party_membership.rb +3 -5
- data/lib/parliament/decorator/person.rb +15 -51
- data/lib/parliament/decorator/seat_incumbency.rb +8 -3
- data/lib/parliament/request/base_request.rb +136 -0
- data/lib/parliament/request/open_search_request.rb +73 -0
- data/lib/parliament/request/url_request.rb +60 -0
- data/lib/parliament/request.rb +2 -188
- data/lib/parliament/version.rb +1 -1
- data/lib/parliament.rb +1 -0
- data/parliament-ruby.gemspec +1 -1
- metadata +26 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d6e3ce9cb153b579936aca384cbdb8f73d1c824
|
4
|
+
data.tar.gz: 8ab2872d2a93301be8420d3ba7815ef809a855c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7ba819f59a91286db8a2dd132b1b61d590e057ba93347da04692c87d0d10da37f03b9beeeda90aed8b18adf19871ecae6052da1eec46b2696166fd989b5ca8f
|
7
|
+
data.tar.gz: 18aa6d056e56843c7d08456d6b3a3b78dcdeeeac8ab2aecd78ded20b5ae785d80095755c607daa110663db61a9e0bab81ae9e2b65a16bdbbe67d379484af3f60
|
data/Gemfile
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Parliament
|
2
|
+
module Builder
|
3
|
+
class NTripleResponseBuilder < Parliament::Builder::BaseResponseBuilder
|
4
|
+
def build
|
5
|
+
objects = Grom::Reader.new(@response.body).objects
|
6
|
+
objects.map { |object| assign_decorator(object) }
|
7
|
+
|
8
|
+
Parliament::Response.new(objects)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def assign_decorator(object)
|
14
|
+
return object unless object.respond_to?(:type)
|
15
|
+
|
16
|
+
object_type = Grom::Helper.get_id(object.type)
|
17
|
+
|
18
|
+
return object unless Parliament::Decorator.constants.include?(object_type.to_sym)
|
19
|
+
|
20
|
+
decorator_module = Object.const_get("Parliament::Decorator::#{object_type}")
|
21
|
+
object.extend(decorator_module)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'feedjira'
|
2
|
+
|
3
|
+
module Parliament
|
4
|
+
module Builder
|
5
|
+
class OpenSearchResponseBuilder < Parliament::Builder::BaseResponseBuilder
|
6
|
+
OPEN_SEARCH_ELEMENTS = %w(totalResults Query startIndex itemsPerPage).freeze
|
7
|
+
|
8
|
+
def build
|
9
|
+
OPEN_SEARCH_ELEMENTS.each do |element|
|
10
|
+
Feedjira::Feed.add_common_feed_element(element)
|
11
|
+
end
|
12
|
+
|
13
|
+
Feedjira::Feed.parse(@response.body)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -13,14 +13,14 @@ module Parliament
|
|
13
13
|
#
|
14
14
|
# @return [DateTime, nil] the start date of the Grom::Node or nil.
|
15
15
|
def start_date
|
16
|
-
respond_to?(:constituencyGroupStartDate) ? DateTime.parse(constituencyGroupStartDate) : nil
|
16
|
+
@start_date ||= respond_to?(:constituencyGroupStartDate) ? DateTime.parse(constituencyGroupStartDate) : nil
|
17
17
|
end
|
18
18
|
|
19
19
|
# Alias constituencyGroupEndDate with fallback.
|
20
20
|
#
|
21
21
|
# @return [DateTime, nil] the end date of the Grom::Node or nil.
|
22
22
|
def end_date
|
23
|
-
respond_to?(:constituencyGroupEndDate) ? DateTime.parse(constituencyGroupEndDate) : nil
|
23
|
+
@end_date ||= respond_to?(:constituencyGroupEndDate) ? DateTime.parse(constituencyGroupEndDate) : nil
|
24
24
|
end
|
25
25
|
|
26
26
|
# Alias constituencyGroupHasHouseSeat with fallback.
|
@@ -6,23 +6,21 @@ module Parliament
|
|
6
6
|
#
|
7
7
|
# @return [DateTime, nil] the start date of the Grom::Node or nil.
|
8
8
|
def start_date
|
9
|
-
respond_to?(:incumbencyStartDate) ? DateTime.parse(incumbencyStartDate) : nil
|
9
|
+
@start_date ||= respond_to?(:incumbencyStartDate) ? DateTime.parse(incumbencyStartDate) : nil
|
10
10
|
end
|
11
11
|
|
12
12
|
# Alias incumbencyEndDate with fallback.
|
13
13
|
#
|
14
14
|
# @return [DateTime, nil] the end date of the Grom::Node or nil.
|
15
15
|
def end_date
|
16
|
-
respond_to?(:incumbencyEndDate) ? DateTime.parse(incumbencyEndDate) : nil
|
16
|
+
@end_date ||= respond_to?(:incumbencyEndDate) ? DateTime.parse(incumbencyEndDate) : nil
|
17
17
|
end
|
18
18
|
|
19
19
|
# Checks if Grom::Node has an end date.
|
20
20
|
#
|
21
21
|
# @return [Boolean] a boolean depending on whether or not the Grom::Node has an end date.
|
22
22
|
def current?
|
23
|
-
|
24
|
-
|
25
|
-
!has_end_date
|
23
|
+
end_date.nil?
|
26
24
|
end
|
27
25
|
|
28
26
|
# Alias houseIncumbencyHasHouse with fallback.
|
@@ -6,23 +6,21 @@ module Parliament
|
|
6
6
|
#
|
7
7
|
# @return [DateTime, nil] the start date of the Grom::Node or nil.
|
8
8
|
def start_date
|
9
|
-
respond_to?(:incumbencyStartDate) ? DateTime.parse(incumbencyStartDate) : nil
|
9
|
+
@start_date ||= respond_to?(:incumbencyStartDate) ? DateTime.parse(incumbencyStartDate) : nil
|
10
10
|
end
|
11
11
|
|
12
12
|
# Alias incumbencyEndDate with fallback.
|
13
13
|
#
|
14
14
|
# @return [DateTime, nil] the end date of the Grom::Node or nil.
|
15
15
|
def end_date
|
16
|
-
respond_to?(:incumbencyEndDate) ? DateTime.parse(incumbencyEndDate) : nil
|
16
|
+
@end_date ||= respond_to?(:incumbencyEndDate) ? DateTime.parse(incumbencyEndDate) : nil
|
17
17
|
end
|
18
18
|
|
19
19
|
# Checks if Grom::Node has an end date.
|
20
20
|
#
|
21
21
|
# @return [Boolean] a boolean depending on whether or not the Grom::Node has an end date.
|
22
22
|
def current?
|
23
|
-
|
24
|
-
|
25
|
-
!has_end_date
|
23
|
+
end_date.nil?
|
26
24
|
end
|
27
25
|
|
28
26
|
# Alias incumbencyHasMember with fallback.
|
@@ -13,23 +13,21 @@ module Parliament
|
|
13
13
|
#
|
14
14
|
# @return [DateTime, nil] the start date of the Grom::Node or nil.
|
15
15
|
def start_date
|
16
|
-
respond_to?(:partyMembershipStartDate) ? DateTime.parse(partyMembershipStartDate) : nil
|
16
|
+
@start_date ||= respond_to?(:partyMembershipStartDate) ? DateTime.parse(partyMembershipStartDate) : nil
|
17
17
|
end
|
18
18
|
|
19
19
|
# Alias partyMembershipEndDate with fallback.
|
20
20
|
#
|
21
21
|
# @return [DateTime, nil] the end date of the Grom::Node or nil.
|
22
22
|
def end_date
|
23
|
-
respond_to?(:partyMembershipEndDate) ? DateTime.parse(partyMembershipEndDate) : nil
|
23
|
+
@end_date ||= respond_to?(:partyMembershipEndDate) ? DateTime.parse(partyMembershipEndDate) : nil
|
24
24
|
end
|
25
25
|
|
26
26
|
# Checks if Grom::Node has an end date.
|
27
27
|
#
|
28
28
|
# @return [Boolean] a boolean depending on whether or not the Grom::Node has an end date.
|
29
29
|
def current?
|
30
|
-
|
31
|
-
|
32
|
-
!has_end_date
|
30
|
+
end_date.nil?
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
@@ -28,17 +28,20 @@ module Parliament
|
|
28
28
|
#
|
29
29
|
# @return [DateTime, nil] the date of birth of the Grom::Node or nil.
|
30
30
|
def date_of_birth
|
31
|
-
respond_to?(:personDateOfBirth) ? DateTime.parse(personDateOfBirth) : nil
|
31
|
+
@date_of_birth ||= respond_to?(:personDateOfBirth) ? DateTime.parse(personDateOfBirth) : nil
|
32
32
|
end
|
33
33
|
|
34
34
|
# Builds a full name using personGivenName and personFamilyName.
|
35
35
|
#
|
36
36
|
# @return [String, String] the full name of the Grom::Node or an empty string.
|
37
37
|
def full_name
|
38
|
-
full_name
|
39
|
-
|
40
|
-
full_name
|
41
|
-
full_name
|
38
|
+
return @full_name unless @full_name.nil?
|
39
|
+
|
40
|
+
full_name = []
|
41
|
+
full_name << personGivenName if respond_to?(:personGivenName)
|
42
|
+
full_name << personFamilyName if respond_to?(:personFamilyName)
|
43
|
+
|
44
|
+
@full_name = full_name.join(' ')
|
42
45
|
end
|
43
46
|
|
44
47
|
# Alias memberHasIncumbency with fallback.
|
@@ -52,68 +55,35 @@ module Parliament
|
|
52
55
|
#
|
53
56
|
# @return [Array, Array] the seat incumbencies of the Grom::Node or an empty array.
|
54
57
|
def seat_incumbencies
|
55
|
-
|
56
|
-
memberHasIncumbency.select { |inc| inc.type == 'http://id.ukpds.org/schema/SeatIncumbency' }
|
57
|
-
else
|
58
|
-
[]
|
59
|
-
end
|
58
|
+
@seat_incumbencies ||= incumbencies.select { |inc| inc.type == 'http://id.ukpds.org/schema/SeatIncumbency' }
|
60
59
|
end
|
61
60
|
|
62
61
|
# Alias memberHasIncumbency with fallback.
|
63
62
|
#
|
64
63
|
# @return [Array, Array] the house incumbencies of the Grom::Node or an empty array.
|
65
64
|
def house_incumbencies
|
66
|
-
|
67
|
-
memberHasIncumbency.select { |inc| inc.type == 'http://id.ukpds.org/schema/HouseIncumbency' }
|
68
|
-
else
|
69
|
-
[]
|
70
|
-
end
|
65
|
+
@house_incumbencies ||= incumbencies.select { |inc| inc.type == 'http://id.ukpds.org/schema/HouseIncumbency' }
|
71
66
|
end
|
72
67
|
|
73
68
|
# Alias seatIncumbencyHasHouseSeat with fallback.
|
74
69
|
#
|
75
70
|
# @return [Array, Array] the seats of the Grom::Node or an empty array.
|
76
71
|
def seats
|
77
|
-
|
78
|
-
|
79
|
-
seats = []
|
80
|
-
seat_incumbencies.each do |incumbency|
|
81
|
-
seats << incumbency.seat if incumbency.respond_to?(:seat)
|
82
|
-
end
|
83
|
-
|
84
|
-
@seats = seats.flatten.uniq
|
72
|
+
@seats ||= seat_incumbencies.map(&:seat).flatten.uniq
|
85
73
|
end
|
86
74
|
|
87
75
|
# Alias houseSeatHasHouse with fallback.
|
88
76
|
#
|
89
77
|
# @return [Array, Array] the houses of the Grom::Node or an empty array.
|
90
78
|
def houses
|
91
|
-
|
92
|
-
|
93
|
-
houses = []
|
94
|
-
seats.each do |seat|
|
95
|
-
houses << seat.house
|
96
|
-
end
|
97
|
-
|
98
|
-
house_incumbencies.each do |inc|
|
99
|
-
houses << inc.house
|
100
|
-
end
|
101
|
-
|
102
|
-
@houses = houses.flatten.uniq
|
79
|
+
@houses ||= [seats.map(&:house), house_incumbencies.map(&:house)].flatten.uniq
|
103
80
|
end
|
104
81
|
|
105
82
|
# Alias houseSeatHasConstituencyGroup with fallback.
|
106
83
|
#
|
107
84
|
# @return [Array, Array] the constituencies of the Grom::Node or an empty array.
|
108
85
|
def constituencies
|
109
|
-
|
110
|
-
|
111
|
-
constituencies = []
|
112
|
-
seats.each do |seat|
|
113
|
-
constituencies << seat.constituency
|
114
|
-
end
|
115
|
-
|
116
|
-
@constituencies = constituencies.flatten.uniq
|
86
|
+
@constituencies ||= seats.map(&:constituency).flatten.uniq
|
117
87
|
end
|
118
88
|
|
119
89
|
# Alias partyMemberHasPartyMembership with fallback.
|
@@ -127,14 +97,7 @@ module Parliament
|
|
127
97
|
#
|
128
98
|
# @return [Array, Array] the parties of the Grom::Node or an empty array.
|
129
99
|
def parties
|
130
|
-
|
131
|
-
|
132
|
-
parties = []
|
133
|
-
party_memberships.each do |party_membership|
|
134
|
-
parties << party_membership.party
|
135
|
-
end
|
136
|
-
|
137
|
-
@parties = parties.flatten.uniq.compact
|
100
|
+
@parties ||= party_memberships.map(&:party).flatten.uniq.compact
|
138
101
|
end
|
139
102
|
|
140
103
|
# Alias personHasContactPoint with fallback.
|
@@ -203,6 +166,7 @@ module Parliament
|
|
203
166
|
build_house_membership_status(no_current_seat_incumbency, no_current_house_incumbency, former_lord, former_mp)
|
204
167
|
end
|
205
168
|
|
169
|
+
# TODO: Convert hard-coded strings to language file values
|
206
170
|
def build_house_membership_status(no_current_seat_incumbency, no_current_house_incumbency, former_lord, former_mp)
|
207
171
|
statuses = []
|
208
172
|
statuses << 'Current MP' unless no_current_seat_incumbency
|
@@ -23,13 +23,18 @@ module Parliament
|
|
23
23
|
respond_to?(:seatIncumbencyHasHouseSeat) ? seatIncumbencyHasHouseSeat.first : nil
|
24
24
|
end
|
25
25
|
|
26
|
-
# Checks if Grom::Node has
|
26
|
+
# Checks if Grom::Node has no end date.
|
27
27
|
#
|
28
28
|
# @return [Boolean] a boolean depending on whether or not the Grom::Node has an end date.
|
29
29
|
def current?
|
30
|
-
|
30
|
+
!former?
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
+
# Checks if Grom::Node has an end date.
|
34
|
+
#
|
35
|
+
# @return [Boolean] a boolean depending on whether or not the Grom::Node has an end date.
|
36
|
+
def former?
|
37
|
+
respond_to?(:incumbencyEndDate)
|
33
38
|
end
|
34
39
|
|
35
40
|
# Alias houseSeatHasHouse with fallback.
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module Parliament
|
2
|
+
module Request
|
3
|
+
class BaseRequest
|
4
|
+
attr_reader :base_url, :headers
|
5
|
+
# Creates a new instance of Parliament::Request.
|
6
|
+
#
|
7
|
+
# An interesting note for #initialize is that setting base_url on the class, or using the environment variable
|
8
|
+
# PARLIAMENT_BASE_URL means you don't need to pass in a base_url. You can pass one anyway to override the
|
9
|
+
# environment variable or class parameter. Similarly, headers can be set by either settings the headers on the class, or passing headers in.
|
10
|
+
#
|
11
|
+
# @example Setting the base_url on the class
|
12
|
+
# Parliament::Request.base_url = 'http://example.com'
|
13
|
+
#
|
14
|
+
# Parliament::Request.new.base_url #=> 'http://example.com'
|
15
|
+
#
|
16
|
+
# @example Setting the base_url via environment variable
|
17
|
+
# ENV['PARLIAMENT_BASE_URL'] #=> 'http://test.com'
|
18
|
+
#
|
19
|
+
# Parliament::Request.new.base_url #=> 'http://test.com'
|
20
|
+
#
|
21
|
+
# @example Setting the base_url via a parameter
|
22
|
+
# Parliament::Request.base_url #=> nil
|
23
|
+
# ENV['PARLIAMENT_BASE_URL'] #=> nil
|
24
|
+
#
|
25
|
+
# Parliament::Request.new(base_url: 'http://example.com').base_url #=> 'http://example.com'
|
26
|
+
#
|
27
|
+
# @example Overriding the base_url via a parameter
|
28
|
+
# ENV['PARLIAMENT_BASE_URL'] #=> 'http://test.com'
|
29
|
+
#
|
30
|
+
# Parliament::Request.new(base_url: 'http://example.com').base_url #=> 'http://example.com'
|
31
|
+
#
|
32
|
+
# @example Setting the headers on the class
|
33
|
+
# Parliament::Request.headers = { 'Accept' => 'Test' }
|
34
|
+
#
|
35
|
+
# Parliament::Request.new.headers #=> '{ 'Accept' => 'Test' }
|
36
|
+
#
|
37
|
+
# @example Setting the headers via a parameter
|
38
|
+
# Parliament::Request.headers #=> nil
|
39
|
+
#
|
40
|
+
# Parliament::Request.new(headers: '{ 'Accept' => 'Test' }).headers #=> { 'Accept' => 'Test' }
|
41
|
+
#
|
42
|
+
# @example Overriding the headers via a parameter
|
43
|
+
# Parliament::Request.headers = { 'Accept' => 'Test' }
|
44
|
+
#
|
45
|
+
# Parliament::Request.new(headers: '{ 'Accept' => 'Test2' }).headers #=> { 'Accept' => 'Test2' }
|
46
|
+
#
|
47
|
+
# @param [String] base_url the base url of our api. (expected: http://example.com - without the trailing slash).
|
48
|
+
# @param [Hash] headers the headers being sent in the request.
|
49
|
+
def initialize(base_url: nil, headers: nil, builder: nil)
|
50
|
+
@base_url = base_url || self.class.base_url
|
51
|
+
@headers = headers || self.class.headers || {}
|
52
|
+
@builder = builder || Parliament::Builder::BaseResponseBuilder
|
53
|
+
end
|
54
|
+
|
55
|
+
# Using our url built via #method_missing, make a HTTP GET request and process results into a response.
|
56
|
+
#
|
57
|
+
# @example HTTP GET request
|
58
|
+
# request = Parliament::Request.new(base_url: 'http://example.com')
|
59
|
+
#
|
60
|
+
# # url: http://example.com/people/123456
|
61
|
+
# response = request.people('123456').get #=> #<Parliament::Response ...>
|
62
|
+
#
|
63
|
+
# @example HTTP GET request with URI encoded form values
|
64
|
+
# request = Parliament::Request.new(base_url: 'http://example.com')
|
65
|
+
#
|
66
|
+
# # url: http://example.com/people/current?limit=10&page=4&lang=en-gb
|
67
|
+
# response = request.people.current.get({ limit: 10, page: 4, lang: 'en-gb' }) #=> #<Parliament::Response ...>
|
68
|
+
#
|
69
|
+
# @raise [Parliament::ServerError] when the server responds with a 5xx status code.
|
70
|
+
# @raise [Parliament::ClientError] when the server responds with a 4xx status code.
|
71
|
+
# @raise [Parliament::NoContentResponseError] when the server responds with a 204 status code.
|
72
|
+
#
|
73
|
+
# @param [Hash] params (optional) additional URI encoded form values to be added to the URI.
|
74
|
+
#
|
75
|
+
# @return [Parliament::Response] a Parliament::Response object containing all of the nodes returned from the URL.
|
76
|
+
def get(params: nil)
|
77
|
+
endpoint_uri = URI.parse(query_url)
|
78
|
+
endpoint_uri.query = URI.encode_www_form(params.to_a) unless params.nil?
|
79
|
+
|
80
|
+
http = Net::HTTP.new(endpoint_uri.host, endpoint_uri.port)
|
81
|
+
http.use_ssl = true if endpoint_uri.scheme == 'https'
|
82
|
+
|
83
|
+
net_response = http.start do |h|
|
84
|
+
api_request = Net::HTTP::Get.new(endpoint_uri.request_uri)
|
85
|
+
add_headers(api_request)
|
86
|
+
|
87
|
+
h.request api_request
|
88
|
+
end
|
89
|
+
|
90
|
+
handle_errors(net_response)
|
91
|
+
|
92
|
+
build_response(net_response)
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
# @attr [String] base_url the base url of our api. (expected: http://example.com - without the trailing slash).
|
98
|
+
# @attr [Hash] headers the headers being sent in the request.
|
99
|
+
class << self
|
100
|
+
attr_accessor :base_url, :headers
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_response(net_response)
|
104
|
+
@builder.new(net_response).build
|
105
|
+
end
|
106
|
+
|
107
|
+
def query_url
|
108
|
+
@base_url
|
109
|
+
end
|
110
|
+
|
111
|
+
def default_headers
|
112
|
+
{ 'Accept' => 'application/n-triples' }
|
113
|
+
end
|
114
|
+
|
115
|
+
def add_headers(request)
|
116
|
+
headers = default_headers.merge(@headers)
|
117
|
+
headers.each do |key, value|
|
118
|
+
request.add_field(key, value)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def handle_errors(response)
|
123
|
+
case response
|
124
|
+
when Net::HTTPSuccess # 2xx Status
|
125
|
+
exception_class = Parliament::NoContentResponseError if response.code == '204'
|
126
|
+
when Net::HTTPClientError # 4xx Status
|
127
|
+
exception_class = Parliament::ClientError
|
128
|
+
when Net::HTTPServerError # 5xx Status
|
129
|
+
exception_class = Parliament::ServerError
|
130
|
+
end
|
131
|
+
|
132
|
+
raise exception_class.new(query_url, response) if exception_class
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Parliament
|
2
|
+
module Request
|
3
|
+
class OpenSearchRequest < Parliament::Request::BaseRequest
|
4
|
+
OPEN_SEARCH_PARAMETERS = {
|
5
|
+
count: 10,
|
6
|
+
start_index: 1,
|
7
|
+
start_page: 1,
|
8
|
+
language: '*',
|
9
|
+
output_encoding: 'UTF-8',
|
10
|
+
input_encoding: 'UTF-8'
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
def initialize(base_url: nil, headers: nil, builder: nil)
|
14
|
+
@base_url = Parliament::Request::OpenSearchRequest.get_description(base_url) || self.class.base_url || ENV['OPENSEARCH_DESCRIPTION_URL']
|
15
|
+
@open_search_parameters = self.class.open_search_parameters
|
16
|
+
|
17
|
+
super(base_url: @base_url, headers: headers, builder: builder)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get(search_params, params: nil)
|
21
|
+
setup_query_url(search_params)
|
22
|
+
|
23
|
+
super(params: params)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
class << self
|
29
|
+
attr_reader :base_url, :open_search_parameters
|
30
|
+
|
31
|
+
def base_url=(base_url)
|
32
|
+
@base_url = get_description(base_url)
|
33
|
+
end
|
34
|
+
|
35
|
+
def open_search_parameters
|
36
|
+
OPEN_SEARCH_PARAMETERS.dup
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_description(url)
|
40
|
+
return if url.nil?
|
41
|
+
|
42
|
+
request = Parliament::Request::BaseRequest.new(base_url: url,
|
43
|
+
headers: { 'Accept' => 'application/opensearchdescription+xml' })
|
44
|
+
xml_response = request.get
|
45
|
+
|
46
|
+
xml_root = REXML::Document.new(xml_response.body).root
|
47
|
+
xml_root.elements['Url'].attributes['template']
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def query_url
|
52
|
+
@query_url
|
53
|
+
end
|
54
|
+
|
55
|
+
def setup_query_url(search_params)
|
56
|
+
search_terms = search_params[:query]
|
57
|
+
query_url = @base_url.dup
|
58
|
+
query_url.gsub!('{searchTerms}', search_terms)
|
59
|
+
|
60
|
+
@open_search_parameters.each do |key, value|
|
61
|
+
camel_case_key = ActiveSupport::Inflector.camelize(key.to_s, false)
|
62
|
+
if search_params.keys.include?(key)
|
63
|
+
query_url.gsub!("{#{camel_case_key}?}", search_params[key].to_s)
|
64
|
+
else
|
65
|
+
query_url.gsub!("{#{camel_case_key}?}", value.to_s)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
@query_url = query_url
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Parliament
|
2
|
+
module Request
|
3
|
+
class UrlRequest < Parliament::Request::BaseRequest
|
4
|
+
def initialize(base_url: nil, headers: nil, builder: nil)
|
5
|
+
@endpoint_parts = []
|
6
|
+
base_url ||= ENV['PARLIAMENT_BASE_URL']
|
7
|
+
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
# Overrides ruby's method_missing to allow creation of URLs through method calls.
|
12
|
+
#
|
13
|
+
# @example Adding a simple URL part
|
14
|
+
# request = Parliament::Request.new(base_url: 'http://example.com')
|
15
|
+
#
|
16
|
+
# # url: http://example.com/people
|
17
|
+
# request.people
|
18
|
+
#
|
19
|
+
# @example Adding a simple URL part with parameters
|
20
|
+
# request = Parliament::Request.new(base_url: 'http://example.com')
|
21
|
+
#
|
22
|
+
# # url: http://example.com/people/123456
|
23
|
+
# request.people('123456')
|
24
|
+
#
|
25
|
+
# @example Chaining URL parts and using hyphens
|
26
|
+
# request = Parliament::Request.new(base_url: 'http://example.com')
|
27
|
+
#
|
28
|
+
# # url: http://example.com/people/123456/foo/bar/hello-world/7890
|
29
|
+
# request.people('123456').foo.bar('hello-world', '7890')
|
30
|
+
#
|
31
|
+
# @param [Symbol] method the 'method' (url part) we are processing.
|
32
|
+
# @param [Array<Object>] params parameters passed to the specified method (url part).
|
33
|
+
# @param [Block] block additional block (kept for compatibility with method_missing API).
|
34
|
+
#
|
35
|
+
# @return [Parliament::Request] self.
|
36
|
+
def method_missing(method, *params, &block)
|
37
|
+
@endpoint_parts << method.to_s
|
38
|
+
@endpoint_parts << params
|
39
|
+
@endpoint_parts = @endpoint_parts.flatten!
|
40
|
+
|
41
|
+
block&.call
|
42
|
+
|
43
|
+
self || super
|
44
|
+
end
|
45
|
+
|
46
|
+
# This class always responds to method calls, even those missing. Therefore, respond_to_missing? always returns true.
|
47
|
+
#
|
48
|
+
# @return [Boolean] always returns true.
|
49
|
+
def respond_to_missing?(_, _ = false)
|
50
|
+
true # responds to everything, always
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def query_url
|
56
|
+
[@base_url, @endpoint_parts].join('/')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/parliament/request.rb
CHANGED
@@ -6,193 +6,7 @@ module Parliament
|
|
6
6
|
#
|
7
7
|
# @attr_reader [String] base_url the base url of our api. (expected: http://example.com - without the trailing slash).
|
8
8
|
# @attr_reader [Hash] headers the headers being sent in the request.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# Creates a new instance of Parliament::Request.
|
13
|
-
#
|
14
|
-
# An interesting note for #initialize is that setting base_url on the class, or using the environment variable
|
15
|
-
# PARLIAMENT_BASE_URL means you don't need to pass in a base_url. You can pass one anyway to override the
|
16
|
-
# environment variable or class parameter. Similarly, headers can be set by either settings the headers on the class, or passing headers in.
|
17
|
-
#
|
18
|
-
# @example Setting the base_url on the class
|
19
|
-
# Parliament::Request.base_url = 'http://example.com'
|
20
|
-
#
|
21
|
-
# Parliament::Request.new.base_url #=> 'http://example.com'
|
22
|
-
#
|
23
|
-
# @example Setting the base_url via environment variable
|
24
|
-
# ENV['PARLIAMENT_BASE_URL'] #=> 'http://test.com'
|
25
|
-
#
|
26
|
-
# Parliament::Request.new.base_url #=> 'http://test.com'
|
27
|
-
#
|
28
|
-
# @example Setting the base_url via a parameter
|
29
|
-
# Parliament::Request.base_url #=> nil
|
30
|
-
# ENV['PARLIAMENT_BASE_URL'] #=> nil
|
31
|
-
#
|
32
|
-
# Parliament::Request.new(base_url: 'http://example.com').base_url #=> 'http://example.com'
|
33
|
-
#
|
34
|
-
# @example Overriding the base_url via a parameter
|
35
|
-
# ENV['PARLIAMENT_BASE_URL'] #=> 'http://test.com'
|
36
|
-
#
|
37
|
-
# Parliament::Request.new(base_url: 'http://example.com').base_url #=> 'http://example.com'
|
38
|
-
#
|
39
|
-
# @example Setting the headers on the class
|
40
|
-
# Parliament::Request.headers = { 'Accept' => 'Test' }
|
41
|
-
#
|
42
|
-
# Parliament::Request.new.headers #=> '{ 'Accept' => 'Test' }
|
43
|
-
#
|
44
|
-
# @example Setting the headers via a parameter
|
45
|
-
# Parliament::Request.headers #=> nil
|
46
|
-
#
|
47
|
-
# Parliament::Request.new(headers: '{ 'Accept' => 'Test' }).headers #=> { 'Accept' => 'Test' }
|
48
|
-
#
|
49
|
-
# @example Overriding the headers via a parameter
|
50
|
-
# Parliament::Request.headers = { 'Accept' => 'Test' }
|
51
|
-
#
|
52
|
-
# Parliament::Request.new(headers: '{ 'Accept' => 'Test2' }).headers #=> { 'Accept' => 'Test2' }
|
53
|
-
#
|
54
|
-
# @param [String] base_url the base url of our api. (expected: http://example.com - without the trailing slash).
|
55
|
-
# @param [Hash] headers the headers being sent in the request.
|
56
|
-
def initialize(base_url: nil, headers: nil)
|
57
|
-
@endpoint_parts = []
|
58
|
-
@base_url = base_url || self.class.base_url || ENV['PARLIAMENT_BASE_URL']
|
59
|
-
@headers = headers || self.class.headers || {}
|
60
|
-
end
|
61
|
-
|
62
|
-
# Overrides ruby's method_missing to allow creation of URLs through method calls.
|
63
|
-
#
|
64
|
-
# @example Adding a simple URL part
|
65
|
-
# request = Parliament::Request.new(base_url: 'http://example.com')
|
66
|
-
#
|
67
|
-
# # url: http://example.com/people
|
68
|
-
# request.people
|
69
|
-
#
|
70
|
-
# @example Adding a simple URL part with parameters
|
71
|
-
# request = Parliament::Request.new(base_url: 'http://example.com')
|
72
|
-
#
|
73
|
-
# # url: http://example.com/people/123456
|
74
|
-
# request.people('123456')
|
75
|
-
#
|
76
|
-
# @example Chaining URL parts and using hyphens
|
77
|
-
# request = Parliament::Request.new(base_url: 'http://example.com')
|
78
|
-
#
|
79
|
-
# # url: http://example.com/people/123456/foo/bar/hello-world/7890
|
80
|
-
# request.people('123456').foo.bar('hello-world', '7890')
|
81
|
-
#
|
82
|
-
# @param [Symbol] method the 'method' (url part) we are processing.
|
83
|
-
# @param [Array<Object>] params parameters passed to the specified method (url part).
|
84
|
-
# @param [Block] block additional block (kept for compatibility with method_missing API).
|
85
|
-
#
|
86
|
-
# @return [Parliament::Request] self.
|
87
|
-
def method_missing(method, *params, &block)
|
88
|
-
@endpoint_parts << method.to_s
|
89
|
-
@endpoint_parts << params
|
90
|
-
@endpoint_parts = @endpoint_parts.flatten!
|
91
|
-
|
92
|
-
block&.call
|
93
|
-
|
94
|
-
self || super
|
95
|
-
end
|
96
|
-
|
97
|
-
# This class always responds to method calls, even those missing. Therefore, respond_to_missing? always returns true.
|
98
|
-
#
|
99
|
-
# @return [Boolean] always returns true.
|
100
|
-
def respond_to_missing?(_, _ = false)
|
101
|
-
true # responds to everything, always
|
102
|
-
end
|
103
|
-
|
104
|
-
# Using our url built via #method_missing, make a HTTP GET request and process results into a response.
|
105
|
-
#
|
106
|
-
# @example HTTP GET request
|
107
|
-
# request = Parliament::Request.new(base_url: 'http://example.com')
|
108
|
-
#
|
109
|
-
# # url: http://example.com/people/123456
|
110
|
-
# response = request.people('123456').get #=> #<Parliament::Response ...>
|
111
|
-
#
|
112
|
-
# @example HTTP GET request with URI encoded form values
|
113
|
-
# request = Parliament::Request.new(base_url: 'http://example.com')
|
114
|
-
#
|
115
|
-
# # url: http://example.com/people/current?limit=10&page=4&lang=en-gb
|
116
|
-
# response = request.people.current.get({ limit: 10, page: 4, lang: 'en-gb' }) #=> #<Parliament::Response ...>
|
117
|
-
#
|
118
|
-
# @raise [Parliament::ServerError] when the server responds with a 5xx status code.
|
119
|
-
# @raise [Parliament::ClientError] when the server responds with a 4xx status code.
|
120
|
-
# @raise [Parliament::NoContentResponseError] when the server responds with a 204 status code.
|
121
|
-
#
|
122
|
-
# @param [Hash] params (optional) additional URI encoded form values to be added to the URI.
|
123
|
-
#
|
124
|
-
# @return [Parliament::Response] a Parliament::Response object containing all of the nodes returned from the URL.
|
125
|
-
def get(params: nil)
|
126
|
-
endpoint_uri = URI.parse(api_endpoint)
|
127
|
-
endpoint_uri.query = URI.encode_www_form(params.to_a) unless params.nil?
|
128
|
-
|
129
|
-
http = Net::HTTP.new(endpoint_uri.host, endpoint_uri.port)
|
130
|
-
http.use_ssl = true if endpoint_uri.scheme == 'https'
|
131
|
-
|
132
|
-
net_response = http.start do |h|
|
133
|
-
api_request = Net::HTTP::Get.new(endpoint_uri.request_uri)
|
134
|
-
add_headers(api_request)
|
135
|
-
|
136
|
-
h.request api_request
|
137
|
-
end
|
138
|
-
|
139
|
-
handle_errors(net_response)
|
140
|
-
|
141
|
-
build_parliament_response(net_response)
|
142
|
-
end
|
143
|
-
|
144
|
-
private
|
145
|
-
|
146
|
-
# @attr [String] base_url the base url of our api. (expected: http://example.com - without the trailing slash).
|
147
|
-
# @attr [Hash] headers the headers being sent in the request.
|
148
|
-
class << self
|
149
|
-
attr_accessor :base_url, :headers
|
150
|
-
end
|
151
|
-
|
152
|
-
def default_headers
|
153
|
-
{ 'Accept' => 'application/n-triples' }
|
154
|
-
end
|
155
|
-
|
156
|
-
def add_headers(request)
|
157
|
-
headers = default_headers.merge(@headers)
|
158
|
-
headers.each do |key, value|
|
159
|
-
request.add_field(key, value)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def api_endpoint
|
164
|
-
[@base_url, @endpoint_parts].join('/')
|
165
|
-
end
|
166
|
-
|
167
|
-
def handle_errors(response)
|
168
|
-
case response
|
169
|
-
when Net::HTTPSuccess # 2xx Status
|
170
|
-
exception_class = Parliament::NoContentResponseError if response.code == '204'
|
171
|
-
when Net::HTTPClientError # 4xx Status
|
172
|
-
exception_class = Parliament::ClientError
|
173
|
-
when Net::HTTPServerError # 5xx Status
|
174
|
-
exception_class = Parliament::ServerError
|
175
|
-
end
|
176
|
-
|
177
|
-
raise exception_class.new(api_endpoint, response) if exception_class
|
178
|
-
end
|
179
|
-
|
180
|
-
def build_parliament_response(response)
|
181
|
-
objects = Grom::Reader.new(response.body).objects
|
182
|
-
objects.map { |object| assign_decorator(object) }
|
183
|
-
|
184
|
-
Parliament::Response.new(objects)
|
185
|
-
end
|
186
|
-
|
187
|
-
def assign_decorator(object)
|
188
|
-
return object unless object.respond_to?(:type)
|
189
|
-
|
190
|
-
object_type = Grom::Helper.get_id(object.type)
|
191
|
-
|
192
|
-
return object unless Parliament::Decorator.constants.include?(object_type.to_sym)
|
193
|
-
|
194
|
-
decorator_module = Object.const_get("Parliament::Decorator::#{object_type}")
|
195
|
-
object.extend(decorator_module)
|
196
|
-
end
|
9
|
+
module Request
|
10
|
+
Dir[File.join(File.dirname(__FILE__), '../parliament/request', '*.rb')].each { |request| require request }
|
197
11
|
end
|
198
12
|
end
|
data/lib/parliament/version.rb
CHANGED
data/lib/parliament.rb
CHANGED
data/parliament-ruby.gemspec
CHANGED
@@ -13,7 +13,6 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = 'http://github.com/ukparliament/parliament_ruby'
|
14
14
|
spec.license = 'Nonstandard'
|
15
15
|
|
16
|
-
|
17
16
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
17
|
f.match(%r{^(test|spec|features)/})
|
19
18
|
end
|
@@ -21,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
21
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
21
|
spec.require_paths = ['lib']
|
23
22
|
|
23
|
+
spec.add_dependency 'feedjira', '~> 2.1.2'
|
24
24
|
spec.add_dependency 'grom', '~> 0.3.6'
|
25
25
|
|
26
26
|
spec.add_development_dependency 'bundler', '~> 1.13'
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parliament-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Rayner
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: feedjira
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.1.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.1.2
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: grom
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,6 +158,10 @@ files:
|
|
144
158
|
- bin/console
|
145
159
|
- bin/setup
|
146
160
|
- lib/parliament.rb
|
161
|
+
- lib/parliament/builder.rb
|
162
|
+
- lib/parliament/builder/base_response_builder.rb
|
163
|
+
- lib/parliament/builder/ntriple_response_builder.rb
|
164
|
+
- lib/parliament/builder/open_search_response_builder.rb
|
147
165
|
- lib/parliament/client_error.rb
|
148
166
|
- lib/parliament/decorator.rb
|
149
167
|
- lib/parliament/decorator/constituency_area.rb
|
@@ -163,6 +181,9 @@ files:
|
|
163
181
|
- lib/parliament/network_error.rb
|
164
182
|
- lib/parliament/no_content_response_error.rb
|
165
183
|
- lib/parliament/request.rb
|
184
|
+
- lib/parliament/request/base_request.rb
|
185
|
+
- lib/parliament/request/open_search_request.rb
|
186
|
+
- lib/parliament/request/url_request.rb
|
166
187
|
- lib/parliament/response.rb
|
167
188
|
- lib/parliament/server_error.rb
|
168
189
|
- lib/parliament/utils.rb
|
@@ -183,12 +204,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
204
|
version: '0'
|
184
205
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
206
|
requirements:
|
186
|
-
- - "
|
207
|
+
- - ">"
|
187
208
|
- !ruby/object:Gem::Version
|
188
|
-
version:
|
209
|
+
version: 1.3.1
|
189
210
|
requirements: []
|
190
211
|
rubyforge_project:
|
191
|
-
rubygems_version: 2.6.
|
212
|
+
rubygems_version: 2.6.10
|
192
213
|
signing_key:
|
193
214
|
specification_version: 4
|
194
215
|
summary: Internal parliamentary API wrapper
|