Skip to content

Commit c59ed84

Browse files
Fix LDM issue + handle scenario if one is teaching or registered for an NUS offering
1 parent 1df3421 commit c59ed84

File tree

5 files changed

+78
-61
lines changed

5 files changed

+78
-61
lines changed

autokattis/api/nuskattis.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,13 +446,21 @@ def offerings(self, course_id):
446446
[
447447
{
448448
"name": "CS2040_S1_AY2425",
449-
"end_date": "2024-12-08"
449+
"status": "teaching",
450+
"end_date": "2024-12-08",
450451
"link": "https://nus.kattis.com/courses/CS2040/CS2040_S1_AY2425"
451452
},
452453
{
453454
"name": "CS2040_S2_AY2324",
454-
"end_date": "2024-05-06"
455+
"status": "registered",
456+
"end_date": "2024-05-06",
455457
"link": "https://nus.kattis.com/courses/CS2040/CS2040_S2_AY2324"
458+
},
459+
{
460+
"name": "CS2040_S2_AY2425",
461+
"status": "N/A",
462+
"end_date": "2025-05-03",
463+
"link": "https://nus.kattis.com/courses/CS2040/CS2040_S2_AY2425"
456464
}
457465
]
458466
'''
@@ -466,8 +474,10 @@ def offerings(self, course_id):
466474
try:
467475
name, end_date = [truncate_spaces(column.text.strip()) for column in columns]
468476
link, _ = [column.find('a') for column in columns]
477+
name_split = name.split('\n')
469478
data.append({
470-
'name': name.replace('\n', ''),
479+
'name': name_split[0], # special example: CS2040_S2_AY2324\n \n\n \xa0(teaching)
480+
'status': 'N/A' if len(name_split) == 1 else name_split[-1][name_split[-1].find('(')+1:name_split[-1].find(')')],
471481
'end_date': end_date.split()[1][:-1],
472482
'link': self.get_base_url() + link.get('href')
473483
})
@@ -504,7 +514,9 @@ def assignments(self, offering_id, course_id=None):
504514
# try to guess
505515
for cid in self.courses().to_df().course_id:
506516
if offering_id in [*self.offerings(cid).to_df().name]: course_id = cid; break
507-
assert course_id != None, '[assignments] Cannot guess course ID automatically, please provide one'
517+
if course_id == None:
518+
print('[assignments] Cannot guess course ID automatically, please provide one', flush=True)
519+
return self.Result([])
508520
print('[assignments] Guessed course ID:', course_id, flush=True)
509521

510522
soup = self.get_soup_response(f'{self.get_base_url()}/courses/{course_id}/{offering_id}')

autokattis/api/openkattis.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,16 @@ def problems(self, show_solved=True, show_partial=True, show_tried=False, show_u
9999
if low_detail_mode:
100100
# we can just take from the given dropdown list
101101
soup = self.get_soup_response(f'{self.get_base_url()}/users/{self.get_username()}?tab=submissions')
102-
for option in soup.find_all('option')[4:]:
103-
pid = option.get('value').strip()
104-
if not pid: break
105-
data.append({
106-
'name': option.text.strip(),
107-
'id': pid,
108-
'link': f"{self.get_base_url()}/problems/{pid}"
109-
})
102+
submissions = soup.find('div', {'id': 'submissions-tab'})
103+
if submissions:
104+
for option in submissions.find_all('option')[1:]: # first option is 'Any Problem'
105+
pid = option.get('value').strip()
106+
if not pid: break
107+
data.append({
108+
'name': option.text.strip(),
109+
'id': pid,
110+
'link': f"{self.get_base_url()}/problems/{pid}"
111+
})
110112
else:
111113
params = {
112114
'page': 1,

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup_args = dict(
77
name='autokattis',
8-
version='2.1.2',
8+
version='2.1.3',
99
description='Updated Kattis API wrapper',
1010
long_description_content_type="text/markdown",
1111
long_description=README,

test/nuskattis.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,28 @@
44

55
kt = NUSKattis(USER, PASSWORD)
66

7-
test('nus_problems_solved', kt.problems, {})
8-
test('nus_problems_all', kt.problems, {'show_solved': False})
7+
test('nus_01_problems_solved', kt.problems, {})
8+
test('nus_02_problems_all', kt.problems, {'show_solved': False})
99

10-
test('nus_problem_single_nodownload', kt.problem, {'problem_ids': 'magicsequence'})
11-
test('nus_problem_single_download', kt.problem, {'problem_ids': 'magicsequence', 'download_files': True})
12-
test('nus_problem_multiple_nodownload', kt.problem, {'problem_ids': ['magicsequence', 'racinggame', 'rationalsequence3']})
13-
test('nus_problem_multiple_download', kt.problem, {'problem_ids': {'magicsequence', 'racinggame', 'rationalsequence3'}, 'download_files': True})
14-
test('nus_problem_invalid', kt.problem, {'problem_ids': ('@?@?', 'ABC', 'finalexam')})
10+
test('nus_03_problem_single_nodownload', kt.problem, {'problem_ids': 'magicsequence'})
11+
test('nus_04_problem_single_download', kt.problem, {'problem_ids': 'magicsequence', 'download_files': True})
12+
test('nus_05_problem_multiple_nodownload', kt.problem, {'problem_ids': ['magicsequence', 'racinggame', 'rationalsequence3']})
13+
test('nus_06_problem_multiple_download', kt.problem, {'problem_ids': {'magicsequence', 'racinggame', 'rationalsequence3'}, 'download_files': True})
14+
test('nus_07_problem_invalid', kt.problem, {'problem_ids': ('@?@?', 'ABC', 'finalexam')})
1515

16-
test('nus_stats_all', kt.stats, {})
17-
test('nus_stats_single', kt.stats, {'languages': 'C++'})
18-
test('nus_stats_multiple', kt.stats, {'languages': ['C++', 'Python 3']})
19-
test('nus_stats_invalid', kt.stats, {'languages': ('@?@?', 'ABC')})
16+
test('nus_08_stats_all', kt.stats, {})
17+
test('nus_09_stats_single', kt.stats, {'languages': 'C++'})
18+
test('nus_10_stats_multiple', kt.stats, {'languages': ['C++', 'Python 3']})
19+
test('nus_11_stats_invalid', kt.stats, {'languages': ('@?@?', 'ABC')})
2020

21-
test('nus_courses', kt.courses, {})
21+
test('nus_12_courses', kt.courses, {})
2222

23-
test('nus_offerings_valid_1', kt.offerings, {'course_id': 'CS2040'})
24-
test('nus_offerings_valid_2', kt.offerings, {'course_id': 'CS3233'})
25-
test('nus_offerings_invalid', kt.offerings, {'course_id': 'idk'})
23+
test('nus_13_offerings_valid_1', kt.offerings, {'course_id': 'CS2040'})
24+
test('nus_14_offerings_valid_2', kt.offerings, {'course_id': 'CS3233'})
25+
test('nus_15_offerings_invalid', kt.offerings, {'course_id': 'idk'})
2626

27-
test('nus_assignments_courseid_guessed', kt.assignments, {'offering_id': 'CS2040_S1_AY2425'})
28-
test('nus_assignments_courseid_given', kt.assignments, {'offering_id': 'CS3233_S2_AY2223', 'course_id': 'CS3233'})
27+
test('nus_16_assignments_courseid_guessed_1', kt.assignments, {'offering_id': 'CS2040_S1_AY2425'})
28+
test('nus_17_assignments_courseid_guessed_2', kt.assignments, {'offering_id': 'CS3233_S2_AY2425'})
29+
test('nus_18_assignments_courseid_given', kt.assignments, {'offering_id': 'CS3233_S2_AY2223', 'course_id': 'CS3233'})
30+
test('nus_19_assignments_unknown_courseid', kt.assignments, {'offering_id': 'xyz'})
31+
test('nus_20_assignments_unknown_offeringid', kt.assignments, {'offering_id': 'xyz', 'course_id': 'CS3233'})

test/openkattis.py

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,46 @@
55
kt = Kattis(USER, PASSWORD)
66
kt = OpenKattis(USER, PASSWORD)
77

8-
test('open_problems_solved_fdm', kt.problems, {})
9-
test('open_problems_all_fdm', kt.problems, {'show_tried': True, 'show_untried': True})
10-
test('open_problems_ldm', kt.problems, {'low_detail_mode': True})
8+
test('open_01_problems_solved_fdm', kt.problems, {})
9+
test('open_02_problems_all_fdm', kt.problems, {'show_tried': True, 'show_untried': True})
10+
test('open_03_problems_ldm', kt.problems, {'low_detail_mode': True})
1111

12-
test('open_plot_problems_solved_nofile', kt.plot_problems, {})
13-
test('open_plot_problems_solved_file', kt.plot_problems, {'filepath': 'plot1.png'})
14-
test('open_plot_problems_all_file', kt.plot_problems, {'filepath': 'plot2.png', 'show_tried': True, 'show_untried': True})
12+
test('open_04_plot_problems_solved_nofile', kt.plot_problems, {})
13+
test('open_05_plot_problems_solved_file', kt.plot_problems, {'filepath': 'plot1.png'})
14+
test('open_06_plot_problems_all_file', kt.plot_problems, {'filepath': 'plot2.png', 'show_tried': True, 'show_untried': True})
1515

16-
test('open_problem_single_nodownload', kt.problem, {'problem_ids': '2048'})
17-
test('open_problem_single_download', kt.problem, {'problem_ids': '2048', 'download_files': True})
18-
test('open_problem_partial_scoring', kt.problem, {'problem_ids': 'golf'})
19-
test('open_problem_multiple_nodownload', kt.problem, {'problem_ids': ['2048', 'abinitio', 'teque']})
20-
test('open_problem_multiple_download', kt.problem, {'problem_ids': {'2048', 'abinitio', 'teque'}, 'download_files': True})
21-
test('open_problem_invalid', kt.problem, {'problem_ids': ('@?@?', 'ABC')})
16+
test('open_07_problem_single_nodownload', kt.problem, {'problem_ids': '2048'})
17+
test('open_08_problem_single_download', kt.problem, {'problem_ids': '2048', 'download_files': True})
18+
test('open_09_problem_partial_scoring', kt.problem, {'problem_ids': 'golf'})
19+
test('open_10_problem_multiple_nodownload', kt.problem, {'problem_ids': ['2048', 'abinitio', 'teque']})
20+
test('open_11_problem_multiple_download', kt.problem, {'problem_ids': {'2048', 'abinitio', 'teque'}, 'download_files': True})
21+
test('open_12_problem_invalid', kt.problem, {'problem_ids': ('@?@?', 'ABC')})
2222

23-
test('open_achievements', kt.achievements, {})
23+
test('open_13_achievements', kt.achievements, {})
2424

25-
test('open_stats_all', kt.stats, {})
26-
test('open_stats_single', kt.stats, {'languages': 'C++'})
27-
test('open_stats_multiple', kt.stats, {'languages': ['C++', 'Python 3']})
28-
test('open_stats_invalid', kt.stats, {'languages': ('@?@?', 'ABC')})
25+
test('open_14_stats_all', kt.stats, {})
26+
test('open_15_stats_single', kt.stats, {'languages': 'C++'})
27+
test('open_16_stats_multiple', kt.stats, {'languages': ['C++', 'Python 3']})
28+
test('open_17_stats_invalid', kt.stats, {'languages': ('@?@?', 'ABC')})
2929

30-
test('open_suggest', kt.suggest, {})
30+
test('open_18_suggest', kt.suggest, {})
3131

32-
test('open_user_ranklist', kt.user_ranklist, {})
32+
test('open_19_user_ranklist', kt.user_ranklist, {})
3333

34-
test('open_country_ranklist_top100', kt.country_ranklist, {})
35-
test('open_country_ranklist_specific_1', kt.country_ranklist, {'value': 'SGP'})
36-
test('open_country_ranklist_specific_2', kt.country_ranklist, {'value': 'Singapore'})
37-
test('open_country_ranklist_specific_3', kt.country_ranklist, {'value': 'ISL'})
34+
test('open_20_country_ranklist_top100', kt.country_ranklist, {})
35+
test('open_21_country_ranklist_specific_1', kt.country_ranklist, {'value': 'SGP'})
36+
test('open_22_country_ranklist_specific_2', kt.country_ranklist, {'value': 'Singapore'})
37+
test('open_23_country_ranklist_specific_3', kt.country_ranklist, {'value': 'ISL'})
3838

39-
test('open_affiliation_ranklist_top100', kt.affiliation_ranklist, {})
40-
test('open_affiliation_ranklist_specific_1', kt.affiliation_ranklist, {'value': 'nus.edu.sg'})
41-
test('open_affiliation_ranklist_specific_2', kt.affiliation_ranklist, {'value': 'National University of Singapore'})
42-
test('open_affiliation_ranklist_specific_3', kt.affiliation_ranklist, {'value': 'ru.is'})
39+
test('open_24_affiliation_ranklist_top100', kt.affiliation_ranklist, {})
40+
test('open_25_affiliation_ranklist_specific_1', kt.affiliation_ranklist, {'value': 'nus.edu.sg'})
41+
test('open_26_affiliation_ranklist_specific_2', kt.affiliation_ranklist, {'value': 'National University of Singapore'})
42+
test('open_27_affiliation_ranklist_specific_3', kt.affiliation_ranklist, {'value': 'ru.is'})
4343

44-
test('open_challenge_ranklist', kt.challenge_ranklist, {})
44+
test('open_28_challenge_ranklist', kt.challenge_ranklist, {})
4545

46-
test('open_ranklist', kt.ranklist, {})
46+
test('open_29_ranklist', kt.ranklist, {})
4747

48-
test('open_problem_authors', kt.problem_authors, {})
48+
test('open_30_problem_authors', kt.problem_authors, {})
4949

50-
test('open_problem_sources', kt.problem_sources, {})
50+
test('open_31_problem_sources', kt.problem_sources, {})

0 commit comments

Comments
 (0)