Command-Line Cloud: gcalcli

Meeting Notifications in Screen

Having access to my calendar from the command line is handy, but it still doesn't quite solve my problem of getting notifications so I don't miss an important meeting. I'm sure many people simply rely on the pop-up notification in their browsers, but I usually am not looking at my browser, and when I am, I'm not logged in to Gmail. I am, however, almost always looking at a screen session, so I found the best approach for me was to put notifications there.

I wrote about how to set up screen notifications in my February 2011 Hack and / column, so I recommend reading that column if you haven't set up your hardstatus line yet. Because notifications in screen are simply scripts that output short lines of text, what I want to do is tell gcalcli to display the next meeting in my agenda today that hasn't yet started, or if there are no more meetings today, to display nothing. That way, I can see at a glance what meeting is next.

The first step is to create a basic shell script in my local ~/bin/ directory called gagenda that calls gcalcli with extra arguments and then parses the results:

$ gcalcli --nocolor --nostarted agenda "`date`" 11:59pm | 
 ↪grep -v 'No Events' | head -2 | tail -1 | grep -v '^$'

With this long one-liner, I tell gcalcli to show me all of the events on my agenda that haven't started (--nostarted) between now ("`date`") and 11:59pm. Then if there are no events, I grep that out so I get empty output. If there are results, I use head and tail to pull out the line I want. Finally, if the line is empty I also grep that out. The end result is a single line of output suitable for screen.

Of course, I didn't want to stop there. What I wanted was for regular events to show up in white on my output, but then as the meeting got closer, I thought it would be nice if it turned to yellow and then finally to red. Also, when commands in your screen hardstatus line take a long time to run, the whole screen session can stall, so my solution was to have my gagenda script redirect the output to a few temporary files. The key to having a status appear to change colors is to have different backtick commands show up in the same location, each assigned its own color. Then as long as you make sure that only one of the commands will display output at any time, you get the illusion that you have only one status that changes color. Here is the resulting gagenda shell script to accomplish that:


# first look for urgent events occurring 
# in the next five minutes
gcalcli --nocolor --nostarted agenda "`date`" "`date -d 
 ↪'now + 5 minutes'`" | grep -v 'No Events' | head -2 | 
 ↪tail -1 | grep -v '^$' > /tmp/gagenda-urgent
# if there are no urgent events, look for warning 
# events in the next 10 minutes
if [ ! -s /tmp/gagenda-urgent ]; then
  gcalcli --nocolor --nostarted agenda "`date`" "`date -d 
 ↪'now + 10 minutes'`" | grep -v 'No Events' | head -2 | 
 ↪tail -1 | grep -v '^$' > /tmp/gagenda-warning
# if there are no warning events, just grab the next 
# event for the day
  if [ ! -s /tmp/gagenda-warning ]; then
    gcalcli --nocolor --nostarted agenda "`date`" 11:59pm | 
 ↪grep -v 'No Events' | head -2 | tail -1 | 
 ↪grep -v '^$' > /tmp/gagenda
    cat /dev/null > /tmp/gagenda
  cat /dev/null > /tmp/gagenda-warning
  cat /dev/null > /tmp/gagenda

Now I edited my local user's crontab with crontab -e to add gagenda:

* *     * * *    /home/greenfly/bin/gagenda

To configure screen, I updated my .screenrc with three new backtick commands that just cat the output of the temporary files:

backtick 111 37 37 cat /tmp/gagenda
backtick 112 37 37 cat /tmp/gagenda-warning
backtick 113 37 37 cat /tmp/gagenda-urgent

And finally, I referenced those backtick commands with the appropriate colors in my hardstatus line:

hardstatus string '%{= w}%Y-%m-%d %c%{= w}|%{= w}%111`%{+b 
 ↪y}%112`%{+b r}%113`%{-}%{= w}|%= |%{+b g}%108`%{-}|%{+b 
 ↪b}%105`%{-}|%{= y}%107`%{= w}'

The relevant section of the hardstatus line for these commands is:

|%{= w}%111`%{+b y}%112`%{+b r}%113`%{-}%{= w}|

Once I reload my .screenrc file, Figure 2 shows that I have an urgent meeting in a few minutes.

Figure 2. Urgent Meeting

In this article, I just touched on using gcalcli to access your agenda from the command line, but in my next column, I'll expand on the topic to talk about how to add new events and do even more with your Google Calendar without having to leave your terminal.


Kyle Rankin is SVP of Security and Infrastructure at Zero, the author of many books including Linux Hardening in Hostile Networks, DevOps Troubleshooting and The Official Ubuntu Server Book, and a columnist for Linux Journal. Follow him @kylerankin