parliament-ruby 0.6.3 → 0.7.0.pre
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.
- 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
|