#!/usr/bin/env python #03/21/2010 jcvernaleo (john@netpurgatory.com) #$Id: read_ical.py,v 1.2 2010/03/31 01:29:27 john Exp $ #Copyright 2010 John C. Vernaleo # read_ical v0.1 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See the file gpl.txt in the same directory as this. # # This is a first pass at a python interface to ical files (specifically # what Apple's iCal considers an ical file. It only handle's todo items # (VTODO) at the moment since that was all I wanted. # # The main purpose of it was to convert iCal todo's to a format I can use # with emacs org-mode. Thanks to this I was able to completely move my todo # lists (and I really depend on todo lists) from iCal (which I never liked) # to emacs (which I really like). # I may try to improve this, but for now it does what I needed. import sys import re class todo: """A simple class to hold a single TODO element from ical along with some routines to work with it. The goal is to get data out of ical and into emacs org-mode. """ def __init__(self): self.created="" self.UID="" self.summary="" self.completed="" self.due="" self.description="" return def get_item(self,line,item,name): if not item: term=re.compile(name) result=term.match(line) if result: return(term.split(line)[1]) else: return else: return(item) def read_ical_line(self,line): self.created=self.get_item(line,self.created,"CREATED:") self.UID=self.get_item(line,self.UID,"UID:") self.summary=self.get_item(line,self.summary,"SUMMARY:") self.completed=self.get_item(line,self.completed,"COMPLETED:") self.due=self.get_item(line,self.due,"DUE;VALUE=DATE:") self.description=self.get_item(line,self.description,"DESCRIPTION:") return def org_mode_date(self,date): """This is assuming that dates are always in the form YYYYMMDD followed by other stuff I don't care about. org mode allows for more precision for the completion dates but the extra info in the ical files doesn't look very helpful. """ if date and (len(date)>=8): corrected_date=date[0]+date[1]+date[2]+date[3]+"-"+date[4]+date[5]+"-"+date[6]+date[7] return(corrected_date) else: return def print_orgmode(self): line="**" if not (self.completed): line=line+" TODO "+self.summary else: line=line+" DONE "+self.summary print(line) line="" if self.due: line=" DEADLINE: <"+self.org_mode_date(self.due)+">" if self.completed: if not self.due: line=line+" " line=line+" CLOSED: ["+self.org_mode_date(self.completed)+"]" if line: print(line) line="" if self.description: line=" "+self.description print(line) return def read_ical(filename): """This function reads a filename and put any VTODO items it finds in a list of TODO objects. """ infile=open(filename) intodo=0 i=0 todo_list=[] for line in infile: line=line.rstrip() if line == "END:VTODO": intodo=0 if intodo: todo_list[i-1].read_ical_line(line) if line == "BEGIN:VTODO": intodo=1 todo_list.append(todo()) i+=1 infile.close() return(todo_list) if __name__ == "__main__": if not len(sys.argv)>1: print("MUST SUPPLY A FILENAME") sys.exit() filename=sys.argv[1] todo_list=read_ical(filename) for item in todo_list: item.print_orgmode()