From 639f14df5e65572f8dc87c0c636a72a6591b89d0 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sat, 4 Feb 2023 16:32:00 -0600 Subject: [PATCH] Thumbnail work, added locals setting, cleanup --- plugins/vod_thumbnailer/plugin.py | 7 +- .../solarfm-0.0.1/SolarFM/solarfm/__main__.py | 3 + .../SolarFM/solarfm/plugins/plugin_base.py | 6 +- .../shellfm/windows/tabs/icons/icon.py | 79 +++++++++++++------ .../tabs/icons/mixins/desktopiconmixin.py | 2 +- 5 files changed, 63 insertions(+), 34 deletions(-) diff --git a/plugins/vod_thumbnailer/plugin.py b/plugins/vod_thumbnailer/plugin.py index ae30515..e2b0af7 100644 --- a/plugins/vod_thumbnailer/plugin.py +++ b/plugins/vod_thumbnailer/plugin.py @@ -115,9 +115,7 @@ class Plugin(PluginBase): hash_img_pth = f"{self._fm_state.tab.ABS_THUMBS_PTH}/{file_hash}.jpg" try: - os.remove(hash_img_pth) if os.path.isfile(hash_img_pth) else ... - - self._fm_state.tab.create_thumbnail(dir, file, f"{scrub_percent}%") + self._fm_state.tab.create_video_thumbnail(f"{dir}/{file}", f"{scrub_percent}%", True) preview_pixbuf = GdkPixbuf.Pixbuf.new_from_file(hash_img_pth) self._thumbnail_preview_img.set_from_pixbuf(preview_pixbuf) @@ -135,8 +133,7 @@ class Plugin(PluginBase): uri = self._fm_state.uris[0] path = self._fm_state.tab.get_current_directory() parts = uri.split("/") - - file_hash = hashlib.sha256(str.encode(uri)).hexdigest() + file_hash = self._fm_state.tab.fast_hash(uri) hash_img_pth = f"{self._fm_state.tab.ABS_THUMBS_PTH}/{file_hash}.jpg" preview_pixbuf = GdkPixbuf.Pixbuf.new_from_file(hash_img_pth) diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/__main__.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/__main__.py index fc2778f..be201a4 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/__main__.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/__main__.py @@ -3,6 +3,7 @@ # Python imports import argparse import faulthandler +import locale import traceback from setproctitle import setproctitle @@ -20,6 +21,8 @@ from app import Application def run(): try: + locale.setlocale(locale.LC_NUMERIC, 'C') + setproctitle(f"{app_name}") faulthandler.enable() # For better debug info diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/plugins/plugin_base.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/plugins/plugin_base.py index ce1e42a..ee8b536 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/plugins/plugin_base.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/plugins/plugin_base.py @@ -12,16 +12,18 @@ class PluginBaseException(Exception): class PluginBase: - def __init__(self): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.name = "Example Plugin" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus # where self.name should not be needed for message comms - self._builder = None self._ui_objects = None self._fm_state = None self._event_system = None + def set_fm_event_system(self, fm_event_system): """ Requests Key: 'pass_fm_events': "true" diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/shellfm/windows/tabs/icons/icon.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/shellfm/windows/tabs/icons/icon.py index 6e95aa5..f9a43f8 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/shellfm/windows/tabs/icons/icon.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/shellfm/windows/tabs/icons/icon.py @@ -1,4 +1,5 @@ # Python imports +import os import hashlib from os.path import isfile @@ -34,31 +35,30 @@ class Icon(DesktopIconMixin, VideoIconMixin, MeshsIconMixin): if file.lower().endswith(self.fmeshs): # 3D Mesh icon ... if file.lower().endswith(self.fvideos): # Video icon - thumbnl = self.create_thumbnail(dir, file, full_path) + thumbnl = self.create_video_thumbnail(full_path) elif file.lower().endswith(self.fimages): # Image Icon thumbnl = self.create_scaled_image(full_path) elif file.lower().endswith( (".blend",) ): # Blender icon - thumbnl = self.create_blender_thumbnail(dir, file, full_path) + thumbnl = self.create_blender_thumbnail(full_path) elif full_path.lower().endswith( ('.desktop',) ): # .desktop file parsing - thumbnl = self.parse_desktop_files(full_path) + thumbnl = self.find_thumbnail_from_desktop_file(full_path) if not thumbnl: thumbnl = self.get_system_thumbnail(full_path, self.sys_icon_wh[0]) if not thumbnl: - thumbnl = self.return_generic_icon() + thumbnl = self.get_generic_icon() return thumbnl except Exception: ... - return self.return_generic_icon() + return self.get_generic_icon() - def create_blender_thumbnail(self, dir, file, full_path=None): + def create_blender_thumbnail(self, full_path): try: - file_hash = hashlib.sha256(str.encode(full_path)).hexdigest() - hash_img_path = f"{self.ABS_THUMBS_PTH}/{file_hash}.png" - if not isfile(hash_img_path): + path_exists, hash_img_path = self.generate_hash_and_path(full_path) + if not path_exists: self.generate_blender_thumbnail(full_path, hash_img_path) return self.create_scaled_image(hash_img_path, self.video_icon_wh) @@ -68,11 +68,14 @@ class Icon(DesktopIconMixin, VideoIconMixin, MeshsIconMixin): return None - def create_thumbnail(self, dir, file, full_path=None, scrub_percent = "65%"): + def create_video_thumbnail(self, full_path, scrub_percent = "65%", replace=False): try: - file_hash = hashlib.sha256(str.encode(full_path)).hexdigest() - hash_img_path = f"{self.ABS_THUMBS_PTH}/{file_hash}.jpg" - if not isfile(hash_img_path): + path_exists, hash_img_path = self.generate_hash_and_path(full_path) + if path_exists and replace: + os.remove(hash_img_path) + path_exists = False + + if not path_exists: self.generate_video_thumbnail(full_path, hash_img_path, scrub_percent) return self.create_scaled_image(hash_img_path, self.video_icon_wh) @@ -103,18 +106,6 @@ class Icon(DesktopIconMixin, VideoIconMixin, MeshsIconMixin): return None - def image2pixbuf(self, full_path, wxh): - """Convert Pillow image to GdkPixbuf""" - im = PImage.open(full_path) - data = im.tobytes() - data = GLib.Bytes.new(data) - w, h = im.size - - pixbuf = GdkPixbuf.Pixbuf.new_from_bytes(data, GdkPixbuf.Colorspace.RGB, - False, 8, w, h, w * 3) - - return pixbuf.scale_simple(wxh[0], wxh[1], 2) # BILINEAR = 2 - def create_from_file(self, full_path): try: return GdkPixbuf.Pixbuf.new_from_file(full_path) @@ -137,5 +128,41 @@ class Icon(DesktopIconMixin, VideoIconMixin, MeshsIconMixin): return None - def return_generic_icon(self): + def get_generic_icon(self): return GdkPixbuf.Pixbuf.new_from_file(self.DEFAULT_ICON) + + def generate_hash_and_path(self, full_path): + file_hash = self.fast_hash(full_path) + hash_img_path = f"{self.ABS_THUMBS_PTH}/{file_hash}.jpg" + path_exists = True if isfile(hash_img_path) else False + + return path_exists, hash_img_path + + + def fast_hash(self, filename, hash_factory=hashlib.md5, chunk_num_blocks=128, i=1): + h = hash_factory() + with open(filename,'rb') as f: + f.seek(0, 2) + mid = int(f.tell() / 2) + f.seek(mid, 0) + + while chunk := f.read(chunk_num_blocks*h.block_size): + h.update(chunk) + if (i == 12): + break + + i += 1 + + return h.hexdigest() + + def image2pixbuf(self, full_path, wxh): + """Convert Pillow image to GdkPixbuf""" + im = PImage.open(full_path) + data = im.tobytes() + data = GLib.Bytes.new(data) + w, h = im.size + + pixbuf = GdkPixbuf.Pixbuf.new_from_bytes(data, GdkPixbuf.Colorspace.RGB, + False, 8, w, h, w * 3) + + return pixbuf.scale_simple(wxh[0], wxh[1], 2) # BILINEAR = 2 diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/shellfm/windows/tabs/icons/mixins/desktopiconmixin.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/shellfm/windows/tabs/icons/mixins/desktopiconmixin.py index 5997d91..09da06b 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/shellfm/windows/tabs/icons/mixins/desktopiconmixin.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/shellfm/windows/tabs/icons/mixins/desktopiconmixin.py @@ -17,7 +17,7 @@ from .xdg.DesktopEntry import DesktopEntry class DesktopIconMixin: - def parse_desktop_files(self, full_path): + def find_thumbnail_from_desktop_file(self, full_path): try: xdgObj = DesktopEntry(full_path) icon = xdgObj.getIcon()