Skip to content

Commit

Permalink
[frontend] Changing task access structure during imports in task_disp…
Browse files Browse the repository at this point in the history
…enser

Changing access structure of tasks when importing in course template and task edit. Also moving change_access_structure, dict_data_str_to_datetime and dict_data_datetimes_to_str in util file in frontend directory.
  • Loading branch information
AlexandreDoneux committed Dec 13, 2023
1 parent 62993a6 commit 66ce37e
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 79 deletions.
65 changes: 1 addition & 64 deletions inginious/frontend/course_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,72 +12,9 @@

from inginious.frontend.exceptions import CourseNotFoundException, CourseAlreadyExistsException, TasksetNotFoundException
from inginious.frontend.courses import Course
from inginious.frontend.util import change_access_structure, dict_data_str_to_datetimes


# remove from pages/utils.py because only used here for the moment
def dict_data_str_to_datetimes(data):
if isinstance(data, dict):
for key, value in data.items():
if isinstance(value, str):
try:
if value == "1-01-01 00:00:00":
data[key] = datetime.min
elif value == "9999-12-31 23:59:59":
data[key] = datetime.max
else:
data[key] = datetime.strptime(value, '%Y-%m-%d %H:%M:%S') if (value != "") else None
except ValueError:
pass # If it's not a valid date string, continue without converting
else:
dict_data_str_to_datetimes(value)
elif isinstance(data, list):
for index, item in enumerate(data):
dict_data_str_to_datetimes(item)
return data


def change_access_structure(access_data, needs_soft_end=False):
"""
Transforms old access structure (course access and registration, task access) into new structure.
ex: "accessible" can be a boolean or a concatenation of start and end dates ("start/end").
It will be transformed to have this structure:
"accessible": {"start": ..., "end": ...}
"registration": {"start": ..., "end": ...}
"accessibility": {"start": ...,"soft_end": ..., "end": ...}
When one of the dates is not given in a custom access or always/never accessible, it will be set to a max or min date.
examples:
"registration": {"start": "2023-11-24 16:44:56", "end": "2023-11-24 16:44:56"}
"accessible": {"start": "2023-11-24 16:44:56", "end": "2023-11-24 16:44:56"}
:param access_data: dict, old access structure
:param needs_soft_end: bool, True if the new structure needs a soft_end date in the structure
:return: dict, new access structure
"""

new_access_data = {"start": None, "end": None}
# PK pas des objets datetime ? Les datetime seraint manipulés à l'écriture en YAML (et en DB si cette fonction est appelée à l'écriture en DB)


if isinstance(access_data, bool):
new_access_data["end"] = "9999-12-31 23:59:59"
if needs_soft_end:
new_access_data["soft_end"] = "9999-12-31 23:59:59"
if access_data:
new_access_data["start"] = "0001-01-01 00:00:00"
else:
new_access_data["start"] = "9999-12-31 23:59:59"


elif isinstance(access_data, str) and access_data != "":
dates = access_data.split("/")
if needs_soft_end:
new_access_data["start"] = dates[0]
new_access_data["soft_end"] = dates[1]
new_access_data["end"] = dates[2]
else:
new_access_data["start"] = dates[0]
new_access_data["end"] = dates[1]

return new_access_data


class CourseFactory(object):
Expand Down
4 changes: 4 additions & 0 deletions inginious/frontend/pages/course_admin/task_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from natsort import natsorted

from inginious.frontend.pages.course_admin.utils import INGIniousAdminPage
from inginious.frontend.util import change_access_structure, dict_data_str_to_datetimes

class CourseTaskListPage(INGIniousAdminPage):
""" List informations about all tasks """
Expand Down Expand Up @@ -37,6 +38,9 @@ def POST_AUTH(self, courseid): # pylint: disable=arguments-differ
task_dispenser = course.get_task_dispenser()
try:
data = task_dispenser.import_legacy_tasks()
for taskid, task in data["config"].items():
task["accessibility"] = dict_data_str_to_datetimes(
change_access_structure(task["accessibility"], True))
self.update_dispenser(course, data)
except Exception as e:
errors.append(_("Something wrong happened: ") + str(e))
Expand Down
5 changes: 4 additions & 1 deletion inginious/frontend/pages/taskset_admin/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from natsort import natsorted

from inginious.frontend.pages.taskset_admin.utils import INGIniousAdminPage

from inginious.frontend.util import change_access_structure, dict_data_str_to_datetimes


class TasksetTemplatePage(INGIniousAdminPage):
Expand Down Expand Up @@ -39,6 +39,9 @@ def POST_AUTH(self, tasksetid): # pylint: disable=arguments-differ
task_dispenser = taskset.get_task_dispenser()
try:
data = task_dispenser.import_legacy_tasks()
for taskid, task in data["config"].items():
task["accessibility"] = dict_data_str_to_datetimes(
change_access_structure(task["accessibility"], True))
self.update_dispenser(taskset, data)
except Exception as e:
errors.append(_("Something wrong happened: ") + str(e))
Expand Down
3 changes: 2 additions & 1 deletion inginious/frontend/task_dispensers/combinatory_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import inginious
from inginious.frontend.task_dispensers.toc import TableOfContents
from inginious.frontend.task_dispensers.util import SectionConfigItem, Weight, SubmissionStorage, EvaluationMode, \
Categories, SubmissionLimit, Accessibility, dict_data_datetimes_to_str
Categories, SubmissionLimit, Accessibility
from inginious.frontend.accessible_time import AccessibleTime
from inginious.frontend.util import dict_data_datetimes_to_str


class CombinatoryTest(TableOfContents):
Expand Down
3 changes: 2 additions & 1 deletion inginious/frontend/task_dispensers/toc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
from operator import concat
from inginious.frontend.task_dispensers.util import check_toc, parse_tasks_config, check_task_config,\
SectionsList, SectionConfigItem, GroupSubmission, Weight, SubmissionStorage, EvaluationMode, Categories, \
SubmissionLimit, Accessibility, dict_data_datetimes_to_str
SubmissionLimit, Accessibility
from inginious.frontend.task_dispensers import TaskDispenser
from inginious.frontend.accessible_time import AccessibleTime
from inginious.frontend.util import change_access_structure, dict_data_str_to_datetimes, dict_data_datetimes_to_str


class TableOfContents(TaskDispenser):
Expand Down
12 changes: 0 additions & 12 deletions inginious/frontend/task_dispensers/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,15 +385,3 @@ def check_task_config(task_list, config_items, data):
except Exception as ex:
return False, str(ex)


def dict_data_datetimes_to_str(data):
if isinstance(data, dict):
for key, value in data.items():
if isinstance(value, datetime):
data[key] = value.strftime("%Y-%m-%d %H:%M:%S")
else:
dict_data_datetimes_to_str(value)
elif isinstance(data, list):
for index, item in enumerate(data):
dict_data_datetimes_to_str(item)
return data
83 changes: 83 additions & 0 deletions inginious/frontend/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
#
# This file is part of INGInious. See the LICENSE and the COPYRIGHTS files for
# more information about the licensing of this file.

from datetime import datetime



def dict_data_datetimes_to_str(data):
if isinstance(data, dict):
for key, value in data.items():
if isinstance(value, datetime):
data[key] = value.strftime("%Y-%m-%d %H:%M:%S")
else:
dict_data_datetimes_to_str(value)
elif isinstance(data, list):
for index, item in enumerate(data):
dict_data_datetimes_to_str(item)
return data


def dict_data_str_to_datetimes(data):
if isinstance(data, dict):
for key, value in data.items():
if isinstance(value, str):
try:
if value == "1-01-01 00:00:00":
data[key] = datetime.min
elif value == "9999-12-31 23:59:59":
data[key] = datetime.max
else:
data[key] = datetime.strptime(value, '%Y-%m-%d %H:%M:%S') if (value != "") else None
except ValueError:
pass # If it's not a valid date string, continue without converting
else:
dict_data_str_to_datetimes(value)
elif isinstance(data, list):
for index, item in enumerate(data):
dict_data_str_to_datetimes(item)
return data


def change_access_structure(access_data, needs_soft_end=False):
"""
Transforms old access structure (course access and registration, task access) into new structure.
ex: "accessible" can be a boolean or a concatenation of start and end dates ("start/end").
It will be transformed to have this structure:
"accessible": {"start": ..., "end": ...}
"registration": {"start": ..., "end": ...}
"accessibility": {"start": ...,"soft_end": ..., "end": ...}
When one of the dates is not given in a custom access or always/never accessible, it will be set to a max or min date.
examples:
"registration": {"start": "2023-11-24 16:44:56", "end": "2023-11-24 16:44:56"}
"accessible": {"start": "2023-11-24 16:44:56", "end": "2023-11-24 16:44:56"}
:param access_data: dict, old access structure
:param needs_soft_end: bool, True if the new structure needs a soft_end date in the structure
:return: dict, new access structure
"""

new_access_data = {"start": None, "end": None}

if isinstance(access_data, bool):
new_access_data["end"] = "9999-12-31 23:59:59"
if needs_soft_end:
new_access_data["soft_end"] = "9999-12-31 23:59:59"
if access_data:
new_access_data["start"] = "0001-01-01 00:00:00"
else:
new_access_data["start"] = "9999-12-31 23:59:59"


elif isinstance(access_data, str) and access_data != "":
dates = access_data.split("/")
if needs_soft_end:
new_access_data["start"] = dates[0]
new_access_data["soft_end"] = dates[1]
new_access_data["end"] = dates[2]
else:
new_access_data["start"] = dates[0]
new_access_data["end"] = dates[1]

return new_access_data

0 comments on commit 66ce37e

Please sign in to comment.