manabu 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/manabu.rb +5 -0
- data/lib/manabu/class_group.rb +93 -0
- data/lib/manabu/class_groups.rb +0 -0
- data/lib/manabu/client.rb +96 -0
- data/lib/manabu/connection/auth.rb +56 -0
- data/lib/manabu/connection/error.rb +10 -0
- data/lib/manabu/connection/transactor.rb +149 -0
- data/lib/manabu/course.rb +105 -0
- data/lib/manabu/courses.rb +35 -0
- data/lib/manabu/guardian.rb +20 -0
- data/lib/manabu/resource.rb +24 -0
- data/lib/manabu/student.rb +49 -0
- data/lib/manabu/students.rb +89 -0
- data/lib/manabu/syllabuses.rb +19 -0
- data/manabu.gemspec +21 -14
- metadata +125 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a9e858021472f03b2d532caf72061380aeabe89a644faae4471492496604ac48
|
4
|
+
data.tar.gz: 176b6bdba3acfb636ecd2c6d71b67e16ae6e833bc759d5b8cd2742b812171643
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 306735afa0cf37124823c0feb56e445822667423e6c2ad460d6a3781ce266944b840b5b9c2ec5eaaeb1fc639cdd8b6c0eed4fea400a894b8e79edf9dad962b14
|
7
|
+
data.tar.gz: 31653b603f44ed4a2c69cc4545eb4002f81e956cb2874b1f165710d8d9a3b5aa108fbd1c1ebf55730c6f78f55ca3076bfa7436aa9f04c500cd9e32e333161f9f
|
data/lib/manabu.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
module Manabu
|
2
|
+
class ClassGroup < Resource
|
3
|
+
|
4
|
+
class Enrollment
|
5
|
+
|
6
|
+
def initialize(client, attributes = {})
|
7
|
+
@client = client
|
8
|
+
@id = attributes.fetch(:id, @id)
|
9
|
+
@class_group_id = attributes.fetch(:class_group_id, @class_group_id)
|
10
|
+
@student_id = attributes.fetch(:student_id, @student_id)
|
11
|
+
@student = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def student
|
15
|
+
if @student
|
16
|
+
@student
|
17
|
+
else
|
18
|
+
@student = _fetch_student
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def _fetch_student
|
25
|
+
response = @client.get("students/#{@student_id}")
|
26
|
+
Manabu::Student.new(@client, response)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :id, :name, :grade, :homeroom, :notes_count,
|
31
|
+
:enrollments_count, :facility_id
|
32
|
+
|
33
|
+
def initialize(client, **info)
|
34
|
+
super
|
35
|
+
@students = []
|
36
|
+
@enrollments = []
|
37
|
+
end
|
38
|
+
|
39
|
+
def fill(**info)
|
40
|
+
@id = info.fetch(:id, @id)
|
41
|
+
@name = info.fetch(:name, @name)
|
42
|
+
@grade = info.fetch(:grade, @grade)
|
43
|
+
@homeroom = info.fetch(:homeroom, @homeroom)
|
44
|
+
@notes_count = info.fetch(:notes_count, @notes_count)
|
45
|
+
@enrollments_count = info.fetch(:enrollments_count, @enrollments_count)
|
46
|
+
@facility_id = info.fetch(:facility_id, @facility_id)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def students
|
51
|
+
if @students.any?
|
52
|
+
@students
|
53
|
+
else
|
54
|
+
@students = _fetch_students
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def enrollments
|
59
|
+
if @enrollments.any?
|
60
|
+
@enrollments
|
61
|
+
else
|
62
|
+
@enrollments = _fetch_enrollments
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_student(student, args = {})
|
67
|
+
response = @client.post("class_groups/#{id}/enrollments",
|
68
|
+
student_id: student.id
|
69
|
+
)
|
70
|
+
|
71
|
+
Enrollment.new(@client, response).tap do |enrollment|
|
72
|
+
@enrollments << enrollment
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def _fetch_students
|
79
|
+
response = @client.get("class_groups/#{id}/students")
|
80
|
+
response[:students].map do |student|
|
81
|
+
Manabu::Student.new(@client, student)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def _fetch_enrollments
|
86
|
+
response = @client.get("class_groups/#{id}/enrollments")
|
87
|
+
response[:enrollments].map do |enrollment|
|
88
|
+
Enrollment.new(@client, enrollment)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
File without changes
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require_relative 'connection/auth'
|
2
|
+
require_relative 'connection/transactor'
|
3
|
+
|
4
|
+
module Manabu
|
5
|
+
# General client interface which bundles together most client functionality
|
6
|
+
class Client
|
7
|
+
attr_accessor :auth, :transactor, :status
|
8
|
+
|
9
|
+
# Initializes with login details and passes options to all linked instances.
|
10
|
+
#
|
11
|
+
# == Parameters:
|
12
|
+
# username::
|
13
|
+
# The User Name or e-mail address
|
14
|
+
# password::
|
15
|
+
# The password for the given user
|
16
|
+
# host::
|
17
|
+
# The host URL
|
18
|
+
# port::
|
19
|
+
# The host port (default 80)
|
20
|
+
# options::
|
21
|
+
# A hash of options, such as:
|
22
|
+
# * force_secure_connection - (default true), set to false to disable HTTPS/SSL
|
23
|
+
# * transport_type - (default :msgpack), sets transport data type [:msgpack, :json]
|
24
|
+
def initialize(username, password, host, port = 80, **options)
|
25
|
+
@status = :initializing
|
26
|
+
@auth = Manabu::Connection::Auth.new(username, password, host, port, options)
|
27
|
+
if @auth.success?
|
28
|
+
@transactor = @auth.transactor
|
29
|
+
@status = :connected
|
30
|
+
else
|
31
|
+
@status = :failed
|
32
|
+
raise Error::Connection::Unauthorized
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Performs a GET against the API
|
37
|
+
#
|
38
|
+
# == Parameters:
|
39
|
+
# path::
|
40
|
+
# The API endpoint path
|
41
|
+
# args::
|
42
|
+
# An argument hash
|
43
|
+
#
|
44
|
+
# == Returns:
|
45
|
+
# The returned data as an object
|
46
|
+
def get(path, **args)
|
47
|
+
@transactor.get(path, args)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Performs a POST against the API
|
51
|
+
#
|
52
|
+
# == Parameters:
|
53
|
+
# path::
|
54
|
+
# The API endpoint path
|
55
|
+
# args::
|
56
|
+
# An argument hash
|
57
|
+
#
|
58
|
+
# == Returns:
|
59
|
+
# The returned data as an object
|
60
|
+
def post(path, **args)
|
61
|
+
@transactor.post(path, args)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Performs a PATCH against the API
|
65
|
+
#
|
66
|
+
# == Parameters:
|
67
|
+
# path::
|
68
|
+
# The API endpoint path
|
69
|
+
# args::
|
70
|
+
# An argument hash
|
71
|
+
#
|
72
|
+
# == Returns:
|
73
|
+
# The returned data as an object
|
74
|
+
def patch(path, **args)
|
75
|
+
@transactor.patch(path, args)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Performs a DELETE against the API
|
79
|
+
#
|
80
|
+
# == Parameters:
|
81
|
+
# path::
|
82
|
+
# The API endpoint path
|
83
|
+
# args::
|
84
|
+
# An argument hash
|
85
|
+
#
|
86
|
+
# == Returns:
|
87
|
+
# The returned data as an object
|
88
|
+
def delete(path, **args)
|
89
|
+
@transactor.delete(path, args)
|
90
|
+
end
|
91
|
+
|
92
|
+
# def inspect
|
93
|
+
# "#<Manabu::Client:#{object_id}>"
|
94
|
+
# end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative 'transactor'
|
2
|
+
|
3
|
+
module Manabu
|
4
|
+
module Connection
|
5
|
+
class Auth
|
6
|
+
attr_accessor :username, :host, :port, :connection, :transactor, :token, :refresh_token
|
7
|
+
|
8
|
+
def initialize(username, password, host, port, **options)
|
9
|
+
@username = username
|
10
|
+
@host = host
|
11
|
+
@port = port
|
12
|
+
@transactor = Transactor.new(host, port,
|
13
|
+
options.fetch(:force_secure_connection, true),
|
14
|
+
options.fetch(:transport_type, :msgpack),
|
15
|
+
options)
|
16
|
+
@connection = false
|
17
|
+
_authenticate(username, password)
|
18
|
+
|
19
|
+
ObjectSpace.define_finalizer(self, -> { @connection = false })
|
20
|
+
end
|
21
|
+
|
22
|
+
def success?()
|
23
|
+
@connection
|
24
|
+
end
|
25
|
+
|
26
|
+
def stop()
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def _authenticate(username, password)
|
31
|
+
response = @transactor.post("authenticate", username: username, password: password)
|
32
|
+
@connection = true
|
33
|
+
|
34
|
+
@token = response[:tokens][:auth_token]
|
35
|
+
@transactor.authorization = @token
|
36
|
+
|
37
|
+
_refresh(response[:tokens])
|
38
|
+
end
|
39
|
+
|
40
|
+
def _refresh(tokens)
|
41
|
+
@refresh_token = tokens[:refresh_token]
|
42
|
+
thread = Thread.new do
|
43
|
+
loop do
|
44
|
+
break unless @connection
|
45
|
+
sleep(120)
|
46
|
+
refresh_response = transactor.post("authenticate/refresh",
|
47
|
+
refresh_token: @refresh_token
|
48
|
+
)
|
49
|
+
@transactor.authorization = refresh_response[:tokens][:auth_token]
|
50
|
+
@refresh_token = refresh_response[:tokens][:refresh_token]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require 'typhoeus'
|
4
|
+
require 'typhoeus/adapters/faraday'
|
5
|
+
require 'json'
|
6
|
+
require 'msgpack'
|
7
|
+
require_relative 'error'
|
8
|
+
|
9
|
+
module Manabu
|
10
|
+
module Connection
|
11
|
+
# Handles transactions between server, abstracting the transport protocol and returning objects
|
12
|
+
class Transactor
|
13
|
+
attr_accessor :server_url, :server_port, :transport_type, :force_secure_connection, :status,
|
14
|
+
:api_version, :authorization
|
15
|
+
|
16
|
+
def initialize(server_url, server_port = 80, force_secure_connection = true,
|
17
|
+
transport_type = :msgpack, **options)
|
18
|
+
@server_url = server_url
|
19
|
+
@server_port = server_port
|
20
|
+
@transport_type = transport_type
|
21
|
+
@status = :unknown
|
22
|
+
@force_secure_connection = force_secure_connection
|
23
|
+
@options = options
|
24
|
+
@api_version = options[:api_version] || 1
|
25
|
+
connect
|
26
|
+
_check_server_status
|
27
|
+
end
|
28
|
+
|
29
|
+
def connect()
|
30
|
+
return @connection if @connection
|
31
|
+
@connection = Faraday.new do |conn|
|
32
|
+
conn.request :url_encoded
|
33
|
+
|
34
|
+
case @transport_type
|
35
|
+
when :msgpack
|
36
|
+
conn.headers['Accept'] = 'application/msgpack'
|
37
|
+
when :json
|
38
|
+
conn.headers['Accept'] = 'application/json'
|
39
|
+
else # someone messed up, defaulting to msgpack
|
40
|
+
@transport_type = :msgpack
|
41
|
+
conn.headers['Accept'] = 'application/msgpack'
|
42
|
+
end
|
43
|
+
|
44
|
+
conn.use FaradayMiddleware::FollowRedirects, limit: 5
|
45
|
+
conn.adapter :typhoeus
|
46
|
+
end
|
47
|
+
|
48
|
+
_kludge_windows if Gem.win_platform?
|
49
|
+
|
50
|
+
_check_server_status
|
51
|
+
end
|
52
|
+
|
53
|
+
# Gets data from the server
|
54
|
+
def get(endpoint, **args)
|
55
|
+
_define_action(:get, endpoint, args)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Sets data from the server
|
59
|
+
def post(endpoint, **args)
|
60
|
+
_define_action(:post, endpoint, args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def patch(endpoint, **args)
|
64
|
+
_define_action(:patch, endpoint, args)
|
65
|
+
end
|
66
|
+
|
67
|
+
def delete(endpoint, **args)
|
68
|
+
_define_action(:delete, endpoint, args)
|
69
|
+
end
|
70
|
+
|
71
|
+
def _define_action(action, endpoint, args)
|
72
|
+
response = connect.send(
|
73
|
+
action,
|
74
|
+
URI.encode(
|
75
|
+
"#{@protocol}://#{@server_url}:#{@server_port}/api/v#{@api_version}/#{endpoint}"),
|
76
|
+
args,
|
77
|
+
_header_hash
|
78
|
+
)
|
79
|
+
_status_raiser(response)
|
80
|
+
_datafy_response(response.body)
|
81
|
+
end
|
82
|
+
|
83
|
+
def _header_hash
|
84
|
+
Hash.new.tap do |h|
|
85
|
+
h['Authorization'] = authorization if authorization
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
def _status_raiser(response)
|
91
|
+
case response.status
|
92
|
+
when 200..299
|
93
|
+
return # don't raise
|
94
|
+
else
|
95
|
+
case @transport_type
|
96
|
+
when :msgpack
|
97
|
+
raise Error::UnprocessableEntity, _datafy_msgpack(response.body)
|
98
|
+
when :json
|
99
|
+
raise Error::UnprocessableEntity, _datafy_json(response.body)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def _datafy_response(body)
|
105
|
+
case @transport_type
|
106
|
+
when :msgpack
|
107
|
+
return _datafy_msgpack(body)
|
108
|
+
when :json
|
109
|
+
return _datafy_json(body)
|
110
|
+
end
|
111
|
+
|
112
|
+
body # Just return raw data if no transport type was specified...
|
113
|
+
end
|
114
|
+
|
115
|
+
def _datafy_msgpack(body)
|
116
|
+
MessagePack::DefaultFactory.register_type(0x00, Symbol)
|
117
|
+
MessagePack.unpack(body)
|
118
|
+
rescue
|
119
|
+
raise Manabu::Connection::Error::InvalidMsgPack, 'Malformed data from server!'
|
120
|
+
end
|
121
|
+
|
122
|
+
def _datafy_json(body)
|
123
|
+
JSON.parse(body, symbolize_names: true)
|
124
|
+
rescue JSON::ParseError
|
125
|
+
raise Manabu::Connection::Error::InvalidJSON, 'Malformed data from server!'
|
126
|
+
end
|
127
|
+
|
128
|
+
def _check_server_status
|
129
|
+
@protocol = 'https'
|
130
|
+
@status = get('status')[:status]
|
131
|
+
rescue Faraday::ConnectionFailed
|
132
|
+
unless @force_secure_connection
|
133
|
+
@protocol = 'http'
|
134
|
+
@status = get('status')[:status]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Windows doesn't supply us with the correct cacert.pem, so we force it
|
139
|
+
def _kludge_windows
|
140
|
+
cert_loc = "#{__dir__}/cacert.pem"
|
141
|
+
unless File.exist? cert_loc
|
142
|
+
response = @connection.get('http://curl.haxx.se/ca/cacert.pem')
|
143
|
+
File.open(cert_loc, 'wb') { |fp| fp.write(response.body) }
|
144
|
+
end
|
145
|
+
ENV['SSL_CERT_FILE'] = cert_loc
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Manabu
|
2
|
+
class Course < Resource
|
3
|
+
|
4
|
+
class Enrollment
|
5
|
+
|
6
|
+
attr_reader :seat_number
|
7
|
+
|
8
|
+
def initialize(client, attributes = {})
|
9
|
+
@client = client
|
10
|
+
@id = attributes.fetch(:id, @id)
|
11
|
+
@course_id = attributes.fetch(:course_id, @course_id)
|
12
|
+
@student_id = attributes.fetch(:student_id, @student_id)
|
13
|
+
@seat_number = attributes.fetch(:seat_number, @seat_number)
|
14
|
+
@student = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def student
|
18
|
+
if @student
|
19
|
+
@student
|
20
|
+
else
|
21
|
+
@student = _fetch_student
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def seat_number=(value)
|
26
|
+
# TODO: handle when seat is occupied by another student
|
27
|
+
# TODO: handle other errors (EG request was invalid, request timed out)
|
28
|
+
response = @client.patch("courses/#{@course_id}/enrollments/#{@id}", seat_number: value)
|
29
|
+
@seat_number = value
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def _fetch_student
|
35
|
+
response = @client.get("students/#{@student_id}")
|
36
|
+
Manabu::Student.new(@client, response)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :id, :name, :code, :notes_count, :students_count,
|
41
|
+
:enrollments_count, :facility_id, :syllbaus_id
|
42
|
+
|
43
|
+
def initialize(client, **info)
|
44
|
+
super
|
45
|
+
@students = []
|
46
|
+
@enrollments = []
|
47
|
+
end
|
48
|
+
|
49
|
+
def fill(**info)
|
50
|
+
@id = info.fetch(:id, @id)
|
51
|
+
@name = info.fetch(:name, @name)
|
52
|
+
@code = info.fetch(:code, @code)
|
53
|
+
@notes_count = info.fetch(:notes_count, @notes_count)
|
54
|
+
@students_count = info.fetch(:students_count, @students_count)
|
55
|
+
@enrollments_count = info.fetch(:enrollments_count, @enrollments_count)
|
56
|
+
@facility_id = info.fetch(:facility_id, @facility_id)
|
57
|
+
@syllabus_id = info.fetch(:syllabus_id, @syllabus_id)
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def students
|
62
|
+
if @students.any?
|
63
|
+
@students
|
64
|
+
else
|
65
|
+
@students = _fetch_students
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def enrollments
|
70
|
+
if @enrollments.any?
|
71
|
+
@enrollments
|
72
|
+
else
|
73
|
+
@enrollments = _fetch_enrollments
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_student(student, args = {})
|
78
|
+
response = @client.post("courses/#{id}/enrollments",
|
79
|
+
student_id: student.id,
|
80
|
+
seat_number: args[:seat_number]
|
81
|
+
)
|
82
|
+
|
83
|
+
Enrollment.new(@client, response).tap do |enrollment|
|
84
|
+
@enrollments << enrollment
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def _fetch_students
|
91
|
+
response = @client.get("courses/#{id}/students")
|
92
|
+
response[:students].map do |student|
|
93
|
+
Manabu::Student.new(@client, student)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def _fetch_enrollments
|
98
|
+
response = @client.get("courses/#{id}/enrollments")
|
99
|
+
response[:enrollments].map do |enrollment|
|
100
|
+
Enrollment.new(@client, enrollment)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'client'
|
2
|
+
|
3
|
+
module Manabu
|
4
|
+
class Courses
|
5
|
+
def initialize(client)
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
def index
|
10
|
+
# TODO format object
|
11
|
+
@client.get('courses')
|
12
|
+
end
|
13
|
+
|
14
|
+
def register(course)
|
15
|
+
case course
|
16
|
+
when Manabu::Course
|
17
|
+
return register_course_by_object(course)
|
18
|
+
when Hash
|
19
|
+
return register_course_by_hash(course)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def register_course_by_object(course)
|
24
|
+
res = @client.post('courses', course.to_hash)
|
25
|
+
# TODO: handle errors
|
26
|
+
course.fill(res)
|
27
|
+
end
|
28
|
+
|
29
|
+
def register_course_by_hash(course)
|
30
|
+
res = @client.post('courses', course)
|
31
|
+
# TODO: handle errors
|
32
|
+
Manabu::Course.new(@client, res)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative './resource'
|
2
|
+
|
3
|
+
module Manabu
|
4
|
+
class Guardian < Resource
|
5
|
+
attr_accessor :id, :surname, :name, :name_reading, :surname_reading, :birth_date, :gender
|
6
|
+
|
7
|
+
def fill(**info)
|
8
|
+
@id = info.fetch(:id, @id)
|
9
|
+
@surname = info.fetch(:surname, @surname)
|
10
|
+
@name = info.fetch(:name, @name)
|
11
|
+
@name_reading = info.fetch(:name_reading, @name_reading)
|
12
|
+
@surname_reading = info.fetch(:surname_reading, @surname_reading)
|
13
|
+
@birth_date = info.fetch(:birth_date, @birth_date)
|
14
|
+
@gender = info.fetch(:gender, @gender)
|
15
|
+
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Manabu
|
2
|
+
class Resource
|
3
|
+
def initialize(client, **info)
|
4
|
+
@client = client
|
5
|
+
fill(info)
|
6
|
+
end
|
7
|
+
|
8
|
+
def fill(**info)
|
9
|
+
end
|
10
|
+
|
11
|
+
def _fill(var, sym, hash)
|
12
|
+
var = hash[sym] if (hash.include?(sym) && !hash[sym].nil?)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_hash
|
16
|
+
hash = {}
|
17
|
+
instance_variables.each do |var|
|
18
|
+
iv = instance_variable_get(var)
|
19
|
+
hash[(var.to_s.delete("@")).to_sym] = iv if !iv.nil?
|
20
|
+
end
|
21
|
+
hash
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative './resource'
|
2
|
+
require_relative './guardian'
|
3
|
+
|
4
|
+
module Manabu
|
5
|
+
class Student < Resource
|
6
|
+
class GuardianNotAdded < StandardError; end
|
7
|
+
attr_accessor :id, :surname, :name, :name_reading,
|
8
|
+
:surname_reading, :birth_date, :gender
|
9
|
+
|
10
|
+
def fill(**info)
|
11
|
+
@id = info.fetch(:id, @id)
|
12
|
+
@surname = info.fetch(:surname, @surname)
|
13
|
+
@name = info.fetch(:name, @name)
|
14
|
+
@name_reading = info.fetch(:name_reading, @name_reading)
|
15
|
+
@surname_reading = info.fetch(:surname_reading, @surname_reading)
|
16
|
+
@birth_date = info.fetch(:birth_date, @birth_date)
|
17
|
+
@gender = info.fetch(:gender, @gender)
|
18
|
+
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def set(**info)
|
23
|
+
response = @client.patch("students/#{@id}", info)
|
24
|
+
fill(response)
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_guardian(guardian)
|
28
|
+
# NOTE: detect when guardian is already added to student
|
29
|
+
response = @client.post("students/#{id}/student_guardians", guardian_id: guardian.id)
|
30
|
+
self
|
31
|
+
rescue StandardError
|
32
|
+
raise GuardianNotAdded, 'Guardian is not added to student'
|
33
|
+
end
|
34
|
+
|
35
|
+
def guardians
|
36
|
+
response = @client.get("students/#{id}/guardians")
|
37
|
+
response[:guardians].map do |guardian|
|
38
|
+
Manabu::Guardian.new(@client, guardian)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def courses
|
43
|
+
response = @client.get("students/#{id}/courses")
|
44
|
+
response[:courses].map do |course|
|
45
|
+
Manabu::Course.new(@client, course)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require_relative 'client'
|
2
|
+
require_relative 'student'
|
3
|
+
|
4
|
+
module Manabu
|
5
|
+
# Handles the student index for the given client
|
6
|
+
class Students
|
7
|
+
# Initializes against the passed client instance. If the client instance does not
|
8
|
+
# contain a client with a valid authorization all methods will return nil.
|
9
|
+
#
|
10
|
+
# == Parameters:
|
11
|
+
# client::
|
12
|
+
# A Manabu::Client instance (with a valid authorization)
|
13
|
+
def initialize(client)
|
14
|
+
@client = client
|
15
|
+
@students = []
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns a roster of all students which the client user has access to.
|
19
|
+
#
|
20
|
+
# == Parameters:
|
21
|
+
# filters:
|
22
|
+
# A hash of filters to narrow down results. Available filters include:
|
23
|
+
# * enrollment_status - [] TODO fill in enrollment statuses
|
24
|
+
def roster(**filters)
|
25
|
+
# TODO: handle errors
|
26
|
+
# TODO: handle filters in API endpoint
|
27
|
+
# NOTE: cache results
|
28
|
+
return students if filters.empty?
|
29
|
+
|
30
|
+
students.select do |student|
|
31
|
+
filters.slice(*whitelist_filter_attributes).all? do |filter, value|
|
32
|
+
student.send(filter) == value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def register(student)
|
38
|
+
new_student = case student
|
39
|
+
when Manabu::Student
|
40
|
+
register_student_by_object(student)
|
41
|
+
when Hash
|
42
|
+
register_student_by_hash(student)
|
43
|
+
end
|
44
|
+
new_student.tap { |object| @students << object }
|
45
|
+
end
|
46
|
+
|
47
|
+
def register_student_by_object(student)
|
48
|
+
res = @client.post('students', student.to_hash)
|
49
|
+
# TODO: handle errors
|
50
|
+
student.fill(res)
|
51
|
+
end
|
52
|
+
|
53
|
+
def register_student_by_hash(student)
|
54
|
+
res = @client.post('students', student)
|
55
|
+
# TODO: handle errors
|
56
|
+
Manabu::Student.new(@client, res)
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete(student)
|
60
|
+
@client.delete("students/#{student.id}")
|
61
|
+
@students.reject! { |object| object.id == student.id }
|
62
|
+
# NOTE: check in response when implement error object
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def students()
|
69
|
+
if @students.any?
|
70
|
+
@students
|
71
|
+
else
|
72
|
+
@students = _fetch_students
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def whitelist_filter_attributes()
|
77
|
+
[:name, :surname]
|
78
|
+
end
|
79
|
+
|
80
|
+
def _fetch_students()
|
81
|
+
# TODO raise error if @client is nil
|
82
|
+
response = @client.get('students')
|
83
|
+
response[:students].map do |student|
|
84
|
+
Manabu::Student.new(@client, student)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'client'
|
2
|
+
|
3
|
+
module Manabu
|
4
|
+
class Syllabuses
|
5
|
+
def initialize(client)
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
def index
|
10
|
+
# TODO format object
|
11
|
+
@client.get('syllabuses')
|
12
|
+
end
|
13
|
+
|
14
|
+
def register(attributes = {})
|
15
|
+
@client.post('syllabuses', attributes)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/manabu.gemspec
CHANGED
@@ -1,22 +1,29 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
|
-
s.name
|
3
|
-
s.version
|
4
|
-
s.licenses
|
5
|
-
s.summary
|
6
|
-
s.description
|
7
|
-
' Engine is a highly customizable Open Source School Management System. ' +
|
2
|
+
s.name = 'manabu'
|
3
|
+
s.version = '0.0.3'
|
4
|
+
s.licenses = ['AGPL-3.0', 'GPL-3.0']
|
5
|
+
s.summary = 'API client for GAKU Engine'
|
6
|
+
s.description = 'Manabu is an API client module used to access the GAKU Engine API'
|
8
7
|
s.post_install_message = \
|
9
8
|
'╔═════════════════════════╼' +
|
10
|
-
"║Manabu for ⚙学 GAKU Engine [学エンジン] " +
|
9
|
+
"║Manabu API Client for ⚙学 GAKU Engine [学エンジン] " +
|
11
10
|
'╟─────────────────────────╼' +
|
12
|
-
'║©2015
|
11
|
+
'║©2015 (株)幻創社 [Phantom Creation Inc.]' +
|
13
12
|
'║http://www.gakuengine.com' +
|
14
13
|
'╟─────────────────────────╼' +
|
15
|
-
'║Manabu is Open Sourced under the
|
14
|
+
'║Manabu is Open Sourced under the AGPLv3/GPLv3.' +
|
16
15
|
'╚═════════════════════════╼'
|
17
|
-
s.
|
18
|
-
s.
|
19
|
-
s.
|
20
|
-
|
21
|
-
s.
|
16
|
+
s.authors = ['Rei Kagetsuki']
|
17
|
+
s.email = 'info@gakuengine.com'
|
18
|
+
s.homepage = 'http://www.gakuengine.com'
|
19
|
+
|
20
|
+
s.files = Dir.glob('lib/**/*.rb') +
|
21
|
+
['manabu.gemspec']
|
22
|
+
s.require_paths = ['lib']
|
23
|
+
|
24
|
+
s.add_dependency 'faraday', '~> 0.13', '~> 0.13.1'
|
25
|
+
s.add_dependency 'faraday_middleware', '~> 0.12', '~> 0.12.2'
|
26
|
+
s.add_dependency 'typhoeus', '~> 1.3', '~> 1.3.0'
|
27
|
+
s.add_dependency 'msgpack', '~> 1.2', '~> 1.2.2'
|
28
|
+
s.add_development_dependency 'gaku', '~> 0.3.0', '~> 0.3.0.pre.4'
|
22
29
|
end
|
metadata
CHANGED
@@ -1,32 +1,144 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: manabu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rei Kagetsuki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
date: 2018-02-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.13'
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.13.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.13'
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.13.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: faraday_middleware
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.12'
|
40
|
+
- - "~>"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.12.2
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0.12'
|
50
|
+
- - "~>"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.12.2
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: typhoeus
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.3'
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.3.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.3'
|
70
|
+
- - "~>"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.3.0
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: msgpack
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '1.2'
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.2.2
|
83
|
+
type: :runtime
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.2'
|
90
|
+
- - "~>"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 1.2.2
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: gaku
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 0.3.0
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.3.0.pre.4
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.3.0
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 0.3.0.pre.4
|
113
|
+
description: Manabu is an API client module used to access the GAKU Engine API
|
17
114
|
email: info@gakuengine.com
|
18
115
|
executables: []
|
19
116
|
extensions: []
|
20
117
|
extra_rdoc_files: []
|
21
118
|
files:
|
119
|
+
- lib/manabu.rb
|
120
|
+
- lib/manabu/class_group.rb
|
121
|
+
- lib/manabu/class_groups.rb
|
122
|
+
- lib/manabu/client.rb
|
123
|
+
- lib/manabu/connection/auth.rb
|
124
|
+
- lib/manabu/connection/error.rb
|
125
|
+
- lib/manabu/connection/transactor.rb
|
126
|
+
- lib/manabu/course.rb
|
127
|
+
- lib/manabu/courses.rb
|
128
|
+
- lib/manabu/guardian.rb
|
129
|
+
- lib/manabu/resource.rb
|
130
|
+
- lib/manabu/student.rb
|
131
|
+
- lib/manabu/students.rb
|
132
|
+
- lib/manabu/syllabuses.rb
|
22
133
|
- manabu.gemspec
|
23
134
|
homepage: http://www.gakuengine.com
|
24
135
|
licenses:
|
25
|
-
-
|
136
|
+
- AGPL-3.0
|
137
|
+
- GPL-3.0
|
26
138
|
metadata: {}
|
27
|
-
post_install_message: "╔═════════════════════════╼║Manabu for ⚙学 GAKU Engine
|
28
|
-
╟─────────────────────────╼║©2015
|
29
|
-
is Open Sourced under the
|
139
|
+
post_install_message: "╔═════════════════════════╼║Manabu API Client for ⚙学 GAKU Engine
|
140
|
+
[学エンジン] ╟─────────────────────────╼║©2015 (株)幻創社 [Phantom Creation Inc.]║http://www.gakuengine.com╟─────────────────────────╼║Manabu
|
141
|
+
is Open Sourced under the AGPLv3/GPLv3.╚═════════════════════════╼"
|
30
142
|
rdoc_options: []
|
31
143
|
require_paths:
|
32
144
|
- lib
|
@@ -42,8 +154,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
42
154
|
version: '0'
|
43
155
|
requirements: []
|
44
156
|
rubyforge_project:
|
45
|
-
rubygems_version: 2.
|
157
|
+
rubygems_version: 2.7.3
|
46
158
|
signing_key:
|
47
159
|
specification_version: 4
|
48
|
-
summary:
|
160
|
+
summary: API client for GAKU Engine
|
49
161
|
test_files: []
|