#!/usr/bin/python # -*- coding: UTF-8 -*- # vim:ts=4:sw=4:ai:si:ci # ogoObjects - Python module to "objectify" opengroupware XML-RPC calls # Copyright 2006 Eliphas Levy Theodoro # License: GPLv2 # keywords: python opengroupware ogo xml rpc # Changelog # 2006-02-17: v0.1 # First version, release # TODO: # Define optional team and participant filter for appointments # Objects for Jobs, Job, Contacts, Contact # I18N the module and remove static strings # Handle exceptions like connection errors # BEGIN import xmlrpclib, time, sys, locale from mx import DateTime # How to get right "Today" string? today = DateTime.now() todayStrs = {'en': 'Today', 'pt': 'Hoje' } lang = locale.getdefaultlocale()[0] if todayStrs.has_key(lang): todayStr = todayStrs[lang] elif todayStrs.has_key(lang[:2]): todayStr = todayStrs[lang[:2]] else: todayStr = todayStrs['en'] # Magic to get internationalized weekdays, 0 is monday # Care to simplify it? weekDays = [ i.strftime('%A').capitalize() for i in [DateTime.DateFrom('2001-01-%02d' % j) for j in range(1,8)] ] def PrettyDate(dtime): if dtime.absdate == today.absdate: return dtime.strftime(todayStr + ', %H:%M') else: return dtime.strftime(weekDays[dtime.day_of_week]+', %d/%m %H:%M') class Participant: def __str__(self): return self.name def __init__(self,partDict,connection): self.isPerson = False self.isTeam = False self.name = '' self.email = [] self.isPerson = partDict.has_key('isPerson') self.isTeam = partDict.has_key('isTeam') if not self.isPerson and not self.isTeam: sys.stderr.write('DEBUGME: %s\n' % partDict) sys.exit(1) if self.isPerson: self.name = partDict['firstname'] + ' ' + partDict['name'] elif self.isTeam: self.name = partDict['description'] if self.isPerson: personDetail = connection.person.getByNumber(partDict['number']) if len(personDetail) > 0: if personDetail.has_key('extendedAttrs') \ and personDetail['extendedAttrs'].has_key('email1'): self.email.append(personDetail['extendedAttrs']['email1']) elif self.isTeam: teamDetail = connection.team.getMembersForTeam(partDict['number']) if len(teamDetail) > 0: for person in teamDetail: personDetail = connection.person.getByNumber(person['number']) if personDetail.has_key('extendedAttrs') \ and personDetail['extendedAttrs'].has_key('email1'): self.email.append(personDetail['extendedAttrs']['email1']) self.name = self.name.encode('UTF-8') class Appointment: def __cmp__(self,other): return cmp(self.start,other.start) def __str__(self): return '%s - %s\n%s' % (self.startPretty, self.endPretty, self.title) def __init__(self,appDict,connection): # When this appointment will happen. # -1: Before now, 0: Now, 1: Will happen today, 2: Will happen some other day toHappen = 1 self.participants = [] self.dic = appDict try: self.title = appDict['title'].encode('UTF-8') self.start = DateTime.mktime(time.strptime(appDict['startDate'].value, '%Y%m%dT%H:%M:%S')) self.end = DateTime.mktime(time.strptime(appDict['endDate'].value, '%Y%m%dT%H:%M:%S')) self.startPretty = PrettyDate(self.start) self.endPretty = PrettyDate(self.end) if appDict.has_key('aptType'): self.type = appDict['aptType'].encode('UTF-8') else: self.type = '' if today > self.end: # already happened self.toHappen = -1 elif today >= self.start and today <= self.end: # is happening self.toHappen = 0 elif today.absdate == self.end.absdate: # will happen today self.toHappen = 1 else: # will happen, but not today self.toHappen = 2 for p in appDict['participants']: self.participants.append( Participant(p,connection) ) except KeyError,e: sys.stderr.write('Erro: appDict %s\n' % e) sys.exit(1) class Appointments: connection = None def connect(self,user,password,host='localhost',port=22000): url = 'http://%s:%s@%s:%d/RPC2' % (user,password,host,port) self.connection = xmlrpclib.Server( url ) def fetch(self,start,end): fSpec = {} start = start + '.00:00' end = end + '.23:59' startDate = xmlrpclib.DateTime(time.strptime(start,'%Y-%m-%d.%H:%M')) endDate = xmlrpclib.DateTime(time.strptime(end,'%Y-%m-%d.%H:%M')) fSpec['qualifier'] = {} fSpec['qualifier']['startDate'] = startDate fSpec['qualifier']['endDate'] = endDate fSpec['sortOrdering'] = ['startDate',] if type(self.connection) == type(None): raise Exception('NotConnected','XML-RPC connection not initialized, please connect first') return False appointments = self.connection.appointment.fetch(fSpec) apps = [] for appointment in appointments: apps.append( Appointment(appointment,self.connection) ) apps.sort() self.Appointments = apps return True if __name__ == '__main__': if len(sys.argv) not in (1,3): sys.stderr.write("""Usage:\n%s startdate enddate\n\nEx: %s %s %s\n""" % \ ( sys.argv[0], sys.argv[0], (today-1).date, today.date )) sys.exit(1) elif len(sys.argv) == 3: start = sys.argv[1] end = sys.argv[2] else: start = today.date end = start print "Username: ", user = sys.stdin.readline()[:-1] from getpass import getpass password = getpass("Password: ") appsObj = Appointments() appsObj.connect(user,password) appsObj.fetch(start,end) print "\nSchedule:\n" for appObj in appsObj.Appointments: happenOn = '' if appObj.toHappen == -1: happenOn = '(Happened)' elif appObj.toHappen == 0: happenOn = '(Now)' print '%s - %s: %s %s' % \ ( appObj.startPretty, appObj.endPretty, appObj.title, happenOn ) party = [] for participant in appObj.participants: party.append(participant.name) party.sort() print '\t', '\n\t'.join(party)