apartment_ratings 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,7 +1,9 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gem 'hashie', git: 'https://github.com/intridea/hashie.git', branch: :master
3
+ gem 'hashie', '~> 3.3.1'
4
+ gem 'tnt', '~> 0.1.0'
4
5
  gem 'faraday', '~> 0.9.0'
6
+ gem 'faraday_middleware', '~> 0.9.0'
5
7
 
6
8
  group :development do
7
9
  gem 'pry'
@@ -1,10 +1,3 @@
1
- GIT
2
- remote: https://github.com/intridea/hashie.git
3
- revision: 8b4ffbd6aa2ff9e6aeccd8181c82a85ffd1eea7a
4
- branch: master
5
- specs:
6
- hashie (3.1.1)
7
-
8
1
  GEM
9
2
  remote: http://rubygems.org/
10
3
  specs:
@@ -18,6 +11,8 @@ GEM
18
11
  docile (1.1.5)
19
12
  faraday (0.9.0)
20
13
  multipart-post (>= 1.2, < 3)
14
+ faraday_middleware (0.9.1)
15
+ faraday (>= 0.7.4, < 0.10)
21
16
  git (1.2.7)
22
17
  github_api (0.11.3)
23
18
  addressable (~> 2.3)
@@ -27,6 +22,7 @@ GEM
27
22
  multi_json (>= 1.7.5, < 2.0)
28
23
  nokogiri (~> 1.6.0)
29
24
  oauth2
25
+ hashie (3.3.1)
30
26
  highline (1.6.21)
31
27
  jeweler (2.0.1)
32
28
  builder
@@ -92,6 +88,7 @@ GEM
92
88
  simplecov-html (0.8.0)
93
89
  slop (3.5.0)
94
90
  thread_safe (0.3.4)
91
+ tnt (0.1.0)
95
92
 
96
93
  PLATFORMS
97
94
  ruby
@@ -99,7 +96,8 @@ PLATFORMS
99
96
  DEPENDENCIES
100
97
  bundler (~> 1.0)
101
98
  faraday (~> 0.9.0)
102
- hashie!
99
+ faraday_middleware (~> 0.9.0)
100
+ hashie (~> 3.3.1)
103
101
  jeweler (~> 2.0.1)
104
102
  pry
105
103
  rdoc (~> 3.12)
@@ -107,3 +105,4 @@ DEPENDENCIES
107
105
  rspec (~> 3.0)
108
106
  rubocop (>= 0.21.0)
109
107
  simplecov
108
+ tnt (~> 0.1.0)
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # ApartmentRatings [![Build Status](https://travis-ci.org/gregory/apartment_ratings.svg)](https://travis-ci.org/gregory/apartment_ratings)
2
2
 
3
+ ## THIS IS A WIP, WATING FOR CREDENTIALS TO TEST :)
4
+
3
5
  Description goes here.
4
6
 
5
7
  ## Contributing to apartment_ratings
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 1.0.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "apartment_ratings"
8
- s.version = "0.0.1"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["gregory"]
12
- s.date = "2014-07-08"
12
+ s.date = "2014-09-25"
13
13
  s.description = "Ruby client for ApartmentRating API"
14
14
  s.email = "greg2502@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  "lib/apartment_ratings/client.rb",
34
34
  "lib/apartment_ratings/complex.rb",
35
35
  "lib/apartment_ratings/configuration.rb",
36
+ "lib/apartment_ratings/errors.rb",
36
37
  "lib/apartment_ratings/review.rb",
37
38
  "lib/apartment_ratings/reviews/rating.rb",
38
39
  "lib/apartment_ratings/reviews/response.rb",
@@ -43,6 +44,7 @@ Gem::Specification.new do |s|
43
44
  "spec/apartment_ratings/reviews/rating_spec.rb",
44
45
  "spec/apartment_ratings/reviews/response_spec.rb",
45
46
  "spec/apartment_ratings_spec.rb",
47
+ "spec/spec.yml.sample",
46
48
  "spec/spec_helper.rb"
47
49
  ]
48
50
  s.homepage = "http://github.com/gregory/apartment_ratings"
@@ -55,8 +57,10 @@ Gem::Specification.new do |s|
55
57
  s.specification_version = 3
56
58
 
57
59
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
- s.add_runtime_dependency(%q<hashie>, [">= 0"])
60
+ s.add_runtime_dependency(%q<hashie>, ["~> 3.3.1"])
61
+ s.add_runtime_dependency(%q<tnt>, ["~> 0.1.0"])
59
62
  s.add_runtime_dependency(%q<faraday>, ["~> 0.9.0"])
63
+ s.add_runtime_dependency(%q<faraday_middleware>, ["~> 0.9.0"])
60
64
  s.add_development_dependency(%q<pry>, [">= 0"])
61
65
  s.add_development_dependency(%q<rr>, ["~> 1.1.2"])
62
66
  s.add_development_dependency(%q<rspec>, ["~> 3.0"])
@@ -66,8 +70,10 @@ Gem::Specification.new do |s|
66
70
  s.add_development_dependency(%q<simplecov>, [">= 0"])
67
71
  s.add_development_dependency(%q<rubocop>, [">= 0.21.0"])
68
72
  else
69
- s.add_dependency(%q<hashie>, [">= 0"])
73
+ s.add_dependency(%q<hashie>, ["~> 3.3.1"])
74
+ s.add_dependency(%q<tnt>, ["~> 0.1.0"])
70
75
  s.add_dependency(%q<faraday>, ["~> 0.9.0"])
76
+ s.add_dependency(%q<faraday_middleware>, ["~> 0.9.0"])
71
77
  s.add_dependency(%q<pry>, [">= 0"])
72
78
  s.add_dependency(%q<rr>, ["~> 1.1.2"])
73
79
  s.add_dependency(%q<rspec>, ["~> 3.0"])
@@ -78,8 +84,10 @@ Gem::Specification.new do |s|
78
84
  s.add_dependency(%q<rubocop>, [">= 0.21.0"])
79
85
  end
80
86
  else
81
- s.add_dependency(%q<hashie>, [">= 0"])
87
+ s.add_dependency(%q<hashie>, ["~> 3.3.1"])
88
+ s.add_dependency(%q<tnt>, ["~> 0.1.0"])
82
89
  s.add_dependency(%q<faraday>, ["~> 0.9.0"])
90
+ s.add_dependency(%q<faraday_middleware>, ["~> 0.9.0"])
83
91
  s.add_dependency(%q<pry>, [">= 0"])
84
92
  s.add_dependency(%q<rr>, ["~> 1.1.2"])
85
93
  s.add_dependency(%q<rspec>, ["~> 3.0"])
@@ -1,4 +1,5 @@
1
1
  require 'hashie'
2
+ require 'tnt'
2
3
 
3
4
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'apartment_ratings'))
4
5
 
@@ -8,6 +9,7 @@ module ApartmentRatings
8
9
  autoload :Address, 'address'
9
10
  autoload :Complex, 'complex'
10
11
  autoload :Review, 'review'
12
+ autoload :Errors, 'errors'
11
13
 
12
14
  module Reviews
13
15
  autoload :Rating, 'reviews/rating'
@@ -22,12 +24,44 @@ module ApartmentRatings
22
24
  @config = Configuration.new.tap { |configuration| yield(configuration) }
23
25
  end
24
26
 
27
+ def self.credentials
28
+ if config.nil?
29
+ fail InvalidConfig
30
+ else
31
+ config.select { |key, _| [:username, :password].include?(key) }
32
+ end
33
+ end
34
+
25
35
  def self.client
26
- options = {
27
- username: config.username,
28
- password: config.password,
29
- api_base_path: config.api_base_path
36
+ @client ||= begin
37
+ fail Errors::InvalidConfig if config.nil?
38
+ options = {
39
+ api_base_path: config.api_base_path
40
+ }
41
+ Client.new(options)
42
+ end
43
+ end
44
+
45
+ def self.post(url = nil, params = {}, headers = nil, errors_opts = { token: 0 }, &block)
46
+ payload = default_params.merge(params)
47
+ json_result = client.connection.post(url, payload, headers).body
48
+ result = JSON.parse json_result
49
+
50
+ if !result['errors'].nil? && !result['errors']['serviceToken'].nil?
51
+ # Mostlikely the token expired, lets try to refresh it
52
+ fail Errors::InvalidToken unless errors_opts[:token] < ApartmentRatings.config.max_token_retry
53
+
54
+ client.refresh_token
55
+ return post(url, params, headers, { token: (errors_opts[:token] + 1) }, &block)
56
+ else
57
+ block.call(result)
58
+ end
59
+ end
60
+
61
+ def self.default_params
62
+ {
63
+ serviceToken: client.token,
64
+ username: credentials[:username]
30
65
  }
31
- Client.new(options)
32
66
  end
33
67
  end
@@ -1,5 +1,7 @@
1
1
  module ApartmentRatings
2
2
  class Address < Hashie::Trash
3
+ include Hashie::Extensions::IndifferentAccess
4
+
3
5
  property :full_address
4
6
 
5
7
  def self.coerce(raw_address)
@@ -1,31 +1,38 @@
1
1
  require 'faraday'
2
+ require 'faraday_middleware'
2
3
 
3
4
  module ApartmentRatings
4
5
  class Client
6
+ attr_reader :connection
7
+
5
8
  def initialize(options = {})
6
9
  path = options.fetch(:api_base_path)
7
- params = {
8
- username: options.fetch(:username),
9
- password: options.fetch(:password)
10
- }
11
10
 
12
- @client = Faraday.new(path, params) do |faraday|
13
- faraday.response :json, content_type: /\bjson\z/
11
+ @connection = Faraday.new(path) do |faraday|
12
+ faraday.request :url_encoded # Unfortunately, we need to encode post and put params
13
+ faraday.request :json
14
+
15
+ # NOTE: Unfortunately, the response content type is not json... But we know it is.
16
+ faraday.response :json, content_type: /\Atext\/html;charset=ISO-8859-1\z/
14
17
  faraday.response :logger if ApartmentRatings.config.debug
15
18
 
16
19
  faraday.adapter ApartmentRatings.config.faraday_adapter || Faraday.default_adapter
17
20
  end
18
21
  end
19
22
 
20
- def complexes
21
- result = @client.get('index')
22
- # TODO: store the result and hangle unsuccessful response
23
- result['complexes'].map { |complex_json| Complex.new complex_json }
23
+ def token
24
+ @token ||= refresh_token
24
25
  end
25
26
 
26
- def complex(id)
27
- result = @client.get('complex', complexId: id)
28
- Complex.new result
27
+ def refresh_token
28
+ @token = nil
29
+ result = JSON.parse @connection.post('login', ApartmentRatings.credentials.merge(format: 'json')).body
30
+
31
+ if result['success']
32
+ @token = result['response']
33
+ else
34
+ fail Errors::InvalidToken
35
+ end
29
36
  end
30
37
  end
31
38
  end
@@ -1,5 +1,6 @@
1
1
  module ApartmentRatings
2
2
  class Complex < Hashie::Trash
3
+ include Hashie::Extensions::IndifferentAccess
3
4
  include Hashie::Extensions::IgnoreUndeclared
4
5
  include Hashie::Extensions::Coercion
5
6
 
@@ -8,6 +9,7 @@ module ApartmentRatings
8
9
  property :address, from: :propertyAddress
9
10
  property :propertyAddress
10
11
  property :feedUrl
12
+ property :url, from: :propertyUrl
11
13
 
12
14
  property :apartmentRating
13
15
  property :averageRating
@@ -17,5 +19,26 @@ module ApartmentRatings
17
19
  coerce_key :address, Address
18
20
  coerce_key :averageRating, Hash[String => Reviews::Rating]
19
21
  coerce_key :reviews, Set[Review]
22
+
23
+ def self.all
24
+ ApartmentRatings.post('index') do |result|
25
+ if result['success']
26
+ result['complexes'].map { |complex_json| new complex_json }
27
+ else
28
+ fail StandardError
29
+ end
30
+ end
31
+ end
32
+
33
+ def self.find(id)
34
+ ApartmentRatings.post('complex', complexId: id) do |result|
35
+ if result['success']
36
+ default_options = { id: id }
37
+ new default_options.merge(result)
38
+ else
39
+ fail Errors::InvalidComplexId.new(id, result['errorMessage'])
40
+ end
41
+ end
42
+ end
20
43
  end
21
44
  end
@@ -2,12 +2,17 @@ module ApartmentRatings
2
2
  class Configuration < Hashie::Dash
3
3
  DEFAULTS = {
4
4
  format: 'json',
5
+ debug: false,
5
6
  api_base_path: 'https://services.apartmentratings.com/services/rms/v1/',
6
- hours_before_token_expiration: 48
7
+ hours_before_token_expiration: 48,
8
+ max_token_retry: 2
7
9
  }.freeze
8
10
 
9
11
  property :username
10
12
  property :password
13
+ property :debug, default: DEFAULTS[:debug]
14
+ property :faraday_adapter
15
+ property :max_token_retry, default: DEFAULTS[:max_token_retry]
11
16
  property :format, default: DEFAULTS[:format]
12
17
  property :api_base_path, default: DEFAULTS[:api_base_path]
13
18
  property :hours_before_token_expiration, default: DEFAULTS[:hours_before_token_expiration]
@@ -0,0 +1,19 @@
1
+ module ApartmentRatings
2
+ module Errors
3
+ InvalidToken = Tnt.boom do
4
+ credentials = ApartmentRatings.credentials.map { |k, v| "#{k} => #{v}" }.join(', ')
5
+ "Unable to retrieve token for the following credentials: #{credentials}"
6
+ end
7
+
8
+ InvalidConfig = Tnt.boom do
9
+ %s(
10
+ Please provide valid credentials. Ex:
11
+ > ApartmentRatings.configure { |c| c.username = 'username'; c.password= 'bar'; }
12
+ )
13
+ end
14
+
15
+ InvalidComplexId = Tnt.boom do |id, msg|
16
+ "Invalid Complex id (#{id}) : #{msg}"
17
+ end
18
+ end
19
+ end
@@ -1,5 +1,6 @@
1
1
  module ApartmentRatings
2
2
  class Review < Hashie::Trash
3
+ include Hashie::Extensions::IndifferentAccess
3
4
  include Hashie::Extensions::Coercion
4
5
 
5
6
  property :datePosted
@@ -7,6 +8,7 @@ module ApartmentRatings
7
8
  property :responses
8
9
  property :author, from: :reviewerScreenName
9
10
  property :rating, from: :starRatings
11
+ property :updated_at, from: :lastUpdatedDate
10
12
  property :url
11
13
 
12
14
  coerce_key :responses, Set[Reviews::Response]
@@ -1,6 +1,7 @@
1
1
  module ApartmentRatings
2
2
  module Reviews
3
3
  class Rating < Hashie::Trash
4
+ include Hashie::Extensions::IndifferentAccess
4
5
  property :value
5
6
 
6
7
  def self.coerce(raw_rating)
@@ -0,0 +1,3 @@
1
+ credentials:
2
+ username: foo@bar.com
3
+ password: password
@@ -19,6 +19,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
19
19
  $LOAD_PATH.unshift(File.dirname(__FILE__))
20
20
 
21
21
  require 'rspec'
22
+ require 'yaml'
22
23
  require 'apartment_ratings'
23
24
 
24
25
  # Requires supporting files with custom matchers and macros, etc,
@@ -27,7 +28,15 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
27
28
 
28
29
  RSpec.configure do |config|
29
30
  config.before :suite do
30
- ApartmentRatings.configure do
31
+ ApartmentRatings.configure do |conf|
32
+ credentials = settings['credentials']
33
+
34
+ conf.username = credentials['username']
35
+ conf.password = credentials['password']
31
36
  end
32
37
  end
38
+
39
+ def settings
40
+ @settings ||= YAML.load_file(File.join(File.dirname(File.expand_path(__FILE__)), 'spec.yml'))
41
+ end
33
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apartment_ratings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,40 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-07-08 00:00:00.000000000 Z
12
+ date: 2014-09-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: hashie
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
21
+ version: 3.3.1
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ! '>='
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: '0'
29
+ version: 3.3.1
30
+ - !ruby/object:Gem::Dependency
31
+ name: tnt
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.1.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.1.0
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: faraday
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -43,6 +59,22 @@ dependencies:
43
59
  - - ~>
44
60
  - !ruby/object:Gem::Version
45
61
  version: 0.9.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: faraday_middleware
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.0
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.0
46
78
  - !ruby/object:Gem::Dependency
47
79
  name: pry
48
80
  requirement: !ruby/object:Gem::Requirement
@@ -195,6 +227,7 @@ files:
195
227
  - lib/apartment_ratings/client.rb
196
228
  - lib/apartment_ratings/complex.rb
197
229
  - lib/apartment_ratings/configuration.rb
230
+ - lib/apartment_ratings/errors.rb
198
231
  - lib/apartment_ratings/review.rb
199
232
  - lib/apartment_ratings/reviews/rating.rb
200
233
  - lib/apartment_ratings/reviews/response.rb
@@ -205,6 +238,7 @@ files:
205
238
  - spec/apartment_ratings/reviews/rating_spec.rb
206
239
  - spec/apartment_ratings/reviews/response_spec.rb
207
240
  - spec/apartment_ratings_spec.rb
241
+ - spec/spec.yml.sample
208
242
  - spec/spec_helper.rb
209
243
  homepage: http://github.com/gregory/apartment_ratings
210
244
  licenses:
@@ -221,7 +255,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
221
255
  version: '0'
222
256
  segments:
223
257
  - 0
224
- hash: 1571250886427044213
258
+ hash: -426309642446831234
225
259
  required_rubygems_version: !ruby/object:Gem::Requirement
226
260
  none: false
227
261
  requirements: