immobilienscout24 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +1 -0
  3. data/Gemfile +1 -0
  4. data/README.md +31 -5
  5. data/immobilienscout24.gemspec +2 -3
  6. data/lib/immobilienscout24/api.rb +12 -1
  7. data/lib/immobilienscout24/api/attachment.rb +39 -0
  8. data/lib/immobilienscout24/api/connection.rb +13 -8
  9. data/lib/immobilienscout24/api/contact.rb +39 -0
  10. data/lib/immobilienscout24/api/publish.rb +39 -0
  11. data/lib/immobilienscout24/api/real_estate.rb +43 -0
  12. data/lib/immobilienscout24/api/request.rb +30 -16
  13. data/lib/immobilienscout24/api/request/base.rb +98 -7
  14. data/lib/immobilienscout24/api/request/json.rb +8 -15
  15. data/lib/immobilienscout24/api/request/xml.rb +10 -14
  16. data/lib/immobilienscout24/api/search.rb +5 -3
  17. data/lib/immobilienscout24/api/user.rb +21 -0
  18. data/lib/immobilienscout24/client.rb +7 -3
  19. data/lib/immobilienscout24/configuration.rb +16 -3
  20. data/lib/immobilienscout24/helper/attachment.rb +75 -0
  21. data/spec/fixtures/estate.jpg +0 -0
  22. data/spec/fixtures/estate.pdf +0 -0
  23. data/spec/fixtures/raw_contact.json +31 -0
  24. data/spec/fixtures/raw_estate1.json +90 -0
  25. data/spec/fixtures/raw_picture.json +7 -0
  26. data/spec/fixtures/raw_publication.json +4 -0
  27. data/spec/fixtures/raw_publications.json +12 -0
  28. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Attachment/attachments/should_retrieve_all_attachments.json +1 -0
  29. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Attachment/create_attachment/should_create_the_attachment.json +1 -0
  30. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Attachment/delete_attachment/should_delete_an_attachment.json +1 -0
  31. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Contact/contact/should_retrieve_a_signle_contact.json +1 -0
  32. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Contact/contacts/should_retrieve_all_contacts.json +1 -0
  33. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Contact/create_contact/should_create_the_contact.json +1 -0
  34. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Contact/update_contact/should_update_the_contact.json +1 -0
  35. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Publish/create_publication/should_create_the_publication.json +1 -0
  36. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Publish/create_publications/should_create_the_publications.json +1 -0
  37. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Publish/delete_publication/should_delete_the_selected_publication.json +1 -0
  38. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Publish/publication/should_retrieve_a_single_publication.json +1 -0
  39. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Publish/publications/should_retrieve_all_publications.json +1 -0
  40. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_RealEstate/create_real_estate/when_using_an_object_that_responds_to_to_json/should_create_the_estate.json +1 -0
  41. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_RealEstate/create_real_estate/when_using_raw_json/should_create_the_estate.json +1 -0
  42. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_RealEstate/delete_real_estate/should_delete_the_real_estate.json +1 -0
  43. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_RealEstate/real_estate/should_retrieve_a_single_estate.json +1 -0
  44. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_RealEstate/real_estates/should_retrieve_all_estates.json +1 -0
  45. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_RealEstate/update_real_estate/should_update_the_real_estate.json +1 -0
  46. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_Search/region_search/should_return_a_result_list.json +1 -0
  47. data/spec/fixtures/vcr_cassettes/Immobilienscout24_Api_User/current_user/should_return_the_current_user.json +1 -0
  48. data/spec/integration/attachment_spec.rb +31 -0
  49. data/spec/integration/contact_spec.rb +40 -0
  50. data/spec/integration/publish_spec.rb +46 -0
  51. data/spec/integration/real_estate_spec.rb +66 -0
  52. data/spec/integration/search_spec.rb +2 -3
  53. data/spec/integration/user_spec.rb +13 -0
  54. data/spec/spec_helper.rb +12 -0
  55. data/spec/support/auth.yml.tmpl +13 -0
  56. data/spec/support/estate_support.rb +7 -0
  57. data/spec/support/integration_support.rb +8 -4
  58. data/spec/support/vcr.rb +10 -2
  59. data/spec/unit/immobilienscout24/api/attachment_spec.rb +5 -0
  60. data/spec/unit/immobilienscout24/api/connection_spec.rb +21 -0
  61. data/spec/unit/immobilienscout24/api/publication_spec.rb +51 -0
  62. data/spec/unit/immobilienscout24/api/real_estate_spec.rb +56 -0
  63. data/spec/unit/immobilienscout24/api/request_spec.rb +75 -0
  64. data/spec/unit/immobilienscout24/api/search_spec.rb +29 -0
  65. data/spec/unit/immobilienscout24/api/user_spec.rb +38 -0
  66. data/spec/unit/immobilienscout24/client_spec.rb +48 -0
  67. data/spec/unit/immobilienscout24/configuration_spec.rb +10 -2
  68. metadata +95 -47
  69. data/spec/fixtures/vcr_cassettes/Search_requests/region_search/should_return_a_result_list.yml +0 -2414
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OWNlNWZjZmJlZmI5ZWVlNmNjOGQ5NzQyNjAzMjM5MTcwODk3NTlkMw==
5
+ data.tar.gz: !binary |-
6
+ YzNlMDY4YzM4N2NkMzA5NDNkODEwMjY2ZGU3ZWRhZGU1MTNiMzk0Yg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZmU3NjZkNWM1MDIzZTM4ZTYyOGRlNGNkNTkyMDA5YThkY2MxMjk4NGQyOGZi
10
+ MGI2ZWM0ZTRkNDkxMmIzMzZmNWI2NjkxNTczNzI4OTE2NGJhOTk2N2Y4ZjRk
11
+ ZDgxMTY4OWM3MGU5YWI4Y2I3YmRhOTk4OGE3ZTgyZmM5MTZmNWU=
12
+ data.tar.gz: !binary |-
13
+ ZDRhMzk2ZTBlNGViOGQ0NWExYjUyN2Q5YjE3Nzg3MjJlYzk2ODUwZGQ0NDAz
14
+ ZjA3NmFmN2QyYzA3YTRhZjFmMDVlMTUxNjY4OTJlMjM1MjllMTI2NWQzMjBj
15
+ MTMxZmQ3ZTlkYjU5MTZkNmVkMDg0OWY3MTUwYjA3Y2UzODEwYmM=
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .DS_Store
19
+ auth.yml
data/Gemfile CHANGED
@@ -8,4 +8,5 @@ group :test do
8
8
  gem 'pry'
9
9
  gem 'vcr'
10
10
  gem 'json_spec'
11
+ gem 'hashie'
11
12
  end
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # Immobilienscout24
2
2
 
3
- *WORK IN PROGRESS*
4
- Expected release: end of april 2014
3
+ A Ruby wrapper for the Immobilienscout24 REST API. This wrapper has all the important parts to create and maintain the real estate of a broker on Immobilienscout24.
5
4
 
6
- ## Installation
5
+ *Warning: This gem is not complete. There are still some parts of the Immobilienscout24 that we haven't had the time to implement. We will extend the functionallity as soon as we have more time. In the spirit of free software, everyone is encouraged to help improve this project.*
6
+
7
+ ## Quick start
7
8
 
8
9
  Add this line to your application's Gemfile:
9
10
 
@@ -17,9 +18,25 @@ Or install it yourself as:
17
18
 
18
19
  $ gem install immobilienscout24
19
20
 
20
- ## Usage
21
+ API methods are available from the `Immobilienscout24.client`.
22
+
23
+ ```ruby
24
+ # Provide authentication credentials
25
+
26
+ Immobilienscout24.configure do |config|
27
+ config.consumer_key = 'your_consumer_key'
28
+ config.consumer_secret = 'your_consumer_secret'
29
+ end
30
+
31
+ # Fetch your real estates
32
+ client = Immobilienscout24.client(token: 'your_oauth_token', token_secret: 'your_oauth_token_secret')
33
+ client.real_estates
34
+ ```
35
+
36
+ For the oauth process you can use the excellent [omniauth-immobilienscout24][oauthgem] gem.
37
+
38
+ [oauthgem]: https://github.com/endil/omniauth-immobilienscout24
21
39
 
22
- TODO: Write usage instructions here
23
40
 
24
41
  ## Contributing
25
42
 
@@ -28,3 +45,12 @@ TODO: Write usage instructions here
28
45
  3. Commit your changes (`git commit -am 'Add some feature'`)
29
46
  4. Push to the branch (`git push origin my-new-feature`)
30
47
  5. Create new Pull Request
48
+
49
+ ## TODO
50
+
51
+ * Extend API
52
+ * Write more tests
53
+ * Extend README
54
+ * Write wiki about multi-tanent management
55
+
56
+
@@ -2,10 +2,10 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "immobilienscout24"
5
- spec.version = "0.0.1"
5
+ spec.version = "0.1.0"
6
6
  spec.author = ["Converate Consulting Group GmbH"]
7
7
  spec.email = ["info@converate.com"]
8
- spec.description = %q{Immobilienscout 24 API}
8
+ spec.description = %q{A Ruby wrapper for the Immobilienscout24 REST API}
9
9
  spec.summary = spec.description
10
10
  spec.homepage = "https://github.com/converate-consulting-group/immobilienscout24"
11
11
  spec.license = "MIT"
@@ -18,7 +18,6 @@ Gem::Specification.new do |spec|
18
18
  spec.add_runtime_dependency "faraday_middleware", ">= 0.9.0"
19
19
  spec.add_runtime_dependency "multi_xml", ">= 0"
20
20
  spec.add_runtime_dependency "hashie", ">= 0"
21
- spec.add_runtime_dependency "activesupport", ">= 3.0.0"
22
21
  spec.add_runtime_dependency "simple_oauth", ">= 0"
23
22
 
24
23
  spec.add_development_dependency "bundler", "~> 1.3"
@@ -3,12 +3,23 @@ require "immobilienscout24/api/request"
3
3
  require "immobilienscout24/api/request/base"
4
4
  require "immobilienscout24/api/request/json"
5
5
  require "immobilienscout24/api/request/xml"
6
+ require "immobilienscout24/api/search"
7
+ require "immobilienscout24/api/user"
8
+ require "immobilienscout24/api/real_estate"
9
+ require "immobilienscout24/api/publish"
10
+ require "immobilienscout24/api/attachment"
11
+ require "immobilienscout24/api/contact"
6
12
 
7
13
  module Immobilienscout24
8
14
  module Api
9
15
  include Connection
10
16
  include Request
11
-
17
+ include Search
18
+ include User
19
+ include RealEstate
20
+ include Publish
21
+ include Attachment
22
+ include Contact
12
23
 
13
24
  end
14
25
  end
@@ -0,0 +1,39 @@
1
+ module Immobilienscout24
2
+ module Api
3
+
4
+ # Methods for the Attachment API
5
+ #
6
+ # @see http://developerwiki.immobilienscout24.de/wiki/User/Realestate/attachment
7
+ module Attachment
8
+
9
+ def attachments(options = {})
10
+ get attachment_endpoint("/attachment", options)
11
+ end
12
+
13
+ def create_attachment(metadata, attachment, options = {})
14
+ attachment = ::Immobilienscout24::Helper::Attachment.new(attachment).build
15
+ multipart = {metadata: metadata, attachment: Faraday::UploadIO.new(*attachment)}
16
+
17
+ with_request_options(multipart: true) do |client|
18
+ client.post attachment_endpoint("/attachment", options), multipart
19
+ end
20
+ end
21
+
22
+ def delete_attachment(id, options = {})
23
+ delete attachment_endpoint("/attachment/#{id}", options)
24
+ end
25
+
26
+ # -- endpoint
27
+
28
+ def attachment_endpoint(resource, options = {})
29
+ estate = options.fetch(:estate)
30
+ estate_attachment_endpoint(estate, resource, options)
31
+ end
32
+
33
+ def estate_attachment_endpoint(estate, resource, options = {})
34
+ [real_estate_endpoint("/realestate/#{estate}", options), resource].join
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -2,25 +2,30 @@ module Immobilienscout24
2
2
  module Api
3
3
  module Connection
4
4
 
5
- def connection(options = {})
6
- options = {raw: false}.merge(options)
7
-
8
- ::Faraday::Connection.new(configuration.faraday_connection) do |builder|
5
+ def connection
6
+ connection = ::Faraday::Connection.new(configuration.faraday_connection) do |builder|
9
7
  builder.request :oauth, oauth_credentials
8
+ builder.request :multipart
10
9
  builder.request :url_encoded
11
- builder.response(*configuration.faraday_logger) unless configuration.disable_logging
12
- builder.response :raise_error
10
+
11
+ if configuration.logging?
12
+ builder.response(*configuration.faraday_logger)
13
+ end
14
+
13
15
  builder.response :follow_redirects
14
16
 
15
- unless options.fetch(:raw)
17
+ unless request_options[:raw_response]
16
18
  builder.response :mashify
17
19
  builder.response :xml, content_type: /\bxml$/
18
20
  builder.response :json, content_type: /\bjson$/
19
21
  end
20
22
 
21
- builder.use :instrumentation
22
23
  builder.adapter configuration.faraday_adapter
24
+
25
+ configuration.build_extension.call(builder, request_options)
23
26
  end
27
+
28
+ connection
24
29
  end
25
30
 
26
31
  end
@@ -0,0 +1,39 @@
1
+ module Immobilienscout24
2
+ module Api
3
+
4
+ # Methods for the Contact API
5
+ #
6
+ # @see http://developerwiki.immobilienscout24.de/wiki/User/Contact
7
+ module Contact
8
+
9
+ def contacts(options = {})
10
+ get contact_endpoint("/contact", options)
11
+ end
12
+
13
+ def contact(id)
14
+ get contact_endpoint("/contact/#{id}")
15
+ end
16
+
17
+ def create_contact(contact, options = {})
18
+ post contact_endpoint("/contact", options), contact
19
+ end
20
+
21
+ def update_contact(id, contact, options = {})
22
+ put contact_endpoint("/contact/#{id}", options), contact
23
+ end
24
+
25
+ # -- endpoint
26
+
27
+ def contact_endpoint(resource, options = {})
28
+ options = {user: "me"}.merge(options)
29
+ user_contact_endpoint(options.fetch(:user), resource, options)
30
+ end
31
+
32
+ def user_contact_endpoint(user, resource, options = {})
33
+ [user_endpoint("/user/#{user}"), resource].join
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ module Immobilienscout24
2
+ module Api
3
+
4
+ # Methods for the Publish API
5
+ #
6
+ # @see http://developerwiki.immobilienscout24.de/wiki/Publish
7
+ # @see http://developerwiki.immobilienscout24.de/wiki/PublishChannel/GET
8
+ module Publish
9
+
10
+ def publications(estate, params = {})
11
+ params = {realestate: estate}.merge(params)
12
+ get publish_endpoint("/publish"), params
13
+ end
14
+
15
+ def publication(id)
16
+ get publish_endpoint("/publish/#{id}")
17
+ end
18
+
19
+ def create_publications(publications)
20
+ post publish_endpoint("/publish/list"), publications
21
+ end
22
+
23
+ def create_publication(publication)
24
+ post publish_endpoint("/publish"), publication
25
+ end
26
+
27
+ def delete_publication(id)
28
+ delete publish_endpoint("/publish/#{id}")
29
+ end
30
+
31
+ # -- endpoint
32
+
33
+ def publish_endpoint(resource)
34
+ ["api/offer/#{api_version}", resource].join
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ module Immobilienscout24
2
+ module Api
3
+
4
+ # Methods for the RealEstate API
5
+ #
6
+ # @see http://developerwiki.immobilienscout24.de/wiki/User/Realestate
7
+ module RealEstate
8
+
9
+ def real_estates(options = {})
10
+ get real_estate_endpoint("/realestate", options)
11
+ end
12
+
13
+ def real_estate(id, options = {})
14
+ get real_estate_endpoint("/realestate/#{id}", options)
15
+ end
16
+
17
+ def create_real_estate(estate, options = {})
18
+ post real_estate_endpoint("/realestate", options), estate
19
+ end
20
+
21
+ def update_real_estate(id, estate, options = {})
22
+ put real_estate_endpoint("/realestate/#{id}", options), estate
23
+ end
24
+
25
+ def delete_real_estate(id, options = {})
26
+ delete real_estate_endpoint("/realestate/#{id}", options)
27
+ end
28
+
29
+ # -- endpoint
30
+
31
+ def real_estate_endpoint(resource, options = {})
32
+ options = {user: "me"}.merge(options)
33
+ user_real_estate_endpoint(options.fetch(:user), resource, options)
34
+ end
35
+
36
+ def user_real_estate_endpoint(user, resource, options = {})
37
+ [user_endpoint("/user/#{user}"), resource].join
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
@@ -2,37 +2,51 @@ module Immobilienscout24
2
2
  module Api
3
3
  module Request
4
4
 
5
- def get(path, request_data = {}, request_options = {})
6
- request(:get, path, request_data, request_options)
5
+ def get(path, request_data = nil, &block)
6
+ request(:get, path, request_data, &block)
7
7
  end
8
8
 
9
- def post(path, request_data = {}, request_options = {})
10
- request(:post, path, request_data, request_options)
9
+ def post(path, request_data = nil, &block)
10
+ request(:post, path, request_data, &block)
11
11
  end
12
12
 
13
- def put(path, request_data = {}, request_options = {})
14
- request(:put, path, request_data, request_options)
13
+ def put(path, request_data = nil, &block)
14
+ request(:put, path, request_data, &block)
15
15
  end
16
16
 
17
- def delete(path, request_data = {}, request_options = {})
18
- request(:delete, path, request_data, request_options)
17
+ def delete(path, request_data = nil, &block)
18
+ request(:delete, path, request_data, &block)
19
19
  end
20
20
 
21
- def request(method, path, request_data = {}, request_options = {})
22
- request_options = {raw: false, raw_data: false}.merge(request_options)
21
+ def request(method, path, request_data = nil, &block)
22
+ response = connection.send(method) do |request|
23
+ request_config = {method: method, path: path, request_data: request_data, request_options: request_options}
24
+ strategy = configuration.request_strategy.new(request, request_config)
25
+ configured_request = strategy.configure
23
26
 
24
- response = connection(request_options).send(method) do |request|
25
- req = configuration.request_strategy.
26
- new(request).configure(method, path, request_data, request_options)
27
-
28
- yield req if block_given?
27
+ yield configured_request if block_given?
29
28
  end
30
29
 
31
- return response if request_options.fetch(:raw)
30
+ return response if request_options[:raw_response]
32
31
 
33
32
  response.body
34
33
  end
35
34
 
35
+ def with_request_options(options = {})
36
+ @request_options = request_option_defaults.merge(options)
37
+
38
+ yield self
39
+ ensure
40
+ @request_options = {}
41
+ end
42
+
43
+ def request_options
44
+ @request_options ||= {}
45
+ end
46
+
47
+ def request_option_defaults
48
+ {raw_response: false, raw_request: false}
49
+ end
36
50
 
37
51
  end
38
52
  end
@@ -1,17 +1,108 @@
1
- require 'delegate'
2
-
3
1
  module Immobilienscout24
4
2
  module Api
5
3
  module Request
6
4
 
7
- class Base < SimpleDelegator
5
+ class Base
6
+
7
+ attr_reader :request
8
+ attr_reader :configuration
9
+
10
+ def initialize(request, configuration = {})
11
+ @request = request
12
+ @configuration = configuration
13
+ end
14
+
15
+ def serialized_data(data)
16
+ raise NotImplementedError
17
+ end
18
+
19
+ def content_type
20
+ raise NotImplementedError
21
+ end
22
+
23
+ def extension
24
+ raise NotImplementedError
25
+ end
26
+
27
+ def configure
28
+ set_accept_header
29
+
30
+ return configure_multipart_request if multipart?
31
+
32
+ set_content_type
33
+
34
+ return configure_get_request if get?
35
+ configure_post_request
36
+ end
37
+
38
+ def set_accept_header
39
+ request.headers['Accept'] = content_type
40
+ end
41
+
42
+ def set_content_type
43
+ request.headers['Content-Type'] = "#{content_type};charset=UTF-8"
44
+ end
45
+
46
+ def configure_multipart_request
47
+ request.path = path
48
+ request.body = prepared_multipart_data
49
+ request
50
+ end
51
+
52
+ def configure_get_request
53
+ request.url(path, request_data)
54
+ request
55
+ end
56
+
57
+ def configure_post_request
58
+ request.path = path
59
+ if raw_request?
60
+ request.body = request_data
61
+ else
62
+ request.body = serialized_data(request_data) unless request_data.nil?
63
+ end
64
+
65
+ request
66
+ end
67
+
68
+ def path
69
+ configuration[:path]
70
+ end
71
+
72
+ def multipart?
73
+ !!request_options[:multipart]
74
+ end
75
+
76
+ def raw_request?
77
+ !!request_options[:raw_request]
78
+ end
79
+
80
+ def request_data
81
+ configuration[:request_data]
82
+ end
83
+
84
+ def request_options
85
+ configuration[:request_options]
86
+ end
87
+
88
+ def request_method
89
+ configuration[:method]
90
+ end
8
91
 
9
- def initialize(request)
10
- super(request)
92
+ def get?
93
+ request_method == :get
11
94
  end
12
95
 
13
- def configure(method, path, request_data = {}, request_options = {})
14
- # implement
96
+ def prepared_multipart_data
97
+ request_data.inject({}) do |memo, (key, value)|
98
+ if !value.is_a?(Faraday::UploadIO)
99
+ io_value = StringIO.new(serialized_data(value))
100
+ memo[key] = Faraday::UploadIO.new(io_value, content_type, "#{key}.#{extension}")
101
+ else
102
+ memo[key] = value
103
+ end
104
+ memo
105
+ end
15
106
  end
16
107
 
17
108
  end