add/improve refreshing logic & metadata management, improve thumbnail logic & regenerate kwarg, overall more documentation/commands

This commit is contained in:
Xevion
2020-11-03 18:26:12 -06:00
parent ed3e656ee8
commit 09e82944d7
2 changed files with 54 additions and 9 deletions

View File

@@ -3,6 +3,8 @@ helpers.py
Contains helper functions used as refactored shortcuts or in order to separate code for readability. Contains helper functions used as refactored shortcuts or in order to separate code for readability.
""" """
from typing import Tuple
import cv2 import cv2
from PIL import Image from PIL import Image
@@ -14,8 +16,8 @@ def generate_thumbnail(path: str, output_path: str) -> None:
:param path: The absolute path to the file. :param path: The absolute path to the file.
:param output_path: The absolute path to the intended output thumbnail file. :param output_path: The absolute path to the intended output thumbnail file.
""" """
vidcap = cv2.VideoCapture(path) file = cv2.VideoCapture(path)
success, image = vidcap.read() success, image = file.read()
if success: if success:
img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img) im_pil = Image.fromarray(img)
@@ -26,3 +28,13 @@ def generate_thumbnail(path: str, output_path: str) -> None:
# im_pil.resize((200, 66)) # im_pil.resize((200, 66))
im_pil.save(output_path) im_pil.save(output_path)
def get_resolution(path: str) -> Tuple[int, int]:
"""
Retrieves the resolution of a image or video
:return: A tuple containing two positive integers representing width and height
"""
file = cv2.VideoCapture(path)
return file.get(cv2.CAP_PROP_FRAME_HEIGHT), file.get(cv2.CAP_PROP_FRAME_WIDTH)

View File

@@ -2,10 +2,12 @@ import mimetypes
import os import os
import uuid import uuid
from datetime import datetime from datetime import datetime
from typing import Tuple
import jsonfield import jsonfield
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from django.utils import timezone
from easy_thumbnails.alias import aliases from easy_thumbnails.alias import aliases
from viewer import helpers from viewer import helpers
@@ -64,6 +66,7 @@ class ServedDirectory(models.Model):
# Dump subdirectories found # Dump subdirectories found
self.known_subdirectories = directories self.known_subdirectories = directories
self.save()
def __str__(self): def __str__(self):
return self.path return self.path
@@ -77,6 +80,11 @@ class ImageDimensions(models.Model):
x = models.PositiveIntegerField() x = models.PositiveIntegerField()
y = models.PositiveIntegerField() y = models.PositiveIntegerField()
def set(self, size: Tuple[int, int]) -> None:
"""Sets the X and Y attributes"""
self.x, self.y = size
self.save()
class File(models.Model): class File(models.Model):
""" """
@@ -110,20 +118,33 @@ class File(models.Model):
def refresh(self) -> None: def refresh(self) -> None:
"""Refresh this file's metadata""" """Refresh this file's metadata"""
self.lastRefreshed = timezone.now()
if not self.thumbnail:
self.generate_thumbnail()
# Check the fileLastModified
fileLastModified = datetime.fromtimestamp(os.path.getmtime(self.path)) fileLastModified = datetime.fromtimestamp(os.path.getmtime(self.path))
if fileLastModified != self.fileLastModified: updated = fileLastModified != self.fileLastModified
self.generate_thumbnail() self.fileLastModified = fileLastModified
# thumbnail regeneration logic
if self.mediatype == 'image' or self.mediatype == 'video':
# if the file modification time changed, regenerate it
if updated:
self.generate_thumbnail(regenerate=True)
# if the thumbnail hasn't been generated, attempt to generate it
elif not self.thumbnail:
self.generate_thumbnail()
if updated:
self.size.set(helpers.get_resolution())
self.thumbnailSize.set(helpers.get_resolution())
self.save()
def get_url(self, directory: ServedDirectory) -> str: def get_url(self, directory: ServedDirectory) -> str:
"""Retrieve the direct URL for a given file.""" """Retrieve the direct URL for a given file."""
return reverse('file', args=(directory.id, self.filename)) return reverse('file', args=(directory.id, self.filename))
def delete_thumbnail(self) -> None: def delete_thumbnail(self) -> None:
"""Delete the thumbnail for this File if it exists and forget the filename."""
if self.thumbnail: if self.thumbnail:
try: try:
os.remove(os.path.join(self.thumbs_dir, self.thumbnail)) os.remove(os.path.join(self.thumbs_dir, self.thumbnail))
@@ -143,10 +164,22 @@ class File(models.Model):
return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'thumbnails') return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'thumbnails')
def generate_thumbnail(self, regenerate=False) -> None: def generate_thumbnail(self, regenerate=False) -> None:
"""
Generates a new thumbnail for a given image or video file.
Will not generate thumbnails if the thumbnail already exists.
:param regenerate: Generate the thumbnail even if the thumbnail already exists.
"""
# TODO: Add django-background-task scheduling # TODO: Add django-background-task scheduling
self.delete_thumbnail() # Only generate again if regenerate is True, make sure to delete old thumbnail file
if self.thumbnail:
if not regenerate:
return
else:
self.delete_thumbnail()
# Name the thumbnail a random UUID and remember it
thumb_file = f'{uuid.uuid4()}.jpeg' thumb_file = f'{uuid.uuid4()}.jpeg'
self.thumbnail = thumb_file self.thumbnail = thumb_file