diff mit eclipse

Man mag es kaum glauben, aber Eclipse hat doch die ein oder andere nutzliche Funktion (von Haus aus) dabei. Man kann 2 Dateien sehr einfach miteinander vergleichen. Einfach die Dateien markieren dann Rechtsklick -> „Compare With“ -> „Each Other“ -> 🙂 .

Google Keep in Thunderbird

Google Keep ist eine relativ neue Notiz App von Google (offensichtlich 😉 ). Böse Zungen behaupten Google will Evernote damit aus dem Markt drängen, aber Fakt ist, dass Google Keep bei weitem nicht den Funktionsumfang bietet wie Evernote. Allerdings ist es ein sehr schöner Ersatz für die 100 Zettel die man an den Monitor klebt. Viel mehr kann Google Keep auch nicht: Notizen erstellen, Notiz in Listenform erstellen, Bild an Notiz anhängen, Notizen farbig markieren. Das ist im Großen und Ganzen ein paar Post-It Blöcke und ein Kuli….

Für mich ist das allerding völlig ausreichend, und da ich die Googel Applikationen gerne benutze habe ich mich auch für Google Keep entschieden. Leider teilt Google nicht meine Vorlibe von „klassischen“ Desktop Apps. Wenn ich Google Keep im Browser verwende, kommt es nicht selten vor, dass ich es in meinen gefühlten 600 Tabs nicht finde und ständig neu öffnen muss. Das empfinde ich als nicht praktikabel denn wenn „man mal schnell“ was aufschreiben muss fange ich nicht an die Tabs zu durchsuchen ….

Also bin ich auf die Idee gekommen wie bei ThunderCal einen Butten in Thunderbird einzubauen. Mit einem Klick auf den button öffnet sich in Thunderbird ein neuer Tab der Googel Keep öffnet. Dadurch benutzt man direkt die von Google bereitgestellte WebApp aber in einem schnell erreichbaren Tab. Dadurch erweitert sich Thunderbird auch wieder ein Stück in Richtung Selbstorga-App.

Man muss dazu sagen, dass ich eigenlicht keine Ahnung von AddOn Entwicklung habe. Deswegen habe ich einfach die ThunderCal App so modifizerit, dass sie Google Keep aufruft und dem eigentlichen Thundercal nicht in die Quere kommt (hoffe ich). Die Qualität des Codes ist meines erachtens recht gut. Wenn ich mal etwas mehr Zeit habe, überarbeitet ich die App nochmal aber bis dahin gibt es sie hier als Beta zum download.

Viel Spass damit 😉

ThunderKeep

Links:
Download ThunderCal 1.1 und ThunderKeep 0.6 (auf Basis von ThunderCal 1.1)

Raspberry Pi als „Audiosink“

Ich arbeite momentan an einem kleine Zoneplayer System. Während der Recherche nach geeigneter Software ist mir Airplay und UPNP AV aufgefallen. Frisch motiviert hab ich gleich etwas gebastelt um im Tanzverein dem Trainer einen Airplay Renderer anzubieten. Jetzt bin ich bei den Feinheiten.

Die Sache ist eigentlich ganz einfach wenn man weiss wie es get 😉 XBMC und damit alle XBMC-Ditributionen für das Raspberry Pi unterstützt von Haus aus Airplay und UPNP AV. Und zwar das ganze für Audio UND Video. Sehr cooles Feature muss ich sagen.

Wer Android hat, sollte sich die App BubbleUPNP mal ansehen. Die App ist kostenlos und funktioniert super. Bei Apple kann man mit Boardmitteln loslegen (Stichwor „Airplay“).

Was mich nun interessiert ist die Performance. Bedingt durch das Streaming der Daten und die Latenzen im Netz, die schwachen Prozessoren im Handy/Tablet und im Pi gibt es leider ein paar Delays. Ich versuche nun das Delay auf der Pi Seite zu minimieren und probiere deswegen jede XBMC-Distribution durch 😉

Folgende Daten konnte ich ermitteln:

Xbian:
UPNP Start / Stop: ca. 0,3s
UPNP neues Lied: ca. 5,2s
Airplay Start / Stop: ca. 3,5-4s
Airplay neues Lied: ca. 6 – 10s
Boot Dauer: ca. 47s

Raspbmc:
UPNP Start / Stop: ca. 0,4s
UPNP neues Lied: ca. 5,6s
Airplay Start / Stop: ca. 10,3s
Airplay neues Lied: ca. 11 – 15s
Boot Dauer: ca. 46s

OpenELEC:
UPNP Start / Stop: ca. 0,3s
UPNP neues Lied: ca. 6-9s
Airplay Start / Stop: ca. 3,3s (aber Aussetzer! -> zu kleiner Puffer)
Airplay neues Lied: ca. 5,5s (aber Aussetzer! -> zu kleiner Puffer)
Boot Dauer: ca. 46s

Man muss dazu sagen, dass die Liedlänge Auswirkungen auf die Zeiten hat. Desweiteren ist mein IPod Touch mit erheblich schlechterer Hardware ausgestattet als mein Android Handy. Nichts desto trotz sind die Airplay Zeiten doch etwas enttäuschend. Ich hoffe dass sich das in der Zukunft bessert. Ich denke es gibts noch etwas Tuning potienzial wenn man Puffergröße und ähnliches umstellt. Allerdings suche ich mehr eine „out of the box“ Lösung. Und hier muss man sehen das Xbian die besten Werte liefert. Ich werde das mal eine Weile beobachten 😉

Network Scanner mit dem Raspberry Pi

Heute habe ich dringend meinen alten Scanner gebraucht und musste leider feststellen, dass es keinen Windows 8 Treiber mehr gibt -.-

Abhilfe schafft da ein Raspberry Pi. Ich habe beim kauf darauf geachtet, dass der Scanner von der SANE Bibliothek unterstützt wird 🙂 Jetzt kann ich mit meinem guten alten Scanner über Netzwerk scannen.

Eine Schritt für Schritt Anleitung gibt es hier:

Raspberry Pi: Sharing a scanner with the Network – even Windows!

Alternativ kann man das Pi so einstellen, dass es über einen Knopfdruck mit dem Scan beginnt und das Bild als PDF in die Dropbox kopiert. Das ist vllt die einfachere Lösung 😀

Hier noch ein paar weitere Infos:

Scannen mit dem Raspberry Pi und Canon Scannern

Packer Bash Script

Und hier der besagte Script aus dem letzten Post. Unter Linux wird „packer testscript.sh script.sh daten.tgz“ aufgerufen und man bekommt einen Script namens „testscript.sh“ der die datei „daten.tgz“ enthält.

#!/bin/bash
#
# Creates an script with bundled data
#
# Author: Jens Heuschkel <jens@3und20.eu>
#

BANNER="packer v0.1"

PROG=`basename "$0"`
if [ $# -ne 3 -o "$1" == "--help" -o "$1" == "-h" ]; then
  echo $BANNER
  echo "Usage: ${PROG} NEWSCRIPT SCRIPT DATA_TAR"
  echo "       Creates a wrapper called NEWSCRIPT that wraps the"
  echo "       specified SCRIPT and appends the DATA_TAR"
  echo ""
  echo "   or: ${PROG} -h|--help"
  echo "       Prints this message."
  exit 0
fi

NEWSCRIPT=$1
SCRIPT=$2
DATA_TAR=$3

echo $BANNER
echo "Checking files.."

if [ ! -e ${SCRIPT} ]
then
 echo "Script \"${SCRIPT}\" not found." >&2
 exit 1
fi

if [ ! -e ${DATA_TAR} ]
then
 echo "Data \"${DATA_TAR}\" not found." >&2
 exit 1
fi

touch $NEWSCRIPT
if [ ! -e ${NEWSCRIPT} ]
then
 echo "Can't write \"${NEWSCRIPT}\". Check rights." >&2
 exit 1
fi

# Get size
TAR_SIZE=`stat -c %s ${DATA_TAR}`

#SPLIT_CMD="tail -c ${TAR_SIZE} \$0 | tar -xz ${DATA_TAR}"
SPLIT_CMD="tail -c ${TAR_SIZE} \$0 > ${DATA_TAR}"

# Write untar part
cat > ${NEWSCRIPT} <> $NEWSCRIPT

cat >> ${NEWSCRIPT} <<'EOF' exit # Data goes here EOF cat $DATA_TAR >> $NEWSCRIPT

chmod +x $NEWSCRIPT
echo "done"
exit 0

Der Script funktioniert nach dem Vorbild von jar2sh von martiansoftware

Quelle:
http://www.martiansoftware.com/lab/jar2sh.html

More Bash

Uns schon wieder eine kleine Bash Weisheit….
Ich bastel gerade an einem Script der Scripte und Tar-Daten in eine Datei packt. Ist ganz praktisch für install Scripte die eigene Daten mitbringen sollen.

Das Ganze funktioniert so:

  • Der Script schreibt ein paar Zeilen um die Daten weg zu splitten
  • Dann wird der eigentlich Script geschrieben
  • Dann die Tar-Daten (einfach mit cat)

Beim ausführen werden die Daten einfach vom Ende weg kopiert und dann verhält sich der Script die der Ursprungsscript.

Und in dem Zusammnhang habe ich eine spielerei mit cat entdeckt:

  • cat > ZIELDATEI <<EOF schreibt die folgenden Zeilen bis EOF kommt.
  • cat > ZIELDATEI <<‚EOF‘ macht das gleiche 😀

Ich hab mich jetzt gefragt wo der unterschied ist, weil ich beides in einem Script gesehen habe.
Bei der version mit ‚EOF‘ werden Variablen nicht aufgelöst und bei EOF schon. Gut zu wissen 🙂

Java Server als Daemon auf Debian Linux

Ich habe einige Tage nach einer einfachen Möglichkeit gesucht, meine Java Programme als Daemon auf Debian Linux zu starten. Es gibt einiges an Scripten für SuSe und davon auch Portierungen auf Debian. Allerdings fand‘ ich diese Implementierungen immer unnötig kompliziert und unübersichtlich.

Gestern bin ich endlich auf eine einfache und klar programmierte Lösung gestossen. Ein einfacher Wrapperskript der alle benötigten Funktionen unterstützt. Der Skript ist von 2009 läuft aber noch einwandfrei. Allerdings ist er nicht auf Debian spezialisiert und ist für die KSH geschrieben. Ich bin mal alles durchgegangen und habe einige Anpassungen gemacht. Herausgekommen ist folgende Debian interpretation:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          skeleton
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Java Daemon Script
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO

# Author: Jens Heuschkel <jens@3und20.eu>

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin

APP_NAME="MyApp"
APP_LONG_NAME="My App Server"

#the location of the pid files.
PIDDIR="/var/run"
PIDFILE="${PIDDIR}/${APP_NAME}.pid"
TIMESTAMP=$( date +%Y%m%d_%H%M%S )

#number of seconds to wait after starting up.
WAIT_AFTER_STARTUP=2

#the location of the log files
LOG_DIR="/var/log"
STDOUT="${LOG_DIR}/${APP_NAME}.stdout.log"

#PURGE_EXPRESSION="-mtime +2"
PURGE_EXPRESSION="${LOG_DIR}/${APP_NAME}*"

HEAPSIZE_INIT=16
HEAPSIZE_MAX=100
VMARGS="-Xms${HEAPSIZE_INIT}M -Xmx${HEAPSIZE_MAX}M -verbose:gc"
MAINCLASS="com.wordpress.jensheuschkel.MyApplication"
JARFILE="MyApp.jar"
ARGS=""

JAVA_COMMAND="/usr/bin/java"

# Startup with Classpath
#START_COMMAND="${JAVA_COMMAND} $VMARGS $MAINCLASS $ARGS"
# Startup with jar
START_COMMAND="${JAVA_COMMAND} $VMARGS -jar ${JARFILE} ${ARGS}"
#-----------------------------------------------------------------------------
# Do not modify anything beyond this point
#-----------------------------------------------------------------------------

checkroot() {
 if [[ $EUID -ne 0 ]]; then
  echo "This script must be run as root" 1>&2
  exit 1
 fi
}

getpid() {
  pid=""
  if [ -f "$PIDFILE" ]
  then
    if [ -r "$PIDFILE" ]
    then
      pid=`cat "$PIDFILE"|cut -d: -f1`
      host=`cat "$PIDFILE"|cut -d: -f2`
      currhost=`hostname`
      if [ "$host" != "$currhost" ]
      then
       echo "You are on the wrong host. $APP_LONG_NAME runs on $host."
       exit 1
      fi

      if [ "X$pid" != "X" ]
      then
       kill -0 $pid > /dev/null 2>&1
  if [ $? -ne 0 ]
  then
   # Process doesn't exist, so remove pidfile
   rm -f "$PIDFILE"
            echo "Removed stale pid file: $PIDFILE"
   pid=""
  fi
      fi
    else
      echo "Cannot read $PIDFILE."
      exit 1
    fi
  fi
}

#tests if the pid is alive
testpid() {
  kill -0 $pid > /dev/null 2>&1
  if [ $? -ne 0 ]
  then
   # Process is gone so remove the pid file.
 rm -f "$PIDFILE"
 pid=""
  fi
}

start() {
  echo "Starting $APP_LONG_NAME..."
  getpid
  if [ "X$pid" = "X" ]
  then
    if [ -s $STDOUT ]
    then
     #backup current file
     mv $STDOUT $STDOUT.sav.${TIMESTAMP}
    fi
    echo CLASSPATH is $CLASSPATH > $STDOUT
    echo ${START_COMMAND} >> $STDOUT
    nohup ${START_COMMAND} >> $STDOUT 2>&1 &
    echo $!:`hostname` > $PIDFILE
  else
    echo "$APP_LONG_NAME is already running."
    exit 1
  fi

  # Sleep for a few seconds to allow for intialization if required
  # then test to make sure we're still running.
  i=0
  while [ $i -lt $WAIT_AFTER_STARTUP ]
  do
    sleep 1
    i=`expr $i + 1`
  done
  if [ $WAIT_AFTER_STARTUP -gt 0 ]
  then
    getpid
    if [ "X$pid" = "X" ]
    then
      echo "WARNING: $APP_LONG_NAME may have failed to start."
      exit 1
    else
      echo "running ($pid)."
    fi
  else
    echo ""
  fi
}

stopit() {

  echo "Stopping $APP_LONG_NAME..."
  getpid
  if [ "X$pid" = "X" ]
  then
    echo "$APP_LONG_NAME was not running."
  else
    # Running so try to stop it.
    kill $pid
    if [ $? -ne 0 ]
    then
      echo "Unable to stop $APP_LONG_NAME."
      exit 1
    fi

    #  If it has not stopped in 10 tries, forcibly kill it
    savepid=$pid
    CNT=0
    TOTCNT=0
    while [ "X$pid" != "X" ]
    do
      # Show a waiting message every 5 seconds.
      if [ "$CNT" -lt "5" ]
      then
        CNT=`expr $CNT + 1`
      else
        echo "Waiting for $APP_LONG_NAME to exit..."
        CNT=0
      fi

      if [ $TOTCNT -gt 11 ]
      then
       echo "Killing by force (kill -9)"
       kill -9 $pid
      fi

      TOTCNT=`expr $TOTCNT + 1`
      sleep 1

      testpid
    done

    pid=$savepid
    testpid
    if [ "X$pid" != "X" ]
    then
      echo "Failed to stop $APP_LONG_NAME."
      exit 1
    else
      echo "Stopped $APP_LONG_NAME."
    fi
  fi
}

purge() {
#  pcmd="find $LOG_DIR -follow -type f $PURGE_EXPRESSION -print -exec rm -f {} +"
  pcmd="rm -f ${PURGE_EXPRESSION}"
  echo "Running purge: $pcmd"
  $pcmd
}

alert() {
  if [ "X$EMAIL" != "X" ]
  then
   echo "$APP_LONG_NAME is not running on `hostname`. Please check and restart." \
   | mailx -s "`hostname`: $APP_LONG_NAME is not running" "$EMAIL"
   echo "Sent alert to $EMAIL"
  fi
}

status() {
  getpid
  if [ "X$pid" = "X" ]
  then
    echo "$APP_LONG_NAME is not running."
    alert
    exit 1
  else
    echo "$APP_LONG_NAME is running (PID:$pid)."
    exit 0
  fi
}

dump() {
  echo "Dumping $APP_LONG_NAME..."
  getpid
  if [ "X$pid" = "X" ]
  then
    echo "$APP_LONG_NAME is not running."
  else
    kill -3 $pid

    if [ $? -ne 0 ]
    then
      echo "Failed to dump $APP_LONG_NAME."
      exit 1
    else
      echo "Dumped $APP_LONG_NAME."
    fi
  fi
}

####################

checkroot

case "$1" in

  'start')
    start
    ;;

  'stop')
    stopit
    ;;

  'restart')
    stopit
    start
    ;;

  'status')
    status
    ;;

  'dump')
    dump
    ;;

  'purge')
    purge
    ;;

  *)
    echo "Usage: $0 { start | stop | restart | status | dump | purge }"
    exit 1
    ;;
esac

exit 0

 

Die VM Einstellungen sind für das Rapberry Pi und sollten noch angepasst werden. Es wird auch nicht gecheckt ob JAVA installiert ist aber das kann man ja im Install-Skript des Servers machen 😉

Quelle:
http://fahdshariff.blogspot.de/2009/09/unix-wrapper-script-for-java.html

Bash IF Conditions

Jaja schon wieder Bash :DIch vergesse einfach ständig die Syntax und aufschreiben ist das Einzige das ein bisschen hilft.
Mal „unter uns“: Bash ist auch eine der anstrengensten Skriptsprachen überhaupt …

Also diesmal geht es um IF Conditions. Grundsätzlich funtkioniert es wie folgt:

if [ <condition> ]then

elif [ <condition> ]
then

else

fi

Das allein finde ich schon unintuitiv: „elif“ statt „else if“ und then in einer neuen Zeile. Alternativ kann man auch „; then“ in der gleichen Zeile schreiben. Abgeschlossen wird das ganze mit „if“ rückwärts, also „fi“. Aufpassen, denn die Leerzeichen vor und nach den Klammern sind nicht optional!

Nun nun zu den Conditions:

  • [ -e filepath ] wird true wenn die Datei existiert.
  • [ -x filepath ] wird true wenn die Datei existiert und ausführbar ist.
  • [ -S filepath ] wird true wenn die Datei existiert und eine Socket-Datei ist.
  • [ -d filepath ] wird true wenn die Datei existiert und ein Verzeichnis ist.
  • [ -w filepath ] wird true wenn die Datei existiert und schreibbar ist.
  • [ expr1 -a expr2 ] entspricht dem logischen AND (Java: &&)
  • [ expr1 -o expr2 ] entspricht dem lofischen OR (Java: || )
  • [ -n $VARIABLE ] wird true wenn die Varable (also der String) nicht leer ist.
  • [ -z $VARIABLE ] wird true wenn die Varable (also der String) leer ist (Java: „foo“.isEmpty() ).
  • [ $VARIABLE = $VARIABLE2 ] wird true wenn die beiden Variablen gleich sind (Java: „foo“.equals(„foo“) ).
    ACHTUNG: Das funktioniert nur mit Strings und nicht mit Zahlen und ist Case-Sensitiv.
  • [ $VARIABLE -eq $VARIABLE2 ] wird true wenn die beiden Variablen die gleich Zahl enthalten (Java: == ).
  • [ $VARIABLE -lt $VARIABLE2 ] wird true wenn die 1. Variable kleiner ist (Java: < ).
  • [ $VARIABLE -gt $VARIABLE2 ] wird true wenn die 1. Variable größer ist (Java: > ).
  • [ $VARIABLE -le $VARIABLE2 ] wird true wenn die 1. Variable kleiner oder gleich ist (Java: <= ).
  • [ $VARIABLE -ge $VARIABLE2 ] wird true wenn die 1. Variable gößer oder gleich ist (Java: >= ).
  • [ $VARIABLE -ne $VARIABLE2 ] wird true wenn die beiden Variablen ungleich sind (Java: != ).
  • [ ! <condition> ] negiert die condition (Java: ! ).

Es gibt noch einige mehr, aber ich denke das sind die Wichtigsten.

Quellen:
http://wiki.ubuntuusers.de/Shell/Bash-Skripting-Guide_f%C3%BCr_Anf%C3%A4nger
http://www.thegeekstuff.com/2010/06/bash-conditional-expression/