mirror of
https://github.com/MOIS3Y/logs-collector.git
synced 2025-02-01 09:20:52 +01:00
Add: prototype cleanup_media command
This commit is contained in:
parent
a7a85b1816
commit
431541b3cb
0
logs_collector/collector/management/__init__.py
Normal file
0
logs_collector/collector/management/__init__.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import os
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.apps import apps
|
||||||
|
from django.db.models import Q
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db.models import FileField
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
# HELP MESSAGE:
|
||||||
|
help_part1 = 'This command deletes all media files from'
|
||||||
|
help_part2 = 'the MEDIA_ROOT directory which are no longer referenced'
|
||||||
|
help_part3 = 'by any of the models from installed_apps'
|
||||||
|
help = f'{help_part1} {help_part2} {help_part3}'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
all_models = apps.get_models()
|
||||||
|
physical_files = set()
|
||||||
|
db_files = set()
|
||||||
|
# Get all files from the database
|
||||||
|
for model in all_models:
|
||||||
|
file_fields = []
|
||||||
|
filters = Q()
|
||||||
|
for f_ in model._meta.fields:
|
||||||
|
if isinstance(f_, FileField):
|
||||||
|
file_fields.append(f_.name)
|
||||||
|
is_null = {'{}__isnull'.format(f_.name): True}
|
||||||
|
is_empty = {'{}__exact'.format(f_.name): ''}
|
||||||
|
filters &= Q(**is_null) | Q(**is_empty)
|
||||||
|
# only retrieve the models which have non-empty,
|
||||||
|
# non-null file fields
|
||||||
|
if file_fields:
|
||||||
|
files = model.objects.exclude(filters).values_list(
|
||||||
|
*file_fields,
|
||||||
|
flat=True
|
||||||
|
).distinct()
|
||||||
|
db_files.update(files)
|
||||||
|
# Get all files from the MEDIA_ROOT, recursively
|
||||||
|
media_root = getattr(settings, 'MEDIA_ROOT', None)
|
||||||
|
if media_root is not None:
|
||||||
|
for relative_root, dirs, files in os.walk(media_root):
|
||||||
|
for file_ in files:
|
||||||
|
# Compute the relative file path to the media directory,
|
||||||
|
# so it can be compared to the values from the db
|
||||||
|
relative_file = os.path.join(
|
||||||
|
os.path.relpath(relative_root, media_root), file_
|
||||||
|
)
|
||||||
|
physical_files.add(relative_file)
|
||||||
|
# Compute the difference and delete those files
|
||||||
|
deletables = physical_files - db_files
|
||||||
|
if deletables:
|
||||||
|
for file_ in deletables:
|
||||||
|
os.remove(os.path.join(media_root, file_))
|
||||||
|
# Bottom-up - delete all empty folders
|
||||||
|
for relative_root, dirs, files in os.walk(
|
||||||
|
media_root, topdown=False):
|
||||||
|
for dir_ in dirs:
|
||||||
|
if not os.listdir(os.path.join(relative_root, dir_)):
|
||||||
|
os.rmdir(os.path.join(relative_root, dir_))
|
Loading…
Reference in New Issue
Block a user