Skip to content

Commit

Permalink
Add support to import module model solution from gitmanager
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikael-Lenander committed Sep 2, 2023
1 parent a932c51 commit 6efc054
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 22 deletions.
62 changes: 42 additions & 20 deletions edit_course/operations/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,39 @@ def parse_choices(value, choices, field_name, errors):
return parsed_value


def parse_reveal_rule(rule_config, rule_key, errors):
if not isinstance(rule_config, dict) or "trigger" not in rule_config:
errors.append(format_lazy(_('REVEAL_RULE_ERROR_INVALID_JSON -- {key}'), key=rule_key))
return None
trigger = parse_choices(rule_config["trigger"], {
"immediate": RevealRule.TRIGGER.IMMEDIATE,
"manual": RevealRule.TRIGGER.MANUAL,
"time": RevealRule.TRIGGER.TIME,
"deadline": RevealRule.TRIGGER.DEADLINE,
"deadline_all": RevealRule.TRIGGER.DEADLINE_ALL,
"deadline_or_full_points": RevealRule.TRIGGER.DEADLINE_OR_FULL_POINTS,
"completion": RevealRule.TRIGGER.COMPLETION,
}, "trigger", errors)
rule = RevealRule()
rule.trigger = trigger
if "time" in rule_config:
rule.time = parse_date(rule_config["time"], errors)
if "delay_minutes" in rule_config:
rule.delay_minutes = parse_int(rule_config["delay_minutes"], errors)
rule.save()
return rule


def parse_model_solution_chapter(value, errors):
try:
module_key, chapter_key = value.split('/')
chapter = CourseChapter.objects.get(url=chapter_key, course_module__url=module_key)
return chapter
except CourseChapter.DoesNotExist:
errors.append(format_lazy(_('ERROR_MODEL_SOLUTION_CHAPTER_NOT_FOUND -- {value}'), value=value))
return None


def remove_newlines(value):
# Replace all newlines with a space.
# \r\n is done first to avoid two consecutive spaces.
Expand Down Expand Up @@ -264,28 +297,11 @@ def update_learning_objects( # noqa: MC0001
rule_config = o.get(config_key)
if not rule_config:
continue
if not isinstance(rule_config, dict) or "trigger" not in rule_config:
errors.append(format_lazy(_('REVEAL_RULE_ERROR_INVALID_JSON -- {key}'), key=config_key))
continue
trigger = parse_choices(rule_config["trigger"], {
"immediate": RevealRule.TRIGGER.IMMEDIATE,
"manual": RevealRule.TRIGGER.MANUAL,
"time": RevealRule.TRIGGER.TIME,
"deadline": RevealRule.TRIGGER.DEADLINE,
"deadline_all": RevealRule.TRIGGER.DEADLINE_ALL,
"deadline_or_full_points": RevealRule.TRIGGER.DEADLINE_OR_FULL_POINTS,
"completion": RevealRule.TRIGGER.COMPLETION,
}, "trigger", errors)
rule = getattr(lobject, lobject_key)
if not rule:
rule = RevealRule()
rule.trigger = trigger
if "time" in rule_config:
rule.time = parse_date(rule_config["time"], errors)
if "delay_minutes" in rule_config:
rule.delay_minutes = parse_int(rule_config["delay_minutes"], errors)
rule.save()
setattr(lobject, lobject_key, rule)
rule = parse_reveal_rule(rule_config, config_key, errors)
if rule:
setattr(lobject, lobject_key, rule)
if "grading_mode" in o:
grading_mode = parse_choices(o["grading_mode"], {
"best": BaseExercise.GRADING_MODE.BEST,
Expand Down Expand Up @@ -883,6 +899,12 @@ def configure(instance: CourseInstance, new_config: dict) -> Tuple[bool, List[st
f = parse_float(m["late_penalty"], errors)
if f is not None:
module.late_submission_penalty = f
if "model_answer" in m:
module.model_answer = parse_model_solution_chapter(m["model_answer"], errors)
if "reveal_module_model_solution" in m:
module.model_solution_reveal_rule = parse_reveal_rule(
m["reveal_module_model_solution"], "reveal_module_model_solution", errors
)

module.full_clean()
module.save()
Expand Down
4 changes: 4 additions & 0 deletions exercise/reveal_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ def __init__(self, module: Union[CourseModule, Dict[str, Any]], student: Optiona
self.max_deviation: Optional[DeadlineRuleDeviation] = None

def get_deadline(self) -> Optional[datetime.datetime]:
if len(self.exercises) == 0:
return None
return max(_get_exercise_deadline(exercise) for exercise in self.exercises)

def get_latest_deadline(self) -> Optional[datetime.datetime]:
Expand All @@ -166,6 +168,8 @@ def get_latest_deadline(self) -> Optional[datetime.datetime]:
deadlines.append(
self.max_deviation.get_new_deadline(exercise_dict[self.max_deviation.exercise_id]['closing_time'])
)
if len(deadlines) == 0:
return None
return max(deadlines)

def get_points(self) -> Optional[int]:
Expand Down
6 changes: 5 additions & 1 deletion locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-28 12:16+0300\n"
"POT-Creation-Date: 2023-08-31 15:24+0300\n"
"PO-Revision-Date: 2021-05-27 14:47+0300\n"
"Last-Translator: Jimmy Ihalainen <[email protected]>\n"
"Language-Team: English<>\n"
Expand Down Expand Up @@ -2347,6 +2347,10 @@ msgstr ""
"Invalid reveal rule definition '{key}'. Must be a JSON object with a "
"'trigger' field."

#: edit_course/operations/configure.py
msgid "ERROR_MODEL_SOLUTION_CHAPTER_NOT_FOUND -- {value}"
msgstr "Chapter '{value}' not found."

#: edit_course/operations/configure.py
msgid "BUILD_LOG_ERROR_URL_BLANK"
msgstr "Cannot request build log from build_log_url when it is blank."
Expand Down
6 changes: 5 additions & 1 deletion locale/fi/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-28 12:16+0300\n"
"POT-Creation-Date: 2023-08-31 15:24+0300\n"
"PO-Revision-Date: 2019-08-14 12:16+0200\n"
"Last-Translator: Jimmy Ihalainen <[email protected]>\n"
"Language-Team: Finnish <>\n"
Expand Down Expand Up @@ -2361,6 +2361,10 @@ msgstr ""
"Viallinen paljastamissäännön määrittely '{key}'. Täytyy olla JSON-objekti, "
"jolla on 'trigger'-kenttä."

#: edit_course/operations/configure.py
msgid "ERROR_MODEL_SOLUTION_CHAPTER_NOT_FOUND -- {value}"
msgstr "Lukua '{value}' ei löytynyt."

#: edit_course/operations/configure.py
msgid "BUILD_LOG_ERROR_URL_BLANK"
msgstr "Käännöslokin hakeminen ei onnistu jos build_log_url on tyhjä."
Expand Down

0 comments on commit 6efc054

Please sign in to comment.