Pimp my Gnome

  Daniel Friedrich   Lesezeit: 13 Minuten  🗪 3 Kommentare Auf Mastodon ansehen

Gnoems Nautilus Funktionalitäten erweitern.

pimp my gnome

Ich bin Fan vom Gnome-Desktop, weil das Konzept der minimalistischen Optik und Funktionalität mir hilft, mich auf meine administrativen Aufgaben zu fokussieren.

Wenn der geneigte Gnome-User allerdings die Idee hat, die verfügbaren Funktionalitäten zu erweitern, wird er von Gnome unterstützt. Nautilus hat eine Schnittstelle, um mit mehr oder weniger beliebigen Shell-Scripts die Nautilus-Funktionalität zu erweitern. Und weil es möglich ist, Shell-Scripte hinter einem GUI zu verstecken (Zenity), können wir solche Zusatzfunktionalität mit viel Komfort bereitstellen.
Zenity ist eine kleine Funktionsbibliothek, welche grafische Dialoge für die Shell unter Gnome und anderen GTK basierten Desktops bereitstellt. Unter KDE würde man z. B. Yad verwenden.

Anhand von zwei mehr oder weniger üblichen Büroprozessen möchte ich zeigen, wie man mit allgemein verfügbaren Linux-Bordmitteln diese Prozesse unter Gnome teil-automatisieren kann.

Bevor wir unsere Scripte für die gewünschten Prozessautomatisierungen bauen, schauen wir uns die Script-Schnittstelle von Nautilus an.

Nautilus Script-Erweiterungen

Wenn in Nautilus ein Rechtsklick auf Verzeichnis(e) oder Datei(en) ausgeführt wird, so wird im Kontextmenü ein Skript-Eintrag eingeblendet, falls tatsächlich solche Scripte verfügbar sind. Unter Debian / Ubuntu findet sich dieses Verzeichnis hier:
~/.local/share/nautilus/scripts
Wenn ein verfügbares Script angeklickt wird, so übergibt Nautilus immer automatisch mehrere Informationen an dieses Script, z. B. die Liste aller markierten Dateien.
Es ist also nichts weiter zu tun, als ein funktionierendes Shell-Script in den scripts Folder von Nautilus abzulegen, um dessen Funktionalität zu erweitern.

Beispiel 1: Bildergalerie

Bei jedem grösseren Ausflug habe ich danach 10 bis 50 neue Fotos auf meinem Handy oder Digicam. Es ist keine grosse Sache, diese Fotos auf den PC zu übertragen (bei mir automatisch). Aber die vielen Fotos zu organisieren, ist mir zu zeitaufwendig. Es ist aber einfach, die Fotos in einen entsprechend benannten Ferienordner zu schieben und mit einem Rechtsklick eine Galerie für die Fotos zu erstellen. Das sieht dann beispielsweise so aus:

  • Die Bildergalerie wird als index.html im Bilderordner erstellt.
  • Die Bilder werden als 400px breite Vorschau gelistet.
  • Unter dem Bild ist ein Hyperlink auf das Bild hinterlegt. Wenn der Link angeklickt wird, so öffnet sich das Bild in einem neuen Tab in Originalgrösse.

Script

Das folgende Script kurz erklärt:
Im Kopfbereich:

  • Zeile 9: IFS ist eine spezielle Bash-Variable welche definiert, wie Trennzeichen in Strings verwendet werden. Hier sichern wir die ursprünglichen Einstellungen des Systems, überschreiben sie für die Ausführungsdauer des Scripts und auf Zeile 30 wird IFS wieder auf den ursprünglichen Wert zurückgestellt.
  • Zeile 18 bis 27: Prüft jede Datei, welche mit der Nautilus-Variablen $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS an das Script übergeben wurde, ob es eine Bilddatei ist. Für die Bilddateien werden die HTML-Fragmente für <img> und für <a href=> erzeugt. Diese HTML-Fragmente werden weiter unten in die index.html eingefügt.
  • Zeile 34 bis 55: Der Header und die Style-Informationen für index.html werden geschrieben
  • Zeile 57: Der Body (Vorschaubilder und Links) wird in die index.html geschrieben
  • Zeile 59 bis 63: Die schliessenden HTML-Elemente werden in die index.html geschrieben
#!/bin/bash

# AUTHOR:       Daniel
# NAME:         bilder_index.sh
# DESCRIPTION:  erstellt eine Bild-Index.html für die ausgewählten Bilder

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

newline='\n'
BILDVERZEICHNIS=""
LINKS=""

for file in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
   do
     filename=$(basename $file)
     extension="${filename##*.}"
     BILDVERZEICHNIS=$(dirname $file)

     if [[ "${extension,,}" == "jpg" ]] || [[ "${extension,,}" == "jpeg" ]] || [[ "${extension,,}" == "png" ]] || [[ "${extension,,}" == "webp" ]]; then
        LINKS="$LINKS        $filename$newline"
     fi
done

IFS=$SAVEIFS

# Bildindex generieren
echo '

        Bild-Index

            * { font-size: small;
               font-family: sans-serif; }

            img {width: 300px;}

            .imgCnt{ width: 320px; 
                    display: inline-table; 
                    border: 1px solid gray; 
                    margin: 5px; 
                    padding: 5px;
                    text-align: center; }

        ' > "$BILDVERZEICHNIS/index.html"

echo -e $LINKS >> "$BILDVERZEICHNIS/index.html"     

echo '

        Generator: Bildverzeichnis.shby: Daniel

' >> "$BILDVERZEICHNIS/index.html"
  • Speichere das Script als Bilder_Index.sh nach
    ~/.local/share/nautilus/scripts
  • Mache das Script ausführbar
    chmod +x ~/.local/share/nautilus/scripts/Bilder_Index.sh

Nun kannst Du in Nautilus in jedem beliebigen Ordner eine oder mehrere Bilddateien markieren und dann Rechts-Klicken

Vorsicht: Falls Dein System nicht auf Debian/Ubuntu basiert, musst Du ggf. mit einem anderen Script-Pfad arbeiten.

Beispiel 2: Dokumentprozess

Im nachfolgend beschriebenen Script werden Benutzereingaben erforderlich. Weil diese Scripts den Gnome-Komfort verbessern sollen, zeigen wir statt des Terminals grafische Dialoge an. Die grafischen Dialoge werden von der Bibliothek Zenity bereitgestellt. Unter Debian/Ubuntu ist Zenity bereits vorinstalliert. Falls Zenity auf Deinem System fehlt, installierst Du es mit
sudo apt install zenity

In meinem heimischen Büro verzichte ich auf ein DMS. Ich lege meine elektronischen Dokumente in einer händisch gepflegten Ordnerstruktur ab. Von allen analogen Dokumenten (Papier / Post) welche ich elektronisch ablegen will, sind schätzungsweise 98 % Rechnungen. Damit diese Arbeiten in einem erträglichen Aufwand bleiben, versuche ich das teilweise zu automatisieren.

  • Die Rechnungs-Dokumente, welche als Papier bei mir eintreffen, werden gesammelt und alle 7 Tage bis 14 Tage eingescannt.
  • Das Scannen geschieht mit einem mobilen Dokument-Scanner via XSane.
  • XSane erstellt pro gescannter Seite eine Bilddatei und benennt diese mit einer fortlaufenden Nummerierung.

  • Die Bilder, welche zusammen ein Rechnungs-Dokument ergeben, werden markiert und mit Rechtsklick an das PDF-Script übergeben, welches das neue Dokument nach den richtigen Konventionen benennt und im richtigen Ordner ablegt.
  • Das Rechnungs-Dokument wird im Archiv-Ordner abgelegt, eine Kopie davon wird im Ordner offene Rechnungen abgelegt. So habe ich auch die offenen Zahlungen im Griff.

Script

Das folgende Script kurz erklärt:
Im Kopfbereich:

  • Zeile 6: Unter Requires sind alle zusätzlichen Bibliotheken gelistet, welche für die Funktionen dieses Scripts notwendig sind. Mit apt install [paket-name] können sie installiert werden.

  • Zeile 8: IFS ist eine spezielle Bash-Variable welche definiert, wie Trennzeichen in Strings verwendet werden. Hier sichern wir die ursprünglichen Einstellungen des Systems, überschreiben sie für die Ausführungsdauer des Scripts und am Script-Ende wird IFS wieder auf den ursprünglichen Wert zurückgestellt.

  • Zeile 11 bis 16: Prozedur, um die Bilddateien in ein PDF zusammenzuführen und gleich anschliessen mit OCR behandelt (also durchsuchbar gemacht)

  • Zeile 22: Prozedur von Zeile 11 wird ausgelöst. Wichtig: Diese Prozedur benötigt mehrere Sekunden Laufzeit. Damit wir nicht auf das Ende warten müssen, schliessen wir den Aufruf am Zeilenende mit einem ampersand (&) ab. Dies bewirkt, dass dieser Befehl in einen separaten Prozess ausgelagert wird und wir (das Script) nicht auf dessen Beendigung warten müssen. Das Script läuft direkt weiter und wartet in Zeile 25 mit einem Formular auf Eingaben.

  • Zeile 25 bis 31: Es wird ein Formular ausgegeben, in dem der Benutzer ein paar Daten erfasst

    • Die Rechnungsnummer
    • Den Lieferanten-Namen
    • Das Rechnungsdatum
  • Zeile 34: Der Benutzer bestimmt das Zielverzeichnis für das PDF. Hier kannst Du sprechende Bezeichnungen für alle von Dir gewünschten Zielordnern definieren. Im Beispiel sind es 3 Ordner

  • Zeile 44: Die Bilder werden gelöscht

  • Zeile 51 bis 65: Der Zielorder für das PDF wird bestimmt. Hier kannst Du die Zielordner gemäss Deinen Konventionen anpassen. Die match-pattern müssen für alle unter Zeile 34 erfassten Labels eine Entsprechung haben.

  • Zeile 67: Falls der Zielordner nicht besteht (z. B. neues Rechnungsjahr) > Ordner anlegen

  • Zeile 71: PDF im Archiv

  • Zeile 72: PDF in Ordner offene Rechnungen

  • Zeile 74: IFS Variable wieder gemäss System belegen.


#!/bin/bash

# AUTHOR:   Daniel
# NAME:     img2rechnung_pdf.sh
# DESCRIPTION:  pack image(s) to .PDF file and then OCR this PDF
# REQUIRES: poppler-utils imagemagick tesseract-ocr tesseract-ocr-deu imagemagick parallel ghostscript qpdf unpaper ocrmypdf
# Prepare:      /etc/ImageMagick-7/policy.xml, set "<policy domain=coder" rights="read | write" pattern="PDF" />" bevore "</policymap>"   

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

proc_makePDF(){
    # PDF erstellen, OCR/Textlayer darüber legen
    convert $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS -page A4 $1.pdf
    sleep 1
    ocrmypdf -d -c -i -q -l deu -f "$1.pdf" "$1.pdf"
}

# Tempfile Ordner für OCR sicherstellen
mkdir -p /tmp/ocrPdf
tmpFileName=$(date +%Y%m%d%H%M%S%N)

proc_makePDF $tmpFileName &

# Zenity Dialog
result=$(zenity --forms --title="Rechnung - Scan" \
        --text="PDF Rechnung aus Scans erstellen und ablegen" \
        --separator="," \
        --add-entry="Rechnung-Nr" \
        --add-entry="Firma/Lieferant" \
        --add-calendar="Dokument-Datum" --forms-date-format="%Y%m%d" \
        )
readarray -d "," -t rgData <<< "$result"

# Zenity Ziel Dialog
tgtUsr=$(zenity --list --title="Empfänger wählen" --column="Empfänger" "Daniel" "Godot" "Downloads")

# endgültiger Filename
fn="${rgData[1]}_${rgData[0]}_${rgData[2]}.pdf"
fName=${fn//$'\n'/}
year=${rgData[2]:0:4}
mv "$tmpFileName.pdf" "$fName"
sleep 1

# Bilddateien aufräumen
for f in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
  do
    rm $f
  done

# PDF-File in Ziel-Ordner verschieben
case $tgtUsr in
  Daniel)
    tgtPath=~/work/Daniel/eRechnung/$year/
    ;;
  Maliwan)
    tgtPath=~/work/Godot/eRechnung/$year/
    ;;
  Downloads)
    tgtPath=~/Downloads/
    ;;
  *)
    tgtPath=~/Downloads/
    ;;
esac 

if [ ! -d $tgtPath ]; then
  mkdir -p $tgtPath
fi

cp $fName $tgtPath

IFS=$SAVEIFS

Quellen:
https://wiki.ubuntuusers.de/Zenity/

  • Speichere das Script als img2rechnung_pdf.sh nach
    ~/.local/share/nautilus/scripts/
  • Mache das Script ausführbar
    chmod +x ~/.local/share/nautilus/scripts/img2rechnung_pdf.sh

Nun kannst Du in Nautilus in jedem beliebigen Ordner eine oder mehrere Bilddateien markieren und dann Rechts-Klicken

Vorsicht Falls Dein System nicht auf Debian/Ubuntu basiert, musst Du ggf mit einem anderen Script-Pfad arbeiten.


Die beiden Scripte wurden unter Debian 12 und Ubuntu 24.4/24.10 getestet. Trotzdem gilt wie immer: Es wird keine Garantie für Folgen allfälliger Fehler übernommen. Für jede Veränderung welche Du an Deinem System vornimmst, trägst Du die volle Verantwortung.

Tags

Tips & Tricks, Gnome, Nautilus, Bilderverwaltung, Dokumentenverwaltung

Fritz
Geschrieben von Fritz am 31. Dezember 2024 um 14:16

Alle Achtung. Tolle Leistung. Als "Normal-User" kann ich nur staunen, was hier möglich ist. Bei mir reichts es nur für echo: "hello user".

Horst
Geschrieben von Horst am 31. Dezember 2024 um 19:29

@Daniel Friedrich: Guter Tip - Thx! Ich habe durch Deinen Artikel nebenbei auch gelernt, wie man mit Scripten umgeht.

Btw freut es mich, dass ich nicht der Einzige bin, welcher das minimalistische Gnome mag. ; ) Zusammen mit den Erweiterungen "Removable Drive Menu" und "Window List" habe ich Alles, was ich brauche.

Eigentlich Prima, dass mit KDE (ästhetisch) und Gnome (minimalistisch) bei Linux zwei mächtige Oberflächen existieren, welche dem Look and Feel jedes Nutzers entgegenkommen.

Sascha
Geschrieben von Sascha am 8. Januar 2025 um 21:17

Ich habe nachdem ich das hier gelesen habe mir auch mal ein paar Sachen überlegt, die man damit anstellen könnte. Hier sind meine Ergebnisse:

Qr-Code aus einem Bild/Screenshot auslesen: [code]

!/bin/bash -e

while read FILE do gnome-terminal --geometry=160x60 --title="ZBaring" -- /bin/bash -c "zbarimg '$FILE'; echo Press a key to Exit; read _" break done