develop #11
| @@ -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) | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user