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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 581a69e9850b75eef39d684fd40f5347ebcf8bb1
4
- data.tar.gz: f28f46585c4dc4cfd9f14735918804e184367d4f
3
+ metadata.gz: 1d6e3ce9cb153b579936aca384cbdb8f73d1c824
4
+ data.tar.gz: 8ab2872d2a93301be8420d3ba7815ef809a855c4
5
5
  SHA512:
6
- metadata.gz: 5e1f64b23a425ee4e1b9c4a816eeb1f583a7c84a382010b0da35c6ef2dfcb5fc5ea0fc5a4bb23764b8b50650edcb5985b718e918bca9b3192137543930d9217c
7
- data.tar.gz: '08882fbca6ac37527cd83420cb0a6d1a8bbf120db74e73ebdc8114548b40110d988948fdeaf37c97e803f5d791adf15d81d0cf8a7813080462cfe6b9d9c35cc8'
6
+ metadata.gz: a7ba819f59a91286db8a2dd132b1b61d590e057ba93347da04692c87d0d10da37f03b9beeeda90aed8b18adf19871ecae6052da1eec46b2696166fd989b5ca8f
7
+ data.tar.gz: 18aa6d056e56843c7d08456d6b3a3b78dcdeeeac8ab2aecd78ded20b5ae785d80095755c607daa110663db61a9e0bab81ae9e2b65a16bdbbe67d379484af3f60
data/Gemfile CHANGED
@@ -5,3 +5,6 @@ gemspec
5
5
 
6
6
  # Include coveralls for CI coverage reports
7
7
  gem 'coveralls', require: false
8
+
9
+ gem 'pry'
10
+ gem 'rb-readline'
@@ -0,0 +1,13 @@
1
+ module Parliament
2
+ module Builder
3
+ class BaseResponseBuilder
4
+ def initialize(response)
5
+ @response = response
6
+ end
7
+
8
+ def build
9
+ @response
10
+ end
11
+ end
12
+ end
13
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ module Parliament
2
+ module Builder
3
+ Dir[File.join(File.dirname(__FILE__), '../parliament/builder', '*.rb')].each { |builder| require builder }
4
+ end
5
+ 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
- has_end_date = respond_to?(:incumbencyEndDate)
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
- has_end_date = respond_to?(:incumbencyEndDate)
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
- has_end_date = respond_to?(:partyMembershipEndDate)
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
- full_name += respond_to?(:personGivenName) ? personGivenName + ' ' : ''
40
- full_name += respond_to?(:personFamilyName) ? personFamilyName : ''
41
- full_name.rstrip
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
- if respond_to?(:memberHasIncumbency)
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
- if respond_to?(:memberHasIncumbency)
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
- return @seats unless @seats.nil?
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
- return @houses unless @houses.nil?
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
- return @constituencies unless @constituencies.nil?
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
- return @parties unless @parties.nil?
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 an end date.
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
- has_end_date = respond_to?(:incumbencyEndDate)
30
+ !former?
31
+ end
31
32
 
32
- !has_end_date
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
@@ -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
- class Request
10
- attr_reader :base_url, :headers
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
@@ -1,3 +1,3 @@
1
1
  module Parliament
2
- VERSION = '0.6.3'.freeze
2
+ VERSION = '0.7.0.pre'.freeze
3
3
  end
data/lib/parliament.rb CHANGED
@@ -6,6 +6,7 @@ require 'parliament/request'
6
6
  require 'parliament/response'
7
7
  require 'parliament/utils'
8
8
  require 'parliament/decorator'
9
+ require 'parliament/builder'
9
10
 
10
11
  require 'parliament/network_error'
11
12
  require 'parliament/client_error'
@@ -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.6.3
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-03-31 00:00:00.000000000 Z
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: '0'
209
+ version: 1.3.1
189
210
  requirements: []
190
211
  rubyforge_project:
191
- rubygems_version: 2.6.6
212
+ rubygems_version: 2.6.10
192
213
  signing_key:
193
214
  specification_version: 4
194
215
  summary: Internal parliamentary API wrapper