I might still "elegant it up a bit" but below are the edited versions of the linked ones.
What is the difference?
I added a predefined list to the head section:
specs = ["folder.png", "cover.png", "monkey.png"]
and I replaced:
try:
first = min(p for p in os.listdir(folder)
if p.split(".")[-1].lower() in ext)
except ValueError:
pass
by:
fls = os.listdir(folder)
try:
first = [p for p in fls if p in specs]
first = first[0] if first else min(
p for p in fls if p.split(".")[-1].lower() in ext
)
except ValueError:
pass
so that the script first tries to find (file) matches in the list specs
, (only) if there are no, it jumps to searching for matching extension, and does the trick if it finds a suitable image.
1. The basic version
To be used with the targeted directory as argument:
#!/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"]
# --- set the list of preferred filenames
# --- use quotes
specs = ["folder.png", "cover.png", "monkey.png"]
# ---
# retrieve the path of the targeted folder
dr = sys.argv[1]
for root, dirs, files in os.walk(dr):
for directory in dirs:
folder = os.path.join(root, directory)
try:
fls = os.listdir(folder)
first = [p for p in fls if p in specs]
first = first[0] if first else min(
p for p in fls if p.split(".")[-1].lower() in ext
)
except (ValueError, PermissionError):
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))
])
How to use
- Copy the script into an empty file, save it as
change_icon.py
- In the head of the script, edit, if you like, the list of extensions to be used as valid icon images. Also set the preferred list of filenames.
Run it with the targeted directory as an argument:
python3 /path/to/change_icon.py <targeted_directory>
That's it!
2. The edited right-click option, to be used as a nautilus (right-click) script
#!/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"]
# --- set the list of preferred filenames
# --- use quotes
specs = ["folder.png", "cover.png", "aap.png"]
# ---
def fix(path):
for c in [("%23", "#"), ("%5D", "]"), ("%5E", "^"),
("file://", ""), ("%20", " ")]:
path = path.replace(c[0], c[1])
return path
# retrieve the path of the targeted folder
current = fix(os.getenv("NAUTILUS_SCRIPT_CURRENT_URI"))
dr = os.path.realpath(current)
for root, dirs, files in os.walk(dr):
for directory in dirs:
folder = os.path.join(root, directory)
try:
fls = os.listdir(folder)
first = [p for p in fls if p in specs]
first = first[0] if first else min(
p for p in fls if p.split(".")[-1].lower() in ext
)
except (ValueError, PermissionError):
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))
])
To use
Create, if it doesn't exist yet, the directory
~/.local/share/nautilus/scripts
Copy the script into an empty file, save it in ~/.local/share/nautilus/scripts
as set_foldericons
(no extension!), and make it executable.
- In the head of the script, edit, if you like, the list of extensions to be used as valid icon images. Also set the preferred list of filenames.
- Log out and back in, and it works.
If, for some reason you'd like to reset the icons inside a folder to their default icon(s), use the script here