ladok3 4.9__py3-none-any.whl → 4.11__py3-none-any.whl
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.
Potentially problematic release.
This version of ladok3 might be problematic. Click here for more details.
- doc/ltxobj/ladok3.pdf +0 -0
- ladok3/__init__.py +5016 -4668
- ladok3/cli.nw +28 -10
- ladok3/cli.py +261 -237
- ladok3/data.py +180 -142
- ladok3/ladok3.nw +118 -59
- ladok3/report.nw +1 -1
- ladok3/report.py +142 -105
- {ladok3-4.9.dist-info → ladok3-4.11.dist-info}/METADATA +22 -4
- ladok3-4.11.dist-info/RECORD +21 -0
- ladok3/kth.py +0 -117
- ladok3/test.py +0 -0
- ladok3-4.9.dist-info/RECORD +0 -23
- {ladok3-4.9.dist-info → ladok3-4.11.dist-info}/LICENSE +0 -0
- {ladok3-4.9.dist-info → ladok3-4.11.dist-info}/WHEEL +0 -0
- {ladok3-4.9.dist-info → ladok3-4.11.dist-info}/entry_points.txt +0 -0
ladok3/cli.nw
CHANGED
|
@@ -504,7 +504,11 @@ If all fail, the function will return [[None]] for both.
|
|
|
504
504
|
(This is due to how we handle the [[login]] command.)
|
|
505
505
|
<<functions>>=
|
|
506
506
|
def load_credentials(filename="config.json"):
|
|
507
|
-
"""
|
|
507
|
+
"""
|
|
508
|
+
Loads credentials from environment or file named filename.
|
|
509
|
+
Returns the tuple (instituation, credential dictionary) that
|
|
510
|
+
can be passed to `LadokSession(instiution, credential dictionary)`.
|
|
511
|
+
"""
|
|
508
512
|
|
|
509
513
|
<<fetch vars from keyring>>
|
|
510
514
|
<<fetch username and password from keyring>>
|
|
@@ -518,6 +522,9 @@ def load_credentials(filename="config.json"):
|
|
|
518
522
|
|
|
519
523
|
First we try the newest format.
|
|
520
524
|
We try to fetch the institution and vars from the keyring.
|
|
525
|
+
|
|
526
|
+
Note that [[keyring]] returns [[None]] if the key doesn't exist, it doesn't
|
|
527
|
+
raise an exception.
|
|
521
528
|
<<fetch vars from keyring>>=
|
|
522
529
|
try:
|
|
523
530
|
institution = keyring.get_password("ladok3", "institution")
|
|
@@ -525,7 +532,9 @@ try:
|
|
|
525
532
|
|
|
526
533
|
vars = {}
|
|
527
534
|
for key in vars_keys.split(";"):
|
|
528
|
-
|
|
535
|
+
value = keyring.get_password("ladok3", key)
|
|
536
|
+
if value:
|
|
537
|
+
vars[key] = value
|
|
529
538
|
|
|
530
539
|
if institution and vars:
|
|
531
540
|
return institution, vars
|
|
@@ -538,12 +547,10 @@ supported KTH.
|
|
|
538
547
|
<<fetch username and password from keyring>>=
|
|
539
548
|
try:
|
|
540
549
|
institution = "KTH Royal Institute of Technology"
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
if vars:
|
|
546
|
-
return institution, vars
|
|
550
|
+
username = keyring.get_password("ladok3", "username")
|
|
551
|
+
password = keyring.get_password("ladok3", "password")
|
|
552
|
+
if username and password:
|
|
553
|
+
return institution, {"username": username, "password": password}
|
|
547
554
|
except:
|
|
548
555
|
pass
|
|
549
556
|
@
|
|
@@ -577,7 +584,10 @@ try:
|
|
|
577
584
|
|
|
578
585
|
vars = {}
|
|
579
586
|
for key in vars_keys.split(":"):
|
|
580
|
-
|
|
587
|
+
try:
|
|
588
|
+
vars[key] = os.environ[key]
|
|
589
|
+
except KeyError:
|
|
590
|
+
<<print warning about missing variable in [[LADOK_VARS]]>>
|
|
581
591
|
|
|
582
592
|
if institution and vars:
|
|
583
593
|
return institution, vars
|
|
@@ -585,6 +595,14 @@ except:
|
|
|
585
595
|
pass
|
|
586
596
|
@
|
|
587
597
|
|
|
598
|
+
Unlike in the other cases, we don't just ignore the exception of the key not
|
|
599
|
+
existing.
|
|
600
|
+
Since the user has explicitly specified the variable, we should warn them that
|
|
601
|
+
it doesn't exist.
|
|
602
|
+
<<print warning about missing variable in [[LADOK_VARS]]>>=
|
|
603
|
+
warn(f"Variable {key} not set, ignoring.")
|
|
604
|
+
@
|
|
605
|
+
|
|
588
606
|
If none of the above worked, the last resort is to try to read the
|
|
589
607
|
configuration file.
|
|
590
608
|
We pop the institution from the configuration file (a dictionary), because then
|
|
@@ -595,7 +613,7 @@ try:
|
|
|
595
613
|
config = json.load(conf_file)
|
|
596
614
|
|
|
597
615
|
institution = config.pop("institution",
|
|
598
|
-
|
|
616
|
+
"KTH Royal Institute of Technology")
|
|
599
617
|
return institution, config
|
|
600
618
|
except:
|
|
601
619
|
pass
|
ladok3/cli.py
CHANGED
|
@@ -26,92 +26,97 @@ import ladok3.student
|
|
|
26
26
|
|
|
27
27
|
dirs = appdirs.AppDirs("ladok", "dbosk@kth.se")
|
|
28
28
|
|
|
29
|
+
|
|
29
30
|
def err(rc, msg):
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
print(f"{sys.argv[0]}: error: {msg}", file=sys.stderr)
|
|
32
|
+
sys.exit(rc)
|
|
33
|
+
|
|
32
34
|
|
|
33
35
|
def warn(msg):
|
|
34
|
-
|
|
35
|
-
def store_ladok_session(ls, credentials):
|
|
36
|
-
if not os.path.isdir(dirs.user_cache_dir):
|
|
37
|
-
os.makedirs(dirs.user_cache_dir)
|
|
36
|
+
print(f"{sys.argv[0]}: {msg}", file=sys.stderr)
|
|
38
37
|
|
|
39
|
-
file_path = dirs.user_cache_dir + "/LadokSession"
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
def store_ladok_session(ls, credentials):
|
|
40
|
+
if not os.path.isdir(dirs.user_cache_dir):
|
|
41
|
+
os.makedirs(dirs.user_cache_dir)
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
try:
|
|
47
|
-
salt = credentials["username"]
|
|
48
|
-
passwd = credentials["password"]
|
|
49
|
-
except KeyError:
|
|
50
|
-
credentials = list(credentials.values())
|
|
51
|
-
salt = credentials[0]
|
|
52
|
-
passwd = credentials[1]
|
|
53
|
-
else:
|
|
54
|
-
salt = credentials[0]
|
|
55
|
-
passwd = credentials[1]
|
|
56
|
-
|
|
57
|
-
kdf = PBKDF2HMAC(
|
|
58
|
-
algorithm=hashes.SHA256(),
|
|
59
|
-
length=32,
|
|
60
|
-
salt=salt.encode("utf-8"),
|
|
61
|
-
iterations=100000
|
|
62
|
-
)
|
|
63
|
-
key = base64.urlsafe_b64encode(kdf.derive(passwd.encode("utf-8")))
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
fernet_protocol = Fernet(key)
|
|
67
|
-
encrypted_ls = fernet_protocol.encrypt(pickled_ls)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
with open(file_path, "wb") as file:
|
|
71
|
-
file.write(encrypted_ls)
|
|
72
|
-
|
|
73
|
-
def restore_ladok_session(credentials):
|
|
74
|
-
file_path = dirs.user_cache_dir + "/LadokSession"
|
|
43
|
+
file_path = dirs.user_cache_dir + "/LadokSession"
|
|
75
44
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
encrypted_ls = file.read()
|
|
79
|
-
if not credentials or len(credentials) < 2:
|
|
45
|
+
pickled_ls = pickle.dumps(ls)
|
|
46
|
+
if not credentials or len(credentials) < 2:
|
|
80
47
|
raise ValueError(f"Missing credentials, see `ladok login -h`.")
|
|
81
48
|
|
|
82
|
-
|
|
49
|
+
if isinstance(credentials, dict):
|
|
83
50
|
try:
|
|
84
|
-
|
|
85
|
-
|
|
51
|
+
salt = credentials["username"]
|
|
52
|
+
passwd = credentials["password"]
|
|
86
53
|
except KeyError:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
54
|
+
credentials = list(credentials.values())
|
|
55
|
+
salt = credentials[0]
|
|
56
|
+
passwd = credentials[1]
|
|
57
|
+
else:
|
|
91
58
|
salt = credentials[0]
|
|
92
59
|
passwd = credentials[1]
|
|
93
60
|
|
|
94
|
-
|
|
61
|
+
kdf = PBKDF2HMAC(
|
|
95
62
|
algorithm=hashes.SHA256(),
|
|
96
63
|
length=32,
|
|
97
64
|
salt=salt.encode("utf-8"),
|
|
98
|
-
iterations=100000
|
|
99
|
-
|
|
100
|
-
|
|
65
|
+
iterations=100000,
|
|
66
|
+
)
|
|
67
|
+
key = base64.urlsafe_b64encode(kdf.derive(passwd.encode("utf-8")))
|
|
68
|
+
|
|
69
|
+
fernet_protocol = Fernet(key)
|
|
70
|
+
encrypted_ls = fernet_protocol.encrypt(pickled_ls)
|
|
71
|
+
|
|
72
|
+
with open(file_path, "wb") as file:
|
|
73
|
+
file.write(encrypted_ls)
|
|
101
74
|
|
|
102
75
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
76
|
+
def restore_ladok_session(credentials):
|
|
77
|
+
file_path = dirs.user_cache_dir + "/LadokSession"
|
|
78
|
+
|
|
79
|
+
if os.path.isfile(file_path):
|
|
80
|
+
with open(file_path, "rb") as file:
|
|
81
|
+
encrypted_ls = file.read()
|
|
82
|
+
if not credentials or len(credentials) < 2:
|
|
83
|
+
raise ValueError(f"Missing credentials, see `ladok login -h`.")
|
|
84
|
+
|
|
85
|
+
if isinstance(credentials, dict):
|
|
86
|
+
try:
|
|
87
|
+
salt = credentials["username"]
|
|
88
|
+
passwd = credentials["password"]
|
|
89
|
+
except KeyError:
|
|
90
|
+
credentials = list(credentials.values())
|
|
91
|
+
salt = credentials[0]
|
|
92
|
+
passwd = credentials[1]
|
|
93
|
+
else:
|
|
94
|
+
salt = credentials[0]
|
|
95
|
+
passwd = credentials[1]
|
|
96
|
+
|
|
97
|
+
kdf = PBKDF2HMAC(
|
|
98
|
+
algorithm=hashes.SHA256(),
|
|
99
|
+
length=32,
|
|
100
|
+
salt=salt.encode("utf-8"),
|
|
101
|
+
iterations=100000,
|
|
102
|
+
)
|
|
103
|
+
key = base64.urlsafe_b64encode(kdf.derive(passwd.encode("utf-8")))
|
|
104
|
+
|
|
105
|
+
fernet_protocol = Fernet(key)
|
|
106
|
+
try:
|
|
107
|
+
pickled_ls = fernet_protocol.decrypt(encrypted_ls)
|
|
108
|
+
except Exception as err:
|
|
109
|
+
warn(f"cache was corrupted, cannot decrypt: {err}")
|
|
110
|
+
pickled_ls = None
|
|
111
|
+
if pickled_ls:
|
|
112
|
+
return pickle.loads(pickled_ls)
|
|
113
|
+
|
|
114
|
+
return None
|
|
115
|
+
|
|
111
116
|
|
|
112
|
-
return None
|
|
113
117
|
def update_credentials_in_keyring(ls, args):
|
|
114
|
-
|
|
118
|
+
print(
|
|
119
|
+
"""
|
|
115
120
|
This login process is exactly the same as when you log in using
|
|
116
121
|
the web browser. You need three things:
|
|
117
122
|
|
|
@@ -126,57 +131,66 @@ the web browser. You need three things:
|
|
|
126
131
|
|
|
127
132
|
3) Your password at your institution.
|
|
128
133
|
|
|
129
|
-
"""
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
"""
|
|
135
|
+
)
|
|
136
|
+
while True:
|
|
137
|
+
institution = input("Institution: ")
|
|
138
|
+
matches = sa.find_entity_data_by_name(institution)
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
140
|
+
if not matches:
|
|
141
|
+
print("No match, try again.")
|
|
142
|
+
continue
|
|
137
143
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
144
|
+
if len(matches) > 1:
|
|
145
|
+
print("More than one match. Which one?")
|
|
146
|
+
for match in matches:
|
|
147
|
+
print(f"- {match['title']}")
|
|
148
|
+
continue
|
|
143
149
|
|
|
144
|
-
|
|
150
|
+
match = matches[0]
|
|
145
151
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
152
|
+
print(
|
|
153
|
+
f"Matched uniquely, using {match['title']}\n"
|
|
154
|
+
f" with domain {match['domain']} and\n"
|
|
155
|
+
f" unique identifier {match['id']}."
|
|
156
|
+
)
|
|
149
157
|
|
|
150
|
-
|
|
151
|
-
|
|
158
|
+
institution = match["id"]
|
|
159
|
+
break
|
|
152
160
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
161
|
+
vars = {
|
|
162
|
+
"username": input("Institution username: "),
|
|
163
|
+
"password": getpass.getpass("Institution password: [input is hidden] "),
|
|
164
|
+
}
|
|
165
|
+
while True:
|
|
166
|
+
temp_ls = ladok3.LadokSession(institution, vars=vars)
|
|
167
|
+
|
|
168
|
+
try:
|
|
169
|
+
temp_ls.user_info_JSON()
|
|
170
|
+
except weblogin.AuthenticationError as err:
|
|
171
|
+
adjust_vars(vars, err.variables)
|
|
172
|
+
else:
|
|
173
|
+
break
|
|
159
174
|
|
|
160
175
|
try:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
clear_cache(ls, args)
|
|
176
|
+
keyring.set_password("ladok3", "institution", institution)
|
|
177
|
+
keyring.set_password("ladok3", "vars", ";".join(vars.keys()))
|
|
178
|
+
for key, value in vars.items():
|
|
179
|
+
keyring.set_password("ladok3", key, value)
|
|
180
|
+
except Exception as err:
|
|
181
|
+
globals()["err"](
|
|
182
|
+
-1,
|
|
183
|
+
f"You don't seem to have a working keyring. "
|
|
184
|
+
f"Use one of the other methods, see "
|
|
185
|
+
f"`ladok login -h`: {err}.",
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
clear_cache(ls, args)
|
|
189
|
+
|
|
190
|
+
|
|
178
191
|
def adjust_vars(vars, form_variables):
|
|
179
|
-
|
|
192
|
+
print(
|
|
193
|
+
"""
|
|
180
194
|
Some part of the authentication went wrong. Either you typed your username or
|
|
181
195
|
password incorrectly, or your institution requires some adjustments. We'll
|
|
182
196
|
guide you through it.
|
|
@@ -191,103 +205,115 @@ when it should be 'dbosk@ug.kth.se' --- or something similar. Use your
|
|
|
191
205
|
institution's login page to figure this out.
|
|
192
206
|
|
|
193
207
|
Note: Your password will be visible on screen during this process.
|
|
194
|
-
"""
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
key
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
208
|
+
"""
|
|
209
|
+
)
|
|
210
|
+
input("\nPress return to continue.\n")
|
|
211
|
+
|
|
212
|
+
for key, value in form_variables.items():
|
|
213
|
+
key = key.casefold()
|
|
214
|
+
new_val = input(f"{key} = '{value}' " f"[enter new value, blank to keep] ")
|
|
215
|
+
if new_val:
|
|
216
|
+
vars[key] = new_val
|
|
217
|
+
|
|
218
|
+
|
|
203
219
|
def load_credentials(filename="config.json"):
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
220
|
+
"""
|
|
221
|
+
Loads credentials from environment or file named filename.
|
|
222
|
+
Returns the tuple (instituation, credential dictionary) that
|
|
223
|
+
can be passed to `LadokSession(instiution, credential dictionary)`.
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
try:
|
|
227
|
+
institution = keyring.get_password("ladok3", "institution")
|
|
228
|
+
vars_keys = keyring.get_password("ladok3", "vars")
|
|
229
|
+
|
|
230
|
+
vars = {}
|
|
231
|
+
for key in vars_keys.split(";"):
|
|
232
|
+
value = keyring.get_password("ladok3", key)
|
|
233
|
+
if value:
|
|
234
|
+
vars[key] = value
|
|
235
|
+
|
|
236
|
+
if institution and vars:
|
|
237
|
+
return institution, vars
|
|
238
|
+
except:
|
|
239
|
+
pass
|
|
240
|
+
try:
|
|
241
|
+
institution = "KTH Royal Institute of Technology"
|
|
242
|
+
username = keyring.get_password("ladok3", "username")
|
|
243
|
+
password = keyring.get_password("ladok3", "password")
|
|
244
|
+
if username and password:
|
|
245
|
+
return institution, {"username": username, "password": password}
|
|
246
|
+
except:
|
|
247
|
+
pass
|
|
248
|
+
try:
|
|
249
|
+
institution = os.environ["LADOK_INST"]
|
|
250
|
+
except:
|
|
251
|
+
institution = "KTH Royal Institute of Technology"
|
|
252
|
+
|
|
253
|
+
try:
|
|
254
|
+
vars = {
|
|
255
|
+
"username": os.environ["LADOK_USER"],
|
|
256
|
+
"password": os.environ["LADOK_PASS"],
|
|
257
|
+
}
|
|
258
|
+
if institution and vars:
|
|
259
|
+
return institution, vars
|
|
260
|
+
except:
|
|
261
|
+
pass
|
|
262
|
+
try:
|
|
263
|
+
vars_keys = os.environ["LADOK_VARS"]
|
|
264
|
+
|
|
265
|
+
vars = {}
|
|
266
|
+
for key in vars_keys.split(":"):
|
|
267
|
+
try:
|
|
268
|
+
vars[key] = os.environ[key]
|
|
269
|
+
except KeyError:
|
|
270
|
+
warn(f"Variable {key} not set, ignoring.")
|
|
271
|
+
|
|
272
|
+
if institution and vars:
|
|
273
|
+
return institution, vars
|
|
274
|
+
except:
|
|
275
|
+
pass
|
|
276
|
+
try:
|
|
277
|
+
with open(filename) as conf_file:
|
|
278
|
+
config = json.load(conf_file)
|
|
279
|
+
|
|
280
|
+
institution = config.pop("institution", "KTH Royal Institute of Technology")
|
|
281
|
+
return institution, config
|
|
282
|
+
except:
|
|
283
|
+
pass
|
|
284
|
+
|
|
285
|
+
return None, None
|
|
286
|
+
|
|
287
|
+
|
|
264
288
|
def clear_cache(ls, args):
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
289
|
+
try:
|
|
290
|
+
os.remove(dirs.user_cache_dir + "/LadokSession")
|
|
291
|
+
except FileNotFoundError as err:
|
|
292
|
+
pass
|
|
293
|
+
|
|
294
|
+
sys.exit(0)
|
|
295
|
+
|
|
269
296
|
|
|
270
|
-
sys.exit(0)
|
|
271
297
|
def main():
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
required=True
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
298
|
+
"""Run the command-line interface for the ladok command"""
|
|
299
|
+
argp = argparse.ArgumentParser(
|
|
300
|
+
description="This is a CLI-ification of LADOK3's web GUI.",
|
|
301
|
+
epilog="Web: https://github.com/dbosk/ladok3",
|
|
302
|
+
)
|
|
303
|
+
argp.add_argument(
|
|
304
|
+
"-f",
|
|
305
|
+
"--config-file",
|
|
306
|
+
default=f"{dirs.user_config_dir}/config.json",
|
|
307
|
+
help="Path to configuration file "
|
|
308
|
+
f"(default: {dirs.user_config_dir}/config.json) "
|
|
309
|
+
"or set LADOK_USER and LADOK_PASS environment variables.",
|
|
310
|
+
)
|
|
311
|
+
subp = argp.add_subparsers(title="commands", dest="command", required=True)
|
|
312
|
+
login_parser = subp.add_parser(
|
|
313
|
+
"login",
|
|
314
|
+
help="Manage login credentials",
|
|
315
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
316
|
+
description=f"""
|
|
291
317
|
Manages the user's LADOK login credentials. There are three ways to supply the
|
|
292
318
|
login credentials, in order of priority:
|
|
293
319
|
|
|
@@ -317,42 +343,40 @@ def main():
|
|
|
317
343
|
option). (The keys 'username' and 'password' can be renamed to correspond to
|
|
318
344
|
the necessary values if the university login system uses other names.)
|
|
319
345
|
|
|
320
|
-
"""
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
ls
|
|
349
|
-
|
|
350
|
-
args.func(ls, args)
|
|
351
|
-
store_ladok_session(ls, LADOK_VARS)
|
|
346
|
+
""",
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
login_parser.set_defaults(func=update_credentials_in_keyring)
|
|
350
|
+
cache_parser = subp.add_parser(
|
|
351
|
+
"cache", help="Manage cache", description="Manages the cache of LADOK data"
|
|
352
|
+
)
|
|
353
|
+
cache_subp = cache_parser.add_subparsers(
|
|
354
|
+
title="subcommands", dest="subcommand", required=True
|
|
355
|
+
)
|
|
356
|
+
cache_clear = cache_subp.add_parser(
|
|
357
|
+
"clear", help="Clear the cache", description="Clears everything from the cache"
|
|
358
|
+
)
|
|
359
|
+
cache_clear.set_defaults(func=clear_cache)
|
|
360
|
+
ladok3.data.add_command_options(subp)
|
|
361
|
+
ladok3.report.add_command_options(subp)
|
|
362
|
+
ladok3.student.add_command_options(subp)
|
|
363
|
+
argcomplete.autocomplete(argp)
|
|
364
|
+
args = argp.parse_args()
|
|
365
|
+
LADOK_INST, LADOK_VARS = load_credentials(args.config_file)
|
|
366
|
+
try:
|
|
367
|
+
ls = restore_ladok_session(LADOK_VARS)
|
|
368
|
+
except ValueError as error:
|
|
369
|
+
err(-1, f"Couldn't restore LADOK session: {error}")
|
|
370
|
+
if not ls:
|
|
371
|
+
ls = ladok3.LadokSession(LADOK_INST, vars=LADOK_VARS)
|
|
372
|
+
if "func" in args:
|
|
373
|
+
args.func(ls, args)
|
|
374
|
+
store_ladok_session(ls, LADOK_VARS)
|
|
375
|
+
|
|
352
376
|
|
|
353
377
|
if __name__ == "__main__":
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
378
|
+
try:
|
|
379
|
+
main()
|
|
380
|
+
sys.exit(0)
|
|
381
|
+
except Exception as e:
|
|
382
|
+
err(-1, e)
|