antaeus-sdk 0.2.3
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/LICENSE +22 -0
- data/README.md +119 -0
- data/bin/antaeus-cli +35 -0
- data/lib/antaeus-sdk.rb +58 -0
- data/lib/antaeus-sdk/api_client.rb +105 -0
- data/lib/antaeus-sdk/api_info.rb +47 -0
- data/lib/antaeus-sdk/config.rb +54 -0
- data/lib/antaeus-sdk/exception.rb +5 -0
- data/lib/antaeus-sdk/exceptions/approval_change_failed.rb +6 -0
- data/lib/antaeus-sdk/exceptions/authentication_failure.rb +6 -0
- data/lib/antaeus-sdk/exceptions/checkin_change_failed.rb +6 -0
- data/lib/antaeus-sdk/exceptions/checkout_change_failed.rb +6 -0
- data/lib/antaeus-sdk/exceptions/immutable_instance.rb +6 -0
- data/lib/antaeus-sdk/exceptions/immutable_modification.rb +6 -0
- data/lib/antaeus-sdk/exceptions/invalid_api_client.rb +6 -0
- data/lib/antaeus-sdk/exceptions/invalid_config_data.rb +6 -0
- data/lib/antaeus-sdk/exceptions/invalid_entity.rb +6 -0
- data/lib/antaeus-sdk/exceptions/invalid_input.rb +6 -0
- data/lib/antaeus-sdk/exceptions/invalid_options.rb +6 -0
- data/lib/antaeus-sdk/exceptions/invalid_property.rb +6 -0
- data/lib/antaeus-sdk/exceptions/invalid_where_query.rb +6 -0
- data/lib/antaeus-sdk/exceptions/login_required.rb +6 -0
- data/lib/antaeus-sdk/exceptions/missing_api_client.rb +6 -0
- data/lib/antaeus-sdk/exceptions/missing_entity.rb +6 -0
- data/lib/antaeus-sdk/exceptions/missing_path.rb +6 -0
- data/lib/antaeus-sdk/exceptions/new_instance_with_id.rb +6 -0
- data/lib/antaeus-sdk/guest_api_client.rb +63 -0
- data/lib/antaeus-sdk/helpers/string.rb +24 -0
- data/lib/antaeus-sdk/resource.rb +363 -0
- data/lib/antaeus-sdk/resource_collection.rb +198 -0
- data/lib/antaeus-sdk/resources/appointment.rb +166 -0
- data/lib/antaeus-sdk/resources/group.rb +27 -0
- data/lib/antaeus-sdk/resources/guest.rb +41 -0
- data/lib/antaeus-sdk/resources/hook.rb +17 -0
- data/lib/antaeus-sdk/resources/location.rb +50 -0
- data/lib/antaeus-sdk/resources/remote_application.rb +13 -0
- data/lib/antaeus-sdk/resources/user.rb +28 -0
- data/lib/antaeus-sdk/user_api_client.rb +63 -0
- data/lib/antaeus-sdk/version.rb +7 -0
- metadata +209 -0
@@ -0,0 +1,198 @@
|
|
1
|
+
module Antaeus
|
2
|
+
# The ResourceCollection class
|
3
|
+
# Should not allow or use mixed types
|
4
|
+
class ResourceCollection
|
5
|
+
include Enumerable
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# @return [Class] this is a collection of this {Resource} subclass
|
9
|
+
attr_reader :type
|
10
|
+
|
11
|
+
def initialize(list, options = {})
|
12
|
+
raise Exceptions::InvalidOptions unless options.is_a?(Hash)
|
13
|
+
raise Exceptions::MissingAPIClient unless options[:client]
|
14
|
+
raise Exceptions::InvalidAPIClient unless options[:client].is_a?(APIClient)
|
15
|
+
raise Exceptions::InvalidInput if list.empty? and options[:type].nil?
|
16
|
+
@client = options[:client]
|
17
|
+
@list = list
|
18
|
+
if options[:type]
|
19
|
+
@type = options[:type]
|
20
|
+
else
|
21
|
+
@type = list.first.class
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def each(&block)
|
26
|
+
@list.each(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Does the collection contain anything?
|
30
|
+
# @return [Boolean]
|
31
|
+
def empty?
|
32
|
+
@list.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
def first(n = nil)
|
36
|
+
if n
|
37
|
+
self.class.new(@list.first(n), type: @type, client: @client)
|
38
|
+
else
|
39
|
+
@list.first
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def last(n = nil)
|
44
|
+
if n
|
45
|
+
self.class.new(@list.last(n), type: @type, client: @client)
|
46
|
+
else
|
47
|
+
@list.last
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Merge two collections
|
52
|
+
# @return [ResourceCollection]
|
53
|
+
def merge(other)
|
54
|
+
if other.is_a?(self.class)
|
55
|
+
new_list = @list.dup
|
56
|
+
self + (other - self)
|
57
|
+
else
|
58
|
+
fail Exceptions::InvalidInput
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Makes #model compatible with the server-side
|
63
|
+
def model
|
64
|
+
type
|
65
|
+
end
|
66
|
+
|
67
|
+
# Hacked together #or() method in the same spirit as #where().
|
68
|
+
# This method can be chained for multiple / more specific queries.
|
69
|
+
#
|
70
|
+
# @param attribute [Symbol] the attribute to query
|
71
|
+
# @param value [Object] the value to compare against
|
72
|
+
# @param comparison_method [String,Symbol] the method to use for comparison
|
73
|
+
# - allowed options are "'==', '!=', '>', '>=', '<', '<=', and 'match'"
|
74
|
+
# @raise [Exceptions::InvalidWhereQuery] if not the right kind of comparison
|
75
|
+
# @return [ResourceCollection]
|
76
|
+
def or(attribute, value, options = {})
|
77
|
+
options[:comparison] ||= '=='
|
78
|
+
if empty?
|
79
|
+
@type.where(attribute, value, comparison: options[:comparison], client: @client)
|
80
|
+
else
|
81
|
+
merge first.class.where(
|
82
|
+
attribute, value,
|
83
|
+
comparison: options[:comparison],
|
84
|
+
client: @client
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Pass pagination through to the Array (which passes to will_paginate)
|
90
|
+
def paginate(*args)
|
91
|
+
@list.paginate(*args)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns the number of Resource instances in the collection
|
95
|
+
# @return [Fixnum]
|
96
|
+
def size
|
97
|
+
@list.size
|
98
|
+
end
|
99
|
+
|
100
|
+
# Allow complex sorting like an Array
|
101
|
+
# @return [ResourceCollection] sorted collection
|
102
|
+
def sort(&block)
|
103
|
+
self.class.new(super(&block), type: @type, client: @client)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Horribly inefficient way to allow querying Resources by their attributes.
|
107
|
+
# This method can be chained for multiple / more specific queries.
|
108
|
+
#
|
109
|
+
# @param attribute [Symbol] the attribute to query
|
110
|
+
# @param value [Object] the value to compare against
|
111
|
+
# @param comparison_method [String,Symbol] the method to use for comparison
|
112
|
+
# - allowed options are "'==', '!=', '>', '>=', '<', '<=', and 'match'"
|
113
|
+
# @raise [Exceptions::InvalidWhereQuery] if not the right kind of comparison
|
114
|
+
# @return [ResourceCollection]
|
115
|
+
def where(attribute, value, options = {})
|
116
|
+
valid_comparisons = [:'==', :'!=', :>, :'>=', :<, :'<=', :match]
|
117
|
+
options[:comparison] ||= '=='
|
118
|
+
unless valid_comparisons.include?(options[:comparison].to_sym)
|
119
|
+
fail Exceptions::InvalidWhereQuery
|
120
|
+
end
|
121
|
+
self.class.new(
|
122
|
+
@list.collect do |item|
|
123
|
+
if item.send(attribute).nil?
|
124
|
+
nil
|
125
|
+
else
|
126
|
+
item if item.send(attribute).send(options[:comparison].to_sym, value)
|
127
|
+
end
|
128
|
+
end.compact,
|
129
|
+
type: @type,
|
130
|
+
client: @client
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
alias_method :and, :where
|
135
|
+
|
136
|
+
# Return the collection item at the specified index
|
137
|
+
# @return [Resource,ResourceCollection] the item at the requested index
|
138
|
+
def [](index)
|
139
|
+
if index.is_a?(Range)
|
140
|
+
self.class.new(@list[index], type: @type, client: @client)
|
141
|
+
else
|
142
|
+
@list[index]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Return a collection after subtracting from the original
|
147
|
+
# @return [ResourceCollection]
|
148
|
+
def -(other)
|
149
|
+
new_list = @list.dup
|
150
|
+
if other.respond_to?(:to_a)
|
151
|
+
other.to_a.each do |item|
|
152
|
+
new_list.delete_if { |res| res.id == item.id }
|
153
|
+
end
|
154
|
+
elsif other.is_a?(Resource)
|
155
|
+
new_list.delete_if { |res| res.id == other.id }
|
156
|
+
else
|
157
|
+
raise Exceptions::InvalidInput
|
158
|
+
end
|
159
|
+
self.class.new(new_list, type: @type, client: @client)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Return a collection after adding to the original
|
163
|
+
# Warning: this may cause duplicates or mixed type joins! For safety,
|
164
|
+
# use #merge
|
165
|
+
# @return [ResourceCollection]
|
166
|
+
def +(other)
|
167
|
+
if other.is_a?(self.class)
|
168
|
+
self.class.new(@list + other.to_a, type: @type, client: @client)
|
169
|
+
elsif other.is_a?(@type)
|
170
|
+
self.class.new(@list + [other], type: @type, client: @client)
|
171
|
+
else
|
172
|
+
fail Exceptions::InvalidInput
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def <<(other)
|
177
|
+
if other.class == @type
|
178
|
+
@list << other
|
179
|
+
else
|
180
|
+
fail Exceptions::InvalidInput
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def <=>(other)
|
185
|
+
collect(&:id).sort <=> other.collect(&:id).sort
|
186
|
+
end
|
187
|
+
|
188
|
+
# Allow comparison of collection
|
189
|
+
# @return [Boolean] do the collections contain the same resource ids?
|
190
|
+
def ==(other)
|
191
|
+
if other.is_a? self.class
|
192
|
+
collect(&:id).sort == other.collect(&:id).sort
|
193
|
+
else
|
194
|
+
false
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
module Antaeus
|
2
|
+
module Resources
|
3
|
+
class Appointment < Resource
|
4
|
+
property :arrival, type: :time
|
5
|
+
property :comment
|
6
|
+
property :contact
|
7
|
+
property :departure, type: :time
|
8
|
+
property :location_id
|
9
|
+
property :guest_id
|
10
|
+
property :created_at, read_only: true, type: :time
|
11
|
+
property :created_by, read_only: true
|
12
|
+
property :arrived?, read_only: true
|
13
|
+
property :approved?, read_only: true
|
14
|
+
property :departed?, read_only: true
|
15
|
+
property :checkin_time, read_only: true, type: :time
|
16
|
+
property :checkout_time, read_only: true, type: :time
|
17
|
+
|
18
|
+
path :all, '/appointments'
|
19
|
+
|
20
|
+
# A collection of all upcoming appointments
|
21
|
+
def self.upcoming(options = {})
|
22
|
+
validate_options(options)
|
23
|
+
ResourceCollection.new(
|
24
|
+
options[:client].get("#{path_for(:all)}/upcoming")['appointments'].collect do |record|
|
25
|
+
self.new(
|
26
|
+
entity: record,
|
27
|
+
lazy: true,
|
28
|
+
tainted: false,
|
29
|
+
client: options[:client]
|
30
|
+
)
|
31
|
+
end,
|
32
|
+
type: self,
|
33
|
+
client: options[:client]
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Generate a report of appointments based on some criteria
|
38
|
+
def self.report(options = {})
|
39
|
+
validate_options(options)
|
40
|
+
ResourceCollection.new(
|
41
|
+
options[:client].post("/reports/generate", q: options[:criteria])['appointments'].collect do |record|
|
42
|
+
self.new(
|
43
|
+
entity: record,
|
44
|
+
lazy: false,
|
45
|
+
tainted: false,
|
46
|
+
client: options[:client]
|
47
|
+
)
|
48
|
+
end,
|
49
|
+
type: self,
|
50
|
+
client: options[:client]
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Approve an Appointment
|
55
|
+
def approve
|
56
|
+
if @client.patch("#{path_for(:all)}/#{id}/approve", approve: true)
|
57
|
+
true
|
58
|
+
else
|
59
|
+
fail Exceptions::ApprovalChangeFailed
|
60
|
+
end
|
61
|
+
reload
|
62
|
+
return true
|
63
|
+
end
|
64
|
+
|
65
|
+
# Checkin a Guest
|
66
|
+
def checkin
|
67
|
+
if @client.patch("#{path_for(:all)}/#{id}/checkin", email: guest.email)
|
68
|
+
true
|
69
|
+
else
|
70
|
+
raise Exceptions::CheckinChangeFailed
|
71
|
+
end
|
72
|
+
reload
|
73
|
+
return true
|
74
|
+
end
|
75
|
+
|
76
|
+
# Checkout a Guest
|
77
|
+
def checkout
|
78
|
+
if @client.patch("#{path_for(:all)}/#{id}/checkout", email: guest.email)
|
79
|
+
true
|
80
|
+
else
|
81
|
+
raise Exceptions::CheckoutChangeFailed
|
82
|
+
end
|
83
|
+
reload
|
84
|
+
return true
|
85
|
+
end
|
86
|
+
|
87
|
+
# Hidden property used to lookup related resource
|
88
|
+
def guest
|
89
|
+
Guest.get(@entity['guest_id'], client: @client)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Set the guest associated with this appointment
|
93
|
+
def guest=(guest_or_guest_id)
|
94
|
+
@entity['guest_id'] = if guest_or_guest_id.is_a?(Guest)
|
95
|
+
guest_or_guest_id.id
|
96
|
+
else
|
97
|
+
guest_or_guest_id
|
98
|
+
end
|
99
|
+
@tainted = true
|
100
|
+
end
|
101
|
+
|
102
|
+
# Hidden property used to lookup related resource
|
103
|
+
def location
|
104
|
+
Location.get(@entity['location_id'], client: @client)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Set the location associated with this appointment
|
108
|
+
def location=(location_or_location_id)
|
109
|
+
@entity['location_id'] = if location_or_location_id.is_a?(Location)
|
110
|
+
location_or_location_id.id
|
111
|
+
else
|
112
|
+
location_or_location_id
|
113
|
+
end
|
114
|
+
@tainted = true
|
115
|
+
end
|
116
|
+
|
117
|
+
# Unapprove an Appointment
|
118
|
+
def unapprove
|
119
|
+
if @client.patch("#{path_for(:all)}/#{id}/approve", approve: false)
|
120
|
+
true
|
121
|
+
else
|
122
|
+
fail Exceptions::ApprovalChangeFailed
|
123
|
+
end
|
124
|
+
reload
|
125
|
+
return true
|
126
|
+
end
|
127
|
+
|
128
|
+
# Checkin a Guest
|
129
|
+
def undo_checkin
|
130
|
+
if @client.delete("#{path_for(:all)}/#{id}/checkin")
|
131
|
+
true
|
132
|
+
else
|
133
|
+
raise Exceptions::CheckinChangeFailed
|
134
|
+
end
|
135
|
+
reload
|
136
|
+
return true
|
137
|
+
end
|
138
|
+
|
139
|
+
# Checkout a Guest
|
140
|
+
def undo_checkout
|
141
|
+
if @client.delete("#{path_for(:all)}/#{id}/checkout")
|
142
|
+
true
|
143
|
+
else
|
144
|
+
raise Exceptions::CheckoutChangeFailed
|
145
|
+
end
|
146
|
+
reload
|
147
|
+
return true
|
148
|
+
end
|
149
|
+
|
150
|
+
# User related to an appointment
|
151
|
+
def user
|
152
|
+
User.get(contact, client: @client)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Set the user related to an appointment
|
156
|
+
def user=(username)
|
157
|
+
contact = if username.is_a?(User)
|
158
|
+
username.id
|
159
|
+
else
|
160
|
+
username
|
161
|
+
end
|
162
|
+
@tainted = true
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Antaeus
|
2
|
+
module Resources
|
3
|
+
class Group < Resource
|
4
|
+
delayed_property { Antaeus.config.group_name_attribute || :cn }
|
5
|
+
|
6
|
+
path :all, '/groups'
|
7
|
+
immutable true
|
8
|
+
|
9
|
+
def members
|
10
|
+
ResourceCollection.new(
|
11
|
+
@client.get("#{path_for(:all)}/#{id}/members")['users'].collect do |record|
|
12
|
+
User.new(
|
13
|
+
entity: record,
|
14
|
+
lazy: true,
|
15
|
+
tainted: false,
|
16
|
+
client: @client
|
17
|
+
)
|
18
|
+
end,
|
19
|
+
type: Antaeus::Resources::User,
|
20
|
+
client: @client
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
alias_method :users, :members
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Antaeus
|
2
|
+
module Resources
|
3
|
+
class Guest < Resource
|
4
|
+
property :email
|
5
|
+
property :full_name
|
6
|
+
property :phone
|
7
|
+
property :citizenship
|
8
|
+
property :need_nda
|
9
|
+
property :signed_nda
|
10
|
+
property :need_tcpa
|
11
|
+
property :signed_tcpa
|
12
|
+
property :pin
|
13
|
+
property :created_at, read_only: true, type: :time
|
14
|
+
|
15
|
+
path :all, '/guests'
|
16
|
+
|
17
|
+
def appointments
|
18
|
+
ResourceCollection.new(
|
19
|
+
@client.get("#{path_for(:all)}/#{id}/appointments")['appointments'].collect do |record|
|
20
|
+
Appointment.new(
|
21
|
+
entity: record,
|
22
|
+
lazy: true,
|
23
|
+
tainted: false,
|
24
|
+
client: @client
|
25
|
+
)
|
26
|
+
end,
|
27
|
+
type: Antaeus::Resources::Appointment,
|
28
|
+
client: @client
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def available_appointments(location)
|
33
|
+
upcoming_appointments.where(location: location)
|
34
|
+
end
|
35
|
+
|
36
|
+
def upcoming_appointments
|
37
|
+
Appointment.upcoming(client: client).where(:guest_id, id)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Antaeus
|
2
|
+
module Resources
|
3
|
+
class Hook < Resource
|
4
|
+
property :name
|
5
|
+
property :plugins
|
6
|
+
property :configurations
|
7
|
+
property :created_at, read_only: true, type: :time
|
8
|
+
|
9
|
+
path :all, '/hooks'
|
10
|
+
|
11
|
+
def self.all_available(options = {})
|
12
|
+
validate_options(options)
|
13
|
+
options[:client].get("#{path_for(:all)}/available")['available_hooks']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|