Home Blog CV Projects Patterns Notes Book Colophon Search

Gnome Thumbnailers

16 Aug, 2023

I have a hard disk full of old files, some of which are photos.

I've written a script to take find the photos and store a de-duplicated copy (based on sha256) into a drive.

I then re-generate the original folder structure so that I can browse them as before, using a hard link to the sha256 copy.

Now I'd like to be able to browse that folder structure quickly using Gnome's built in file manager. To do that I need to generate all the thumbnails in advance.

WARNING: This is quickly jotted down as a note to myself rather than a full, tested tutorial, your mileage may vary.

Before I go into some code, here are some related links:

It turns out there is an entire infrastructure for thumbnailing.

I amend my /usr/share/thumbnailers/gdk-pixbuf-thumbnailer.thumbnailer file to this to support more file types:

[Thumbnailer Entry]
Exec=/usr/bin/gdk-pixbuf-thumbnailer -s %s %u %o

This doesn't seem to work for Fuji or Lumix cameras so I create a new /usr/share/thumbnailers/raf.thumbnailer like this:

[Thumbnailer Entry]
Exec=/usr/local/bin/raf-thumbnailer %i %o %s

Where the /usr/local/bin/raf-thumbnailer file looks like this:


# Thumbnailer for Fujifilm RAF files

# This script depends on the following packages:
# - exiv2 for exiv2
# - imagemagick for convert

# Check for correct number of command-line arguments
if [ $# -eq 3 ]

  # First argument is path to RAW file (convert from URI to normal path)

  # Second argument is output path for thumbnail file

  # Third argument is image size

  # Remove directory from path

  # Remove extension from file name

  # Compose path to thumbnail as composed by exiv2

  # Extract preview image from RAW file
  exiv2 -l /tmp -ep2 -f "${RAW}"
  # Convert preview image into thumbnail
  convert -auto-orient -scale "${SIZE}x${SIZE}" "${PREV}" "${OUT}"

  # Delete preview image
  rm -f "${PREV}"

Checking the permissions:

ls -la /usr/share/thumbnailers/raf.thumbnailer /usr/local/bin/raf-thumbnailer
-rw-r--r-- 1 james james 1828 Aug 16 09:21 /home/james/Desktop/thumbs/thumbs.py
-rwxr-xr-x 1 root  root   901 Aug 16 09:35 /usr/local/bin/raf-thumbnailer
-rw-r--r-- 1 root  root   143 Aug 16 09:25 /usr/share/thumbnailers/raf.thumbnailer

Now, thumbnails should be correctly generated as I browse, but I want to convert them all upfront.

Here's a script to run the thumbnailer infrastructure (adjust the paths for bits you want to skip):

import os
import sys

from gi.repository import Gio, GnomeDesktop

def make_thumbnail(factory, filename):
    mtime = os.path.getmtime(filename)
    # Use Gio to determine the URI and mime type
    f = Gio.file_new_for_path(filename)
    uri = f.get_uri()
    if uri.startswith('file:///media/james/src') or uri.startswith('file:///media/james/target/'):
        # print("SKIP        %s" % uri)
        return False

    info = f.query_info(
        'standard::content-type', Gio.FileQueryInfoFlags.NONE, None)
    mime_type = info.get_content_type()

    if factory.lookup(uri, mtime) is not None:
        print("FRESH       %s" % uri)
        return False

    if not factory.can_thumbnail(uri, mime_type, mtime):
        print("UNSUPPORTED %s" % uri)
        return False

        thumbnail = factory.generate_thumbnail(uri, mime_type)
        if thumbnail is None:
            print("ERROR       %s" % uri)
            return False
    except BaseException as e:
        print("ERROR       %s" % uri)
        return False

    print("OK          %s" % uri)
    factory.save_thumbnail(thumbnail, uri, mtime)
    return True

def thumbnail_folder(factory, folder):
    for dirpath, dirnames, filenames in os.walk(folder):
        for filename in filenames:
            make_thumbnail(factory, os.path.join(dirpath, filename))

def main(argv):
    factory = GnomeDesktop.DesktopThumbnailFactory.new(GnomeDesktop.DesktopThumbnailSize.LARGE)
    for filename in argv[1:]:
        if os.path.isdir(filename):
            thumbnail_folder(factory, filename)
            make_thumbnail(factory, filename)

if __name__ == '__main__':

When I run this all thumbnails are generated.

Gnome is quite keen at purging them all though, so I back them all up and restore them as needed.

mkdir -p /home/james/Desktop/thumbs/cache/large
rsync -aHv /home/james/.cache/thumbnails/large/ /home/james/Desktop/thumbs/cache/large/
du -hs /home/james/Desktop/thumbs/cache/large

I can find any misgenerated ones, or work their types with commands similar to this:

find ~/.cache/thumbnails/large/ -type f -size -4096c -exec ls -la {} \;
xdg-mime query filetype INPUT_FILE


Be the first to comment.

Add Comment

Copyright James Gardner 1996-2020 All Rights Reserved. Admin.