Your main questions
Is there a way I could do this in one loop?
Yes.
The two loops do essentially the same thing,
but use different values.
The loop should be inside a function,
the range of values and the event details should be parameters of the function.
Or should I be using another method?
As it is, the dates of the event are very hard to read.
It would be better to have a function that takes start date, end date, and other event details, and use a loop from start date stepping forward one week until the end date is reached.
Furthermore, a "recurring event" is usually not the same event registered n times, but a single event with some parameters. I don't know the API of Google Calendar, but I suggest to check on that, as there might be a much easier method, natural and intuitive method to register a proper recurring event.
Code review
Avoid pointless comments like this one that only state the obvious:
#assigning variables
start="14:00"
duration="150"
title="Exper. Lab"
year="2016"
start2="17:30"
duration2="230"
title2="Calc1"
And there's really no need to define start2
, duration2
and title2
at the top of the file.
It's unnecessary information at that point.
You could define these right before the second loop.
You could even reuse the start
, duration
, title
variables.
If you did that, the two loop bodies would look identical,
and converting to a function would be a trivial step.
Be extremely cautious with long lines like this:
for monthday in {09/{1..29..7},09/{6..27..7},10/{4..25..7},10/{6..27..7},11/{1..29..7},11{3..24..7},12/{6..20..7},12/{1..15..7}}
Can you spot the bug?
Should have been 11/{3..24..7}
instead of 11{3..24..7}
A long relative path like this is awful:
... | ../../../../usr/bin/gcalcli add --calendar 'Class'
What if you later need to change the directory of this script or gcalcli
?
You will have to recalculate the correct depth,
and update the script at multiple places (the two loops).
It's better to add ../../../../usr/bin
to PATH
, and use simply gcalcli
. Alternatively, you could define a function like this:
gcalcli() {
../../../../usr/bin/gcalcli "$@"
}
Actually, since I don't have gcalcli
on my PC,
I used this function as a dummy in my tests:
gcalcli() {
cat
}
Code is easiest to read from top to bottom,
with minimal distractions sideways.
This line is too long,
and I'm forced to scroll to the right to see it:
(echo $title ; echo "'$monthday/$year $start'"; echo $duration) | ../../../../usr/bin/gcalcli add --calendar 'Class'
Avoid multiple statements on one line, break it up like this:
(
echo $title
echo "'$monthday/$year $start'"
echo $duration
) | gcalcli add --calendar 'Class'
Alternative implementation
Consider the alternative implementation below, using some of the suggestions above.
#!/bin/bash
PATH="path_to_gcalcli:$PATH"
add_to_calendar() {
title=$1
datetime=$2
minutes=$3
(
echo $title
echo "'$datetime'"
echo $minutes
) | gcalcli add --calendar 'Class'
}
add_weekly_event() {
title=$1
start_time=$2
minutes=$3
start_date=$4
end_date=$5
event_date=$start_date
while [[ "$event_date" < "$end_date" ]]; do
datetime="$(date +%m/%d/%Y -d $event_date) $start_time"
add_to_calendar "$title" "$datetime" $minutes
event_date=$(date +%Y/%m/%d -d "$event_date + 1 week")
done
}
add_weekly_event "Exper. Lab" 14:00 150 2016/09/01 2016/12/21
add_weekly_event "Exper. Lab" 14:00 150 2016/09/06 2016/12/21
add_weekly_event "Calc1" 17:30 230 2016/09/12 2016/12/20
This script is much slower than yours, due to the many calls to date
.
But it's a lot easier to understand what dates will be added,
and it's trivially easy to reuse it for other events.
Note that the add_weekly_event
function takes the date parameters in %Y/%m/%d
format, where month and day are 0-padded. This is to make the loop condition possible, as the alphabetic ordering of dates in this format coincides with the correct chronological ordering.
Also note that before passing the date to add_to_calendar
,
it is formatted to (roughly the same) format in your script.
I don't know the Google Calendar API,
but I suspect this is unnecessary,
the %Y/%m/%d
format probably works just fine.
For the date parsing and + 1 week
calculation,
this script depends on GNU date.
This is the default on Linux,
on other OS you can usually find it in a coreutils
package,
named gdate
.
To use gdate
instead of date
,
you can create a function:
date() {
gdate "$@"
}
But this technique is not my first recommendation.
My first recommendation is to check the Google Calendar API to create proper recurring events, instead of manually looping over dates and adding the same event multiple times.