Custom file browser icon for GDTF files

Posted February 4, 2024  ‐ 5 min read  ‐ Categories: GDTF, Robe Lighting

Configure your desktop to show custom icon for each GDTF file, featuring a thumbnail image of each device in this icon.

This article has been sent to us by the GDTF team at Robe Lighting, thank you!

ℹ️ If you like to write a guide on how to do a custom GDTF thumbnailer on Windows or macOS, send us an email to info (at) gdtf.eu.

Introduction

One of the nice features of contemporary desktop operating systems is the ability to show a different icon for files that belong to a particular application. Where the files are highly dynamic in graphical content (images, PDFs), file explorers even allow to show thumbnails of the content itself.

GDTF files contain a thumbnail of the device, allowing for a great user experience of listing GDTF files:

Linux Nautilus file explorer with GDTF files listing
Linux Nautilus file explorer with GDTF files listing

Of course, the file format has to be popular enough to have it’s own icon handler - an application which is able to extract or generate the thumbnail view of the file content. If the thumbnailer does not exist, creating own file handler is also possible, on Windows, this is specified in the IconHandler. On Linux, the XDG Thumbnails Specification provides some basic information about this topic. We should also be aware of the fact that operating systems utilize thumbnailer sandboxing to prevent a number of different potential attack vectors. This will be affecting some file locations in the system.

This article describes how to create and setup a custom thumbnailer for GDTF files on Linux.

ℹ️ To skip the technicalities, you can jump down to Installation on Linux. This guide has been used and tested with Nautilus Files file manager on GNOME on Debian GNU/Linux.

Specifications

What will need to be done is roughly this:

  • create new mime type x-gdtf for .gdtf files
  • create a custom thumbnailer to generate icon from .gdtf files
  • assign our custom thumbnailer for the new x-gdtf mime type

GDTF files typically do contain a PNG thumbnail image for the given device, but as the GDTF specification makes the .png thumbnail optional, we should have an alternative strategy for .gdtf files without a thumbnail. There are other situations where the provided thumbnail might not be sufficient (for example the size of the object is a too small), thus to have a good fallback, we will use a default icon for GDTF files over which we will overlay the extracted thumbnail PNG if it exists inside the .gdtf.

Under the hood

For the default GDTF icon, we will use the logo from the image provided on the GDTF GitHub page. After extracting it, we get this:

Now we need to create a mime definition, in the form of an xml file, it will define new x-gdtf mime type, this is what it will look like:

<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
  <mime-type type="application/x-gdtf">
    <comment>GDTF file</comment>
    <acronym>GDTF</acronym>
    <expanded-acronym>General Device Type Format file</expanded-acronym>
    <glob pattern="*.gdtf"/>
    <icon name="gdtf"/>
  </mime-type>
</mime-info>

To assign the thumbnailer, we need a XDG Desktop Entry specification file, with a .thumbnailer extension, it will look like this:

[Thumbnailer Entry]
Exec=/usr/local/bin/thumbnailer.py %s %i %o
MimeType=application/x-gdtf;

Now we need the thumbnail extractor itself, will use a few lines of Python to create one.

The Pillow package needs to be installed system-wise, we will need it for the image composition. The Thumbnail image in GDTF file can have custom name, but as in the root of the .gdtf package can only be one .png file - the required thumbnail - we don’t even need to parse the description.xml for the Thumbnail field. The variable base_thumbnail in the code below specifies a location of our background and at the same time fallback image.

#!/usr/bin/env python3

from sys import argv
from zipfile import ZipFile
from PIL import Image
import io
import re

#maxsize = (int(argv[1]), int(argv[1]))
maxsize = (128, 128)  # set fixed size
file_in = argv[2]
file_out = argv[3]
base_thumbnail="/usr/local/bin/gdtf.png"

regx = re.compile("[^\/].*\.png")

with ZipFile(file_in, "r") as zip:
    if len(list(filter(regx.match, zip.namelist()))) > 0:
        thumbname = list(filter(regx.match, zip.namelist()))[0]
        thumbnail = zip.read(thumbname)
        image = io.BytesIO(thumbnail)
        icon = Image.open(base_thumbnail)

        with Image.open(image) as img:
            img.thumbnail(maxsize, Image.LANCZOS)
            icon.paste(img, (0, 0), mask=img)
            icon.save(file_out)
    else:
        with Image.open(base_thumbnail) as img:
            img.save(file_out)

System location of the data

Now we have all parts we need, so lets tell our system what to do with them, for copy/paste version, scroll down below:

  • copy the gdtf.thumbnailer to /usr/share/thumbnailers/
    • cp gdtf.thumbnailer /usr/share/thumbnailers
  • copy the thumbnailer.py to /usr/local/bin/
    • cp thumbnailer.py /usr/local/bin/
  • copy the gdtf.png to /usr/local/bin/
    • cp gdtf.png /usr/local/bin/
  • install the x-gdtf.xml mime file:
    • xdg-mime install --novendor --mode user x-gdtf.xml
  • install the resources:
    • xdg-icon-resource install --novendor --context mimetypes --size 128 --mode user gdtf.png x-gdtf.xml
  • update icon caches:
    • sudo update-icon-caches ~/.local/share/icons
    • or:
    • /usr/sbin/update-icon-caches ~/.local/share/icons
  • update mime database:
    • update-mime-database ~/.local/share/mime

Installation

Here is copy/paste installation:

The complete set of files required for the customer thumbnailer is available for download. Unzip these files into any folder, you can inspect them as needed and then from the same folder, run the following commands:

sudo cp gdtf.thumbnailer /usr/share/thumbnailers
sudo cp thumbnailer.py /usr/local/bin/
sudo cp gdtf.png /usr/local/bin/
xdg-mime install --novendor --mode user x-gdtf.xml
xdg-icon-resource install --novendor --context mimetypes --size 128 --mode user gdtf.png x-gdtf.xml
sudo update-icon-caches ~/.local/share/icons
update-mime-database ~/.local/share/mime

Result

Here is the final result with nice icons, specific to each GDTF file:

Robe Robin Forte GDTF files listing in Nautilus
Robe Robin Forte GDTF files listing in Nautilus

Assign default application

To have your Archive manager to open the GDTF files automatically, you can set the default application via the right click Context Menu. This could be for example the Archive Manager or other GDTF supporting applications, like Production Assist:

Troubleshooting

Make sure to have python3 and python3-pillow installed. In case of further issues, you can check things by killing Nautilus and starting it from the terminal with the following arguments:

G_MESSAGES_DEBUG=all NAUTILUS_DEBUG=Window nautilus

Final words

With the GDTF landscape and eco-system growing, user experience can be made superb on many different levels. This article described one of them, enjoy!