diff --git a/AKModel/forms.py b/AKModel/forms.py index ddf46f3c27737cbe56fbcb16c7613102fdad3e42..1e3c5aa141c3637747c3089674b103632b0fa5e9 100644 --- a/AKModel/forms.py +++ b/AKModel/forms.py @@ -304,15 +304,16 @@ class JSONScheduleImportForm(AdminIntermediateForm): try: schedule = json.loads(data) except json.JSONDecodeError as ex: - return ValidationError(_("Cannot decode as JSON"), "invalid") + raise ValidationError(_("Cannot decode as JSON"), "invalid") for field in ["input", "scheduled_aks"]: if not field in schedule: - return ValidationError( + raise ValidationError( _("Invalid JSON format: field '%(field)s' is missing"), "invalid", params={"field": field} ) # TODO: Add further checks on json input + return schedule def clean(self): cleaned_data = super().clean() @@ -328,16 +329,15 @@ class JSONScheduleImportForm(AdminIntermediateForm): ) self.add_error("json_data", err) self.add_error("json_file", err) - elif cleaned_data.get("json_file"): - data = self.cleaned_data.get("json_file") - with data.open() as ff: - read_data = ff.read() - err = self._check_json_data(read_data) - if err is not None: - self.add_error("json_file", err) - elif cleaned_data.get("json_data"): - err = self._check_json_data(cleaned_data.get("json_data")) - if err is not None: - self.add_error("json_data", err) - + else: + source_field = "json_data" + data = cleaned_data.get(source_field) + if not data: + source_field = "json_file" + with cleaned_data.get(source_field).open() as ff: + data = ff.read() + try: + cleaned_data["data"] = self._check_json_data(data) + except ValidationError as ex: + self.add_error(source_field, ex) return cleaned_data diff --git a/AKModel/models.py b/AKModel/models.py index 08e19499c1d3cdee19e995d89c421c7e7c6171c3..d648ac5688ee7f02b0ef730b45dc105115cf7c0b 100644 --- a/AKModel/models.py +++ b/AKModel/models.py @@ -412,7 +412,9 @@ class Event(models.Model): yield from self.uniform_time_slots(slots_in_an_hour=slots_in_an_hour) @transaction.atomic - def schedule_from_json(self, schedule: str, *, check_for_data_inconsistency: bool = True) -> int: + def schedule_from_json( + self, schedule: str | dict[str, Any], *, check_for_data_inconsistency: bool = True + ) -> int: """Load AK schedule from a json string. :param schedule: A string that can be decoded to json, describing @@ -420,7 +422,8 @@ class Event(models.Model): following the output specification of the KoMa conference optimizer, cf. https://github.com/Die-KoMa/ak-plan-optimierung/wiki/Input-&-output-format """ - schedule = json.loads(schedule) + if isinstance(schedule, str): + schedule = json.loads(schedule) export_dict = self.as_json_dict() if "input" not in schedule or "scheduled_aks" not in schedule: diff --git a/AKModel/views/manage.py b/AKModel/views/manage.py index 5ca9dfcbd7b16b76edf8005f961401288c82765d..1a7f1930b079edc4061ac5bc0a145466640bd574 100644 --- a/AKModel/views/manage.py +++ b/AKModel/views/manage.py @@ -259,15 +259,7 @@ class AKScheduleJSONImportView(EventSlugMixin, IntermediateAdminView): def form_valid(self, form): try: - if form.cleaned_data.get("json_data"): - data = form.cleaned_data["json_data"] - elif form.cleaned_data.get("json_file"): - with form.cleaned_data["json_file"].open() as ff: - data = ff.read() - else: - raise ValueError("No data entered!") - - number_of_slots_changed = self.event.schedule_from_json(data) + number_of_slots_changed = self.event.schedule_from_json(form.cleaned_data["data"]) messages.add_message( self.request, messages.SUCCESS,