hi
i searched the web for a program to log my time i work on a project. but i dind't find one that satisfied me. it should be simple and easy to use.i couldn't believe it but i didn't find such a program. so i wrote one in bash ^^
Feature List:
- start, stop and cancel opened sessions
- multiple databases
- multiple users
- show all bygone sessions (with comments)
- calculate the over all working time
- optional: 7zip compression
Code:
#!/bin/bash
##########
# CONFIG #
##########
path=/home/jonny007/scripts/workTime/ # where shall the databases be saved at?
zip=0 # change to 1 to enable zipping by default
user=`whoami` # the default user. normally the output of 'whoami` is used
dbFile="dbTime.db" # the default database
##########
# SCRIPT #
##########
function funcParam {
eval "cmd=\$${#@}"
while getopts "fzdh?c:p:u::" optval; do
#echo "$optval -> $OPTARG"
case $optval in
"f")
forceRun=1;;
"z")
zip=1;;
"d")
debug=1;;
"h"|"?")
funcHelp
exit;;
"c")
comment=$OPTARG;;
"p")
if [ "$OPTARG" == "ALL" ]; then
eval "cmd=\$${#@}"
funcEveryDb $cmd
return
else
dbFile="dbTime.$OPTARG.db"
fi;;
"u")
user=$OPTARG;;
":")
echo "No argument value for option $OPTARG";;
esac
done
if [ -f workTime.lock -a "$forceRun" != "1" ]; then
echo -e "\033[31mERROR: workTime.lock existing! exiting..."
return
else
touch workTime.lock
fi
funcHandleDb
case $cmd in
"start")
funcStart;;
"stop")
funcStop;;
"cancel")
funcStop 1;;
"show")
funcShowOne $user;;
"showWT"|"showWt"|"showwt")
doEcho="0";funcShowOne $user;;
"showAll"|"showall")
funcShowAll;;
"showAllWT"|"showAllWt"|"showallwt")
doEcho="0";funcShowAll;;
"showOpen")
funcShowOpenWithBegin;;
"showDB"|"showDb"|"showdb")
funcShowCompleteDb;;
"showAllDB"|"showAllDb"|"showalldb")
funcShowAllDb;;
"help")
funcHelp;;
*)
funcNoParam $cmd;;
esac
doEcho=""
funcHandleDb "save"
rm workTime.lock
echo ""
}
function funcHead {
echo -e "\033[0;33mWorkTime Script by Jonny007-MKD v.0.1.1 alpha\033[37m\n"
}
function funcNoParam {
echo -e "\033[31m\n - - - WRONG OR MISSING PARAMETER $1 - - -"
echo -e " \033[37mTry \"help\" to show the help\n\n"
}
function funcHelp {
echo -e "\033[1;31mworkTime [-f -z -d] [-c comment] [-u user] [-p project|ALL] command\033[1;37m\n"
echo "-> FORCE"
echo -e " \033[36m-f\033[37m forces the script not to check for the lock file\n"
echo "-> ZIP"
echo -e " \033[36m-z\033[37m enables 7zip compression of the database\n"
echo "-> DEBUG"
echo -e " \033[36m-d\033[37m enables debug mode, at the moment only shows the output of 7zip\n"
echo "-> COMMENT"
echo -e " \033[36mcomment\033[37m is added to the datasegment to remind the \033[36maim of the work\033[37m and just needed when command is stop\n"
echo "-> USER"
echo -e " give a \033[36musername\033[37m to use for the script. Standard value is the \033[36mreturn of 'whoami\`\033[37m\n"
echo "-> PROJECT"
echo -e " project is used for \033[36mseveral databases\033[37m with the name \033[36mdbTime.%project%.db\033[37m\nIf you enter \"ALL\", then every available database is used\n"
echo "-> COMMAND"
echo -e " \033[0;36mstart\t\t\033[37m: Start a new session"
echo -e " \033[0;36mstop\t\t\033[37m: Stop an open session"
echo -e " \033[0;36mcancel\t\t\033[37m: Cancel a session (delete open session)\n"
echo -e " \033[0;36mshow\t\t\033[37m: Show your own open session, all old sessions and your working time"
echo -e " \033[0;36mshowWT\t\t\033[37m: Show your own working time"
echo -e " \033[0;36mshowAll\t\033[37m: Show all open sessions and all closed sessions sorted by user in the database"
echo -e " \033[0;36mshowAllWT\t\033[37m: Show all working times"
echo -e " \033[0;36mshowOpen\t\033[37m: Show all open sessions"
echo -e " \033[0;36mshowDB\t\t\033[37m: Show the complete database"
echo ""
echo -e " \033[0;36mhelp\t\t\033[37m: Show this help"
}
function funcHandleDb {
if [ -f "$dbFile" -a "$1" == "save" -a "$zip" == "1" ]; then
if [ "$debug" == "1" ]; then
7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on -y $dbFile.7z $dbFile
else
7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on -y $dbFile.7z $dbFile > /dev/null
fi
chmod 666 $dbFile.7z
rm $dbFile
return;
fi
if [ "$zip" == "1" -a -f "$dbFile.7z" ]; then
if [ "$debug" == "1" ]; then
7z e -y $dbFile
else
7z e -y $dbFile.7z > /dev/null
fi
chmod 666 $dbFile.7z
fi
if [ -f "$dbFile" ]; then
db=`cat $dbFile`
else
touch $dbFile
chmod 666 $dbFile
fi
if [ "$1" != "save" ]; then
echo -e "\033[1;32mUsing database: \033[0;31m$dbFile\033[37m\n"
fi
}
function funcStart {
doEcho="0"
funcShowOpen $user
if [ "$TS1" == "" ]; then
echo "$user§`date +"%s"`+" >> $dbFile
echo -e " Session \033[32mopened\033[37m for \033[32m$user\033[037m at \033[32m`date +"%F %H:%M:%S"`\033[37m"
else
echo -e " \033[31mAlready opened\033[37m session for \033[31m$user\033[037m since \033[31m`date --date="1970-01-01 $TS1 sec" +"%F %H:%M:%S"`\033[37m"
fi
}
function funcStop {
doEcho="0"
lastOpen="1"
funcShowOpen $user
if [ "$OS" == "" ]; then
echo -e " \033[31mNo opened\033[37m session for user \033[31m$user\033[37m found!"
fi
TS2=`date +%s`
cat /dev/null > $dbFile
for line in $db; do
OS=`echo $line | grep "^$user§[0-9]*+$"`
if [ "$fnd" != "1" -a "$OS" != "" -a "$1" == "1" ]; then
echo -e " \033[32mCanceled\033[37m session for \033[32m$user\033[037m from \033[32m`date --date="1970-01-01 $TS1 sec" +"%F %H:%M:%S"`\033[37m after \033[32m$((`date --date="1970-01-01 $(($TS2-$TS1)) sec" +%j`-1))d `date --date="1970-01-01 $(($TS2-$TS1)) sec" +%H:%M:%S`\033[037m"
fnd=1
elif [ "$fnd" != "1" -a "$OS" != "" ]; then
if [ "$comment" == "" ]; then
echo "No comment is given, insert one now if you want to [a-zA-Z0-9_. ]"
read comment
fi
echo "`echo $OS | grep -o "^$user§[0-9]*"`-`date +%s`#${comment// /_}" >> $dbFile
echo -e " \033[32mClosed\033[37m session for \033[32m$user\033[037m from \033[32m`date --date="1970-01-01 $TS1 sec" +"%F %H:%M:%S"`\033[37m after \033[32m$((`date --date="1970-01-01 $(($TS2-$TS1)) sec" +%j`-1))d `date --date="1970-01-01 $(($TS2-$TS1)) sec" +%H:%M:%S`\033[037m"
fnd=1
else
echo $line >> $dbFile
fi
comment=""
done
fnd=""
}
function funcShowOpenWithBegin {
funcShowOpen $1
if [ "$doEcho" != "0" -a "$output" != "" ]; then
if [ "$1" != "" ]; then
echo -e "\033[1;30mOpen Session for \033[32m$1\033[37m:\n$output\n"
else
echo -e "\033[1;30mOpen Sessions\033[0;37m:\n$output\n"
fi
fi
output=""
}
function funcShowOpen {
WRK="0"
for line in $db; do
OS=`echo $line | grep -e "$1§[0-9]*+$"`
if [ "$OS" != "" ]; then
US=`echo $OS | grep -o "^[a-zA-Z0-9]*§" | grep -o "^[a-zA-Z0-9]*"`
TS1=`echo $OS | grep -o "[0-9]*+$" | grep -o "[0-9]*"`
if [ "$doEcho" != "0" ]; then
if [ ${#US} -ge 7 ]; then
USd="\033[32m$US\033[037m"
else
USd="\033[32m$US\033[037m\t"
fi
output="$output Open session for $USd\tsince \033[32m`date --date="1970-01-01 $TS1 sec" +"%F %H:%M:%S"`\033[37m for \033[32m$((`date --date="1970-01-01 $((\`date +%s\`-$TS1)) sec" +%j`-1))d `date --date="1970-01-01 $((\`date +%s\`-$TS1)) sec" +%H:%M:%S`\033[037m\n"
fi
if [ "$WRK" == "0" -a "$US" == "$1" ]; then
WRK="$((`date +%s`-$TS1))"
if [ "$lastOpen" == "1" ]; then
return;
fi
fi
fi
done
}
function funcShowOne {
funcShowOpenWithBegin $1
for line in $db; do
OS=`echo $line | grep "^$1§[0-9]*-[0-9]*"`
if [ "$OS" != "" ]; then
US=`echo $OS | grep -o "^[a-zA-Z0-9]*§" | grep -o "^[a-zA-Z0-9]*"`
TS1=`echo $OS | grep -o "[0-9]*-" | grep -o "[0-9]*"`
TS2=`echo $OS | grep -o -e "-[0-9]*" | grep -o "[0-9]*$"`
COM=`echo $OS | grep -o "#[a-zA-Z0-9_.,()]*$" | grep -o "[a-zA-Z0-9_.,()]*$"`
DUR=$(($TS2-$TS1))
WRK=$(($WRK+$DUR))
if [ "$doEcho" != "0" ]; then
if [ ${#US} -ge 7 ]; then
USd="\033[32m$US\033[037m\t| "
else
USd="\033[32m$US\033[037m\t\t| "
fi
if [ "$COM" != "" ]; then
COM="\033[32m${COM//_/ }\033[37m"
else
COM=" -- "
fi
output="$output $USd \033[32m`date --date="1970-01-01 $TS1 sec" +"%F %H:%M:%S"`\033[37m | \033[32m`date --date="1970-01-01 $TS2 sec" +"%F %H:%M:%S"`\033[37m | \033[32m$((`date --date="1970-01-01 $(($TS2-$TS1)) sec" +%j`-1))d `date --date="1970-01-01 $(($TS2-$TS1)) sec" +%H:%M:%S`\033[37m\t| $COM\n"
fi
fi
done
if [ "$doEcho" != "0" -a "$output" != "" ]; then
output="\033[1;30mClosed Sessions for \033[1;33m$1\033[0;37m:\n \033[1;30mUser\033[0;37m \t|\t \033[1;30mBegin\033[0;37m |\t \033[1;30mEnd\033[0;37m\t | \033[1;30mDuration\033[0;37m\t| \033[1;30mComment\033[0;37m\n$output"
fi
echo -e "$output \n\033[1;30mWorking time for \033[33m$1\033[0;37m: \033[1;32m$((`date --date="1970-01-01 $WRK sec" +%j`-1))d `date --date="1970-01-01 $WRK sec" +%H:%M:%S`\033[37m"
output=""
WRK="0"
}
function funcShowAll {
for line in $db; do
US=`echo $line | grep -o "^[a-zA-Z0-9]*§" | grep -o "^[a-zA-Z0-9]*"`
if [ "`echo "${UsA[@]}" | grep -o "$US"`" != "$US" ]; then
UsA=(${UsA[@]} $US)
funcShowOne $US
echo -e " - -- - - -- - - -- - - -- - - -- - - -- - - -- - - -- - - -- - - -- - - -- - - -- -"
fi
done
echo
UsA=("")
}
function funcShowCompleteDb {
funcShowOpenWithBegin
for line in $db; do
OS=`echo $line | grep -e "§[0-9]*-[0-9]*#[a-zA-Z0-9_.,()]*$"`
if [ "$OS" != "" ]; then
US=`echo $OS | grep -o "^[a-zA-Z0-9]*§" | grep -o "^[a-zA-Z0-9]*"`
TS1=`echo $OS | grep -o "[0-9]*-" | grep -o "[0-9]*"`
TS2=`echo $OS | grep -o -e "-[0-9]*" | grep -o "[0-9]*$"`
COM=`echo $OS | grep -o "#[a-zA-Z0-9_.,()]*$" | grep -o "[a-zA-Z0-9_.,()]*$"`
if [ ${#US} -ge 7 ]; then
USd="\033[32m$US\033[037m\t| "
else
USd="\033[32m$US\033[037m\t\t| "
fi
if [ "$COM" != "" ]; then
COM="\033[32m$COM\033[37m"
else
COM=" -- "
fi
output="$output $USd \033[32m`date --date="1970-01-01 $TS1 sec" +"%F %H:%M:%S"`\033[37m | \033[32m`date --date="1970-01-01 $TS2 sec" +"%F %H:%M:%S"`\033[37m | \033[32m$((`date --date="1970-01-01 $(($TS2-$TS1)) sec" +%j`-1))d `date --date="1970-01-01 $(($TS2-$TS1)) sec" +%H:%M:%S`\033[37m\t| $COM\n"
fi
done
if [ "$output" != "" ]; then
echo -e "\033[1;30mAll Closed Sessions\033[0;37m:\n \033[1;30mUser\033[0;37m \t|\t \033[1;30mBegin\033[0;37m |\t \033[1;30mEnd\033[0;37m\t | \033[1;30m Duration\033[0;37m\t| \033[1;30mComment\033[0;37m\n$output"
fi
output=""
}
function funcEveryDb {
funcParam $1
echo -e " \n \033[0;31m-|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|-\033[1;37m \n"
for dbFile in `ls dbTime*db*`; do
dbFile=`echo $dbFile | grep -o "dbTime\.[a-zA-Z0-9]*\.db"`
if [ "$dbFile" != "" ]; then
pro=`echo $dbFile | grep -o "\.[a-zA-Z0-9]*\.db" | grep -o "\.[a-zA-Z0-9]*\." | grep -o "\.[a-zA-Z0-9]*" | grep -o "[a-zA-Z0-9]*$"`
funcParam -p $pro $1
echo -e " \n \033[0;31m-|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|- -|-\033[1;37m \n"
fi
done
}
cd $path
funcHead
funcParam "$@"
EDIT: updated code 2009-10-11 (extended