#!/bin/bash #========== # # timeTrack.sh # by 4nima # v.1.5.1 # #========== # Einfaches Erfassen von Zeiten mit einer SQLDB (SQLite, kein Server) #========== # Variablen Definieren #===================== # Pfad zur Datenbank (Vollständiger Pfad benutzen!) DBDIR="/root/time/work/.timeTrack.db" DB="timeTrack" ## Verfügbare Kategorien (0 = Default) ### ACHTUNG: in der DB werden die IDs gespeichert, verändern der Rheinfolge verfälscht Reports # Alternativ neben Kategorien noch Tags oder Projekte anbieten declare -a categories categories[0]="Junk" categories+=("Kunden") categories+=("Internes") categories+=("Meetings") categories+=("Schulung") categories+=("Pause") categories+=("Sonstiges") categories+=("Privates") # Funktionen #=========== ## DB ### Erstellt eine Datenbank Datei function createDB { sqlite3 $DBDIR " CREATE TABLE IF NOT EXISTS $DB ( id INTEGER PRIMARY KEY, date INTEGER, day INTEGER, kw INTEGER, task TEXT, category INTEGER, worktime INTEGER ); " } ### Fügt einen Task in die DB ein function insertTask { sqlite3 $DBDIR " INSERT INTO $DB ( date, day, kw, task, category, worktime ) VALUES ( '$(date +%s)', '$(date +%u)', '$(date +%V)', '$1', '$2', '$3' ); " } ### Eintrag aus der Datenbank löschen function eraseTask { echo "<================================================>" sqlite3 $DBDIR " DELETE FROM $DB WHERE id = $DBID " echo "Task wurde gelöscht" echo "<================================================>" } ### Suche #### Anhand der ID function searchById { echo "<================================================>" sqlite3 $DBDIR -column -header " SELECT * FROM $DB WHERE id = $DBID " echo "<================================================>" } #### Anhand eines Strings (in Tasks) function searchByString { echo "<================================================>" sqlite3 $DBDIR -column -header " SELECT * FROM $DB WHERE task LIKE '%$SEARCH%' " echo "<================================================>" } ### Updates #### Datum function updateDate { echo "<================================================>" sqlite3 $DBDIR " UPDATE $DB SET date = '$UPDATEVALUE' WHERE id = $DBID " echo "Datum geupdatet" echo "<================================================>" } function updateTask { echo "<================================================>" sqlite3 $DBDIR " UPDATE $DB SET task = '$UPDATEVALUE' WHERE id = $DBID " echo "Task geupdatet" echo "<================================================>" } function updateCategory { echo "<================================================>" sqlite3 $DBDIR " UPDATE $DB SET category = '$UPDATEVALUE' WHERE id = $DBID " echo "Kategorie geupdatet" echo "<================================================>" } function updateWorktime { echo "<================================================>" sqlite3 $DBDIR " UPDATE $DB SET worktime = '$UPDATEVALUE' WHERE id = $DBID " echo " Arbeitszeit geupdatet" echo "<================================================>" } ### Reports #### Auslesen aller Heutigen Tasks function dailyReport { echo "<================================================>" day=$(convertDay $(date +%u)) echo "Daly Report vom $day - KW $(date +%V)" sqlite3 $DBDIR -column -header " SELECT count(id) AS 'Tasks', time(sum(worktime), 'unixepoch') AS 'Arbeitszeit' FROM $DB WHERE kw = '$(date +%V)' AND day = '$(date +%u)' " echo } function weeklyReport { echo "<================================================>" echo "Weekly Report vom KW $(date +%V)" sqlite3 $DBDIR -column -header " SELECT count(id) AS 'Tasks', time(sum(worktime), 'unixepoch') AS 'Arbeitszeit' FROM $DB WHERE kw = '$(date +%V)' " echo } function dailyCategoryReport { day=$(convertDay $(date +%u)) for i in ${!categories[@]}; do echo "<================================================>" echo "Report für Kategorie: ${categories[i]}" echo "Für $day in KW: $(date +%V)" sqlite3 $DBDIR -column -header " SELECT count(id) AS 'Tasks', time(sum(worktime), 'unixepoch') AS 'Arbeitszeit' FROM $DB WHERE kw = '$(date +%V)' AND day = '$(date +%u)' AND category = '$i' " echo done } function weeklyCategoryReport { week=$(convertDay $(date +%u)) for i in ${!categories[@]}; do echo "<================================================>" echo "Report für Kategorie: ${categories[i]}" echo "In KW: $(date +%V)" sqlite3 $DBDIR -column -header " SELECT count(id) AS 'Tasks', time(sum(worktime), 'unixepoch') AS 'Arbeitszeit' FROM $DB WHERE kw = '$(date +%V)' AND category = '$i' " echo done } ## Abläufe ### Prüft ob SQLite3 installiert ist und erstellt eine Datenbank wenn nicht schon vorhanden function checkRequirements { dpkg -l sqlite3 if [ $? -ne 0 ]; then echo "Bitte sqlite3 installieren!" exit fi if [ ! -d $DIR ];then mkdir -r $DIR fi createDB } ### Start des Trackings und Tätigkeits Abfrage function startTracking { starttime=$(date +%s) echo "<================================================>" echo "Time Tracking gestartet um: $(date +%H:%M)" IFS= read -a doingwords -p "Tätigkeit? `echo $'\n> '`" doing=${doingwords[0]} } ### Beendet das Tacking und Kategorie Abfrage function endTracking { for i in ${!categories[@]}; do echo "$i. ${categories[i]}" done IFS= read -p "Kategorie? `echo $'\n> '`" category endtime=$(date +%s) worktime=$(($endtime - $starttime)) } ### Erstellt eine Zusammenfassung zu dem eben Bearbeiteten Task #### Verbesserung: Möglichkeit auch Tasks aus der DB erneut auszugeben function printTask { echo "<================================================>" echo "Time Tracking beendet um $(date +%H:%M) - $outputtime" echo "<================================================>" echo "Du hast $outputtime in ${categories[$category]} investiert" echo "<================================================>" echo "Task: $doing" echo "<================================================>" } ### Aufruf bei -D(atenbank) function showDB { sqlite3 $DBDIR -column -header "SELECT * from $DB" } ### Aufruf bei -c(onfig) [/path/to/config.file] function config { if [ -f $OPTARG ];then config=$OPTARG echo $config # Datei einlesen; Prüfung was angepasst wurde (DB / DB file / Kategorien); validieren; weiter oder exit. else echo "Dieses Konfigfile existiert nicht" exit fi } ### Aufruf bei -e(rase) [DB ID] function erase { if [[ $OPTARG =~ ^[0-9]+$ ]]; then DBID=$OPTARG searchById IFS= read -p "Diesen Eintrag löschen?(y/n) `echo $'\n> '`" DELIT if [ $DELIT == "Y" ] || [ $DELIT == "y" ]; then eraseTask fi else echo "Gib die ID des zu löschenden Tasks ein" echo "Mit '-s' kannst du eine Suche starten" exit fi } ### Aufruf bei -h(elp) function printHelp { echo ' Benutzung: ./timeTrack.sh [option [argument]] Ohne Option wird das Skript für eine Zeitmessung ausgeführt und dann beendet. Optionen: -D # Listet die Tabelle der Datenbank auf -c [arg] # Konfigurationsdatei -e [DB ID] # Eintrag aus Tabelle löschen (Siehe -s) -h # Zeigt diese Hilfe -H [option] # Zeigt Detail Hilfe zu der Option -i # Startet eine Aufgaben speicherung mit eigenen Zeiteingaben -l # Startet das Skript im Loop (abbrechen mit Strg + C) -r [type] # Zeigt Reports für [day / week / month / category / ...] -s [string] # Sucht in der Datenbank nach [string] (nur im Aufgaben Feld) -u [DB ID] # Update für bereits vorhandene Einträge in der Datenbank (Siehe -s) ' } ### Aufrug bei -H(elp) [option] function helpTo { case $1 in c) echo ' Benutzung: ./timeTrack.sh -c /path/to/my.conf Mit der Option -c kann ein eine Konigurationsdatei angegeben werden. In der Konfigurationsdatei können individuelle Parameter übergeben werden: Pfad zur Datenbankdatei: DBDIR="/path/to/file.db" # Vollständigen Pfad angeben In der Datenbankdatei die Tabelle festlegen: DB="myTable" # Keine Sonder- oder Leerzeichen Eigene Kategorien: categories[0]="Default") # Standard Kategorie categories+=("newCategory") # Hinzufügen einer Kategorie (wiederholbar) ' ;; *) exit ;; esac } ### Aufruf bei -i(nsert) function insert { IFS= read -p "Tätigkeit? `echo $'\n> '`" TASK IFS= read -p "Dauer? `echo $'\n> '`" WORKTIME IFS= read -p "Endzeit? `echo $'\n> '`" ENDDATE IFS= read -p "Kategorie? `echo $'\n> '`" CATEGORY } ### Aufruf bei -r(eport) [Ansicht...] function report { REPORT=$OPTARG clear case $REPORT in day|daily) dailyReport dailyCategoryReport ;; week|weekly) weeklyReport weeklyCategoryReport ;; *) dailyReport ;; esac } ### Standard Aufruf function default { checkRequirements clear startTracking endTracking calcWorktime $worktime insertTask "$doing" "$category" "$worktime" clear printTask } ### Aufruf bei -s(earch) [Suchstring] function search { # Optionen ob damit was gemacht werden soll (Update / Löschen) SEARCH=$OPTARG searchByString } ### Aufruf bei -u(pdate) [DB ID] function update { # Prüfung ob angaben stimmen, weitere eingaben ändern DBID=$OPTARG searchById echo " 1. Datum 2. Task 3. Kategorie 4. Arbeitszeit " IFS= read -p "Was soll geupdatet werden? `echo $'\n> '`" UPDATETYPE IFS= read -p "Was soll eingetragen werden? `echo $'\n> '`" UPDATEVALUE case $UPDATETYPE in 1|Datum) updateDate ;; 2|Task) updateTask ;; 3|Kategorie) updateCategory ;; 4|Arbeitszeit) updateWorktime ;; *) echo "Falsche angabe" exit ;; esac } ## Umwandlung / Umrechnung ### Rechnet die Sekunden in Stunden und Minuten um function calcWorktime { if [ $1 -ge 3600 ]; then hworktime=$((worktime / 3600)) mworktime=$(((worktime % 3600) / 60)) gmworktime=$((worktime / 60)) outputtime="$gmworktime min ($hworktime:$mworktime H)" else gmworktime=$((worktime / 60)) outputtime="$gmworktime min" fi } function convertDay { case $1 in 1) echo "Montag" ;; 2) echo "Dienstag" ;; 3) echo "Mittwoch" ;; 4) echo "Donnerstag" ;; 5) echo "Freitag" ;; 6) echo "Samstag" ;; 7) echo "Sonntag" ;; esac } # Argumente auslesen #=============================== while getopts "Dc:e:hH:ilr:s:Tu:" opt; do case $opt in D) showDB exit ;; c) config exit ;; e) erase exit ;; h) printHelp exit ;; H) helpTo $OPTARG exit ;; i) insert exit ;; l) while true; do default done ;; r) report exit ;; s) search exit ;; T) # Testing results=($(sqlite3 $DBDIR " SELECT * FROM $DB ")) #for i in ${!results[@]}; do for i in "${!results[@]}"; do echo "<================================================>" echo "Test für: ${results[i]}" echo "Record No. $i: ${results[$i]}" fieldA=${results[0]}; fieldB=${results[1]}; fieldC=${results[2]}; fieldD=${results[3]}; done echo $fieldA $fieldB $fieldC $fieldD exit ;; u) update exit ;; *) exit ;; esac done default