justimmo_client 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +15 -0
- data/.gitignore +15 -0
- data/.gitlab-ci.yml +67 -0
- data/.rspec +2 -0
- data/.rubocop.yml +90 -0
- data/.ruby-version +1 -0
- data/Gemfile +21 -0
- data/LICENSE +21 -0
- data/README.md +72 -0
- data/Rakefile +14 -0
- data/bin/console +21 -0
- data/bin/setup +8 -0
- data/examples/client.rb +16 -0
- data/justimmo_client.gemspec +41 -0
- data/lib/justimmo_client/api/v1/models/city.rb +16 -0
- data/lib/justimmo_client/api/v1/models/country.rb +44 -0
- data/lib/justimmo_client/api/v1/models/employee.rb +45 -0
- data/lib/justimmo_client/api/v1/models/federal_state.rb +15 -0
- data/lib/justimmo_client/api/v1/models/file.rb +64 -0
- data/lib/justimmo_client/api/v1/models/geo_location.rb +47 -0
- data/lib/justimmo_client/api/v1/models/image.rb +10 -0
- data/lib/justimmo_client/api/v1/models/justimmo_base.rb +15 -0
- data/lib/justimmo_client/api/v1/models/realty.rb +82 -0
- data/lib/justimmo_client/api/v1/models/realty_area.rb +49 -0
- data/lib/justimmo_client/api/v1/models/realty_category.rb +13 -0
- data/lib/justimmo_client/api/v1/models/realty_marketing.rb +12 -0
- data/lib/justimmo_client/api/v1/models/realty_price.rb +94 -0
- data/lib/justimmo_client/api/v1/models/realty_room_count.rb +35 -0
- data/lib/justimmo_client/api/v1/models/realty_type.rb +12 -0
- data/lib/justimmo_client/api/v1/models/realty_usage.rb +24 -0
- data/lib/justimmo_client/api/v1/models/region.rb +12 -0
- data/lib/justimmo_client/api/v1/representers/json/attachment_image_representer.rb +16 -0
- data/lib/justimmo_client/api/v1/representers/json/attachment_representer.rb +15 -0
- data/lib/justimmo_client/api/v1/representers/json/contact_representer.rb +30 -0
- data/lib/justimmo_client/api/v1/representers/json/justimmo_representer.rb +13 -0
- data/lib/justimmo_client/api/v1/representers/json/location_representer.rb +14 -0
- data/lib/justimmo_client/api/v1/representers/json/realty_category_representer.rb +21 -0
- data/lib/justimmo_client/api/v1/representers/json/realty_detail_representer.rb +69 -0
- data/lib/justimmo_client/api/v1/representers/json.rb +10 -0
- data/lib/justimmo_client/api/v1/representers/xml/city_representer.rb +18 -0
- data/lib/justimmo_client/api/v1/representers/xml/contact_representer.rb +15 -0
- data/lib/justimmo_client/api/v1/representers/xml/country_representer.rb +15 -0
- data/lib/justimmo_client/api/v1/representers/xml/employee_list_representer.rb +15 -0
- data/lib/justimmo_client/api/v1/representers/xml/employee_representer.rb +46 -0
- data/lib/justimmo_client/api/v1/representers/xml/federal_state_representer.rb +17 -0
- data/lib/justimmo_client/api/v1/representers/xml/geo_location_representer.rb +24 -0
- data/lib/justimmo_client/api/v1/representers/xml/justimmo_representer.rb +13 -0
- data/lib/justimmo_client/api/v1/representers/xml/realty_area_representer.rb +28 -0
- data/lib/justimmo_client/api/v1/representers/xml/realty_category_representer.rb +15 -0
- data/lib/justimmo_client/api/v1/representers/xml/realty_detail_representer.rb +92 -0
- data/lib/justimmo_client/api/v1/representers/xml/realty_list_representer.rb +85 -0
- data/lib/justimmo_client/api/v1/representers/xml/realty_price_representer.rb +53 -0
- data/lib/justimmo_client/api/v1/representers/xml/realty_representer.rb +32 -0
- data/lib/justimmo_client/api/v1/representers/xml/realty_room_count_representer.rb +22 -0
- data/lib/justimmo_client/api/v1/representers/xml/realty_type_representer.rb +14 -0
- data/lib/justimmo_client/api/v1/representers/xml/region_representer.rb +14 -0
- data/lib/justimmo_client/api/v1/representers/xml.rb +11 -0
- data/lib/justimmo_client/api/v1/requests/employee_request.rb +24 -0
- data/lib/justimmo_client/api/v1/requests/justimmo_request.rb +64 -0
- data/lib/justimmo_client/api/v1/requests/realty_request.rb +209 -0
- data/lib/justimmo_client/api/v1.rb +16 -0
- data/lib/justimmo_client/autoload.rb +17 -0
- data/lib/justimmo_client/core/caching.rb +55 -0
- data/lib/justimmo_client/core/config.rb +46 -0
- data/lib/justimmo_client/core/logging.rb +46 -0
- data/lib/justimmo_client/core/utils.rb +38 -0
- data/lib/justimmo_client/employee.rb +39 -0
- data/lib/justimmo_client/errors.rb +58 -0
- data/lib/justimmo_client/misc.rb +10 -0
- data/lib/justimmo_client/option_parser.rb +107 -0
- data/lib/justimmo_client/realty.rb +150 -0
- data/lib/justimmo_client/version.rb +5 -0
- data/lib/justimmo_client.rb +22 -0
- data/notes.md +19 -0
- metadata +271 -0
@@ -0,0 +1,209 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JustimmoClient::V1
|
4
|
+
# @api private
|
5
|
+
module RealtyRequest
|
6
|
+
extend JustimmoRequest
|
7
|
+
|
8
|
+
# Mappings for the option parser
|
9
|
+
TRANSLATION_MAPPING = {
|
10
|
+
limit: :Limit,
|
11
|
+
offset: :Offset,
|
12
|
+
lang: :culture,
|
13
|
+
with_projects: :alleProjektObjekte,
|
14
|
+
number: :objektnummer,
|
15
|
+
price: :preis,
|
16
|
+
zip_code: :plz,
|
17
|
+
price_per_sqm: :preis_per_m2,
|
18
|
+
type: :objektart,
|
19
|
+
subtype: :subobjektart,
|
20
|
+
tag: :tagname,
|
21
|
+
room_count: :zimmer,
|
22
|
+
area: :flaeche,
|
23
|
+
living_area: :wohnflaeche,
|
24
|
+
floor_area: :nutzflaeche,
|
25
|
+
surface_area: :grundflaeche,
|
26
|
+
keyword: :stichwort,
|
27
|
+
country: :land,
|
28
|
+
federal_state: :bundesland,
|
29
|
+
small_undbanded: :small,
|
30
|
+
small2_unbranded: :s220x155,
|
31
|
+
small3_unbranded: :s312x208,
|
32
|
+
id: :objekt_id,
|
33
|
+
salutation: :anrede,
|
34
|
+
title: :titel,
|
35
|
+
first_name: :vorname,
|
36
|
+
last_name: :nachname,
|
37
|
+
phone: :tel,
|
38
|
+
location: :ort,
|
39
|
+
all: :alle
|
40
|
+
}.freeze
|
41
|
+
|
42
|
+
module_function
|
43
|
+
|
44
|
+
# @!group Realty Requests
|
45
|
+
|
46
|
+
# @param [Hash] params
|
47
|
+
# @return [String] The requested XML.
|
48
|
+
def list(**params)
|
49
|
+
get("objekt/list", list_option_parser.parse(params))
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param [Integer] id
|
53
|
+
# @param [String, Symbol] lang
|
54
|
+
# @return [String] The requested XML.
|
55
|
+
def detail(id, lang: nil)
|
56
|
+
get("objekt/detail", detail_option_parser.parse(id: id, lang: lang))
|
57
|
+
end
|
58
|
+
|
59
|
+
# @param [Integer] id
|
60
|
+
# @param [Hash] params
|
61
|
+
# @return [String] The requested XML.
|
62
|
+
def inquiry(id, **params)
|
63
|
+
get("objekt/anfrage", inquiry_option_parser.parse(params.update(id: id)))
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param [Hash] params
|
67
|
+
# @return [String] A JSON string containing an array of ids.
|
68
|
+
def ids(**params)
|
69
|
+
get("objekt/ids", ids_option_parser.parse(params))
|
70
|
+
end
|
71
|
+
|
72
|
+
# @todo implement this
|
73
|
+
# @param [Hash] params
|
74
|
+
# @return [File] The PDF file.
|
75
|
+
def expose(**params)
|
76
|
+
get("objekt/expose", params)
|
77
|
+
end
|
78
|
+
|
79
|
+
# @!group Basic Data Requests
|
80
|
+
|
81
|
+
# @param [Boolean] all (false)
|
82
|
+
# @return [String] The requested XML.
|
83
|
+
def categories(all: false)
|
84
|
+
get("objekt/kategorien", alle: all ? 1 : 0)
|
85
|
+
end
|
86
|
+
|
87
|
+
# @param [Boolean] all (false)
|
88
|
+
# @return [String] The requested XML.
|
89
|
+
def types(all: false)
|
90
|
+
get("objekt/objektarten", alle: all ? 1 : 0)
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param [Boolean] all (false)
|
94
|
+
# @return [String] The requested XML.
|
95
|
+
def countries(all: false)
|
96
|
+
get("objekt/laender", alle: all ? 1 : 0)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @param [Boolean] all (false)
|
100
|
+
# @param [Integer, String] country
|
101
|
+
# @return [String] The requested XML.
|
102
|
+
def federal_states(country:, all: false)
|
103
|
+
get("objekt/bundeslaender", land: country, alle: all ? 1 : 0)
|
104
|
+
end
|
105
|
+
|
106
|
+
# @param [Boolean] all (false)
|
107
|
+
# @param [Integer, String] country
|
108
|
+
# @param [Integer] federal_state
|
109
|
+
# @return [String] The requested XML.
|
110
|
+
def regions(country: nil, federal_state: nil, all: false)
|
111
|
+
get("objekt/regionen", land: country, bundesland: federal_state, alle: all ? 1 : 0)
|
112
|
+
end
|
113
|
+
|
114
|
+
# @param [Boolean] all (false)
|
115
|
+
# @param [Integer, String] country
|
116
|
+
# @param [Integer] federal_state
|
117
|
+
# @return [String] The requested XML.
|
118
|
+
def zip_codes_and_cities(country: nil, federal_state: nil, all: false)
|
119
|
+
get("objekt/plzsUndOrte", land: country, bundesland: federal_state, alle: all ? 1 : 0)
|
120
|
+
end
|
121
|
+
|
122
|
+
# @!group Option Parsers
|
123
|
+
|
124
|
+
# @return [Hash]
|
125
|
+
def list_option_parser
|
126
|
+
@option_parsers ||= {}
|
127
|
+
@option_parsers[:list] ||= JustimmoClient::OptionParser.new do |options|
|
128
|
+
options.mappings = TRANSLATION_MAPPING
|
129
|
+
options.range_suffix = %i[_von _bis]
|
130
|
+
|
131
|
+
options.add :limit
|
132
|
+
options.add :offset
|
133
|
+
options.add :lang
|
134
|
+
options.add :orderby, values: %w[price zip_code number created_at updated_at published_at]
|
135
|
+
options.add :ordertype, values: %w[asc desc]
|
136
|
+
options.add :picturesize, values: %w[small_unbranded small2_unbranded small3_unbranded medium_unbranded big_unbranded big2_unbranded medium big bin2]
|
137
|
+
options.add :with_projects, type: :bool
|
138
|
+
options.group :filter do |f|
|
139
|
+
f.add :price_min
|
140
|
+
f.add :price_max
|
141
|
+
f.add :price_per_sqm_min
|
142
|
+
f.add :price_per_sqm_max
|
143
|
+
f.add :type_id
|
144
|
+
f.add :subtype_id
|
145
|
+
f.add :tag
|
146
|
+
f.add :zip_code
|
147
|
+
f.add :zip_code_min
|
148
|
+
f.add :zip_code_max
|
149
|
+
f.add :room_count_min
|
150
|
+
f.add :room_count_max
|
151
|
+
f.add :number
|
152
|
+
f.add :number_min
|
153
|
+
f.add :number_max
|
154
|
+
f.add :area_min
|
155
|
+
f.add :area_max
|
156
|
+
f.add :living_area_min
|
157
|
+
f.add :living_area_max
|
158
|
+
f.add :floor_area_min
|
159
|
+
f.add :floor_area_max
|
160
|
+
f.add :surface_area_min
|
161
|
+
f.add :surface_area_max
|
162
|
+
f.add :keyword
|
163
|
+
f.add :country_id
|
164
|
+
f.add :federal_state_id
|
165
|
+
f.add :status_id
|
166
|
+
f.add :project_id
|
167
|
+
f.add :type
|
168
|
+
f.add :parent_id
|
169
|
+
f.add :updated_at_min, as: :aktualisiert_am_von
|
170
|
+
f.add :updated_at_max, as: :aktualisiert_am_bis
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
alias ids_option_parser list_option_parser
|
176
|
+
|
177
|
+
# @return [Hash]
|
178
|
+
def inquiry_option_parser
|
179
|
+
@option_parsers ||= {}
|
180
|
+
@option_parsers[:inquiry] = JustimmoClient::OptionParser.new do |options|
|
181
|
+
options.mappings = TRANSLATION_MAPPING
|
182
|
+
options.range_suffix = %i[_von _bis]
|
183
|
+
|
184
|
+
options.add :salutation_id
|
185
|
+
options.add :title
|
186
|
+
options.add :first_name
|
187
|
+
options.add :last_name
|
188
|
+
options.add :email
|
189
|
+
options.add :phone
|
190
|
+
options.add :message
|
191
|
+
options.add :street
|
192
|
+
options.add :zip_code
|
193
|
+
options.add :location
|
194
|
+
options.add :country
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# @return [Hash]
|
199
|
+
def detail_option_parser
|
200
|
+
@option_parsers ||= {}
|
201
|
+
@option_parsers[:detail] = JustimmoClient::OptionParser.new do |options|
|
202
|
+
options.mappings = TRANSLATION_MAPPING
|
203
|
+
|
204
|
+
options.add :all
|
205
|
+
options.add :lang
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "justimmo_client/autoload"
|
4
|
+
|
5
|
+
module JustimmoClient
|
6
|
+
# Version 1 of the API
|
7
|
+
module V1
|
8
|
+
extend JustimmoClient::Utils
|
9
|
+
|
10
|
+
API_PATH = "#{__dir__}/v1"
|
11
|
+
|
12
|
+
autoload_dir "#{API_PATH}/models/*.rb"
|
13
|
+
autoload_dir "#{API_PATH}/representers/*.rb"
|
14
|
+
autoload_dir "#{API_PATH}/requests/*_request.rb"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "justimmo_client/version"
|
4
|
+
require "justimmo_client/errors"
|
5
|
+
require "justimmo_client/misc"
|
6
|
+
|
7
|
+
module JustimmoClient
|
8
|
+
include JustimmoClient::Errors
|
9
|
+
|
10
|
+
autoload :Config, "justimmo_client/core/config"
|
11
|
+
autoload :Logging, "justimmo_client/core/logging"
|
12
|
+
autoload :Utils, "justimmo_client/core/utils"
|
13
|
+
autoload :Caching, "justimmo_client/core/caching"
|
14
|
+
autoload :Realty, "justimmo_client/realty"
|
15
|
+
autoload :Employee, "justimmo_client/employee"
|
16
|
+
autoload :OptionParser, "justimmo_client/option_parser"
|
17
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "justimmo_client/core/config"
|
4
|
+
require "justimmo_client/core/logging"
|
5
|
+
|
6
|
+
module JustimmoClient
|
7
|
+
# Caching support
|
8
|
+
# @api private
|
9
|
+
module Caching
|
10
|
+
extend JustimmoClient::Logging
|
11
|
+
|
12
|
+
class NullCache
|
13
|
+
def write(_key, _data, **options); end
|
14
|
+
def read(_key); end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
# Returns the current cache
|
19
|
+
# @!attribute [rw] cache
|
20
|
+
def cache
|
21
|
+
@cache ||= default_cache
|
22
|
+
end
|
23
|
+
|
24
|
+
def cache=(c)
|
25
|
+
@cache = c
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_cache
|
29
|
+
cache = JustimmoClient::Config.cache || NullCache.new
|
30
|
+
log.info("Using default cache #{cache.class}")
|
31
|
+
cache
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def cache
|
36
|
+
JustimmoClient::Caching.cache
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: JSON serialize/deserialize the cached value
|
40
|
+
def with_cache(key, **options)
|
41
|
+
log.debug("Looking up cache key #{key}")
|
42
|
+
data = cache.read(key)
|
43
|
+
|
44
|
+
if data.nil?
|
45
|
+
log.debug("Cache miss for #{key}")
|
46
|
+
data = yield
|
47
|
+
cache.write(key, data, options)
|
48
|
+
else
|
49
|
+
log.debug("Cache hit for #{key}")
|
50
|
+
end
|
51
|
+
|
52
|
+
data
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "base64"
|
4
|
+
require "active_support/configurable"
|
5
|
+
require "justimmo_client/errors"
|
6
|
+
|
7
|
+
module JustimmoClient
|
8
|
+
# Configuration options storage
|
9
|
+
# @api private
|
10
|
+
class Config
|
11
|
+
include ActiveSupport::Configurable
|
12
|
+
|
13
|
+
SUPPORTED_API_VERSIONS = [1].freeze
|
14
|
+
REQUIRED = %i[username password].freeze
|
15
|
+
|
16
|
+
config_accessor(:base_url) { "api.justimmo.at/rest" }
|
17
|
+
config_accessor(:secure) { true }
|
18
|
+
config_accessor(:api_ver) { 1 }
|
19
|
+
config_accessor(:username)
|
20
|
+
config_accessor(:password)
|
21
|
+
config_accessor(:credentials)
|
22
|
+
config_accessor(:debug) { false }
|
23
|
+
config_accessor(:cache) { nil }
|
24
|
+
config_accessor(:request_retries) { 3 }
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def configure
|
28
|
+
super
|
29
|
+
self.credentials = Base64.urlsafe_encode64("#{username}:#{password}")
|
30
|
+
validate
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate
|
34
|
+
missing = REQUIRED.select { |r| @_config[r].nil? }
|
35
|
+
raise MissingConfiguration, missing unless missing.empty?
|
36
|
+
|
37
|
+
supported_ver = SUPPORTED_API_VERSIONS.include?(api_ver)
|
38
|
+
raise UnsupportedAPIVersion, api_ver unless supported_ver
|
39
|
+
end
|
40
|
+
|
41
|
+
def url
|
42
|
+
"#{secure ? 'https' : 'http'}://#{base_url}/v#{api_ver}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
require "justimmo_client/core/config"
|
5
|
+
|
6
|
+
module JustimmoClient
|
7
|
+
# Logging support
|
8
|
+
# @api private
|
9
|
+
module Logging
|
10
|
+
class << self
|
11
|
+
# Use the Rails or default logger if none is set.
|
12
|
+
# @!attribute [rw] logger
|
13
|
+
# @return [Logger]
|
14
|
+
def logger
|
15
|
+
@logger ||= rails_logger || default_logger
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_writer :logger
|
19
|
+
|
20
|
+
def default_logger
|
21
|
+
logger = Logger.new($stdout)
|
22
|
+
logger.level = JustimmoClient::Config.debug ? Logger::DEBUG : Logger::INFO
|
23
|
+
logger.datetime_format = "%Y-%m-%d %H:%M:%S"
|
24
|
+
logger.progname = "JustimmoClient"
|
25
|
+
logger.formatter = proc do |severity, datetime, progname, message|
|
26
|
+
"[#{format("%-5s", severity)}] #{datetime} #{progname} #{message}\n"
|
27
|
+
end
|
28
|
+
logger
|
29
|
+
end
|
30
|
+
|
31
|
+
# The Ruby on Rails logger
|
32
|
+
# @return [Logger, nil] The logger object
|
33
|
+
def rails_logger
|
34
|
+
if ("true" == ENV.fetch("JUSTIMMO_USE_RAILS_LOGGER", "true")) && defined?(::Rails)
|
35
|
+
::Rails&.logger
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def logger
|
41
|
+
Logging.logger
|
42
|
+
end
|
43
|
+
|
44
|
+
alias log logger
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/inflections"
|
4
|
+
|
5
|
+
module JustimmoClient
|
6
|
+
# Useful utility methods
|
7
|
+
# @api private
|
8
|
+
module Utils
|
9
|
+
def autoload_dir(path)
|
10
|
+
dirname = File.dirname(path)
|
11
|
+
|
12
|
+
Dir[path].each do |f|
|
13
|
+
basename = File.basename(f, ".rb")
|
14
|
+
send :autoload, basename.classify, File.join(dirname, basename)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def versioned_api(*name)
|
19
|
+
(["JustimmoClient::V#{JustimmoClient::Config.api_ver}"] + name).join("::").constantize
|
20
|
+
end
|
21
|
+
|
22
|
+
def api(name)
|
23
|
+
"JustimmoClient::#{name.to_s.classify}".constantize
|
24
|
+
end
|
25
|
+
|
26
|
+
def representer(name, type = :xml)
|
27
|
+
versioned_api(type.to_s.classify, "#{name.to_s.classify}Representer")
|
28
|
+
end
|
29
|
+
|
30
|
+
def model(name)
|
31
|
+
versioned_api(name.to_s.classify)
|
32
|
+
end
|
33
|
+
|
34
|
+
def request(name)
|
35
|
+
versioned_api("#{name.to_s.classify}Request")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JustimmoClient
|
4
|
+
# Public employee query interface
|
5
|
+
module Employee
|
6
|
+
extend JustimmoClient::Utils
|
7
|
+
|
8
|
+
module_function
|
9
|
+
|
10
|
+
# Retrieve a list of employee data.
|
11
|
+
# @return [Array<Object>]
|
12
|
+
def list
|
13
|
+
xml_response = request(:employee).list
|
14
|
+
model = Struct.new(:employees).new
|
15
|
+
representer(:employee_list).new(model).from_xml(xml_response).employees
|
16
|
+
rescue JustimmoClient::RetrievalFailed
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieve detailed information about a single employee.
|
21
|
+
# @param id [Integer] The ID of the employee
|
22
|
+
# @return [Object]
|
23
|
+
def detail(id)
|
24
|
+
xml_response = request(:employee).detail(id)
|
25
|
+
model = model(:employee).new
|
26
|
+
representer(:employee).new(model).from_xml(xml_response)
|
27
|
+
rescue JustimmoClient::RetrievalFailed
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Array<Integer>] An array of employee IDs
|
32
|
+
def ids
|
33
|
+
json_response = request(:employee).ids
|
34
|
+
::JSON.parse(json_response).map(&:to_i)
|
35
|
+
rescue JustimmoClient::RetrievalFailed
|
36
|
+
[]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Exceptions for internal use
|
4
|
+
module JustimmoClient::Errors
|
5
|
+
JustimmoError = Class.new(StandardError)
|
6
|
+
InitializationError = Class.new(JustimmoError)
|
7
|
+
|
8
|
+
# Raised when configuration validation fails.
|
9
|
+
ConfigurationError = Class.new(JustimmoError)
|
10
|
+
|
11
|
+
# Raised when authentication with the API fails.
|
12
|
+
class AuthenticationFailed < JustimmoError
|
13
|
+
def initialize
|
14
|
+
super("Authentication failed.")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Raised when retrieval from the API fails.
|
19
|
+
class RetrievalFailed < JustimmoError
|
20
|
+
def initialize(message)
|
21
|
+
super("Failed to get data from the API: #{message}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# A mapping could not be found in the mappings hash.
|
26
|
+
class MappingNotFound < JustimmoError
|
27
|
+
def initialize(map)
|
28
|
+
super("Could not find #{map} mapping.")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# A key could not be found in the specified mapping.
|
33
|
+
class KeyNotFound < JustimmoError
|
34
|
+
def initialize(key, map)
|
35
|
+
super("Key #{key} not found in #{map} mapping.")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class NotImplemented < JustimmoError
|
40
|
+
def initialize(meth)
|
41
|
+
super("Method #{meth} not implemented!")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Raised when an unsupported API version is set.
|
46
|
+
class UnsupportedAPIVersion < ConfigurationError
|
47
|
+
def initialize(version)
|
48
|
+
super("API Version #{version} not supported.")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Raised on missing required configuration options.
|
53
|
+
class MissingConfiguration < ConfigurationError
|
54
|
+
def initialize(missing)
|
55
|
+
super("Required configuration missing: #{missing}.")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JustimmoClient
|
4
|
+
# @api private
|
5
|
+
class OptionParser
|
6
|
+
include JustimmoClient::Logging
|
7
|
+
|
8
|
+
attr_accessor :range_suffix
|
9
|
+
attr_accessor :mappings
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@options = options
|
13
|
+
@mappings = {}
|
14
|
+
@range_suffix = %i[_min _max]
|
15
|
+
@context = nil
|
16
|
+
|
17
|
+
yield self if block_given?
|
18
|
+
|
19
|
+
parse unless options.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
def add(key, **options)
|
23
|
+
add_option(key, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def group(groupname)
|
27
|
+
@context = groupname.to_sym
|
28
|
+
yield self if block_given?
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse(options = {})
|
32
|
+
out = {}
|
33
|
+
|
34
|
+
options.each do |key, value|
|
35
|
+
raise ArgumentError, "Invalid option: #{key}" unless @options.key?(key.to_sym)
|
36
|
+
group = group_of(key)
|
37
|
+
|
38
|
+
if group
|
39
|
+
out[group] ||= {}
|
40
|
+
out[group].update(parse_option(key.to_sym, value))
|
41
|
+
else
|
42
|
+
out.update(parse_option(key.to_sym, value))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
out
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def add_option(key, **options)
|
52
|
+
@options[key.to_sym] = {
|
53
|
+
group: @context,
|
54
|
+
type: options[:type],
|
55
|
+
as: options[:as],
|
56
|
+
values: options[:values]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def group_of(key)
|
61
|
+
@options.dig(key, :group)
|
62
|
+
end
|
63
|
+
|
64
|
+
def mapping(key)
|
65
|
+
@mappings.fetch(key, key)
|
66
|
+
end
|
67
|
+
|
68
|
+
def translate(key)
|
69
|
+
return @options[key][:as] if @options[key][:as]
|
70
|
+
|
71
|
+
suffix =
|
72
|
+
case key
|
73
|
+
when /(.*)_min/ then @range_suffix.first
|
74
|
+
when /(.*)_max/ then @range_suffix.last
|
75
|
+
when /(.*)_id/ then "_id"
|
76
|
+
else nil
|
77
|
+
end
|
78
|
+
|
79
|
+
key = ($1 || key).to_sym
|
80
|
+
|
81
|
+
"#{mapping(key)}#{suffix}".to_sym
|
82
|
+
end
|
83
|
+
|
84
|
+
def parse_option(key, value)
|
85
|
+
values = @options.dig(key, :values)
|
86
|
+
raise ArgumentError, "Value #{value} not supported" unless values.nil? || values.include?(value)
|
87
|
+
|
88
|
+
coerced =
|
89
|
+
case @options.dig(key, :type)
|
90
|
+
when :bool then i_to_bool(value)
|
91
|
+
else mapping(value)
|
92
|
+
end
|
93
|
+
|
94
|
+
{ translate(key) => coerced }
|
95
|
+
end
|
96
|
+
|
97
|
+
def parse_range(key, range)
|
98
|
+
min, max = @options[key][:range_suffix]
|
99
|
+
api_param = @options[key][:mapped]
|
100
|
+
{ "#{api_param}#{min}": range.first, "#{api_param}#{max}": range.last }
|
101
|
+
end
|
102
|
+
|
103
|
+
def i_to_bool(value)
|
104
|
+
value ? 1 : 0
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|