-
-
Notifications
You must be signed in to change notification settings - Fork 128
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'beta' into require-auth-at-project-level
- Loading branch information
Showing
8 changed files
with
242 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
onadata/apps/logger/management/commands/soft_delete_orphan_attachments_2_023_37c_fix.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
from __future__ import annotations | ||
|
||
from django.core.management.base import BaseCommand | ||
from django.core.management import call_command | ||
from django.db.models import F, Q | ||
|
||
from onadata.apps.logger.models import ( | ||
Attachment, | ||
Instance, | ||
XForm, | ||
) | ||
from onadata.apps.main.models import UserProfile | ||
|
||
|
||
class Command(BaseCommand): | ||
|
||
help = ( | ||
'Undelete background audio files and audit logs previously soft-deleted' | ||
' by a bug introduced in release 2.023.37c' | ||
) | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument( | ||
'--chunks', | ||
type=int, | ||
default=2000, | ||
help='Number of records to process per query' | ||
) | ||
|
||
parser.add_argument( | ||
'--force', | ||
action='store_true', | ||
default=False, | ||
help='Run the management command even if no attachments are affected' | ||
) | ||
|
||
def handle(self, *args, **kwargs): | ||
chunks = kwargs['chunks'] | ||
verbosity = kwargs['verbosity'] | ||
force = kwargs['force'] | ||
|
||
self.stdout.write( | ||
'⚠ Warning! This management can take a while (i.e. several hours) ' | ||
'to run on big databases' | ||
) | ||
|
||
queryset = Attachment.all_objects.filter( | ||
Q(media_file_basename='audit.csv') | ||
| Q(media_file_basename__endswith='.enc') | ||
| Q(media_file_basename__regex=r'^\d{10,}\.(m4a|amr)$'), | ||
deleted_at__isnull=False, | ||
) | ||
|
||
if not queryset.exists() and not force: | ||
self.stdout.write( | ||
'No background recording or audit logs seem to be affected' | ||
) | ||
return | ||
|
||
att_queryset = Attachment.all_objects.filter( | ||
Q(media_file_basename='audit.csv') | ||
| Q(media_file_basename__endswith='.enc') | ||
| Q(media_file_basename__regex=r'^\d{10,}\.(m4a|amr)$') | ||
) | ||
if not force: | ||
att_queryset = att_queryset.filter(deleted_at__isnull=False) | ||
|
||
instance_ids = list( | ||
att_queryset.values_list('instance_id', flat=True).distinct() | ||
) | ||
|
||
if verbosity > 1: | ||
instances_count = len(instance_ids) | ||
self.stdout.write(f'Instances to process: {instances_count}…') | ||
|
||
cpt = 1 | ||
|
||
instances = Instance.objects.filter(pk__in=instance_ids).order_by('id') | ||
for instance in instances.iterator(chunk_size=chunks): | ||
message = '' if verbosity <= 1 else f' - {cpt}/{instances_count}' | ||
if verbosity: | ||
self.stdout.write( | ||
f'Processing instance #{instance.pk}{message}…' | ||
) | ||
Attachment.all_objects.filter( | ||
Q(media_file_basename='audit.csv') | ||
| Q(media_file_basename__endswith='.enc') | ||
| Q(media_file_basename__regex=r'^\d+\.(m4a|amr)$'), | ||
instance_id=instance.pk, | ||
).update(deleted_at=None) | ||
try: | ||
instance.parsed_instance.update_mongo() | ||
except Instance.parsed_instance.RelatedObjectDoesNotExist: | ||
pass | ||
cpt += 1 | ||
|
||
if verbosity: | ||
self.stdout.write( | ||
f'Updating storage counters…' | ||
) | ||
# Attachment storage counters need to be updated. | ||
xform_ids = ( | ||
Instance.objects.filter(pk__in=instance_ids) | ||
.values_list('xform_id', flat=True) | ||
.distinct() | ||
) | ||
|
||
# Update related profile counters with a wrong value to let | ||
# the management command `update_attachment_storage_byte` find them | ||
# when calling with `--sync` option. | ||
UserProfile.objects.filter( | ||
user_id__in=XForm.objects.filter( | ||
pk__in=list(xform_ids) | ||
).values_list('user_id', flat=True) | ||
).update(attachment_storage_bytes=F('attachment_storage_bytes') - 1) | ||
|
||
call_command( | ||
'update_attachment_storage_bytes', verbosity=verbosity, sync=True | ||
) | ||
|
||
self.stdout.write('Done!') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
onadata/apps/main/migrations/0013_remove_userprofile_created_by.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Generated by Django 3.2.15 on 2023-10-30 16:38 | ||
|
||
from django.db import migrations | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('main', '0012_add_validate_password_flag_to_profile'), | ||
] | ||
|
||
operations = [ | ||
migrations.RemoveField( | ||
model_name='userprofile', | ||
name='created_by', | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters