spark_api 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +86 -3
- data/VERSION +1 -1
- data/lib/spark_api.rb +1 -0
- data/lib/spark_api/authentication/oauth2.rb +43 -2
- data/lib/spark_api/configuration/oauth2_configurable.rb +3 -1
- data/lib/spark_api/models.rb +1 -0
- data/lib/spark_api/models/listing.rb +17 -1
- data/lib/spark_api/models/rental_calendar.rb +26 -0
- data/lib/spark_api/options_hash.rb +18 -0
- data/script/combined_flow_example.rb +55 -0
- data/script/oauth2_example.rb +2 -2
- data/spec/fixtures/listings/rental_calendar.json +19 -0
- data/spec/fixtures/listings/with_rental_calendar.json +52 -0
- data/spec/unit/spark_api/authentication/oauth2_spec.rb +79 -1
- data/spec/unit/spark_api/models/listing_spec.rb +7 -0
- data/spec/unit/spark_api/models/rental_calendar_spec.rb +30 -0
- data/spec/unit/spark_api/options_hash_spec.rb +14 -0
- metadata +15 -96
- data/bin/spark_api~ +0 -8
- data/lib/spark_api/authentication/api_auth.rb~ +0 -104
- data/lib/spark_api/authentication/base_auth.rb~ +0 -47
- data/lib/spark_api/authentication/oauth2.rb~ +0 -199
- data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb~ +0 -87
- data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb~ +0 -49
- data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb~ +0 -45
- data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb~ +0 -36
- data/lib/spark_api/authentication/oauth2_impl/middleware.rb~ +0 -39
- data/lib/spark_api/authentication/oauth2_impl/password_provider.rb~ +0 -25
- data/lib/spark_api/cli.rb~ +0 -158
- data/lib/spark_api/cli/api_auth.rb~ +0 -8
- data/lib/spark_api/cli/oauth2.rb~ +0 -14
- data/lib/spark_api/cli/setup.rb~ +0 -47
- data/lib/spark_api/configuration.rb~ +0 -54
- data/lib/spark_api/configuration/yaml.rb~ +0 -101
- data/lib/spark_api/faraday.rb~ +0 -64
- data/lib/spark_api/models.rb~ +0 -33
- data/lib/spark_api/models/account.rb~ +0 -115
- data/lib/spark_api/models/base.rb~ +0 -118
- data/lib/spark_api/models/connect_prefs.rb~ +0 -10
- data/lib/spark_api/models/constraint.rb~ +0 -16
- data/lib/spark_api/models/contact.rb~ +0 -49
- data/lib/spark_api/models/custom_fields.rb~ +0 -12
- data/lib/spark_api/models/document.rb~ +0 -11
- data/lib/spark_api/models/finders.rb~ +0 -45
- data/lib/spark_api/models/idx_link.rb~ +0 -47
- data/lib/spark_api/models/listing.rb~ +0 -197
- data/lib/spark_api/models/listing_cart.rb~ +0 -72
- data/lib/spark_api/models/market_statistics.rb~ +0 -33
- data/lib/spark_api/models/message.rb~ +0 -21
- data/lib/spark_api/models/note.rb~ +0 -41
- data/lib/spark_api/models/notification.rb~ +0 -42
- data/lib/spark_api/models/open_house.rb~ +0 -24
- data/lib/spark_api/models/photo.rb~ +0 -70
- data/lib/spark_api/models/property_types.rb~ +0 -7
- data/lib/spark_api/models/saved_search.rb~ +0 -16
- data/lib/spark_api/models/shared_listing.rb~ +0 -35
- data/lib/spark_api/models/standard_fields.rb~ +0 -50
- data/lib/spark_api/models/subresource.rb~ +0 -19
- data/lib/spark_api/models/system_info.rb~ +0 -14
- data/lib/spark_api/models/tour_of_home.rb~ +0 -24
- data/lib/spark_api/models/video.rb~ +0 -16
- data/lib/spark_api/models/virtual_tour.rb~ +0 -18
- data/lib/spark_api/multi_client.rb~ +0 -59
- data/lib/spark_api/paginate.rb~ +0 -109
- data/lib/spark_api/primary_array.rb~ +0 -29
- data/lib/spark_api/request.rb~ +0 -96
- data/lib/spark_api/response.rb~ +0 -70
- data/lib/spark_api/version.rb~ +0 -4
- data/script/console~ +0 -6
- data/script/example.rb~ +0 -27
- data/spec/unit/flexmls_api_spec.rb~ +0 -23
- data/spec/unit/spark_api/authentication/api_auth_spec.rb~ +0 -169
- data/spec/unit/spark_api/authentication/base_auth_spec.rb~ +0 -10
- data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb~ +0 -10
- data/spec/unit/spark_api/authentication/oauth2_spec.rb~ +0 -205
- data/spec/unit/spark_api/authentication_spec.rb~ +0 -38
- data/spec/unit/spark_api/configuration/yaml_spec.rb~ +0 -72
- data/spec/unit/spark_api/configuration_spec.rb~ +0 -122
- data/spec/unit/spark_api/faraday_spec.rb~ +0 -90
- data/spec/unit/spark_api/models/contact_spec.rb~ +0 -108
- data/spec/unit/spark_api/models/listing_cart_spec.rb~ +0 -127
- data/spec/unit/spark_api/models/listing_spec.rb~ +0 -320
- data/spec/unit/spark_api/models/message_spec.rb~ +0 -47
- data/spec/unit/spark_api/models/note_spec.rb~ +0 -63
- data/spec/unit/spark_api/models/notification_spec.rb~ +0 -62
- data/spec/unit/spark_api/models/shared_listing_spec.rb~ +0 -45
- data/spec/unit/spark_api/multi_client_spec.rb~ +0 -56
- data/spec/unit/spark_api/paginate_spec.rb~ +0 -224
- data/spec/unit/spark_api/primary_array_spec.rb~ +0 -41
- data/spec/unit/spark_api/request_spec.rb~ +0 -344
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require 'date'
|
|
2
|
-
require 'time'
|
|
3
|
-
|
|
4
|
-
module FlexmlsApi
|
|
5
|
-
module Models
|
|
6
|
-
class OpenHouse < Base
|
|
7
|
-
extend Subresource
|
|
8
|
-
|
|
9
|
-
self.element_name = "openhouses"
|
|
10
|
-
|
|
11
|
-
def initialize(attributes={})
|
|
12
|
-
# Transform the date strings
|
|
13
|
-
unless attributes['Date'].nil?
|
|
14
|
-
date = Date.parse(attributes['Date'])
|
|
15
|
-
attributes['Date'] = date
|
|
16
|
-
attributes['StartTime'] = Time.parse("#{date}T#{attributes['StartTime']}") unless attributes['StartTime'].nil?
|
|
17
|
-
attributes['EndTime'] = Time.parse("#{date}T#{attributes['EndTime']}") unless attributes['EndTime'].nil?
|
|
18
|
-
end
|
|
19
|
-
super(attributes)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
module Models
|
|
3
|
-
class Photo < Base
|
|
4
|
-
extend Subresource
|
|
5
|
-
self.element_name = "photos"
|
|
6
|
-
|
|
7
|
-
attr_accessor :update_path
|
|
8
|
-
|
|
9
|
-
EDITABLE_FIELDS = [:Picture, :FileName, :Name, :Caption, :Primary]
|
|
10
|
-
|
|
11
|
-
def initialize(opts={})
|
|
12
|
-
defaulted_opts = {}
|
|
13
|
-
EDITABLE_FIELDS.each do |k|
|
|
14
|
-
key = k.to_s()
|
|
15
|
-
defaulted_opts[key] = opts[key] || nil
|
|
16
|
-
end
|
|
17
|
-
super(opts.merge(defaulted_opts))
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def primary?
|
|
21
|
-
@attributes["Primary"] == true
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def save(arguments={})
|
|
25
|
-
begin
|
|
26
|
-
return save!(arguments)
|
|
27
|
-
rescue NotFound, BadResourceRequest => e
|
|
28
|
-
FlexmlsApi.logger.error("Failed to save resource #{self}: #{e.message}")
|
|
29
|
-
end
|
|
30
|
-
false
|
|
31
|
-
end
|
|
32
|
-
def save!(arguments={})
|
|
33
|
-
payload = {"Photos" => [ build_photo_hash]}
|
|
34
|
-
if exists?
|
|
35
|
-
results = connection.put "#{update_path}/#{self.Id}", payload, arguments
|
|
36
|
-
else
|
|
37
|
-
results = connection.post update_path, payload, arguments
|
|
38
|
-
end
|
|
39
|
-
result = results.first
|
|
40
|
-
load(result)
|
|
41
|
-
true
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def load_picture(file_name)
|
|
45
|
-
self.Picture = Base64.encode64(File.open(file_name, 'rb').read).gsub(/\n/, '')
|
|
46
|
-
self.FileName = File.basename(file_name)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def delete(args={})
|
|
50
|
-
connection.delete("#{update_path}/#{self.Id}", args)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def exists?
|
|
54
|
-
@attributes.include?("Id")
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
private
|
|
58
|
-
|
|
59
|
-
def build_photo_hash
|
|
60
|
-
results_hash = {}
|
|
61
|
-
EDITABLE_FIELDS.each do |k|
|
|
62
|
-
key = k.to_s
|
|
63
|
-
results_hash[key] = @attributes[key] unless @attributes[key].nil?
|
|
64
|
-
end
|
|
65
|
-
results_hash
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
module Models
|
|
3
|
-
class SavedSearch < Base
|
|
4
|
-
extend Finders
|
|
5
|
-
self.element_name="savedsearches"
|
|
6
|
-
|
|
7
|
-
def self.provided()
|
|
8
|
-
Class.new(self).tap do |provided|
|
|
9
|
-
provided.element_name = '/savedsearches'
|
|
10
|
-
provided.prefix = '/provided'
|
|
11
|
-
FlexmlsApi.logger.info("#{self.name}.path: #{provided.path}")
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
module Models
|
|
3
|
-
class SharedListing < Base
|
|
4
|
-
extend Finders
|
|
5
|
-
self.element_name="sharedlistings"
|
|
6
|
-
|
|
7
|
-
def ListingIds=(listing_ids)
|
|
8
|
-
attributes["ListingIds"] = Array(listing_ids)
|
|
9
|
-
end
|
|
10
|
-
def ViewId=(id)
|
|
11
|
-
attributes["ViewId"] = id
|
|
12
|
-
end
|
|
13
|
-
def ReportId=(id)
|
|
14
|
-
attributes["ReportId"] = id
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def save(arguments={})
|
|
18
|
-
begin
|
|
19
|
-
return save!(arguments)
|
|
20
|
-
rescue BadResourceRequest => e
|
|
21
|
-
rescue NotFound => e
|
|
22
|
-
# log and leave
|
|
23
|
-
FlexmlsApi.logger.error("Failed to save SharedListing #{self}: #{e.message}")
|
|
24
|
-
end
|
|
25
|
-
false
|
|
26
|
-
end
|
|
27
|
-
def save!(arguments={})
|
|
28
|
-
results = connection.post self.class.path, attributes, arguments
|
|
29
|
-
result = results.first
|
|
30
|
-
attributes['ResourceUri'] = result['ResourceUri']
|
|
31
|
-
true
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
module Models
|
|
3
|
-
class StandardFields < Base
|
|
4
|
-
extend Finders
|
|
5
|
-
self.element_name="standardfields"
|
|
6
|
-
|
|
7
|
-
# expand all fields passed in
|
|
8
|
-
def self.find_and_expand_all(fields, arguments={}, max_list_size=1000)
|
|
9
|
-
returns = {}
|
|
10
|
-
|
|
11
|
-
# find all standard fields, but expand only the location fields
|
|
12
|
-
# TODO: when _expand support is added to StandardFields API, use the following
|
|
13
|
-
# standard_fields = find(:all, {:ApiUser => owner, :_expand => fields.join(",")})
|
|
14
|
-
standard_fields = find(:all, arguments)
|
|
15
|
-
|
|
16
|
-
# filter through the list and return only the location fields found
|
|
17
|
-
fields.each do |field|
|
|
18
|
-
# search for field in the payload
|
|
19
|
-
if standard_fields.first.attributes.has_key?(field)
|
|
20
|
-
returns[field] = standard_fields.first.attributes[field]
|
|
21
|
-
|
|
22
|
-
# lookup fully _expand field, if the field has a list
|
|
23
|
-
if returns[field]['HasList'] && returns[field]['MaxListSize'].to_i <= max_list_size
|
|
24
|
-
returns[field] = connection.get("/standardfields/#{field}", arguments).first[field]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
returns
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# find_nearby: find fields nearby via lat/lon
|
|
35
|
-
def self.find_nearby(prop_types = ["A"], arguments={})
|
|
36
|
-
return_json = {"D" => {"Success" => true, "Results" => []} }
|
|
37
|
-
|
|
38
|
-
# add _expand=1 so the fields are returned
|
|
39
|
-
arguments.merge!({:_expand => 1})
|
|
40
|
-
|
|
41
|
-
# find and return
|
|
42
|
-
return_json["D"]["Results"] = connection.get("/standardfields/nearby/#{prop_types.join(',')}", arguments)
|
|
43
|
-
|
|
44
|
-
# return
|
|
45
|
-
return_json
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
module Models
|
|
3
|
-
module Subresource
|
|
4
|
-
|
|
5
|
-
def build_subclass
|
|
6
|
-
Class.new(self)
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def find_by_listing_key(key, arguments={})
|
|
10
|
-
collect(connection.get("/listings/#{key}#{self.path}", arguments))
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def find_by_id(id, parent_id, arguments={})
|
|
14
|
-
collect(connection.get("/listings/#{parent_id}#{self.path}/#{id}", arguments)).first
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
module Models
|
|
3
|
-
class SystemInfo < Base
|
|
4
|
-
self.element_name="system"
|
|
5
|
-
|
|
6
|
-
def primary_logo
|
|
7
|
-
logo = nil
|
|
8
|
-
mls_logos = attributes['Configuration'].first['MlsLogos']
|
|
9
|
-
logo = mls_logos.first if !mls_logos.nil? and !mls_logos.empty?
|
|
10
|
-
logo
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require 'date'
|
|
2
|
-
require 'time'
|
|
3
|
-
|
|
4
|
-
module FlexmlsApi
|
|
5
|
-
module Models
|
|
6
|
-
class TourOfHome < Base
|
|
7
|
-
extend Subresource
|
|
8
|
-
|
|
9
|
-
self.element_name = "tourofhomes"
|
|
10
|
-
|
|
11
|
-
def initialize(attributes={})
|
|
12
|
-
# Transform the date strings
|
|
13
|
-
unless attributes['Date'].nil?
|
|
14
|
-
date = Date.parse(attributes['Date'])
|
|
15
|
-
attributes['Date'] = date
|
|
16
|
-
attributes['StartTime'] = Time.parse("#{date}T#{attributes['StartTime']}") unless attributes['StartTime'].nil?
|
|
17
|
-
attributes['EndTime'] = Time.parse("#{date}T#{attributes['EndTime']}") unless attributes['EndTime'].nil?
|
|
18
|
-
end
|
|
19
|
-
super(attributes)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
module Models
|
|
3
|
-
class Video < Base
|
|
4
|
-
extend Subresource
|
|
5
|
-
self.element_name = 'videos'
|
|
6
|
-
|
|
7
|
-
def branded?
|
|
8
|
-
attributes['Type'] == 'branded'
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def unbranded?
|
|
12
|
-
attributes['Type'] == 'unbranded'
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
module Models
|
|
3
|
-
class VirtualTour < Base
|
|
4
|
-
extend Subresource
|
|
5
|
-
self.element_name="virtualtours"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def branded?
|
|
9
|
-
attributes["Type"] == "branded"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def unbranded?
|
|
13
|
-
attributes["Type"] == "unbranded"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
module FlexmlsApi
|
|
2
|
-
#===Active support for multiple clients
|
|
3
|
-
module MultiClient
|
|
4
|
-
include FlexmlsApi::Configuration
|
|
5
|
-
|
|
6
|
-
# Activate a specific instance of the client (with appropriate config settings). Each client
|
|
7
|
-
# is lazily instanciated by calling the matching FlexmlsApi.symbol_name method on the
|
|
8
|
-
# FlexmlsApi module. It's the developers responsibility to extend the module and provide this
|
|
9
|
-
# method.
|
|
10
|
-
# Parameters
|
|
11
|
-
# @sym - the unique symbol identifier for a client configuration.
|
|
12
|
-
# &block - a block of code to run with the specified client enabled, after which the original
|
|
13
|
-
# client setting will be reenabled
|
|
14
|
-
def activate(sym)
|
|
15
|
-
if block_given?
|
|
16
|
-
original_client = Thread.current[:flexmls_api_client]
|
|
17
|
-
begin
|
|
18
|
-
activate_client(sym)
|
|
19
|
-
yield
|
|
20
|
-
ensure
|
|
21
|
-
Thread.current[:flexmls_api_client] = original_client
|
|
22
|
-
end
|
|
23
|
-
else
|
|
24
|
-
activate_client(sym)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
|
|
30
|
-
# set the active client for the symbol
|
|
31
|
-
def activate_client(symbol)
|
|
32
|
-
if !Thread.current[symbol].nil?
|
|
33
|
-
active_client = Thread.current[symbol]
|
|
34
|
-
elsif FlexmlsApi.respond_to? symbol
|
|
35
|
-
active_client = FlexmlsApi.send(symbol)
|
|
36
|
-
elsif YamlConfig.exists? symbol.to_s
|
|
37
|
-
active_client = activate_client_from_config(symbol)
|
|
38
|
-
else
|
|
39
|
-
raise ArgumentError, "The symbol #{symbol} is not setup correctly as a multi client key."
|
|
40
|
-
end
|
|
41
|
-
Thread.current[symbol] = active_client
|
|
42
|
-
Thread.current[:flexmls_api_client] = active_client
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def activate_client_from_config(symbol)
|
|
46
|
-
FlexmlsApi.logger.debug("Loading multiclient [#{symbol.to_s}] from config")
|
|
47
|
-
yaml = YamlConfig.build(symbol.to_s)
|
|
48
|
-
if(yaml.oauth2?)
|
|
49
|
-
Client.new(yaml.client_keys.merge({
|
|
50
|
-
:oauth2_provider => Authentication::OAuth2Impl.load_provider(yaml.oauth2_provider, yaml.oauth2_keys),
|
|
51
|
-
:authentication_mode => FlexmlsApi::Authentication::OAuth2,
|
|
52
|
-
}))
|
|
53
|
-
else
|
|
54
|
-
Client.new(yaml.client_keys)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
end
|
|
59
|
-
end
|
data/lib/spark_api/paginate.rb~
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
require 'will_paginate/collection'
|
|
2
|
-
|
|
3
|
-
# =Pagination for api resource collections
|
|
4
|
-
# Will paginate adapter for the api client. Utilizes the same interface as will paginate and returns the
|
|
5
|
-
# same WillPaginate::Collection for finder results.
|
|
6
|
-
module FlexmlsApi
|
|
7
|
-
module Paginate
|
|
8
|
-
|
|
9
|
-
DEFAULT_PAGE_SIZE = 25
|
|
10
|
-
|
|
11
|
-
# == Replacement hook for will_paginate's class method
|
|
12
|
-
# Does a best effort to mimic the will_paginate method of same name. All arguments are
|
|
13
|
-
# passed on to the finder method except the special keys for the options hash listed below.
|
|
14
|
-
#
|
|
15
|
-
# == Special parameters for paginating finders
|
|
16
|
-
# * <tt>:page</tt> -- REQUIRED, but defaults to 1 if false or nil
|
|
17
|
-
# * <tt>:per_page</tt> -- defaults to <tt>CurrentModel.per_page</tt> (which is 25 if not overridden)
|
|
18
|
-
# * <tt>:finder</tt> -- name of the finder used (default: "get"). This needs to be a class finder method on the class
|
|
19
|
-
def paginate(*args)
|
|
20
|
-
options = args.last.is_a?(::Hash) ? args.pop : {}
|
|
21
|
-
page = options.delete(:page) || 1
|
|
22
|
-
items_per_page = options.delete(:per_page) || self.per_page
|
|
23
|
-
finder = (options.delete(:finder) || 'get').to_s
|
|
24
|
-
page_options = {
|
|
25
|
-
"_pagination" => 1,
|
|
26
|
-
"_limit" => items_per_page,
|
|
27
|
-
"_page" => page
|
|
28
|
-
}
|
|
29
|
-
options.merge!(page_options)
|
|
30
|
-
args << options
|
|
31
|
-
collection = send(finder,*args)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# == Instanciate class instances from array of hash representations.
|
|
35
|
-
# Needs to be called by all finders that would like to support paging. Takes the hash result
|
|
36
|
-
# set from the request layer and instanciates instances of the class called for the finder.
|
|
37
|
-
#
|
|
38
|
-
# * result_array -- the results object returned from the api request layer. An array of hashes.
|
|
39
|
-
#
|
|
40
|
-
# :returns:
|
|
41
|
-
# An array of class instances for the Class of the calling finder
|
|
42
|
-
def collect(result_array)
|
|
43
|
-
|
|
44
|
-
# when conducting a count (pagination=count), the result_array is not an array
|
|
45
|
-
# in those cases, simply return the Fixnum
|
|
46
|
-
return result_array unless result_array.kind_of? Array
|
|
47
|
-
|
|
48
|
-
collection = result_array.collect { |item| new(item)}
|
|
49
|
-
result_array.replace(collection)
|
|
50
|
-
result_array
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Default per_page limit set on all models. Override this method in the model such ala the
|
|
54
|
-
# will_paginate gem to change
|
|
55
|
-
def per_page
|
|
56
|
-
DEFAULT_PAGE_SIZE
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# ==Paginate Api Responses
|
|
63
|
-
# Module used by the request layer to decorate the response's results array with paging support.
|
|
64
|
-
# Pagination only happens if the response includes the pagination information as specified by the
|
|
65
|
-
# API.
|
|
66
|
-
module PaginateResponse
|
|
67
|
-
attr_accessor :results
|
|
68
|
-
def method_missing(method_symbol, *arguments)
|
|
69
|
-
if results.respond_to?(method_symbol)
|
|
70
|
-
arguments.empty? ? self.results.send(method_symbol) : self.results.send(method_symbol, arguments)
|
|
71
|
-
else
|
|
72
|
-
super
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# ==Pagination Helpers
|
|
78
|
-
# Helpers to create the pagination collection
|
|
79
|
-
module PaginateHelper
|
|
80
|
-
# ==Enable pagination
|
|
81
|
-
# * results -- array of hashes representing api resources
|
|
82
|
-
# * paging_hash -- the pagination response information from the api representing paging state.
|
|
83
|
-
#
|
|
84
|
-
# :returns:
|
|
85
|
-
# The result set decorated as a WillPaginate::Collection
|
|
86
|
-
def paginate_response(results, paging_hash)
|
|
87
|
-
pager = Pagination.new(paging_hash)
|
|
88
|
-
paged_results = WillPaginate::Collection.create(pager.current_page, pager.page_size, pager.total_rows) do |p|
|
|
89
|
-
p.replace(results)
|
|
90
|
-
end
|
|
91
|
-
paged_results.extend PaginateResponse
|
|
92
|
-
paged_results.results = results
|
|
93
|
-
paged_results
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# ==Pagination
|
|
98
|
-
# Simple class representing the API's pagination response object
|
|
99
|
-
class Pagination
|
|
100
|
-
attr_accessor :total_rows, :page_size, :total_pages, :current_page
|
|
101
|
-
def initialize(hash)
|
|
102
|
-
@total_rows = hash["TotalRows"]
|
|
103
|
-
@page_size = hash["PageSize"]
|
|
104
|
-
@total_pages = hash["TotalPages"]
|
|
105
|
-
@current_page = hash["CurrentPage"]
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
end
|