mirror of
https://github.com/Xevion/simple-viewer.git
synced 2025-12-06 03:16:32 -06:00
add/improve refreshing logic & metadata management, improve thumbnail logic & regenerate kwarg, overall more documentation/commands
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user