fountain 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []