rentlinx 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -16
- data/lib/rentlinx.rb +19 -0
- data/lib/rentlinx/client.rb +24 -0
- data/lib/rentlinx/default.rb +1 -0
- data/lib/rentlinx/errors.rb +20 -0
- data/lib/rentlinx/models/base.rb +46 -8
- data/lib/rentlinx/models/property.rb +25 -0
- data/lib/rentlinx/models/property_amenity.rb +4 -0
- data/lib/rentlinx/models/property_link.rb +4 -0
- data/lib/rentlinx/models/property_photo.rb +4 -0
- data/lib/rentlinx/models/unit.rb +14 -0
- data/lib/rentlinx/models/unit_amenity.rb +1 -0
- data/lib/rentlinx/models/unit_link.rb +1 -0
- data/lib/rentlinx/models/unit_photo.rb +1 -0
- data/lib/rentlinx/modules/amenity_client_methods.rb +24 -0
- data/lib/rentlinx/modules/amenityable.rb +23 -0
- data/lib/rentlinx/modules/link_client_methods.rb +24 -0
- data/lib/rentlinx/modules/linkable.rb +12 -0
- data/lib/rentlinx/modules/photo_client_methods.rb +3 -0
- data/lib/rentlinx/modules/photoable.rb +4 -0
- data/lib/rentlinx/modules/property_client_methods.rb +5 -0
- data/lib/rentlinx/modules/unit_client_methods.rb +1 -0
- data/lib/rentlinx/validators/address_validator.rb +13 -0
- data/lib/rentlinx/validators/attribute_processor_service.rb +20 -1
- data/lib/rentlinx/validators/base_validator.rb +12 -0
- data/lib/rentlinx/validators/city_validator.rb +3 -0
- data/lib/rentlinx/validators/phone_validator.rb +2 -0
- data/lib/rentlinx/validators/state_validator.rb +3 -0
- data/lib/rentlinx/validators/url_validator.rb +1 -0
- data/lib/rentlinx/validators/zip_validator.rb +1 -0
- data/lib/rentlinx/version.rb +3 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cedfa421e0893f1fb8ece12bd133929b75107c85
|
4
|
+
data.tar.gz: d2de51edd47f047a7244efa188e406b237ea964d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c22c7e3ed1751a8863519d5b02563db53b47f939e6a9bfa39e87fb1a2453d2e16cc2d207da897b3dcc94274c0fe3c664b504bbf95bd0ad639acd4c9924a5824
|
7
|
+
data.tar.gz: 2f6c08a6f4643ba3b5c78c588d235fb6490fb7beeba556b7c2790b647a3b296d17e942235c613427a17e5354896e094550eecb69aa968c6110a572df403e0cf5
|
data/README.md
CHANGED
@@ -9,8 +9,39 @@ _rentlinx_client_ is a ruby wrapper for the RentLinx API.
|
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
12
|
+
To install from the command line, run:
|
13
|
+
|
12
14
|
gem install rentlinx
|
13
15
|
|
16
|
+
To include in a rails app, include this line in your gemfile:
|
17
|
+
|
18
|
+
gem 'rentlinx'
|
19
|
+
|
20
|
+
### Usage
|
21
|
+
|
22
|
+
Configure like so:
|
23
|
+
|
24
|
+
Rentlinx.configure do |rentlinx|
|
25
|
+
rentlinx.username ENV['RENTLINX_USERNAME']
|
26
|
+
rentlinx.password ENV['RENTLINX_PASSWORD']
|
27
|
+
rentlinx.site_url 'https://rentlinx.com/api/v2'
|
28
|
+
rentlinx.log_level :error
|
29
|
+
end
|
30
|
+
|
31
|
+
For all endpoints, attributes are defined by the API: https://www.rentlinx.com/mongoose/help
|
32
|
+
|
33
|
+
Properties:
|
34
|
+
|
35
|
+
prop = Property.new(attributes)
|
36
|
+
prop.post # creates
|
37
|
+
|
38
|
+
prop.website = 'http://example.com'
|
39
|
+
prop.post # updates
|
40
|
+
|
41
|
+
prop = Property.from_id('property-id') # fetches
|
42
|
+
|
43
|
+
Objects can be created for all endpoints supported by the Rentlinx API, including Units, Amenities, Photos, and Links. For more detailed information, see the [full documentation on rubygems](http://www.rubydoc.info/gems/rentlinx).
|
44
|
+
|
14
45
|
## Contributing and development
|
15
46
|
|
16
47
|
Pull requests are welcome for this gem. New features require writing new
|
@@ -36,6 +67,12 @@ Not all rubocop's rules are set in stone, so once you are receiving only
|
|
36
67
|
warnings testing rules that may not make sense, please comment on your pull
|
37
68
|
request indicating you think the rules should be adjusted with your reasoning.
|
38
69
|
|
70
|
+
### Documentation
|
71
|
+
|
72
|
+
All new classes, modules, and public methods should be documented in the style
|
73
|
+
of [yard](http://yardoc.org/). Modified classes and methods should have their
|
74
|
+
documentation updated accordingly. Tests do not need documentation.
|
75
|
+
|
39
76
|
### Testing: Unit tests
|
40
77
|
|
41
78
|
The second suite is running minitest. The simplest way to invoke our minitest
|
@@ -48,22 +85,6 @@ test files can be executed via:
|
|
48
85
|
|
49
86
|
ruby -Ilib:test test/FILENAME.rb
|
50
87
|
|
51
|
-
|
52
|
-
### Usage
|
53
|
-
|
54
|
-
For all endpoints, attributes are defined by the API: https://www.rentlinx.com/mongoose/help
|
55
|
-
|
56
|
-
Properties can be created, updated, and fetched from Rentlinx like so:
|
57
|
-
|
58
|
-
prop = Property.new(attributes)
|
59
|
-
prop.post # creates
|
60
|
-
|
61
|
-
prop.website = 'http://example.com'
|
62
|
-
prop.post # updates
|
63
|
-
|
64
|
-
prop = Property.from_id('property-id') # fetches
|
65
|
-
|
66
|
-
|
67
88
|
## Copyright and license
|
68
89
|
|
69
90
|
Source released under the Simplified BSD License.
|
data/lib/rentlinx.rb
CHANGED
@@ -11,16 +11,29 @@ require 'rentlinx/models/unit_amenity'
|
|
11
11
|
require 'rentlinx/models/property_link'
|
12
12
|
require 'rentlinx/models/unit_link'
|
13
13
|
|
14
|
+
# This is the main rentlinx module. All Rentlinx objects
|
15
|
+
# and methods are namespaced under this module.
|
14
16
|
module Rentlinx
|
15
17
|
@username = nil
|
16
18
|
@password = nil
|
17
19
|
@site_url = nil
|
18
20
|
|
19
21
|
class << self
|
22
|
+
# Allows the configuration of Rentlinx in a configure-block
|
23
|
+
# style.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# Rentlinx.configure do |rentlinx|
|
27
|
+
# rentlinx.username ENV['RENTLINX_USERNAME']
|
28
|
+
# rentlinx.password ENV['RENTLINX_PASSWORD']
|
29
|
+
# rentlinx.site_url 'https://rentlinx.com/api/v2'
|
30
|
+
# rentlinx.log_level :error
|
31
|
+
# end
|
20
32
|
def configure(&block)
|
21
33
|
block.call(self)
|
22
34
|
end
|
23
35
|
|
36
|
+
# Sets and retrieves the username used to log in to Rentlinx
|
24
37
|
def username(*args)
|
25
38
|
if args.empty?
|
26
39
|
@username
|
@@ -29,6 +42,7 @@ module Rentlinx
|
|
29
42
|
end
|
30
43
|
end
|
31
44
|
|
45
|
+
# Sets and retrieves the password used to log in to Rentlinx
|
32
46
|
def password(*args)
|
33
47
|
if args.empty?
|
34
48
|
@password
|
@@ -37,6 +51,7 @@ module Rentlinx
|
|
37
51
|
end
|
38
52
|
end
|
39
53
|
|
54
|
+
# Sets and retrieves the URL where the API is hosted.
|
40
55
|
def site_url(*args)
|
41
56
|
if args.empty?
|
42
57
|
@site_url
|
@@ -45,6 +60,8 @@ module Rentlinx
|
|
45
60
|
end
|
46
61
|
end
|
47
62
|
|
63
|
+
# Sets and retrieves the log level, currently only :error
|
64
|
+
# and :debug are supported
|
48
65
|
def log_level(*args)
|
49
66
|
if args.empty?
|
50
67
|
@log_level
|
@@ -53,10 +70,12 @@ module Rentlinx
|
|
53
70
|
end
|
54
71
|
end
|
55
72
|
|
73
|
+
# The client object used for communicating with Rentlinx
|
56
74
|
def client
|
57
75
|
@client ||= Rentlinx::Client.new
|
58
76
|
end
|
59
77
|
|
78
|
+
# The logger object
|
60
79
|
def logger
|
61
80
|
lgr = Logging.logger(STDOUT)
|
62
81
|
lgr.level = (@log_level || :error)
|
data/lib/rentlinx/client.rb
CHANGED
@@ -9,6 +9,11 @@ require 'rentlinx/modules/amenity_client_methods'
|
|
9
9
|
require 'rentlinx/modules/link_client_methods'
|
10
10
|
|
11
11
|
module Rentlinx
|
12
|
+
# This class and its included modules encapsulate all
|
13
|
+
# communication directly with the Rentlinx API.
|
14
|
+
#
|
15
|
+
# It should not be interacted with, the objects provide
|
16
|
+
# all the functionality necessary to work with Rentlinx.
|
12
17
|
class Client
|
13
18
|
include Rentlinx::PropertyClientMethods
|
14
19
|
include Rentlinx::UnitClientMethods
|
@@ -16,6 +21,14 @@ module Rentlinx
|
|
16
21
|
include Rentlinx::AmenityClientMethods
|
17
22
|
include Rentlinx::LinkClientMethods
|
18
23
|
|
24
|
+
# Returns a new instance of client. Avoid using.
|
25
|
+
#
|
26
|
+
# Note that the method {Rentlinx.client} initializes and caches
|
27
|
+
# an instance of the Rentlinx client. This method should be used
|
28
|
+
# instead of this one when interacting directly with the client
|
29
|
+
# to avoid making multiple connections to Rentlinx.
|
30
|
+
#
|
31
|
+
# Rentlinx must be configured before invoking this method.
|
19
32
|
def initialize
|
20
33
|
raise Rentlinx::NotConfigured if Rentlinx.username.nil? ||
|
21
34
|
Rentlinx.password.nil? ||
|
@@ -25,6 +38,9 @@ module Rentlinx
|
|
25
38
|
@api_token ||= authenticate(Rentlinx.username, Rentlinx.password)
|
26
39
|
end
|
27
40
|
|
41
|
+
# Pushes an object's attributes out to Rentlinx
|
42
|
+
#
|
43
|
+
# @param object [Rentlinx::Base] the object to be posted
|
28
44
|
def post(object)
|
29
45
|
case object
|
30
46
|
when Rentlinx::Property
|
@@ -38,6 +54,10 @@ module Rentlinx
|
|
38
54
|
end
|
39
55
|
end
|
40
56
|
|
57
|
+
# Unposts an object from Rentlinx
|
58
|
+
#
|
59
|
+
# @param type [Symbol] the type of object to be unposted
|
60
|
+
# @param id [String] the rentlinx id of the object to be unposted
|
41
61
|
def unpost(type, id)
|
42
62
|
case type
|
43
63
|
when :property
|
@@ -49,6 +69,10 @@ module Rentlinx
|
|
49
69
|
end
|
50
70
|
end
|
51
71
|
|
72
|
+
# Pulls the attributes for an object from Rentlinx and instantiates it
|
73
|
+
#
|
74
|
+
# @param type [Symbol] the type of object to be fetched
|
75
|
+
# @param id [String] the rentlinx id of the object to be fetched
|
52
76
|
def get(type, id)
|
53
77
|
case type
|
54
78
|
when :property
|
data/lib/rentlinx/default.rb
CHANGED
data/lib/rentlinx/errors.rb
CHANGED
@@ -1,33 +1,48 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
3
|
module Rentlinx
|
4
|
+
# Basic error class to be inherited from
|
5
|
+
#
|
6
|
+
# Use this error to rescue all types of Rentlinx errors
|
4
7
|
class RentlinxError < StandardError
|
5
8
|
end
|
6
9
|
|
10
|
+
# Thrown when instantiating an object with attributes
|
11
|
+
# that object does not support them
|
7
12
|
class UnexpectedAttributes < RentlinxError
|
8
13
|
end
|
9
14
|
|
15
|
+
# Thrown when posting or getting an invalid type
|
10
16
|
class InvalidTypeParam < RentlinxError
|
11
17
|
end
|
12
18
|
|
19
|
+
# Thrown when the Rentlinx client is initialized without first
|
20
|
+
# being configured
|
13
21
|
class NotConfigured < RentlinxError
|
14
22
|
def initialize
|
15
23
|
super('Rentlinx is not configured.')
|
16
24
|
end
|
17
25
|
end
|
18
26
|
|
27
|
+
# Thrown when an object that does not pass validation tries
|
28
|
+
# to post or update
|
19
29
|
class InvalidObject < RentlinxError
|
20
30
|
def initialize(object)
|
21
31
|
super("#{object.class} is invalid: #{object.error_messages}")
|
22
32
|
end
|
23
33
|
end
|
24
34
|
|
35
|
+
# Thrown when a group of objects is passed to a batch endpoint but
|
36
|
+
# cannot be posted because they belong to different properties
|
25
37
|
class IncompatibleGroupOfObjectsForPost < RentlinxError
|
26
38
|
def initialize(property)
|
27
39
|
super("These objects cannot be grouped together ('#{property}' differ).")
|
28
40
|
end
|
29
41
|
end
|
30
42
|
|
43
|
+
# A general class of errors for handling issues in the communication with
|
44
|
+
# Rentlinx. To be inherited from, or thrown when the server returns a code
|
45
|
+
# not otherwise handled.
|
31
46
|
class HTTPError < RentlinxError
|
32
47
|
attr_reader :response
|
33
48
|
|
@@ -37,6 +52,7 @@ module Rentlinx
|
|
37
52
|
end
|
38
53
|
end
|
39
54
|
|
55
|
+
# Thrown when error code 400 (bad request) is received
|
40
56
|
class BadRequest < HTTPError
|
41
57
|
def initialize(response)
|
42
58
|
default_message = 'The request sent to the server was invalid.'
|
@@ -49,24 +65,28 @@ module Rentlinx
|
|
49
65
|
end
|
50
66
|
end
|
51
67
|
|
68
|
+
# Thrown when error code 404 (not found) is received
|
52
69
|
class NotFound < HTTPError
|
53
70
|
def initialize(response)
|
54
71
|
super(response, 'The item you requested could not be found on the remote server.')
|
55
72
|
end
|
56
73
|
end
|
57
74
|
|
75
|
+
# Thrown when error code 409 (conflict) is received
|
58
76
|
class Conflict < HTTPError
|
59
77
|
def initialize(response)
|
60
78
|
super(response, 'There was a conflict on the remote server.')
|
61
79
|
end
|
62
80
|
end
|
63
81
|
|
82
|
+
# Thrown when error code 403 (forbidden) is received
|
64
83
|
class Forbidden < HTTPError
|
65
84
|
def initialize(response)
|
66
85
|
super(response, 'You are not permitted to access the item you requested.')
|
67
86
|
end
|
68
87
|
end
|
69
88
|
|
89
|
+
# Thrown when 500 series error codes (internal server errors) are received
|
70
90
|
class ServerError < HTTPError
|
71
91
|
def initialize(response)
|
72
92
|
super(response, 'The remote server has experienced an error.')
|
data/lib/rentlinx/models/base.rb
CHANGED
@@ -1,7 +1,20 @@
|
|
1
1
|
require 'rentlinx/validators/attribute_processor_service'
|
2
2
|
|
3
3
|
module Rentlinx
|
4
|
+
# This is the class on which all other Rentlinx classes are based,
|
5
|
+
# it encapsulates much of the important logic used by every class.
|
6
|
+
#
|
7
|
+
# It should never be instantiated on its own, use one of its
|
8
|
+
# subclasses.
|
4
9
|
class Base
|
10
|
+
# Creates a new instance of the class, but the base class should
|
11
|
+
# never be directly instantiated.
|
12
|
+
#
|
13
|
+
# This method takes in the attributes for the new instance, runs
|
14
|
+
# them through the {AttributeProcessor} and saves them as instance
|
15
|
+
# variables.
|
16
|
+
#
|
17
|
+
# @param attrs [Hash] a hash of attributes to save.
|
5
18
|
def initialize(attrs)
|
6
19
|
@processor = AttributeProcessor.new(attrs.dup)
|
7
20
|
attrs = @processor.process
|
@@ -12,30 +25,41 @@ module Rentlinx
|
|
12
25
|
raise UnexpectedAttributes, "Unexpected Attributes: #{remaining_attrs.join(', ')}" if remaining_attrs.compact.size > 0
|
13
26
|
end
|
14
27
|
|
28
|
+
# Provides a list of attributes supported by the class.
|
29
|
+
#
|
30
|
+
# @return an array of attribute keys
|
15
31
|
def attributes
|
16
32
|
self.class::ATTRIBUTES
|
17
33
|
end
|
18
34
|
|
35
|
+
# Provides the list of required attributes for the class (a subset of Class.attributes)
|
36
|
+
#
|
37
|
+
# @return an array of attribute keys
|
19
38
|
def required_attributes
|
20
39
|
self.class::REQUIRED_ATTRIBUTES
|
21
40
|
end
|
22
41
|
|
42
|
+
# Sends the object to Rentlinx
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# prop = Rentlinx::Property.new(attrs)
|
46
|
+
# prop.post
|
23
47
|
def post
|
24
48
|
Rentlinx.client.post(self)
|
25
49
|
end
|
26
50
|
|
51
|
+
# Removes the object from Rentlinx
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# prop = Rentlinx::Property.new(attrs)
|
55
|
+
# prop.unpost
|
27
56
|
def unpost
|
28
57
|
Rentlinx.client.unpost(type, send(type.to_s + 'ID'))
|
29
58
|
end
|
30
59
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
def self.get_from_id(type, id)
|
36
|
-
Rentlinx.client.get(type.to_sym, id)
|
37
|
-
end
|
38
|
-
|
60
|
+
# Converts the object to a hash
|
61
|
+
#
|
62
|
+
# @return a hash including the attributes and values
|
39
63
|
def to_hash
|
40
64
|
{}.tap do |hash|
|
41
65
|
attributes.each do |at|
|
@@ -44,10 +68,16 @@ module Rentlinx
|
|
44
68
|
end
|
45
69
|
end
|
46
70
|
|
71
|
+
# Determines the validity of the object
|
72
|
+
#
|
73
|
+
# @return true if valid, false if invalid
|
47
74
|
def valid?
|
48
75
|
error_messages.empty?
|
49
76
|
end
|
50
77
|
|
78
|
+
# Provides error messages on invalid objects
|
79
|
+
#
|
80
|
+
# @return a hash of error messages
|
51
81
|
def error_messages
|
52
82
|
@processor = AttributeProcessor.new(to_hash)
|
53
83
|
@processor.process
|
@@ -63,6 +93,14 @@ module Rentlinx
|
|
63
93
|
|
64
94
|
private
|
65
95
|
|
96
|
+
def self.unpost(id)
|
97
|
+
Rentlinx.client.unpost(type, id)
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.get_from_id(type, id)
|
101
|
+
Rentlinx.client.get(type.to_sym, id)
|
102
|
+
end
|
103
|
+
|
66
104
|
def type
|
67
105
|
self.class.type
|
68
106
|
end
|
@@ -3,6 +3,7 @@ require 'rentlinx/modules/amenityable'
|
|
3
3
|
require 'rentlinx/modules/linkable'
|
4
4
|
|
5
5
|
module Rentlinx
|
6
|
+
# An object that represents a Rentlinx property.
|
6
7
|
class Property < Base
|
7
8
|
ATTRIBUTES = [:companyID, :propertyID, :description, :address, :city, :state,
|
8
9
|
:zip, :marketingName, :hideAddress, :latitude, :longitude,
|
@@ -15,15 +16,29 @@ module Rentlinx
|
|
15
16
|
|
16
17
|
attr_accessor(*ATTRIBUTES)
|
17
18
|
|
19
|
+
# Posts the property with all of its attached units.
|
20
|
+
#
|
21
|
+
# TODO: Discuss whether or not these kinds of methods are needed,
|
22
|
+
# or whether we should have post do everything every time.
|
18
23
|
def post_with_units
|
19
24
|
post
|
20
25
|
units.each(&:post) unless units.nil? || units.empty?
|
21
26
|
end
|
22
27
|
|
28
|
+
# The list of units attached to the property.
|
29
|
+
#
|
30
|
+
# If the units list is empty, it will query Rentlinx for the list
|
31
|
+
# of units stored on their end.
|
32
|
+
#
|
33
|
+
# @return a list of Rentlinx::Unit objects
|
23
34
|
def units
|
24
35
|
@units ||= get_units_for_property_id(propertyID)
|
25
36
|
end
|
26
37
|
|
38
|
+
# Allows assigning a list of units to the property.
|
39
|
+
#
|
40
|
+
# @param unit_list [Array] a list of Rentlinx::Unit objects
|
41
|
+
# @return the updated list of Rentlinx::Unit objects
|
27
42
|
def units=(unit_list)
|
28
43
|
@units = unit_list.map do |unit|
|
29
44
|
unit.propertyID = propertyID
|
@@ -31,21 +46,31 @@ module Rentlinx
|
|
31
46
|
end
|
32
47
|
end
|
33
48
|
|
49
|
+
# Queries rentlinx and builds a property with the given ID.
|
50
|
+
#
|
51
|
+
# The returned property will have all the attributes Rentlinx
|
52
|
+
# has for the property on their end.
|
53
|
+
#
|
54
|
+
# @param id [String] the rentlinx id of the property
|
55
|
+
# @return a Rentlinx::Property that is up to date with the remote one
|
34
56
|
def self.from_id(id)
|
35
57
|
get_from_id(:property, id)
|
36
58
|
end
|
37
59
|
|
38
60
|
include Rentlinx::Photoable
|
61
|
+
# For internal use.
|
39
62
|
def photo_class
|
40
63
|
Rentlinx::PropertyPhoto
|
41
64
|
end
|
42
65
|
|
43
66
|
include Rentlinx::Amenityable
|
67
|
+
# For internal use.
|
44
68
|
def amenity_class
|
45
69
|
Rentlinx::PropertyAmenity
|
46
70
|
end
|
47
71
|
|
48
72
|
include Rentlinx::Linkable
|
73
|
+
# For internal use.
|
49
74
|
def link_class
|
50
75
|
Rentlinx::PropertyLink
|
51
76
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# An amenity on a propery
|
2
3
|
class PropertyAmenity < Base
|
3
4
|
ATTRIBUTES = [:details, :name, :propertyID]
|
4
5
|
|
@@ -6,6 +7,9 @@ module Rentlinx
|
|
6
7
|
|
7
8
|
attr_accessor(*ATTRIBUTES)
|
8
9
|
|
10
|
+
# Converts the object to a hash
|
11
|
+
#
|
12
|
+
# @return a hash with the details and name of the link
|
9
13
|
def to_hash
|
10
14
|
{ details: details, name: name }
|
11
15
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# A link on a property
|
2
3
|
class PropertyLink < Base
|
3
4
|
ATTRIBUTES = [:propertyID, :title, :url]
|
4
5
|
|
@@ -6,6 +7,9 @@ module Rentlinx
|
|
6
7
|
|
7
8
|
attr_accessor(*ATTRIBUTES)
|
8
9
|
|
10
|
+
# Converts the link to a hash
|
11
|
+
#
|
12
|
+
# @return a hash with the url and title of the link
|
9
13
|
def to_hash
|
10
14
|
{ url: url, title: title }
|
11
15
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# A photo on a property
|
2
3
|
class PropertyPhoto < Base
|
3
4
|
ATTRIBUTES = [:url, :caption, :position, :propertyID, :unitID]
|
4
5
|
|
@@ -6,6 +7,9 @@ module Rentlinx
|
|
6
7
|
|
7
8
|
attr_accessor(*ATTRIBUTES)
|
8
9
|
|
10
|
+
# Converts the photo to a hash
|
11
|
+
#
|
12
|
+
# @return a hash with the url and caption of the photo
|
9
13
|
def to_hash
|
10
14
|
{ url: url, caption: caption }
|
11
15
|
end
|
data/lib/rentlinx/models/unit.rb
CHANGED
@@ -3,6 +3,7 @@ require 'rentlinx/modules/amenityable'
|
|
3
3
|
require 'rentlinx/modules/linkable'
|
4
4
|
|
5
5
|
module Rentlinx
|
6
|
+
# An object that represents a Rentlinx unit.
|
6
7
|
class Unit < Base
|
7
8
|
ATTRIBUTES = [:unitID, :propertyID, :name, :description, :rent, :maxRent,
|
8
9
|
:deposit, :maxDeposit, :squareFeet, :maxSquareFeet,
|
@@ -16,24 +17,37 @@ module Rentlinx
|
|
16
17
|
attr_accessor(*ATTRIBUTES)
|
17
18
|
|
18
19
|
include Rentlinx::Photoable
|
20
|
+
# For internal use
|
19
21
|
def photo_class
|
20
22
|
Rentlinx::UnitPhoto
|
21
23
|
end
|
22
24
|
|
23
25
|
include Rentlinx::Amenityable
|
26
|
+
# For internal use
|
24
27
|
def amenity_class
|
25
28
|
Rentlinx::UnitAmenity
|
26
29
|
end
|
27
30
|
|
28
31
|
include Rentlinx::Linkable
|
32
|
+
# For internal use
|
29
33
|
def link_class
|
30
34
|
Rentlinx::UnitLink
|
31
35
|
end
|
32
36
|
|
37
|
+
# Gets all the photos for a unit.
|
38
|
+
#
|
39
|
+
# @return a list of Rentlinx::UnitPhoto objects
|
33
40
|
def photos
|
34
41
|
super.select { |p| p.unitID == unitID }
|
35
42
|
end
|
36
43
|
|
44
|
+
# Queries rentlinx and builds a unit with the given ID
|
45
|
+
#
|
46
|
+
# The returned unit will have all the attributes Rentlinx
|
47
|
+
# has for the unit on their end.
|
48
|
+
#
|
49
|
+
# @param id [String] the rentlinx id of the unit
|
50
|
+
# @return a Rentlinx::Unit that is up to date with the remote one
|
37
51
|
def self.from_id(id)
|
38
52
|
get_from_id(:unit, id)
|
39
53
|
end
|
@@ -1,5 +1,11 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# Client methods for amenities
|
3
|
+
#
|
4
|
+
# TODO: Refactor into AttachmentClientMethods
|
2
5
|
module AmenityClientMethods
|
6
|
+
# Submits amenities to the batch endpoint on Rentlinx
|
7
|
+
#
|
8
|
+
# @param amenities [Array] an array of amenity objects
|
3
9
|
def post_amenities(amenities)
|
4
10
|
return if amenities.nil?
|
5
11
|
raise(Rentlinx::InvalidObject, amenities.find { |a| !a.valid? }) unless amenities.all?(&:valid?)
|
@@ -12,6 +18,11 @@ module Rentlinx
|
|
12
18
|
post_unit_amenities(unit_amenities) unless unit_amenities.empty?
|
13
19
|
end
|
14
20
|
|
21
|
+
# Unposts all amenities for a unit or property by posting
|
22
|
+
# an empty list to the batch update endpoint.
|
23
|
+
#
|
24
|
+
# @param object [Rentlinx::Property, Rentlinx::Unit] the object
|
25
|
+
# whos amenities should be unposted
|
15
26
|
def unpost_amenities_for(object)
|
16
27
|
case object
|
17
28
|
when Rentlinx::Unit
|
@@ -23,6 +34,11 @@ module Rentlinx
|
|
23
34
|
end
|
24
35
|
end
|
25
36
|
|
37
|
+
# Gets all the amenities for a property, dividing them into
|
38
|
+
# {Rentlinx::PropertyAmenity} and {Rentlinx::UnitAmenity} objects
|
39
|
+
#
|
40
|
+
# @param id [String] an ID for a property posted to Rentlinx
|
41
|
+
# @return an array of unit and property amenities
|
26
42
|
def get_amenities_for_property_id(id)
|
27
43
|
data = request('GET', "properties/#{id}/amenities")['data']
|
28
44
|
data.map do |amenity_data|
|
@@ -37,11 +53,19 @@ module Rentlinx
|
|
37
53
|
return []
|
38
54
|
end
|
39
55
|
|
56
|
+
# Gets all the amenities for a unit
|
57
|
+
#
|
58
|
+
# @param unit [Rentlinx::Unit] the unit to fetch amenities for
|
59
|
+
# @return an array of unit amenities
|
40
60
|
def get_amenities_for_unit(unit)
|
41
61
|
amenities = get_amenities_for_property_id(unit.propertyID)
|
42
62
|
amenities.select { |a| defined? a.unitID && a.unitID == unit.unitID }
|
43
63
|
end
|
44
64
|
|
65
|
+
# Unposts a single amenity
|
66
|
+
#
|
67
|
+
# @param amenity [Rentlinx::UnitAmenity, Rentlinx::PropertyAmenity] the
|
68
|
+
# amenity to be unposted
|
45
69
|
def unpost_amenity(amenity)
|
46
70
|
case amenity
|
47
71
|
when Rentlinx::UnitAmenity
|
@@ -1,10 +1,19 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# A module that encapsulates all ammenity related logic for {Rentlinx::Property} and
|
3
|
+
# {Rentlinx::Unit} objects. All of these methods can be called on Properties and Units.
|
4
|
+
#
|
5
|
+
# TODO: Refactor into BaseAble class along with {Linkable} and {Photoable}
|
2
6
|
module Amenityable
|
7
|
+
# Posts the object with its associated amenities
|
8
|
+
#
|
9
|
+
# TODO: Discuss whether or not these kinds of methods are needed,
|
10
|
+
# or whether we should have post do everything every time.
|
3
11
|
def post_with_amenities
|
4
12
|
post
|
5
13
|
post_amenities
|
6
14
|
end
|
7
15
|
|
16
|
+
# Posts the object's amenities
|
8
17
|
def post_amenities
|
9
18
|
return if @amenities.nil?
|
10
19
|
|
@@ -15,6 +24,9 @@ module Rentlinx
|
|
15
24
|
end
|
16
25
|
end
|
17
26
|
|
27
|
+
# Loads and caches the list of amenities from Rentlinx.
|
28
|
+
#
|
29
|
+
# @return a list of amenities
|
18
30
|
def amenities
|
19
31
|
return @amenities if @amenities
|
20
32
|
|
@@ -26,6 +38,10 @@ module Rentlinx
|
|
26
38
|
end
|
27
39
|
end
|
28
40
|
|
41
|
+
# Allows assignment of amenities to the object.
|
42
|
+
#
|
43
|
+
# @param amenity_list [Array] an array of amenities
|
44
|
+
# @return the list of amenities on the object
|
29
45
|
def amenities=(amenity_list)
|
30
46
|
@amenities = amenity_list.map do |amenity|
|
31
47
|
amenity.propertyID = propertyID
|
@@ -34,6 +50,13 @@ module Rentlinx
|
|
34
50
|
end
|
35
51
|
end
|
36
52
|
|
53
|
+
# Builds a single amenity and attaches it to the object. This method
|
54
|
+
# conveniently assigns the propertyID and unitID (if present) of the
|
55
|
+
# parent object, so these need not be passed.
|
56
|
+
#
|
57
|
+
# @param options [Hash] the attributes for the amenity, defined in
|
58
|
+
# {Rentlinx::PropertyAmenity}
|
59
|
+
# @return the updated list of amenities on the object
|
37
60
|
def add_amenity(options)
|
38
61
|
options.merge!(propertyID: propertyID)
|
39
62
|
options.merge!(unitID: unitID) if defined? unitID
|
@@ -1,5 +1,15 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# Client methods for Amenities
|
3
|
+
#
|
4
|
+
# TODO: Refactor into AttachmentClientMethods
|
2
5
|
module LinkClientMethods
|
6
|
+
# Posts an array of links to Rentlinx
|
7
|
+
#
|
8
|
+
# This uses the batch endpoint, so all links must be associated with
|
9
|
+
# the same property. They can be on different units, so long as all units
|
10
|
+
# are on the same property.
|
11
|
+
#
|
12
|
+
# @param links [Array] an array of links which all have the same propertyID
|
3
13
|
def post_links(links)
|
4
14
|
return if links.nil?
|
5
15
|
|
@@ -13,6 +23,11 @@ module Rentlinx
|
|
13
23
|
post_unit_links(unit_links) unless unit_links.empty?
|
14
24
|
end
|
15
25
|
|
26
|
+
# Unposts all links for unit or property by posting an empty
|
27
|
+
# array to the batch update endpoint
|
28
|
+
#
|
29
|
+
# @param object [Rentlinx::Property, Rentlinx::Unit] the object whos
|
30
|
+
# links should be unposted
|
16
31
|
def unpost_links_for(object)
|
17
32
|
case object
|
18
33
|
when Rentlinx::Unit
|
@@ -24,6 +39,9 @@ module Rentlinx
|
|
24
39
|
end
|
25
40
|
end
|
26
41
|
|
42
|
+
# Gets all the links for a given property, including unit links
|
43
|
+
#
|
44
|
+
# @param id [String] the id of the property
|
27
45
|
def get_links_for_property_id(id)
|
28
46
|
data = request('GET', "properties/#{id}/links")['data']
|
29
47
|
data.map do |link_data|
|
@@ -38,11 +56,17 @@ module Rentlinx
|
|
38
56
|
return []
|
39
57
|
end
|
40
58
|
|
59
|
+
# Gets all the links for a given unit
|
60
|
+
#
|
61
|
+
# @param unit [Rentlinx::Unit] the unit for which links should be fetched
|
41
62
|
def get_links_for_unit(unit)
|
42
63
|
links = get_links_for_property_id(unit.propertyID)
|
43
64
|
links.select { |link| defined?(link.unitID) && link.unitID == unit.unitID }
|
44
65
|
end
|
45
66
|
|
67
|
+
# Unposts a specific link
|
68
|
+
#
|
69
|
+
# @param link [Rentlinx::UnitLink, Rentlinx::PropertyLink] the link to be unposted
|
46
70
|
def unpost_link(link)
|
47
71
|
case link
|
48
72
|
when Rentlinx::UnitLink
|
@@ -1,10 +1,19 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# A module that encapsulates all link related logic for {Rentlinx::Property} and
|
3
|
+
# {Rentlinx::Unit} objects. All of these methods can be called on Properties and Units.
|
4
|
+
#
|
5
|
+
# TODO: Refactor into BaseAble class along with {Amenityable} and {Photoable}
|
2
6
|
module Linkable
|
7
|
+
# Posts the object with associated links
|
8
|
+
#
|
9
|
+
# TODO: Discuss whether or not these kinds of methods are needed,
|
10
|
+
# or whether we should have post do everything every time.
|
3
11
|
def post_with_links
|
4
12
|
post
|
5
13
|
post_links
|
6
14
|
end
|
7
15
|
|
16
|
+
# Posts the links for an object
|
8
17
|
def post_links
|
9
18
|
return if @links.nil?
|
10
19
|
|
@@ -15,6 +24,9 @@ module Rentlinx
|
|
15
24
|
end
|
16
25
|
end
|
17
26
|
|
27
|
+
# Loads and caches the list of amenities from Rentlinx.
|
28
|
+
#
|
29
|
+
# @return a list of amenities
|
18
30
|
def links
|
19
31
|
@links ||=
|
20
32
|
if defined? unitID
|
@@ -1,4 +1,8 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# A module that encapsulates all photo related logic for {Rentlinx::Property} and
|
3
|
+
# {Rentlinx::Unit} objects. All of these methods can be called on Properties and Units.
|
4
|
+
#
|
5
|
+
# TODO: Refactor into BaseAble class along with {Linkable} and {Amenityable}
|
2
6
|
module Photoable
|
3
7
|
def post_with_photos
|
4
8
|
post
|
@@ -1,5 +1,10 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# Client methods for property
|
2
3
|
module PropertyClientMethods
|
4
|
+
# Gets all the units for a given property id
|
5
|
+
#
|
6
|
+
# @param id [String] the id of the property
|
7
|
+
# @return a list of Rentlinx::Unit objects
|
3
8
|
def get_units_for_property_id(id)
|
4
9
|
data = request('GET', "properties/#{id}/units")['data']
|
5
10
|
data.map do |unit_data|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Rentlinx
|
2
|
+
# Validator for addresses
|
3
|
+
#
|
4
|
+
# Ensures they are three or more characters.
|
5
|
+
class AddressValidator < BaseValidator
|
6
|
+
private
|
7
|
+
|
8
|
+
def validate
|
9
|
+
return if !@value.nil? && @value.length > 2
|
10
|
+
@error = "'#{@value}' is not a valid address, an address must be 3 characters or more."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rentlinx/validators/base_validator'
|
2
|
+
require 'rentlinx/validators/address_validator'
|
2
3
|
require 'rentlinx/validators/city_validator'
|
3
4
|
require 'rentlinx/validators/phone_validator'
|
4
5
|
require 'rentlinx/validators/state_validator'
|
@@ -6,22 +7,37 @@ require 'rentlinx/validators/url_validator'
|
|
6
7
|
require 'rentlinx/validators/zip_validator'
|
7
8
|
|
8
9
|
module Rentlinx
|
10
|
+
# Provides processing and validation for attributes on {Rentlinx::Property} and
|
11
|
+
# {Rentlinx::Unit} objects
|
9
12
|
class AttributeProcessor
|
10
13
|
attr_reader :errors
|
11
14
|
attr_reader :processed_attrs
|
12
15
|
|
16
|
+
# @param attrs [Hash] the attributes to be processed
|
13
17
|
def initialize(attrs)
|
14
18
|
@attrs = attrs
|
15
19
|
@processed_attrs = @attrs
|
16
20
|
@errors = {}
|
17
21
|
end
|
18
22
|
|
23
|
+
# Processes the attributes, both validating them and processing them
|
24
|
+
# into a format suitable for Rentlinx.
|
25
|
+
#
|
26
|
+
# This method also populates the errors attribute, so it must be run
|
27
|
+
# before calling .valid? or querying for errors.
|
28
|
+
#
|
29
|
+
# Currently, phone number, state, zip, and leads URL are validated.
|
30
|
+
# They are passed into their own validator objects: {PhoneValidator},
|
31
|
+
# {StateValidator}, {ZipValidator}, and {UrlValidator}
|
32
|
+
#
|
33
|
+
# @return the processed attributes ready to submit to Rentlinx
|
19
34
|
def process
|
20
35
|
validators = { phoneNumber: PhoneValidator,
|
21
36
|
state: StateValidator,
|
22
37
|
zip: ZipValidator,
|
23
38
|
leadsURL: UrlValidator,
|
24
|
-
city: CityValidator
|
39
|
+
city: CityValidator,
|
40
|
+
address: AddressValidator }
|
25
41
|
|
26
42
|
@attrs.each do |field, val|
|
27
43
|
next unless validators.keys.include?(field)
|
@@ -33,6 +49,9 @@ module Rentlinx
|
|
33
49
|
@processed_attrs
|
34
50
|
end
|
35
51
|
|
52
|
+
# Determines the validity of the attributes it contains.
|
53
|
+
#
|
54
|
+
# @return [Boolean] true if valid, false if not
|
36
55
|
def valid?
|
37
56
|
@errors.size == 0
|
38
57
|
end
|
@@ -1,21 +1,33 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# This is the base validator. It encapsulates all the logic shared
|
3
|
+
# between the various validators.
|
2
4
|
class BaseValidator
|
3
5
|
attr_reader :error
|
4
6
|
|
7
|
+
# Creates a new instance of the class, and validates but
|
8
|
+
# BaseValidator should never be directly instantiated.
|
5
9
|
def initialize(val)
|
6
10
|
@value = val
|
7
11
|
@error = ''
|
8
12
|
validate
|
9
13
|
end
|
10
14
|
|
15
|
+
# Determines the validity of the attribute.
|
16
|
+
#
|
17
|
+
# @return true if valid, false if invalid
|
11
18
|
def valid?
|
12
19
|
@error == ''
|
13
20
|
end
|
14
21
|
|
22
|
+
# The processed value after validation of the attribute.
|
23
|
+
#
|
24
|
+
# @return a processed value, a stripped phone number for example
|
15
25
|
def processed_value
|
16
26
|
@value
|
17
27
|
end
|
18
28
|
|
29
|
+
private
|
30
|
+
|
19
31
|
def value_blank?
|
20
32
|
@value.nil? || @value == ''
|
21
33
|
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module Rentlinx
|
2
|
+
# Validator for two letter state codes
|
3
|
+
#
|
4
|
+
# Contains a list of all the states Rentlinx permits
|
2
5
|
class StateValidator < BaseValidator
|
3
6
|
STATES = %w(AK AL AR AS AZ CA CO CT DC DE FL GA GU HI IA ID IL IN KS KY LA
|
4
7
|
MA MD ME MI MN MO MP MS MT NC ND NE NH NJ NM NV NY OH OK OR PA
|
data/lib/rentlinx/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rentlinx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AppFolio, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|
@@ -95,6 +95,7 @@ files:
|
|
95
95
|
- lib/rentlinx/modules/photoable.rb
|
96
96
|
- lib/rentlinx/modules/property_client_methods.rb
|
97
97
|
- lib/rentlinx/modules/unit_client_methods.rb
|
98
|
+
- lib/rentlinx/validators/address_validator.rb
|
98
99
|
- lib/rentlinx/validators/attribute_processor_service.rb
|
99
100
|
- lib/rentlinx/validators/base_validator.rb
|
100
101
|
- lib/rentlinx/validators/city_validator.rb
|
@@ -123,9 +124,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
124
|
version: '0'
|
124
125
|
requirements: []
|
125
126
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.4.
|
127
|
+
rubygems_version: 2.4.8
|
127
128
|
signing_key:
|
128
129
|
specification_version: 4
|
129
130
|
summary: API Wrapper for the Rentlinx API
|
130
131
|
test_files: []
|
131
|
-
has_rdoc:
|