diff options
author | Matthias Baumgartner <dev@igsor.net> | 2023-02-17 08:29:26 +0100 |
---|---|---|
committer | Matthias Baumgartner <dev@igsor.net> | 2023-02-17 08:29:26 +0100 |
commit | 906076a24fd3baca68e0381aca1953a05f5b45b7 (patch) | |
tree | dca85ff7f5f3357cdab4c51860ac5e0261d91b5d /tagit | |
parent | 580caf6f5c9b795f9c38b9c970efce12d006ce1d (diff) | |
download | tagit-906076a24fd3baca68e0381aca1953a05f5b45b7.tar.gz tagit-906076a24fd3baca68e0381aca1953a05f5b45b7.tar.bz2 tagit-906076a24fd3baca68e0381aca1953a05f5b45b7.zip |
Fixes:
* Preview loading in browser
* Search via bsfs.Graph.sorted to preserve order
* Fixes in parsing.filter.to_string
Diffstat (limited to 'tagit')
-rw-r--r-- | tagit/actions/search.py | 2 | ||||
-rw-r--r-- | tagit/parsing/filter/to_string.py | 4 | ||||
-rw-r--r-- | tagit/widgets/browser.py | 78 |
3 files changed, 48 insertions, 36 deletions
diff --git a/tagit/actions/search.py b/tagit/actions/search.py index ca36a51..630413f 100644 --- a/tagit/actions/search.py +++ b/tagit/actions/search.py @@ -128,7 +128,7 @@ class Search(Action, StorageAwareMixin, ConfigAwareMixin): items = Cache.get(self._CACHE_CATEGORY, (query, sort), None) if items is None: # FIXME: mb/port: consider sort - items = list(session.storage.get(ns.bsfs.File, query)) + items = list(session.storage.sorted(ns.bsfs.File, query)) Cache.append(self._CACHE_CATEGORY, (query, sort), items) # apply search order because it's cheaper to do it here rather diff --git a/tagit/parsing/filter/to_string.py b/tagit/parsing/filter/to_string.py index 0b1a3e1..a2815de 100644 --- a/tagit/parsing/filter/to_string.py +++ b/tagit/parsing/filter/to_string.py @@ -206,10 +206,10 @@ class ToString(): guids = {guid for sub in query for guid in get_guids(sub.value) } elif self.matches(query, ast.filter.Not(matcher.Partial(ast.filter.Is))): negated = True - guids = get_guids(query.value) + guids = get_guids(query.expr.value) elif self.matches(query, ast.filter.Not(ast.filter.Or(matcher.Rest(matcher.Partial(ast.filter.Is))))): negated = True - guids = {guid for sub in query for guid in get_guids(sub.value) } + guids = {guid for sub in query.expr for guid in get_guids(sub.value) } if len(guids) == 0: # no matches diff --git a/tagit/widgets/browser.py b/tagit/widgets/browser.py index bbc3748..28f7440 100644 --- a/tagit/widgets/browser.py +++ b/tagit/widgets/browser.py @@ -394,18 +394,30 @@ class Browser(GridLayout, StorageAwareMixin, ConfigAwareMixin): if len(items) == 0: # FIXME: mb/port return + resolution = self._cell_resolution() + previews = self._fetch_previews(items, resolution) + default = resource_find('no_preview.png') + for ent, child in zip(reversed(items), childs): + if ent in previews: + buf = previews[ent] + else: + buf = open(default, 'rb') + child.update(ent, buf, f'{ent}x{resolution}') + + def _fetch_previews(self, items, resolution): + """Fetch previews matching *resolution* for *items*. + Return a dict with items as key and a BytesIO as value. + Items without valid asset are omitted from the dict. + """ # fetch previews node_preview = reduce(operator.add, items).get(ns.bse.preview, node=True) previews = {p for previews in node_preview.values() for p in previews} - previews = reduce(operator.add, previews) + previews = reduce(operator.add, previews) # FIXME: empty previews # fetch preview resolutions res_preview = previews.get(ns.bsp.width, ns.bsp.height, node=True) - # get target resolution - resolution = self._cell_resolution() - # get default preview - default = resource_find('no_preview.png') # select a preview for each item - for ent, child in zip(reversed(items), childs): + chosen = {} + for ent in items: try: # get previews and their resolution for this ent options = [] @@ -416,19 +428,21 @@ class Browser(GridLayout, StorageAwareMixin, ConfigAwareMixin): height = res.get(ns.bsp.height, 0) options.append((preview, Resolution(width, height))) # select the best fitting preview - chosen = rmatcher.by_area_min(resolution, options) - # open the preview file, default if no asset is available - thumb_data = chosen.asset(default=None) # FIXME: get all assets in one call - if thumb_data is None: - raise KeyError() - thumb = io.BytesIO(thumb_data) - + chosen[ent] = rmatcher.by_area_min(resolution, options) except (KeyError, IndexError): - # KeyError: - # no viable resolution found - thumb = open(default, 'rb') - # update the image in the child widget - child.update(ent, thumb, f'{ent}x{resolution}') + # skip objects w/o preview (KeyError in node_preview) + # skip objects w/o valid preview (IndexError in rmatcher) + pass + + # fetch assets + assets = reduce(operator.add, chosen.values()).asset(node=True) # FIXME: empty chosen + # build ent -> asset mapping and convert raw data to io buffer + return { + ent: io.BytesIO(assets[thumb]) + for ent, thumb + in chosen.items() + if thumb in assets + } #def _preload_all(self): # # prefer loading from start to end @@ -436,26 +450,24 @@ class Browser(GridLayout, StorageAwareMixin, ConfigAwareMixin): def _preload_items(self, items, resolution=None): """Load an item into the kivy *Cache* without displaying the image anywhere.""" - resolution = resolution if resolution is not None else self._cell_resolution() - def _buf_loader(buffer, fname): # helper method to load the image from a raw buffer with buffer as buf: return ImageLoaderTagit(filename=fname, inline=True, rawdata=buf) - for obj in items: - try: - buffer = obj.get('preview').best_match(resolution) - source = f'{obj.guid}x{resolution}' - - Loader.image(source, - nocache=False, mipmap=False, - anim_delay=0, - load_callback=partial(_buf_loader, buffer) # mb: pass load_callback - ) - - except PredicateNotSet: - pass + resolution = resolution if resolution is not None else self._cell_resolution() + try: + foo = self._fetch_previews(items, resolution) # FIXME: _fetch_previews fails on empty previews/chosen + except TypeError: + return + for obj, buffer in foo.items(): + guid = ','.join(obj.guids) + source = f'{guid}x{resolution}' + Loader.image(source, + nocache=False, mipmap=False, + anim_delay=0, + load_callback=partial(_buf_loader, buffer) # mb: pass load_callback + ) class BrowserAwareMixin(object): |