From c1e3d8b2a85c6362418bc483e2cea955569dff80 Mon Sep 17 00:00:00 2001 From: xstag Date: Mon, 14 Jun 2021 17:30:30 +0400 Subject: [PATCH 1/2] adding videos thumbnails support --- filebrowser/base.py | 28 +++++++++++++------ filebrowser/namers.py | 2 ++ filebrowser/settings.py | 5 +++- .../templates/filebrowser/custom_field.html | 2 +- .../filebrowser/custom_upload_field.html | 2 +- filebrowser/templates/filebrowser/detail.html | 4 +-- .../filebrowser/include/filelisting.html | 10 +++---- .../templates/filebrowser/version.html | 2 +- filebrowser/utils.py | 21 +++++++++++++- 9 files changed, 56 insertions(+), 20 deletions(-) diff --git a/filebrowser/base.py b/filebrowser/base.py index 1cda6148f..bd9cc200c 100644 --- a/filebrowser/base.py +++ b/filebrowser/base.py @@ -15,8 +15,8 @@ from filebrowser.settings import (ADMIN_VERSIONS, DEFAULT_PERMISSIONS, EXTENSIONS, IMAGE_MAXBLOCK, SELECT_FORMATS, STRICT_PIL, VERSION_QUALITY, VERSIONS, - VERSIONS_BASEDIR) -from filebrowser.utils import get_modified_time, path_strip, process_image + VERSIONS_BASEDIR, VIDEO_THUMBNAIL) +from filebrowser.utils import get_modified_time, path_strip, process_image, get_video_image from .namers import get_namer @@ -31,7 +31,6 @@ import Image import ImageFile - ImageFile.MAXBLOCK = IMAGE_MAXBLOCK # default is 64k @@ -342,10 +341,13 @@ def url(self): @cached_property def dimensions(self): "Image dimensions as a tuple" - if self.filetype != 'Image': + if self.filetype != 'Image' and self.filetype != 'Video': return None try: - im = Image.open(self.site.storage.open(self.path)) + if VIDEO_THUMBNAIL and self.filetype == 'Video': + im = Image.open(get_video_image(self.path_full)) + elif self.filetype == 'Image': + im = Image.open(self.site.storage.open(self.path)) return im.size except: pass @@ -514,7 +516,17 @@ def _generate_version(self, version_path, version_suffix, options): f = self.site.storage.open(self.path) except IOError: return "" - im = Image.open(f) + + im = None + + if VIDEO_THUMBNAIL and self.filetype == 'Video': + im = Image.open(get_video_image(self.path_full)) + elif self.filetype == 'Image': + im = Image.open(f) + + if not im: + return None + version_dir, version_basename = os.path.split(version_path) root, ext = os.path.splitext(version_basename) version = process_image(im, options) @@ -526,9 +538,9 @@ def _generate_version(self, version_path, version_suffix, options): version = m(version) # IF need Convert RGB - if ext in [".jpg", ".jpeg"] and version.mode not in ("L", "RGB"): + if ext.lower() in [".jpg", ".jpeg"] and version.mode not in ("L", "RGB"): version = version.convert("RGB") - + # save version quality = VERSIONS.get(version_suffix, {}).get("quality", VERSION_QUALITY) try: diff --git a/filebrowser/namers.py b/filebrowser/namers.py index d0342420d..17fba2857 100644 --- a/filebrowser/namers.py +++ b/filebrowser/namers.py @@ -24,6 +24,8 @@ def __init__(self, **kwargs): setattr(self, k, v) def get_version_name(self): + if self.file_object.filetype == 'Video': + return self.file_object.filename_root + "_" + self.version_suffix + '.jpg' return self.file_object.filename_root + "_" + self.version_suffix + self.extension def get_original_name(self): diff --git a/filebrowser/settings.py b/filebrowser/settings.py index 8430af2a8..9bd1c6af8 100644 --- a/filebrowser/settings.py +++ b/filebrowser/settings.py @@ -11,7 +11,7 @@ # EXTENSIONS AND FORMATS # Allowed Extensions for File Upload. Lower case is important. EXTENSIONS = getattr(settings, "FILEBROWSER_EXTENSIONS", { - 'Image': ['.jpg', '.jpeg', '.gif', '.png', '.tif', '.tiff'], + 'Image': ['.jpg', '.jpeg', '.gif', '.png', '.tif', '.tiff', '.heic'], 'Document': ['.pdf', '.doc', '.rtf', '.txt', '.xls', '.csv', '.docx'], 'Video': ['.mov', '.mp4', '.m4v', '.webm', '.wmv', '.mpeg', '.mpg', '.avi', '.rm'], 'Audio': ['.mp3', '.wav', '.aiff', '.midi', '.m4p'] @@ -48,6 +48,9 @@ # Which Version should be used as Admin-thumbnail. ADMIN_THUMBNAIL = getattr(settings, 'FILEBROWSER_ADMIN_THUMBNAIL', 'admin_thumbnail') +VIDEO_THUMBNAIL = getattr(settings, 'FILEBROWSER_VIDEO_THUMBNAIL', True) +VIDEO_THUMBNAIL_FRAME = getattr(settings, 'FILEBROWSER_ADMIN_VIDEO_THUMBNAIL_FRAME', 10) + VERSION_PROCESSORS = getattr(settings, 'FILEBROWSER_VERSION_PROCESSORS', [ 'filebrowser.utils.scale_and_crop', ]) diff --git a/filebrowser/templates/filebrowser/custom_field.html b/filebrowser/templates/filebrowser/custom_field.html index cf8f0da3e..dfaa905cb 100644 --- a/filebrowser/templates/filebrowser/custom_field.html +++ b/filebrowser/templates/filebrowser/custom_field.html @@ -1,6 +1,6 @@ {% load i18n fb_versions %} -{% if value.filetype == "Image" and value.exists %} +{% if value.filetype == "Image" or fileobject.filetype == "Video" and value.exists %} {% version value.path final_attrs.ADMIN_THUMBNAIL as thumbnail_version %} {% if thumbnail_version %}

diff --git a/filebrowser/templates/filebrowser/custom_upload_field.html b/filebrowser/templates/filebrowser/custom_upload_field.html index d5959be36..ca45641d8 100644 --- a/filebrowser/templates/filebrowser/custom_upload_field.html +++ b/filebrowser/templates/filebrowser/custom_upload_field.html @@ -6,7 +6,7 @@

{% endif %} -{% if value.filetype == "Image" %} +{% if value.filetype == "Image" or fileobject.filetype == "Video" %} {% version value.path final_attrs.ADMIN_THUMBNAIL as thumbnail_version %} {% if thumbnail_version %}

diff --git a/filebrowser/templates/filebrowser/detail.html b/filebrowser/templates/filebrowser/detail.html index 80ab89dba..2f0378db1 100644 --- a/filebrowser/templates/filebrowser/detail.html +++ b/filebrowser/templates/filebrowser/detail.html @@ -122,7 +122,7 @@

{% trans "File Information" %}

- {% if fileobject.filetype == "Image" %} + {% if fileobject.filetype == "Image" or fileobject.filetype == "Video" %}
@@ -136,7 +136,7 @@

{% trans "File Information" %}

{% endif %} {% endif %} - {% if fileobject.filetype == "Image" %} + {% if fileobject.filetype == "Image" or fileobject.filetype == "Video" %}

{% trans "Image Versions" %}

{% if settings_var.ADMIN_THUMBNAIL %} diff --git a/filebrowser/templates/filebrowser/include/filelisting.html b/filebrowser/templates/filebrowser/include/filelisting.html index d7aff2546..0a0eabdc7 100644 --- a/filebrowser/templates/filebrowser/include/filelisting.html +++ b/filebrowser/templates/filebrowser/include/filelisting.html @@ -3,7 +3,7 @@ {% for fileobject in page.object_list %} - {% if fileobject.filetype == "Image" %} + {% if fileobject.filetype == "Image" or fileobject.filetype == "Video" %} {% version fileobject settings_var.ADMIN_THUMBNAIL as thumbnail_version %} {% endif %} @@ -16,7 +16,7 @@ - {% if fileobject.filetype == "Image" and settings_var.ADMIN_VERSIONS %} + {% if fileobject.filetype == "Image" or fileobject.filetype == "Video" and settings_var.ADMIN_VERSIONS %}
 
    @@ -41,7 +41,7 @@ - {% if fileobject.filetype == "Image" and settings_var.ADMIN_VERSIONS %} + {% if fileobject.filetype == "Image" or fileobject.filetype == "Video" and settings_var.ADMIN_VERSIONS %}
     
      @@ -65,7 +65,7 @@ - {% if fileobject.filetype == "Image" and settings_var.ADMIN_VERSIONS %} + {% if fileobject.filetype == "Image" or fileobject.filetype == "Video" and settings_var.ADMIN_VERSIONS %}
       
        @@ -93,7 +93,7 @@ - {% if fileobject.filetype == "Image" %} + {% if fileobject.filetype == "Image" or fileobject.filetype == "Video" %} {% endif %} diff --git a/filebrowser/templates/filebrowser/version.html b/filebrowser/templates/filebrowser/version.html index 507b3433f..95dc836fe 100644 --- a/filebrowser/templates/filebrowser/version.html +++ b/filebrowser/templates/filebrowser/version.html @@ -40,7 +40,7 @@ {% block content %} - {% if fileobject.filetype == "Image" %} + {% if fileobject.filetype == "Image" or fileobject.filetype == "Video" %} {% version fileobject.path settings_var.ADMIN_THUMBNAIL as thumbnail_version %} {% version fileobject.path query.version as image_version %} {% ifequal query.pop '1' %} diff --git a/filebrowser/utils.py b/filebrowser/utils.py index 4ebb5a5b7..f32963680 100644 --- a/filebrowser/utils.py +++ b/filebrowser/utils.py @@ -9,7 +9,7 @@ from django.utils.module_loading import import_string from filebrowser.settings import (CONVERT_FILENAME, NORMALIZE_FILENAME, - STRICT_PIL, VERSION_PROCESSORS) + STRICT_PIL, VERSION_PROCESSORS, VIDEO_THUMBNAIL_FRAME) if STRICT_PIL: from PIL import Image @@ -19,6 +19,11 @@ except ImportError: import Image +try: + import cv2 + from io import BytesIO +except ImportError: + pass def convert_filename(value): """ @@ -119,3 +124,17 @@ def get_modified_time(storage, path): if hasattr(storage, "get_modified_time"): return storage.get_modified_time(path) return storage.modified_time(path) + +def get_video_image(path): + v = cv2.VideoCapture(path) + vtf = VIDEO_THUMBNAIL_FRAME + if v.get(cv2.CAP_PROP_FRAME_COUNT) -1 < vtf: + vtf = v.get(cv2.CAP_PROP_FRAME_COUNT) -1 + if v.set(cv2.CAP_PROP_POS_FRAMES, vtf): + success, frame = v.read() + if success: + success, buffer = cv2.imencode(".jpg", frame) + temp = BytesIO(buffer) + temp.seek(0) + return temp + return None From bf93e97ff524e4a5377407f6619c6b0fe0ddb8b2 Mon Sep 17 00:00:00 2001 From: xstag Date: Mon, 14 Jun 2021 19:38:01 +0400 Subject: [PATCH 2/2] registering admin link --- filebrowser/admin.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 filebrowser/admin.py diff --git a/filebrowser/admin.py b/filebrowser/admin.py new file mode 100644 index 000000000..79712b5e4 --- /dev/null +++ b/filebrowser/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin +from django.db import models + +class browse(models.Model): + class Meta: + verbose_name_plural = "browse" + +admin.site.register(browse)