immoscout 1.0.0
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.
- 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
|