flexmls_api 0.4.5 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
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
+ }