firmenwissen 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 479f8a1bea375d5c4af1c8980981c1fc2f0d4d0bfe7c8b7ac60cf17821b76672
4
+ data.tar.gz: e4aa6079c3be8d66819ff0d49e8f7c8fef9261c61f4b5353174c4227788593c2
5
+ SHA512:
6
+ metadata.gz: c877c1e82ffde13a74f956d72d94d5b7eb7106e27dabb66e377c40d7983076706a34276be83bb0c325d7fa3dde0b735f5164b62a86666c380e31d20851fb2acb
7
+ data.tar.gz: '095e5255d2bb6c45cea6151bd5acafeba67fc07fa074db666c56e06c0c7c9748690bded252489748ed23c0f913c038af9e3e6be7a4258e02712735c96f2cbc5e'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2017 Gerrit Seger
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Firmenwissen
2
+ A ruby gem to conveniently access the [Firmenwissen](www.firmenwissen.de) Smart Sign-Up API.
3
+
4
+ ## Installation
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'firmenwissen'
9
+ ```
10
+
11
+ And then execute:
12
+ ```bash
13
+ $ bundle
14
+ ```
15
+
16
+ Or install it yourself as:
17
+ ```bash
18
+ $ gem install firmenwissen
19
+ ```
20
+
21
+ ## Usage
22
+ ### Searching
23
+ ```ruby
24
+ response = Firmenwissen.search('company xyz')
25
+
26
+ if response.successful?
27
+ suggestions = response.suggestions
28
+ ...
29
+ end
30
+ ```
31
+
32
+ will give you an array of suggestions from Firmenwissen, if any, for the specified query string.
33
+
34
+ ```ruby
35
+ suggestion = suggestions.first
36
+
37
+ suggestion.crefo_id # => '1234567890'
38
+ suggestion.name # => 'COMPEON GmbH'
39
+ suggestion.trade_name # => 'Compeon'
40
+ suggestion.country # => 'DE'
41
+ suggestion.state # => 'Nordrhein-Westfalen'
42
+ suggestion.zip_code # => '40211'
43
+ suggestion.city # => 'Düsseldorf'
44
+ suggestion.address # => 'Louise-Dumon-Straße 5'
45
+
46
+ suggestion.to_h # => { crefo_id: '1234567890', name: 'COMPEON GmbH', ... }
47
+ ```
48
+ ### Configuration
49
+ ```ruby
50
+ Firmenwissen.configure do |config|
51
+ config.user = 'username' # Username for Firmenwissen basic auth (required)
52
+ config.password = 'password' # Password for Firmenwissen basic auth (required)
53
+ config.timeout = 5 # Request timeout in seconds
54
+
55
+ # Configure the endpoint yourself. %s will be replaced by the actual query
56
+ config.endpoint = 'https://example.com/search?query=%s'
57
+ end
58
+ ```
59
+ ### Mocking results
60
+ In a non production-like environment you will not want to perform real requests to the API. Thus you can configure the gem to respond with mocked data.
61
+
62
+ ```ruby
63
+ Firmenwissen.configure do |config|
64
+ config.mock_requests = true
65
+
66
+ # respond with a fixed array
67
+ config.mock_data = [{ crefo_id: '1111111111', name: 'Test GmbH', ... }, { ... }, ...]
68
+
69
+ # respond when a query matches an exact keyword
70
+ # this will return a result mock when you search for 'compeon' or 'test', otherwise an empty result
71
+ mock_data = {
72
+ 'compeon' => [{ crefo_id: '1234567890', name: 'COMPEON GmbH', ... }],
73
+ 'test' => [{ crefo_id: '1111111111', ... }]
74
+ }
75
+
76
+ config.mock_data = mock_data
77
+
78
+ # generate your own dynamic response
79
+ config.mock_data = Proc.new do |query|
80
+ # your code for mock data generation here
81
+ end
82
+
83
+ # or
84
+
85
+ class DynamicMockData
86
+ def call(query)
87
+ # your code for mock data generation here
88
+ end
89
+ end
90
+
91
+ config.mock_data = DynamicMockData.new
92
+ end
93
+ ```
94
+ **Note:** All configuration options can be overridden on a per-request basis by passing an options hash to the `search` method.
95
+
96
+ ## License
97
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,30 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'addressable/template'
4
+
5
+ require 'firmenwissen/configuration'
6
+ require 'firmenwissen/http_request'
7
+ require 'firmenwissen/key_mapper'
8
+ require 'firmenwissen/request'
9
+ require 'firmenwissen/suggestion'
10
+ require 'firmenwissen/version'
11
+
12
+ require 'firmenwissen/errors/credentials_error'
13
+
14
+ require 'firmenwissen/request/base'
15
+ require 'firmenwissen/request/mock'
16
+
17
+ require 'firmenwissen/response/base'
18
+ require 'firmenwissen/response/mock'
19
+
20
+ module Firmenwissen
21
+ extend Configuration::Accessors
22
+
23
+ class << self
24
+ def search(query, options = {})
25
+ strategy = configuration.mock_requests? ? :mock : :base
26
+
27
+ Request.from_strategy(strategy, query, options).execute
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,50 @@
1
+ module Firmenwissen
2
+ class Configuration
3
+ module Accessors
4
+ def configuration
5
+ @config ||= Configuration.new
6
+ end
7
+
8
+ def configure
9
+ yield configuration
10
+ end
11
+ end
12
+
13
+ SETTINGS = %i[endpoint password mock_data mock_requests timeout user]
14
+
15
+ DEFAULT_SETTINGS = {
16
+ endpoint: 'https://www.firmenwissen.de/search/suggest/companywithaddress/{query}{?country}',
17
+ mock_requests: false,
18
+ mock_data: [],
19
+ timeout: 5
20
+ }.freeze
21
+
22
+ SETTINGS.each do |setting|
23
+ define_method(setting) do
24
+ settings[setting]
25
+ end
26
+
27
+ define_method("#{setting}=") do |value|
28
+ settings[setting] = value
29
+ end
30
+ end
31
+
32
+ attr_reader :settings
33
+
34
+ def initialize(options = {})
35
+ @settings = DEFAULT_SETTINGS.dup.merge(options)
36
+ end
37
+
38
+ def merge(options)
39
+ Configuration.new(settings.merge(options))
40
+ end
41
+
42
+ def credentials_present?
43
+ [user, password].all? { |setting| setting.is_a?(String) && !setting.empty? }
44
+ end
45
+
46
+ def mock_requests?
47
+ mock_requests
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,7 @@
1
+ module Firmenwissen
2
+ class CredentialsError < StandardError
3
+ def initialize(message = 'Firmenwissen credentials are missing')
4
+ super
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ module Firmenwissen
2
+ class HttpRequest
3
+ def initialize(uri, options = {})
4
+ @uri = uri
5
+ @options = options
6
+ end
7
+
8
+ def execute
9
+ http = Net::HTTP.start(uri.host)
10
+ http.read_timeout = config.timeout
11
+ http.request(request)
12
+ ensure
13
+ http.finish
14
+ http
15
+ end
16
+
17
+ protected
18
+
19
+ attr_reader :uri, :options, :params
20
+
21
+ def request
22
+ @request ||= begin
23
+ Net::HTTP::Get.new(uri).tap do |req|
24
+ req.basic_auth(config.user, config.password)
25
+ end
26
+ end
27
+ end
28
+
29
+ def config
30
+ @config ||= Firmenwissen.configuration.merge(options)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ module Firmenwissen
2
+ module KeyMapper
3
+ KEY_MAPPINGS = {
4
+ crefo_id: 'crefonummer',
5
+ name: 'name',
6
+ trade_name: 'handelsName',
7
+ country: 'land',
8
+ state: 'bundesland',
9
+ zip_code: 'plz',
10
+ city: 'ort',
11
+ address: 'strasseHausnummer'
12
+ }.freeze
13
+
14
+ class << self
15
+ def from_api(hash)
16
+ map(hash, :from_api)
17
+ end
18
+
19
+ def to_api(hash)
20
+ map(hash, :to_api)
21
+ end
22
+
23
+ private
24
+
25
+ def map(hash, direction)
26
+ {}.tap do |result|
27
+ mapping_for(direction).each do |key, value|
28
+ result[key] = hash[value]
29
+ end
30
+ end
31
+ end
32
+
33
+ def mapping_for(direction)
34
+ direction == :from_api ? KEY_MAPPINGS : KEY_MAPPINGS.invert
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ module Firmenwissen
2
+ module Request
3
+ class << self
4
+ def from_strategy(strategy, query, options = {})
5
+ strategy_name = strategy.to_s.capitalize
6
+
7
+ self.const_get(strategy_name).new(query, options)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ module Firmenwissen
2
+ module Request
3
+ class Base
4
+ def initialize(query, options = {})
5
+ @query = query
6
+ @options = options
7
+ @params = options.fetch(:params, {})
8
+
9
+ raise CredentialsError unless config.credentials_present?
10
+ end
11
+
12
+ def execute
13
+ Response::Base.new(http_request.execute)
14
+ end
15
+
16
+ protected
17
+
18
+ attr_reader :options, :query, :params
19
+
20
+ def http_request
21
+ HttpRequest.new(uri, options)
22
+ end
23
+
24
+ def uri
25
+ template = Addressable::Template.new(config.endpoint)
26
+ template.expand(query: query, **params)
27
+ end
28
+
29
+ def config
30
+ @config ||= Firmenwissen.configuration.merge(options)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ module Firmenwissen
2
+ module Request
3
+ class Mock < Base
4
+ def execute
5
+ Response::Mock.new(config.mock_data, query, params)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,37 @@
1
+ module Firmenwissen
2
+ module Response
3
+ class Base
4
+ def initialize(http_response)
5
+ @http_response = http_response
6
+ end
7
+
8
+ def suggestions
9
+ @suggestions ||= data.map { |suggestion| Suggestion.new(suggestion) }
10
+ end
11
+
12
+ def data
13
+ api_response = JSON.parse(http_response.body).fetch('companyNameSuggestions', [])
14
+
15
+ map_response(api_response)
16
+ end
17
+
18
+ def status_code
19
+ http_response.code
20
+ end
21
+
22
+ def successful?
23
+ status_code == '200'
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :http_response
29
+
30
+ def map_response(api_response)
31
+ api_response.map do |hash|
32
+ KeyMapper.from_api(hash)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ module Firmenwissen
2
+ module Response
3
+ class Mock < Base
4
+ def initialize(mock_data, query, params = {})
5
+ @mock_data = mock_data
6
+ @query = query
7
+ @params = params
8
+
9
+ raise ArgumentError, 'mock data must either be an array, a hash or respond to `call`' unless mock_data_valid?
10
+ end
11
+
12
+ def data
13
+ return mock_data.call(query, params) if mock_data.respond_to?(:call)
14
+
15
+ case mock_data
16
+ when Array
17
+ mock_data
18
+ when Hash
19
+ mock_data[query] || []
20
+ else
21
+ []
22
+ end
23
+ end
24
+
25
+ def status_code
26
+ '200'
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :mock_data, :query, :params
32
+
33
+ def mock_data_valid?
34
+ mock_data.respond_to?(:call) || mock_data.is_a?(Array) || mock_data.is_a?(Hash)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ module Firmenwissen
2
+ class Suggestion
3
+ KeyMapper::KEY_MAPPINGS.keys.each do |key|
4
+ define_method(key) do
5
+ suggestion[key]
6
+ end
7
+ end
8
+
9
+ def initialize(suggestion)
10
+ @suggestion = suggestion
11
+ end
12
+
13
+ def to_h
14
+ suggestion.dup
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :suggestion
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Firmenwissen
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: firmenwissen
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Gerrit Seger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-11-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: addressable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: vcr
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - gerrit.seger@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - MIT-LICENSE
91
+ - README.md
92
+ - Rakefile
93
+ - lib/firmenwissen.rb
94
+ - lib/firmenwissen/configuration.rb
95
+ - lib/firmenwissen/errors/credentials_error.rb
96
+ - lib/firmenwissen/http_request.rb
97
+ - lib/firmenwissen/key_mapper.rb
98
+ - lib/firmenwissen/request.rb
99
+ - lib/firmenwissen/request/base.rb
100
+ - lib/firmenwissen/request/mock.rb
101
+ - lib/firmenwissen/response/base.rb
102
+ - lib/firmenwissen/response/mock.rb
103
+ - lib/firmenwissen/suggestion.rb
104
+ - lib/firmenwissen/version.rb
105
+ homepage:
106
+ licenses:
107
+ - MIT
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.7.3
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Ruby client for the FirmenWissen API
129
+ test_files: []