magister 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/magister/authenticator.rb +31 -2
- data/lib/magister/data.rb +31 -1
- data/lib/magister/profile.rb +34 -3
- data/lib/magister/types/class.rb +253 -0
- data/lib/magister/types/classroom.rb +20 -0
- data/lib/magister/types/grade.rb +124 -0
- data/lib/magister/types/person.rb +138 -0
- data/lib/magister/types/subject.rb +31 -0
- data/lib/magister/types/teacher.rb +46 -0
- data/lib/magister.rb +36 -3
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d4013917db1501eda0924a787e95db303ea9d7a3db6a460e44195b3acab37d9
|
4
|
+
data.tar.gz: 83bb2ccd6c25a015d7b658bbe3a39c3321d5d083f87a4ee82e8916bebffc6712
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e140dfad3980e5940557361bc319aaedc2270dbfa336fdccb73a776d9e6ccb25d84ffe686e5b739aed86d7ecdd0189a4b42c5ba818c30e95478953d3ad0bf7c1
|
7
|
+
data.tar.gz: 9b0f53e39c5baa249e70811390475583613b4727ab9f9cda45d7e5e501b834dc118d331377a605bd4a0ffde7739c83cf141a9381ae90d23bbbe76a5ea0413d90
|
@@ -1,17 +1,24 @@
|
|
1
1
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
2
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
3
|
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
-
require '
|
4
|
+
require 'magister/profile'
|
5
5
|
require 'net/http'
|
6
6
|
require 'json'
|
7
7
|
require 'securerandom'
|
8
8
|
require 'base64'
|
9
9
|
require 'digest'
|
10
10
|
require 'selenium-webdriver'
|
11
|
+
require 'time'
|
11
12
|
|
13
|
+
# A module used to authenticate a user with the magister api.
|
12
14
|
module Authenticator
|
13
15
|
extend self
|
14
16
|
|
17
|
+
# Log in with username and password
|
18
|
+
# @param username [String] The username, usually in the form of a "leerlingnummer"
|
19
|
+
# @param password [String] The users password
|
20
|
+
# @param school [String] The school the user attends
|
21
|
+
# @since 1.1.0
|
15
22
|
def login(username, password, school)
|
16
23
|
# uri = URI("https://#{school}.magister.net/oidc_config.js")
|
17
24
|
# http = Net::HTTP.new(uri.host, uri.port)
|
@@ -21,6 +28,19 @@ module Authenticator
|
|
21
28
|
# oidc_conf = (response.body.split("config =").last.split("};").first.gsub("window.location.hostname", "'" + uri.hostname + "'") + "}").gsub(': ', '":').gsub(/,(\s*)/, ',"').gsub(/{(\s*)/, '{"').gsub("'", '"').gsub('" + "', "")
|
22
29
|
|
23
30
|
# oidc_conf = JSON.parse(oidc_conf)
|
31
|
+
if $magister_useCache && File.exist?($magister_cachingDirectory + "/auth.json")
|
32
|
+
f = File.open($magister_cachingDirectory + "/auth.json")
|
33
|
+
cached_data = f.read
|
34
|
+
cached_data = JSON.parse(cached_data)
|
35
|
+
expires = Time.at(cached_data["expires"].to_i)
|
36
|
+
puts "attempting to use cached token..."
|
37
|
+
if expires.to_i > Time.now.to_i
|
38
|
+
puts "using cached token."
|
39
|
+
return Profile.new(cached_data["token"], school)
|
40
|
+
else
|
41
|
+
puts "cached token expired."
|
42
|
+
end
|
43
|
+
end
|
24
44
|
|
25
45
|
codeVerifier = SecureRandom.alphanumeric(128)
|
26
46
|
verifier = Base64.urlsafe_encode64(codeVerifier)
|
@@ -34,6 +54,7 @@ module Authenticator
|
|
34
54
|
auth_uri = "https://#{school}.magister.net/connect/authorize?client_id=M6LOAPP&redirect_uri=m6loapp%3A%2F%2Foauth2redirect%2F&scope=openid%20profile%20opp.read%20opp.manage%20attendance.overview%20attendance.administration%20calendar.ical.user%20calendar.to-do.user%20grades.read%20grades.manage&state=#{@@state}&nonce=#{@@nonce}&code_challenge=#{challenge}&code_challenge_method=S256&prompt=select_account"
|
35
55
|
# puts "using authentication url #{auth_uri}"
|
36
56
|
|
57
|
+
token = ""
|
37
58
|
if $authMode == "local"
|
38
59
|
raise NotImplementedError.new("\n\nLocal authentication mode has not been implemented yet, \nCheck our github for any updates, or if you want to help implementing it!\n")
|
39
60
|
else
|
@@ -63,11 +84,19 @@ module Authenticator
|
|
63
84
|
wait = Selenium::WebDriver::Wait.new(timeout: 30)
|
64
85
|
wait.until { driver.current_url.start_with? "https://#{school}.magister.net/oidc/redirect_callback.html" }
|
65
86
|
|
87
|
+
expires_in = driver.current_url.split("expires_in=").last.split("&").first.to_i
|
88
|
+
expires = Time.now + expires_in
|
66
89
|
token = driver.current_url.split("access_token=").last.split("&").first
|
67
90
|
|
68
91
|
driver.quit
|
92
|
+
end
|
69
93
|
|
70
|
-
|
94
|
+
if $magister_useCache
|
95
|
+
if $magister_cacheType == "json"
|
96
|
+
File.write($magister_cachingDirectory + "/auth.json", "{\"token\": \"#{token}\", \"expires\": \"#{expires.to_i}\"}")
|
97
|
+
end
|
71
98
|
end
|
99
|
+
|
100
|
+
return Profile.new(token, school)
|
72
101
|
end
|
73
102
|
end
|
data/lib/magister/data.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
2
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
3
|
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
+
require 'magister/types/class'
|
5
|
+
require 'magister/types/grade'
|
4
6
|
require 'date'
|
7
|
+
require 'json'
|
5
8
|
|
9
|
+
# Validates a date
|
10
|
+
# @param date [String]
|
11
|
+
# @return [Boolean]
|
12
|
+
# @see get_classes
|
6
13
|
def validate_date(date)
|
7
14
|
format = '%Y-%m-%d'
|
8
15
|
DateTime.strptime(date, format)
|
@@ -11,12 +18,35 @@ rescue ArgumentError
|
|
11
18
|
false
|
12
19
|
end
|
13
20
|
|
21
|
+
# Functions for getting or setting data from/to the magister apis
|
14
22
|
module MagisterData
|
23
|
+
# Get all the scheduled classes between 2 dates
|
24
|
+
# @param dateFrom [String] the start of the selection
|
25
|
+
# @param dateTo [String] the end of the selection
|
26
|
+
# @since 1.0.0
|
15
27
|
def get_classes(dateFrom, dateTo)
|
16
28
|
if validate_date(dateFrom) && validate_date(dateTo)
|
17
|
-
@profile.authenticatedRequest("/personen/{*id*}/afspraken?status=1&van=#{dateFrom}&tot=#{dateTo}")
|
29
|
+
data = @profile.authenticatedRequest("/personen/{*id*}/afspraken?status=1&van=#{dateFrom}&tot=#{dateTo}")
|
30
|
+
classes = Array.new
|
31
|
+
data["Items"].each do |classItem|
|
32
|
+
classes.push MagClass.new(classItem)
|
33
|
+
end
|
34
|
+
classes
|
18
35
|
else
|
19
36
|
puts "Invalid date, Format is yyyy-mm-dd"
|
20
37
|
end
|
21
38
|
end
|
39
|
+
|
40
|
+
# Get a certain ammount of grades.
|
41
|
+
# @param count [String] The ammount of grades to get
|
42
|
+
# @param page [String] What page to get from
|
43
|
+
# @since 1.1.0
|
44
|
+
def get_grades(count = 5, page = 0)
|
45
|
+
data = @profile.authenticatedRequest("/personen/{*id*}/cijfers/laatste?top=#{count}&skip=#{count * page}")
|
46
|
+
grades = Array.new
|
47
|
+
data["items"].each do |grade|
|
48
|
+
grades.push Grade.new(grade)
|
49
|
+
end
|
50
|
+
grades
|
51
|
+
end
|
22
52
|
end
|
data/lib/magister/profile.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
2
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
3
|
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
+
require 'magister/types/person'
|
4
5
|
require 'uri'
|
5
6
|
require 'net/http'
|
6
7
|
require 'json'
|
7
8
|
|
9
|
+
# This represents a profile or a user in magister
|
8
10
|
class Profile
|
11
|
+
# Returns a new instance of Profile.
|
12
|
+
# @param token [String] the users token
|
13
|
+
# @param school [String] the school the user attends
|
14
|
+
# @since 1.1.0
|
9
15
|
def initialize(token, school)
|
10
16
|
@token = token
|
11
17
|
@id = 0
|
@@ -13,23 +19,41 @@ class Profile
|
|
13
19
|
@person = nil
|
14
20
|
end
|
15
21
|
|
22
|
+
# Set the user token
|
23
|
+
# @param token [String] new token
|
24
|
+
# @since 1.1.0
|
16
25
|
def token=(token)
|
17
26
|
@token=token
|
18
27
|
end
|
28
|
+
# Get the user id
|
29
|
+
# @return [Integer] id
|
30
|
+
# @since 1.0.0
|
19
31
|
def id
|
20
32
|
@id
|
21
33
|
end
|
34
|
+
# What school the user attends
|
35
|
+
# @return [String] name of the school
|
36
|
+
# @since 1.0.0
|
22
37
|
def school
|
23
38
|
@school
|
24
39
|
end
|
40
|
+
# Get a summary of the object
|
41
|
+
# @return [String] the summary
|
42
|
+
# @since 1.0.0
|
25
43
|
def inspect
|
26
44
|
"#<#{self.class}:0x#{object_id} @token=\"[PRIVATE]\", @id=#{@id}, @school=#{@school}>"
|
27
45
|
end
|
28
46
|
|
47
|
+
# Get the person of the profile
|
48
|
+
# @return [Person] the person
|
49
|
+
# @since 1.0.0
|
29
50
|
def person
|
30
51
|
@person
|
31
52
|
end
|
32
53
|
|
54
|
+
# Verify the authenticity of the token and obtain user data
|
55
|
+
# @note +token+ and +school+ of the #Profile must be defined
|
56
|
+
# @since 1.0.0
|
33
57
|
def verify()
|
34
58
|
if @school == nil || @token == nil
|
35
59
|
puts "Either school or token was not defined!"
|
@@ -45,9 +69,9 @@ class Profile
|
|
45
69
|
response = http.request(request)
|
46
70
|
if response.is_a?(Net::HTTPSuccess)
|
47
71
|
res = JSON.parse(response.body)
|
48
|
-
@person = res["Persoon"]
|
49
|
-
@id = person
|
50
|
-
puts "Succesfully authenticated as #{@person
|
72
|
+
@person = Person.new res["Persoon"]
|
73
|
+
@id = @person.id.to_i
|
74
|
+
puts "Succesfully authenticated as #{@person.firstName} with id #{@person.id}"
|
51
75
|
else
|
52
76
|
puts "Failed to authenticate, http code #{response.code}"
|
53
77
|
end
|
@@ -56,6 +80,13 @@ class Profile
|
|
56
80
|
end
|
57
81
|
end
|
58
82
|
|
83
|
+
# Makes a request that is authenticated on the users behalve.
|
84
|
+
# @param endpoint [String] the endpoint to request (starting with slash, excluding /api)
|
85
|
+
# @note if you put +{*id*}+ in the endpoint, it will be replaced by the users actual id.
|
86
|
+
# @return [Hash] the response given by the magister api.
|
87
|
+
# @example make a request to +https://SCHOOL.magister.net/api/sessions/current+ to get information about the current session (+profile+ is an instance of +Profile+)
|
88
|
+
# sessionInfo = profile.authenticatedRequest("/sessions/current")
|
89
|
+
# @since 1.0.0
|
59
90
|
def authenticatedRequest(endpoint)
|
60
91
|
if @id == 0
|
61
92
|
puts "Not yet authenticated!"
|
@@ -0,0 +1,253 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
+
require "magister/types/classroom.rb"
|
5
|
+
require "magister/types/subject.rb"
|
6
|
+
require "magister/types/teacher.rb"
|
7
|
+
|
8
|
+
# This class describes a Class as it would appear in the schedule in magister.
|
9
|
+
# MagClass instead of Class becasue ruby got confused with class
|
10
|
+
class MagClass
|
11
|
+
# Returns a new instance of MagClass.
|
12
|
+
# @param rawParsed [Hash] The raw data, yet it has already been parsed (like with JSON.parse)
|
13
|
+
# @since 1.1.0
|
14
|
+
def initialize(rawParsed)
|
15
|
+
@id = rawParsed["Id"]
|
16
|
+
@classStart = rawParsed["Start"]
|
17
|
+
@classEndInclusive = rawParsed["Einde"]
|
18
|
+
@wholeDay = rawParsed["DuurtHeleDag"]
|
19
|
+
@description = rawParsed["Omschrijving"]
|
20
|
+
# I dont know why location is here when theres also classrooms
|
21
|
+
@location = rawParsed["Lokatie"]
|
22
|
+
@content = rawParsed["Inhoud"]
|
23
|
+
@remark = rawParsed["Opmerking"]
|
24
|
+
@note = rawParsed["Aantekening"]
|
25
|
+
@finished = rawParsed["Afgerond"]
|
26
|
+
@repeatStatus = rawParsed["HerhaalStatus"]
|
27
|
+
@repeat = rawParsed["Herhaling"]
|
28
|
+
|
29
|
+
@subjects = Array.new
|
30
|
+
rawParsed["Vakken"].each do |subject|
|
31
|
+
@subjects.push Subject.new(subject)
|
32
|
+
end
|
33
|
+
|
34
|
+
@teachers = Array.new
|
35
|
+
rawParsed["Docenten"].each do |teacher|
|
36
|
+
@teachers.push Teacher.new(teacher)
|
37
|
+
end
|
38
|
+
|
39
|
+
@classrooms = Array.new
|
40
|
+
rawParsed["Lokalen"].each do |classRoom|
|
41
|
+
@classrooms.push ClassRoom.new(classRoom)
|
42
|
+
end
|
43
|
+
|
44
|
+
@hasAttachments = rawParsed["HeeftBijlagen"]
|
45
|
+
@attachments = rawParsed["Bijlagen"]
|
46
|
+
|
47
|
+
# I dont know what these values do
|
48
|
+
@infoType = rawParsed["InfoType"] # I think what kind of content like homework/test
|
49
|
+
@status = rawParsed["Status"] # I think the status as in cancelled
|
50
|
+
@type = rawParsed["Type"]
|
51
|
+
@subtype = rawParsed["SubType"]
|
52
|
+
@isOnline = rawParsed["IsOnlineDeelname"] # Wether there is a way to participate online?
|
53
|
+
@viewType = rawParsed["WeergaveType"]
|
54
|
+
@assignmentId = rawParsed["OpdrachtId"]
|
55
|
+
@groups = rawParsed["Groepen"]
|
56
|
+
end
|
57
|
+
|
58
|
+
# Gets a summary of the object.
|
59
|
+
# Overwrites default function.
|
60
|
+
# @return [String] object summary
|
61
|
+
# @since 1.1.0
|
62
|
+
def inspect
|
63
|
+
"#<#{self.class}:0x#{object_id} @id=#{@id}, @description=#{@description}, @subjects[0]=#{@subjects[0].inspect}, @teachers[0]=#{@teachers[0].inspect}, @location=#{@location}>"
|
64
|
+
end
|
65
|
+
|
66
|
+
# getters
|
67
|
+
|
68
|
+
# The ID of the class
|
69
|
+
# @return [Integer] the id
|
70
|
+
# @since 1.1.0
|
71
|
+
def id
|
72
|
+
@id
|
73
|
+
end
|
74
|
+
# The time the class starts
|
75
|
+
# @return [String] the date formatted in ISO 8601
|
76
|
+
# @since 1.1.0
|
77
|
+
def classStart
|
78
|
+
@classStart
|
79
|
+
end
|
80
|
+
# @see classStart
|
81
|
+
# @since 1.1.0
|
82
|
+
def startTime
|
83
|
+
@classStart
|
84
|
+
end
|
85
|
+
# The time the class ends
|
86
|
+
# @return [String] the ending date formatted in ISO 8601
|
87
|
+
# @since 1.1.0
|
88
|
+
def classEndInclusive
|
89
|
+
@classEndInclusive
|
90
|
+
end
|
91
|
+
# @see classEndInclusive
|
92
|
+
# @since 1.1.0
|
93
|
+
def endTime
|
94
|
+
@classEndInclusive
|
95
|
+
end
|
96
|
+
# If the class lasts the whole day
|
97
|
+
# @return [Boolean]
|
98
|
+
# @since 1.1.0
|
99
|
+
def wholeDay
|
100
|
+
@wholeDay
|
101
|
+
end
|
102
|
+
# The description of the class formatted like
|
103
|
+
# a - b - c.
|
104
|
+
# where a is a short version of the classes name.
|
105
|
+
# where b is the short code of the teachers name.
|
106
|
+
# where c is the class/group the class belongs to.
|
107
|
+
# @return [String] a - b - c
|
108
|
+
# @since 1.1.0
|
109
|
+
def description
|
110
|
+
@description
|
111
|
+
end
|
112
|
+
# The location where the class is
|
113
|
+
# @note reccommended to use the +classrooms+ property instead
|
114
|
+
# @return [String] the location
|
115
|
+
# @see classrooms
|
116
|
+
# @since 1.1.0
|
117
|
+
def location
|
118
|
+
@location
|
119
|
+
end
|
120
|
+
# The content of the class.
|
121
|
+
# @return [String, nil] the content
|
122
|
+
# @note This is stuff like homework or test descriptions.
|
123
|
+
# @since 1.1.0
|
124
|
+
def content
|
125
|
+
@content
|
126
|
+
end
|
127
|
+
# A remark (opmerking) added to the class
|
128
|
+
# @return [String, nil] the remark
|
129
|
+
# @note This is diffrent form the +note+
|
130
|
+
# @see note
|
131
|
+
# @since 1.1.0
|
132
|
+
def remark
|
133
|
+
@remark
|
134
|
+
end
|
135
|
+
# A note (aantekening) added to the class
|
136
|
+
# @return [String, nil] the note
|
137
|
+
# @note This is diffrent from +remark+
|
138
|
+
# @see remark
|
139
|
+
# @since 1.1.0
|
140
|
+
def note
|
141
|
+
@note
|
142
|
+
end
|
143
|
+
# If it is marked as finished
|
144
|
+
# @note this has been set by the user, not by the teacher or anyone else.
|
145
|
+
# @return [Boolean]
|
146
|
+
# @since 1.1.0
|
147
|
+
def finished
|
148
|
+
@finished
|
149
|
+
end
|
150
|
+
# If the class repeats
|
151
|
+
# @note Currently we are not certain what every status means.
|
152
|
+
# @return [Integer] the status
|
153
|
+
# @since 1.1.0
|
154
|
+
def repeatStatus
|
155
|
+
@repeatStatus
|
156
|
+
end
|
157
|
+
# |?| How it repeats
|
158
|
+
# @note We do not have info on what this property does/means
|
159
|
+
# @return [?]
|
160
|
+
# @since 1.1.0
|
161
|
+
def repeat
|
162
|
+
@repeat
|
163
|
+
end
|
164
|
+
# What subjects are in this class
|
165
|
+
# @return [Array<Subject>] The subjects
|
166
|
+
# @since 1.1.0
|
167
|
+
def subjects
|
168
|
+
@subjects
|
169
|
+
end
|
170
|
+
# What teachers are giving this class
|
171
|
+
# @return [Array<Teacher>] The teachers
|
172
|
+
# @since 1.1.0
|
173
|
+
def teachers
|
174
|
+
@teachers
|
175
|
+
end
|
176
|
+
# What classrooms this class is given in
|
177
|
+
# @return [Array<ClassRoom>] The classrooms
|
178
|
+
# @since 1.1.0
|
179
|
+
def classrooms
|
180
|
+
@classrooms
|
181
|
+
end
|
182
|
+
# If the class has any attachments
|
183
|
+
# @return [Boolean] has attachments
|
184
|
+
# @see attachments
|
185
|
+
# @since 1.1.0
|
186
|
+
def hasAttachments
|
187
|
+
@hasAttachments
|
188
|
+
end
|
189
|
+
# The attachments that are attached
|
190
|
+
# @note Unsure yet what type the attachments will be
|
191
|
+
# @return [?, nil]
|
192
|
+
# @since 1.1.0
|
193
|
+
def attachments
|
194
|
+
@attachments
|
195
|
+
end
|
196
|
+
|
197
|
+
# |?| What kind of content it has
|
198
|
+
# @note We do not have info on what this property does/means
|
199
|
+
# @return [?]
|
200
|
+
# @since 1.1.0
|
201
|
+
def infoType
|
202
|
+
@infoType
|
203
|
+
end
|
204
|
+
# |?| if the class is cancelled etc?
|
205
|
+
# @note We do not have info on what this property does/means
|
206
|
+
# @return [Integer]
|
207
|
+
# @since 1.1.0
|
208
|
+
def status
|
209
|
+
@status
|
210
|
+
end
|
211
|
+
# |?|
|
212
|
+
# @note We do not have info on what this property does/means
|
213
|
+
# @return [?]
|
214
|
+
# @since 1.1.0
|
215
|
+
def type
|
216
|
+
@type
|
217
|
+
end
|
218
|
+
# |?|
|
219
|
+
# @note We do not have info on what this property does/means
|
220
|
+
# @return [?]
|
221
|
+
# @since 1.1.0
|
222
|
+
def subtype
|
223
|
+
@subtype
|
224
|
+
end
|
225
|
+
# |?| Wether or not the class has online attendance
|
226
|
+
# @note We do not have info on what this property does/means
|
227
|
+
# @return [Boolean]
|
228
|
+
# @since 1.1.0
|
229
|
+
def isOnline
|
230
|
+
@isOnline
|
231
|
+
end
|
232
|
+
# |?|
|
233
|
+
# @note We do not have info on what this property does/means
|
234
|
+
# @return [Integer]
|
235
|
+
# @since 1.1.0
|
236
|
+
def viewType
|
237
|
+
@viewType
|
238
|
+
end
|
239
|
+
# |?|
|
240
|
+
# @note We do not have info on what this property does/means
|
241
|
+
# @return [?]
|
242
|
+
# @since 1.1.0
|
243
|
+
def assignmentId
|
244
|
+
@assignmentId
|
245
|
+
end
|
246
|
+
# |?|
|
247
|
+
# @note We do not have info on what this property does/means
|
248
|
+
# @return [?, nil]
|
249
|
+
# @since 1.1.0
|
250
|
+
def groups
|
251
|
+
@groups
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
# This class represents a physical classroom.
|
6
|
+
class ClassRoom
|
7
|
+
# Returns a new instance of ClassRoom.
|
8
|
+
# @param rawParsed [Hash] The raw data, yet it has already been parsed (like with JSON.parse)
|
9
|
+
# @since 1.1.0
|
10
|
+
def initialize(rawParsed)
|
11
|
+
@name = rawParsed["Naam"]
|
12
|
+
end
|
13
|
+
|
14
|
+
# The name of the class
|
15
|
+
# @return [String] name
|
16
|
+
# @since 1.1.0
|
17
|
+
def name
|
18
|
+
@name
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# This class is used to represent a grade and all metadata of it.
|
7
|
+
class Grade
|
8
|
+
# Returns a new instance of Grade.
|
9
|
+
# @param rawParsed [Hash] The raw data, yet it has already been parsed (like with JSON.parse)
|
10
|
+
# @since 1.1.0
|
11
|
+
def initialize(rawParsed)
|
12
|
+
@id = rawParsed["kolomId"]
|
13
|
+
@description = rawParsed["omschrijving"]
|
14
|
+
# This is an attrocity and shouldnt exist. yet here it is.
|
15
|
+
@subject = Subject.new(JSON.parse("{\"Id\": \"#{rawParsed["vak"]["code"]}\", \"Naam\": \"#{rawParsed["vak"]["omschrijving"]}\"}"))
|
16
|
+
|
17
|
+
@grade = rawParsed["waarde"].gsub(",", ".").to_f
|
18
|
+
@weight = rawParsed["weegfactor"]
|
19
|
+
|
20
|
+
@isSufficient = rawParsed["isVoldoende"]
|
21
|
+
@counts = rawParsed["teltMee"]
|
22
|
+
@toBeCaughtUp = rawParsed["moetInhalen"]
|
23
|
+
|
24
|
+
@isExempt = rawParsed["heeftVrijstelling"]
|
25
|
+
|
26
|
+
# addedOn is when the teacher added it to magister
|
27
|
+
# earnedOn is when the test was done, most teachers dont put this in
|
28
|
+
@addedOn = rawParsed["ingevoerdOp"]
|
29
|
+
@earnedOn = rawParsed["behaaldOp"]
|
30
|
+
end
|
31
|
+
|
32
|
+
# The id of the grade
|
33
|
+
# @return [Integer] id
|
34
|
+
# @since 1.1.0
|
35
|
+
def id
|
36
|
+
@id
|
37
|
+
end
|
38
|
+
# The description of the grade
|
39
|
+
# @return [String] description
|
40
|
+
# @since 1.1.0
|
41
|
+
def description
|
42
|
+
@description
|
43
|
+
end
|
44
|
+
# The subject the grade belongs to
|
45
|
+
# @return [Subject] subject
|
46
|
+
# @since 1.1.0
|
47
|
+
def subject
|
48
|
+
@subject
|
49
|
+
end
|
50
|
+
# If the grade is considered sufficient
|
51
|
+
# @return [Boolean] sufficient
|
52
|
+
# @since 1.1.0
|
53
|
+
def isSufficient
|
54
|
+
@isSufficient
|
55
|
+
end
|
56
|
+
# If the grade is considered insufficient
|
57
|
+
# @return [Boolean] insufficient
|
58
|
+
# @note This is simply the inverse of +isSufficient+
|
59
|
+
# @see isSufficient
|
60
|
+
# @since 1.1.0
|
61
|
+
def isInsufficient
|
62
|
+
!@isSufficient
|
63
|
+
end
|
64
|
+
# Get the actual grade/value
|
65
|
+
# @return [Float] grade
|
66
|
+
# @since 1.1.0
|
67
|
+
def grade
|
68
|
+
@grade
|
69
|
+
end
|
70
|
+
# Get the actual grade/value
|
71
|
+
# @return [Float] grade
|
72
|
+
# @see grade
|
73
|
+
# @since 1.1.0
|
74
|
+
def value
|
75
|
+
@grade
|
76
|
+
end
|
77
|
+
# Get the wight of the grade
|
78
|
+
# @return [Integer] weight
|
79
|
+
# @since 1.1.0
|
80
|
+
def weight
|
81
|
+
@weight
|
82
|
+
end
|
83
|
+
# If the grade actually counts
|
84
|
+
# @return [Boolean] counts
|
85
|
+
# @since 1.1.0
|
86
|
+
def counts
|
87
|
+
@counts
|
88
|
+
end
|
89
|
+
# If the test/thing that caused the grade needs to be caught up on
|
90
|
+
# @return [Boolean] needs to be caught up
|
91
|
+
# @since 1.1.0
|
92
|
+
def toBeCaughtUp
|
93
|
+
@toBeCaughtUp
|
94
|
+
end
|
95
|
+
# If the current user is exempt from the subject
|
96
|
+
# @return [Boolean] exempt
|
97
|
+
# @since 1.1.0
|
98
|
+
def isExempt
|
99
|
+
@isExempt
|
100
|
+
end
|
101
|
+
# If the current user is exempt from the subject
|
102
|
+
# @return [Boolean] exempt
|
103
|
+
# @see exempt
|
104
|
+
# @since 1.1.0
|
105
|
+
def exempt
|
106
|
+
@isExempt
|
107
|
+
end
|
108
|
+
# When the grade was entered
|
109
|
+
# @return [String] Date
|
110
|
+
# @note This is when the teacher added the grade to magisters
|
111
|
+
# @see earnedOn
|
112
|
+
# @since 1.1.0
|
113
|
+
def addedOn
|
114
|
+
@addedOn
|
115
|
+
end
|
116
|
+
# If the current user is exempt from the subhect
|
117
|
+
# @return [Boolean, nil] exempt
|
118
|
+
# @note This is when the actual test occurred
|
119
|
+
# @see addedOn
|
120
|
+
# @since 1.1.0
|
121
|
+
def earnedOn
|
122
|
+
@earnedOn
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
# Module used in the #person class
|
6
|
+
# @since 1.2.0
|
7
|
+
module Birth
|
8
|
+
# The birthday of the person
|
9
|
+
# @return [String] birthday
|
10
|
+
# @since 1.2.0
|
11
|
+
def day
|
12
|
+
@birthDay
|
13
|
+
end
|
14
|
+
# The persons last name given at birth
|
15
|
+
# @return [String] name
|
16
|
+
# @since 1.2.0
|
17
|
+
def lastName
|
18
|
+
@birthLastName
|
19
|
+
end
|
20
|
+
# The persons preposition given at birth
|
21
|
+
# @return [String] preposition
|
22
|
+
# @since 1.2.0
|
23
|
+
def preposition
|
24
|
+
@birthnamePreposition
|
25
|
+
end
|
26
|
+
# Wether or not to use the users birth name
|
27
|
+
# @return [Boolean] use birth name
|
28
|
+
# @since 1.2.0
|
29
|
+
def use
|
30
|
+
@useBirthname
|
31
|
+
end
|
32
|
+
# Wether or not to use the users birth name
|
33
|
+
# @return [Boolean] use birth name
|
34
|
+
# @since 1.2.0
|
35
|
+
def useBirthname
|
36
|
+
@useBirthname
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Module used in the #person class
|
41
|
+
# @since 1.2.0
|
42
|
+
module Official
|
43
|
+
# The official first of the person
|
44
|
+
# @return [String] name
|
45
|
+
# @since 1.2.0
|
46
|
+
def firstNames
|
47
|
+
@officialFirstNames
|
48
|
+
end
|
49
|
+
# The official prepositions of the person
|
50
|
+
# @return [String, nil] prepositions
|
51
|
+
# @since 1.2.0
|
52
|
+
def prepositions
|
53
|
+
@officialPrepositions
|
54
|
+
end
|
55
|
+
# The official last name of the person
|
56
|
+
# @return [String] name
|
57
|
+
# @since 1.2.0
|
58
|
+
def lastName
|
59
|
+
@officialLastName
|
60
|
+
end
|
61
|
+
# The initials of the person
|
62
|
+
# @return [String] initials
|
63
|
+
# @since 1.2.0
|
64
|
+
def initials
|
65
|
+
@initials
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# This class describes the person object the magister api gives us
|
70
|
+
# this object includes all the user's personal data like name and birthday
|
71
|
+
class Person
|
72
|
+
include Birth
|
73
|
+
include Official
|
74
|
+
|
75
|
+
# Returns a new instance of Person.
|
76
|
+
# @param rawParsed [Hash] The raw data, yet it has already been parsed (like with JSON.parse)
|
77
|
+
# @since 1.2.0
|
78
|
+
def initialize(rawParsed)
|
79
|
+
@id = rawParsed["Id"]
|
80
|
+
@firstName = rawParsed["Roepnaam"]
|
81
|
+
@preposition = rawParsed["Tussenvoegsel"]
|
82
|
+
@lastName = rawParsed["Achternaam"]
|
83
|
+
@officialFirstNames = rawParsed["OfficieleVoornamen"]
|
84
|
+
@initials = rawParsed["Voorletters"]
|
85
|
+
@officialPrepositions = rawParsed["OfficieleTussenvoegsels"]
|
86
|
+
@officialLastName = rawParsed["OfficieleAchternaam"]
|
87
|
+
@birthDay = rawParsed["Geboortedatum"]
|
88
|
+
@birthLastName = rawParsed["GeboorteAchternaam"]
|
89
|
+
@birthnamePreposition = rawParsed["GeboortenaamTussenvoegsel"]
|
90
|
+
@useBirthname = rawParsed["GebruikGeboortenaam"]
|
91
|
+
|
92
|
+
# probably only for tracking
|
93
|
+
@externalId = rawParsed["ExterneId"]
|
94
|
+
end
|
95
|
+
|
96
|
+
# The id of the person
|
97
|
+
# @return [Integer] id
|
98
|
+
# @since 1.2.0
|
99
|
+
def id
|
100
|
+
@id
|
101
|
+
end
|
102
|
+
# The first name of the person
|
103
|
+
# @return [String] name
|
104
|
+
# @since 1.2.0
|
105
|
+
def firstName
|
106
|
+
@firstName
|
107
|
+
end
|
108
|
+
# The preposition (thing between first & last name) of the person
|
109
|
+
# @return [String, nil] preposition
|
110
|
+
# @since 1.2.0
|
111
|
+
def preposition
|
112
|
+
@preposition
|
113
|
+
end
|
114
|
+
# The last name of the person
|
115
|
+
# @return [String] name
|
116
|
+
# @since 1.2.0
|
117
|
+
def lastName
|
118
|
+
@lastName
|
119
|
+
end
|
120
|
+
# The initials of the person
|
121
|
+
# @return [String] initials
|
122
|
+
# @since 1.2.0
|
123
|
+
def initials
|
124
|
+
@initials
|
125
|
+
end
|
126
|
+
# The birthday of the person
|
127
|
+
# @return [String] birthday
|
128
|
+
# @since 1.2.0
|
129
|
+
def birthDay
|
130
|
+
@birthDay
|
131
|
+
end
|
132
|
+
# Wether or not to use the users birth name
|
133
|
+
# @return [Boolean] use birth name
|
134
|
+
# @since 1.2.0
|
135
|
+
def useBirthname
|
136
|
+
@useBirthname
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
# This class represents a subject in magister in the sense of when it is linked to another object
|
6
|
+
class Subject
|
7
|
+
# Returns a new instance of Subject.
|
8
|
+
# @param rawParsed [Hash] The raw data, yet it has already been parsed (like with JSON.parse)
|
9
|
+
# @since 1.1.0
|
10
|
+
def initialize(rawParsed)
|
11
|
+
@id = rawParsed["Id"]
|
12
|
+
@name = rawParsed["Naam"]
|
13
|
+
end
|
14
|
+
|
15
|
+
# The id (or code) of the subject
|
16
|
+
# @return [Integer, String] id
|
17
|
+
# @note When initialized by +Grade+ it uses the code as the id to initialize
|
18
|
+
# @see Grade
|
19
|
+
# @since 1.1.0
|
20
|
+
def id
|
21
|
+
@id
|
22
|
+
end
|
23
|
+
# The name of the subject
|
24
|
+
# @return [String] Name
|
25
|
+
# @note When initialized by +Grade+ it uses the description as the name to initialize
|
26
|
+
# @see Grade
|
27
|
+
# @since 1.1.0
|
28
|
+
def name
|
29
|
+
@name
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
# This class represents the teacher object magister gives us.
|
6
|
+
class Teacher
|
7
|
+
# Returns a new instance of Teacher.
|
8
|
+
# @param rawParsed [Hash] The raw data, yet it has already been parsed (like with JSON.parse)
|
9
|
+
# @since 1.1.0
|
10
|
+
def initialize(rawParsed)
|
11
|
+
@id = rawParsed["Id"]
|
12
|
+
@name = rawParsed["Naam"]
|
13
|
+
@abrev = rawParsed["Docentcode"]
|
14
|
+
end
|
15
|
+
|
16
|
+
# The id of the teacher
|
17
|
+
# @return [Integer] id
|
18
|
+
# @since 1.1.0
|
19
|
+
def id
|
20
|
+
@id
|
21
|
+
end
|
22
|
+
# The name of the teacher
|
23
|
+
# @return [String] name
|
24
|
+
# @since 1.1.0
|
25
|
+
def name
|
26
|
+
@name
|
27
|
+
end
|
28
|
+
# The abreviation of the teacher
|
29
|
+
# @return [String] Abreviation
|
30
|
+
# @since 1.1.0
|
31
|
+
def abrev
|
32
|
+
@abrev
|
33
|
+
end
|
34
|
+
# The abreviation of the teacher
|
35
|
+
# @return [String] Abreviation
|
36
|
+
# @since 1.1.0
|
37
|
+
def abreviaton
|
38
|
+
@abrev
|
39
|
+
end
|
40
|
+
# The abreviation of the teacher
|
41
|
+
# @return [String] Abreviation
|
42
|
+
# @since 1.1.0
|
43
|
+
def code
|
44
|
+
@abrev
|
45
|
+
end
|
46
|
+
end
|
data/lib/magister.rb
CHANGED
@@ -1,30 +1,63 @@
|
|
1
1
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
2
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
3
|
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
require '
|
4
|
+
require 'magister/profile'
|
5
|
+
require 'magister/data'
|
6
|
+
require 'magister/authenticator'
|
7
7
|
|
8
8
|
# can be either "selenium" or "local"
|
9
9
|
# "selenium" will run headlessly
|
10
10
|
# "local" will open a browser window for the user to login
|
11
11
|
$authMode = "selenium"
|
12
12
|
|
13
|
+
# Caching options
|
14
|
+
$magister_useCache = true
|
15
|
+
$magister_cachingDirectory = ".cache/magister"
|
16
|
+
|
17
|
+
prev = ""
|
18
|
+
$magister_cachingDirectory.split("/").each do |directory|
|
19
|
+
Dir.mkdir(prev + directory) unless File.exist?(prev + directory)
|
20
|
+
prev += directory + "/"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Cache type can eitehr be "compact" or "json"
|
24
|
+
$magister_cacheType = "json"
|
25
|
+
# Wether to encrypt the cache, this can secure the acount by not exposing the token or any sensetive data.
|
26
|
+
$magister_encryptCache = false
|
27
|
+
# When using encryption, this may not be empty
|
28
|
+
$magister_encryptionKey = ""
|
29
|
+
|
30
|
+
# The main magister class
|
13
31
|
class Magister
|
14
32
|
include MagisterData
|
15
33
|
|
34
|
+
# Returns a new instance of Magister.
|
35
|
+
# @since 1.0.0
|
16
36
|
def initialize
|
17
37
|
@profile = nil
|
18
38
|
end
|
19
39
|
|
40
|
+
# Create a new profile and authenticate with a token
|
41
|
+
# @param school [String] The school the user attends
|
42
|
+
# @param token [String] The users token
|
43
|
+
# @since 1.0.0
|
20
44
|
def authenticate(school, token)
|
21
45
|
@profile = Profile.new(token, school)
|
22
46
|
@profile.verify
|
23
47
|
end
|
48
|
+
# Create a new profile based on a username and password
|
49
|
+
# @param school [String] The school the user attends
|
50
|
+
# @param username [String] The users username
|
51
|
+
# @param password [String] The users password
|
52
|
+
# @see Authenticator#login
|
53
|
+
# @since 1.1.0
|
24
54
|
def login(school, username, password)
|
25
55
|
@profile = Authenticator.login(username, password, school)
|
26
56
|
end
|
27
57
|
|
58
|
+
# Get the users profile
|
59
|
+
# @return [Profile] the profile
|
60
|
+
# @since 1.0.0
|
28
61
|
def profile
|
29
62
|
@profile
|
30
63
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magister
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Riley0122
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -82,11 +82,18 @@ files:
|
|
82
82
|
- lib/magister/authenticator.rb
|
83
83
|
- lib/magister/data.rb
|
84
84
|
- lib/magister/profile.rb
|
85
|
+
- lib/magister/types/class.rb
|
86
|
+
- lib/magister/types/classroom.rb
|
87
|
+
- lib/magister/types/grade.rb
|
88
|
+
- lib/magister/types/person.rb
|
89
|
+
- lib/magister/types/subject.rb
|
90
|
+
- lib/magister/types/teacher.rb
|
85
91
|
homepage: https://github.com/riley0122/rubymag#readme
|
86
92
|
licenses:
|
87
93
|
- MPL-2.0
|
88
94
|
metadata:
|
89
95
|
source_code_uri: https://github.com/riley0122/rubymag
|
96
|
+
documentation_uri: https://riley0122.github.io/rubymag
|
90
97
|
post_install_message:
|
91
98
|
rdoc_options: []
|
92
99
|
require_paths:
|