magister 1.0.0 → 1.2.0
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/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:
|