3 import config.config as config
5 class ActionStatus(Status):
8 class UnprocessedStatus(Status):
10 super(UnprocessedStatus,self).__init__(u'unprocessed',0)
11 def update(self,owner):
16 unprocessed = UnprocessedStatus()
17 active = ActionStatus(u'active',1,u'-')
18 done = ActionStatus(u'done',2,u'+')
19 tickled = ActionStatus(u'tickled',3,u'/')
20 inactive = ActionStatus(u'inactive',4,u'!')
21 someday = ActionStatus(u'someday',5,u'~')
22 info = ActionStatus(u'info',0)
24 action_regexp = re.compile('(?P<status>[+-/!])?\s*(?P<context>\S*)\s*(?P<description>[^\(]*)(\((?P<info>[^\)]*))?',re.U)
25 context_regexp = re.compile('(?P<numbers>\d*)(?P<text>\D?.*)',re.U)
28 def parse_action_line(string):
29 matching = action_regexp.match(string)
30 description = matching.group('description').rstrip(u' \r\n')
31 status_symbol = matching.group('status')
32 if (status_symbol == None):
34 status = ActionStatus.get_status(status_symbol)
35 info = matching.group('info')
36 context = parse_context(matching.group('context'))
39 return context,description,info,status
42 def parse_context(context):
43 context_matching = context_regexp.match(context)
44 context_numbers = context_matching.group('numbers')
45 context_text = context_matching.group('text')
46 if(context_numbers in config.ABBREVIATIONS):
47 context=(unicode(config.ABBREVIATIONS[context_numbers])+context_text).rstrip(u'/')
57 class Action(ObservableItem,ItemWithStatus):
58 """Actions in the GTD terminology are physical, visible activities.
59 In MobileGTD, an action consists of a description (e.g. "Google for Python"),
60 a context ("@Computer") and optionally a project which it belongs to and
61 additional information.
62 An Action also has a state. This can be one of the following:
63 - unprocessed: New, has not yet been processed in any way by MobileGTD
64 - active: The action is among the next actions
65 - done: The action has been performed
66 - tickled: The action has been postponed to a certain date
67 - inactive: The action has been paused
70 assert type(string) == unicode
71 context,description,info,status = parse_action_line(string)
72 return Action(description,context,info=info,status=status)
74 parse = staticmethod(parse)
76 def __init__(self,description,context,project=None,info=u'',status=unprocessed):
77 super(Action, self).__init__()
78 self.project = project
79 assert type(description) == unicode
80 assert type(context) == unicode
81 assert type(info) == unicode
83 self.description = description
84 self.context = context
89 return self.status in [active,unprocessed]
91 def is_reviewable(self):
92 return self.status in [unprocessed,inactive]
94 def is_not_done(self):
95 return self.status in [active,unprocessed,inactive]
100 advanced_info = advanced_info+' Project: '+str(self.project)
101 if len(self.info) > 0:
102 advanced_info = advanced_info +' Info: '+self.info
103 if len(advanced_info) > 0:
104 advanced_info = ' ('+advanced_info+' )'
105 return repr(self.description)+' @'+repr(self.context)+repr(advanced_info)
107 def project_file_string(self,entry_separator=' '):
108 return (u'%s%s'%(self.status_symbol(),self.context_description_info())).strip()
110 def context_description_info(self,entry_separator=' '):
111 return u'%s%s%s%s%s'%(\
112 self.context,entry_separator,\
113 self.description,entry_separator,\
116 def info_string(self,entry_separator=''):
118 if (len(self.info) > 1):
119 info_string = u'%s(%s)'%(entry_separator,self.info)
123 return self.project_file_string()
124 def __cmp__(self,other):
125 return self.status.__cmp__(other.status)
128 return self.description
129 __all__ = ["Action","ActionStatus","active","done","tickled","inactive","someday","info","unprocessed","parse_action_line","parse_context"]