Anna Sirota
700c61e74a
Introduces `REQUIRE_FILE_VALIDATION` flag (defaults to `False`), which allows skipping checks for file validation and generate thumbnails right after a new file is created.
72 lines
2.8 KiB
Python
72 lines
2.8 KiB
Python
import logging
|
|
import os.path
|
|
|
|
from background_task import background
|
|
from background_task.tasks import TaskSchedule
|
|
from django.conf import settings
|
|
|
|
import files.models
|
|
import files.utils
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@background(schedule={'action': TaskSchedule.RESCHEDULE_EXISTING})
|
|
def clamdscan(file_id: int):
|
|
"""Run a scan of a given file and save its output as a FileValidation record."""
|
|
file = files.models.File.objects.get(pk=file_id)
|
|
abs_path = os.path.join(settings.MEDIA_ROOT, file.source.path)
|
|
scan_status, scan_found = files.utils.run_clamdscan(abs_path)
|
|
logger.info('File pk=%s scanned: %s', file.pk, (scan_status, scan_found))
|
|
scan_result = {'clamdscan': [scan_status, scan_found]}
|
|
is_ok = scan_status == 'OK'
|
|
file_validation, is_new = files.models.FileValidation.objects.get_or_create(
|
|
file=file, defaults={'results': scan_result, 'is_ok': is_ok}
|
|
)
|
|
if not is_new:
|
|
file_validation.results = scan_result
|
|
file_validation.is_ok = is_ok
|
|
file_validation.save(update_fields={'results', 'is_ok', 'date_modified'})
|
|
|
|
|
|
@background(schedule={'action': TaskSchedule.RESCHEDULE_EXISTING})
|
|
def make_thumbnails(file_id: int) -> None:
|
|
"""Generate thumbnails for a given file, store them in thumbnail and metadata columns."""
|
|
file = files.models.File.objects.get(pk=file_id)
|
|
args = {'pk': file_id, 'type': file.get_type_display()}
|
|
|
|
if not file.is_image and not file.is_video:
|
|
logger.error('File pk=%(pk)s of type "%(type)s" is neither an image nor a video', args)
|
|
return
|
|
if settings.REQUIRE_FILE_VALIDATION and not file.validation.is_ok:
|
|
logger.error("File pk={pk} is flagged, won't make thumbnails".format(**args))
|
|
return
|
|
|
|
# For an image, source of the thumbnails is the original image
|
|
source_path = file.source.path
|
|
thumbnail_field = file.thumbnail
|
|
unchanged_thumbnail = thumbnail_field.name
|
|
|
|
if file.is_video:
|
|
frame_path = files.utils.get_thumbnail_upload_to(file.hash)
|
|
# For a video, source of the thumbnails is a frame extracted with ffpeg
|
|
files.utils.extract_frame(source_path, frame_path)
|
|
thumbnail_field.name = frame_path
|
|
source_path = frame_path
|
|
|
|
thumbnails = files.utils.make_thumbnails(source_path, file.hash)
|
|
|
|
if not thumbnail_field.name:
|
|
thumbnail_field.name = thumbnails['1080p']['path']
|
|
|
|
update_fields = set()
|
|
if thumbnail_field.name != unchanged_thumbnail:
|
|
update_fields.add('thumbnail')
|
|
if file.metadata.get('thumbnails') != thumbnails:
|
|
file.metadata.update({'thumbnails': thumbnails})
|
|
update_fields.add('metadata')
|
|
if update_fields:
|
|
args['update_fields'] = update_fields
|
|
logger.info('Made thumbnails for file pk=%(pk)s, updating %(update_fields)s', args)
|
|
file.save(update_fields=update_fields)
|