From: Christian Heller Date: Fri, 23 Aug 2024 23:36:25 +0000 (+0200) Subject: To Browser, add caching of metadata per file. X-Git-Url: https://plomlompom.com/repos/index.html?a=commitdiff_plain;h=0defa373a3fa81e02632b6a9c947908fd60fb92e;p=stable_plom To Browser, add caching of metadata per file. --- diff --git a/browser.py b/browser.py index d6925f6..81b089b 100755 --- a/browser.py +++ b/browser.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 from exiftool import ExifToolHelper # type: ignore +from json import dump as json_dump, load as json_load +from os.path import exists as path_exists, join as path_join, abspath import gi # type: ignore gi.require_version('Gtk', '4.0') gi.require_version('Gio', '2.0') @@ -8,28 +10,30 @@ from gi.repository import Gtk, Gio, GObject # type: ignore # noqa: E402 from stable.gen_params import GenParams # noqa: E402 +IMG_DIR='.' + + class FileItem(GObject.GObject): - def __init__(self, name, last_mod): + def __init__(self, path, info, cache): super().__init__() - self.name = name - self.last_mod = last_mod - self._metadata = None - - @property - def metadata(self): - if not self._metadata: - with ExifToolHelper() as et: - for d in et.get_tags([self.name], ['Comment']): - for k, v in d.items(): - if k.endswith('Comment'): - self._metadata = '' - gen_params = GenParams.from_str(v) - for k, v_ in gen_params.as_dict.items(): - self._metadata += f'\n{k}: {v_}' - if not self._metadata: - self._metadata = 'no SD comment' - return self._metadata + self.name = info.get_name() + self.last_mod_time = info.get_modification_date_time().format_iso8601() + self.full_path = path_join(path, self.name) + self.metadata = '' + if self.full_path in cache: + if self.last_mod_time in cache[self.full_path]: + self.metadata = cache[self.full_path][self.last_mod_time] + + def set_metadata(self, et): + self.metadata = 'no SD comment' + for d in et.get_tags([self.name], ['Comment']): + for k, v in d.items(): + if k.endswith('Comment'): + self.metadata = '' + gen_params = GenParams.from_str(v) + for k, v_ in gen_params.as_dict.items(): + self.metadata += f'\n{k}: {v_}' class Window(Gtk.ApplicationWindow): @@ -54,7 +58,8 @@ class Window(Gtk.ApplicationWindow): self.viewer.append(self.metadata) self.viewer.append(self.label_nothing_to_show) - self.dir = Gio.File.new_for_path('.') + img_dir_absolute = abspath(IMG_DIR) + self.dir = Gio.File.new_for_path(img_dir_absolute) self.list_store = Gio.ListStore(item_type=FileItem) self.selection = Gtk.SingleSelection.new(self.list_store) factory = Gtk.SignalListItemFactory() @@ -65,6 +70,11 @@ class Window(Gtk.ApplicationWindow): box_outer.append(self.viewer) self.props.child = box_outer + if not path_exists('cache.json'): + with open('cache.json', 'w') as f: + json_dump({}, f) + with open('cache.json', 'r') as f: + cache = json_load(f) self.max_index = 0 self.item = None self.selection.connect('selection-changed', self.update_selected) @@ -78,14 +88,20 @@ class Window(Gtk.ApplicationWindow): to_sort = [] for info in [info for info in enumerator if info.get_content_type().startswith('image/')]: - item = FileItem(info.get_name(), - info.get_modification_date_time().format_iso8601()) + item = FileItem(img_dir_absolute, info, cache) to_sort += [item] - to_sort.sort(key=lambda i: i.last_mod) + with ExifToolHelper() as et: + for item in [item for item in to_sort if not item.metadata]: + if not item.metadata: + item.set_metadata(et) + cache[item.full_path] = {item.last_mod_time: item.metadata} + to_sort.sort(key=lambda i: i.last_mod_time) for file_item in to_sort: self.list_store.append(file_item) self.max_index = len(self.list_store) - 1 self.update_selected() + with open('cache.json', 'w') as f: + json_dump(cache, f) def update_selected(self, *_args): self.item = self.selection.props.selected_item @@ -96,7 +112,7 @@ class Window(Gtk.ApplicationWindow): def reload(self): self.viewer.remove(self.viewer.get_last_child()) if self.item: - metadata = f'{self.item.name}: {self.item.metadata}' + metadata = f'{self.item.full_path}: {self.item.metadata}' self.metadata.props.label = metadata pic = Gtk.Picture.new_for_filename(self.item.name) self.viewer.append(pic)