Wie werden Ordnersymbole mehrerer Ordner automatisch festgelegt?

10

Wie lege ich das erste Bild jedes Ordners als Ordnersymbol fest?

Die oben verlinkte Frage hat eine Antwort, die aus einem Skript besteht, das für mich funktioniert hat. Es muss nur ein wenig verbessert werden.

Was tut es?

Es findet Dateien mit den Erweiterungen .jpg, .jpeg, .png, .gif, .icns und .ico und legt sie als Ordnersymbol des Ordners fest, in dem die Datei gefunden wurde. Es funktioniert rekursiv in mehreren Ordnern. Grundsätzlich wird versucht, eine Bilddatei im Ordner zu finden, und das erste gefundene Bild wird als Ordnersymbol festgelegt. Es funktioniert in vielen Szenarien hervorragend und das Einrichten dieses Skripts ist normalerweise das erste, was ich nach der Neuinstallation mache (weil es erstaunlich ist).

Was ist das Problem?

Möglicherweise gibt es einige Verzeichnisse, die viele Bilddateien enthalten, und die erste Bilddatei in diesem Verzeichnis ist möglicherweise nicht als Ordnersymbol geeignet.

Was soll es tun?

Anstatt erweiterungsbasiert zu sein, könnte dieses Problem gelöst werden , wenn es auf Dateinamen basiert und auf einen (z. B. folder.png) oder mehrere (z. B. albumart.png cover.png) Dateinamen abzielt.

oder noch besser, beide Ansätze funktionieren in einem einzigen Skript

  • Finden Sie vordefinierte filenames
  • Wenn gefunden, setzen Sie es als Ordnersymbol und wechseln Sie zum nächsten Ordner
  • Wenn NICHT gefunden, suchen Sie die vordefinierte Erweiterung, legen Sie sie als Ordnersymbol fest und wechseln Sie zum nächsten Ordner
Sumeet Deshmukh
quelle
Lassen Sie uns diese Diskussion im Chat fortsetzen .
Sumeet Deshmukh

Antworten:

9

Ich könnte es immer noch "ein bisschen elegant machen", aber unten sind die bearbeiteten Versionen der verknüpften.

Was ist der Unterschied?

Ich habe dem Kopfbereich eine vordefinierte Liste hinzugefügt:

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

und ich ersetzte:

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

durch:

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

Damit das Skript zuerst versucht, (Datei-) Übereinstimmungen in der Liste zu specsfinden (nur), wenn keine vorhanden sind, springt es zur Suche nach einer passenden Erweiterung und führt den Trick aus, wenn es ein geeignetes Bild findet.


1. Die Basisversion

Zur Verwendung mit dem Zielverzeichnis als 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))
                ])

Wie benutzt man

  1. Kopieren Sie das Skript in eine leere Datei und speichern Sie es unter change_icon.py
  2. Bearbeiten Sie im Kopf des Skripts die Liste der Erweiterungen, die als gültige Symbolbilder verwendet werden sollen, wenn Sie möchten. Legen Sie auch die bevorzugte Liste der Dateinamen fest.
  3. Führen Sie es mit dem Zielverzeichnis als Argument aus:

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

Das ist es!


2. Die bearbeitete Rechtsklick-Option, die als Nautilus-Skript (Rechtsklick) verwendet werden soll

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

Benutzen

  1. Erstellen Sie das Verzeichnis, falls es noch nicht vorhanden ist

    ~/.local/share/nautilus/scripts
    
  2. Kopieren Sie das Skript in eine leere Datei, speichern Sie es ~/.local/share/nautilus/scriptsunter set_foldericons(keine Erweiterung!) Und machen Sie es ausführbar .

  3. Bearbeiten Sie im Kopf des Skripts die Liste der Erweiterungen, die als gültige Symbolbilder verwendet werden sollen, wenn Sie möchten. Legen Sie auch die bevorzugte Liste der Dateinamen fest.
  4. Melden Sie sich ab und wieder an, und es funktioniert.

Wenn Sie aus irgendeinem Grund die Symbole in einem Ordner auf ihre Standardsymbole zurücksetzen möchten, verwenden Sie das Skript hier

Jacob Vlijm
quelle
2
Sie sollten überprüfen, ob der URI von Nautilus tatsächlich mit beginnt file://. Stattdessen replace("%20", " ")sollten Sie die richtige URI-Decodierung (z. B. urllib.parse.unquote) und die spätere Codierung ( urllib.parse.quote) verwenden.
David Foerster
@ DavidFoerster wird dies die Leistung des Skripts trotzdem verbessern? Ich habe versucht, zu wechseln subprocess.Popen, subprocess.callaber in riesigen Verzeichnissen mit fast 700+ Subs sind nicht alle Ordnersymbole chnage.
Sumeet Deshmukh
@ DavidFoerster danke! urllib.parse.quotefunktioniert aber gut bei einem "trockenen" Test, nicht im Skript. Sie müssen herausfinden, warum, aber die funktionierende Version des Skripts vorerst verlassen.
Jacob Vlijm
@SumeetDeshmukh: Nein, aber das Skript funktioniert mit URLs, die neben dem Leerzeichen (U + 0020) noch andere "Sonderzeichen" enthalten. Außerdem wäre es robuster gegen fehlerhafte oder falsche Eingaben und würde es frühzeitig erkennen.
David Foerster
@JacobVlijm: Was passiert, wenn Sie versuchen, es im Skript zu verwenden? Fehlermeldung? Unerwartete Ergebnisse? Funktioniert unquotewie erwartet?
David Foerster