Source code for codegrade.models.plagiarism_run

"""The module that defines the ``PlagiarismRun`` 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 .. import parsers
from ..utils import to_dict
from .assignment import Assignment
from .plagiarism_run_plagiarism_assignment_as_json import (
    PlagiarismRunPlagiarismAssignmentAsJSON,
)
from .plagiarism_run_plagiarism_course_as_json import (
    PlagiarismRunPlagiarismCourseAsJSON,
)
from .plagiarism_state import PlagiarismState


[docs]@dataclass class PlagiarismRun: """The way this class will be represented in JSON.""" #: The id of the run. id: "int" #: The state this run is in. state: "PlagiarismState" #: The amount of submissions that have finished the current state. submissions_done: "t.Optional[int]" #: The total amount of submissions connected to this run. submissions_total: "t.Optional[int]" #: Which provider is doing this run. provider_name: "str" #: The config used for this run. config: "t.Any" #: The time this run was created. created_at: "datetime.datetime" #: The assignment this run was done on. assignment: "Assignment" #: The log produced by the provider while running. log: "t.Optional[str]" #: A mapping between assignment id and the assignment for each assignment #: that is connected to this run. These are not (!) full assignment #: objects, but only contain the `name` and `id`. assignments: "t.Mapping[str, PlagiarismRunPlagiarismAssignmentAsJSON]" #: The mapping between course id and the course for each course that is #: connected to this run. These are not (!) full course object, but contain #: only the `name`, `id` and if the course is virtual. courses: "t.Mapping[str, PlagiarismRunPlagiarismCourseAsJSON]" #: If we found more matches than the maximum allowed (i.e. matches were #: dropped) this value is set to `True`. cases_dropped: "bool" raw_data: t.Optional[t.Dict[str, t.Any]] = field(init=False, repr=False) data_parser: t.ClassVar = rqa.Lazy( lambda: rqa.FixedMapping( rqa.RequiredArgument( "id", rqa.SimpleValue.int, doc="The id of the run.", ), rqa.RequiredArgument( "state", rqa.EnumValue(PlagiarismState), doc="The state this run is in.", ), rqa.RequiredArgument( "submissions_done", rqa.Nullable(rqa.SimpleValue.int), doc="The amount of submissions that have finished the current state.", ), rqa.RequiredArgument( "submissions_total", rqa.Nullable(rqa.SimpleValue.int), doc="The total amount of submissions connected to this run.", ), rqa.RequiredArgument( "provider_name", rqa.SimpleValue.str, doc="Which provider is doing this run.", ), rqa.RequiredArgument( "config", rqa.AnyValue, doc="The config used for this run.", ), rqa.RequiredArgument( "created_at", rqa.RichValue.DateTime, doc="The time this run was created.", ), rqa.RequiredArgument( "assignment", parsers.ParserFor.make(Assignment), doc="The assignment this run was done on.", ), rqa.RequiredArgument( "log", rqa.Nullable(rqa.SimpleValue.str), doc="The log produced by the provider while running.", ), rqa.RequiredArgument( "assignments", rqa.LookupMapping( parsers.ParserFor.make( PlagiarismRunPlagiarismAssignmentAsJSON ) ), doc="A mapping between assignment id and the assignment for each assignment that is connected to this run. These are not (!) full assignment objects, but only contain the `name` and `id`.", ), rqa.RequiredArgument( "courses", rqa.LookupMapping( parsers.ParserFor.make(PlagiarismRunPlagiarismCourseAsJSON) ), doc="The mapping between course id and the course for each course that is connected to this run. These are not (!) full course object, but contain only the `name`, `id` and if the course is virtual.", ), rqa.RequiredArgument( "cases_dropped", rqa.SimpleValue.bool, doc="If we found more matches than the maximum allowed (i.e. matches were dropped) this value is set to `True`.", ), ).use_readable_describe(True) ) def to_dict(self) -> t.Dict[str, t.Any]: res: t.Dict[str, t.Any] = { "id": to_dict(self.id), "state": to_dict(self.state), "submissions_done": to_dict(self.submissions_done), "submissions_total": to_dict(self.submissions_total), "provider_name": to_dict(self.provider_name), "config": to_dict(self.config), "created_at": to_dict(self.created_at), "assignment": to_dict(self.assignment), "log": to_dict(self.log), "assignments": to_dict(self.assignments), "courses": to_dict(self.courses), "cases_dropped": to_dict(self.cases_dropped), } return res @classmethod def from_dict( cls: t.Type["PlagiarismRun"], d: t.Dict[str, t.Any] ) -> "PlagiarismRun": parsed = cls.data_parser.try_parse(d) res = cls( id=parsed.id, state=parsed.state, submissions_done=parsed.submissions_done, submissions_total=parsed.submissions_total, provider_name=parsed.provider_name, config=parsed.config, created_at=parsed.created_at, assignment=parsed.assignment, log=parsed.log, assignments=parsed.assignments, courses=parsed.courses, cases_dropped=parsed.cases_dropped, ) res.raw_data = d return res