-
Notifications
You must be signed in to change notification settings - Fork 0
/
avail
182 lines (164 loc) · 4.81 KB
/
avail
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
#!/bin/bash
#Preferences
lunch=true
weekends=true
remote=true
remote_title="Remote work"
calendar="Calendar"
days=14
day_start="09:00"
day_end="17:00"
lunch_start="12:00"
lunch_end="13:00"
minimum_duration=60 #minutes
next_day () {
date=$(gdate -d "$date + 1 day" "+%Y-%m-%d") #Go to next day
weekday=$(gdate -d "$date" "+%A")
if [ $weekends = true ]; then
if [[ "$weekday" = "Saturday" || "$weekday" = "Sunday" ]]; then
next_day
fi
fi
free_from=$day_start
date_printed=false
}
print_date () {
month=$(gdate -d "$date" "+%B")
day=$((10#$(gdate -d "$date" "+%d"))) #Remove leading zero
if (! $first_row); then
echo ""
fi
echo -n "$weekday, $month $day at "
date_printed=true
first_row=false
}
print_time () {
dash_printed=false
if ($date_printed); then
echo -n ", "
else
print_date
fi
start_hours=$((10#$(gdate -d "$1" "+%I"))) #Remove leading zero
start_minutes=$(gdate -d "$1" "+%M")
end_hours=$((10#$(gdate -d "$2" "+%I"))) #Remove leading zero
end_minutes=$(gdate -d "$2" "+%M")
if [ "$start_minutes" = "00" ]; then
echo -n "$start_hours"
else
echo -n "$start_hours:$start_minutes – "
dash_printed=true
fi
if [ "$end_minutes" = "00" ]; then
if (! $dash_printed); then
echo -n "–"
fi
echo -n "$end_hours"
else
if (! $dash_printed); then
echo -n " – "
fi
echo -n "$end_hours:$end_minutes"
fi
}
#Override preferences with flags
while getopts 'lwrR:c:d:s:e:S:E:m:' option; do
case "$option" in
l)
lunch=!lunch #Reverse preference for lunch breaks
;;
w)
weekends=!weekends #Reverse preference for lunch breaks
;;
r)
remote=!$remote #Reverse preference for remote meeting
;;
R)
remote_title=${OPTARG} #Specify remote work day title
;;
c)
calendar=${OPTARG} #Specify calendar
;;
d)
days=${OPTARG} #Provide availability for specified number of days
;;
s)
day_start=$(gdate -d "${OPTARG}" "+%H:%M") #Specify start time for each day
;;
e)
day_end=$(gdate -d "${OPTARG}" "+%H:%M") #Specify end time for each day
;;
S)
lunch_start=$(gdate -d "${OPTARG}" "+%H:%M") #Specify start time for lunch break
;;
E)
lunch_end=$(gdate -d "${OPTARG}" "+%H:%M") #Specify end time for lunch break
;;
m)
minimum_duration=${OPTARG} #Specify minimum duration of times available, in minutes
;;
esac
done
#Initialize
date=$(gdate -d today "+%Y-%m-%d")
weekday=$(gdate -d $date "+%A")
end_date=$(gdate -d "$date + $days days" "+%Y-%m-%d")
first_row=true
#Start running here
next_day #Start with tomorrow, and skip weekend days
#Look up events in Apple calendar database
events=$(icalbuddy -ic "$calendar" -iep datetime,title -po datetime,title -ps "^ | ^" -nrd -nc -df "%Y-%m-%d" -b "" eventsFrom:$date to:$end_date)
#List available times between events
while IFS= read -r line; do
event_date=${line:0:10}
while [ "$event_date" \> "$date" ] #Event on later date
do
if [ $(datediff -f "%M" $free_from $day_end) -ge $minimum_duration ]; then
print_time $free_from $day_end
#If there are no events during or after lunch, no lunch break is reserved. That is intentional. It most often means that totally unscheduled days are listed as entirely available.
fi
next_day
done
if [ "$event_date" = "$date" ]; then
if [ "${line:11:1}" = "|" ]; then #All-day event
if [[ "${line:13:${#remote_title}}" != "$remote_title" || $remote != true ]]; then #Not remote work day, or not looking for remote meeting time
next_day
fi
elif [ "${line:11:1}" = "-" ]; then #Date range
if [[ "${line:26:${#remote_title}}" != "$remote_title" || $remote != true ]]; then #Not remote work day, or not looking for remote meeting time
date=$(gdate -d "${line:13:10}" "+%Y-%m-%d") #Go to last day
next_day
fi
else #Timed event on correct date
start=${line:14:5}
stop=${line:22:5}
if [ "$start" \> "$free_from" ]; then
if [ $lunch = true ] && [ "$free_from" \< "$lunch_start" ] && [ "$start" \> "$lunch_start" ]; then
if [ $(datediff -f "%M" $free_from $lunch_start) -ge $minimum_duration ]; then
print_time $free_from $lunch_start
fi
if [ "$start" \> "$lunch_end" ] && [ $(datediff -f "%M" $lunch_end $start) -ge $minimum_duration ]; then
print_time $lunch_end $start
fi
elif [ $(datediff -f "%M" $free_from $start) -ge $minimum_duration ]; then
print_time $free_from $start
fi
fi
if [ ! "$stop" \< "$day_end" ]; then #Event ends at or after end of workday
next_day
elif [ "$stop" \> "$free_from" ]; then #Event ends after known free time
free_from=$stop
if [ $lunch = true ] && [ ! "$free_from" \< "$lunch_start" ] && [ "$free_from" \< "$lunch_end" ]; then #Event ends during lunch
free_from=$lunch_end
fi
fi
fi
fi
done <<< "$events"
#List available times after all events
while [ ! "$end_date" \< "$date" ]
do
print_time $free_from $day_end
next_day
done
echo ""