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,115 @@
|
|
|
1
|
+
module SparkApi
|
|
2
|
+
module Models
|
|
3
|
+
class Account < Base
|
|
4
|
+
extend Finders
|
|
5
|
+
self.element_name="accounts"
|
|
6
|
+
|
|
7
|
+
SUBELEMENTS = [:emails, :phones, :websites, :addresses, :images]
|
|
8
|
+
attr_accessor :my_account, *SUBELEMENTS
|
|
9
|
+
|
|
10
|
+
def initialize(attributes={})
|
|
11
|
+
@emails = subresource(Email, "Emails", attributes)
|
|
12
|
+
@phones = subresource(Phone, "Phones", attributes)
|
|
13
|
+
@websites = subresource(Website, "Websites", attributes)
|
|
14
|
+
@addresses = subresource(Address, "Addresses", attributes)
|
|
15
|
+
if attributes["Images"]
|
|
16
|
+
@images = []
|
|
17
|
+
attributes["Images"].each { |i| @images << Image.new(i) }
|
|
18
|
+
else
|
|
19
|
+
@images = nil
|
|
20
|
+
end
|
|
21
|
+
@my_account = false
|
|
22
|
+
super(attributes)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.my(arguments={})
|
|
26
|
+
account = collect(connection.get("/my/account", arguments)).first
|
|
27
|
+
account.my_account = true
|
|
28
|
+
account
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def my_account?
|
|
32
|
+
@my_account
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.by_office(office_id, arguments={})
|
|
36
|
+
collect(connection.get("#{self.path()}/by/office/#{office_id}", arguments))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def primary_img(typ)
|
|
40
|
+
if @images.is_a?(Array)
|
|
41
|
+
matches = @images.select {|i| i.Type == typ}
|
|
42
|
+
matches.sort {|a,b| a.Name <=> b.Name }.first
|
|
43
|
+
else
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def save(arguments={})
|
|
49
|
+
self.errors = [] # clear the errors hash
|
|
50
|
+
begin
|
|
51
|
+
return save!(arguments)
|
|
52
|
+
rescue NotFound, BadResourceRequest => e
|
|
53
|
+
self.errors << {:code => e.code, :message => e.message}
|
|
54
|
+
SparkApi.logger.error("Failed to save resource #{self}: #{e.message}")
|
|
55
|
+
end
|
|
56
|
+
false
|
|
57
|
+
end
|
|
58
|
+
def save!(arguments={})
|
|
59
|
+
# The long-term idea is that any setting in the user's account could be updated by including
|
|
60
|
+
# an attribute and calling PUT /my/account, but for now only the GetEmailUpdates attribute
|
|
61
|
+
# is supported
|
|
62
|
+
|
|
63
|
+
save_path = "/accounts/"+self.Id
|
|
64
|
+
|
|
65
|
+
ojbsome = {}
|
|
66
|
+
if attributes['GetEmailUpdates']
|
|
67
|
+
save_path = my_account? ? "/my/account" : self.class.path
|
|
68
|
+
ojbsome["GetEmailUpdates"] = attributes['GetEmailUpdates']
|
|
69
|
+
end
|
|
70
|
+
if attributes['PasswordValidation']
|
|
71
|
+
ojbsome["PasswordValidation"] = attributes['PasswordValidation']
|
|
72
|
+
end
|
|
73
|
+
if attributes['Password']
|
|
74
|
+
ojbsome["Password"] = attributes['Password']
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
results = connection.put save_path, ojbsome, arguments
|
|
78
|
+
true
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def subresource(klass, key, attributes)
|
|
85
|
+
return nil unless attributes.key?(key)
|
|
86
|
+
array = attributes[key]
|
|
87
|
+
result = PrimaryArray.new()
|
|
88
|
+
array.each do |i|
|
|
89
|
+
result << klass.new(i)
|
|
90
|
+
end
|
|
91
|
+
result
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
class Email < Base
|
|
95
|
+
include Primary
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class Phone < Base
|
|
99
|
+
include Primary
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
class Website < Base
|
|
103
|
+
include Primary
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
class Address < Base
|
|
107
|
+
include Primary
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
class Image < Base
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
module FlexmlsApi
|
|
2
|
+
module Models
|
|
3
|
+
class Account < Base
|
|
4
|
+
extend Finders
|
|
5
|
+
self.element_name="accounts"
|
|
6
|
+
|
|
7
|
+
SUBELEMENTS = [:emails, :phones, :websites, :addresses, :images]
|
|
8
|
+
attr_accessor :my_account, *SUBELEMENTS
|
|
9
|
+
|
|
10
|
+
def initialize(attributes={})
|
|
11
|
+
@emails = subresource(Email, "Emails", attributes)
|
|
12
|
+
@phones = subresource(Phone, "Phones", attributes)
|
|
13
|
+
@websites = subresource(Website, "Websites", attributes)
|
|
14
|
+
@addresses = subresource(Address, "Addresses", attributes)
|
|
15
|
+
if attributes["Images"]
|
|
16
|
+
@images = []
|
|
17
|
+
attributes["Images"].each { |i| @images << Image.new(i) }
|
|
18
|
+
else
|
|
19
|
+
@images = nil
|
|
20
|
+
end
|
|
21
|
+
@my_account = false
|
|
22
|
+
super(attributes)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.my(arguments={})
|
|
26
|
+
account = collect(connection.get("/my/account", arguments)).first
|
|
27
|
+
account.my_account = true
|
|
28
|
+
account
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def my_account?
|
|
32
|
+
@my_account
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.by_office(office_id, arguments={})
|
|
36
|
+
collect(connection.get("#{self.path()}/by/office/#{office_id}", arguments))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def primary_img(typ)
|
|
40
|
+
if @images.is_a?(Array)
|
|
41
|
+
matches = @images.select {|i| i.Type == typ}
|
|
42
|
+
matches.sort {|a,b| a.Name <=> b.Name }.first
|
|
43
|
+
else
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def save(arguments={})
|
|
49
|
+
self.errors = [] # clear the errors hash
|
|
50
|
+
begin
|
|
51
|
+
return save!(arguments)
|
|
52
|
+
rescue NotFound, BadResourceRequest => e
|
|
53
|
+
self.errors << {:code => e.code, :message => e.message}
|
|
54
|
+
FlexmlsApi.logger.error("Failed to save resource #{self}: #{e.message}")
|
|
55
|
+
end
|
|
56
|
+
false
|
|
57
|
+
end
|
|
58
|
+
def save!(arguments={})
|
|
59
|
+
# The long-term idea is that any setting in the user's account could be updated by including
|
|
60
|
+
# an attribute and calling PUT /my/account, but for now only the GetEmailUpdates attribute
|
|
61
|
+
# is supported
|
|
62
|
+
|
|
63
|
+
save_path = "/accounts/"+self.Id
|
|
64
|
+
|
|
65
|
+
ojbsome = {}
|
|
66
|
+
if attributes['GetEmailUpdates']
|
|
67
|
+
save_path = my_account? ? "/my/account" : self.class.path
|
|
68
|
+
ojbsome["GetEmailUpdates"] = attributes['GetEmailUpdates']
|
|
69
|
+
end
|
|
70
|
+
if attributes['PasswordValidation']
|
|
71
|
+
ojbsome["PasswordValidation"] = attributes['PasswordValidation']
|
|
72
|
+
end
|
|
73
|
+
if attributes['Password']
|
|
74
|
+
ojbsome["Password"] = attributes['Password']
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
results = connection.put save_path, ojbsome, arguments
|
|
78
|
+
true
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def subresource(klass, key, attributes)
|
|
85
|
+
return nil unless attributes.key?(key)
|
|
86
|
+
array = attributes[key]
|
|
87
|
+
result = PrimaryArray.new()
|
|
88
|
+
array.each do |i|
|
|
89
|
+
result << klass.new(i)
|
|
90
|
+
end
|
|
91
|
+
result
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
class Email < Base
|
|
95
|
+
include Primary
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class Phone < Base
|
|
99
|
+
include Primary
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
class Website < Base
|
|
103
|
+
include Primary
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
class Address < Base
|
|
107
|
+
include Primary
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
class Image < Base
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
module SparkApi
|
|
2
|
+
module Models
|
|
3
|
+
# =API Model Base class
|
|
4
|
+
# Intended to be a lot like working with ActiveResource, this class adds most of the basic
|
|
5
|
+
# active model type niceties.
|
|
6
|
+
class Base
|
|
7
|
+
extend Paginate
|
|
8
|
+
|
|
9
|
+
attr_accessor :attributes, :errors
|
|
10
|
+
attr_reader :changed
|
|
11
|
+
|
|
12
|
+
# Name of the resource as related to the path name
|
|
13
|
+
def self.element_name
|
|
14
|
+
# TODO I'd love to pull in active model at this point to provide default naming
|
|
15
|
+
@element_name ||= "resource"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.element_name=(name)
|
|
19
|
+
@element_name = name
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Resource path prefix, prepended to the url
|
|
23
|
+
def self.prefix
|
|
24
|
+
@prefix ||= "/"
|
|
25
|
+
end
|
|
26
|
+
def self.prefix=(prefix)
|
|
27
|
+
@prefix = prefix
|
|
28
|
+
end
|
|
29
|
+
def self.path
|
|
30
|
+
"#{prefix}#{element_name}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.connection
|
|
34
|
+
SparkApi.client
|
|
35
|
+
end
|
|
36
|
+
def connection
|
|
37
|
+
self.class.connection
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def initialize(attributes={})
|
|
41
|
+
@attributes = {}
|
|
42
|
+
@errors = []
|
|
43
|
+
@changed = []
|
|
44
|
+
load(attributes)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def load(attributes)
|
|
48
|
+
attributes.each do |key,val|
|
|
49
|
+
@attributes[key.to_s] = val
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.get(options={})
|
|
54
|
+
collect(connection.get(path, options))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.first(options={})
|
|
58
|
+
get(options).first
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.count(options={})
|
|
62
|
+
connection.get(path, options.merge({:_pagination=>"count"}))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def method_missing(method_symbol, *arguments)
|
|
66
|
+
method_name = method_symbol.to_s
|
|
67
|
+
|
|
68
|
+
if method_name =~ /(=|\?)$/
|
|
69
|
+
case $1
|
|
70
|
+
when "="
|
|
71
|
+
write_attribute($`, arguments.first)
|
|
72
|
+
# TODO figure out a nice way to present setters for the standard fields
|
|
73
|
+
when "?"
|
|
74
|
+
if attributes.include?($`)
|
|
75
|
+
attributes[$`] ? true : false
|
|
76
|
+
else
|
|
77
|
+
raise NoMethodError
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
return attributes[method_name] if attributes.include?(method_name)
|
|
82
|
+
super # GTFO
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def respond_to?(method_symbol, include_private=false)
|
|
87
|
+
if super
|
|
88
|
+
return true
|
|
89
|
+
else
|
|
90
|
+
method_name = method_symbol.to_s
|
|
91
|
+
|
|
92
|
+
if method_name =~ /=$/
|
|
93
|
+
true
|
|
94
|
+
elsif method_name =~ /(\?)$/
|
|
95
|
+
attributes.include?($`)
|
|
96
|
+
else
|
|
97
|
+
attributes.include?(method_name)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def parse_id(uri)
|
|
104
|
+
uri[/\/.*\/(.+)$/, 1]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
protected
|
|
108
|
+
|
|
109
|
+
def write_attribute(attribute, value)
|
|
110
|
+
unless attributes[attribute] == value
|
|
111
|
+
attributes[attribute] = value
|
|
112
|
+
@changed << attribute unless @changed.include?(attribute)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
module FlexmlsApi
|
|
2
|
+
module Models
|
|
3
|
+
# =API Model Base class
|
|
4
|
+
# Intended to be a lot like working with ActiveResource, this class adds most of the basic
|
|
5
|
+
# active model type niceties.
|
|
6
|
+
class Base
|
|
7
|
+
extend Paginate
|
|
8
|
+
|
|
9
|
+
attr_accessor :attributes, :errors
|
|
10
|
+
attr_reader :changed
|
|
11
|
+
|
|
12
|
+
# Name of the resource as related to the path name
|
|
13
|
+
def self.element_name
|
|
14
|
+
# TODO I'd love to pull in active model at this point to provide default naming
|
|
15
|
+
@element_name ||= "resource"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.element_name=(name)
|
|
19
|
+
@element_name = name
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Resource path prefix, prepended to the url
|
|
23
|
+
def self.prefix
|
|
24
|
+
@prefix ||= "/"
|
|
25
|
+
end
|
|
26
|
+
def self.prefix=(prefix)
|
|
27
|
+
@prefix = prefix
|
|
28
|
+
end
|
|
29
|
+
def self.path
|
|
30
|
+
"#{prefix}#{element_name}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.connection
|
|
34
|
+
FlexmlsApi.client
|
|
35
|
+
end
|
|
36
|
+
def connection
|
|
37
|
+
self.class.connection
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def initialize(attributes={})
|
|
41
|
+
@attributes = {}
|
|
42
|
+
@errors = []
|
|
43
|
+
@changed = []
|
|
44
|
+
load(attributes)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def load(attributes)
|
|
48
|
+
attributes.each do |key,val|
|
|
49
|
+
@attributes[key.to_s] = val
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.get(options={})
|
|
54
|
+
collect(connection.get(path, options))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.first(options={})
|
|
58
|
+
get(options).first
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.count(options={})
|
|
62
|
+
connection.get(path, options.merge({:_pagination=>"count"}))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def method_missing(method_symbol, *arguments)
|
|
66
|
+
method_name = method_symbol.to_s
|
|
67
|
+
|
|
68
|
+
if method_name =~ /(=|\?)$/
|
|
69
|
+
case $1
|
|
70
|
+
when "="
|
|
71
|
+
write_attribute($`, arguments.first)
|
|
72
|
+
# TODO figure out a nice way to present setters for the standard fields
|
|
73
|
+
when "?"
|
|
74
|
+
if attributes.include?($`)
|
|
75
|
+
attributes[$`] ? true : false
|
|
76
|
+
else
|
|
77
|
+
raise NoMethodError
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
return attributes[method_name] if attributes.include?(method_name)
|
|
82
|
+
super # GTFO
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def respond_to?(method_symbol, include_private=false)
|
|
87
|
+
if super
|
|
88
|
+
return true
|
|
89
|
+
else
|
|
90
|
+
method_name = method_symbol.to_s
|
|
91
|
+
|
|
92
|
+
if method_name =~ /=$/
|
|
93
|
+
true
|
|
94
|
+
elsif method_name =~ /(\?)$/
|
|
95
|
+
attributes.include?($`)
|
|
96
|
+
else
|
|
97
|
+
attributes.include?(method_name)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def parse_id(uri)
|
|
104
|
+
uri[/\/.*\/(.+)$/, 1]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
protected
|
|
108
|
+
|
|
109
|
+
def write_attribute(attribute, value)
|
|
110
|
+
unless attributes[attribute] == value
|
|
111
|
+
attributes[attribute] = value
|
|
112
|
+
@changed << attribute unless @changed.include?(attribute)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|