[Pythonmac-SIG] Please critique my first appscript - a fix for Palm sync of iCal Tasks (for kGTD)
Nicholas Riley
njriley at uiuc.edu
Tue Aug 29 20:47:19 CEST 2006
These are (mostly) all issues of personal opinion, but anyway...
On Tue, Aug 29, 2006 at 12:49:44AM -0400, Marcin Komorowski wrote:
>#!/usr/bin/env /usr/bin/pythonw
There's no point of using env if you specify an absolute path.
"#!/usr/bin/env pythonw" is probably what you want.
> def myDebug( txt ):
> if txt == None:
> sys.stderr.flush()
> else:
> sys.stderr.write( txt )
stderr should be unbuffered by default; you shouldn't need to flush it
at all. Also, if you've got a sentinel value, try representing it
with a default/optional argument, e.g.:
def myDebug(txt, flush=False):
or:
def myDebug(txt=None):
> def getTaskList():
> appCal = app( 'iCal' )
Use a bundle ID or creator to refer to iCal, in case it is renamed.
> cal_todos = appCal.calendars.filter(its.name !=
> '').todos.properties()
> tasks = [ todo for cals in cal_todos for todo in cals]
Consider being more consistent about spacing - see PEP 8 for one
possible coding style. Also, wow, I never noticed how backwards
reading nested list comprehensions is - yuck (Python problem, not
yours...).
> # Iterate flattened list, builing a local dictionary of
> dictionaries, by uid
> tasks_data = {}
> for task in tasks:
> if task[ k.class__ ] == k.todo:
Why do you need to do this? It seems if you ask for todos, all you
get is todos, right? :) If you're working around some iCal bug it
makes sense to comment it.
> uid = task[ k.uid ]
> tasks_data[uid] = task;
> myDebug('.')
> myDebug(None)
You could do the above with a generator expression, e.g:
tasks_data = dict((todo[k.uid], todo) for todos in cal_todos for todo in todos
if todo[k.class__] == k.todo)
(this should be fast enough; I can't imagine it'd be worth displaying progress)
> k_decode = {
> k.priority : "k.priority",
> k.due_date : "k.due_date",
> k.completion_date : "k.completion_date",
> k.description : "k.description",
> k.url : "k.url",
> k.uid : "k.uid",
> k.summary : "k.summary",
> k.class__ : "k.class__"
> }
There's no need to do this; you can just print k.priority, etc.,
directly.
> def diffTaskLists( task_list1, task_list2 ):
> diff_list = []
> for uid in [ id for id in task_list1.keys() if
> task_list2.has_key( id ) ]:
You can use 'id in task_list2' instead of 'task_list2.has_key(id)'.
For clarity (if not necessarily speed) you might consider using the
set data type instead.
> t1 = task_list1[uid]
> t2 = task_list2[uid]
> found_difference = False
> for field in [ k.priority, k.due_date, k.completion_date,
> k.description, k.url, k.summary ]:
> if t1[field] != t2[field]:
> if found_difference == False:
I generally find it easier to read "if not found_difference".
> myDebug( " task ID %s:\n" % str( uid ) )
You don't need to use 'str', that's what %s does already. And don't
be afraid of the print statement, e.g.:
print >> sys.stderr, ' task ID %s:' % uid
> myDebug( " field %s: " % k_decode[field] );
> try:
> myDebug( "t1 = '%s' t2 = '%s'" % ( t1[field], t2
> [field] ) )
> except:
> pass
Eww. If there are problems converting the fields to a string, you
should address them (or report a bug in appscript or iCal...) At the
very list, make your except statement more specific so it doesn't mask
other exceptions.
> myDebug( "\n" )
> found_difference = True
> break
Huh, what's the point of checking 'found_difference' then, if you
break immediately after setting it to true? Looks like you can get
rid of it completely.
> def updateTimeStamp( task_uid_list, timestamp ):
> myDebug( "Setting new timestamp for task UIDs %s\n" % repr
> ( task_uid_list ) )
You can use '%r' % task_uid_list to get the repr.
> def usage():
> print "USAGE: " + sys.argv[0] + " save|check"
It's a bit more efficient (and clearer, IMO) to use commas to give
print multiple arguments rathern than using + to concatenate strings.
> def main(mode):
> if mode != 'save' and mode != 'check':
if mode not in ('save', check'):
> pp = pprint.PrettyPrinter(indent=4)
Since you only use this once, it makes sense to move it closer to its
definition and/or combine the creation and invocation.
--
Nicholas Riley <njriley at uiuc.edu> | <http://www.uiuc.edu/ph/www/njriley>
More information about the Pythonmac-SIG
mailing list