gcal2org / gcal2org.py

Felix Geller 99741ab 





















Felix Geller 8fa7d2b 









Felix Geller 99741ab 


Felix Geller 0c86e81 

Felix Geller 99741ab 







Felix Geller 62f983c 
Felix Geller 99741ab 


















Felix Geller 0c86e81 




Felix Geller 99741ab 
Felix Geller 0c86e81 



Felix Geller 99741ab 

Felix Geller 62f983c 
Felix Geller 99741ab 
Felix Geller 0c86e81 
Felix Geller 99741ab 


Felix Geller 62f983c 
Felix Geller 99741ab 




























#!/usr/bin/env python
# Copyright (C) 2011 by Felix Geller
# 
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Queries Google Calendar for entries in that are at most 30 days in
# the past or future, then prints each entry into a org-entry to a
# given file.
#
# N.B.: Uses authinfo_pw to retrieve a password from an encrypted
# file. Please change this according to your preferences.
#
# Usage:
#  > gcal2org.py email@gmail.com org-file

import gdata.calendar.client
from datetime import date, datetime, timedelta
from time import strftime, strptime, mktime, localtime
import sys, re, os, getopt

preamble = """#+STARTUP: overview
#+DESCRIPTION: Converted on %s
* Events
"""

item = """** %s
   :PROPERTIES:
   :Id:       %s
   :When:     %s
   :Where:    %s
   :Who:      %s
   :END:
 - Description:
%s
"""

def date_range_query(cal_client, 
                     max_results = 333, 
                     start_date = str(date.today() - timedelta(30)), 
                     end_date = str(date.today() + timedelta(30))):
  query = gdata.calendar.client.CalendarEventQuery()
  query.start_min = start_date
  query.start_max = end_date
  query.max_results = max_results
  feed = cal_client.GetCalendarEventFeed(q=query)
  return feed.entry

def date_range(start_time, end_time):
  if 'T' in start_time:
    st = strptime(start_time[:16], '%Y-%m-%dT%H:%M')
    et = strptime(end_time[:16], '%Y-%m-%dT%H:%M')
    tstamp = '<%Y-%m-%d %a %H:%M>'
  else:
    st = strptime(start_time, '%Y-%m-%d')
    et = localtime(mktime(strptime(end_time, '%Y-%m-%d')) - 86400.0)
    tstamp = '<%Y-%m-%d %a>'
  return '%s--%s' % tuple([strftime(tstamp, t) for t in (st, et)])

def write_item(event, org_file):
  event_id = event.id.text
  title = event.title.text
  when = date_range(event.when[0].start, event.when[0].end)
  where = event.where[0].text or 'N/A'
  who = ', '.join([x.value for x in event.who])
  description = event.content.text or 'N/A'
  itemdata =  tuple([s.encode('UTF-8') for s in (title, event_id, when, where, who, description)])
  org_file.write(item % itemdata)

def authinfo_pw(login):
  p = re.compile('login %s password ([^ ]+)' % login)
  authinfo = os.popen('gpg -q --no-tty -d ~/.gcal.gpg').read()
  return p.search(authinfo).group(1)

def create_calendar_client(login):
  client = gdata.calendar.client.CalendarClient(source='acme-gcal2org-v1')
  client.ssl = True
  client.ClientLogin(login, authinfo_pw(login), client.source)
  return client

def create_org_file(login, filename):
  org_file = open(filename, 'w')
  org_file.write(preamble % datetime.now())
  client = create_calendar_client(login)
  for event in date_range_query(client):
    write_item(event, org_file)
  org_file.close()

def main():
  if 3 > len(sys.argv):
    print >>sys.stderr, 'Please provide login and filename for output as arguments'
    return 2
  else:
    return create_org_file(sys.argv[1], sys.argv[2])

if __name__ == '__main__':
  sys.exit(main())
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.