forked from alexanderepstein/Sandman-Lite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sandman-lite
executable file
·276 lines (235 loc) · 8.36 KB
/
sandman-lite
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#!/bin/bash
#sandman-lite
#An application that will remind you when to go to bed based on your
#wake up time and the optimal sleep times algorithm.
#Version 1.6.0
# This basically allows me to call date instead of having to call the OS
# specific version and checking OS every time this is called
currentVersion=1.6.0
grep() {
case "$OSTYPE" in
darwin*) command ggrep "$@" ;; # gdate is for OSX was installed with coreutils from homebrew
linux*) command grep "$@" ;; # date is built in
*) printf 'Unsupported OS type: %s\n' "$OSTYPE" >&2 # The OS is unsupported let the user know
exit 1 ;;
esac
}
date () {
case "$OSTYPE" in
darwin*) command gdate "$@" ;; # gdate is for OSX was installed with coreutils from homebrew
linux*) command date "$@" ;; # date is built in
*) printf 'Unsupported OS type: %s\n' "$OSTYPE" >&2 # The OS is unsupported let the user know
exit 1 ;;
esac
}
# Lets the user know how to use the program
function help()
{
echo "Name: sandman-lite"
echo
echo "Author: Alexander Epstein"
echo
echo "Description:
Based on the time you need to wake up Sandman will notify you throughout the
evening at specific times when you could go to sleep and maximize your number
of full sleep cycles."
echo
echo "Usage: "
echo " [-s wakeUpTime] wakeuptime 24 hour time ex. 8:05 (sets new wakeuptime)"
echo " [-t] (tests notification)"
echo " [-g] (gets pending notifications)"
echo " [-u] (checks for and installs updates)"
echo " [-h] (brings up the help page)"
echo " [-v] (prints out version of sandman-lite)"
echo
echo "Repository: https://github.com/alexanderepstein/Sandman-Lite"
echo
echo "Version: 1.6.0"
}
# This function is used inside of here when testing a notification
# and is also called from noti.sh as a workaround on mac for a bug present in
# terminal-notifier
function showRestNotification()
{
if [[ "$OSTYPE" == "linux-gnu" ]]; then
notify-send "Sandman" "Time to take a rest" -u critical -t 7000 -i /usr/local/sbin/sleep.png # send a notification the critical makes sure the notification shows up even if user is fullscreened into something
elif [[ "$OSTYPE" == "darwin"* ]]; then
terminal-notifier -title "Sandman" -message "Time to take a rest" -sound "default" -group rest -timeout 7 -appIcon /usr/local/sbin/sleep.png # send a notification for OSX
fi
}
function writeResetFile()
{
cd ~ || { echo "Writing the reset file failed" ; exit 1 ;}
mkdir Sandman-Lite 2> /dev/null
cd Sandman-Lite || { echo "Writing the reset file failed" ; exit 1 ;}
touch resetSandman.sh
echo "sandman-lite -s $wakeUpTime" > ~/Sandman-Lite/resetSandman.sh
}
function generateSleepTimes()
{
oldIFS=$IFS #so it can be set back late
IFS=: splitTime=(${wakeUpTime##*-}) #split up the wakeUpTime string using : as a delimeter into an array called splitTime
wakeUpHours=${splitTime[0]} # index 0 of split time is the hour of the wake up time
wakeUpMinutes=${splitTime[1]} # index 1 of split time is the minutes of the wake up time
currentHours=$(date +'%H') # grab the current times hour
currentMinutes=$(date +'%M') # grab the current times minutes
# this code block is checking whether the time the user input is actually for today or tommorrow
# by originally assuming it is meant for today and checking if the wakeUpTime already occured if it did
# then it is assumed the user meant for the time to be tomorrow otherwise it is taken as today
if [[ $wakeUpHours < $currentHours ]]; then
IFS=$oldIFS
wakeUpTime="$wakeUpTime tomorrow"
elif [[ "$wakeUpHours" == "$currentHours" && $wakeUpMinutes < $currentMinutes ]]; then
IFS=$oldIFS
wakeUpTime="$wakeUpTime tomorrow"
else
IFS=$oldIFS
wakeUpTime="$wakeUpTime today"
fi
tempTime=$(date -d "$wakeUpTime - 15 minutes" +"%D %H:%M") # account for the time it takes to fall asleep
sleepTimes[6]=$(date -d "$tempTime" +"%D %H:%M") # throw it in the top of the array so the value can be used in the following for loop as a starting point
sleepTimes[7]=$(date -d "$wakeUpTime + 1 hour 15 minutes" +"%Y%m%d%H%M")
wakeUpTime=$(date -d "$wakeUpTime" +"%H:%M")
for i in {5..0}
do
sleepTimes[$i]=$(date -d "${sleepTimes[$i+1]} - 1 hour 30 minutes" +"%D %H:%M") # subtract one sleep cycle from the previous time to get the new sleep/shutdown time
done
for i in {5..0}
do
secondTimes[$i]=$(date -d "${sleepTimes[$i]}" +"%s") # get the amount of time in EPOCH for later testing
sleepTimes[$i]=$(date -d "${sleepTimes[$i]}" +"%Y%m%d%H%M") # format the time to be used with the at command
done
}
function removeNotificationJobs()
{
test -f ~/Sandman-Lite/jobIDS.txt
validFile=$( echo $? )
if [[ $validFile -eq '0' ]]; then
oldIFS=$IFS
IFS=' ' read -d '' -r -a jobID < ~/Sandman-Lite/jobIDS.txt 2> /dev/null
IFS=$oldIFS
tempLength=$(echo ${#jobID[@]})
((tempLength=tempLength-1))
while [[ $tempLength -ge "0" ]]
do
atrm ${jobID[$tempLength]} 2> /dev/null
((tempLength=$tempLength - 1))
done
rm ~/Sandman-Lite/jobIDS.txt
echo "Old Notifications removed"
fi
}
function setUpNotificationJobs()
{
for i in {0..5} # for each sleep time
do
if [[ $(date -d now +"%s") -le ${secondTimes[$i]} ]]; then # if the notification should have occured by now dont set it
at -f /usr/local/sbin/noti.sh -t ${sleepTimes[$i]} 2> /dev/null # set up the at job to run noti.sh an dont show the output (i will do this later plus it lets me parse it)
jobID[${#jobID[@]}]=$(atq | sort -k 1 | tail -1 | cut -d " " -f1 | awk '{print $1;}')
fi
done
writeResetFile
at -f ~/Sandman-Lite/resetSandman.sh -t ${sleepTimes[7]} 2> /dev/null
jobID[${#jobID[@]}]=$(atq | sort -k 1 | tail -1 | cut -d " " -f1 | awk '{print $1;}')
echo "${jobID[@]}" > ~/Sandman-Lite/jobIDS.txt
echo
echo
echo "Optimal sleep/shutdown times generated"
sandman-lite -g # show the sleep times that were generated (hopefuly this will soon be updated to parse it and only grab the exact jobs)
echo
echo "New Notifications set"
}
if [[ $# == 0 ]]; then
help
exit 0
fi
function checkForUpdate()
{
if [[ $(curl -s https://api.github.com/repos/alexanderepstein/Sandman-Lite/tags) == "" ]];then
echo "Error: no active internet connection"
exit 1
fi
latestVersion=$(curl -s https://api.github.com/repos/alexanderepstein/Sandman-Lite/tags | grep -Po '"name":.*?[^\\]",'| head -1 | cut -c11-15)
if [[ "$latestVersion" != "$currentVersion" && "$latestVersion" != "" ]]; then
echo "Version $latestVersion available"
echo -n "Do you wish to update sandman-lite [Y/n]: "
read answer
if [[ "$answer" == "Y" || "$answer" == "y" ]] ;then
removeNotificationJobs
/usr/local/sbin/./supdate.sh
else
exit 1
fi
else
echo "sandman-lite is already the latest version"
fi
}
function getSleepTimes()
{
oldIFS=$IFS
IFS=' ' read -d '' -r -a jobID < ~/Sandman-Lite/jobIDS.txt 2> /dev/null
IFS=$oldIFS
tempLength=0
maxlength=$(echo ${#jobID[@]})
((maxlength = maxlength -1))
while [[ $tempLength -ne $maxlength ]]
do
atq | grep -P -e "${jobID[$tempLength]}" 2> /dev/null | cut -f2 | cut -d " " -f1-5 # shows all jobs and sorts them by job ID and parses it to be more readable
((tempLength=$tempLength + 1))
done
}
while getopts ":uvrghts::" opt; do
case $opt in
s)
if [[ $# -gt 2 ]]; then
echo "Option -s only accepts one argument" <&2
exit 1
fi
date +"%H:%M" -d "$OPTARG" > /dev/null 2>&1
isValid=$?
if [[ $isValid -eq 1 ]]; then
echo "Invalid time format ex 8:30" >&2
exit 1
fi
IFS=$oldIFS
wakeUpTime=$OPTARG
wakeUpTime=$( date +"%H:%M" -d "$wakeUpTime" )
removeNotificationJobs
generateSleepTimes
setUpNotificationJobs
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
t)
echo "Testing rest notification"
showRestNotification
;;
h)
help
;;
g)
test -f ~/Sandman-Lite/jobIDS.txt
validFile=$( echo $? )
if [[ $validFile -eq '0' ]]; then
getSleepTimes
else
echo "No notifications are set to occur"
fi
;;
r)
removeNotificationJobs
;;
v)
echo "Version $currentVersion"
;;
u)
checkForUpdate
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done