From fc3f350e96749c32b78647c8edcf7700c5012e0f Mon Sep 17 00:00:00 2001
From: anima
Date: Fri, 4 Jun 2021 11:28:22 +0200
Subject: [PATCH] Aplha Release from Python TimeTrack
---
timeTrack.py | 486 ++++++++++++++++++++++++++++++++++++++++++++++
timeTrack.sh | 540 ---------------------------------------------------
2 files changed, 486 insertions(+), 540 deletions(-)
create mode 100644 timeTrack.py
delete mode 100644 timeTrack.sh
diff --git a/timeTrack.py b/timeTrack.py
new file mode 100644
index 0000000..3755ea0
--- /dev/null
+++ b/timeTrack.py
@@ -0,0 +1,486 @@
+#!/bin/python3
+#########################
+#
+# timeTrack.py
+# by 4nima
+# v.2.0.0
+#
+#########################
+# simple time tracking with database
+#########################
+
+import datetime
+import sqlite3
+import json
+import os
+import logging
+
+# Main class
+class TimeTrack:
+ def __init__(self, DATABASE='timetrack.db', CONFIG='timetrack.conf'):
+ self.DATABASE = DATABASE
+ self.CONFIG = CONFIG
+ self.USERID = 0
+ self.USERNAME = ''
+ self.OLDEVENT = 2
+ self.LOGFILE = 'timetrack.log'
+ logging.basicConfig(
+ filename=self.LOGFILE,
+ level=logging.DEBUG,
+ format='%(asctime)s - %(process)d-%(levelname)s: %(message)s',
+ datefmt='%Y-%m-%d %H:%M:%S'
+ )
+ self.db_setup()
+ self.load_config()
+
+ ## Prepartation
+ ### Check OS and clear screen
+ def clear_screen(self):
+ if os.name == 'posix':
+ logging.debug('Unix/Linux system detected')
+ _ = os.system('clear')
+ else:
+ logging.debug('Winwos System detected')
+ _ = os.system('cls')
+
+ ### Creates a database if none is found
+ def db_setup(self):
+ if os.path.isfile(self.DATABASE):
+ logging.info('Database file was found')
+ else:
+ logging.info('Database file was not found, will create ')
+
+ sql = []
+ sql.append("""
+ CREATE TABLE IF NOT EXISTS time_entries (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ starttime TIMESTAMP NOT NULL,
+ endtime TIMESTAMP NOT NULL,
+ user_id INTEGER NOT NULL,
+ activity TEXT,
+ catrgory_id INTEGER,
+ client_id INTEGER,
+ lock BOOLEAN
+ )
+ """)
+
+ sql.append("""
+ CREATE TABLE IF NOT EXISTS active_events (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ starttime TIMESTAMP NOT NULL,
+ user_id INT NOT NULL
+ )
+ """)
+
+ sql.append("""
+ CREATE TABLE IF NOT EXISTS users (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL,
+ worktime INT,
+ worktime_span INT
+ )
+ """)
+
+ sql.append("""
+ CREATE TABLE IF NOT EXISTS clients (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL
+ )
+ """)
+
+ sql.append("""
+ CREATE TABLE IF NOT EXISTS categories (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL
+ )
+ """)
+
+ connect = sqlite3.connect(self.DATABASE)
+ cursor = connect.cursor()
+ logging.debug('Create initial database tables')
+ for SQL in sql:
+ try:
+ cursor.execute(SQL)
+ except:
+ logging.error('Table could not be created')
+ logging.debug(SQL)
+ print('TimeTrack wird beendet: Fehler bei Datanbank Setup')
+ quit()
+ else:
+ logging.debug('Table was created successfully or already exists')
+
+ connect.commit()
+ connect.close()
+
+ ### Loads or creates a config file
+ def load_config(self):
+ if os.path.isfile(self.CONFIG):
+ logging.info('Config file was found')
+ try:
+ with open(self.CONFIG) as config_data:
+ data = json.load(config_data)
+ except ValueError:
+ logging.error('Config file has no valid JSON syntax')
+ print('TimeTrack wird beendet: Fehler in der JSON-Konfig ({})'.format(self.CONFIG))
+ quit()
+ else:
+ logging.info('Config file was loaded successfully')
+ self.USERID = data['user']
+ self.OLDEVENT = data['oldevent']
+ logging.debug('UserID {} was used'.format(data['user']))
+ self.set_user()
+
+ else:
+ logging.warning('Config file not found')
+ config = {
+ 'default' : 'interactive',
+ 'user' : 1,
+ 'oldevent' : 2
+ }
+ with open(self.CONFIG, "w") as outfile:
+ json.dump(config, outfile, indent=4, sort_keys=True)
+ logging.info('Config file created successfully')
+
+ #> wenn man keine datei erstellen darf/kann, fällt das skript in einen loop ?
+ self.load_config()
+
+ ## user handling
+ ### Creates a user who does not yet exist
+ def create_user(self, USER=''):
+ if USER == '':
+ username = input('Benutzername eingaben: ')
+ logging.debug('Selected username: {}'.format(username))
+ else:
+ username = USER
+
+ while self.get_users(NAME=username):
+ print('Der gewünsche Benutzername ({}) ist schon vergeben'.format(username))
+ username = input('Wähle einen anderen Benutzernamen: ')
+ logging.debug('Try again: Selected username: {}'.format(username))
+
+ logging.debug('Accepted username: {}'.format(username))
+
+ connect = sqlite3.connect(self.DATABASE)
+ cursor = connect.cursor()
+
+ sql = "INSERT INTO users ( name ) values ( ? )"
+
+ try:
+ cursor.execute(sql, [username])
+ except:
+ logging.error('User could not be saved in database')
+ logging.debug(sql)
+ else:
+ logging.info('User was saved successfully')
+ connect.commit()
+
+ connect.close()
+
+ ### Outputs existing users from the DB
+ def get_users(self, UID=0, NAME=''):
+ if not UID == 0:
+ logging.debug('Get user by ID: {}'.format(UID))
+ data = UID
+ sql = "SELECT * FROM users WHERE id = ?"
+ elif not NAME == '':
+ logging.debug('Get user by username: {}'.format(NAME))
+ data = NAME
+ sql = "SELECT * FROM users WHERE name LIKE ?"
+ else:
+ logging.debug('Get all users')
+ data = ''
+ sql = "SELECT * FROM users"
+
+ connect = sqlite3.connect(self.DATABASE)
+ cursor = connect.cursor()
+
+ try:
+ if data:
+ cursor.execute(sql, [data])
+ else:
+ cursor.execute(sql)
+ except:
+ logging.error('Could not get user')
+ logging.debug(sql)
+ print('Fehler beim Zugriff auf die Benutzer Datenbank')
+ return 1
+ else:
+ logging.debug('User database read out successfully')
+ connect.commit()
+
+ data = cursor.fetchall()
+ connect.close()
+ return data
+
+ ### Defines a user for the session
+ def set_user(self):
+ data = self.get_users()
+ if not data:
+ logging.info("No user was found")
+ print("Es wurde kein Benutzer gefunden, bitte legen sie einen neuen an.")
+ self.create_user()
+
+ data = self.get_users(UID=self.USERID)
+ if data == []:
+ logging.error('User ID was not found')
+ else:
+ self.USERNAME = data[0][1]
+
+ ## Time handling
+ ### Creates an active event if none exists for the user
+ def save_event(self, TIME=datetime.datetime.now()):
+ if not self.get_event(USERID=self.USERID):
+ logging.debug('No active events found for the user: {}'.format(self.USERID))
+ connect = sqlite3.connect(self.DATABASE)
+ cursor = connect.cursor()
+ sql = "INSERT INTO active_events ( starttime, user_id ) VALUES ( ?, ? )"
+
+ try:
+ cursor.execute(sql, [TIME, self.USERID])
+ except:
+ logging.error('Event could not be created')
+ logging.debug(sql)
+ print('Event konnte nicht gespeichert werden.')
+ return False
+ else:
+ logging.info('Event was created successfully')
+ connect.commit()
+
+ connect.close()
+ return True
+ else:
+ logging.warning('Active events found for the user, new event could not be created')
+ return False
+
+ ### Deletes an active event based on a user or event ID
+ def delete_event(self, ENTRYID='', USERID=''):
+ if not ENTRYID == '':
+ logging.info('Deletes event based on eventid: {}'.format(ENTRYID))
+ sql = "DELETE FROM active_events WHERE id = ?"
+ data = ENTRYID
+ elif not USERID == '':
+ logging.info('Deletes events based on userid: {}'.format(USERID))
+ sql = "DELETE FROM active_events WHERE user_id = ?"
+ data = USERID
+ else:
+ logging.warning('No indication of what should be deleted')
+ print('Keine angabe was gelöscht werden soll')
+ return 0
+
+ connect = sqlite3.connect(self.DATABASE, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
+ cursor = connect.cursor()
+
+ try:
+ cursor.execute(sql, [data])
+ except:
+ logging.error('Event could not be deleted')
+ logging.debug(sql)
+ print('Fehler beim löschen des Events.')
+ else:
+ logging.debug('Event was successfully deleted')
+ connect.commit()
+
+ connect.close()
+
+ ### Get an active event based on a user or event ID
+ def get_event(self, ENTRYID='', USERID=''):
+ if not ENTRYID == '':
+ logging.debug('Search event based on eventid: {}'.format(ENTRYID))
+ sql = "SELECT * FROM active_events WHERE id = ?"
+ data = ENTRYID
+ elif not USERID == '':
+ logging.debug('Search events based on userid: {}'.format(USERID))
+ sql = "SELECT * FROM active_events WHERE user_id = ?"
+ data = USERID
+ else:
+ sql = "SELECT * FROM active_events"
+ data = ''
+
+ connect = sqlite3.connect(self.DATABASE, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
+ cursor = connect.cursor()
+ try:
+ if data:
+ logging.debug('Search event')
+ cursor.execute(sql, [data])
+ else:
+ logging.debug('Get all Events')
+ cursor.execute(sql)
+ except:
+ logging.error('Events could not be read')
+ logging.debug(sql)
+ print('Fehler beim auslesen der aktiven Events')
+ else:
+ logging.debug('Events could be read out successfully')
+ data = cursor.fetchall()
+ connect.close()
+ if data == []:
+ logging.debug('No active events found')
+ return 0
+ else:
+ logging.debug('{} events found'.format(len(data)))
+ return data[0]
+
+ def time_start(self, AUTOFORWARD=True):
+ self.clear_screen()
+ starttime = datetime.datetime.now()
+ logging.debug('New Event process started at {}'.format(starttime))
+ if self.save_event(starttime):
+ print('Neues Event gestartet um {}'.format(starttime.strftime("%H:%M")))
+ if AUTOFORWARD:
+ self.time_stop()
+ else:
+ data = self.get_event(USERID=self.USERID)
+ print('Es existiert bereits ein aktives Event.')
+ if (data[1] + datetime.timedelta(hours=self.OLDEVENT)) <= datetime.datetime.now():
+ logging.info('Event exceeds allowed duration')
+ print('Zeiteintrag ist zu alt laut den Einstellungen (älter {} Stunden)'.format(self.OLDEVENT))
+
+ if datetime.date.today() == data[1].date():
+ print('Start um: {}'.format(data[1].strftime("%H:%M")))
+ else:
+ print('Start am: {}'.format(data[1].strftime("%d.%m.%Y um %H:%M")))
+
+ elapsed = datetime.datetime.now() - data[1]
+ if elapsed.days:
+ logging.debug('Event older than 1 day ({} days)'.format(elapsed.days))
+ print('Vergangene Zeit: >{} Tage'.format(elapsed.days))
+ else:
+ logging.debug('Event younger than 1 day')
+ print('Vergangene Zeit: >{} Stunden'.format(int(elapsed.seconds/3600)))
+
+ userinput = ''
+ while True:
+ if userinput == "F" or userinput == "f" or userinput == "1" \
+ or userinput == "L" or userinput == "l" or userinput == "2" \
+ or userinput == "A" or userinput == "a" or userinput == "3":
+ break
+ print('Soll das Event fortgesetzt oder gelöscht werden?')
+ print('[1/F/f] für fortsetzen')
+ print('[2/L/l] für löschen')
+ print('[3/A/a] für abbrechen')
+ userinput = input('Aktion: ')
+ logging.debug('User input: {}'.format(userinput))
+ self.clear_screen()
+
+ if userinput == "F" or userinput == "f" or userinput == "1":
+ logging.debug('Event should be continued')
+ self.time_stop()
+ elif userinput == "L" or userinput == "l" or userinput == "2":
+ logging.info('Event should be deleted (eventid: {})'.format(data[0]))
+ self.delete_event(data[0])
+ self.time_start()
+ else:
+ logging.debug('Terminated by the user')
+ exit()
+
+ else:
+ logging.debug('Event continues (eventid{})'.format(data[0]))
+ print('Event von {} Uhr geladen'.format(data[1].strftime("%H:%M")))
+ self.time_stop()
+
+ def time_stop(self):
+ data = self.get_event(USERID=self.USERID)
+ logging.debug('Event stop progess is started')
+ if data:
+ self.clear_screen()
+ userinput = ''
+ while True:
+ if userinput == "B" or userinput == "b" or userinput == "1" \
+ or userinput == "L" or userinput == "l" or userinput == "2" \
+ or userinput == "A" or userinput == "a" or userinput == "3":
+ break
+ print('Event von {} Uhr beenden?'.format(data[1].strftime("%H:%M")))
+ print('[1/B/b] für beenden')
+ print('[2/L/l] für löschen')
+ print('[3/A/a] für abbrechen')
+ userinput = input('Aktion: ')
+ logging.debug('User input: {}'.format(userinput))
+ self.clear_screen()
+
+ if userinput == "B" or userinput == "b" or userinput == "1":
+ logging.debug('Event is ended')
+ print('Eingabe beenden mittels doppelter Leerzeile.')
+ print('Durchgeführte Tätigkeiten:')
+ userinput = []
+ while True:
+ try:
+ if userinput[-1] == '' and userinput[-2] == '':
+ break
+ except IndexError:
+ pass
+ userinput.append(input())
+
+ logging.debug('User input: {}'.format(userinput))
+ del userinput[-1]
+ del userinput[-1]
+ action = ''
+ for i in userinput:
+ if not action == '':
+ action += "\n"
+ action += i
+
+ endtime = datetime.datetime.now()
+ logging.debug('Event end process start at {}'.format(endtime))
+ connect = sqlite3.connect(self.DATABASE)
+ cursor = connect.cursor()
+ sql = "INSERT INTO time_entries ( starttime, endtime, user_id, activity ) VALUES ( ?, ?, ?, ? )"
+
+ try:
+ cursor.execute(sql, [data[1], endtime, self.USERID, action])
+ except:
+ logging.error('Time entry could not be created')
+ logging.debug(sql)
+ print('Zeiteintrag konnte nicht gespeichert werden.')
+ return False
+ else:
+ logging.info('Time entry was created successfully')
+ connect.commit()
+ self.delete_event(data[0])
+ self.print_time_entry(STARTTIME=data[1], ENDTIME=endtime, ACTIVITY=action)
+ print('Zeiteintrag wurde gespeichert.')
+ while True:
+ if userinput == "J" or userinput == "j" or userinput == "1" \
+ or userinput == "N" or userinput == "n" or userinput == "2":
+ break
+ print('Nächsten Zeiteintrag begrinnen ?')
+ print('[1/J/j] Ja')
+ print('[2/N/n] Nein')
+ userinput = input('Aktion: ')
+ logging.debug('User input: {}'.format(userinput))
+ self.clear_screen()
+
+ if userinput == "J" or userinput == "j" or userinput == "1":
+ self.time_start()
+ else:
+ logging.debug('Terminated by the user')
+ exit()
+
+
+ connect.close()
+
+ elif userinput == "L" or userinput == "l" or userinput == "2":
+ logging.info('Event should be deleted (eventid: {})'.format(data[0]))
+ self.delete_event(data[0])
+ else:
+ logging.debug('Terminated by the user')
+ exit()
+
+ def get_time(self):
+ pass
+
+ def print_time_entry(self, STARTTIME='', ENDTIME='', ACTIVITY=''):
+ s = (ENDTIME - STARTTIME).seconds
+ hours, remainder = divmod(s, 3600)
+ minutes, seconds = divmod(remainder, 60)
+
+ print(50*"-")
+ print('Start: {} Uhr'.format(STARTTIME.strftime('%H:%M')))
+ print('Ende: {} Uhr'.format(ENDTIME.strftime('%H:%M')))
+ print('Dauer: {:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds)))
+ if not ACTIVITY == '':
+ print('Aktivität:')
+ print(ACTIVITY)
+ print(50*"-")
+
+test = TimeTrack()
+test.time_start()
\ No newline at end of file
diff --git a/timeTrack.sh b/timeTrack.sh
deleted file mode 100644
index 4d24292..0000000
--- a/timeTrack.sh
+++ /dev/null
@@ -1,540 +0,0 @@
-#!/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