359 lines
6.9 KiB
Bash
Executable file
359 lines
6.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# TODO: enforce machine to routine consistency
|
|
# (maybe with a TRIGGER on the routine
|
|
# column in the machine table and a
|
|
# matching EXCLUDE constraint?)
|
|
#
|
|
# as a bonus, this would allow easily
|
|
# changing machines between routines
|
|
|
|
### variable definitions
|
|
|
|
## tui
|
|
|
|
# prompts
|
|
selectprompt="
|
|
Your selection: "
|
|
|
|
dateselectprompt="Enter the date as shown: "
|
|
|
|
weightprompt="Enter the weight in Kg: "
|
|
|
|
repsprompt="Enter the number of repititions: "
|
|
|
|
newmachineprompt="Enter name of new machine: "
|
|
|
|
newroutineprompt="Enter name of new routine: "
|
|
|
|
# menus
|
|
routinemenu="To begin, you must select your routine
|
|
"
|
|
|
|
machinemenu="
|
|
And now select the machine
|
|
"
|
|
|
|
datemenu="
|
|
What date do you want to choose?
|
|
"
|
|
|
|
repeatviewreadmenu="
|
|
Would you like to enter another mode?
|
|
(y/N)"
|
|
|
|
repeatmachinemenu="
|
|
Would you like to select another machine?
|
|
(y/N)"
|
|
|
|
repeatweightmenu="
|
|
Would you like to select another weight?
|
|
(y/N)"
|
|
|
|
repeatrepsmenu="
|
|
Would you like to add another set?
|
|
(y/N)"
|
|
|
|
vieworlogmenu="
|
|
Would you like to view your previous workouts,
|
|
or would you like to begin logging sets?
|
|
|
|
(1) View Previous Workouts.
|
|
(2) Begin Logging."
|
|
|
|
onlydatedmenu="
|
|
Would you like to view all from a
|
|
certain day, or all previous sets?
|
|
|
|
(1) All sets
|
|
(2) Sets worked on a specific day"
|
|
|
|
## enviromental
|
|
: ${dbname=workouts} # default database name
|
|
currentdate=$(date --iso)
|
|
### function definitions
|
|
|
|
## database
|
|
|
|
# reading
|
|
query() {
|
|
local command="$1"; shift
|
|
case $command in
|
|
machines)
|
|
psql -tAd ${dbname} <<<"
|
|
SELECT name
|
|
FROM machine
|
|
WHERE routine='${routine[$workingroutine]}';
|
|
";;
|
|
routines)
|
|
psql -tAd ${dbname} <<<"
|
|
SELECT name
|
|
FROM routine;
|
|
";;
|
|
sets)
|
|
# -tA is omitted as we're borrowing the
|
|
# formatting from the database and only
|
|
# want to turn off the row count footer
|
|
psql -P footer=off -d ${dbname} <<<"
|
|
SELECT weight, reps, date
|
|
FROM ${routine[$workingroutine]}
|
|
WHERE machine='${machine[${workingmachine}]}';
|
|
";;
|
|
setdates)
|
|
psql -P footer=off -d ${dbname} <<<"
|
|
SELECT DISTINCT date
|
|
FROM ${routine[$workingroutine]}
|
|
WHERE machine='${machine[${workingmachine}]}';
|
|
";;
|
|
datedsets)
|
|
psql -P footer=off -d ${dbname} <<<"
|
|
SELECT weight, reps
|
|
FROM ${routine[$workingroutine]}
|
|
WHERE machine='${machine[${workingmachine}]}'
|
|
AND date='${date}';
|
|
";;
|
|
esac
|
|
}
|
|
|
|
# writing
|
|
insert() {
|
|
local command="$1"; shift
|
|
case $command in
|
|
newset)
|
|
psql -qd ${dbname} <<<"
|
|
INSERT INTO ${routine[$workingroutine]}
|
|
(date, machine, weight, setno, reps)
|
|
VALUES
|
|
('${currentdate}',
|
|
'${machine[${workingmachine}]}',
|
|
'${weight}',
|
|
'${setnumber}',
|
|
'${reps}');
|
|
";;
|
|
newmachine)
|
|
psql -qd ${dbname} <<<"
|
|
INSERT INTO machine
|
|
(name, routine)
|
|
VALUES
|
|
('${newmachine}',
|
|
'${routine[${workingroutine}]}');
|
|
";;
|
|
newroutine)
|
|
psql -qd ${dbname} <<<"
|
|
BEGIN;
|
|
INSERT INTO routine
|
|
(name)
|
|
VALUES
|
|
('${newroutine}');
|
|
CREATE TABLE IF NOT EXISTS ${newroutine} (
|
|
date date NOT NULL,
|
|
machine text NOT NULL REFERENCES machine(name),
|
|
weight real NOT NULL,
|
|
setno smallint NOT NULL,
|
|
reps smallint NOT NULL
|
|
);
|
|
COMMIT;
|
|
"
|
|
echo $?
|
|
;;
|
|
esac
|
|
}
|
|
|
|
## data handling
|
|
|
|
# serialize queries
|
|
get() {
|
|
local command=$1; shift
|
|
case $command in
|
|
machines)
|
|
local i
|
|
local j
|
|
while read i; do
|
|
# this is 1 indexed to avoid math later on
|
|
(( j++ ))
|
|
machine[$j]="$i"
|
|
done < <( query machines )
|
|
;;
|
|
routines)
|
|
local i
|
|
local j
|
|
while read i; do
|
|
# this is 1 indexed to avoid math later on
|
|
(( j++ ))
|
|
routine[$j]="$i"
|
|
done < <( query routines )
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# present serialized queries
|
|
numerate() {
|
|
local command=$1; shift
|
|
case $command in
|
|
machines)
|
|
local i
|
|
(( i++ ))
|
|
while [[ -n ${machine[$i]} ]]; do
|
|
echo "($i) ${machine[$i]@u}"
|
|
(( i++ ))
|
|
done
|
|
;;
|
|
routines)
|
|
local i
|
|
(( i++ ))
|
|
while [[ -n ${routine[$i]} ]]; do
|
|
echo "($i) ${routine[$i]@u}"
|
|
(( i++ ))
|
|
done
|
|
;;
|
|
esac
|
|
}
|
|
|
|
## user interface
|
|
|
|
# statuses
|
|
showpastselections() {
|
|
clear
|
|
if [ "${routine[$workingroutine]}" ]; then
|
|
echo "Routine: ${routine[$workingroutine]@u}"
|
|
fi
|
|
if [ "${machine[${workingmachine}]}" ]; then
|
|
echo "Machine: ${machine[${workingmachine}]@u}"
|
|
fi
|
|
if [ "${weight}" ]; then
|
|
echo "Weight: ${weight}Kg"
|
|
fi
|
|
if [ "${setnumber}" ]; then
|
|
echo "Set: ${setnumber}"
|
|
fi
|
|
}
|
|
|
|
# menus
|
|
onlydated?() {
|
|
showpastselections
|
|
echo "${onlydatedmenu}"
|
|
read -p "${selectprompt}" onlydated
|
|
case $onlydated in
|
|
1)
|
|
query sets
|
|
;;
|
|
2)
|
|
echo "${datemenu}"
|
|
query setdates
|
|
read -p "${dateselectprompt}" date
|
|
query datedsets
|
|
;;
|
|
esac
|
|
}
|
|
|
|
reps?() {
|
|
(( setnumber++ ))
|
|
showpastselections
|
|
read -p "${repsprompt}" reps
|
|
insert newset
|
|
echo "${repeatrepsmenu}"
|
|
read -p "${selectprompt}" repeat
|
|
if [ "${repeat}" = "y" ]; then
|
|
reps?
|
|
fi
|
|
}
|
|
|
|
weight?() {
|
|
showpastselections
|
|
read -p "${weightprompt}" weight
|
|
reps?
|
|
unset setnumber
|
|
echo "${repeatweightmenu}"
|
|
read -p "${selectprompt}" repeat
|
|
if [ "${repeat}" = "y" ]; then
|
|
unset weight
|
|
weight?
|
|
fi
|
|
}
|
|
|
|
vieworlog?() {
|
|
showpastselections
|
|
echo "${vieworlogmenu}"
|
|
read -p "${selectprompt}" mode
|
|
case $mode in
|
|
1) # view
|
|
onlydated?
|
|
;;
|
|
2) # log
|
|
weight?
|
|
;;
|
|
esac
|
|
echo "${repeatviewreadmenu}"
|
|
read -p "${selectprompt}" repeat
|
|
if [ "${repeat}" = "y" ]; then
|
|
vieworlog?
|
|
fi
|
|
}
|
|
|
|
machine?() {
|
|
showpastselections
|
|
declare -a machine
|
|
get machines
|
|
echo "${machinemenu}"
|
|
numerate machines
|
|
echo "(0) New machine"
|
|
read -p "${selectprompt}" workingmachine
|
|
newmachine?
|
|
if [ "${workingmachine}" ] &&
|
|
[ "${workingmachine}" != 0 ]; then
|
|
vieworlog?
|
|
fi
|
|
echo "${repeatmachinemenu}"
|
|
if [ "${workingmachine}" != 0 ]; then
|
|
read -p "${selectprompt}" repeat
|
|
if [ "${repeat}" = "y" ]; then
|
|
unset workingmachine
|
|
machine?
|
|
fi
|
|
else
|
|
machine?
|
|
fi
|
|
}
|
|
|
|
newmachine?(){
|
|
if [ "${workingmachine}" = '0' ]; then
|
|
read -p "${newmachineprompt}" newmachine
|
|
if [ "${newmachine}" ]; then
|
|
insert newmachine
|
|
fi
|
|
fi
|
|
}
|
|
|
|
newroutine?(){
|
|
if [ "${workingroutine}" = '0' ]; then
|
|
read -p "${newroutineprompt}" newroutine
|
|
if [ "${newroutine}" ]; then
|
|
insert newroutine
|
|
fi
|
|
fi
|
|
}
|
|
|
|
routines?() {
|
|
showpastselections
|
|
get routines
|
|
echo "${routinemenu}"
|
|
numerate routines
|
|
echo "(0) New routine"
|
|
read -p "${selectprompt}" workingroutine
|
|
newroutine?
|
|
if [ "${workingroutine}" ] &&
|
|
[ "${workingroutine}" != 0 ]; then
|
|
machine?
|
|
fi
|
|
if [ -z "${workingroutine}" ] ||
|
|
[ "${newroutine}" ]; then
|
|
routines?
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
routines?
|
|
}
|
|
|
|
### function calls
|
|
|
|
main
|