absorb_api 0.2.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +866 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/Gemfile +3 -10
- data/README.md +0 -2
- data/Rakefile +3 -1
- data/absorb_api.gemspec +30 -16
- data/bin/console +11 -5
- data/doc/AbsorbApi.html +33 -64
- data/doc/AbsorbApi/Api.html +358 -0
- data/doc/AbsorbApi/Authorize.html +263 -0
- data/doc/AbsorbApi/Category.html +3 -2
- data/doc/AbsorbApi/Certificate.html +3 -2
- data/doc/AbsorbApi/Chapter.html +3 -2
- data/doc/AbsorbApi/Collection.html +3 -2
- data/doc/AbsorbApi/Configuration.html +3 -28
- data/doc/AbsorbApi/Course.html +3 -71
- data/doc/AbsorbApi/CourseEnrollment.html +6 -58
- data/doc/AbsorbApi/Create.html +164 -0
- data/doc/AbsorbApi/Curriculum.html +3 -2
- data/doc/AbsorbApi/Department.html +4 -14
- data/doc/AbsorbApi/Lesson.html +3 -2
- data/doc/AbsorbApi/LessonEnrollment.html +3 -2
- data/doc/AbsorbApi/Prerequisite.html +3 -2
- data/doc/AbsorbApi/Record.html +360 -0
- data/doc/AbsorbApi/Relations.html +2 -196
- data/doc/AbsorbApi/Relations/ClassMethods.html +197 -0
- data/doc/AbsorbApi/Resource.html +3 -2
- data/doc/AbsorbApi/ResourceNotFound.html +2 -1
- data/doc/AbsorbApi/Role.html +3 -2
- data/doc/AbsorbApi/RouteNotFound.html +2 -1
- data/doc/AbsorbApi/SessionSchedule.html +3 -2
- data/doc/AbsorbApi/Tag.html +4 -14
- data/doc/AbsorbApi/User.html +85 -35
- data/doc/AbsorbApi/ValidationError.html +2 -1
- data/doc/AbsorbApi/Where.html +162 -0
- data/doc/CODE_OF_CONDUCT_md.html +196 -0
- data/doc/Gemfile.html +8 -8
- data/doc/Gemfile_lock.html +57 -29
- data/doc/Icon/r.html +96 -0
- data/doc/LICENSE_txt.html +6 -1
- data/doc/Object.html +159 -0
- data/doc/README_md.html +6 -3
- data/doc/Rakefile.html +7 -2
- data/doc/absorb_api_gemspec.html +24 -7
- data/doc/bin/setup.html +6 -1
- data/doc/created.rid +34 -30
- data/doc/css/fonts.css +6 -6
- data/doc/index.html +19 -4
- data/doc/js/darkfish.js +7 -7
- data/doc/js/search_index.js +1 -1
- data/doc/js/search_index.js.gz +0 -0
- data/doc/js/searcher.js +1 -0
- data/doc/js/searcher.js.gz +0 -0
- data/doc/table_of_contents.html +118 -31
- data/lib/absorb_api.rb +43 -29
- data/lib/absorb_api/api.rb +69 -5
- data/lib/absorb_api/authorize.rb +37 -7
- data/lib/absorb_api/category.rb +3 -1
- data/lib/absorb_api/certificate.rb +5 -2
- data/lib/absorb_api/chapter.rb +3 -1
- data/lib/absorb_api/collection.rb +2 -19
- data/lib/absorb_api/configuration.rb +14 -12
- data/lib/absorb_api/course.rb +11 -25
- data/lib/absorb_api/course_enrollment.rb +13 -26
- data/lib/absorb_api/create.rb +19 -0
- data/lib/absorb_api/curriculum.rb +11 -2
- data/lib/absorb_api/department.rb +10 -4
- data/lib/absorb_api/lesson.rb +5 -2
- data/lib/absorb_api/lesson_enrollment.rb +8 -2
- data/lib/absorb_api/prerequisite.rb +5 -2
- data/lib/absorb_api/record.rb +58 -0
- data/lib/absorb_api/relations.rb +42 -40
- data/lib/absorb_api/resource.rb +3 -1
- data/lib/absorb_api/role.rb +3 -1
- data/lib/absorb_api/session_schedule.rb +6 -2
- data/lib/absorb_api/tag.rb +6 -3
- data/lib/absorb_api/user.rb +13 -29
- data/lib/absorb_api/version.rb +3 -1
- data/lib/absorb_api/where.rb +17 -0
- metadata +133 -8
- data/lib/absorb_api/base.rb +0 -12
- data/lib/absorb_api/orm.rb +0 -36
data/lib/absorb_api/api.rb
CHANGED
@@ -1,15 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
4
|
class Api
|
3
|
-
|
5
|
+
attr_writer :connection
|
4
6
|
|
5
|
-
|
6
|
-
@token = AbsorbApi::Authorize.new.token
|
7
|
+
delegate :get, :put, :patch, :post, :delete, to: :connection
|
7
8
|
|
8
|
-
|
9
|
+
def connection
|
10
|
+
Faraday.new(
|
11
|
+
url: AbsorbApi.configuration.url,
|
12
|
+
parallel_manager: Typhoeus::Hydra.new(max_concurrency: 200)
|
13
|
+
) do |faraday|
|
9
14
|
faraday.request :json
|
10
15
|
faraday.response :json, content_type: /\bjson$/
|
11
16
|
faraday.adapter :typhoeus
|
12
|
-
faraday.headers = {
|
17
|
+
faraday.headers = { "Authorization" => AbsorbApi.token }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def get(path, params = {})
|
22
|
+
request(:get, path, params)
|
23
|
+
end
|
24
|
+
|
25
|
+
def put(path, params = {})
|
26
|
+
request(:put, path, params)
|
27
|
+
end
|
28
|
+
|
29
|
+
def patch(path, params = {})
|
30
|
+
request(:patch, path, params)
|
31
|
+
end
|
32
|
+
|
33
|
+
def post(path, params = {})
|
34
|
+
request(:post, path, params)
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(path, params = {})
|
38
|
+
request(:delete, path, params)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def request(http_method, path, params)
|
44
|
+
ignore_resource_not_found = params.delete(:ignore_resource_not_found)
|
45
|
+
response = connection.send(http_method, path, params)
|
46
|
+
handle_errored_response(response, ignore_resource_not_found)
|
47
|
+
|
48
|
+
if response.status == 401
|
49
|
+
response = fetch_new_token_and_try_again(http_method, path, params)
|
50
|
+
handle_errored_response(response, ignore_resource_not_found)
|
51
|
+
end
|
52
|
+
|
53
|
+
fetch_response_body(response, ignore_resource_not_found)
|
54
|
+
end
|
55
|
+
|
56
|
+
def fetch_new_token_and_try_again(http_method, path, params)
|
57
|
+
AbsorbApi.authorization = nil
|
58
|
+
connection.send(http_method, path, params)
|
59
|
+
end
|
60
|
+
|
61
|
+
def handle_errored_response(response, ignore_resource_not_found = false)
|
62
|
+
unless ignore_resource_not_found
|
63
|
+
raise RouteNotFound if [404, 405].include?(response.status)
|
64
|
+
raise ResourceNotFound if [400].include?(response.status)
|
65
|
+
end
|
66
|
+
|
67
|
+
raise ValidationError if [500].include?(response.status)
|
68
|
+
end
|
69
|
+
|
70
|
+
def fetch_response_body(response, ignore_resource_not_found = false)
|
71
|
+
return response.body unless ignore_resource_not_found
|
72
|
+
|
73
|
+
if [404, 405, 400].include?(response.status)
|
74
|
+
[]
|
75
|
+
else
|
76
|
+
response.body
|
13
77
|
end
|
14
78
|
end
|
15
79
|
end
|
data/lib/absorb_api/authorize.rb
CHANGED
@@ -1,17 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
4
|
class Authorize
|
3
|
-
|
5
|
+
attr_accessor :created_at
|
4
6
|
|
5
7
|
def initialize
|
6
|
-
|
8
|
+
token
|
9
|
+
end
|
10
|
+
|
11
|
+
def expired?
|
12
|
+
return true if created_at.blank?
|
13
|
+
|
14
|
+
DateTime.now >= created_at + 4.hours
|
15
|
+
end
|
16
|
+
|
17
|
+
def token
|
18
|
+
return @token unless expired?
|
19
|
+
|
20
|
+
@token = ActiveSupport::JSON.decode(connection.post do |req|
|
21
|
+
req.url "Authenticate"
|
22
|
+
req.headers["Content-Type"] = "application/json"
|
23
|
+
req.headers["accept"] = "json"
|
24
|
+
req.body = payload.to_json
|
25
|
+
end.body)
|
26
|
+
@created_at = DateTime.now
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def connection
|
32
|
+
Faraday.new(url: AbsorbApi.configuration.url) do |faraday|
|
7
33
|
faraday.request :url_encoded
|
8
34
|
faraday.response :logger
|
9
35
|
faraday.adapter :typhoeus
|
10
|
-
end
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def payload
|
40
|
+
{
|
41
|
+
"Username" => AbsorbApi.configuration.absorbuser,
|
42
|
+
"Password" => AbsorbApi.configuration.absorbpass,
|
43
|
+
"PrivateKey" => AbsorbApi.configuration.absorbkey
|
44
|
+
}
|
15
45
|
end
|
16
46
|
end
|
17
47
|
end
|
data/lib/absorb_api/category.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
|
-
class Certificate <
|
3
|
-
attr_accessor :id, :enrollment_id, :full_name, :course_name, :acquired_date,
|
4
|
+
class Certificate < Record
|
5
|
+
attr_accessor :id, :enrollment_id, :full_name, :course_name, :acquired_date,
|
6
|
+
:expiry_date, :notes
|
4
7
|
end
|
5
8
|
end
|
data/lib/absorb_api/chapter.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
4
|
class Collection < ::Array
|
3
5
|
attr_reader :metadata
|
@@ -6,24 +8,5 @@ module AbsorbApi
|
|
6
8
|
super(elements)
|
7
9
|
@metadata = metadata
|
8
10
|
end
|
9
|
-
|
10
|
-
# private
|
11
|
-
# def method_missing(method_name, *arguments, &block)
|
12
|
-
# if "AbsorbApi::#{metadata[:klass]}".constantize.new.respond_to? method_name
|
13
|
-
# collection = []
|
14
|
-
# Base.api.in_parallel do
|
15
|
-
# self.each do |object|
|
16
|
-
# collection << Base.api.get("#{metadata[:klass].to_s.pluralize}/#{object.id}/#{method_name}")
|
17
|
-
# end
|
18
|
-
# end
|
19
|
-
# collection.map { |response| response.body.map { |attrs| CourseEnrollment.new(attrs) } }.flatten
|
20
|
-
# else
|
21
|
-
# super
|
22
|
-
# end
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# def respond_to_missing?(method_name, include_private = false)
|
26
|
-
# self.first.respond_to? method_name || super
|
27
|
-
# end
|
28
11
|
end
|
29
12
|
end
|
@@ -1,21 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
4
|
class Configuration
|
3
|
-
attr_accessor :url, :absorbuser, :absorbpass, :absorbkey
|
5
|
+
attr_accessor :url, :absorbuser, :absorbpass, :absorbkey
|
4
6
|
end
|
5
7
|
|
6
|
-
|
7
|
-
attr_accessor :configuration
|
8
|
-
end
|
8
|
+
cattr_accessor :configuration
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
class << self
|
11
|
+
def configuration
|
12
|
+
@configuration ||= Configuration.new
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
def reset
|
16
|
+
@configuration = Configuration.new
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
def configure
|
20
|
+
yield(configuration)
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
data/lib/absorb_api/course.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
|
-
class Course <
|
3
|
-
|
4
|
+
class Course < Record
|
5
|
+
with_relationships
|
6
|
+
can_search
|
4
7
|
|
5
8
|
attr_accessor :id, :name, :description, :notes, :external_id, :access_date,
|
6
9
|
:expire_type, :expire_duration, :expiry_date, :active_status,
|
@@ -10,28 +13,11 @@ module AbsorbApi
|
|
10
13
|
:category_id, :certificate_url, :audience, :goals, :vendor,
|
11
14
|
:company_cost, :learner_cost, :company_time, :learner_time
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# gets all associated enrollments given a collection of courses
|
21
|
-
# all calls are called in parallel
|
22
|
-
def self.enrollments_from_collection(courses, **conditions)
|
23
|
-
enrollments = []
|
24
|
-
connection = AbsorbApi::Api.new.connection
|
25
|
-
courses.reject! do |course|
|
26
|
-
AbsorbApi.configuration.ignored_course_ids.include? course.id
|
27
|
-
end
|
28
|
-
|
29
|
-
connection.in_parallel do
|
30
|
-
courses.each do |course|
|
31
|
-
enrollments << connection.get("courses/#{course.id}/enrollments", conditions)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
enrollments.map { |response| response.body.map { |attrs| CourseEnrollment.new(attrs) } }.flatten
|
35
|
-
end
|
16
|
+
with_many :certificates
|
17
|
+
with_many :chapters
|
18
|
+
with_many :enrollments, :course_enrollment
|
19
|
+
with_many :resources
|
20
|
+
with_many :prerequisites
|
21
|
+
with_many :lessons
|
36
22
|
end
|
37
23
|
end
|
@@ -1,35 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
|
-
class CourseEnrollment <
|
3
|
-
attr_accessor :id, :course_id, :course_name, :course_version_id, :user_id,
|
4
|
+
class CourseEnrollment < Record
|
5
|
+
attr_accessor :id, :course_id, :course_name, :course_version_id, :user_id,
|
6
|
+
:full_name, :status, :progress, :score,
|
7
|
+
:accepted_terms_and_conditions, :time_spent, :date_started,
|
8
|
+
:date_completed, :enrollment_key_id, :certificate_id, :credits
|
4
9
|
|
5
10
|
def lessons(**conditions)
|
6
|
-
|
7
|
-
LessonEnrollment.new(
|
11
|
+
get(url, conditions.merge(ignore_resource_not_found: true)).map do |attrs|
|
12
|
+
LessonEnrollment.new(attrs)
|
8
13
|
end
|
9
14
|
end
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
def self.lessons_from_collection(course_enrollments, **filters)
|
16
|
-
lessons = []
|
17
|
-
connection = AbsorbApi::Api.new.connection
|
18
|
-
course_enrollments.each_slice(105) do |enrollment_slice|
|
19
|
-
connection.in_parallel do
|
20
|
-
enrollment_slice.each do |enrollment|
|
21
|
-
lessons << connection.get("users/#{enrollment.user_id}/enrollments/#{enrollment.course_id}/lessons", filters)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
lessons.map! do |response|
|
26
|
-
response.body.map do |body|
|
27
|
-
LessonEnrollment.new(body)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
lessons.flatten.reject do |lesson|
|
31
|
-
AbsorbApi.configuration.ignored_lesson_types.include? lesson.type
|
32
|
-
end
|
16
|
+
private
|
17
|
+
|
18
|
+
def url
|
19
|
+
"users/#{user_id}/enrollments/#{course_id}/lessons"
|
33
20
|
end
|
34
21
|
end
|
35
22
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AbsorbApi
|
4
|
+
module Create
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
class_methods do
|
8
|
+
def create(attributes = {})
|
9
|
+
object = new(attributes)
|
10
|
+
yield(object) if block_given?
|
11
|
+
|
12
|
+
attrs = object.as_json.transform_keys(&:camelize)
|
13
|
+
response = api.post(to_s.demodulize.pluralize.to_s, attrs)
|
14
|
+
object.id = response.body["Id"]
|
15
|
+
object
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,5 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
|
-
class Curriculum <
|
3
|
-
attr_accessor :is_pacing_enabled, :curriculum_group_ids, :id, :name,
|
4
|
+
class Curriculum < Record
|
5
|
+
attr_accessor :is_pacing_enabled, :curriculum_group_ids, :id, :name,
|
6
|
+
:description, :notes, :external_id, :access_date,
|
7
|
+
:expire_type, :expire_duration, :expiry_date, :active_status,
|
8
|
+
:tag_ids, :resource_ids, :editor_ids, :prices,
|
9
|
+
:competency_definition_ids, :prerequisite_course_ids,
|
10
|
+
:post_enrollment_course_ids, :allow_course_evaluation,
|
11
|
+
:category_id, :certificate_url, :audience, :goals, :vendor,
|
12
|
+
:company_cost, :learner_cost, :company_time, :learner_time
|
4
13
|
end
|
5
14
|
end
|
@@ -1,9 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
|
-
class Department <
|
3
|
-
|
4
|
+
class Department < Record
|
5
|
+
with_relationships
|
6
|
+
can_create
|
7
|
+
can_search
|
4
8
|
|
5
|
-
attr_accessor :id, :name, :use_department_contact_details, :company_name,
|
9
|
+
attr_accessor :id, :name, :use_department_contact_details, :company_name,
|
10
|
+
:phone_number, :email_address, :external_id, :parent_id,
|
11
|
+
:currency_id
|
6
12
|
|
7
|
-
|
13
|
+
with_one :parent, :department
|
8
14
|
end
|
9
15
|
end
|
data/lib/absorb_api/lesson.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
|
-
class Lesson <
|
3
|
-
attr_accessor :id, :chapter_id, :name, :description, :notes, :type, :width,
|
4
|
+
class Lesson < Record
|
5
|
+
attr_accessor :id, :chapter_id, :name, :description, :notes, :type, :width,
|
6
|
+
:height, :url, :use_popup, :passing_score, :weight, :ref_id
|
4
7
|
end
|
5
8
|
end
|
@@ -1,5 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
|
-
class LessonEnrollment <
|
3
|
-
attr_accessor :lesson_id, :chapter_enrollment_id, :type, :attempts,
|
4
|
+
class LessonEnrollment < Record
|
5
|
+
attr_accessor :lesson_id, :chapter_enrollment_id, :type, :attempts,
|
6
|
+
:failures, :last_attempt, :id, :course_enrollment_id,
|
7
|
+
:chapter_id, :session_id, :name, :user_id, :full_name,
|
8
|
+
:status, :progress, :score, :time_spent, :date_enrolled,
|
9
|
+
:date_started, :date_completed
|
4
10
|
end
|
5
11
|
end
|
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AbsorbApi
|
2
|
-
class Prerequisite <
|
3
|
-
attr_accessor :id, :name, :required_number, :prerequisite_type, :course_ids,
|
4
|
+
class Prerequisite < Record
|
5
|
+
attr_accessor :id, :name, :required_number, :prerequisite_type, :course_ids,
|
6
|
+
:competency_definition_ids
|
4
7
|
end
|
5
8
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AbsorbApi
|
4
|
+
class Record
|
5
|
+
delegate :connection, :get, :put, :patch, :post, :delete, to: :api
|
6
|
+
delegate :in_parallel, to: :connection
|
7
|
+
|
8
|
+
def initialize(params = {})
|
9
|
+
params.each do |attr, value|
|
10
|
+
next unless respond_to?("#{attr.to_s.underscore}=")
|
11
|
+
|
12
|
+
public_send("#{attr.to_s.underscore}=", value)
|
13
|
+
end
|
14
|
+
|
15
|
+
yield self if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def find(id)
|
20
|
+
raise ResourceNotFound if id.blank?
|
21
|
+
|
22
|
+
new(api.get("#{to_s.demodulize.pluralize}/#{id}"))
|
23
|
+
end
|
24
|
+
|
25
|
+
def all
|
26
|
+
objs = api.get(to_s.demodulize.pluralize).map do |attrs|
|
27
|
+
new(attrs)
|
28
|
+
end
|
29
|
+
|
30
|
+
Collection.new(objs, klass: to_s.demodulize)
|
31
|
+
end
|
32
|
+
|
33
|
+
def with_relationships
|
34
|
+
include Relations
|
35
|
+
end
|
36
|
+
|
37
|
+
def can_create
|
38
|
+
include Create
|
39
|
+
end
|
40
|
+
|
41
|
+
def can_search
|
42
|
+
include Where
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def api
|
48
|
+
AbsorbApi::Api.new
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def api
|
55
|
+
@api ||= AbsorbApi::Api.new
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|