fountain 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a2daa741ce144d022348233a66319f12b9051345
4
- data.tar.gz: 47adbc3dca6bff4b821fd3aaa0c1de20e309f8f9
3
+ metadata.gz: b38b462449586bea1c3a1ce67e116b9c439c8e52
4
+ data.tar.gz: c83cd25cf68b8099f8ec7b11cb0b2eed89f0f326
5
5
  SHA512:
6
- metadata.gz: a9f3497193a066efca8db1e1eaeb9314e86abeeda82440dd121b4c06ed68831ff3aaacc5a4f705e50e461f453a6cabded34e807756854cefa0502c600acc829e
7
- data.tar.gz: 8a672762206813f509994c127c8027c333c72253a5ad97c4ae909abca7f32a5b0a5e45c6e10fcb94994f5161dcb7ccd22251c77306d4b17face0e1a30ceabd61
6
+ metadata.gz: 55ff9dfeabf1fab057d055b2ae17d6cb5040d6f1a36f4827436d8d108b26996366e58117a5e834b36c2fc7e32d8547fb6abd5c37475c240658648d301e9ebb3e
7
+ data.tar.gz: 8bacdea06f7863d57114c3281133ca991a4a5e3cf26172813a137318406f8d337ba053e7bed54df8c492c6d208fedb72ae0abb6480e979335d4c2f35b6e9e33f
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'fountain'
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
@@ -9,12 +9,12 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = %w[abrom]
10
10
  spec.email = %w[a.bromwich@gmail.com]
11
11
 
12
- spec.summary = 'Fountain REST API v2 for Ruby'
13
- spec.description = 'Fountain REST API v2 for Ruby'
12
+ spec.summary = 'Fountain REST API v2 wrapper for Ruby'
13
+ spec.description = 'Fountain REST API v2 wrapper for Ruby'
14
14
  spec.homepage = 'https://github.com/Studiosity/fountain-ruby'
15
15
  spec.license = 'MIT'
16
16
 
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|docs)/}) }
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|docs)/}) }
18
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ['lib']
20
20
 
@@ -1 +1,26 @@
1
- require 'rocket_chat/gem_version'
1
+ require 'fountain/gem_version'
2
+
3
+ require 'json'
4
+
5
+ require 'fountain/configuration'
6
+ require 'fountain/util'
7
+
8
+ module Fountain
9
+ class Error < StandardError; end
10
+ class HTTPError < Error; end
11
+ class NotFoundError < HTTPError; end
12
+ class AuthenticationError < HTTPError; end
13
+ class InvalidMethodError < HTTPError; end
14
+ class JsonParseError < Error; end
15
+ class MissingApiKeyError < Error; end
16
+ class StatusError < Error; end
17
+ end
18
+
19
+ require 'fountain/applicant'
20
+ require 'fountain/background_check'
21
+ require 'fountain/document_signature'
22
+ require 'fountain/funnel'
23
+ require 'fountain/stage'
24
+
25
+ require 'fountain/api/request_helper'
26
+ require 'fountain/api/applicants'
@@ -0,0 +1,57 @@
1
+ module Fountain
2
+ module Api
3
+ #
4
+ # Fountain Applicant API
5
+ #
6
+ class Applicants
7
+ include RequestHelper
8
+
9
+ #
10
+ # List applicants
11
+ # @param [Hash] filter_options A hash of options to send to Fountain.
12
+ # funnel_id - Unique identifier of the position/funnel
13
+ # stage_id - Unique identifier of the stage
14
+ # stage - Filter applicants by stage type
15
+ # labels - MUST be URL-encoded
16
+ # cursor - Cursor parameter for cursor-based pagination
17
+ # @return [Array] of Fountain::Applicant
18
+ def list(filter_options = {})
19
+ response = request_json(
20
+ '/v2/applicants',
21
+ body: Util.slice_hash(
22
+ filter_options,
23
+ :funnel_id, :stage_id, :stage, :labels, :cursor
24
+ )
25
+ )
26
+ response['applicants'].map { |hash| Fountain::Applicant.new hash }
27
+ end
28
+
29
+ #
30
+ # Update applicant info
31
+ # @param [String] applicant_id ID of the Fountain applicant
32
+ # @param [Hash] update_options A hash of options to update applicant
33
+ # name
34
+ # email
35
+ # phone_number
36
+ # data - must be passed in a data object/array
37
+ # secure_data - See 'Secure Fields' section of
38
+ # https://developer.fountain.com/docs/update-applicant-info
39
+ # rejection_reason
40
+ # on_hold_reason
41
+ # @return [Fountain::Applicant]
42
+ #
43
+ def update(applicant_id, update_options = {})
44
+ response = request_json(
45
+ "/v2/applicants/#{applicant_id}",
46
+ method: :put,
47
+ body: Util.slice_hash(
48
+ update_options,
49
+ :name, :email, :phone_number, :data, :secure_data,
50
+ :rejection_reason, :on_hold_reason
51
+ )
52
+ )
53
+ Fountain::Applicant.new response
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,113 @@
1
+ require 'uri'
2
+ require 'openssl'
3
+ require 'net/http'
4
+
5
+ module Fountain
6
+ module Api
7
+ #
8
+ # Fountain API HTTP request helper
9
+ #
10
+ module RequestHelper
11
+ DEFAULT_REQUEST_OPTIONS = {
12
+ method: :get,
13
+ body: nil,
14
+ headers: nil,
15
+ ssl_verify_mode: OpenSSL::SSL::VERIFY_PEER,
16
+ ssl_ca_file: nil
17
+ }.freeze
18
+
19
+ def request_json(path, options = {})
20
+ response = request path, options
21
+ check_response response
22
+ parse_response response.body
23
+ end
24
+
25
+ def request(path, options = {})
26
+ options = DEFAULT_REQUEST_OPTIONS.merge(options)
27
+
28
+ raise Fountain::InvalidMethodError unless %i[get post put].include? options[:method]
29
+
30
+ http = create_http(options)
31
+ req = create_request(path, options)
32
+ http.start { http.request(req) }
33
+ end
34
+
35
+ private
36
+
37
+ def check_response(response)
38
+ case response
39
+ when Net::HTTPOK then nil
40
+ when Net::HTTPUnauthorized then raise Fountain::AuthenticationError
41
+ when Net::HTTPNotFound then raise Fountain::NotFoundError
42
+ else raise HTTPError, "Invalid http response code: #{response.code}"
43
+ end
44
+ end
45
+
46
+ def parse_response(response)
47
+ JSON.parse(response)
48
+ rescue JSON::ParserError
49
+ raise Fountain::JsonParseError, "Fountain response parse error: #{response}"
50
+ end
51
+
52
+ def create_http(options)
53
+ server = URI.parse Fountain.host_path
54
+ http = Net::HTTP.new(server.host, server.port)
55
+
56
+ if server.scheme == 'https'
57
+ http.use_ssl = true
58
+ http.verify_mode = options[:ssl_verify_mode]
59
+ http.ca_file = options[:ssl_ca_file] if options[:ssl_ca_file]
60
+ end
61
+
62
+ http
63
+ end
64
+
65
+ def create_request(path, options)
66
+ headers = get_headers(options)
67
+ body = options[:body]
68
+
69
+ if options[:method] == :post
70
+ create_post_request path, headers, body
71
+ elsif options[:method] == :put
72
+ create_put_request path, headers, body
73
+ else
74
+ create_get_request path, headers, body
75
+ end
76
+ end
77
+
78
+ def create_post_request(path, headers, body)
79
+ req = Net::HTTP::Post.new(path, headers)
80
+ add_body(req, body) if body
81
+ req
82
+ end
83
+
84
+ def create_put_request(path, headers, body)
85
+ req = Net::HTTP::Put.new(path, headers)
86
+ add_body(req, body) if body
87
+ req
88
+ end
89
+
90
+ def create_get_request(path, headers, body)
91
+ path += '?' + body.map { |k, v| "#{k}=#{v}" }.join('&') if body
92
+ Net::HTTP::Get.new(path, headers)
93
+ end
94
+
95
+ def get_headers(options)
96
+ headers = options[:headers]
97
+ headers ||= {}
98
+ raise Fountain::MissingApiKeyError if Fountain.api_token.nil?
99
+ headers['X-ACCESS-TOKEN'] = Fountain.api_token
100
+ headers
101
+ end
102
+
103
+ def add_body(request, body)
104
+ if body.is_a? Hash
105
+ request.body = body.to_json
106
+ request.content_type = 'application/json'
107
+ else
108
+ request.body = body.to_s
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,79 @@
1
+ module Fountain
2
+ #
3
+ # Fountain Applicant
4
+ #
5
+ class Applicant
6
+ # Raw applicant data
7
+ attr_reader :raw_data
8
+
9
+ #
10
+ # @param [Hash] data Raw applicant data
11
+ #
12
+ def initialize(data)
13
+ @raw_data = Util.stringify_hash_keys data
14
+ end
15
+
16
+ # Applicant ID
17
+ def id
18
+ raw_data['id']
19
+ end
20
+
21
+ # Created at
22
+ def created_at
23
+ Time.parse raw_data['created_at']
24
+ end
25
+
26
+ # Email
27
+ def email
28
+ raw_data['email']
29
+ end
30
+
31
+ # Name
32
+ def name
33
+ raw_data['name']
34
+ end
35
+
36
+ # Phone number
37
+ def phone_number
38
+ raw_data['phone_number']
39
+ end
40
+
41
+ # data
42
+ def data
43
+ raw_data['data']
44
+ end
45
+
46
+ # Funnel
47
+ def funnel
48
+ Funnel.new raw_data['funnel']
49
+ end
50
+
51
+ # Stage
52
+ def stage
53
+ Stage.new raw_data['stage']
54
+ end
55
+
56
+ # Background checks
57
+ def background_checks
58
+ return [] unless raw_data['background_checks'].is_a? Array
59
+ raw_data['background_checks'].map { |check| BackgroundCheck.new check }
60
+ end
61
+
62
+ # Document signatures
63
+ def document_signatures
64
+ return [] unless raw_data['document_signatures'].is_a? Array
65
+ raw_data['document_signatures'].map { |signature| DocumentSignature.new signature }
66
+ end
67
+
68
+ def inspect
69
+ format(
70
+ '#<%<class_name>s:0x%<object_id>p @id="%<id>s" @name="%<name>s" @email="%<email>s">',
71
+ class_name: self.class.name,
72
+ object_id: object_id,
73
+ id: id,
74
+ name: name,
75
+ email: email
76
+ )
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,51 @@
1
+ module Fountain
2
+ #
3
+ # Fountain Background Check
4
+ #
5
+ class BackgroundCheck
6
+ # Raw background check data
7
+ attr_reader :raw_data
8
+
9
+ #
10
+ # @param [Hash] data Raw background check data
11
+ #
12
+ def initialize(data)
13
+ @raw_data = Util.stringify_hash_keys data
14
+ end
15
+
16
+ # Title
17
+ def title
18
+ raw_data['title']
19
+ end
20
+
21
+ # Status
22
+ def status
23
+ raw_data['status']
24
+ end
25
+
26
+ # Vendor
27
+ def vendor
28
+ raw_data['vendor']
29
+ end
30
+
31
+ # Candidate ID
32
+ def candidate_id
33
+ raw_data['candidate_id']
34
+ end
35
+
36
+ # Report ID
37
+ def report_id
38
+ raw_data['report_id']
39
+ end
40
+
41
+ def inspect
42
+ format(
43
+ '#<%<class_name>s:0x%<object_id>p @title="%<title>s" @status="%<status>s">',
44
+ class_name: self.class.name,
45
+ object_id: object_id,
46
+ title: title,
47
+ status: status
48
+ )
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ #
2
+ # Fountain configuration
3
+ #
4
+ module Fountain
5
+ class << self
6
+ # The path of the Fountain host
7
+ attr_accessor :host_path
8
+
9
+ # API token for Fountain
10
+ attr_accessor :api_token
11
+
12
+ def configure
13
+ yield self if block_given?
14
+ end
15
+ end
16
+
17
+ # Set default values for options
18
+ @host_path = 'https://api.fountain.com'
19
+ end
@@ -0,0 +1,40 @@
1
+ module Fountain
2
+ #
3
+ # Fountain Document Signature
4
+ #
5
+ class DocumentSignature
6
+ # Raw document signature data
7
+ attr_reader :raw_data
8
+
9
+ #
10
+ # @param [Hash] data Raw document signature data
11
+ #
12
+ def initialize(data)
13
+ @raw_data = Util.stringify_hash_keys data
14
+ end
15
+
16
+ # Signature ID
17
+ def signature_id
18
+ raw_data['signature_id']
19
+ end
20
+
21
+ # Vendor
22
+ def vendor
23
+ raw_data['vendor']
24
+ end
25
+
26
+ # Status
27
+ def status
28
+ raw_data['status']
29
+ end
30
+
31
+ def inspect
32
+ format(
33
+ '#<%<class_name>s:0x%<object_id>p @signature_id="%<signature_id>s">',
34
+ class_name: self.class.name,
35
+ object_id: object_id,
36
+ signature_id: signature_id
37
+ )
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,41 @@
1
+ module Fountain
2
+ #
3
+ # Fountain Funnel
4
+ #
5
+ class Funnel
6
+ # Raw funnel data
7
+ attr_reader :raw_data
8
+
9
+ #
10
+ # @param [Hash] data Raw funnel data
11
+ #
12
+ def initialize(data)
13
+ @raw_data = Util.stringify_hash_keys data
14
+ end
15
+
16
+ # Funnel ID
17
+ def id
18
+ raw_data['id']
19
+ end
20
+
21
+ # Title
22
+ def title
23
+ raw_data['title']
24
+ end
25
+
26
+ # Custom ID
27
+ def custom_id
28
+ raw_data['custom_id']
29
+ end
30
+
31
+ def inspect
32
+ format(
33
+ '#<%<class_name>s:0x%<object_id>p @id="%<id>s" @title="%<title>s">',
34
+ class_name: self.class.name,
35
+ object_id: object_id,
36
+ id: id,
37
+ title: title
38
+ )
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module Fountain
2
- VERSION = '0.0.1'.freeze
2
+ VERSION = '0.0.2'.freeze
3
3
  end
@@ -0,0 +1,36 @@
1
+ module Fountain
2
+ #
3
+ # Fountain Stage
4
+ #
5
+ class Stage
6
+ # Raw stage data
7
+ attr_reader :raw_data
8
+
9
+ #
10
+ # @param [Hash] data Raw stage data
11
+ #
12
+ def initialize(data)
13
+ @raw_data = Util.stringify_hash_keys data
14
+ end
15
+
16
+ # Stage ID
17
+ def id
18
+ raw_data['id']
19
+ end
20
+
21
+ # Title
22
+ def title
23
+ raw_data['title']
24
+ end
25
+
26
+ def inspect
27
+ format(
28
+ '#<%<class_name>s:0x%<object_id>p @id="%<id>s" @title="%<title>s">',
29
+ class_name: self.class.name,
30
+ object_id: object_id,
31
+ id: id,
32
+ title: title
33
+ )
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ module Fountain
2
+ #
3
+ # Fountain generic utility functions
4
+ #
5
+ module Util
6
+ #
7
+ # Stringify symbolized hash keys
8
+ # @param [Hash] hash A string/symbol keyed hash
9
+ # @return Stringified hash
10
+ #
11
+ def stringify_hash_keys(hash)
12
+ new_hash = {}
13
+ hash.each do |key, value|
14
+ new_hash[key.to_s] =
15
+ if value.is_a? Hash
16
+ stringify_hash_keys value
17
+ else
18
+ value
19
+ end
20
+ end
21
+ new_hash
22
+ end
23
+ module_function :stringify_hash_keys
24
+
25
+ #
26
+ # Slice keys from hash
27
+ # @param [Hash] hash A hash to slice key/value pairs from
28
+ # @param [Array] *keys The keys to be sliced
29
+ # @return Hash filtered by keys
30
+ #
31
+ def slice_hash(hash, *keys)
32
+ return {} if keys.length.zero?
33
+
34
+ new_hash = {}
35
+ hash.each do |key, value|
36
+ new_hash[key] = value if keys.include? key
37
+ end
38
+ new_hash
39
+ end
40
+ module_function :slice_hash
41
+ end
42
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fountain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - abrom
@@ -94,10 +94,11 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '2.3'
97
- description: Fountain REST API v2 for Ruby
97
+ description: Fountain REST API v2 wrapper for Ruby
98
98
  email:
99
99
  - a.bromwich@gmail.com
100
- executables: []
100
+ executables:
101
+ - console
101
102
  extensions: []
102
103
  extra_rdoc_files: []
103
104
  files:
@@ -108,9 +109,19 @@ files:
108
109
  - LICENSE
109
110
  - README.md
110
111
  - Rakefile
112
+ - bin/console
111
113
  - fountain.gemspec
112
114
  - lib/fountain.rb
115
+ - lib/fountain/api/applicants.rb
116
+ - lib/fountain/api/request_helper.rb
117
+ - lib/fountain/applicant.rb
118
+ - lib/fountain/background_check.rb
119
+ - lib/fountain/configuration.rb
120
+ - lib/fountain/document_signature.rb
121
+ - lib/fountain/funnel.rb
113
122
  - lib/fountain/gem_version.rb
123
+ - lib/fountain/stage.rb
124
+ - lib/fountain/util.rb
114
125
  homepage: https://github.com/Studiosity/fountain-ruby
115
126
  licenses:
116
127
  - MIT
@@ -134,5 +145,5 @@ rubyforge_project:
134
145
  rubygems_version: 2.6.14
135
146
  signing_key:
136
147
  specification_version: 4
137
- summary: Fountain REST API v2 for Ruby
148
+ summary: Fountain REST API v2 wrapper for Ruby
138
149
  test_files: []