Org-Mode für unterwegs mit Orgzly & Syncthing

2018-10-26

Ich suchte schon länger nach einer geeigneten Lösung, wie ich Notizen, erstellt mit Emacs unter dem Org Mode, auch mobil lesen und pflegen kann. Bisher probierte ich z.B. MobileOrg mit der entsprechenden Android-App oder aber die App Orgzly in Kombination mit Nextcloud aus.

Doch erst das Zusammenspiel von Orgzly und syncthing hat mich als mobile Alternative überzeugt, insbesondere was eine flüssige und nahtlose Synchronisation angeht.

Syncthing für den Desktop

Syncthing ist offen, dezentral und kommuniziert verschlüsselt von Ende zu Ende. Es ist für die gängigen Betriebssysteme frei verfügbar. Unter einem aktuellen Debian/Ubuntu kann es direkt über den Package-Manager installiert werden:

apt install syncthing

Nach dem Aufruf syncthing kann die Einrichtung anhand einer Web-Oberfläche im Browser unter localhost:8384 vorgenommen werden. Hier können Verzeichnisse und Geräte für andere syncthing-Instanzen einfach angemeldet werden, was die Dokumentation bereits gut beschreibt. Unter dieser Web-Oberfläche kann somit das zu synchronisierende Org-Verzeichnis berücksichtigt werden, z.B. ~/Documents/org.

Es können dabei auch Dateien von der Synchronisation ausgeschlossen werden. Dies macht Sinn für die Archiv-Dateien des Org-Modes. Diese Dateien werden ausgenommen, wenn z.B. unter ~/Documents/org die Datei .stignore mit dem folgenden Inhalt angelegt wird:

*.org_archive

Bei permanenter Nutzung lohnt sich natürlich die Einrichtung eines Autostarts. Bei einem Desktop vorzugsweise als Daemon über einen Systemd User Service. Ist der Daemon eingerichtet, kann dieser beim Start der GNOME Shell aktiviert werden, indem unter dem Verzeichnis ~/.config/autostart z.B. eine Datei, wie synching-launcher.desktop, mit dem folgendem Inhalt hinterlegt wird:

[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Icon[de_DE]=gnome-panel-launcher
Exec=systemctl --user start syncthing.service
Name[de_DE]=syncthing launcher
Name=syncthing launcher
Icon=gnome-panel-launcher

Als zusätzliche Option gibt es noch eine schöne GNOME Shell Extension namens Syncthing Icon (alternativ via Ubuntu SW-Center installierbar), mit welcher sich der aktive Status von syncthing in der Statusleiste anzeigen und steuern lässt.

Syncthing & Orgzly für das Smartphone

Auf dem Smartphone werden 2 Apps benötigt. Syncthing für die Synchronisation und Orgzly für die eigentliche Bearbeitung der eigenen Org-Notizen, also quasi als mobile und abgespeckte Alternative gegenüber dem Org-Mode unter Emacs.

Syncthing-App

Syncthing ist als gleichnamige App für Android unter F-Droid oder unter GooglePlay verfügbar. Die Einrichtung der zu synchronisierenden Geräte und Verzeichnisse erfolgt analog dem Desktop. Nachdem mit der App die jeweiligen Schlüssel bzw. IDs von Desktop- und Smartphone-Instanzen gegenseitig bekannt gemacht und freigegeben wurden, kann man nun auf das vom Desktop freigegebene Org-Verzeichnis zugreifen.

Orgzly

Orgzly ist ebenfalls unter F-Droid und GooglePlay verfügbar. Unter Orgzly macht man nun das frisch synchronisierte Org-Verzeichnis bekannt mit: Einstellung->Synchronisieren->Ablageorte->Verzeichnis Das Verzeichnis findet man an einem Ort, welcher zum Beispiel, wie folgt, aussehen könnte: /storage/.../Android/data.com.nutomic.syncthingandroid/files/org

Tipp: Um das konkrete Org-Verzeichnis auf dem Smartphone ausfindig zu machen, kann man sich in der syncthing-App den physischen Ablageort des Verzeichnisses anzeigen lassen, indem man sich die Details des Verzeichnisses auflisten lässt.

Zudem habe ich gute Sync-Erfahrungen mit den (noch experimentellen!) Funktionen unter Einstellungen->Synchronisieren->Automatisch synchronisieren gemacht. Ich aktivierte hierzu die folgenden Funktionen:

  • Auto-Synchronisation
  • Notiz erstellt
  • Notiz aktualisiert oder gelöscht
  • App gestartet oder fortgesetzt

Wird nun zum Beispiel eine Org-Datei im o.g. Verzeichnis neu angelegt und synchronisiert, so wird diese von Orgzly erkannt und berücksichtigt. D.h. neue Aufgaben und Notizen werden so unmittelbar automagisch mit eingebunden.

Alternative Syncthing-Zwischenstelle

Die Synchronisation zwischen Smartphone und dem Desktop ist natürlich nur möglich, wenn beide Geräte gleichzeitig online sind. Wenn das selten der Fall sein sollte, dann macht es Sinn die Synchronisation über eine weitere, zwischengeschaltete Instanz laufen zu lassen, die permanent online ist. Hierzu ist z.B. ein stromsparender Raspberry Pi ausreichend, der als Zwischenstelle immer für einen Abgleich zur Verfügung stehen kann. Auf dem PI wäre dann in diesem Falle eine weitere Syncthing-Instanz installiert, welche zwischen Desktop und Smartphone vermittelt: Desktop <-> PI <-> Smartphone

Emacs etwas reaktiver

Ist Emacs mit einer Org-Datei geöffnet, so ist es ärgerlich, wenn neue oder geänderte Notizen für diese Datei nicht direkt angezeigt werden, wenn diese z.B. von außen mit dem Smartphone erstellt oder geändert wurden. Ein manuelles, erneutes Laden wäre da eher nervig. Damit derartige Änderungen direkt automagisch angezeigt werden, aktiviert man den auto-revert-mode beim Start von Emacs via folgender Ergänzung seitens init.el:

(global-auto-revert-mode t)

Das automagische Anzeigen der synchronisierten Änderungen funktioniert tadellos, wenn die im Emacs geladene Datei keine ungespeicherten Änderungen enthält. Sollte dies mal nicht der Fall sein, so gibt Emacs (unabhängig vom auto-revert-mode) beim darauf folgenden Speicherversuch einen Warn-Dialog aus:

dateiname.org has changed since visited or saved. Save anyway? (yes or no)

Bei einem derartigen Fall ist es empfehlenswert, erst einmal die Änderungen unter einem anderen Dateinamen abzuspeichern und die beiden Dateien mit der Funktion ediff-buffers abzugleichen.

Wird allerdings eine Änderung gespeichert kurz bevor eine andere Änderung über die Synchronisation eingeht, so gibt es definitiv einen Konflikt, welcher nur von syncthing selbst aufgezeigt werden kann. In diesem Falle wird die Datei mit der jüngsten Änderung von syncthing übernommen und die andere Version wird als neue Datei mit dem Namen <dateiname>.sync-conflict-<datum>-<zeit>.<org> im gleichen Verzeichnis abgelegt. Doch auch dann kann der User die Konflikte zwischen den beiden Dateien selbst auflösen, wofür sich ebenfalls wieder die Funktion ediff-buffers anbietet.


Subshell Web Service

2014-12-27

Das folgende Bash-Skript antwortet auf einen HTTP-Request mit der aktuellen Uhrzeit.

Beim Start des Skripts werden 2 Prozesse gestartet:

  1. nc horcht auf Port 8080 auf einen HTTP-Request und leitet diesen an die named Pipe weiter.
  2. Der zweite Prozess liest von der named Pipe und leitet mitsamt HTTP Return Code die aktuelle Zeit an nc weiter.

Die named Pipe in Kombination mit der Subshell des 2. Prozesses ist der Kniff des Skripts damit auch die aktuelle Zeit über nc als HTTP-Response zurück geliefert wird.

#!/bin/bash

if [ ! -p pipe ]; then
    mkfifo pipe
fi

while true; do 
    { 
       read line < pipe        
       echo -e "HTTP/1.1 200 OK\r\n"        
       echo $(date)     
     }  | nc -l 8080 > pipe
done

Eine brauchbare Erklärung zur Subshell ist auf Stackexchange zu finden.


Backup-Medium Erstellen und Booten

2014-12-03

Die folgenden Schritte beschreiben, wie der Inhalt von Gerät /dev/sdX nach /dev/sdY kopiert wird. Die entstandene Linux-Kopie (in diesem Fall Ubuntu) wird im Anschluss Boot-fähig gemacht.

Wozu benötigt man dies? Ein Anwendungsfall ist z.B. ein Backup einer internen Festplatte auf ein externes Medium (z.B. USB-Festplatte). So kann beim Ausfall der internen Festplatte vom externen Medium gebootet werden.

Als erstes ist von einem Live-Medium zu booten, wenn z.B. ein Backup des Betriebssystem erstellt werden soll. Die hier aufgezählten Schritte wurden mit Ubuntu 14.04 ausgeführt, sollten jedoch auch auf andere Linux-Distributionen übertragbar sein. Die oben aufgeführten Geräte /dev/sdX nach /dev/sdY werden hier lediglich als Beispiel verwendet und sind zu ersetzten durch die tatsächlich genutzten. Diese kann man z.B. durch das folgende Kommando ermitteln:

sudo lshw -class disk

Vorbereitung: Partitionen auflisten, um Typ und Größe zu prüfen; was ist die bootbare Systempartition?

sudo fdisk -l
  1. Kopie von Gerät /dev/sdX auf Gerät /dev/sdY erstellen:

    sudo dd if=/dev/sdX of=/dev/sdY bs=1M conv=noerror
    
  2. Mounten der kopierten Systempartition /dev/sdYn (n=Partitionsnummer):

    sudo mount /dev/sdYn /mnt
    
  3. Re-Mount der virtuellen Dateisysteme auf das kopierte System:

    sudo mount --bind /dev  /mnt/dev
    sudo mount --bind /dev/pts  /mnt/dev/pts
    sudo mount --bind /proc /mnt/proc
    sudo mount --bind /sys  /mnt/sys 
    
  4. Nun der Trick – Wechsel des Root-Verzeichnisses auf kopierte Systempartition (öffnet von nun an root-Shell):

    sudo chroot /mnt
    
  5. Dies ermöglicht das erstellen der Grub2 Konfiguration /boot/grub/grub.cfg auf das kopierte System:

    update-grub
    
  6. Grub2 auf dem kopierten Medium installieren:

    grub-install /dev/sdY
    
  7. Grub2 Installation verifizieren:

    grub-install --recheck /dev/sdY
    
  8. Im Anschluss sind noch die Mount-Einträge der Dateien /etc/fstab bzw /etc/mtab zu überprüfen. Es wird empfohlen die logischen Partitionsnamen, die dort eingetragen sind, z.B. /dev/sdYn, durch die entsprechende UUID zu ersetzten. Die UUIDs lassen sich, wie folgt, ermitteln:

    blkid
    
  9. Rechner neu booten (und im Anschluss im Bios das entsprechende Laufwerk für /dev/sdY als Boot-Medium auswählen):

    reboot
    

Subversion-Historie um Dateien bereinigen

2011-11-09

Es kann schon mal vorkommen, dass man versehentlich eine Datei in Subversion eincheckt, die dort einfach nichts verloren hat – zum Beispiel eine Konfigurationsdatei mit Zugangsdaten. Hier kommt man mit dem logischem Löschen anhand des Kommandos svn rm file nicht wirklich weiter, da die Datei in der Historie verbleibt und so für andere weiterhin abrufbar ist. In diesem Fall hilft nur das Exportieren, Filtern und neue Aufsetzen des Subversion-Repositories, wie in den folgenden Schritten beschrieben wird.

Im ersten Schritt wird ein Dump vom bestehenden Repository erstellt.

svnadmin dump /var/svn > svn-repo-dump

Im Anschluss wird der Dump um die gegebenen Dateien, welche nicht mehr in der Historie geführt werden sollen, gefiltert.

svndumpfilter exclude path/to/pwd-file \
                      path/to-another/file \
                      < svn-repo-dump \
                      > svn-repo-dump-filtered

Dann ist das bestehende Repository zu sichern und ein neues unter dem gleichen Pfad anzulegen.

mv /var/svn /var/svn.backup
svnadmin create /var/svn

Zum Schluss wird dann noch der gefilterte Dump in das neu angelegte Repository eingespielt. Fertig.

svnadmin load --force-uuid /var/svn < svn-repo-dump-filtered 

Rekursive Suche nach Klassen in Java-Archiven

2011-08-25

In welchem Java-Archiv war noch einmal die Klasse X? Ist die Klasse Y vielleicht noch in einem anderen JAR vorhanden? Hier kann eine rekursive Suche im Dateisystem helfen indem als kleines Hilfswerkzeug die folgende Shell-Funktion in der Datei ~/.bashrc eingefügt wird.

search_jars() {
    search_dir=$1 
    search_term=$2 
    if [ -z "$search_term" -o -z "$search_dir" ]; 
    then
        echo "usage: search_jars [DIRECTORY] [SEARCH_TERM]"
        return 1
    fi
    echo "Searching JARs which contain classes matching \
        '$search_term' in '$search_dir'"
    find $search_dir -name "*.jar" -type f -exec \
         bash -c 'jar tvf "$1" | grep "$2"; \
             if [ $? == 0 ]; then \
                 echo "Found in JAR $1"; \
             fi' {} {} $search_term \;
}

Das folgende Beispiel ruft search_jars auf der Konsole im aktuellen Verzeichnis auf und findet sämtliche Java Archive, die einen Klassennamen enthalten, welcher mit Locator.class endet.

>search_jars . Locator.class
Searching JARs which contain classes matching 'Locator.class' in directory '.'
  com/sun/xml/bind/validator/DOMLocator.class
  com/sun/xml/bind/validator/Locator.class
  com/sun/xml/bind/validator/SAXLocator.class
Found in JAR ./jaxb1-impl.jar
  javax/xml/bind/ValidationEventLocator.class
Found in JAR ./jaxb-api.jar
  com/sun/tools/xjc/reader/dtd/bindinfo/DOM4JLocator.class
  com/sun/tools/xjc/reader/dtd/bindinfo/DOM4JLocator.class
Found in JAR ./jaxb-xjc.jar

>> Ältere Einträge