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.
Files changed (257) hide show
  1. data/History.txt +139 -0
  2. data/LICENSE +14 -0
  3. data/README.md +153 -0
  4. data/Rakefile +18 -0
  5. data/VERSION +1 -0
  6. data/bin/spark_api +8 -0
  7. data/bin/spark_api~ +8 -0
  8. data/lib/spark_api.rb +46 -0
  9. data/lib/spark_api/authentication.rb +55 -0
  10. data/lib/spark_api/authentication/api_auth.rb +104 -0
  11. data/lib/spark_api/authentication/api_auth.rb~ +104 -0
  12. data/lib/spark_api/authentication/base_auth.rb +47 -0
  13. data/lib/spark_api/authentication/base_auth.rb~ +47 -0
  14. data/lib/spark_api/authentication/oauth2.rb +198 -0
  15. data/lib/spark_api/authentication/oauth2.rb~ +199 -0
  16. data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb +87 -0
  17. data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb~ +87 -0
  18. data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb +48 -0
  19. data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb~ +49 -0
  20. data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb +44 -0
  21. data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb~ +45 -0
  22. data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb +35 -0
  23. data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb~ +36 -0
  24. data/lib/spark_api/authentication/oauth2_impl/middleware.rb +38 -0
  25. data/lib/spark_api/authentication/oauth2_impl/middleware.rb~ +39 -0
  26. data/lib/spark_api/authentication/oauth2_impl/password_provider.rb +24 -0
  27. data/lib/spark_api/authentication/oauth2_impl/password_provider.rb~ +25 -0
  28. data/lib/spark_api/cli.rb +158 -0
  29. data/lib/spark_api/cli.rb~ +158 -0
  30. data/lib/spark_api/cli/api_auth.rb +8 -0
  31. data/lib/spark_api/cli/api_auth.rb~ +8 -0
  32. data/lib/spark_api/cli/oauth2.rb +14 -0
  33. data/lib/spark_api/cli/oauth2.rb~ +14 -0
  34. data/lib/spark_api/cli/setup.rb +47 -0
  35. data/lib/spark_api/cli/setup.rb~ +47 -0
  36. data/lib/spark_api/client.rb +27 -0
  37. data/lib/spark_api/configuration.rb +54 -0
  38. data/lib/spark_api/configuration.rb~ +54 -0
  39. data/lib/spark_api/configuration/yaml.rb +101 -0
  40. data/lib/spark_api/configuration/yaml.rb~ +101 -0
  41. data/lib/spark_api/connection.rb +42 -0
  42. data/lib/spark_api/faraday.rb +64 -0
  43. data/lib/spark_api/faraday.rb~ +64 -0
  44. data/lib/spark_api/models.rb +33 -0
  45. data/lib/spark_api/models.rb~ +33 -0
  46. data/lib/spark_api/models/account.rb +115 -0
  47. data/lib/spark_api/models/account.rb~ +115 -0
  48. data/lib/spark_api/models/base.rb +118 -0
  49. data/lib/spark_api/models/base.rb~ +118 -0
  50. data/lib/spark_api/models/connect_prefs.rb +10 -0
  51. data/lib/spark_api/models/connect_prefs.rb~ +10 -0
  52. data/lib/spark_api/models/constraint.rb +16 -0
  53. data/lib/spark_api/models/constraint.rb~ +16 -0
  54. data/lib/spark_api/models/contact.rb +49 -0
  55. data/lib/spark_api/models/contact.rb~ +49 -0
  56. data/lib/spark_api/models/custom_fields.rb +12 -0
  57. data/lib/spark_api/models/custom_fields.rb~ +12 -0
  58. data/lib/spark_api/models/document.rb +11 -0
  59. data/lib/spark_api/models/document.rb~ +11 -0
  60. data/lib/spark_api/models/finders.rb +45 -0
  61. data/lib/spark_api/models/finders.rb~ +45 -0
  62. data/lib/spark_api/models/idx_link.rb +47 -0
  63. data/lib/spark_api/models/idx_link.rb~ +47 -0
  64. data/lib/spark_api/models/listing.rb +197 -0
  65. data/lib/spark_api/models/listing.rb~ +197 -0
  66. data/lib/spark_api/models/listing_cart.rb +72 -0
  67. data/lib/spark_api/models/listing_cart.rb~ +72 -0
  68. data/lib/spark_api/models/market_statistics.rb +33 -0
  69. data/lib/spark_api/models/market_statistics.rb~ +33 -0
  70. data/lib/spark_api/models/message.rb +21 -0
  71. data/lib/spark_api/models/message.rb~ +21 -0
  72. data/lib/spark_api/models/note.rb +41 -0
  73. data/lib/spark_api/models/note.rb~ +41 -0
  74. data/lib/spark_api/models/notification.rb +42 -0
  75. data/lib/spark_api/models/notification.rb~ +42 -0
  76. data/lib/spark_api/models/open_house.rb +24 -0
  77. data/lib/spark_api/models/open_house.rb~ +24 -0
  78. data/lib/spark_api/models/photo.rb +70 -0
  79. data/lib/spark_api/models/photo.rb~ +70 -0
  80. data/lib/spark_api/models/property_types.rb +7 -0
  81. data/lib/spark_api/models/property_types.rb~ +7 -0
  82. data/lib/spark_api/models/saved_search.rb +16 -0
  83. data/lib/spark_api/models/saved_search.rb~ +16 -0
  84. data/lib/spark_api/models/shared_listing.rb +35 -0
  85. data/lib/spark_api/models/shared_listing.rb~ +35 -0
  86. data/lib/spark_api/models/standard_fields.rb +50 -0
  87. data/lib/spark_api/models/standard_fields.rb~ +50 -0
  88. data/lib/spark_api/models/subresource.rb +19 -0
  89. data/lib/spark_api/models/subresource.rb~ +19 -0
  90. data/lib/spark_api/models/system_info.rb +14 -0
  91. data/lib/spark_api/models/system_info.rb~ +14 -0
  92. data/lib/spark_api/models/tour_of_home.rb +24 -0
  93. data/lib/spark_api/models/tour_of_home.rb~ +24 -0
  94. data/lib/spark_api/models/video.rb +16 -0
  95. data/lib/spark_api/models/video.rb~ +16 -0
  96. data/lib/spark_api/models/virtual_tour.rb +18 -0
  97. data/lib/spark_api/models/virtual_tour.rb~ +18 -0
  98. data/lib/spark_api/multi_client.rb +59 -0
  99. data/lib/spark_api/multi_client.rb~ +59 -0
  100. data/lib/spark_api/paginate.rb +109 -0
  101. data/lib/spark_api/paginate.rb~ +109 -0
  102. data/lib/spark_api/primary_array.rb +29 -0
  103. data/lib/spark_api/primary_array.rb~ +29 -0
  104. data/lib/spark_api/request.rb +96 -0
  105. data/lib/spark_api/request.rb~ +96 -0
  106. data/lib/spark_api/response.rb +70 -0
  107. data/lib/spark_api/response.rb~ +70 -0
  108. data/lib/spark_api/version.rb +4 -0
  109. data/lib/spark_api/version.rb~ +4 -0
  110. data/script/console +6 -0
  111. data/script/console~ +6 -0
  112. data/script/example.rb +27 -0
  113. data/script/example.rb~ +27 -0
  114. data/spec/fixtures/accounts/all.json +160 -0
  115. data/spec/fixtures/accounts/my.json +74 -0
  116. data/spec/fixtures/accounts/my_portal.json +20 -0
  117. data/spec/fixtures/accounts/my_put.json +5 -0
  118. data/spec/fixtures/accounts/my_save.json +5 -0
  119. data/spec/fixtures/accounts/office.json +142 -0
  120. data/spec/fixtures/accounts/password_save.json +6 -0
  121. data/spec/fixtures/authentication_failure.json +7 -0
  122. data/spec/fixtures/base.json +13 -0
  123. data/spec/fixtures/contacts/contacts.json +28 -0
  124. data/spec/fixtures/contacts/my.json +19 -0
  125. data/spec/fixtures/contacts/new.json +11 -0
  126. data/spec/fixtures/contacts/new_empty.json +8 -0
  127. data/spec/fixtures/contacts/new_notify.json +11 -0
  128. data/spec/fixtures/contacts/post.json +10 -0
  129. data/spec/fixtures/contacts/tags.json +11 -0
  130. data/spec/fixtures/count.json +10 -0
  131. data/spec/fixtures/empty.json +3 -0
  132. data/spec/fixtures/errors/expired.json +7 -0
  133. data/spec/fixtures/errors/failure.json +5 -0
  134. data/spec/fixtures/errors/failure_with_constraint.json +17 -0
  135. data/spec/fixtures/errors/failure_with_msg.json +7 -0
  136. data/spec/fixtures/generic_delete.json +1 -0
  137. data/spec/fixtures/generic_failure.json +5 -0
  138. data/spec/fixtures/listing_carts/add_listing.json +13 -0
  139. data/spec/fixtures/listing_carts/add_listing_post.json +5 -0
  140. data/spec/fixtures/listing_carts/empty.json +5 -0
  141. data/spec/fixtures/listing_carts/listing_cart.json +19 -0
  142. data/spec/fixtures/listing_carts/new.json +12 -0
  143. data/spec/fixtures/listing_carts/post.json +10 -0
  144. data/spec/fixtures/listing_carts/remove_listing.json +13 -0
  145. data/spec/fixtures/listings/constraints.json +18 -0
  146. data/spec/fixtures/listings/constraints_with_pagination.json +24 -0
  147. data/spec/fixtures/listings/document_index.json +19 -0
  148. data/spec/fixtures/listings/multiple.json +69 -0
  149. data/spec/fixtures/listings/no_subresources.json +38 -0
  150. data/spec/fixtures/listings/open_houses.json +21 -0
  151. data/spec/fixtures/listings/photos/index.json +469 -0
  152. data/spec/fixtures/listings/photos/new.json +12 -0
  153. data/spec/fixtures/listings/photos/post.json +20 -0
  154. data/spec/fixtures/listings/put.json +5 -0
  155. data/spec/fixtures/listings/put_expiration_date.json +5 -0
  156. data/spec/fixtures/listings/saved_search.json +17 -0
  157. data/spec/fixtures/listings/shared_listing_get.json +14 -0
  158. data/spec/fixtures/listings/shared_listing_new.json +9 -0
  159. data/spec/fixtures/listings/shared_listing_post.json +10 -0
  160. data/spec/fixtures/listings/tour_of_homes.json +23 -0
  161. data/spec/fixtures/listings/videos_index.json +18 -0
  162. data/spec/fixtures/listings/virtual_tours_index.json +42 -0
  163. data/spec/fixtures/listings/with_documents.json +52 -0
  164. data/spec/fixtures/listings/with_permissions.json +44 -0
  165. data/spec/fixtures/listings/with_photos.json +110 -0
  166. data/spec/fixtures/listings/with_supplement.json +39 -0
  167. data/spec/fixtures/listings/with_videos.json +54 -0
  168. data/spec/fixtures/listings/with_vtour.json +48 -0
  169. data/spec/fixtures/logo_fbs.png +0 -0
  170. data/spec/fixtures/messages/new.json +14 -0
  171. data/spec/fixtures/messages/new_empty.json +7 -0
  172. data/spec/fixtures/messages/new_with_recipients.json +15 -0
  173. data/spec/fixtures/messages/post.json +5 -0
  174. data/spec/fixtures/notes/add.json +11 -0
  175. data/spec/fixtures/notes/agent_shared.json +11 -0
  176. data/spec/fixtures/notes/agent_shared_empty.json +7 -0
  177. data/spec/fixtures/notes/new.json +5 -0
  178. data/spec/fixtures/notifications/mark_read.json +1 -0
  179. data/spec/fixtures/notifications/new.json +8 -0
  180. data/spec/fixtures/notifications/new_empty.json +7 -0
  181. data/spec/fixtures/notifications/notifications.json +43 -0
  182. data/spec/fixtures/notifications/post.json +10 -0
  183. data/spec/fixtures/notifications/unread.json +10 -0
  184. data/spec/fixtures/oauth2/access.json +3 -0
  185. data/spec/fixtures/oauth2/access_with_old_refresh.json +5 -0
  186. data/spec/fixtures/oauth2/access_with_refresh.json +5 -0
  187. data/spec/fixtures/oauth2/authorization_code_body.json +7 -0
  188. data/spec/fixtures/oauth2/error.json +3 -0
  189. data/spec/fixtures/oauth2/password_body.json +7 -0
  190. data/spec/fixtures/oauth2/refresh_body.json +7 -0
  191. data/spec/fixtures/oauth2_error.json +3 -0
  192. data/spec/fixtures/property_types/property_types.json +31 -0
  193. data/spec/fixtures/session.json +10 -0
  194. data/spec/fixtures/standardfields/city.json +1031 -0
  195. data/spec/fixtures/standardfields/nearby.json +53 -0
  196. data/spec/fixtures/standardfields/standardfields.json +188 -0
  197. data/spec/fixtures/standardfields/stateorprovince.json +36 -0
  198. data/spec/fixtures/success.json +5 -0
  199. data/spec/json_helper.rb +76 -0
  200. data/spec/mock_helper.rb +124 -0
  201. data/spec/oauth2_helper.rb +68 -0
  202. data/spec/spec_helper.rb +48 -0
  203. data/spec/unit/flexmls_api_spec.rb~ +23 -0
  204. data/spec/unit/spark_api/authentication/api_auth_spec.rb +169 -0
  205. data/spec/unit/spark_api/authentication/api_auth_spec.rb~ +169 -0
  206. data/spec/unit/spark_api/authentication/base_auth_spec.rb +10 -0
  207. data/spec/unit/spark_api/authentication/base_auth_spec.rb~ +10 -0
  208. data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb +10 -0
  209. data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb~ +10 -0
  210. data/spec/unit/spark_api/authentication/oauth2_spec.rb +205 -0
  211. data/spec/unit/spark_api/authentication/oauth2_spec.rb~ +205 -0
  212. data/spec/unit/spark_api/authentication_spec.rb +38 -0
  213. data/spec/unit/spark_api/authentication_spec.rb~ +38 -0
  214. data/spec/unit/spark_api/configuration/yaml_spec.rb +72 -0
  215. data/spec/unit/spark_api/configuration/yaml_spec.rb~ +72 -0
  216. data/spec/unit/spark_api/configuration_spec.rb +122 -0
  217. data/spec/unit/spark_api/configuration_spec.rb~ +122 -0
  218. data/spec/unit/spark_api/faraday_spec.rb +90 -0
  219. data/spec/unit/spark_api/faraday_spec.rb~ +90 -0
  220. data/spec/unit/spark_api/models/account_spec.rb +176 -0
  221. data/spec/unit/spark_api/models/base_spec.rb +106 -0
  222. data/spec/unit/spark_api/models/connect_prefs_spec.rb +9 -0
  223. data/spec/unit/spark_api/models/constraint_spec.rb +19 -0
  224. data/spec/unit/spark_api/models/contact_spec.rb +108 -0
  225. data/spec/unit/spark_api/models/contact_spec.rb~ +108 -0
  226. data/spec/unit/spark_api/models/document_spec.rb +32 -0
  227. data/spec/unit/spark_api/models/listing_cart_spec.rb +127 -0
  228. data/spec/unit/spark_api/models/listing_cart_spec.rb~ +127 -0
  229. data/spec/unit/spark_api/models/listing_spec.rb +320 -0
  230. data/spec/unit/spark_api/models/listing_spec.rb~ +320 -0
  231. data/spec/unit/spark_api/models/message_spec.rb +47 -0
  232. data/spec/unit/spark_api/models/message_spec.rb~ +47 -0
  233. data/spec/unit/spark_api/models/note_spec.rb +63 -0
  234. data/spec/unit/spark_api/models/note_spec.rb~ +63 -0
  235. data/spec/unit/spark_api/models/notification_spec.rb +62 -0
  236. data/spec/unit/spark_api/models/notification_spec.rb~ +62 -0
  237. data/spec/unit/spark_api/models/open_house_spec.rb +39 -0
  238. data/spec/unit/spark_api/models/photo_spec.rb +92 -0
  239. data/spec/unit/spark_api/models/property_types_spec.rb +33 -0
  240. data/spec/unit/spark_api/models/saved_search_spec.rb +40 -0
  241. data/spec/unit/spark_api/models/shared_listing_spec.rb +45 -0
  242. data/spec/unit/spark_api/models/shared_listing_spec.rb~ +45 -0
  243. data/spec/unit/spark_api/models/standard_fields_spec.rb +60 -0
  244. data/spec/unit/spark_api/models/system_info_spec.rb +83 -0
  245. data/spec/unit/spark_api/models/tour_of_home_spec.rb +44 -0
  246. data/spec/unit/spark_api/models/video_spec.rb +36 -0
  247. data/spec/unit/spark_api/models/virtual_tour_spec.rb +44 -0
  248. data/spec/unit/spark_api/multi_client_spec.rb +56 -0
  249. data/spec/unit/spark_api/multi_client_spec.rb~ +56 -0
  250. data/spec/unit/spark_api/paginate_spec.rb +224 -0
  251. data/spec/unit/spark_api/paginate_spec.rb~ +224 -0
  252. data/spec/unit/spark_api/primary_array_spec.rb +41 -0
  253. data/spec/unit/spark_api/primary_array_spec.rb~ +41 -0
  254. data/spec/unit/spark_api/request_spec.rb +344 -0
  255. data/spec/unit/spark_api/request_spec.rb~ +344 -0
  256. data/spec/unit/spark_api_spec.rb +23 -0
  257. 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