Autocommit of file /home/julien/scripts/gcal-notify changed on host ares
authorJulien Valroff <julien@kirya.net>
Sat, 7 Jan 2012 13:38:07 +0000 (14:38 +0100)
committerJulien Valroff <julien@kirya.net>
Sat, 7 Jan 2012 13:38:07 +0000 (14:38 +0100)
gcal-notify [new file with mode: 0755]

diff --git a/gcal-notify b/gcal-notify
new file mode 100755 (executable)
index 0000000..6fed732
--- /dev/null
@@ -0,0 +1,126 @@
+#!/usr/bin/python
+"""
+Usage: gcal-notify [OPTION]
+
+  -h, --help        displays this help
+  -n, --new         create a new account in the default GNOME keyring
+  -d, --daemonize   check new events on a regular basis (default 10 minutes)
+
+When called without option, gcal-notify will check the events once only.
+
+Send a notification when an event with an alert occurs on the default Google Calendar.
+Accounts information are saved within the default GNOME keyring.
+
+Most code and idea from: http://julien.danjou.info/blog/2012/google-calendar-pynotify
+"""
+
+import sys
+import gtk
+import datetime
+import time
+import getpass
+import pynotify
+import gdata.calendar.service
+import gnomekeyring as gkey
+import string
+import getopt
+
+gkey.get_default_keyring_sync()
+pynotify.init(sys.argv[0])
+
+def get_credentials():
+    """ Retrieve credentials from the default GNOME Keyring """
+    attrs = {"server": "google", "protocol": "googlecal"}
+    items = gkey.find_items_sync(gkey.ITEM_NETWORK_PASSWORD, attrs)
+    return items[0].attributes["user"], items[0].secret
+
+def set_password():
+    """ Add new account into the default GNOME Keyring """
+    username = raw_input("Username: ")
+    password = getpass.getpass(prompt="Password: ")
+    print
+
+    attrs = {
+        "user": username,
+        "server": "google",
+        "protocol": "googlecal" ,
+    }
+    gkey.item_create_sync(gkey.get_default_keyring_sync(),
+            gkey.ITEM_NETWORK_PASSWORD, "Google", attrs, password, True)
+    
+    print ("User added.")
+
+def daemonize():
+    """ Run a loop and check events every 10 minutes """
+    while True:
+        process()
+        time.sleep(600)
+
+
+def process():
+    """ Retrieve events and display a notification """
+    # Then, we need to import gdata Calendar API and connect to the calendar.
+    calendar_service = gdata.calendar.service.CalendarService()
+    (calendar_service.email, calendar_service.password) = get_credentials()
+    calendar_service.ProgrammaticLogin()
+
+    # Request the events from the default calendar.
+    feed = calendar_service.GetCalendarEventFeed()
+
+    # Now we can iterate over feed and do various checks.
+    for event in feed.entry:
+        # If the event status is not confirmed, go to the next event.
+        if event.event_status.value != "CONFIRMED":
+            continue
+        # Now iterate over all the event dates (usually it has one)
+        for when in event.when:
+            # Parse start and end time
+            try:
+                start_time = datetime.datetime.strptime(when.start_time.split(".")[0], "%Y-%m-%dT%H:%M:%S")
+                end_time = datetime.datetime.strptime(when.end_time.split(".")[0], "%Y-%m-%dT%H:%M:%S")
+            except ValueError:
+                # ValueError happens on parsing error. Parsing errors
+                # usually happen for "all day" events since they have
+                # not time, but we do not care about this events.
+                continue
+            now = datetime.datetime.now()
+            # Check that the event hasn't already ended
+            if end_time > now:
+                # Check each alert
+                for reminder in when.reminder:
+                    # We handle only reminders with method "alert"
+                    # and whose start time minus the reminder delay has passed
+                    if reminder.method == "alert" \
+                            and start_time - datetime.timedelta(0, 60 * int(reminder.minutes)) < now:
+                        # Build the notification
+                        notification = pynotify.Notification(summary=event.title.text,
+                                message="\n".join(filter(None, (event.content.text, "<a href='https://www.google.com/calendar/render'>Google Calendar</a>"))))
+                        # Set an icon from the GTK+ stock icons
+                        notification.set_icon_from_pixbuf(gtk.Label().render_icon(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_LARGE_TOOLBAR))
+                        notification.set_timeout(0)
+                        # Show the notification
+                        notification.show()
+
+def main():
+    # parse command line options
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "hnd", ["help", "new", "daemonize"])
+    except getopt.error, msg:
+        print msg
+        print "for help use --help"
+        sys.exit(2)
+    # process options
+    for o, a in opts:
+        if o in ("-h", "--help"):
+            print __doc__
+            sys.exit(0)
+        elif o in ("-n", "--new"):
+            set_password()
+            sys.exit()
+        elif o in ("-d", "--daemonize"):
+            daemonize()
+    # no option, no argument
+    process()
+
+if __name__ == "__main__":
+    main()