immoscout 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +30 -0
- data/.gitignore +14 -0
- data/.reek +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +15 -0
- data/.simplecov +3 -0
- data/.travis.yml +20 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/LICENSE +21 -0
- data/README.md +250 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/doc/assets/logo.png +0 -0
- data/doc/assets/project.png +0 -0
- data/doc/assets/project.xcf +0 -0
- data/immoscout.gemspec +47 -0
- data/lib/immoscout.rb +27 -0
- data/lib/immoscout/api/client.rb +27 -0
- data/lib/immoscout/api/connection.rb +34 -0
- data/lib/immoscout/api/request.rb +33 -0
- data/lib/immoscout/configuration.rb +27 -0
- data/lib/immoscout/errors/failed.rb +11 -0
- data/lib/immoscout/models.rb +9 -0
- data/lib/immoscout/models/actions/attachment.rb +82 -0
- data/lib/immoscout/models/actions/contact.rb +75 -0
- data/lib/immoscout/models/actions/publish.rb +33 -0
- data/lib/immoscout/models/actions/real_estate.rb +122 -0
- data/lib/immoscout/models/apartment_buy.rb +90 -0
- data/lib/immoscout/models/base.rb +48 -0
- data/lib/immoscout/models/concerns/modelable.rb +55 -0
- data/lib/immoscout/models/concerns/propertiable.rb +56 -0
- data/lib/immoscout/models/concerns/renderable.rb +63 -0
- data/lib/immoscout/models/contact.rb +59 -0
- data/lib/immoscout/models/document.rb +31 -0
- data/lib/immoscout/models/house_buy.rb +87 -0
- data/lib/immoscout/models/parts/address.rb +26 -0
- data/lib/immoscout/models/parts/api_search_data.rb +19 -0
- data/lib/immoscout/models/parts/contact.rb +18 -0
- data/lib/immoscout/models/parts/coordinate.rb +18 -0
- data/lib/immoscout/models/parts/courtage.rb +19 -0
- data/lib/immoscout/models/parts/energy_certificate.rb +19 -0
- data/lib/immoscout/models/parts/energy_source.rb +17 -0
- data/lib/immoscout/models/parts/firing_type.rb +17 -0
- data/lib/immoscout/models/parts/geo_code.rb +18 -0
- data/lib/immoscout/models/parts/geo_hierarchy.rb +23 -0
- data/lib/immoscout/models/parts/price.rb +20 -0
- data/lib/immoscout/models/parts/publish_channel.rb +17 -0
- data/lib/immoscout/models/parts/real_estate.rb +17 -0
- data/lib/immoscout/models/parts/url.rb +18 -0
- data/lib/immoscout/models/parts/urls.rb +18 -0
- data/lib/immoscout/models/picture.rb +33 -0
- data/lib/immoscout/models/publish.rb +23 -0
- data/lib/immoscout/version.rb +5 -0
- metadata +268 -0
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "immoscout"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
require "pry"
|
11
|
+
Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/doc/assets/logo.png
ADDED
Binary file
|
Binary file
|
Binary file
|
data/immoscout.gemspec
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "immoscout/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "immoscout"
|
9
|
+
spec.version = Immoscout::VERSION
|
10
|
+
spec.authors = ["Marcus Geissler"]
|
11
|
+
spec.email = ["marcus.geissler@hanseventures.com"]
|
12
|
+
|
13
|
+
spec.summary = 'Ruby client for the Immobilienscout24 REST API'
|
14
|
+
spec.homepage = "https://github.com/hausgold/immoscout"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org.
|
18
|
+
# To allow pushes either set the 'allowed_push_host'
|
19
|
+
# to allow pushing to a single host or delete this
|
20
|
+
# section to allow pushing to any host.
|
21
|
+
if spec.respond_to?(:metadata)
|
22
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
23
|
+
else
|
24
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
25
|
+
"public gem pushes."
|
26
|
+
end
|
27
|
+
|
28
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
29
|
+
f.match(%r{^(test|spec|features)/})
|
30
|
+
end
|
31
|
+
spec.bindir = "exe"
|
32
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
|
+
spec.require_paths = ["lib"]
|
34
|
+
spec.add_dependency "activesupport", ">= 3.2.0"
|
35
|
+
spec.add_dependency "faraday", "~> 0.13.0"
|
36
|
+
spec.add_dependency "faraday_middleware", "~> 0.12.0"
|
37
|
+
spec.add_dependency "simple_oauth", ">= 0.3"
|
38
|
+
|
39
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
40
|
+
spec.add_development_dependency "pry"
|
41
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
42
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
43
|
+
spec.add_development_dependency "rspec-json_expectations", "~> 1.4.0"
|
44
|
+
spec.add_development_dependency "vcr", "~> 3.0.0"
|
45
|
+
spec.add_development_dependency "webmock", "~> 2.3.0"
|
46
|
+
spec.add_development_dependency "simplecov"
|
47
|
+
end
|
data/lib/immoscout.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
require 'active_support/configurable'
|
5
|
+
require 'active_support/core_ext/hash'
|
6
|
+
|
7
|
+
require "immoscout/version"
|
8
|
+
require 'immoscout/configuration'
|
9
|
+
require 'immoscout/models'
|
10
|
+
|
11
|
+
module Immoscout
|
12
|
+
class << self
|
13
|
+
attr_writer :configuration
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.configuration
|
17
|
+
@configuration ||= Configuration.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.configure
|
21
|
+
yield(configuration)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.reset_configuration!
|
25
|
+
self.configuration = Configuration.new
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require_relative "connection"
|
3
|
+
require_relative "request"
|
4
|
+
|
5
|
+
module Immoscout
|
6
|
+
module Api
|
7
|
+
class Client
|
8
|
+
include Singleton
|
9
|
+
include Immoscout::Api::Connection
|
10
|
+
include Immoscout::Api::Request
|
11
|
+
|
12
|
+
attr_writer :user_name
|
13
|
+
|
14
|
+
def user_name
|
15
|
+
@user_name || config.user_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def url
|
19
|
+
config.use_sandbox ? config.api_url_sandbox : config.api_url_live
|
20
|
+
end
|
21
|
+
|
22
|
+
def config
|
23
|
+
Immoscout.configuration
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "faraday_middleware"
|
3
|
+
|
4
|
+
module Immoscout
|
5
|
+
module Api
|
6
|
+
module Connection
|
7
|
+
# :reek:FeatureEnvy
|
8
|
+
def connection
|
9
|
+
@connection ||= Faraday::Connection.new(url: url) do |builder|
|
10
|
+
configure_oauth(builder)
|
11
|
+
builder.request :multipart
|
12
|
+
builder.request :url_encoded
|
13
|
+
builder.request :json
|
14
|
+
builder.response :follow_redirects
|
15
|
+
builder.response :json, content_type: /\bjson$/
|
16
|
+
builder.adapter :net_http
|
17
|
+
end
|
18
|
+
@connection
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def configure_oauth(builder)
|
24
|
+
builder.request(
|
25
|
+
:oauth,
|
26
|
+
token: config.oauth_token,
|
27
|
+
token_secret: config.oauth_token_secret,
|
28
|
+
consumer_key: config.consumer_key,
|
29
|
+
consumer_secret: config.consumer_secret
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Immoscout
|
2
|
+
module Api
|
3
|
+
module Request
|
4
|
+
def get(path, payload = nil, multipart = nil)
|
5
|
+
request(:get, path, payload, multipart)
|
6
|
+
end
|
7
|
+
|
8
|
+
def post(path, payload = nil, multipart = nil)
|
9
|
+
request(:post, path, payload, multipart)
|
10
|
+
end
|
11
|
+
|
12
|
+
def put(path, payload = nil, multipart = nil)
|
13
|
+
request(:put, path, payload, multipart)
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(path, payload = nil, multipart = nil)
|
17
|
+
request(:delete, path, payload, multipart)
|
18
|
+
end
|
19
|
+
|
20
|
+
def request(method, path, payload = nil, multipart = nil)
|
21
|
+
connection.send(method, path, multipart) do |request|
|
22
|
+
if multipart
|
23
|
+
request.headers['Content-Type'] = "multipart/form-data"
|
24
|
+
else
|
25
|
+
request.body = payload if payload
|
26
|
+
request.headers['Content-Type'] = "application/json;charset=UTF-8"
|
27
|
+
end
|
28
|
+
request.headers['Accept'] = "application/json"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Immoscout
|
4
|
+
class Configuration
|
5
|
+
include ActiveSupport::Configurable
|
6
|
+
config_accessor(:consumer_key) { ENV["IMMOSCOUT_CONSUMER_KEY"] }
|
7
|
+
config_accessor(:consumer_secret) { ENV["IMMOSCOUT_CONSUMER_SECRET"] }
|
8
|
+
|
9
|
+
config_accessor(:oauth_token) { ENV["IMMOSCOUT_OAUTH_TOKEN"] }
|
10
|
+
config_accessor(:oauth_token_secret) { ENV["IMMOSCOUT_OAUTH_TOKEN_SECRET"] }
|
11
|
+
|
12
|
+
config_accessor(:use_sandbox) { false }
|
13
|
+
|
14
|
+
config_accessor(:api_version) { "v1.0" }
|
15
|
+
|
16
|
+
config_accessor(:user_name) { 'me' }
|
17
|
+
|
18
|
+
config_accessor(:api_url_live) do
|
19
|
+
"https://rest.immobilienscout24.de/" \
|
20
|
+
"restapi/api/offer/#{api_version}"
|
21
|
+
end
|
22
|
+
config_accessor(:api_url_sandbox) do
|
23
|
+
"https://rest.sandbox-immobilienscout24.de/" \
|
24
|
+
"restapi/api/offer/#{api_version}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative 'errors/failed'
|
2
|
+
require_relative 'api/client'
|
3
|
+
# renderable models
|
4
|
+
require_relative 'models/house_buy'
|
5
|
+
require_relative 'models/apartment_buy'
|
6
|
+
require_relative 'models/contact'
|
7
|
+
require_relative 'models/publish'
|
8
|
+
require_relative 'models/picture'
|
9
|
+
require_relative 'models/document'
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'json'
|
2
|
+
require_relative '../concerns/modelable'
|
3
|
+
|
4
|
+
module Immoscout
|
5
|
+
module Models
|
6
|
+
module Actions
|
7
|
+
module Attachment
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
include Immoscout::Models::Concerns::Modelable
|
12
|
+
|
13
|
+
self.unpack_collection = proc do |hash|
|
14
|
+
hash
|
15
|
+
.fetch("common.attachments")
|
16
|
+
.first
|
17
|
+
.fetch("attachment")
|
18
|
+
end
|
19
|
+
|
20
|
+
def save
|
21
|
+
attachable_id = attachable.try(:id) || attachable
|
22
|
+
response = api.post(
|
23
|
+
"user/#{api.user_name}/realestate/#{attachable_id}/attachment",
|
24
|
+
nil,
|
25
|
+
attachment: Faraday::UploadIO.new(file, content_type, file_name),
|
26
|
+
metadata: as_json
|
27
|
+
)
|
28
|
+
handle_response(response)
|
29
|
+
self.id = id_from_response(response)
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
attachable_id = attachable.try(:id) || attachable
|
35
|
+
response = api.delete(
|
36
|
+
"user/#{api.user_name}/realestate/#{attachable_id}/attachment/#{id}",
|
37
|
+
)
|
38
|
+
handle_response(response)
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def file_extension
|
45
|
+
File.extname(file_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def file_name
|
49
|
+
File.basename(file)
|
50
|
+
end
|
51
|
+
|
52
|
+
def content_type
|
53
|
+
self.class.content_type_from_extension file_extension.downcase
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class_methods do
|
58
|
+
def content_type_from_extension(ext)
|
59
|
+
{
|
60
|
+
".jpg" => "image/jpeg",
|
61
|
+
".jpeg" => "image/jpeg",
|
62
|
+
".gif" => "image/gif",
|
63
|
+
".png" => "image/png",
|
64
|
+
".pdf" => "application/pdf"
|
65
|
+
}.fetch(ext)
|
66
|
+
end
|
67
|
+
|
68
|
+
def all(real_estate_id)
|
69
|
+
response = api.get(
|
70
|
+
"user/#{api.user_name}/realestate/#{real_estate_id}/attachment"
|
71
|
+
)
|
72
|
+
handle_response(response)
|
73
|
+
objects = unpack_collection.call(response.body)
|
74
|
+
objects
|
75
|
+
.map { |object| new(object) }
|
76
|
+
.select { |object| object.type =~ /#{name.demodulize}/i }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'json'
|
2
|
+
require_relative '../concerns/modelable'
|
3
|
+
|
4
|
+
module Immoscout
|
5
|
+
module Models
|
6
|
+
module Actions
|
7
|
+
module Contact
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
include Immoscout::Models::Concerns::Modelable
|
12
|
+
|
13
|
+
self.unpack_collection = proc do |hash|
|
14
|
+
hash
|
15
|
+
.fetch("common.realtorContactDetailsList", {})
|
16
|
+
.fetch("realtorContactDetails", nil)
|
17
|
+
end
|
18
|
+
|
19
|
+
def save
|
20
|
+
response = \
|
21
|
+
if id
|
22
|
+
api.put("user/#{api.user_name}/contact/#{id}", as_json)
|
23
|
+
else
|
24
|
+
api.post("user/#{api.user_name}/contact", as_json)
|
25
|
+
end
|
26
|
+
|
27
|
+
handle_response(response)
|
28
|
+
self.id = id_from_response(response) unless id
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def destroy
|
33
|
+
response = api.delete("user/#{api.user_name}/contact/#{id}")
|
34
|
+
handle_response(response)
|
35
|
+
self
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class_methods do
|
40
|
+
def find(id)
|
41
|
+
response = api.get("user/#{api.user_name}/contact/#{id}")
|
42
|
+
handle_response(response)
|
43
|
+
from_raw(response.body)
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_by(hash)
|
47
|
+
external_id = hash.symbolize_keys.fetch(:external_id)
|
48
|
+
find("ext-#{external_id}")
|
49
|
+
end
|
50
|
+
|
51
|
+
def all
|
52
|
+
response = api.get("user/#{api.user_name}/contact")
|
53
|
+
handle_response(response)
|
54
|
+
objects = unpack_collection.call(response.body)
|
55
|
+
objects.map { |object| new(object) }
|
56
|
+
end
|
57
|
+
|
58
|
+
def first
|
59
|
+
all.first
|
60
|
+
end
|
61
|
+
|
62
|
+
def last
|
63
|
+
all.last
|
64
|
+
end
|
65
|
+
|
66
|
+
def create(hash)
|
67
|
+
instance = new(hash)
|
68
|
+
instance.save
|
69
|
+
instance
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'json'
|
2
|
+
require_relative '../concerns/modelable'
|
3
|
+
|
4
|
+
module Immoscout
|
5
|
+
module Models
|
6
|
+
module Actions
|
7
|
+
module Publish
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
include Immoscout::Models::Concerns::Modelable
|
12
|
+
|
13
|
+
def save
|
14
|
+
response = api.post("publish", as_json)
|
15
|
+
handle_response(response)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def destroy
|
20
|
+
response = api.delete(
|
21
|
+
"publish/#{real_estate.id}_#{publish_channel.id}"
|
22
|
+
)
|
23
|
+
handle_response(response)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class_methods do
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|