homeflow_api 0.14.3

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 (47) hide show
  1. data/.document +5 -0
  2. data/Gemfile +19 -0
  3. data/Gemfile.lock +55 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +19 -0
  6. data/Rakefile +46 -0
  7. data/VERSION +1 -0
  8. data/homeflow_api.gemspec +100 -0
  9. data/lib/homeflow/api.rb +72 -0
  10. data/lib/homeflow/api/agency.rb +9 -0
  11. data/lib/homeflow/api/branch.rb +9 -0
  12. data/lib/homeflow/api/collection.rb +22 -0
  13. data/lib/homeflow/api/county.rb +10 -0
  14. data/lib/homeflow/api/delete.rb +19 -0
  15. data/lib/homeflow/api/exceptions.rb +17 -0
  16. data/lib/homeflow/api/favourite_property.rb +13 -0
  17. data/lib/homeflow/api/lead.rb +13 -0
  18. data/lib/homeflow/api/location.rb +19 -0
  19. data/lib/homeflow/api/message.rb +13 -0
  20. data/lib/homeflow/api/password_reset.rb +13 -0
  21. data/lib/homeflow/api/place.rb +13 -0
  22. data/lib/homeflow/api/portal.rb +13 -0
  23. data/lib/homeflow/api/post.rb +24 -0
  24. data/lib/homeflow/api/postcode.rb +9 -0
  25. data/lib/homeflow/api/property.rb +10 -0
  26. data/lib/homeflow/api/put.rb +8 -0
  27. data/lib/homeflow/api/query.rb +85 -0
  28. data/lib/homeflow/api/queryable.rb +27 -0
  29. data/lib/homeflow/api/request.rb +48 -0
  30. data/lib/homeflow/api/request_specification.rb +11 -0
  31. data/lib/homeflow/api/resource.rb +27 -0
  32. data/lib/homeflow/api/resource_identifier.rb +19 -0
  33. data/lib/homeflow/api/response.rb +108 -0
  34. data/lib/homeflow/api/search.rb +14 -0
  35. data/lib/homeflow/api/session.rb +13 -0
  36. data/lib/homeflow/api/site.rb +9 -0
  37. data/lib/homeflow/api/site_page.rb +17 -0
  38. data/lib/homeflow/api/user.rb +21 -0
  39. data/spec/data/example_search_response.json +1 -0
  40. data/spec/data/invalid_api_key.json +1 -0
  41. data/spec/data/property_details.json +1 -0
  42. data/spec/data/with_alt_places.json +2 -0
  43. data/spec/homeflow_api_spec.rb +22 -0
  44. data/spec/query_spec.rb +38 -0
  45. data/spec/response_spec.rb +46 -0
  46. data/spec/spec_helper.rb +3 -0
  47. metadata +192 -0
@@ -0,0 +1,13 @@
1
+ module Homeflow
2
+ module API
3
+ class FavouriteProperty < Resource
4
+
5
+ is_resource :favourite_properties
6
+
7
+ def self.create(params)
8
+ Request.run_for(Homeflow::API::Post.new("/#{resource_uri}/", {}, params))
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Homeflow
2
+ module API
3
+ class Lead < Resource
4
+
5
+ is_resource :leads
6
+
7
+ def self.create(params)
8
+ Request.run_for(Homeflow::API::Post.new("/#{resource_uri}/", {}, params))
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module Homeflow
2
+ module API
3
+ class Location < Resource
4
+
5
+ is_resource :locations
6
+
7
+
8
+ #returns a search object pre build withe the correct place id
9
+ def properties
10
+ Property.where(:place => {:id => place_id})
11
+ end
12
+
13
+ def self.find_by_county_id_and_location_id(county_id, location_id)
14
+ Request.run_for(Homeflow::API::ResourceIdentifier.new("/counties/#{county_id}/locations/#{location_id}"))
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module Homeflow
2
+ module API
3
+ class Message < Resource
4
+
5
+ is_resource :messages
6
+
7
+ def self.create(params)
8
+ Request.run_for(Homeflow::API::Post.new("/#{resource_uri}/", {}, params))
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Homeflow
2
+ module API
3
+ class PasswordReset < Resource
4
+
5
+ is_resource :password_resets
6
+
7
+ def self.create(params)
8
+ Request.run_for(Homeflow::API::Post.new("/#{resource_uri}/", {}, params))
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Homeflow
2
+ module API
3
+ class Place < Resource
4
+
5
+ is_resource :places
6
+
7
+ def self.disambiguate(disambiguation_phrase)
8
+ Request.run_for(Homeflow::API::ResourceIdentifier.new("/places", :search => {:name => disambiguation_phrase}))
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Homeflow
2
+ module API
3
+ class Portal < Resource
4
+
5
+ is_resource :portal
6
+
7
+ def self.find()
8
+ Request.run_for(Homeflow::API::ResourceIdentifier.new("/#{resource_uri}/"))
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ #This module contains class methods used when building up querys on resources. Think index?
2
+ module Homeflow
3
+ module API
4
+ class Post < RequestSpecification
5
+
6
+ attr_accessor :resource_uri
7
+
8
+ def initialize(resource_uri, params = {}, post_params = {})
9
+ @resource_uri = resource_uri
10
+ @params = params
11
+ @post_params = post_params
12
+ end
13
+
14
+ def post_params
15
+ @post_params
16
+ end
17
+
18
+ def to_params
19
+ @params
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ module Homeflow
2
+ module API
3
+ class Postcode < Resource
4
+
5
+ is_resource :postcodes
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Homeflow
2
+ module API
3
+ class Property < Resource
4
+
5
+ is_resource :properties
6
+
7
+
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ #This module contains class methods used when building up querys on resources. Think index?
2
+ module Homeflow
3
+ module API
4
+ class Put < Post
5
+
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,85 @@
1
+ #This module contains class methods used when building up querys on resources. Think index?
2
+ module Homeflow
3
+ module API
4
+ class Query < RequestSpecification
5
+
6
+ attr_accessor :resource_class, :query, :fields, :page, :page_size
7
+
8
+ def initialize(resource_class, params)
9
+ @resource_class = resource_class
10
+ @fields = []
11
+ @options = {}
12
+ @page_size = nil
13
+ @page = 1
14
+ search,fields = nil
15
+ add_search(search) if search = params.delete(:query)
16
+ set_fields(fields) if fields = params.delete(:fields)
17
+ end
18
+
19
+ def page_size(page_size)
20
+ @page_size = page_size
21
+ self
22
+ end
23
+
24
+ def page(page)
25
+ @page = page
26
+ self
27
+ end
28
+
29
+ def where(search_hash)
30
+ add_search(search_hash)
31
+ self
32
+ end
33
+
34
+ def options(options_hash)
35
+ @options.merge!(options_hash)
36
+ self
37
+ end
38
+
39
+ def fields(*args)
40
+ set_fields(args)
41
+ self
42
+ end
43
+
44
+ def add_search(search_hash)
45
+ @query ||= {}
46
+ @query.merge!(search_hash)
47
+ end
48
+
49
+ def set_fields(fields_array)
50
+ @fields = fields_array
51
+ end
52
+
53
+ def results
54
+ @_results ||= results!
55
+ end
56
+
57
+ def results!
58
+ @_results = @resource_class.execute(self)
59
+ end
60
+
61
+ def response
62
+ results
63
+ end
64
+
65
+ def each(&block)
66
+ r = results.send(resource_class.resource_uri)
67
+ r.each {|k|
68
+ case block.arity
69
+ when 1
70
+ yield k
71
+ when 2
72
+ yield k, results
73
+ end
74
+ }
75
+ end
76
+
77
+ def to_params
78
+ options = {}
79
+ options = options.merge({:page_size => @page_size}) unless @page_size.nil?
80
+ options = options.merge({:search => @query, :fields => @fields.join(','), :search_options => @options, :page=> @page})
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,27 @@
1
+ #All 'queryies' go in search[x]
2
+ module Homeflow
3
+ module API
4
+ module Queryable
5
+
6
+ def self.included(c)
7
+ c.extend ClassMethods
8
+ end
9
+
10
+
11
+ module ClassMethods
12
+ def where(query_hash)
13
+ Homeflow::API::Query.new(self, :query => query_hash)
14
+ end
15
+
16
+ def fields(*args)
17
+ Homeflow::API::Query.new(self, :fields => args)
18
+ end
19
+
20
+ def execute(query)
21
+ Request.run_for(query)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,48 @@
1
+ module Homeflow
2
+ module API
3
+ YAML::ENGINE.yamler = "syck"
4
+ class Request
5
+
6
+ attr_accessor :resource_class, :request_specification
7
+
8
+ def initialize(request_specification)
9
+ @request_specification = request_specification
10
+ end
11
+
12
+ def perform
13
+ begin
14
+ response = perform_request
15
+ rescue Errno::ECONNREFUSED => e
16
+ raise Homeflow::API::Exceptions::APIConnectionError, "Connection error. Homeflow might be down?"
17
+ end
18
+ response
19
+ end
20
+
21
+ def perform_request
22
+ if request_specification.is_a? Query
23
+ return (HTTParty.get("#{Homeflow::API.config.source}/#{request_specification.resource_class.resource_uri}", :query => @request_specification.to_params.merge(constant_params))).body
24
+ elsif request_specification.is_a? ResourceIdentifier
25
+ return (HTTParty.get("#{Homeflow::API.config.source}/#{request_specification.resource_uri}", :query => @request_specification.to_params.merge(constant_params))).body
26
+ elsif request_specification.is_a? Delete
27
+ return (HTTParty.delete("#{Homeflow::API.config.source}/#{request_specification.resource_uri}", :query => @request_specification.to_params.merge(constant_params))).body
28
+ elsif request_specification.is_a? Put
29
+ return (HTTParty.put("#{Homeflow::API.config.source}/#{request_specification.resource_uri}", :query => @request_specification.to_params.merge(constant_params), :body => @request_specification.post_params)).body
30
+ elsif request_specification.is_a? Post
31
+ return (HTTParty.post("#{Homeflow::API.config.source}/#{request_specification.resource_uri}", :query => @request_specification.to_params.merge(constant_params), :body => @request_specification.post_params)).body
32
+ end
33
+ end
34
+
35
+ def constant_params
36
+ {:api_key=> Homeflow::API.config.api_key}
37
+ end
38
+
39
+ class << self
40
+ def run_for(request_specification)
41
+ r = Request.new(request_specification)
42
+ Response.new_from_json(r.perform)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,11 @@
1
+ module Homeflow
2
+ module API
3
+ class RequestSpecification
4
+
5
+ def to_params
6
+ raise "this must be implemented"
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ module Homeflow
2
+ module API
3
+ class Resource < ::Hashie::Mash
4
+ include Homeflow::API::Queryable
5
+
6
+ class << self
7
+
8
+ def is_resource(uri)
9
+ @resource_uri = uri.to_s
10
+ end
11
+
12
+ def find(id, params = {})
13
+ Request.run_for(Homeflow::API::ResourceIdentifier.new("/#{resource_uri}/#{id}", params))
14
+ end
15
+
16
+ def delete(id, params = {})
17
+ Request.run_for(Homeflow::API::Delete.new("/#{resource_uri}/#{id}", params))
18
+ end
19
+
20
+ def resource_uri
21
+ @resource_uri
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ #This module contains class methods used when building up querys on resources. Think index?
2
+ module Homeflow
3
+ module API
4
+ class ResourceIdentifier < RequestSpecification
5
+
6
+ attr_accessor :resource_uri
7
+
8
+ def initialize(resource_uri, params = {})
9
+ @resource_uri = resource_uri
10
+ @params = params
11
+ end
12
+
13
+ def to_params
14
+ @params.merge(@params) { |name, values| values.is_a?(Array) ? values.join(',') : values }
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,108 @@
1
+ module Homeflow
2
+
3
+ module API
4
+ class Response
5
+
6
+ def self.new_from_json(json)
7
+ begin
8
+ hash = JSON.parse(json)
9
+ rescue JSON::ParserError
10
+ raise Homeflow::API::Exceptions::InvalidResponse
11
+ end
12
+ raise Homeflow::API::Exceptions::InvalidResponse unless hash.is_a?(Hash)
13
+ self.new(hash)
14
+ end
15
+
16
+ attr_accessor :query, :result, :response, :error
17
+
18
+
19
+ COLLECTIONS_OBJECTS = {
20
+ "password_reset" => Homeflow::API::PasswordReset,
21
+ "properties" => Homeflow::API::Property,
22
+ "search" => Homeflow::API::Search,
23
+ "property" => Homeflow::API::Property,
24
+ "county" => Homeflow::API::County,
25
+ "location" => Homeflow::API::Location,
26
+ "agency" => Homeflow::API::Agency,
27
+ "agencies" => Homeflow::API::Agency,
28
+ "locations" => Homeflow::API::Location,
29
+ "counties" => Homeflow::API::County,
30
+ "branch" => Homeflow::API::Branch,
31
+ "branches" => Homeflow::API::Branch,
32
+ "session" => Homeflow::API::Session,
33
+ "portal" => Homeflow::API::Portal,
34
+ 'user' => Homeflow::API::User,
35
+ 'message' => Homeflow::API::Message,
36
+ "lead" => Homeflow::API::Lead,
37
+ "postcodes" => Homeflow::API::Postcode,
38
+ "postcode" => Homeflow::API::Postcode,
39
+ "site_page" => Homeflow::API::SitePage,
40
+ "site_pages" => Homeflow::API::SitePage,
41
+ "alternative_places" => {
42
+ "locations" => Homeflow::API::Location,
43
+ "counties" => Homeflow::API::County
44
+ },
45
+ "favourite_properties" => Homeflow::API::FavouriteProperty
46
+ }
47
+
48
+ def initialize(hash)
49
+ @built_result_objects = {}
50
+ @query = Hashie::Mash.new(hash["query"])
51
+ @result = build_result_objects(hash["result"])
52
+ @response = Hashie::Mash.new(hash["response"])
53
+ @error = Hashie::Mash.new(hash["error"])
54
+
55
+ errors if error.type
56
+ end
57
+
58
+ def method_missing(method, *args, &block)
59
+ if @built_result_objects.has_key?(method.to_s)
60
+ @built_result_objects[method.to_s]
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+
67
+ def respond_to?(method, include_private = false)
68
+ if @built_result_objects.has_key?(method.to_s)
69
+ true
70
+ else
71
+ super
72
+ end
73
+ end
74
+
75
+ protected
76
+
77
+ def errors
78
+ Homeflow::API::Exceptions::ExceptionsList.list.each do |a|
79
+ if "Homeflow::API::Exceptions::#{error.type}" == a.name.to_s
80
+ raise a, error.message
81
+ end
82
+ end
83
+ end
84
+
85
+ def build_result_objects(result)
86
+ COLLECTIONS_OBJECTS.each do |key, o|
87
+ if result.has_key?(key)
88
+ if result[key].has_key?("elements")
89
+ item = Collection.new(result[key], o)
90
+ elsif o.is_a? Hash
91
+ hash = {}
92
+ o.each{|k,v| hash[k.to_sym] = Collection.new(result[key][k], v) if result[key][k] }
93
+ item = Hashie::Mash.new(hash)
94
+ else
95
+ item = o.new(result[key])
96
+ end
97
+ end
98
+
99
+ @built_result_objects[key] = item if item
100
+ item = nil
101
+ end
102
+ return result
103
+ end
104
+
105
+
106
+ end
107
+ end
108
+ end