absorb_api 0.2.0 → 0.9.1
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 +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
|