Mutt and Google Calendar

I’ve been meaning to throw this out there for a bit. I wrote a little python shim to connect mutt to Google Calendar. My particular use-case is as follows. I use fetchmail to connect to a Microsoft Exchange Server at work which delivers mail into an IMAP account that I check with mutt. Appointments and conference calls show up as .ics files attached to messages. I use Google Calendar connected to my BlackBerry to keep track of all the stuff I do so I need a quick and easy way to get those events out of mutt into my Google Calendar.

Enter ics-gcal.py.

I associate this script to the ics / vcs files and simply exec the attachment from within mutt. This adds it to my Google Calendar.

You can find the script in my CVS web repository.

I’d be super interested if anyone else finds this useful.

Tags: , , ,

16 Responses to “Mutt and Google Calendar”

  1. Brandon says:

    Hello,

    I have been using your script for a couple days now and have added calendar entries to my Google calendar with no problems. One thing I did change though was the mailcap entry. I removed the ‘copiousoutput’ entry. With the ‘copiousoutput’ entry, I was getting new/duplicate calendar entries added every time I was viewing an email with an event. Without the ‘copiousoutput’ option, I have to go to manually select the ICS attachment, which is what I want.

    A couple things I would like to see added:

    1. Ability to specify which Google calendar I add the event to.
    2. Add a flag to specify the length of the reminder.

    I’ll try (with my crippled python skills) to see if I can add this myself, but my feelings wouldn’t be hurt if you made this magic happen. :)

    At any rate, thanks for the nice hack. Cheers!

  2. mernisse says:

    I’m glad you like it.

    Strange about the ‘copiousoutput’ thing, I use it and don’t get duplicates, and according to the mailcap(5) manpage copiousoutput is just used to tell the MUA you are going to have a bunch of lines of text and should pipe the command through a pager, strictly speaking we probably don’t NEED it but it shouldn’t be creating duplicates. I will look into that more.

    With respect to your feature requests, please give the updated script a shot, version 1.2 should be available in the CVS repo
    http://bagend.ub3rgeek.net/cgi-bin/cvsweb.cgi/misc-scripts/ics-gcal.py

  3. Brandon says:

    Many thanks for the fast turnaround! Version 1.2 does indeed add the event to the calendar I specify. But, it does not add a reminder. Regardless of using the ‘-r’ flag or not, no reminder is set.

    Oh, I also had to correct your ‘getopt’ call to include the new flags:

    optlist, args = getopt.getopt(argv, “hu:p:f:c:r:”)

    Not to be too picky, but you misspell calendar in a couple spots:

    print “cannot login to Google Calnedar: %s” % ( str(e) )
    print “cannot upload event to Google Calnedar: %s” % ( str(e) )

    I will be glad to test another new version (if/when there is one). Cheers!

  4. mernisse says:

    Yikes, pretty lame of me to forget to update the getopt() call :( I fixed that and my misspellings. With respect to the reminder I’m wondering if your invitation that you are importing perhaps does not have an alarm set? I only set a reminder if the input file has an alarm set. I added the -R flag to force the addition of a reminder even if the event doesn’t have an alarm. Let me know if that fixes it for you.

    New version is 1.3 and is in the same spot as 1.2

    I’m glad you’re getting some use out of this :)

    –Matt

  5. Brandon says:

    Hi Matt,

    I ran into one issue with 1.3:

    Traceback (most recent call last):
    File “/home/bboles/bin/ics-gcal.py”, line 236, in
    sys.exit(Main(sys.argv[1:]))
    File “/home/bboles/bin/ics-gcal.py”, line 230, in Main
    if not uploadToGoogle(ics, email, password, calendar, reminder, force):
    File “/home/bboles/bin/ics-gcal.py”, line 146, in uploadToGoogle
    when.reminder.append(Reminder(minutes=reminder))
    UnboundLocalError: local variable ‘when’ referenced before assignment

    I changed line 146, so that ‘when’ gets assigned appropriately:

    elif forceReminder:
    for when in event.when:
    when.reminder.append(Reminder(minutes=reminder))

    After my change, it worked like a champ! Thanks for the explanation on the ‘alarm’ setting of the ICS file. Looking through my events, none seem to automatically set an alarm/reminder so the ‘-R’ flag makes things work like I want them to work. Way cool.

    I’ll continue to use and report if anything else comes up. Many thanks!

  6. Brandon says:

    I just tried out v1.5. It looks like you inadvertently undid the 1.4 changes. After adding back the 1.4 changes, I also made this change in processing the event description:

    event.title = atom.Title(text=ics.vevent.summary.value)
    if getattr(ics.vevent, “description”, None):
    event.content = atom.Content(text=ics.vevent.description.value)

    Not all of my events have a description, so the script was barfing when there was none.

    I also tried to add a recurring event. Here is the (what I think) is the applicable line from my ics file:

    RRULE:COUNT=;FREQ=WEEKLY;INTERVAL=1

    So this should mean that this event should occur once weekly, indefinitely. When trying to process, I get this error:

    cannot upload event to Google Calendar: {’status’: 400, ‘body’: ‘Failed to process recurrence rule’, ‘reason’: ‘Bad Request’}

    I’ll test your update if you have any ideas on how to fix. Thanks! :)

  7. mernisse says:

    I integrated your fixes for the regression and the Description into 1.6 I think the RRULE is gonna be trickier. The problem I think is the “COUNT=;” parameter. It seems the way Gcal wants this is to omit the COUNT value completely. I’ll see if I can whip something up to re.sub() that out…

  8. Steen says:

    Hi,

    Thanks for your little program, it fitted just right. I have made some minor tweaks (corrections, fixes, whatever), and I would like to give them back to you. If you are interested, please email me and I’ll show you what I’ve done.

  9. Jason says:

    I tried your python script, and I am unable to get it to work from within mutt. What does your entry look like for mailcap?

    Also, if I try it on the command line, I am unable to post to a calendar that is not default.

  10. mernisse says:

    The documentation in the top of the script has an example from my .mailcap (I sanitized it for un/pw obviously) you may also need to associate text/x-vcalendar files with the same command depending on how the .ics attachments are formatted and how libmagic detects them on your system.

  11. Jason says:

    Great! Thanks. That worked wonderfully.

    Is there anyway to have it add to an alternative calendar? Not the default. I get an error about my username when using the -c option.

    It would be nice if it could not display the credentials, as well, when adding to the calendar.

    Beyond this, is there a way to not have it auto add? I am using auto_view for the magic entry, however I am not certain how to not use the auto_view, but invoke the insert if I would like to attend the meeting.

    Thanks!

  12. perry says:

    this is cool, but i think it shouldbe made a bit more interactive?

    it would be cool if:
    1) view the event before adding it to my calendar
    2) be able to pick calendar (maybe jsut based on current email account)
    3) storing uname and pword in mailcap is just wrong. why not read a file?

    anyway, this script rocks. if i have time i’ll try and add sth too it

    ty for the work

  13. Bandan says:

    Hi,
    Your script was really helpful.I had been planning to shift to Mutt for a long time and syncing my meetings to google calendar was probably one of the main reasons why I resisted but with your script, I am finally on it! Thanks!

    The only problem which is not even related to your script is that I was not aware that the calendar API only supports updating reminders on the primary calendar. Not sure what prompted google to have this limitation but it’s kinda lame. I had a separate work calendar and finally had to merge everything from it to my primary calendar.

  14. Bender says:

    I just installed this script and it is exactly what I needed. Previously, I parsed the ICS files with a SED script in Mutt for viewing, and manually inserted into the Google calendar.

    I would really like to see my gmail credentials read out of a file (like .gcalclirc) and not appear in the mailcap.

    Thanks for the script!

  15. mernisse says:

    Bender:

    I am glad to hear that this worked out for you. A few people have asked so the latest version of the script now supports a config file, however it should be noted that it is no more or less secure to store your password in .mailcap vs another file in your home directory.

  16. mernisse says:

    perry:

    I have been thinking about 1 and 2 a bit, and it’s kind of hard to handle since you’re getting just the attachment, which means you have no idea whom it came from and stuff like that. I could probably parse the Organiser out but I don’t know if I have any way to know who YOU are. Also I’m not sure if mutt will be happy with me trying to read input after-the-fact, I will have to investigate that as well. Overall that is something that I would like to support. To address #3, there is nothing different between storing the data in your ~/.mailcap vs in ~/.config/configfile.something; they are both files on the file system and are only as secure as the permissions you put upon them and the general security of the machine. As long as you aren’t adding this to /etc/mailcap and letting it get used system wide it should be fine. That being said, because a few people have asked for it, the latest revision of the script now supports a config file, see the docs at the top of the new rev for information on how to use it.

Leave a Reply