Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion cms/grading/languagemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@

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

import logging
from cms import plugin_list
from cms.grading.language import Language


__all__ = [
"LANGUAGES",
"HEADER_EXTS", "SOURCE_EXTS", "OBJECT_EXTS",
"get_language", "filename_to_language"
]


logger = logging.getLogger(__name__)


LANGUAGES: list[Language] = list()
_BY_NAME: dict[str, Language] = dict()
HEADER_EXTS: set[str] = set()
Expand All @@ -50,6 +53,25 @@ def get_language(name: str) -> Language:
return _BY_NAME[name]


def safe_get_lang_filename(lang: str | None, filename: str) -> str:
"""Get the filename of a file in a specific programming language,
avoiding errors if the language isn't recognized.

lang: name of the programming language
filename: filename template (containing .%l)
return: filename with the template replaced.
"""
if lang is None:
return filename
try:
language = get_language(lang)
source_ext = language.source_extension
except KeyError:
logger.warning(f"Found invalid language {lang}!")
source_ext = ".invalid_language"
return filename.replace(".%l", source_ext)


def filename_to_language(filename: str, available_languages: list[Language] | None=None) -> Language | None:
"""Return one of the languages inferred from the given filename.

Expand Down
12 changes: 4 additions & 8 deletions cms/server/admin/handlers/submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import difflib

from cms.db import Dataset, File, Submission
from cms.grading.languagemanager import get_language
from cms.grading.languagemanager import safe_get_lang_filename
from cmscommon.datetime import make_datetime
from .base import BaseHandler, FileHandler, require_permission

Expand Down Expand Up @@ -80,10 +80,7 @@ def get(self, file_id):
sub_file = self.safe_get_item(File, file_id)
submission = sub_file.submission

real_filename = sub_file.filename
if submission.language is not None:
real_filename = real_filename.replace(
".%l", get_language(submission.language).source_extension)
real_filename = safe_get_lang_filename(submission.language, sub_file.filename)
digest = sub_file.digest

self.sql_session.close()
Expand Down Expand Up @@ -130,10 +127,9 @@ def get(self, old_id, new_id):
for fname in files_to_compare:
if ".%l" in fname:
if sub_old.language == sub_new.language and sub_old.language is not None:
ext = get_language(sub_old.language).source_extension
real_fname = safe_get_lang_filename(sub_old.language, fname)
else:
ext = ".txt"
real_fname = fname.replace(".%l", ext)
real_fname = fname.replace(".%l", ".txt")
else:
real_fname = fname

Expand Down
7 changes: 2 additions & 5 deletions cms/server/admin/handlers/usertest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"""

from cms.db import Dataset, UserTestFile, UserTest
from cms.grading.languagemanager import get_language
from cms.grading.languagemanager import safe_get_lang_filename

from .base import BaseHandler, FileHandler, require_permission

Expand Down Expand Up @@ -60,10 +60,7 @@ def get(self, file_id):
user_test_file = self.safe_get_item(UserTestFile, file_id)
user_test = user_test_file.user_test

real_filename = user_test_file.filename
if user_test.language is not None:
real_filename = real_filename.replace(
".%l", get_language(user_test.language).source_extension)
real_filename = safe_get_lang_filename(user_test.language, user_test_file.filename)
digest = user_test_file.digest

self.sql_session.close()
Expand Down
2 changes: 1 addition & 1 deletion cms/server/admin/templates/fragments/user_test_row.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ <h3>Compilation output</h3>{# TODO: trim long outputs and add facility to see ra
</td>
<td>
{% for filename, sub_file in ut.files|dictsort(by="key") %}
{% set real_filename = filename if ut.language is none else filename|replace(".%l", (ut.language|to_language).source_extension) %}
{% set real_filename = get_lang_filename(ut.language, filename) %}
<a href="javascript:void(0);" onclick="utils.show_file('{{ real_filename }}','{{ url("user_test_file", sub_file.id) }}')">{{ real_filename }}</a><br/>
{% endfor %}
</td>
Expand Down
2 changes: 1 addition & 1 deletion cms/server/admin/templates/macro/submission.html
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ <h3>Compilation output</h3>{# TODO: trim long outputs and add facility to see ra
</td>
<td>
{% for filename, sub_file in s.files|dictsort(by="key") %}
{% set real_filename = filename if s.language is none else filename|replace(".%l", (s.language|to_language).source_extension) %}
{% set real_filename = get_lang_filename(s.language, filename) %}
<a href="javascript:void(0);" onclick="utils.show_file('{{ real_filename }}','{{ url("submission_file", sub_file.id) }}')">{{ real_filename }}</a><br/>
{% endfor %}
</td>
Expand Down
12 changes: 8 additions & 4 deletions cms/server/admin/templates/submission.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ <h2 id="title_details" class="toggling_on">Submission details</h2>
<td>
{% for filename in s.task.submission_format %}
{% if filename in s.files %}
{% set real_filename = filename if s.language is none else filename|replace(".%l", (s.language|to_language).source_extension) %}
{% set real_filename = get_lang_filename(s.language, filename) %}
<a href="javascript:void(0);" onclick="utils.show_file('{{ real_filename }}','{{ url("submission_file", s.files[filename].id) }}')">
{{ real_filename }}
</a>
Expand Down Expand Up @@ -234,10 +234,14 @@ <h2 id="title_evaluation_user" class="toggling_on">Evaluation (as seen by the us
<div id="evaluation_user">

<div class="score_details" id="evaluation_{{ s.id }}">
{% if s.tokened() %}
{{ st.get_html_details(sr.score_details, s.task.feedback_level)|safe }}
{% if st is defined %}
{% if s.tokened() %}
{{ st.get_html_details(sr.score_details, s.task.feedback_level)|safe }}
{% else %}
{{ st.get_html_details(sr.public_score_details, s.task.feedback_level)|safe }}
{% endif %}
{% else %}
{{ st.get_html_details(sr.public_score_details, s.task.feedback_level)|safe }}
[Cannot get score type - see logs]
{% endif %}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion cms/server/admin/templates/user_test.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ <h2 id="title_details" class="toggling_on">User test details</h2>
<td>
{% for filename in ut.task.submission_format %}
{% if filename in ut.files %}
{% set real_filename = filename if ut.language is none else filename|replace(".%l", (ut.language|to_language).source_extension) %}
{% set real_filename = get_lang_filename(ut.language, filename) %}
<a href="javascript:void(0);" onclick="utils.show_file('{{ real_filename }}','{{ url("user_test_file", ut.files[filename].id) }}')">
{{ real_filename }}
</a>
Expand Down
4 changes: 2 additions & 2 deletions cms/server/jinja2_toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from cms.db import SubmissionResult, UserTestResult
from cms.db.task import Dataset
from cms.grading import format_status_text
from cms.grading.languagemanager import get_language
from cms.grading.languagemanager import get_language, safe_get_lang_filename
from cms.locale import Translation, DEFAULT_TRANSLATION
from cmscommon.constants import \
SCORE_MODE_MAX, SCORE_MODE_MAX_SUBTASK, SCORE_MODE_MAX_TOKENED_LAST
Expand Down Expand Up @@ -204,10 +204,10 @@ def safe_get_score_type(env: Environment, *, dataset: Dataset):
except Exception as err:
return env.undefined("ScoreType not found: %s" % err)


def instrument_cms_toolbox(env: Environment):
env.globals["get_task_type"] = safe_get_task_type
env.globals["get_score_type"] = safe_get_score_type
env.globals["get_lang_filename"] = safe_get_lang_filename

env.globals["get_mimetype_for_file_name"] = get_type_for_file_name
env.globals["get_icon_for_mimetype"] = get_icon_for_type
Expand Down