Ubuntu – How to set the first picture of every folder as its folder icon

command linedirectoryiconsscriptsthumbnails

If there are pictures in folder A, B, C…..Z, how do I automatically set the first picture in each of these folders as its folder icon? Is there a way like a script or something else?

Best Answer

1. Automatically change folder icon into the first found image inside

The python script below will change the icon of all folders inside a directory (recursively) into the first found valid image file inside the folder.

The script

#!/usr/bin/env python3
import subprocess
import os
import sys

# --- set the list of valid extensions below (lowercase)
# --- use quotes, *don't* include the dot!
ext = ["jpg", "jpeg", "png", "gif","icns", "ico"]
# ---

dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    for directory in dirs:
        folder = os.path.join(root, directory)
        try:
            first = min(p for p in os.listdir(folder) 
                        if p.split(".")[-1].lower() in ext)
        except ValueError:
            pass
        else:
              subprocess.Popen([
                  "gvfs-set-attribute", "-t", "string",
                  os.path.abspath(folder), "metadata::custom-icon",
                  "file://"+os.path.abspath(os.path.join(folder, first))
                  ])

Download from Pastebin

How to use

  1. Copy the script into an empty file, save it as change_icon.py
  2. In the head of the script, edit, if you like, the list of extensions to be used as valid icon images.
  3. Run it with the targeted directory as an argument:

    python3 /path/to/change_icon.py <targeted_directory>
    

That's it!

2. More advanced

...is to make it a right-click option in nautilus:

enter image description here

The script is slightly different then:

#!/usr/bin/env python3
import subprocess
import os

# --- set the list of valid extensions below (lowercase)
# --- use quotes, *don't* include the dot!
ext = ["jpg", "jpeg", "png", "gif", "icns", "ico"]
# ---

# retrieve the path of the targeted folder
current = os.getenv("NAUTILUS_SCRIPT_CURRENT_URI").replace("file://", "").replace("%20", " ")
dr = os.path.realpath(current)

for root, dirs, files in os.walk(dr):
    for directory in dirs:
        folder = os.path.join(root, directory)
        try:
            first = min(p for p in os.listdir(folder) 
                        if p.split(".")[-1].lower() in ext)
        except ValueError:
            pass
        else:
              subprocess.Popen([
                  "gvfs-set-attribute", "-t", "string",
                  os.path.abspath(folder), "metadata::custom-icon",
                  "file://"+os.path.abspath(os.path.join(folder, first))
                  ])

Download from Pastebin

To use

  1. Create, if it doesn't exist yet, the directory

    ~/.local/share/nautilus/scripts
    
  2. Copy the script into an empty file, save it in ~/.local/share/nautilus/scripts as set_foldericons (no extension!), and make it executable.

  3. Log out and back in, it works.

Notes

  • This will change the icon of all folders inside the right-clicked folder, not of the folder itself.
  • Since os.path.realpath() is used, this also works if the targeted folder is a link.

EDIT

Undo (reset) the custom icons inside a directory recursively

If, for some reason you'd like to reset the icons inside a folder to their default icon(s), use the script below. Simply:

  • copy it into an empty file, save it as reset_icons.py
  • run it by the command:

    python3 /path/to/reset_icons.py <target_directory>
    

The script

#!/usr/bin/env python3
import subprocess
import os
import sys

dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    for directory in dirs:
        folder = os.path.join(root, directory)
        subprocess.Popen([
            "gvfs-set-attribute", os.path.abspath(folder),
            "-t", "unset", "metadata::custom-icon"
            ])
Related Question