spark_api 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +139 -0
- data/LICENSE +14 -0
- data/README.md +153 -0
- data/Rakefile +18 -0
- data/VERSION +1 -0
- data/bin/spark_api +8 -0
- data/bin/spark_api~ +8 -0
- data/lib/spark_api.rb +46 -0
- data/lib/spark_api/authentication.rb +55 -0
- data/lib/spark_api/authentication/api_auth.rb +104 -0
- data/lib/spark_api/authentication/api_auth.rb~ +104 -0
- data/lib/spark_api/authentication/base_auth.rb +47 -0
- data/lib/spark_api/authentication/base_auth.rb~ +47 -0
- data/lib/spark_api/authentication/oauth2.rb +198 -0
- data/lib/spark_api/authentication/oauth2.rb~ +199 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb +87 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb~ +87 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb +48 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb~ +49 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb +44 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb~ +45 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb +35 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb~ +36 -0
- data/lib/spark_api/authentication/oauth2_impl/middleware.rb +38 -0
- data/lib/spark_api/authentication/oauth2_impl/middleware.rb~ +39 -0
- data/lib/spark_api/authentication/oauth2_impl/password_provider.rb +24 -0
- data/lib/spark_api/authentication/oauth2_impl/password_provider.rb~ +25 -0
- data/lib/spark_api/cli.rb +158 -0
- data/lib/spark_api/cli.rb~ +158 -0
- data/lib/spark_api/cli/api_auth.rb +8 -0
- data/lib/spark_api/cli/api_auth.rb~ +8 -0
- data/lib/spark_api/cli/oauth2.rb +14 -0
- data/lib/spark_api/cli/oauth2.rb~ +14 -0
- data/lib/spark_api/cli/setup.rb +47 -0
- data/lib/spark_api/cli/setup.rb~ +47 -0
- data/lib/spark_api/client.rb +27 -0
- data/lib/spark_api/configuration.rb +54 -0
- data/lib/spark_api/configuration.rb~ +54 -0
- data/lib/spark_api/configuration/yaml.rb +101 -0
- data/lib/spark_api/configuration/yaml.rb~ +101 -0
- data/lib/spark_api/connection.rb +42 -0
- data/lib/spark_api/faraday.rb +64 -0
- data/lib/spark_api/faraday.rb~ +64 -0
- data/lib/spark_api/models.rb +33 -0
- data/lib/spark_api/models.rb~ +33 -0
- data/lib/spark_api/models/account.rb +115 -0
- data/lib/spark_api/models/account.rb~ +115 -0
- data/lib/spark_api/models/base.rb +118 -0
- data/lib/spark_api/models/base.rb~ +118 -0
- data/lib/spark_api/models/connect_prefs.rb +10 -0
- data/lib/spark_api/models/connect_prefs.rb~ +10 -0
- data/lib/spark_api/models/constraint.rb +16 -0
- data/lib/spark_api/models/constraint.rb~ +16 -0
- data/lib/spark_api/models/contact.rb +49 -0
- data/lib/spark_api/models/contact.rb~ +49 -0
- data/lib/spark_api/models/custom_fields.rb +12 -0
- data/lib/spark_api/models/custom_fields.rb~ +12 -0
- data/lib/spark_api/models/document.rb +11 -0
- data/lib/spark_api/models/document.rb~ +11 -0
- data/lib/spark_api/models/finders.rb +45 -0
- data/lib/spark_api/models/finders.rb~ +45 -0
- data/lib/spark_api/models/idx_link.rb +47 -0
- data/lib/spark_api/models/idx_link.rb~ +47 -0
- data/lib/spark_api/models/listing.rb +197 -0
- data/lib/spark_api/models/listing.rb~ +197 -0
- data/lib/spark_api/models/listing_cart.rb +72 -0
- data/lib/spark_api/models/listing_cart.rb~ +72 -0
- data/lib/spark_api/models/market_statistics.rb +33 -0
- data/lib/spark_api/models/market_statistics.rb~ +33 -0
- data/lib/spark_api/models/message.rb +21 -0
- data/lib/spark_api/models/message.rb~ +21 -0
- data/lib/spark_api/models/note.rb +41 -0
- data/lib/spark_api/models/note.rb~ +41 -0
- data/lib/spark_api/models/notification.rb +42 -0
- data/lib/spark_api/models/notification.rb~ +42 -0
- data/lib/spark_api/models/open_house.rb +24 -0
- data/lib/spark_api/models/open_house.rb~ +24 -0
- data/lib/spark_api/models/photo.rb +70 -0
- data/lib/spark_api/models/photo.rb~ +70 -0
- data/lib/spark_api/models/property_types.rb +7 -0
- data/lib/spark_api/models/property_types.rb~ +7 -0
- data/lib/spark_api/models/saved_search.rb +16 -0
- data/lib/spark_api/models/saved_search.rb~ +16 -0
- data/lib/spark_api/models/shared_listing.rb +35 -0
- data/lib/spark_api/models/shared_listing.rb~ +35 -0
- data/lib/spark_api/models/standard_fields.rb +50 -0
- data/lib/spark_api/models/standard_fields.rb~ +50 -0
- data/lib/spark_api/models/subresource.rb +19 -0
- data/lib/spark_api/models/subresource.rb~ +19 -0
- data/lib/spark_api/models/system_info.rb +14 -0
- data/lib/spark_api/models/system_info.rb~ +14 -0
- data/lib/spark_api/models/tour_of_home.rb +24 -0
- data/lib/spark_api/models/tour_of_home.rb~ +24 -0
- data/lib/spark_api/models/video.rb +16 -0
- data/lib/spark_api/models/video.rb~ +16 -0
- data/lib/spark_api/models/virtual_tour.rb +18 -0
- data/lib/spark_api/models/virtual_tour.rb~ +18 -0
- data/lib/spark_api/multi_client.rb +59 -0
- data/lib/spark_api/multi_client.rb~ +59 -0
- data/lib/spark_api/paginate.rb +109 -0
- data/lib/spark_api/paginate.rb~ +109 -0
- data/lib/spark_api/primary_array.rb +29 -0
- data/lib/spark_api/primary_array.rb~ +29 -0
- data/lib/spark_api/request.rb +96 -0
- data/lib/spark_api/request.rb~ +96 -0
- data/lib/spark_api/response.rb +70 -0
- data/lib/spark_api/response.rb~ +70 -0
- data/lib/spark_api/version.rb +4 -0
- data/lib/spark_api/version.rb~ +4 -0
- data/script/console +6 -0
- data/script/console~ +6 -0
- data/script/example.rb +27 -0
- data/script/example.rb~ +27 -0
- data/spec/fixtures/accounts/all.json +160 -0
- data/spec/fixtures/accounts/my.json +74 -0
- data/spec/fixtures/accounts/my_portal.json +20 -0
- data/spec/fixtures/accounts/my_put.json +5 -0
- data/spec/fixtures/accounts/my_save.json +5 -0
- data/spec/fixtures/accounts/office.json +142 -0
- data/spec/fixtures/accounts/password_save.json +6 -0
- data/spec/fixtures/authentication_failure.json +7 -0
- data/spec/fixtures/base.json +13 -0
- data/spec/fixtures/contacts/contacts.json +28 -0
- data/spec/fixtures/contacts/my.json +19 -0
- data/spec/fixtures/contacts/new.json +11 -0
- data/spec/fixtures/contacts/new_empty.json +8 -0
- data/spec/fixtures/contacts/new_notify.json +11 -0
- data/spec/fixtures/contacts/post.json +10 -0
- data/spec/fixtures/contacts/tags.json +11 -0
- data/spec/fixtures/count.json +10 -0
- data/spec/fixtures/empty.json +3 -0
- data/spec/fixtures/errors/expired.json +7 -0
- data/spec/fixtures/errors/failure.json +5 -0
- data/spec/fixtures/errors/failure_with_constraint.json +17 -0
- data/spec/fixtures/errors/failure_with_msg.json +7 -0
- data/spec/fixtures/generic_delete.json +1 -0
- data/spec/fixtures/generic_failure.json +5 -0
- data/spec/fixtures/listing_carts/add_listing.json +13 -0
- data/spec/fixtures/listing_carts/add_listing_post.json +5 -0
- data/spec/fixtures/listing_carts/empty.json +5 -0
- data/spec/fixtures/listing_carts/listing_cart.json +19 -0
- data/spec/fixtures/listing_carts/new.json +12 -0
- data/spec/fixtures/listing_carts/post.json +10 -0
- data/spec/fixtures/listing_carts/remove_listing.json +13 -0
- data/spec/fixtures/listings/constraints.json +18 -0
- data/spec/fixtures/listings/constraints_with_pagination.json +24 -0
- data/spec/fixtures/listings/document_index.json +19 -0
- data/spec/fixtures/listings/multiple.json +69 -0
- data/spec/fixtures/listings/no_subresources.json +38 -0
- data/spec/fixtures/listings/open_houses.json +21 -0
- data/spec/fixtures/listings/photos/index.json +469 -0
- data/spec/fixtures/listings/photos/new.json +12 -0
- data/spec/fixtures/listings/photos/post.json +20 -0
- data/spec/fixtures/listings/put.json +5 -0
- data/spec/fixtures/listings/put_expiration_date.json +5 -0
- data/spec/fixtures/listings/saved_search.json +17 -0
- data/spec/fixtures/listings/shared_listing_get.json +14 -0
- data/spec/fixtures/listings/shared_listing_new.json +9 -0
- data/spec/fixtures/listings/shared_listing_post.json +10 -0
- data/spec/fixtures/listings/tour_of_homes.json +23 -0
- data/spec/fixtures/listings/videos_index.json +18 -0
- data/spec/fixtures/listings/virtual_tours_index.json +42 -0
- data/spec/fixtures/listings/with_documents.json +52 -0
- data/spec/fixtures/listings/with_permissions.json +44 -0
- data/spec/fixtures/listings/with_photos.json +110 -0
- data/spec/fixtures/listings/with_supplement.json +39 -0
- data/spec/fixtures/listings/with_videos.json +54 -0
- data/spec/fixtures/listings/with_vtour.json +48 -0
- data/spec/fixtures/logo_fbs.png +0 -0
- data/spec/fixtures/messages/new.json +14 -0
- data/spec/fixtures/messages/new_empty.json +7 -0
- data/spec/fixtures/messages/new_with_recipients.json +15 -0
- data/spec/fixtures/messages/post.json +5 -0
- data/spec/fixtures/notes/add.json +11 -0
- data/spec/fixtures/notes/agent_shared.json +11 -0
- data/spec/fixtures/notes/agent_shared_empty.json +7 -0
- data/spec/fixtures/notes/new.json +5 -0
- data/spec/fixtures/notifications/mark_read.json +1 -0
- data/spec/fixtures/notifications/new.json +8 -0
- data/spec/fixtures/notifications/new_empty.json +7 -0
- data/spec/fixtures/notifications/notifications.json +43 -0
- data/spec/fixtures/notifications/post.json +10 -0
- data/spec/fixtures/notifications/unread.json +10 -0
- data/spec/fixtures/oauth2/access.json +3 -0
- data/spec/fixtures/oauth2/access_with_old_refresh.json +5 -0
- data/spec/fixtures/oauth2/access_with_refresh.json +5 -0
- data/spec/fixtures/oauth2/authorization_code_body.json +7 -0
- data/spec/fixtures/oauth2/error.json +3 -0
- data/spec/fixtures/oauth2/password_body.json +7 -0
- data/spec/fixtures/oauth2/refresh_body.json +7 -0
- data/spec/fixtures/oauth2_error.json +3 -0
- data/spec/fixtures/property_types/property_types.json +31 -0
- data/spec/fixtures/session.json +10 -0
- data/spec/fixtures/standardfields/city.json +1031 -0
- data/spec/fixtures/standardfields/nearby.json +53 -0
- data/spec/fixtures/standardfields/standardfields.json +188 -0
- data/spec/fixtures/standardfields/stateorprovince.json +36 -0
- data/spec/fixtures/success.json +5 -0
- data/spec/json_helper.rb +76 -0
- data/spec/mock_helper.rb +124 -0
- data/spec/oauth2_helper.rb +68 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/unit/flexmls_api_spec.rb~ +23 -0
- data/spec/unit/spark_api/authentication/api_auth_spec.rb +169 -0
- data/spec/unit/spark_api/authentication/api_auth_spec.rb~ +169 -0
- data/spec/unit/spark_api/authentication/base_auth_spec.rb +10 -0
- data/spec/unit/spark_api/authentication/base_auth_spec.rb~ +10 -0
- data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb +10 -0
- data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb~ +10 -0
- data/spec/unit/spark_api/authentication/oauth2_spec.rb +205 -0
- data/spec/unit/spark_api/authentication/oauth2_spec.rb~ +205 -0
- data/spec/unit/spark_api/authentication_spec.rb +38 -0
- data/spec/unit/spark_api/authentication_spec.rb~ +38 -0
- data/spec/unit/spark_api/configuration/yaml_spec.rb +72 -0
- data/spec/unit/spark_api/configuration/yaml_spec.rb~ +72 -0
- data/spec/unit/spark_api/configuration_spec.rb +122 -0
- data/spec/unit/spark_api/configuration_spec.rb~ +122 -0
- data/spec/unit/spark_api/faraday_spec.rb +90 -0
- data/spec/unit/spark_api/faraday_spec.rb~ +90 -0
- data/spec/unit/spark_api/models/account_spec.rb +176 -0
- data/spec/unit/spark_api/models/base_spec.rb +106 -0
- data/spec/unit/spark_api/models/connect_prefs_spec.rb +9 -0
- data/spec/unit/spark_api/models/constraint_spec.rb +19 -0
- data/spec/unit/spark_api/models/contact_spec.rb +108 -0
- data/spec/unit/spark_api/models/contact_spec.rb~ +108 -0
- data/spec/unit/spark_api/models/document_spec.rb +32 -0
- data/spec/unit/spark_api/models/listing_cart_spec.rb +127 -0
- data/spec/unit/spark_api/models/listing_cart_spec.rb~ +127 -0
- data/spec/unit/spark_api/models/listing_spec.rb +320 -0
- data/spec/unit/spark_api/models/listing_spec.rb~ +320 -0
- data/spec/unit/spark_api/models/message_spec.rb +47 -0
- data/spec/unit/spark_api/models/message_spec.rb~ +47 -0
- data/spec/unit/spark_api/models/note_spec.rb +63 -0
- data/spec/unit/spark_api/models/note_spec.rb~ +63 -0
- data/spec/unit/spark_api/models/notification_spec.rb +62 -0
- data/spec/unit/spark_api/models/notification_spec.rb~ +62 -0
- data/spec/unit/spark_api/models/open_house_spec.rb +39 -0
- data/spec/unit/spark_api/models/photo_spec.rb +92 -0
- data/spec/unit/spark_api/models/property_types_spec.rb +33 -0
- data/spec/unit/spark_api/models/saved_search_spec.rb +40 -0
- data/spec/unit/spark_api/models/shared_listing_spec.rb +45 -0
- data/spec/unit/spark_api/models/shared_listing_spec.rb~ +45 -0
- data/spec/unit/spark_api/models/standard_fields_spec.rb +60 -0
- data/spec/unit/spark_api/models/system_info_spec.rb +83 -0
- data/spec/unit/spark_api/models/tour_of_home_spec.rb +44 -0
- data/spec/unit/spark_api/models/video_spec.rb +36 -0
- data/spec/unit/spark_api/models/virtual_tour_spec.rb +44 -0
- data/spec/unit/spark_api/multi_client_spec.rb +56 -0
- data/spec/unit/spark_api/multi_client_spec.rb~ +56 -0
- data/spec/unit/spark_api/paginate_spec.rb +224 -0
- data/spec/unit/spark_api/paginate_spec.rb~ +224 -0
- data/spec/unit/spark_api/primary_array_spec.rb +41 -0
- data/spec/unit/spark_api/primary_array_spec.rb~ +41 -0
- data/spec/unit/spark_api/request_spec.rb +344 -0
- data/spec/unit/spark_api/request_spec.rb~ +344 -0
- data/spec/unit/spark_api_spec.rb +23 -0
- metadata +725 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
module SparkApi
|
|
4
|
+
module Configuration
|
|
5
|
+
class YamlConfig
|
|
6
|
+
KEY_CONFIGURATIONS = VALID_OPTION_KEYS + [:oauth2] + OAUTH2_KEYS
|
|
7
|
+
DEFAULT_OAUTH2_PROVIDER = "SparkApi::Authentication::OAuth2Impl::PasswordProvider"
|
|
8
|
+
attr_accessor *KEY_CONFIGURATIONS
|
|
9
|
+
attr_reader :client_keys, :oauth2_keys, :provider
|
|
10
|
+
|
|
11
|
+
def initialize(filename=nil)
|
|
12
|
+
@oauth2 = false
|
|
13
|
+
load_file(filename) unless filename.nil?()
|
|
14
|
+
end
|
|
15
|
+
def load_file(file)
|
|
16
|
+
@file = file
|
|
17
|
+
@name = File.basename(file, ".yml")
|
|
18
|
+
config = YAML.load(ERB.new(File.read(file)).result)[api_env]
|
|
19
|
+
config["oauth2"] == true ? load_oauth2(config) : load_api_auth(config)
|
|
20
|
+
rescue => e
|
|
21
|
+
SparkApi.logger().error("Unable to load config file #{file}[#{api_env}]")
|
|
22
|
+
raise e
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def oauth2?
|
|
26
|
+
return oauth2 == true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def name
|
|
30
|
+
@name
|
|
31
|
+
end
|
|
32
|
+
def api_env
|
|
33
|
+
current_env = "development"
|
|
34
|
+
if env.include?("SPARK_API_ENV")
|
|
35
|
+
current_env = env["SPARK_API_ENV"]
|
|
36
|
+
elsif env.include?("RAILS_ENV")
|
|
37
|
+
current_env = env["RAILS_ENV"]
|
|
38
|
+
end
|
|
39
|
+
return current_env
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Used to specify the root of where to look for SparkApi config files
|
|
43
|
+
def self.config_path
|
|
44
|
+
path_prefix + "config/spark_api"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.config_keys()
|
|
48
|
+
files = Dir["#{config_path}/*.yml"]
|
|
49
|
+
files.map {|f| File.basename(f,".yml") }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.exists?(name)
|
|
53
|
+
File.exists? "#{config_path}/#{name}.yml"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.build(name)
|
|
57
|
+
yaml = YamlConfig.new("#{config_path}/#{name}.yml")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
protected
|
|
61
|
+
def env
|
|
62
|
+
ENV
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
def load_api_auth(config={})
|
|
67
|
+
@client_keys = {}
|
|
68
|
+
@oauth2_keys = {}
|
|
69
|
+
config.each do |key,val|
|
|
70
|
+
sym = key.to_sym
|
|
71
|
+
if VALID_OPTION_KEYS.include?(sym)
|
|
72
|
+
self.send("#{sym}=", val)
|
|
73
|
+
@client_keys[sym] = val
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
def load_oauth2(config={})
|
|
78
|
+
@oauth2_provider = DEFAULT_OAUTH2_PROVIDER
|
|
79
|
+
@client_keys = {:oauth2_provider => @oauth2_provider }
|
|
80
|
+
@oauth2_keys = {}
|
|
81
|
+
@oauth2 = true
|
|
82
|
+
config.each do |key,val|
|
|
83
|
+
sym = key.to_sym
|
|
84
|
+
if VALID_OPTION_KEYS.include?(sym)
|
|
85
|
+
self.send("#{sym}=", val)
|
|
86
|
+
@client_keys[sym] = val
|
|
87
|
+
elsif OAUTH2_KEYS.include? sym
|
|
88
|
+
self.send("#{sym}=", val)
|
|
89
|
+
@oauth2_keys[sym] = val
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
# In a rails app, default to the rails root, regardless of where that may be
|
|
94
|
+
def self.path_prefix
|
|
95
|
+
"#{Rails.root}/"
|
|
96
|
+
rescue => e
|
|
97
|
+
""
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
module FlexmlsApi
|
|
4
|
+
module Configuration
|
|
5
|
+
class YamlConfig
|
|
6
|
+
KEY_CONFIGURATIONS = VALID_OPTION_KEYS + [:oauth2] + OAUTH2_KEYS
|
|
7
|
+
DEFAULT_OAUTH2_PROVIDER = "FlexmlsApi::Authentication::OAuth2Impl::PasswordProvider"
|
|
8
|
+
attr_accessor *KEY_CONFIGURATIONS
|
|
9
|
+
attr_reader :client_keys, :oauth2_keys, :provider
|
|
10
|
+
|
|
11
|
+
def initialize(filename=nil)
|
|
12
|
+
@oauth2 = false
|
|
13
|
+
load_file(filename) unless filename.nil?()
|
|
14
|
+
end
|
|
15
|
+
def load_file(file)
|
|
16
|
+
@file = file
|
|
17
|
+
@name = File.basename(file, ".yml")
|
|
18
|
+
config = YAML.load(ERB.new(File.read(file)).result)[api_env]
|
|
19
|
+
config["oauth2"] == true ? load_oauth2(config) : load_api_auth(config)
|
|
20
|
+
rescue => e
|
|
21
|
+
FlexmlsApi.logger().error("Unable to load config file #{file}[#{api_env}]")
|
|
22
|
+
raise e
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def oauth2?
|
|
26
|
+
return oauth2 == true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def name
|
|
30
|
+
@name
|
|
31
|
+
end
|
|
32
|
+
def api_env
|
|
33
|
+
current_env = "development"
|
|
34
|
+
if env.include?("FLEXMLS_API_ENV")
|
|
35
|
+
current_env = env["FLEXMLS_API_ENV"]
|
|
36
|
+
elsif env.include?("RAILS_ENV")
|
|
37
|
+
current_env = env["RAILS_ENV"]
|
|
38
|
+
end
|
|
39
|
+
return current_env
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Used to specify the root of where to look for flexmlsApi config files
|
|
43
|
+
def self.config_path
|
|
44
|
+
path_prefix + "config/flexmls_api"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.config_keys()
|
|
48
|
+
files = Dir["#{config_path}/*.yml"]
|
|
49
|
+
files.map {|f| File.basename(f,".yml") }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.exists?(name)
|
|
53
|
+
File.exists? "#{config_path}/#{name}.yml"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.build(name)
|
|
57
|
+
yaml = YamlConfig.new("#{config_path}/#{name}.yml")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
protected
|
|
61
|
+
def env
|
|
62
|
+
ENV
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
def load_api_auth(config={})
|
|
67
|
+
@client_keys = {}
|
|
68
|
+
@oauth2_keys = {}
|
|
69
|
+
config.each do |key,val|
|
|
70
|
+
sym = key.to_sym
|
|
71
|
+
if VALID_OPTION_KEYS.include?(sym)
|
|
72
|
+
self.send("#{sym}=", val)
|
|
73
|
+
@client_keys[sym] = val
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
def load_oauth2(config={})
|
|
78
|
+
@oauth2_provider = DEFAULT_OAUTH2_PROVIDER
|
|
79
|
+
@client_keys = {:oauth2_provider => @oauth2_provider }
|
|
80
|
+
@oauth2_keys = {}
|
|
81
|
+
@oauth2 = true
|
|
82
|
+
config.each do |key,val|
|
|
83
|
+
sym = key.to_sym
|
|
84
|
+
if VALID_OPTION_KEYS.include?(sym)
|
|
85
|
+
self.send("#{sym}=", val)
|
|
86
|
+
@client_keys[sym] = val
|
|
87
|
+
elsif OAUTH2_KEYS.include? sym
|
|
88
|
+
self.send("#{sym}=", val)
|
|
89
|
+
@oauth2_keys[sym] = val
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
# In a rails app, default to the rails root, regardless of where that may be
|
|
94
|
+
def self.path_prefix
|
|
95
|
+
"#{Rails.root}/"
|
|
96
|
+
rescue => e
|
|
97
|
+
""
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'faraday'
|
|
3
|
+
require 'faraday_middleware'
|
|
4
|
+
require 'yajl'
|
|
5
|
+
|
|
6
|
+
module SparkApi
|
|
7
|
+
# =Connection
|
|
8
|
+
# Mixin module for handling http connection information
|
|
9
|
+
module Connection
|
|
10
|
+
# Main connection object for running requests. Bootstraps the Faraday abstraction layer with
|
|
11
|
+
# our client configuration.
|
|
12
|
+
def connection(force_ssl = false)
|
|
13
|
+
opts = {
|
|
14
|
+
:headers => headers
|
|
15
|
+
}
|
|
16
|
+
domain = @endpoint
|
|
17
|
+
if(force_ssl || self.ssl)
|
|
18
|
+
opts[:ssl] = {:verify => false }
|
|
19
|
+
opts[:url] = @endpoint.sub /^http:/, "https:"
|
|
20
|
+
else
|
|
21
|
+
opts[:url] = @endpoint.sub /^https:/, "http:"
|
|
22
|
+
end
|
|
23
|
+
conn = Faraday::Connection.new(opts) do |builder|
|
|
24
|
+
builder.adapter Faraday.default_adapter
|
|
25
|
+
builder.use SparkApi::FaradayExt::SparkMiddleware
|
|
26
|
+
end
|
|
27
|
+
SparkApi.logger.debug("Connection: #{conn.inspect}")
|
|
28
|
+
conn
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# HTTP request headers for client requests
|
|
32
|
+
def headers
|
|
33
|
+
{
|
|
34
|
+
:accept => 'application/json',
|
|
35
|
+
:content_type => 'application/json',
|
|
36
|
+
:user_agent => Configuration::DEFAULT_USER_AGENT,
|
|
37
|
+
Configuration::X_SPARK_API_USER_AGENT => user_agent
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module SparkApi
|
|
2
|
+
module FaradayExt
|
|
3
|
+
#=Spark API Faraday middleware
|
|
4
|
+
# HTTP Response after filter to package api responses and bubble up basic api errors.
|
|
5
|
+
class SparkMiddleware < Faraday::Response::ParseJson
|
|
6
|
+
include SparkApi::PaginateHelper
|
|
7
|
+
# Handles pretty much all the api response parsing and error handling. All responses that
|
|
8
|
+
# indicate a failure will raise a SparkApi::ClientError exception
|
|
9
|
+
def on_complete(finished_env)
|
|
10
|
+
body = parse(finished_env[:body])
|
|
11
|
+
SparkApi.logger.debug("Response Body: #{body.inspect}")
|
|
12
|
+
unless body.is_a?(Hash) && body.key?("D")
|
|
13
|
+
raise InvalidResponse, "The server response could not be understood"
|
|
14
|
+
end
|
|
15
|
+
response = ApiResponse.new body
|
|
16
|
+
paging = response.pagination
|
|
17
|
+
if paging.nil?
|
|
18
|
+
results = response
|
|
19
|
+
else
|
|
20
|
+
if finished_env[:url].query_values["_pagination"] == "count"
|
|
21
|
+
results = paging['TotalRows']
|
|
22
|
+
else
|
|
23
|
+
results = paginate_response(response, paging)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
case finished_env[:status]
|
|
27
|
+
when 400
|
|
28
|
+
hash = {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
29
|
+
|
|
30
|
+
# constraint violation
|
|
31
|
+
if response.code == 1053
|
|
32
|
+
details = body['D']['Details']
|
|
33
|
+
hash[:details] = details
|
|
34
|
+
end
|
|
35
|
+
raise BadResourceRequest,hash
|
|
36
|
+
when 401
|
|
37
|
+
# Handle the WWW-Authenticate Response Header Field if present. This can be returned by
|
|
38
|
+
# OAuth2 implementations and wouldn't hurt to log.
|
|
39
|
+
auth_header_error = finished_env[:request_headers]["WWW-Authenticate"]
|
|
40
|
+
SparkApi.logger.warn("Authentication error #{auth_header_error}") unless auth_header_error.nil?
|
|
41
|
+
raise PermissionDenied, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
42
|
+
when 404
|
|
43
|
+
raise NotFound, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
44
|
+
when 405
|
|
45
|
+
raise NotAllowed, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
46
|
+
when 409
|
|
47
|
+
raise BadResourceRequest, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
48
|
+
when 500
|
|
49
|
+
raise ClientError, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
50
|
+
when 200..299
|
|
51
|
+
SparkApi.logger.debug("Success!")
|
|
52
|
+
else
|
|
53
|
+
raise ClientError, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
54
|
+
end
|
|
55
|
+
finished_env[:body] = results
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def initialize(app)
|
|
59
|
+
super(app)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module FlexmlsApi
|
|
2
|
+
module FaradayExt
|
|
3
|
+
#=Flexmls API Faraday middleware
|
|
4
|
+
# HTTP Response after filter to package api responses and bubble up basic api errors.
|
|
5
|
+
class FlexmlsMiddleware < Faraday::Response::ParseJson
|
|
6
|
+
include FlexmlsApi::PaginateHelper
|
|
7
|
+
# Handles pretty much all the api response parsing and error handling. All responses that
|
|
8
|
+
# indicate a failure will raise a FlexmlsApi::ClientError exception
|
|
9
|
+
def on_complete(finished_env)
|
|
10
|
+
body = parse(finished_env[:body])
|
|
11
|
+
FlexmlsApi.logger.debug("Response Body: #{body.inspect}")
|
|
12
|
+
unless body.is_a?(Hash) && body.key?("D")
|
|
13
|
+
raise InvalidResponse, "The server response could not be understood"
|
|
14
|
+
end
|
|
15
|
+
response = ApiResponse.new body
|
|
16
|
+
paging = response.pagination
|
|
17
|
+
if paging.nil?
|
|
18
|
+
results = response
|
|
19
|
+
else
|
|
20
|
+
if finished_env[:url].query_values["_pagination"] == "count"
|
|
21
|
+
results = paging['TotalRows']
|
|
22
|
+
else
|
|
23
|
+
results = paginate_response(response, paging)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
case finished_env[:status]
|
|
27
|
+
when 400
|
|
28
|
+
hash = {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
29
|
+
|
|
30
|
+
# constraint violation
|
|
31
|
+
if response.code == 1053
|
|
32
|
+
details = body['D']['Details']
|
|
33
|
+
hash[:details] = details
|
|
34
|
+
end
|
|
35
|
+
raise BadResourceRequest,hash
|
|
36
|
+
when 401
|
|
37
|
+
# Handle the WWW-Authenticate Response Header Field if present. This can be returned by
|
|
38
|
+
# OAuth2 implementations and wouldn't hurt to log.
|
|
39
|
+
auth_header_error = finished_env[:request_headers]["WWW-Authenticate"]
|
|
40
|
+
FlexmlsApi.logger.warn("Authentication error #{auth_header_error}") unless auth_header_error.nil?
|
|
41
|
+
raise PermissionDenied, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
42
|
+
when 404
|
|
43
|
+
raise NotFound, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
44
|
+
when 405
|
|
45
|
+
raise NotAllowed, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
46
|
+
when 409
|
|
47
|
+
raise BadResourceRequest, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
48
|
+
when 500
|
|
49
|
+
raise ClientError, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
50
|
+
when 200..299
|
|
51
|
+
FlexmlsApi.logger.debug("Success!")
|
|
52
|
+
else
|
|
53
|
+
raise ClientError, {:message => response.message, :code => response.code, :status => finished_env[:status]}
|
|
54
|
+
end
|
|
55
|
+
finished_env[:body] = results
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def initialize(app)
|
|
59
|
+
super(app)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'spark_api/models/base'
|
|
2
|
+
require 'spark_api/models/constraint'
|
|
3
|
+
require 'spark_api/models/finders'
|
|
4
|
+
require 'spark_api/models/subresource'
|
|
5
|
+
|
|
6
|
+
require 'spark_api/models/account'
|
|
7
|
+
require 'spark_api/models/connect_prefs'
|
|
8
|
+
require 'spark_api/models/contact'
|
|
9
|
+
require 'spark_api/models/custom_fields'
|
|
10
|
+
require 'spark_api/models/document'
|
|
11
|
+
require 'spark_api/models/idx_link'
|
|
12
|
+
require 'spark_api/models/listing'
|
|
13
|
+
require 'spark_api/models/listing_cart'
|
|
14
|
+
require 'spark_api/models/market_statistics'
|
|
15
|
+
require 'spark_api/models/message'
|
|
16
|
+
require 'spark_api/models/note'
|
|
17
|
+
require 'spark_api/models/notification'
|
|
18
|
+
require 'spark_api/models/open_house'
|
|
19
|
+
require 'spark_api/models/photo'
|
|
20
|
+
require 'spark_api/models/property_types'
|
|
21
|
+
require 'spark_api/models/saved_search'
|
|
22
|
+
require 'spark_api/models/shared_listing'
|
|
23
|
+
require 'spark_api/models/standard_fields'
|
|
24
|
+
require 'spark_api/models/system_info'
|
|
25
|
+
require 'spark_api/models/tour_of_home'
|
|
26
|
+
require 'spark_api/models/video'
|
|
27
|
+
require 'spark_api/models/virtual_tour'
|
|
28
|
+
|
|
29
|
+
module SparkApi
|
|
30
|
+
module Models
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'flexmls_api/models/base'
|
|
2
|
+
require 'flexmls_api/models/constraint'
|
|
3
|
+
require 'flexmls_api/models/finders'
|
|
4
|
+
require 'flexmls_api/models/subresource'
|
|
5
|
+
|
|
6
|
+
require 'flexmls_api/models/account'
|
|
7
|
+
require 'flexmls_api/models/connect_prefs'
|
|
8
|
+
require 'flexmls_api/models/contact'
|
|
9
|
+
require 'flexmls_api/models/custom_fields'
|
|
10
|
+
require 'flexmls_api/models/document'
|
|
11
|
+
require 'flexmls_api/models/idx_link'
|
|
12
|
+
require 'flexmls_api/models/listing'
|
|
13
|
+
require 'flexmls_api/models/listing_cart'
|
|
14
|
+
require 'flexmls_api/models/market_statistics'
|
|
15
|
+
require 'flexmls_api/models/message'
|
|
16
|
+
require 'flexmls_api/models/note'
|
|
17
|
+
require 'flexmls_api/models/notification'
|
|
18
|
+
require 'flexmls_api/models/open_house'
|
|
19
|
+
require 'flexmls_api/models/photo'
|
|
20
|
+
require 'flexmls_api/models/property_types'
|
|
21
|
+
require 'flexmls_api/models/saved_search'
|
|
22
|
+
require 'flexmls_api/models/shared_listing'
|
|
23
|
+
require 'flexmls_api/models/standard_fields'
|
|
24
|
+
require 'flexmls_api/models/system_info'
|
|
25
|
+
require 'flexmls_api/models/tour_of_home'
|
|
26
|
+
require 'flexmls_api/models/video'
|
|
27
|
+
require 'flexmls_api/models/virtual_tour'
|
|
28
|
+
|
|
29
|
+
module FlexmlsApi
|
|
30
|
+
module Models
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|