Comment définir automatiquement les icônes de dossier de plusieurs dossiers?

10

Comment définir la première image de chaque dossier comme icône de dossier?

La question liée ci-dessus a une réponse consistant en un script qui a fonctionné pour moi. Il a juste besoin d'une petite amélioration.

Qu'est ce que ça fait?

Il recherche les fichiers avec les extensions .jpg, .jpeg, .png, .gif, .icns, .ico et les définit comme l'icône de dossier du dossier dans lequel le fichier a été trouvé. Il fonctionne sur plusieurs dossiers, récursivement. Fondamentalement, il essaie de trouver un fichier image dans le dossier, et la première image qu'il trouve est définie comme une icône de dossier. Cela fonctionne très bien pour de nombreux scénarios, et la configuration de ce script est généralement la première chose que je fais après une nouvelle installation (car c'est incroyable).

Quel est le problème?

Il peut y avoir quelques répertoires contenant un grand nombre de fichiers image et le premier fichier image dans ce répertoire peut ne pas être bien adapté pour être l'icône du dossier.

Que faut-il faire?

Au lieu d'être basé sur une extension, s'il devenait basé sur un nom de fichier et ciblait un (par exemple folder.png) ou plusieurs (par exemple albumart.png cover.png) noms de fichiers, ce problème pourrait être résolu.

ou mieux encore faire fonctionner les deux approches dans un seul script

  • Trouver prédéfini filenames
  • S'il est trouvé, définissez-le comme icône de dossier et passez au dossier suivant
  • S'il n'est PAS trouvé, recherchez l'extension prédéfinie et définissez-la comme icône de dossier et passez au dossier suivant
Sumeet Deshmukh
la source
Continuons cette discussion dans le chat .
Sumeet Deshmukh

Réponses:

9

Je pourrais peut-être encore "l'éléger un peu", mais voici les versions éditées des versions liées.

Quelle est la différence?

J'ai ajouté une liste prédéfinie à la section tête:

specs = ["folder.png", "cover.png", "monkey.png"]

et j'ai remplacé:

try:
    first = min(p for p in os.listdir(folder) 
                if p.split(".")[-1].lower() in ext)
except ValueError:
    pass

par:

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

pour que le script essaie d'abord de trouver (fichier) des correspondances dans la liste specs, (uniquement) s'il n'y en a pas, il passe à la recherche de l'extension correspondante et fait l'affaire s'il trouve une image appropriée.


1. La version de base

A utiliser avec le répertoire cible comme 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))
                ])

Comment utiliser

  1. Copiez le script dans un fichier vide, enregistrez-le sous change_icon.py
  2. Dans la tête du script, modifiez, si vous le souhaitez, la liste des extensions à utiliser comme images d'icônes valides. Définissez également la liste préférée des noms de fichiers.
  3. Exécutez-le avec le répertoire cible comme argument:

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

C'est tout!


2. L'option de clic droit modifiée, à utiliser comme un script nautilus (clic droit)

#!/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))
                ])

Utiliser

  1. Créer, s'il n'existe pas encore, le répertoire

    ~/.local/share/nautilus/scripts
    
  2. Copiez le script dans un fichier vide, enregistrez-le ~/.local/share/nautilus/scriptssous set_foldericons(sans extension!) Et rendez-le exécutable .

  3. Dans la tête du script, modifiez, si vous le souhaitez, la liste des extensions à utiliser comme images d'icônes valides. Définissez également la liste préférée des noms de fichiers.
  4. Déconnectez-vous et reconnectez-vous, et cela fonctionne.

Si, pour une raison quelconque, vous souhaitez réinitialiser les icônes d'un dossier à leurs icônes par défaut, utilisez le script ici

Jacob Vlijm
la source
2
Vous devez vérifier que l'URI de Nautilus commence réellement par file://. Au lieu de cela, replace("%20", " ")vous devez utiliser le décodage URI approprié (par exemple urllib.parse.unquote) et le codage ultérieur ( urllib.parse.quote).
David Foerster
@DavidFoerster est-ce que ça va améliorer les performances du script est de toute façon? J'ai essayé de passer subprocess.Popenà subprocess.callmais sur d'énormes répertoires avec près de 700+ sous-titres pas toutes les icônes de dossier
Sumeet Deshmukh
@DavidFoerster merci! mais urllib.parse.quotefonctionne très bien sur un test "sec", pas dans le script. Besoin de savoir pourquoi, mais en laissant la version de travail du script pour l'instant.
Jacob Vlijm
@SumeetDeshmukh: Non, mais cela va faire fonctionner le script avec des URL qui contiennent d'autres caractères "spéciaux" à part le caractère espace (U + 0020). De plus, il serait plus robuste contre les entrées erronées ou fausses et le rattraperait tôt.
David Foerster
@JacobVlijm: Que se passe-t-il lorsque vous essayez de l'utiliser dans le script? Message d'erreur? Des résultats inattendus? Fonctionne unquotecomme prévu?
David Foerster