# HG changeset patch # User Steve Losh # Date 1478620967 0 # Node ID 655800c5080d713175847fd33ed37d85517bdfcb # Parent bbf7f8da61d374cebf0bf48e580e88ab27dd0280# Parent 4ba594ce5fdbcd5c1ca7db1d624172e807c04b79 Merge pull request #9 from benjaminwhite/brokenurl Fixed task warrior url. diff -r 4ba594ce5fdb -r 655800c5080d t.py --- a/t.py Sat Mar 01 02:24:02 2014 -0800 +++ b/t.py Tue Nov 08 16:02:47 2016 +0000 @@ -2,7 +2,7 @@ """t is for people that want do things, not organize their tasks.""" -from __future__ import with_statement +from __future__ import with_statement, print_function import os, re, sys, hashlib from operator import itemgetter @@ -25,6 +25,13 @@ super(UnknownPrefix, self).__init__() self.prefix = prefix +class BadFile(Exception): + """Raised when something else goes wrong trying to work with the task file.""" + def __init__(self, path, problem): + super(BadFile, self).__init__() + self.path = path + self.problem = problem + def _hash(text): """Return a hash of the given text for use as an id. @@ -32,7 +39,7 @@ Currently SHA1 hashing is used. It should be plenty for our purposes. """ - return hashlib.sha1(text).hexdigest() + return hashlib.sha1(text.encode('utf-8')).hexdigest() def _task_from_taskline(taskline): """Parse a taskline (from a task file) and return a task. @@ -134,12 +141,15 @@ if os.path.isdir(path): raise InvalidTaskfile if os.path.exists(path): - with open(path, 'r') as tfile: - tls = [tl.strip() for tl in tfile if tl] - tasks = map(_task_from_taskline, tls) - for task in tasks: - if task is not None: - getattr(self, kind)[task['id']] = task + try: + with open(path, 'r') as tfile: + tls = [tl.strip() for tl in tfile if tl] + tasks = map(_task_from_taskline, tls) + for task in tasks: + if task is not None: + getattr(self, kind)[task['id']] = task + except IOError as e: + raise BadFile(path, e.strerror) def __getitem__(self, prefix): """Return the unfinished task with the given prefix. @@ -150,13 +160,13 @@ If no tasks match the prefix an UnknownPrefix exception will be raised. """ - matched = filter(lambda tid: tid.startswith(prefix), self.tasks.keys()) + matched = [tid for tid in self.tasks.keys() if tid.startswith(prefix)] if len(matched) == 1: return self.tasks[matched[0]] elif len(matched) == 0: raise UnknownPrefix(prefix) else: - matched = filter(lambda tid: tid == prefix, self.tasks.keys()) + matched = [tid for tid in self.tasks.keys() if tid == prefix] if len(matched) == 1: return self.tasks[matched[0]] else: @@ -183,6 +193,7 @@ text = re.sub(find, repl, task['text']) task['text'] = text + task['id'] = _hash(text) def finish_task(self, prefix): """Mark the task with the given prefix as finished. @@ -219,7 +230,7 @@ for _, task in sorted(tasks.items()): if grep.lower() in task['text'].lower(): p = '%s - ' % task[label].ljust(plen) if not quiet else '' - print p + task['text'] + print(p + task['text']) def write(self, delete_if_empty=False): """Flush the finished and unfinished tasks to the files on disk.""" @@ -230,9 +241,13 @@ raise InvalidTaskfile tasks = sorted(getattr(self, kind).values(), key=itemgetter('id')) if tasks or not delete_if_empty: - with open(path, 'w') as tfile: - for taskline in _tasklines_from_tasks(tasks): - tfile.write(taskline) + try: + with open(path, 'w') as tfile: + for taskline in _tasklines_from_tasks(tasks): + tfile.write(taskline) + except IOError as e: + raise BadFile(path, e.strerror) + elif not tasks and os.path.isfile(path): os.remove(path) @@ -302,10 +317,14 @@ kind = 'tasks' if not options.done else 'done' td.print_list(kind=kind, verbose=options.verbose, quiet=options.quiet, grep=options.grep) - except AmbiguousPrefix, e: + except AmbiguousPrefix: + e = sys.exc_info()[1] sys.stderr.write('The ID "%s" matches more than one task.\n' % e.prefix) - except UnknownPrefix, e: + except UnknownPrefix: + e = sys.exc_info()[1] sys.stderr.write('The ID "%s" does not match any task.\n' % e.prefix) + except BadFile as e: + sys.stderr.write('%s - %s\n' % (e.problem, e.path)) if __name__ == '__main__':