Skip to content

Commit 79fbefe

Browse files
authored
make AWS more resilient towards missing ScoreTypes and Languages (#1460)
1 parent f53345d commit 79fbefe

File tree

8 files changed

+42
-23
lines changed

8 files changed

+42
-23
lines changed

cms/grading/languagemanager.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,20 @@
1818

1919
"""Provide utilities to work with programming language classes."""
2020

21+
import logging
2122
from cms import plugin_list
2223
from cms.grading.language import Language
2324

24-
2525
__all__ = [
2626
"LANGUAGES",
2727
"HEADER_EXTS", "SOURCE_EXTS", "OBJECT_EXTS",
2828
"get_language", "filename_to_language"
2929
]
3030

3131

32+
logger = logging.getLogger(__name__)
33+
34+
3235
LANGUAGES: list[Language] = list()
3336
_BY_NAME: dict[str, Language] = dict()
3437
HEADER_EXTS: set[str] = set()
@@ -50,6 +53,25 @@ def get_language(name: str) -> Language:
5053
return _BY_NAME[name]
5154

5255

56+
def safe_get_lang_filename(lang: str | None, filename: str) -> str:
57+
"""Get the filename of a file in a specific programming language,
58+
avoiding errors if the language isn't recognized.
59+
60+
lang: name of the programming language
61+
filename: filename template (containing .%l)
62+
return: filename with the template replaced.
63+
"""
64+
if lang is None:
65+
return filename
66+
try:
67+
language = get_language(lang)
68+
source_ext = language.source_extension
69+
except KeyError:
70+
logger.warning(f"Found invalid language {lang}!")
71+
source_ext = ".invalid_language"
72+
return filename.replace(".%l", source_ext)
73+
74+
5375
def filename_to_language(filename: str, available_languages: list[Language] | None=None) -> Language | None:
5476
"""Return one of the languages inferred from the given filename.
5577

cms/server/admin/handlers/submission.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import difflib
3232

3333
from cms.db import Dataset, File, Submission
34-
from cms.grading.languagemanager import get_language
34+
from cms.grading.languagemanager import safe_get_lang_filename
3535
from cmscommon.datetime import make_datetime
3636
from .base import BaseHandler, FileHandler, require_permission
3737

@@ -80,10 +80,7 @@ def get(self, file_id):
8080
sub_file = self.safe_get_item(File, file_id)
8181
submission = sub_file.submission
8282

83-
real_filename = sub_file.filename
84-
if submission.language is not None:
85-
real_filename = real_filename.replace(
86-
".%l", get_language(submission.language).source_extension)
83+
real_filename = safe_get_lang_filename(submission.language, sub_file.filename)
8784
digest = sub_file.digest
8885

8986
self.sql_session.close()
@@ -130,10 +127,9 @@ def get(self, old_id, new_id):
130127
for fname in files_to_compare:
131128
if ".%l" in fname:
132129
if sub_old.language == sub_new.language and sub_old.language is not None:
133-
ext = get_language(sub_old.language).source_extension
130+
real_fname = safe_get_lang_filename(sub_old.language, fname)
134131
else:
135-
ext = ".txt"
136-
real_fname = fname.replace(".%l", ext)
132+
real_fname = fname.replace(".%l", ".txt")
137133
else:
138134
real_fname = fname
139135

cms/server/admin/handlers/usertest.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"""
2222

2323
from cms.db import Dataset, UserTestFile, UserTest
24-
from cms.grading.languagemanager import get_language
24+
from cms.grading.languagemanager import safe_get_lang_filename
2525

2626
from .base import BaseHandler, FileHandler, require_permission
2727

@@ -60,10 +60,7 @@ def get(self, file_id):
6060
user_test_file = self.safe_get_item(UserTestFile, file_id)
6161
user_test = user_test_file.user_test
6262

63-
real_filename = user_test_file.filename
64-
if user_test.language is not None:
65-
real_filename = real_filename.replace(
66-
".%l", get_language(user_test.language).source_extension)
63+
real_filename = safe_get_lang_filename(user_test.language, user_test_file.filename)
6764
digest = user_test_file.digest
6865

6966
self.sql_session.close()

cms/server/admin/templates/fragments/user_test_row.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ <h3>Compilation output</h3>{# TODO: trim long outputs and add facility to see ra
5252
</td>
5353
<td>
5454
{% for filename, sub_file in ut.files|dictsort(by="key") %}
55-
{% set real_filename = filename if ut.language is none else filename|replace(".%l", (ut.language|to_language).source_extension) %}
55+
{% set real_filename = get_lang_filename(ut.language, filename) %}
5656
<a href="javascript:void(0);" onclick="utils.show_file('{{ real_filename }}','{{ url("user_test_file", sub_file.id) }}')">{{ real_filename }}</a><br/>
5757
{% endfor %}
5858
</td>

cms/server/admin/templates/macro/submission.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ <h3>Compilation output</h3>{# TODO: trim long outputs and add facility to see ra
165165
</td>
166166
<td>
167167
{% for filename, sub_file in s.files|dictsort(by="key") %}
168-
{% set real_filename = filename if s.language is none else filename|replace(".%l", (s.language|to_language).source_extension) %}
168+
{% set real_filename = get_lang_filename(s.language, filename) %}
169169
<a href="javascript:void(0);" onclick="utils.show_file('{{ real_filename }}','{{ url("submission_file", sub_file.id) }}')">{{ real_filename }}</a><br/>
170170
{% endfor %}
171171
</td>

cms/server/admin/templates/submission.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ <h2 id="title_details" class="toggling_on">Submission details</h2>
4848
<td>
4949
{% for filename in s.task.submission_format %}
5050
{% if filename in s.files %}
51-
{% set real_filename = filename if s.language is none else filename|replace(".%l", (s.language|to_language).source_extension) %}
51+
{% set real_filename = get_lang_filename(s.language, filename) %}
5252
<a href="javascript:void(0);" onclick="utils.show_file('{{ real_filename }}','{{ url("submission_file", s.files[filename].id) }}')">
5353
{{ real_filename }}
5454
</a>
@@ -234,10 +234,14 @@ <h2 id="title_evaluation_user" class="toggling_on">Evaluation (as seen by the us
234234
<div id="evaluation_user">
235235

236236
<div class="score_details" id="evaluation_{{ s.id }}">
237-
{% if s.tokened() %}
238-
{{ st.get_html_details(sr.score_details, s.task.feedback_level)|safe }}
237+
{% if st is defined %}
238+
{% if s.tokened() %}
239+
{{ st.get_html_details(sr.score_details, s.task.feedback_level)|safe }}
240+
{% else %}
241+
{{ st.get_html_details(sr.public_score_details, s.task.feedback_level)|safe }}
242+
{% endif %}
239243
{% else %}
240-
{{ st.get_html_details(sr.public_score_details, s.task.feedback_level)|safe }}
244+
[Cannot get score type - see logs]
241245
{% endif %}
242246
</div>
243247
</div>

cms/server/admin/templates/user_test.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ <h2 id="title_details" class="toggling_on">User test details</h2>
4141
<td>
4242
{% for filename in ut.task.submission_format %}
4343
{% if filename in ut.files %}
44-
{% set real_filename = filename if ut.language is none else filename|replace(".%l", (ut.language|to_language).source_extension) %}
44+
{% set real_filename = get_lang_filename(ut.language, filename) %}
4545
<a href="javascript:void(0);" onclick="utils.show_file('{{ real_filename }}','{{ url("user_test_file", ut.files[filename].id) }}')">
4646
{{ real_filename }}
4747
</a>

cms/server/jinja2_toolbox.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from cms.db import SubmissionResult, UserTestResult
3838
from cms.db.task import Dataset
3939
from cms.grading import format_status_text
40-
from cms.grading.languagemanager import get_language
40+
from cms.grading.languagemanager import get_language, safe_get_lang_filename
4141
from cms.locale import Translation, DEFAULT_TRANSLATION
4242
from cmscommon.constants import \
4343
SCORE_MODE_MAX, SCORE_MODE_MAX_SUBTASK, SCORE_MODE_MAX_TOKENED_LAST
@@ -204,10 +204,10 @@ def safe_get_score_type(env: Environment, *, dataset: Dataset):
204204
except Exception as err:
205205
return env.undefined("ScoreType not found: %s" % err)
206206

207-
208207
def instrument_cms_toolbox(env: Environment):
209208
env.globals["get_task_type"] = safe_get_task_type
210209
env.globals["get_score_type"] = safe_get_score_type
210+
env.globals["get_lang_filename"] = safe_get_lang_filename
211211

212212
env.globals["get_mimetype_for_file_name"] = get_type_for_file_name
213213
env.globals["get_icon_for_mimetype"] = get_icon_for_type

0 commit comments

Comments
 (0)