"""The module that defines the ``PatchAssignmentData`` model.
SPDX-License-Identifier: AGPL-3.0-only OR BSD-3-Clause-Clear
"""
import datetime
import typing as t
from dataclasses import dataclass, field
import cg_request_args as rqa
from cg_maybe import Maybe, Nothing
from cg_maybe.utils import maybe_from_nullable
from .. import parsers
from ..utils import to_dict
from .assignment_anonymization_algo import AssignmentAnonymizationAlgo
from .assignment_done_type import AssignmentDoneType
from .assignment_kind import AssignmentKind
from .assignment_percentage_grading_settings import (
AssignmentPercentageGradingSettings,
)
from .assignment_points_grading_settings import AssignmentPointsGradingSettings
from .assignment_state_enum import AssignmentStateEnum
from .assignment_submission_mode import AssignmentSubmissionMode
from .fixed_availability import FixedAvailability
from .fixed_grade_availability import FixedGradeAvailability
from .submission_validator_input_data import SubmissionValidatorInputData
from .timed_availability import TimedAvailability
[docs]@dataclass
class PatchAssignmentData:
"""Input data required for the `Assignment::Patch` operation."""
#: The new state of the assignment. Deprecated, use the `availability` and
#: `grade_availability` options, will be removed in Q3 2023.
state: Maybe["AssignmentStateEnum"] = Nothing
#: The new name of the assignment
name: Maybe["str"] = Nothing
#: The new deadline of the assignment
deadline: Maybe["datetime.datetime"] = Nothing
#: The new lock date of the assignment
lock_date: Maybe["t.Optional[datetime.datetime]"] = Nothing
#: The maximum possible grade for this assignment. You can reset this by
#: passing `null` as value
max_grade: Maybe["t.Optional[float]"] = Nothing
#: The group set id for this assignment. Set to `null` to make this
#: assignment not a group assignment
group_set_id: Maybe["t.Optional[int]"] = Nothing
#: The time the assignment should become available. Deprecated, use the
#: "availability" option, will be removed in Q3 2023.
available_at: Maybe["t.Optional[datetime.datetime]"] = Nothing
#: Should we send login links to students before the assignment opens. This
#: is only available for assignments with 'kind' equal to 'exam'.
send_login_links: Maybe["bool"] = Nothing
#: The new kind of assignment
kind: Maybe["AssignmentKind"] = Nothing
#: Should students be allowed to make submissions by uploading files
files_upload_enabled: Maybe["bool"] = Nothing
#: Should students be allowed to make submissions using git webhooks
webhook_upload_enabled: Maybe["bool"] = Nothing
#: The maximum amount of submissions a user may create.
max_submissions: Maybe["t.Optional[int]"] = Nothing
#: The amount of time in seconds there should be between
#: `amount_in_cool_off_period + 1` submissions.
cool_off_period: Maybe["float"] = Nothing
#: The maximum amount of submissions that can be made within
#: `cool_off_period` seconds. This should be higher than or equal to 1.
amount_in_cool_off_period: Maybe["int"] = Nothing
#: The ignore file to use
ignore: Maybe["t.Union[SubmissionValidatorInputData, str]"] = Nothing
#: The ignore version to use, defaults to "IgnoreFilterManager".
ignore_version: Maybe[
"t.Literal['EmptySubmissionFilter', 'IgnoreFilterManager', 'SubmissionValidator']"
] = Nothing
#: How to determine grading is done for this assignment, this value is not
#: used when `reminder_time` is `null`.
done_type: Maybe["t.Optional[AssignmentDoneType]"] = Nothing
#: At what time should we send the reminder emails to the graders. This
#: value is not used when `done_type` is `null`.
reminder_time: Maybe["t.Optional[datetime.datetime]"] = Nothing
#: A list of emails that should receive an email when grading is done. This
#: value has no effect when `done_type` is set to `null`.
done_email: Maybe["t.Optional[str]"] = Nothing
#: Should anonymized grading be enabled for this assignment.
anonymized_grading: Maybe["t.Optional[AssignmentAnonymizationAlgo]"] = (
Nothing
)
#: The file we should load first in an assignment
file_to_load_first: Maybe["t.Optional[str]"] = Nothing
#: Grading settings of this assignment.
grading: Maybe[
"t.Union[AssignmentPointsGradingSettings, AssignmentPercentageGradingSettings]"
] = Nothing
#: The availability of this assignment.
availability: Maybe["t.Union[FixedAvailability, TimedAvailability]"] = (
Nothing
)
#: The grade availability of this assignment.
grade_availability: Maybe["FixedGradeAvailability"] = Nothing
#: The submission mode of this assignment
submission_mode: Maybe["AssignmentSubmissionMode"] = Nothing
raw_data: t.Optional[t.Dict[str, t.Any]] = field(init=False, repr=False)
data_parser: t.ClassVar = rqa.Lazy(
lambda: rqa.FixedMapping(
rqa.OptionalArgument(
"state",
rqa.EnumValue(AssignmentStateEnum),
doc="The new state of the assignment. Deprecated, use the `availability` and `grade_availability` options, will be removed in Q3 2023.",
),
rqa.OptionalArgument(
"name",
rqa.SimpleValue.str,
doc="The new name of the assignment",
),
rqa.OptionalArgument(
"deadline",
rqa.RichValue.DateTime,
doc="The new deadline of the assignment",
),
rqa.OptionalArgument(
"lock_date",
rqa.Nullable(rqa.RichValue.DateTime),
doc="The new lock date of the assignment",
),
rqa.OptionalArgument(
"max_grade",
rqa.Nullable(rqa.SimpleValue.float),
doc="The maximum possible grade for this assignment. You can reset this by passing `null` as value",
),
rqa.OptionalArgument(
"group_set_id",
rqa.Nullable(rqa.SimpleValue.int),
doc="The group set id for this assignment. Set to `null` to make this assignment not a group assignment",
),
rqa.OptionalArgument(
"available_at",
rqa.Nullable(rqa.RichValue.DateTime),
doc='The time the assignment should become available. Deprecated, use the "availability" option, will be removed in Q3 2023.',
),
rqa.OptionalArgument(
"send_login_links",
rqa.SimpleValue.bool,
doc="Should we send login links to students before the assignment opens. This is only available for assignments with 'kind' equal to 'exam'.",
),
rqa.OptionalArgument(
"kind",
rqa.EnumValue(AssignmentKind),
doc="The new kind of assignment",
),
rqa.OptionalArgument(
"files_upload_enabled",
rqa.SimpleValue.bool,
doc="Should students be allowed to make submissions by uploading files",
),
rqa.OptionalArgument(
"webhook_upload_enabled",
rqa.SimpleValue.bool,
doc="Should students be allowed to make submissions using git webhooks",
),
rqa.OptionalArgument(
"max_submissions",
rqa.Nullable(rqa.SimpleValue.int),
doc="The maximum amount of submissions a user may create.",
),
rqa.OptionalArgument(
"cool_off_period",
rqa.SimpleValue.float,
doc="The amount of time in seconds there should be between `amount_in_cool_off_period + 1` submissions.",
),
rqa.OptionalArgument(
"amount_in_cool_off_period",
rqa.SimpleValue.int,
doc="The maximum amount of submissions that can be made within `cool_off_period` seconds. This should be higher than or equal to 1.",
),
rqa.OptionalArgument(
"ignore",
parsers.make_union(
parsers.ParserFor.make(SubmissionValidatorInputData),
rqa.SimpleValue.str,
),
doc="The ignore file to use",
),
rqa.OptionalArgument(
"ignore_version",
rqa.StringEnum(
"EmptySubmissionFilter",
"IgnoreFilterManager",
"SubmissionValidator",
),
doc='The ignore version to use, defaults to "IgnoreFilterManager".',
),
rqa.OptionalArgument(
"done_type",
rqa.Nullable(rqa.EnumValue(AssignmentDoneType)),
doc="How to determine grading is done for this assignment, this value is not used when `reminder_time` is `null`.",
),
rqa.OptionalArgument(
"reminder_time",
rqa.Nullable(rqa.RichValue.DateTime),
doc="At what time should we send the reminder emails to the graders. This value is not used when `done_type` is `null`.",
),
rqa.OptionalArgument(
"done_email",
rqa.Nullable(rqa.SimpleValue.str),
doc="A list of emails that should receive an email when grading is done. This value has no effect when `done_type` is set to `null`.",
),
rqa.OptionalArgument(
"anonymized_grading",
rqa.Nullable(rqa.EnumValue(AssignmentAnonymizationAlgo)),
doc="Should anonymized grading be enabled for this assignment.",
),
rqa.OptionalArgument(
"file_to_load_first",
rqa.Nullable(rqa.SimpleValue.str),
doc="The file we should load first in an assignment",
),
rqa.OptionalArgument(
"grading",
parsers.make_union(
parsers.ParserFor.make(AssignmentPointsGradingSettings),
parsers.ParserFor.make(
AssignmentPercentageGradingSettings
),
),
doc="Grading settings of this assignment.",
),
rqa.OptionalArgument(
"availability",
parsers.make_union(
parsers.ParserFor.make(FixedAvailability),
parsers.ParserFor.make(TimedAvailability),
),
doc="The availability of this assignment.",
),
rqa.OptionalArgument(
"grade_availability",
parsers.ParserFor.make(FixedGradeAvailability),
doc="The grade availability of this assignment.",
),
rqa.OptionalArgument(
"submission_mode",
rqa.EnumValue(AssignmentSubmissionMode),
doc="The submission mode of this assignment",
),
).use_readable_describe(True)
)
def __post_init__(self) -> None:
getattr(super(), "__post_init__", lambda: None)()
self.state = maybe_from_nullable(self.state)
self.name = maybe_from_nullable(self.name)
self.deadline = maybe_from_nullable(self.deadline)
self.lock_date = maybe_from_nullable(self.lock_date)
self.max_grade = maybe_from_nullable(self.max_grade)
self.group_set_id = maybe_from_nullable(self.group_set_id)
self.available_at = maybe_from_nullable(self.available_at)
self.send_login_links = maybe_from_nullable(self.send_login_links)
self.kind = maybe_from_nullable(self.kind)
self.files_upload_enabled = maybe_from_nullable(
self.files_upload_enabled
)
self.webhook_upload_enabled = maybe_from_nullable(
self.webhook_upload_enabled
)
self.max_submissions = maybe_from_nullable(self.max_submissions)
self.cool_off_period = maybe_from_nullable(self.cool_off_period)
self.amount_in_cool_off_period = maybe_from_nullable(
self.amount_in_cool_off_period
)
self.ignore = maybe_from_nullable(self.ignore)
self.ignore_version = maybe_from_nullable(self.ignore_version)
self.done_type = maybe_from_nullable(self.done_type)
self.reminder_time = maybe_from_nullable(self.reminder_time)
self.done_email = maybe_from_nullable(self.done_email)
self.anonymized_grading = maybe_from_nullable(self.anonymized_grading)
self.file_to_load_first = maybe_from_nullable(self.file_to_load_first)
self.grading = maybe_from_nullable(self.grading)
self.availability = maybe_from_nullable(self.availability)
self.grade_availability = maybe_from_nullable(self.grade_availability)
self.submission_mode = maybe_from_nullable(self.submission_mode)
def to_dict(self) -> t.Dict[str, t.Any]:
res: t.Dict[str, t.Any] = {}
if self.state.is_just:
res["state"] = to_dict(self.state.value)
if self.name.is_just:
res["name"] = to_dict(self.name.value)
if self.deadline.is_just:
res["deadline"] = to_dict(self.deadline.value)
if self.lock_date.is_just:
res["lock_date"] = to_dict(self.lock_date.value)
if self.max_grade.is_just:
res["max_grade"] = to_dict(self.max_grade.value)
if self.group_set_id.is_just:
res["group_set_id"] = to_dict(self.group_set_id.value)
if self.available_at.is_just:
res["available_at"] = to_dict(self.available_at.value)
if self.send_login_links.is_just:
res["send_login_links"] = to_dict(self.send_login_links.value)
if self.kind.is_just:
res["kind"] = to_dict(self.kind.value)
if self.files_upload_enabled.is_just:
res["files_upload_enabled"] = to_dict(
self.files_upload_enabled.value
)
if self.webhook_upload_enabled.is_just:
res["webhook_upload_enabled"] = to_dict(
self.webhook_upload_enabled.value
)
if self.max_submissions.is_just:
res["max_submissions"] = to_dict(self.max_submissions.value)
if self.cool_off_period.is_just:
res["cool_off_period"] = to_dict(self.cool_off_period.value)
if self.amount_in_cool_off_period.is_just:
res["amount_in_cool_off_period"] = to_dict(
self.amount_in_cool_off_period.value
)
if self.ignore.is_just:
res["ignore"] = to_dict(self.ignore.value)
if self.ignore_version.is_just:
res["ignore_version"] = to_dict(self.ignore_version.value)
if self.done_type.is_just:
res["done_type"] = to_dict(self.done_type.value)
if self.reminder_time.is_just:
res["reminder_time"] = to_dict(self.reminder_time.value)
if self.done_email.is_just:
res["done_email"] = to_dict(self.done_email.value)
if self.anonymized_grading.is_just:
res["anonymized_grading"] = to_dict(self.anonymized_grading.value)
if self.file_to_load_first.is_just:
res["file_to_load_first"] = to_dict(self.file_to_load_first.value)
if self.grading.is_just:
res["grading"] = to_dict(self.grading.value)
if self.availability.is_just:
res["availability"] = to_dict(self.availability.value)
if self.grade_availability.is_just:
res["grade_availability"] = to_dict(self.grade_availability.value)
if self.submission_mode.is_just:
res["submission_mode"] = to_dict(self.submission_mode.value)
return res
@classmethod
def from_dict(
cls: t.Type["PatchAssignmentData"], d: t.Dict[str, t.Any]
) -> "PatchAssignmentData":
parsed = cls.data_parser.try_parse(d)
res = cls(
state=parsed.state,
name=parsed.name,
deadline=parsed.deadline,
lock_date=parsed.lock_date,
max_grade=parsed.max_grade,
group_set_id=parsed.group_set_id,
available_at=parsed.available_at,
send_login_links=parsed.send_login_links,
kind=parsed.kind,
files_upload_enabled=parsed.files_upload_enabled,
webhook_upload_enabled=parsed.webhook_upload_enabled,
max_submissions=parsed.max_submissions,
cool_off_period=parsed.cool_off_period,
amount_in_cool_off_period=parsed.amount_in_cool_off_period,
ignore=parsed.ignore,
ignore_version=parsed.ignore_version,
done_type=parsed.done_type,
reminder_time=parsed.reminder_time,
done_email=parsed.done_email,
anonymized_grading=parsed.anonymized_grading,
file_to_load_first=parsed.file_to_load_first,
grading=parsed.grading,
availability=parsed.availability,
grade_availability=parsed.grade_availability,
submission_mode=parsed.submission_mode,
)
res.raw_data = d
return res