-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBashTaskManager.sh
More file actions
384 lines (313 loc) · 9.31 KB
/
BashTaskManager.sh
File metadata and controls
384 lines (313 loc) · 9.31 KB
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
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
#!/bin/bash
readonly REGEX='^[0-9]+$'
readonly MAX_ERROR_COUNTER=3
readonly ACTIVE_TASKS_PATH="./Tasks"
readonly CONFIG_PATH="./_configs"
readonly SETTINGS_FILE="_settings"
readonly TIMETABLE_FILE="_timetable"
readonly NOTIFICATION_SENDER_FILE="NotificationSender.ps1"
readonly TASK_NUMBER_SETTING="TASK_NUMBER"
readonly JOB_ID_SETTING="JOB_ID"
declare -A tasks=()
declare -i error_counter=0
declare -i selection=-1
function __is_task_manager_installed() {
local -i is_installed=1;
if [[ -d $CONFIG_PATH ]]
then
if [[ (-f $CONFIG_PATH"/"$NOTIFICATION_SENDER_FILE) &&
(-f $CONFIG_PATH"/"$TIMETABLE_FILE) &&
(-f $CONFIG_PATH"/"$TIMETABLE_FILE) ]]
then
is_installed=0
else
is_installed=1
fi
else
is_installed=1
fi
echo $is_installed
}
function __load_all_tasks() {
local path=$1
if [[ -d $path ]]
then
while IFS= read -r -d $'\0'; do
local -l task=("$REPLY")
task=$(echo $(echo $task | cut -d '/' -f 3) | sed 's/^\.\///g')
local -i task_number=$(echo $task | cut -d '_' -f 2)
tasks[$task_number]=$task
done < <(find $path -maxdepth 1 -mindepth 1 -regex '^.*task_[0-9]+$' -print0)
fi
echo "Total tasks: ${#tasks[@]}"
}
function __get_setting_value() {
local -u setting_name=$1
local -i setting_value=0
while IFS= read -r line
do
local -u name=$(echo $line | cut -d '|' -f 1)
setting_value=$(echo $line | cut -d '|' -f 2)
if [[ $setting_name == $name ]]
then
break
fi
done < $CONFIG_PATH"/"$SETTINGS_FILE
echo $setting_value
}
function __update_setting() {
local -u setting_name=$1
local -i new_value=$2
local -i value=$(__get_setting_value $setting_name)
local -u search_text="$setting_name|$value"
local -u new_text="$setting_name|$new_value"
sed -i "s/$search_text/$new_text/" $CONFIG_PATH"/"$SETTINGS_FILE
}
function __delete_expired_task() {
local -l task_to_delete=$1
local -i line_number=0
while IFS= read -r line
do
local -l task=$(echo $line | cut -d '|' -f 1)
line_number+=1
if [[ $task == $task_to_delete ]]
then
sed -i $line_number"d" $CONFIG_PATH"/"$TIMETABLE_FILE
rm "$ACTIVE_TASKS_PATH/$task_to_delete"
break
fi
done < $CONFIG_PATH"/"$TIMETABLE_FILE
}
function add_new_task() {
error_counter=0
read -p "Title: " title
read -p "Details: " details
while [ $error_counter -lt $MAX_ERROR_COUNTER ]
do
read -p "Datetime (yyyy-MM-dd hh:mm): " datetime
if date -d "$datetime" "+%Y-%m-%d %H:%M" >/dev/null 2>&1; then
local datetime_now=$(date "+%Y-%m-%d %H:%M")
if [[ $(date -d "$datetime" +"%Y%m%d%H%M") > $(date -d "$datetime_now" +"%Y%m%d%H%M") ]]
then
error_counter=0
while [ $error_counter -lt $MAX_ERROR_COUNTER ]
do
read -p "Number of days to repeat: " days_repeat
if [[ !($days_repeat =~ $REGEX) || ($days_repeat -lt 0) ]]
then
echo "Invalid '$days_repeat' number of days to repeat the task. Please, try again!"
error_counter+=1
else
error_counter=0
break
fi
done
break
else
echo "Datetime must be bigger then the current datetime '$datetime_now'"
error_counter+=1
fi
else
echo "Invalid '$datetime datetime value. Please, try again!"
error_counter+=1
fi
done
if [[ $error_counter -eq 0 ]]
then
echo "Title: $title"
echo "Details: $details"
echo "Datetime: $datetime"
echo "Repeat: $days_repeat days"
while [ $error_counter -lt $MAX_ERROR_COUNTER ]
do
read -p "Save task (Y/N)?" should_save_task
case $should_save_task in
[yY]) mkdir -p $ACTIVE_TASKS_PATH
local task_number=$(($(__get_setting_value $TASK_NUMBER_SETTING)+1))
local new_task_name="task_"$task_number
local -l created_datetime=$(date "+%Y-%m-%d %H:%M")
echo "$new_task_name|$datetime|$days_repeat" >> $CONFIG_PATH"/"$TIMETABLE_FILE
echo "$title|$details|$datetime|$days_repeat|$created_datetime" > $new_task_name
mv $new_task_name $ACTIVE_TASKS_PATH
__update_setting $TASK_NUMBER_SETTING $task_number
echo "Task saved!"
break;;
[nN]) echo "Task not saved!"
break;;
*) echo "Invalid input!"
error_counter+=1;;
esac
done
fi
}
function show_task() {
error_counter=0
__load_all_tasks $ACTIVE_TASKS_PATH
if [[ ${#tasks[@]} -gt 0 ]]
then
while [ $error_counter -lt $MAX_ERROR_COUNTER ]
do
echo "All tasks: ${tasks[*]}"
read -p "Enter number to read task: " read_task_number
if [[ ${tasks[$read_task_number]} ]]
then
local file_content=$(<$ACTIVE_TASKS_PATH'/task_'$read_task_number)
echo "Title: $(echo $file_content | cut -d '|' -f 1)"
echo "Details: $(echo $file_content | cut -d '|' -f 2)"
echo "Datetime: $(echo $file_content | cut -d '|' -f 3)"
echo "Repeat: $(echo $file_content | cut -d '|' -f 4) days"
echo "Created: $(echo $file_content | cut -d '|' -f 5)"
else
echo "No such task found!"
fi
read -p "Read more tasks (Y/N)?" should_read_task
case $should_read_task in
[yY]) error_counter=0;;
[nN]) break;;
*) echo "Invalid input!"
error_counter+=1;;
esac
done
fi
}
function delete_task() {
local -i line_number=0
error_counter=0
__load_all_tasks $ACTIVE_TASKS_PATH
if [[ ${#tasks[@]} -gt 0 ]]
then
while [ $error_counter -lt $MAX_ERROR_COUNTER ]
do
echo "${tasks[*]}"
read -p "Enter number to delete task: " read_task_number
if [[ ${tasks[$read_task_number]} ]]
then
local -l task_to_delete=${tasks[$read_task_number]}
__delete_expired_task $task_to_delete
echo "Task deleted!"
else
echo "No such task found!"
fi
read -p "Delete more tasks (Y/N)?" delete_more
case $delete_more in
[yY]) error_counter=0;;
[nN]) break;;
*) echo "Invalid input!"
error_counter+=1;;
esac
done
fi
}
# Starts the scheduler in background
function __start_scheduler() {
while true
do
sleep 10s
local -i line_number=0
while IFS= read -r line
do
local datetime_now=$(date "+%Y-%m-%d %H:%M")
local task_name=$(echo $line | cut -d '|' -f 1)
local task_datetime=$(date -d "$(echo $line | cut -d '|' -f 2)" "+%Y-%m-%d %H:%M")
local -i task_days_repeat=$(echo $line | cut -d '|' -f 3)
line_number+=1
if [[ ($task_datetime < $datetime_now) || ($task_datetime == $datetime_now) ]]
then
local -i task_number=$(echo $task_name | cut -d '_' -f 2)
local file_content=$(<$ACTIVE_TASKS_PATH'/task_'$task_number)
local title=$(echo $file_content | cut -d '|' -f 1)
local details=$(echo $file_content | cut -d '|' -f 2)
local datetime_created=$(echo $file_content | cut -d '|' -f 5)
local next_date=$(date -d "$task_datetime next day" "+%Y-%m-%d %H:%M")
task_days_repeat=$((task_days_repeat - 1))
if [[ $task_days_repeat -lt 0 ]]
then
__delete_expired_task "task_"$task_number
else
sed -i $line_number"s/.*/$task_name|$next_date|$task_days_repeat/" $CONFIG_PATH"/"$TIMETABLE_FILE
fi
powershell -ExecutionPolicy Bypass -File $CONFIG_PATH"/"$NOTIFICATION_SENDER_FILE "$title" "$details" "$datetime_created"
fi
done < $CONFIG_PATH"/"$TIMETABLE_FILE
wait
done
}
function install_task_manager() {
local -i is_installed=$(__is_task_manager_installed)
if [[ $is_installed -eq 1 ]]
then
mkdir -p $CONFIG_PATH
echo -e '$title=$args[0]\n$details=$args[1]\n$datetime_created=$args[2]\nmsg * "Title: $title\nDetails: $details\nCreated on: $datetime_created"\n' > $NOTIFICATION_SENDER_FILE
mv $NOTIFICATION_SENDER_FILE $CONFIG_PATH
touch $TIMETABLE_FILE
mv $TIMETABLE_FILE $CONFIG_PATH
echo -e "$TASK_NUMBER_SETTING|0\n$JOB_ID_SETTING|0" > $CONFIG_PATH"/"$SETTINGS_FILE
__start_scheduler &
__update_setting $JOB_ID_SETTING $!
echo "Setup completed successfully!"
else
echo "'Bash Task Manager' has already been installed!"
fi
}
function uninstall_task_manager() {
local -i job_id=$(__get_setting_value $JOB_ID_SETTING)
kill $job_id
rm -rf $ACTIVE_TASKS_PATH
rm -rf $CONFIG_PATH
echo "'Bash Task Manager' successfully uninstalled!"
}
# Checks if the Bash Task Manager was installed first
# before executing any command (for example adding a new task)
function execute_func_command() {
local func_command=$1
local -i is_task_manager_installed=$(__is_task_manager_installed);
if [[ $is_task_manager_installed -eq 0 ]]
then
$func_command
else
echo "'Bash Task Manager' must be installed first!"
fi
}
# Restarts the scheduler running in background
# if the process was killed (for example when the PC was shut down)
function __init() {
local -i job_id=0
local -i is_installed=$(__is_task_manager_installed)
if [[ $is_installed -eq 0 ]]
then
job_id=$(__get_setting_value $JOB_ID_SETTING)
if !(ps -p $job_id >&-); then
__start_scheduler &
__update_setting $JOB_ID_SETTING $!
fi
fi
}
__init
# Catch Ctrl + C
trap 'printf "\nPress 0 to quit!"' SIGINT
clear
while [ $selection -ne 0 ]
do
cat << EOF
## Wellcome to Bash Task Manager ##
Please Select:
1. Install Bash Task Manager
2. Add new task
3. Show task
4. Delete task
5. Uninstall Bash Task Manager
0. Quit
EOF
echo -n 'Enter selection [0-5]: '
read -r selection
case $selection in
0) exit 0;;
1) install_task_manager;;
2) execute_func_command add_new_task;;
3) execute_func_command show_task;;
4) execute_func_command delete_task;;
5) execute_func_command uninstall_task_manager;;
*) echo "Invalid entry!" >&2;;
esac
printf "\n"
done