djgentelella 0.5.6__py3-none-any.whl → 0.5.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- djgentelella/__init__.py +1 -1
- djgentelella/chunked_upload/constants.py +1 -1
- djgentelella/chunked_upload/utils.py +47 -0
- djgentelella/management/commands/delete_expired_uploads.py +42 -32
- djgentelella/migrations/0018_alter_chunkedupload_status.py +1 -1
- djgentelella/static/djgentelella.vendors.header.min.js +1 -1
- djgentelella/static/gentelella/js/permissionmanagement.js +174 -183
- djgentelella/static/vendors/friconix/friconix.js +1 -1
- djgentelella/tasks.py +39 -0
- djgentelella/templates/gentelella/permission_management/permissionmanagement_list.html +19 -10
- {djgentelella-0.5.6.dist-info → djgentelella-0.5.7.dist-info}/METADATA +63 -7
- {djgentelella-0.5.6.dist-info → djgentelella-0.5.7.dist-info}/RECORD +16 -14
- {djgentelella-0.5.6.dist-info → djgentelella-0.5.7.dist-info}/AUTHORS +0 -0
- {djgentelella-0.5.6.dist-info → djgentelella-0.5.7.dist-info}/LICENSE.txt +0 -0
- {djgentelella-0.5.6.dist-info → djgentelella-0.5.7.dist-info}/WHEEL +0 -0
- {djgentelella-0.5.6.dist-info → djgentelella-0.5.7.dist-info}/top_level.txt +0 -0
djgentelella/__init__.py
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility functions for chunked upload management.
|
|
3
|
+
"""
|
|
4
|
+
from django.utils import timezone
|
|
5
|
+
|
|
6
|
+
from djgentelella.chunked_upload.constants import UPLOADING, COMPLETE
|
|
7
|
+
from djgentelella.models import ChunkedUpload
|
|
8
|
+
from djgentelella.settings import EXPIRATION_DELTA
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_expired_uploads():
|
|
12
|
+
"""
|
|
13
|
+
Get queryset of chunked uploads that have expired.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
QuerySet: ChunkedUpload objects that have expired.
|
|
17
|
+
"""
|
|
18
|
+
return ChunkedUpload.objects.filter(
|
|
19
|
+
created_on__lt=(timezone.now() - EXPIRATION_DELTA)
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def delete_expired_uploads(exclude_ids=None):
|
|
24
|
+
"""
|
|
25
|
+
Delete chunked uploads that have already expired.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
exclude_ids: Optional list of upload IDs to exclude from deletion.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
dict: A dictionary with 'complete' and 'uploading' keys containing
|
|
32
|
+
the count of deleted uploads for each status.
|
|
33
|
+
"""
|
|
34
|
+
count = {UPLOADING: 0, COMPLETE: 0}
|
|
35
|
+
qs = get_expired_uploads()
|
|
36
|
+
|
|
37
|
+
if exclude_ids:
|
|
38
|
+
qs = qs.exclude(id__in=exclude_ids)
|
|
39
|
+
|
|
40
|
+
for chunked_upload in qs:
|
|
41
|
+
count[chunked_upload.status] += 1
|
|
42
|
+
chunked_upload.delete()
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
'complete': count[COMPLETE],
|
|
46
|
+
'uploading': count[UPLOADING],
|
|
47
|
+
}
|
|
@@ -1,48 +1,58 @@
|
|
|
1
|
-
from optparse import make_option
|
|
2
|
-
|
|
3
|
-
from chunked_upload.constants import UPLOADING, COMPLETE
|
|
4
|
-
from chunked_upload.models import ChunkedUpload
|
|
5
|
-
from chunked_upload.settings import EXPIRATION_DELTA
|
|
6
1
|
from django.core.management.base import BaseCommand
|
|
7
|
-
from django.utils import timezone
|
|
8
|
-
from django.utils.translation import ugettext as _
|
|
9
2
|
|
|
10
|
-
|
|
3
|
+
from djgentelella.chunked_upload.constants import UPLOADING, COMPLETE
|
|
4
|
+
from djgentelella.chunked_upload.utils import get_expired_uploads, delete_expired_uploads
|
|
11
5
|
|
|
12
6
|
|
|
13
7
|
class Command(BaseCommand):
|
|
14
|
-
# Has to be a ChunkedUpload subclass
|
|
15
|
-
model = ChunkedUpload
|
|
16
|
-
|
|
17
8
|
help = 'Deletes chunked uploads that have already expired.'
|
|
18
9
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
def add_arguments(self, parser):
|
|
11
|
+
parser.add_argument(
|
|
12
|
+
'--interactive',
|
|
13
|
+
action='store_true',
|
|
14
|
+
dest='interactive',
|
|
15
|
+
default=False,
|
|
16
|
+
help='Prompt confirmation before each deletion.',
|
|
17
|
+
)
|
|
26
18
|
|
|
27
19
|
def handle(self, *args, **options):
|
|
28
20
|
interactive = options.get('interactive')
|
|
29
21
|
|
|
22
|
+
if interactive:
|
|
23
|
+
result = self._handle_interactive()
|
|
24
|
+
else:
|
|
25
|
+
result = delete_expired_uploads()
|
|
26
|
+
|
|
27
|
+
self.stdout.write(
|
|
28
|
+
self.style.SUCCESS(
|
|
29
|
+
f"{result['complete']} complete uploads were deleted."
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
self.stdout.write(
|
|
33
|
+
self.style.SUCCESS(
|
|
34
|
+
f"{result['uploading']} incomplete uploads were deleted."
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def _handle_interactive(self):
|
|
39
|
+
"""Handle interactive deletion with user confirmation."""
|
|
30
40
|
count = {UPLOADING: 0, COMPLETE: 0}
|
|
31
|
-
|
|
32
|
-
qs = qs.filter(created_on__lt=(timezone.now() - EXPIRATION_DELTA))
|
|
41
|
+
exclude_ids = []
|
|
33
42
|
|
|
34
|
-
for chunked_upload in
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
for chunked_upload in get_expired_uploads():
|
|
44
|
+
prompt = f'Do you want to delete {chunked_upload}? (y/n): '
|
|
45
|
+
answer = input(prompt).lower()
|
|
46
|
+
while answer not in ('y', 'n'):
|
|
37
47
|
answer = input(prompt).lower()
|
|
38
|
-
while answer not in ('y', 'n'):
|
|
39
|
-
answer = input(prompt).lower()
|
|
40
|
-
if answer == 'n':
|
|
41
|
-
continue
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
if answer == 'n':
|
|
50
|
+
exclude_ids.append(chunked_upload.id)
|
|
51
|
+
else:
|
|
52
|
+
count[chunked_upload.status] += 1
|
|
53
|
+
chunked_upload.delete()
|
|
46
54
|
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
return {
|
|
56
|
+
'complete': count[COMPLETE],
|
|
57
|
+
'uploading': count[UPLOADING],
|
|
58
|
+
}
|
|
@@ -13,6 +13,6 @@ class Migration(migrations.Migration):
|
|
|
13
13
|
migrations.AlterField(
|
|
14
14
|
model_name='chunkedupload',
|
|
15
15
|
name='status',
|
|
16
|
-
field=models.PositiveSmallIntegerField(choices=[(1, '
|
|
16
|
+
field=models.PositiveSmallIntegerField(choices=[(1, 'Uploading'), (2, 'Complete')], default=1),
|
|
17
17
|
),
|
|
18
18
|
]
|