Loading portal/async_celery/periodic_tasks.py +0 −2 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ def setup_periodic_tasks(sender, **kwargs): archive_submissions_in_arch_project.s(), name="Archive all submissions in archived project") @celery_app.task def abort_non_proc_submissions(**kwargs): from portal.async_celery.async_manager import AsyncManager Loading portal/database/queries.py +53 −5 Original line number Diff line number Diff line import datetime from flask_sqlalchemy import BaseQuery from portal.database.models import Client, ClientType, Course, Group, Project, Role, \ Submission, User, Worker from portal.database.models import Client, ClientType, Course, Group, Project, Role, Submission, \ SubmissionState, User, Worker def _get_class_based_on_client_type(client_type): Loading Loading @@ -65,12 +67,12 @@ def user_avail_submissions_by_group(user: User) -> BaseQuery: .filter(Group.users.contains(user)) def course_clients_by_role(course, role, klass=Client): def course_clients_by_role(course, role, klass=Client) -> BaseQuery: return klass.query.join(klass.roles) \ .filter((Role.id == role.id) & (Role.course == course)).all() def course_clients_filtered(course, groups=None, roles=None, client_type=None): def course_clients_filtered(course, groups=None, roles=None, client_type=None) -> BaseQuery: klass = _get_class_based_on_client_type(client_type=client_type) query = klass.query.join(klass.roles) if client_type is not None: Loading @@ -86,8 +88,54 @@ def course_clients_filtered(course, groups=None, roles=None, client_type=None): return query def group_users(group, role: Role = None): def group_users(group: Group, role: Role = None) -> BaseQuery: """Gets the users in the group, if role is provided, it will be selected also by a role Args: group(Group): Group role(Role): Role Returns(BaseQuery): Query to get the result """ query = User.query.join(User.groups).filter(Group.id == group.id) if role: query = query.join(User.roles).filter(Role.id == role.id) return query def user_by_uco(uco: int) -> BaseQuery: """Finds user by it's UCO Args: uco(int): Uco Returns(BaseQuery): Query to get the result """ return User.query.filter(User.uco == uco) def submissions_to_be_archived() -> BaseQuery: """Returns the collection of finished submissions that are finished and the project is archived. Returns(BaseQuery): Query to get the result """ return Submission.query.join(Submission.project).filter( Submission.state == SubmissionState.FINISHED & Project.is_archived) def cancelled_submissions_for_deletion(time_period: datetime.timedelta) -> BaseQuery: """Returns the cancelled or aborted submissions, which are older then the time_period For example when the time_period is one day, it will select all the submissions that are older then a day. Args: time_period(datetime.timedelta): Returns(BaseQuery): Query to get the result """ delete_from = datetime.datetime.now() - time_period return Submission.query.filter( Submission.state.in_(SubmissionState.CANCELLED, SubmissionState.ABORTED) & Submission.created_at < delete_from) portal/service/submissions.py +14 −16 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ from werkzeug.utils import secure_filename from portal import storage from portal.async_celery import submission_processor, tasks from portal.database import queries from portal.database.models import Course, Group, Project, Role, Submission, SubmissionState, User, \ Worker from portal.logger import SUBMIT Loading @@ -34,14 +35,17 @@ def upload_files_to_storage(file): return path def upload_file_is_allowed(file): def upload_file_is_allowed(file, throws: bool = True): extension = Path(file.filename).suffix log.debug(f"[ZIP] Extension for {file.filename}: {extension}") if not extension == '.zip': if throws: raise errors.PortalAPIError( 400, f"File with extension \"{extension}\" is not allowed: #{file.filename}" ) return False return True class SubmissionsService(GeneralService): Loading Loading @@ -257,19 +261,13 @@ class SubmissionsService(GeneralService): def delete_cancelled_submissions(self): one_day = datetime.timedelta(hours=24) one_day_ago = datetime.datetime.now() - one_day query_filter = Submission.query.filter( Submission.state.in_(SubmissionState.CANCELLED, SubmissionState.ABORTED) & Submission.created_at > one_day_ago) query_filter = queries.cancelled_submissions_for_deletion(one_day) for subm in query_filter.all(): SubmissionsService(subm).delete() for submission in query_filter.all(): SubmissionsService(submission).delete() def archive_submissions(self): query_filter = Submission.query.join(Submission.project).filter( Submission.state == SubmissionState.FINISHED & Project.is_archived) query_filter = queries.submissions_to_be_archived() for subm in query_filter.all(): SubmissionsService(subm).archive() Loading Loading
portal/async_celery/periodic_tasks.py +0 −2 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ def setup_periodic_tasks(sender, **kwargs): archive_submissions_in_arch_project.s(), name="Archive all submissions in archived project") @celery_app.task def abort_non_proc_submissions(**kwargs): from portal.async_celery.async_manager import AsyncManager Loading
portal/database/queries.py +53 −5 Original line number Diff line number Diff line import datetime from flask_sqlalchemy import BaseQuery from portal.database.models import Client, ClientType, Course, Group, Project, Role, \ Submission, User, Worker from portal.database.models import Client, ClientType, Course, Group, Project, Role, Submission, \ SubmissionState, User, Worker def _get_class_based_on_client_type(client_type): Loading Loading @@ -65,12 +67,12 @@ def user_avail_submissions_by_group(user: User) -> BaseQuery: .filter(Group.users.contains(user)) def course_clients_by_role(course, role, klass=Client): def course_clients_by_role(course, role, klass=Client) -> BaseQuery: return klass.query.join(klass.roles) \ .filter((Role.id == role.id) & (Role.course == course)).all() def course_clients_filtered(course, groups=None, roles=None, client_type=None): def course_clients_filtered(course, groups=None, roles=None, client_type=None) -> BaseQuery: klass = _get_class_based_on_client_type(client_type=client_type) query = klass.query.join(klass.roles) if client_type is not None: Loading @@ -86,8 +88,54 @@ def course_clients_filtered(course, groups=None, roles=None, client_type=None): return query def group_users(group, role: Role = None): def group_users(group: Group, role: Role = None) -> BaseQuery: """Gets the users in the group, if role is provided, it will be selected also by a role Args: group(Group): Group role(Role): Role Returns(BaseQuery): Query to get the result """ query = User.query.join(User.groups).filter(Group.id == group.id) if role: query = query.join(User.roles).filter(Role.id == role.id) return query def user_by_uco(uco: int) -> BaseQuery: """Finds user by it's UCO Args: uco(int): Uco Returns(BaseQuery): Query to get the result """ return User.query.filter(User.uco == uco) def submissions_to_be_archived() -> BaseQuery: """Returns the collection of finished submissions that are finished and the project is archived. Returns(BaseQuery): Query to get the result """ return Submission.query.join(Submission.project).filter( Submission.state == SubmissionState.FINISHED & Project.is_archived) def cancelled_submissions_for_deletion(time_period: datetime.timedelta) -> BaseQuery: """Returns the cancelled or aborted submissions, which are older then the time_period For example when the time_period is one day, it will select all the submissions that are older then a day. Args: time_period(datetime.timedelta): Returns(BaseQuery): Query to get the result """ delete_from = datetime.datetime.now() - time_period return Submission.query.filter( Submission.state.in_(SubmissionState.CANCELLED, SubmissionState.ABORTED) & Submission.created_at < delete_from)
portal/service/submissions.py +14 −16 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ from werkzeug.utils import secure_filename from portal import storage from portal.async_celery import submission_processor, tasks from portal.database import queries from portal.database.models import Course, Group, Project, Role, Submission, SubmissionState, User, \ Worker from portal.logger import SUBMIT Loading @@ -34,14 +35,17 @@ def upload_files_to_storage(file): return path def upload_file_is_allowed(file): def upload_file_is_allowed(file, throws: bool = True): extension = Path(file.filename).suffix log.debug(f"[ZIP] Extension for {file.filename}: {extension}") if not extension == '.zip': if throws: raise errors.PortalAPIError( 400, f"File with extension \"{extension}\" is not allowed: #{file.filename}" ) return False return True class SubmissionsService(GeneralService): Loading Loading @@ -257,19 +261,13 @@ class SubmissionsService(GeneralService): def delete_cancelled_submissions(self): one_day = datetime.timedelta(hours=24) one_day_ago = datetime.datetime.now() - one_day query_filter = Submission.query.filter( Submission.state.in_(SubmissionState.CANCELLED, SubmissionState.ABORTED) & Submission.created_at > one_day_ago) query_filter = queries.cancelled_submissions_for_deletion(one_day) for subm in query_filter.all(): SubmissionsService(subm).delete() for submission in query_filter.all(): SubmissionsService(submission).delete() def archive_submissions(self): query_filter = Submission.query.join(Submission.project).filter( Submission.state == SubmissionState.FINISHED & Project.is_archived) query_filter = queries.submissions_to_be_archived() for subm in query_filter.all(): SubmissionsService(subm).archive() Loading