Skip to content
Snippets Groups Projects
Commit 81972198 authored by Felix Blanke's avatar Felix Blanke
Browse files

Avoid loading JSON file twice

parent c3ba0532
No related branches found
No related tags found
1 merge request!24Feature: JSON import file upload button and schema input validation
......@@ -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
......@@ -423,7 +423,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
......@@ -431,6 +433,7 @@ 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
"""
if isinstance(schedule, str):
schedule = json.loads(schedule)
export_dict = self.as_json_dict()
......
......@@ -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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment