From fa54ebd7030b8b01cdd5a1e0caea5873893b317b Mon Sep 17 00:00:00 2001 From: Richard Tibbles Date: Mon, 16 Oct 2023 09:28:17 -0700 Subject: [PATCH] Move contentnode removal propagation function to standalone utility. --- .../management/commands/deletecontent.py | 4 ++-- kolibri/core/content/models.py | 21 ------------------ kolibri/core/content/utils/content_request.py | 22 +++++++++++++++++++ 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/kolibri/core/content/management/commands/deletecontent.py b/kolibri/core/content/management/commands/deletecontent.py index d9a1da2e8d0..c2258b54ef8 100644 --- a/kolibri/core/content/management/commands/deletecontent.py +++ b/kolibri/core/content/management/commands/deletecontent.py @@ -7,11 +7,11 @@ from kolibri.core.content.models import ChannelMetadata from kolibri.core.content.models import ContentNode -from kolibri.core.content.models import ContentRequest from kolibri.core.content.models import LocalFile from kolibri.core.content.utils.annotation import propagate_forced_localfile_removal from kolibri.core.content.utils.annotation import reannotate_all_channels from kolibri.core.content.utils.annotation import set_content_invisible +from kolibri.core.content.utils.content_request import propagate_contentnode_removal from kolibri.core.content.utils.importability_annotation import clear_channel_stats from kolibri.core.content.utils.paths import get_content_database_file_path from kolibri.core.tasks.management.commands.base import AsyncCommand @@ -84,7 +84,7 @@ def delete_metadata( channel.delete_content_tree_and_files() if update_content_requests and removed_resources: - ContentRequest.objects.propagate_removal(list(removed_resources)) + propagate_contentnode_removal(list(removed_resources)) # Clear any previously set channel availability stats for this channel clear_channel_stats(channel.id) diff --git a/kolibri/core/content/models.py b/kolibri/core/content/models.py index 9e030609d78..2e0e16b8827 100644 --- a/kolibri/core/content/models.py +++ b/kolibri/core/content/models.py @@ -459,27 +459,6 @@ def get_queryset(self): queryset = queryset.filter(type=self.request_type) return queryset - def propagate_removal(self, contentnode_ids): - """ - Deletes all learner initiated ContentRequests for the passed in contentnode_ids - Matching learner initiated ContentRequests will be deleted - this means that if - resources are deleted by an admin, we remove any associated learner initiated requests. - Also updates the status of any COMPLETED non-learner initiated ContentDownloadRequests to PENDING - """ - BATCH_SIZE = 250 - for i in range(0, len(contentnode_ids), BATCH_SIZE): - batch = contentnode_ids[i : i + BATCH_SIZE] - self.filter( - contentnode_id__in=batch, reason=ContentRequestReason.UserInitiated - ).delete() - self.filter( - contentnode_id__in=batch, - type=ContentRequestType.Download, - status=ContentRequestStatus.Completed, - ).exclude(reason=ContentRequestReason.UserInitiated).update( - status=ContentRequestStatus.Pending - ) - class ContentRequest(models.Model): """ diff --git a/kolibri/core/content/utils/content_request.py b/kolibri/core/content/utils/content_request.py index 09d21b781a5..dc76483c266 100644 --- a/kolibri/core/content/utils/content_request.py +++ b/kolibri/core/content/utils/content_request.py @@ -22,6 +22,7 @@ from kolibri.core.content.models import ContentDownloadRequest from kolibri.core.content.models import ContentNode from kolibri.core.content.models import ContentRemovalRequest +from kolibri.core.content.models import ContentRequest from kolibri.core.content.models import ContentRequestReason from kolibri.core.content.models import ContentRequestStatus from kolibri.core.content.models import File @@ -947,6 +948,27 @@ def process_content_removal_requests(queryset): remaining_pending.update(status=ContentRequestStatus.Completed) +def propagate_contentnode_removal(contentnode_ids): + """ + Deletes all learner initiated ContentRequests for the passed in contentnode_ids + Matching learner initiated ContentRequests will be deleted - this means that if + resources are deleted by an admin, we remove any associated learner initiated requests. + Also updates the status of any COMPLETED non-learner initiated ContentDownloadRequests to PENDING + """ + BATCH_SIZE = 250 + for i in range(0, len(contentnode_ids), BATCH_SIZE): + batch = contentnode_ids[i : i + BATCH_SIZE] + ContentRequest.objects.filter( + contentnode_id__in=batch, reason=ContentRequestReason.UserInitiated + ).delete() + ContentDownloadRequest.objects.filter( + contentnode_id__in=batch, + status=ContentRequestStatus.Completed, + ).exclude(reason=ContentRequestReason.UserInitiated).update( + status=ContentRequestStatus.Pending + ) + + class StorageCalculator: def __init__(self, incomplete_downloads_queryset): incomplete_removals = incomplete_removals_queryset()