flexmls_api 0.4.5 → 0.6.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.
Files changed (93) hide show
  1. data/Gemfile +2 -17
  2. data/Gemfile.lock +35 -27
  3. data/README.md +23 -1
  4. data/Rakefile +18 -5
  5. data/VERSION +1 -1
  6. data/bin/flexmls_api +8 -0
  7. data/lib/flexmls_api.rb +2 -0
  8. data/lib/flexmls_api/authentication.rb +5 -6
  9. data/lib/flexmls_api/authentication/api_auth.rb +4 -2
  10. data/lib/flexmls_api/authentication/oauth2.rb +51 -99
  11. data/lib/flexmls_api/authentication/oauth2_impl/grant_type_base.rb +85 -0
  12. data/lib/flexmls_api/authentication/oauth2_impl/grant_type_code.rb +48 -0
  13. data/lib/flexmls_api/authentication/oauth2_impl/grant_type_password.rb +45 -0
  14. data/lib/flexmls_api/authentication/oauth2_impl/grant_type_refresh.rb +36 -0
  15. data/lib/flexmls_api/authentication/oauth2_impl/middleware.rb +39 -0
  16. data/lib/flexmls_api/cli.rb +132 -0
  17. data/lib/flexmls_api/cli/api_auth.rb +8 -0
  18. data/lib/flexmls_api/cli/oauth2.rb +43 -0
  19. data/lib/flexmls_api/cli/setup.rb +44 -0
  20. data/lib/flexmls_api/configuration.rb +6 -6
  21. data/lib/flexmls_api/faraday.rb +11 -21
  22. data/lib/flexmls_api/models.rb +3 -0
  23. data/lib/flexmls_api/models/account.rb +48 -5
  24. data/lib/flexmls_api/models/base.rb +27 -2
  25. data/lib/flexmls_api/models/contact.rb +28 -9
  26. data/lib/flexmls_api/models/listing_cart.rb +72 -0
  27. data/lib/flexmls_api/models/note.rb +0 -2
  28. data/lib/flexmls_api/models/saved_search.rb +16 -0
  29. data/lib/flexmls_api/models/shared_listing.rb +35 -0
  30. data/lib/flexmls_api/multi_client.rb +37 -0
  31. data/lib/flexmls_api/paginate.rb +5 -0
  32. data/lib/flexmls_api/request.rb +7 -3
  33. data/script/console +6 -0
  34. data/script/example.rb +27 -0
  35. data/spec/fixtures/accounts/all.json +160 -0
  36. data/spec/fixtures/accounts/my.json +74 -0
  37. data/spec/fixtures/accounts/my_portal.json +20 -0
  38. data/spec/fixtures/accounts/my_put.json +5 -0
  39. data/spec/fixtures/accounts/my_save.json +5 -0
  40. data/spec/fixtures/accounts/office.json +142 -0
  41. data/spec/fixtures/base.json +13 -0
  42. data/spec/fixtures/contact_my.json +19 -0
  43. data/spec/fixtures/contact_new.json +11 -0
  44. data/spec/fixtures/contact_new_empty.json +8 -0
  45. data/spec/fixtures/contact_new_notify.json +11 -0
  46. data/spec/fixtures/contact_tags.json +11 -0
  47. data/spec/fixtures/contacts.json +6 -3
  48. data/spec/fixtures/contacts_post.json +10 -0
  49. data/spec/fixtures/empty.json +3 -0
  50. data/spec/fixtures/errors/failure.json +5 -0
  51. data/spec/fixtures/listing_cart.json +19 -0
  52. data/spec/fixtures/listing_cart_add_listing.json +13 -0
  53. data/spec/fixtures/listing_cart_add_listing_post.json +5 -0
  54. data/spec/fixtures/listing_cart_empty.json +5 -0
  55. data/spec/fixtures/listing_cart_new.json +12 -0
  56. data/spec/fixtures/listing_cart_post.json +10 -0
  57. data/spec/fixtures/listing_cart_remove_listing.json +13 -0
  58. data/spec/fixtures/note_new.json +5 -0
  59. data/spec/fixtures/{oauth2_access.json → oauth2/access.json} +0 -0
  60. data/spec/fixtures/oauth2/access_with_old_refresh.json +5 -0
  61. data/spec/fixtures/oauth2/access_with_refresh.json +5 -0
  62. data/spec/fixtures/oauth2/authorization_code_body.json +7 -0
  63. data/spec/fixtures/oauth2/error.json +3 -0
  64. data/spec/fixtures/oauth2/password_body.json +7 -0
  65. data/spec/fixtures/oauth2/refresh_body.json +7 -0
  66. data/spec/fixtures/saved_search.json +17 -0
  67. data/spec/fixtures/shared_listing_new.json +9 -0
  68. data/spec/fixtures/shared_listing_post.json +10 -0
  69. data/spec/mock_helper.rb +123 -0
  70. data/spec/oauth2_helper.rb +69 -0
  71. data/spec/spec_helper.rb +1 -57
  72. data/spec/unit/flexmls_api/authentication/api_auth_spec.rb +1 -0
  73. data/spec/unit/flexmls_api/authentication/oauth2_impl/grant_type_base_spec.rb +10 -0
  74. data/spec/unit/flexmls_api/authentication/oauth2_spec.rb +74 -79
  75. data/spec/unit/flexmls_api/configuration_spec.rb +25 -4
  76. data/spec/unit/flexmls_api/models/account_spec.rb +152 -85
  77. data/spec/unit/flexmls_api/models/base_spec.rb +69 -25
  78. data/spec/unit/flexmls_api/models/contact_spec.rb +48 -34
  79. data/spec/unit/flexmls_api/models/document_spec.rb +1 -7
  80. data/spec/unit/flexmls_api/models/listing_cart_spec.rb +114 -0
  81. data/spec/unit/flexmls_api/models/listing_spec.rb +8 -56
  82. data/spec/unit/flexmls_api/models/note_spec.rb +8 -38
  83. data/spec/unit/flexmls_api/models/photo_spec.rb +1 -11
  84. data/spec/unit/flexmls_api/models/saved_search_spec.rb +34 -0
  85. data/spec/unit/flexmls_api/models/shared_listing_spec.rb +30 -0
  86. data/spec/unit/flexmls_api/models/standard_fields_spec.rb +50 -30
  87. data/spec/unit/flexmls_api/models/tour_of_home_spec.rb +1 -7
  88. data/spec/unit/flexmls_api/models/video_spec.rb +1 -10
  89. data/spec/unit/flexmls_api/models/virtual_tour_spec.rb +1 -7
  90. data/spec/unit/flexmls_api/multi_client_spec.rb +48 -0
  91. data/spec/unit/flexmls_api/request_spec.rb +42 -5
  92. metadata +239 -93
  93. data/spec/unit/flexmls_api/standard_fields_spec.rb +0 -86
@@ -0,0 +1,35 @@
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
@@ -0,0 +1,37 @@
1
+ module FlexmlsApi
2
+ #===Active support for multiple clients
3
+ module MultiClient
4
+
5
+ # Activate a specific instance of the client (with appropriate config settings). Each client
6
+ # is lazily instanciated by calling the matching FlexmlsApi.symbol_name method on the
7
+ # FlexmlsApi module. It's the developers responsibility to extend the module and provide this
8
+ # method.
9
+ # Parameters
10
+ # @sym - the unique symbol identifier for a client configuration.
11
+ # &block - a block of code to run with the specified client enabled, after which the original
12
+ # client setting will be reenabled
13
+ def activate(sym)
14
+ if block_given?
15
+ original_client = Thread.current[:flexmls_api_client]
16
+ activate_client(sym)
17
+ begin
18
+ yield
19
+ ensure
20
+ Thread.current[:flexmls_api_client] = original_client
21
+ end
22
+ else
23
+ activate_client(sym)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ # set the active client for the symbol
30
+ def activate_client(sym)
31
+ active_client = Thread.current[sym] || FlexmlsApi.send(sym)
32
+ Thread.current[:flexmls_api_client] = active_client unless active_client.nil?
33
+ rescue NoMethodError => e
34
+ raise ArgumentError, "The symbol #{sym} is missing a corresponding FlexmlsApi.#{sym} method.", e.backtrace
35
+ end
36
+ end
37
+ end
@@ -40,6 +40,11 @@ module FlexmlsApi
40
40
  # :returns:
41
41
  # An array of class instances for the Class of the calling finder
42
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
+
43
48
  collection = result_array.collect { |item| new(item)}
44
49
  result_array.replace(collection)
45
50
  result_array
@@ -125,10 +125,14 @@ module FlexmlsApi
125
125
  class InvalidResponse < StandardError; end
126
126
  class ClientError < StandardError
127
127
  attr_reader :code, :status
128
- def initialize (code, status)
129
- @code = code
130
- @status = status
128
+ def initialize (options = {})
129
+ # Support the standard initializer for errors
130
+ opts = options.is_a?(Hash) ? options : {:message => options.to_s}
131
+ @code = opts[:code]
132
+ @status = opts[:status]
133
+ super(opts[:message])
131
134
  end
135
+
132
136
  end
133
137
  class NotFound < ClientError; end
134
138
  class PermissionDenied < ClientError; end
data/script/console ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+
4
+ require File.dirname(__FILE__) + '/../lib/flexmls_api/cli'
5
+ ENV["FLEXMLS_API_CONSOLE"] = "true"
6
+ FlexmlsApi::CLI::ConsoleCLI.execute(STDOUT, ARGV)
data/script/example.rb ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+
4
+ Bundler.require(:default, "development") if defined?(Bundler)
5
+
6
+ path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
7
+ $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
8
+ require path + '/flexmls_api'
9
+
10
+ FlexmlsApi.logger.info("Hello!")
11
+
12
+ FlexmlsApi.configure do |config|
13
+ config.api_key = "agent_key"
14
+ config.api_secret = "agent_secret"
15
+ config.version = "v1"
16
+ config.endpoint = "https://api.flexmls.com"
17
+ end
18
+
19
+ client = FlexmlsApi.client
20
+
21
+ list = client.get '/contacts'
22
+ puts "client: #{list.inspect}"
23
+ list = FlexmlsApi::Models::Contact.get
24
+ puts "model: #{list.inspect}"
25
+
26
+
27
+
@@ -0,0 +1,160 @@
1
+ {
2
+ "D": {
3
+ "Success": true,
4
+ "Results": [
5
+ {
6
+ "Name" : "Sample User",
7
+ "Id" : "20000426173054342350000000",
8
+ "Office" : "Sample Office Inc",
9
+ "OfficeId" : "20030426173014239760000000",
10
+ "Mls" : "Your Local MLS",
11
+ "MlsId": "20000426143505724628000000",
12
+ "Emails": [
13
+ {
14
+ "Type": "Work",
15
+ "Name": "My Work E-mail",
16
+ "Address": "work@test.com",
17
+ "Primary": true
18
+ },
19
+ {
20
+ "Type": "Mobile",
21
+ "Name": "My Mobile E-mail",
22
+ "Address": "mobile@test.com"
23
+ }
24
+ ],
25
+ "Phones": [
26
+ {
27
+ "Type": "Work",
28
+ "Name": "My Work Phone",
29
+ "Number": "701-555-1212",
30
+ "Primary": true
31
+ },
32
+ {
33
+ "Type": "Mobile",
34
+ "Name": "My Mobile Phone",
35
+ "Number": "702-555-1313"
36
+ }
37
+ ],
38
+ "Websites": [
39
+ {
40
+ "Type": "Work",
41
+ "Name": "My Work Website",
42
+ "Uri": "http://iamthebestagent.com",
43
+ "Primary": true
44
+ },
45
+ {
46
+ "Type": "Mobile",
47
+ "Name": "My Mobile Website",
48
+ "Uri": "http://m.iamthebestagent.com"
49
+ }
50
+ ],
51
+ "Addresses": [
52
+ {
53
+ "Type": "Work",
54
+ "Name": "My Work Address",
55
+ "Address": "101 Main Ave, Phoenix, AZ 12345",
56
+ "Primary": true
57
+ }
58
+ ],
59
+ "Images": [
60
+ {
61
+ "Type": "Photo",
62
+ "Name": "My Photo",
63
+ "Uri": "http://photos.flexmls.com/az/...."
64
+ },
65
+ {
66
+ "Type": "Logo",
67
+ "Name": "My Logo",
68
+ "Uri": "http://photos.flexmls.com/az/...."
69
+ }
70
+ ]
71
+ },
72
+ {
73
+ "Name" : "Other User",
74
+ "Id" : "20000426173054382350000000",
75
+ "Office" : "Sample Office Inc",
76
+ "OfficeId" : "20030426173014239760000000",
77
+ "Mls" : "Your Local MLS",
78
+ "MlsId": "20000426143505724628000000",
79
+ "Emails": [
80
+ {
81
+ "Type": "Work",
82
+ "Name": "My Work E-mail",
83
+ "Address": "otherwork@test.com",
84
+ "Primary": true
85
+ },
86
+ {
87
+ "Type": "Mobile",
88
+ "Name": "My Mobile E-mail",
89
+ "Address": "othermobile@test.com"
90
+ }
91
+ ],
92
+ "Phones": [
93
+ {
94
+ "Type": "Work",
95
+ "Name": "My Work Phone",
96
+ "Number": "701-555-1414",
97
+ "Primary": true
98
+ },
99
+ {
100
+ "Type": "Mobile",
101
+ "Name": "My Mobile Phone",
102
+ "Number": "702-555-1515"
103
+ }
104
+ ],
105
+ "Websites": [
106
+ {
107
+ "Type": "Work",
108
+ "Name": "My Work Website",
109
+ "Uri": "http://iamtheotheragent.com",
110
+ "Primary": true
111
+ },
112
+ {
113
+ "Type": "Mobile",
114
+ "Name": "My Mobile Website",
115
+ "Uri": "http://m.iamtheotheragent.com"
116
+ }
117
+ ],
118
+ "Addresses": [
119
+ {
120
+ "Type": "Work",
121
+ "Name": "My Work Address",
122
+ "Address": "101 Main Ave, Phoenix, AZ 12345",
123
+ "Primary": true
124
+ }
125
+ ],
126
+ "Images": [
127
+ {
128
+ "Type": "Photo",
129
+ "Name": "My Photo",
130
+ "Uri": "http://photos.flexmls.com/az/1234.jpg"
131
+ },
132
+ {
133
+ "Type": "Logo",
134
+ "Name": "My Logo",
135
+ "Uri": "http://photos.flexmls.com/az/logo.jpg"
136
+ }
137
+ ]
138
+ },
139
+ {
140
+ "Name" : "Empty User",
141
+ "Id" : "20110126173054382350000000",
142
+ "Office" : "New Office Inc",
143
+ "OfficeId" : "20110426173014239760000000",
144
+ "Mls" : "New MLS",
145
+ "MlsId": "20110426143505724628000000",
146
+ "Emails": [
147
+ ],
148
+ "Phones": [
149
+ ],
150
+ "Websites": [
151
+ ],
152
+ "Addresses": [
153
+ ],
154
+ "Images": [
155
+ ]
156
+ }
157
+
158
+ ]
159
+ }
160
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "D": {
3
+ "Success": true,
4
+ "Results": [
5
+ {
6
+ "Name" : "Sample User",
7
+ "Id" : "20000426173054342350000000",
8
+ "Office" : "Sample Office Inc",
9
+ "OfficeId" : "20030426173014239760000000",
10
+ "Mls" : "Your Local MLS",
11
+ "MlsId": "20000426143505724628000000",
12
+ "Emails": [
13
+ {
14
+ "Type": "Work",
15
+ "Name": "My Work E-mail",
16
+ "Address": "work@test.com",
17
+ "Primary": true
18
+ },
19
+ {
20
+ "Type": "Mobile",
21
+ "Name": "My Mobile E-mail",
22
+ "Address": "mobile@test.com"
23
+ }
24
+ ],
25
+ "Phones": [
26
+ {
27
+ "Type": "Work",
28
+ "Name": "My Work Phone",
29
+ "Number": "701-555-1212",
30
+ "Primary": true
31
+ },
32
+ {
33
+ "Type": "Mobile",
34
+ "Name": "My Mobile Phone",
35
+ "Number": "702-555-1313"
36
+ }
37
+ ],
38
+ "Websites": [
39
+ {
40
+ "Type": "Work",
41
+ "Name": "My Work Website",
42
+ "Uri": "http://iamthebestagent.com",
43
+ "Primary": true
44
+ },
45
+ {
46
+ "Type": "Mobile",
47
+ "Name": "My Mobile Website",
48
+ "Uri": "http://m.iamthebestagent.com"
49
+ }
50
+ ],
51
+ "Addresses": [
52
+ {
53
+ "Type": "Work",
54
+ "Name": "My Work Address",
55
+ "Address": "101 Main Ave, Phoenix, AZ 12345",
56
+ "Primary": true
57
+ }
58
+ ],
59
+ "Images": [
60
+ {
61
+ "Type": "Photo",
62
+ "Name": "My Photo",
63
+ "Uri": "http://photos.flexmls.com/az/...."
64
+ },
65
+ {
66
+ "Type": "Logo",
67
+ "Name": "My Logo",
68
+ "Uri": "http://photos.flexmls.com/az/...."
69
+ }
70
+ ]
71
+ }
72
+ ]
73
+ }
74
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "D": {
3
+ "Success": true,
4
+ "Results": [
5
+ {
6
+ "Name" : "Portal User",
7
+ "Id" : "20110426173054342350000000",
8
+ "Emails": [
9
+ ],
10
+ "Phones": [
11
+ ],
12
+ "Websites": [
13
+ ],
14
+ "Addresses": [
15
+ ],
16
+ "GetEmailUpdates": false
17
+ }
18
+ ]
19
+ }
20
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "D": {
3
+ "Success": true
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "D": {
3
+ "GetEmailUpdates": true
4
+ }
5
+ }
@@ -0,0 +1,142 @@
1
+ {
2
+ "D": {
3
+ "Success": true,
4
+ "Results": [
5
+ {
6
+ "Name" : "Sample User",
7
+ "Id" : "20000426173054342350000000",
8
+ "Office" : "Sample Office Inc",
9
+ "OfficeId" : "20030426173014239760000000",
10
+ "Mls" : "Your Local MLS",
11
+ "MlsId": "20000426143505724628000000",
12
+ "Emails": [
13
+ {
14
+ "Type": "Work",
15
+ "Name": "My Work E-mail",
16
+ "Address": "work@test.com",
17
+ "Primary": true
18
+ },
19
+ {
20
+ "Type": "Mobile",
21
+ "Name": "My Mobile E-mail",
22
+ "Address": "mobile@test.com"
23
+ }
24
+ ],
25
+ "Phones": [
26
+ {
27
+ "Type": "Work",
28
+ "Name": "My Work Phone",
29
+ "Number": "701-555-1212",
30
+ "Primary": true
31
+ },
32
+ {
33
+ "Type": "Mobile",
34
+ "Name": "My Mobile Phone",
35
+ "Number": "702-555-1313"
36
+ }
37
+ ],
38
+ "Websites": [
39
+ {
40
+ "Type": "Work",
41
+ "Name": "My Work Website",
42
+ "Uri": "http://iamthebestagent.com",
43
+ "Primary": true
44
+ },
45
+ {
46
+ "Type": "Mobile",
47
+ "Name": "My Mobile Website",
48
+ "Uri": "http://m.iamthebestagent.com"
49
+ }
50
+ ],
51
+ "Addresses": [
52
+ {
53
+ "Type": "Work",
54
+ "Name": "My Work Address",
55
+ "Address": "101 Main Ave, Phoenix, AZ 12345",
56
+ "Primary": true
57
+ }
58
+ ],
59
+ "Images": [
60
+ {
61
+ "Type": "Photo",
62
+ "Name": "My Photo",
63
+ "Uri": "http://photos.flexmls.com/az/...."
64
+ },
65
+ {
66
+ "Type": "Logo",
67
+ "Name": "My Logo",
68
+ "Uri": "http://photos.flexmls.com/az/...."
69
+ }
70
+ ]
71
+ },
72
+ {
73
+ "Name" : "Other User",
74
+ "Id" : "20000426173054382350000000",
75
+ "Office" : "Sample Office Inc",
76
+ "OfficeId" : "20030426173014239760000000",
77
+ "Mls" : "Your Local MLS",
78
+ "MlsId": "20000426143505724628000000",
79
+ "Emails": [
80
+ {
81
+ "Type": "Work",
82
+ "Name": "My Work E-mail",
83
+ "Address": "otherwork@test.com",
84
+ "Primary": true
85
+ },
86
+ {
87
+ "Type": "Mobile",
88
+ "Name": "My Mobile E-mail",
89
+ "Address": "othermobile@test.com"
90
+ }
91
+ ],
92
+ "Phones": [
93
+ {
94
+ "Type": "Work",
95
+ "Name": "My Work Phone",
96
+ "Number": "701-555-1414",
97
+ "Primary": true
98
+ },
99
+ {
100
+ "Type": "Mobile",
101
+ "Name": "My Mobile Phone",
102
+ "Number": "702-555-1515"
103
+ }
104
+ ],
105
+ "Websites": [
106
+ {
107
+ "Type": "Work",
108
+ "Name": "My Work Website",
109
+ "Uri": "http://iamtheotheragent.com",
110
+ "Primary": true
111
+ },
112
+ {
113
+ "Type": "Mobile",
114
+ "Name": "My Mobile Website",
115
+ "Uri": "http://m.iamtheotheragent.com"
116
+ }
117
+ ],
118
+ "Addresses": [
119
+ {
120
+ "Type": "Work",
121
+ "Name": "My Work Address",
122
+ "Address": "101 Main Ave, Phoenix, AZ 12345",
123
+ "Primary": true
124
+ }
125
+ ],
126
+ "Images": [
127
+ {
128
+ "Type": "Photo",
129
+ "Name": "My Photo",
130
+ "Uri": "http://photos.flexmls.com/az/1234.jpg"
131
+ },
132
+ {
133
+ "Type": "Logo",
134
+ "Name": "My Logo",
135
+ "Uri": "http://photos.flexmls.com/az/logo.jpg"
136
+ }
137
+ ]
138
+ }
139
+
140
+ ]
141
+ }
142
+ }