Don't let ListView call a non-existent method on its superclass.
[matthijs/upstream/mobilegtd.git] / src / persistence / project_file.py
1 import re,os,traceback
2 from inout.io import parse_file_to_line_list
3 from inout import io
4 from model.project import *
5 from model.model import invert_dictionary,WriteableItem
6 from action_file import ActionFile
7
8
9
10 projects_dir = '@Projects'
11
12 def project_name(file_name):
13     encoded_filename = io.os_encode(file_name)
14     return io.os_decode(os.path.splitext(os.path.basename(encoded_filename))[0])
15
16
17
18
19 def status_for_dir(dir_name):
20     p,last_part_of_path = os.path.split(dir_name)
21 #    print last_part_of_path
22     if last_part_of_path == '.' or last_part_of_path == '@Projects':
23         return active   
24     if last_part_of_path[0] == '@':
25         return ProjectStatus.get_status_for_name(last_part_of_path[1:].lower())
26     raise "Invalid path"
27
28 def read(file_path):
29     file_name = os.path.basename(file_path)
30     name = project_name(file_name)
31     project = Project(name,status_for_dir(os.path.dirname(file_path)))
32     file_content = parse_file_to_line_list(file_path)
33     actions,infos = parse_lines(file_content)
34     return project,actions,infos
35
36 def parse_lines(lines):
37     actions = []
38     infos = []
39     for line in lines:
40         line = unicode(line)
41         if len(line) < 3:
42             continue
43         elif line[0]=='#':
44             infos.append(Info(line[1:].strip()))
45         else:
46             actions.append(Action.parse(line))
47     return (actions,infos)
48
49
50 def append_action_file_observer(a):
51     a.observers.append(ActionFile(a))
52
53
54 class ProjectFile(WriteableItem):
55     def __init__(self,project):
56         self.project = project
57 #        project.observers.append(self)
58 #        import traceback
59 #        logger.log('Created ProjectFile from %s'%repr(traceback.extract_stack()))
60
61     def path(self):
62         return self.path_for_status(self.project.status)
63
64     def project_file_name(self):
65         return self.project.name+'.prj'
66
67     def path_for_status(self,status):
68         directory = self.directory_for_status(status)
69         if len(directory) > 0:
70             return os.path.join(directory,self.project_file_name())
71         else:
72             return self.project_file_name()
73
74     def directory_for_status(self,status):
75         status_string = status.name.capitalize()
76         if status_string == 'Tickled':
77             year = ''
78             if status.date.year != date.now().year:
79 #                year = '%s'%status.date.year
80                 year = '2012'
81             month = status.date.strftime('%m %B')
82             day = status.date.strftime('%d %A')          
83             path = os.path.join(projects_dir,'@Tickled',year,month,day)
84             return path
85         if status_string != 'Active':
86             return os.path.join(projects_dir,'@'+status_string)
87         return projects_dir
88         
89     def notify(self,project,attribute,new=None,old=None):
90         if attribute == 'status':
91             self.move_to(self.directory_for_status(new),self.directory_for_status(old))
92         elif attribute == 'name':
93             self.rename(new)
94         elif attribute == 'add_action':
95             append_action_file_observer(new)
96             super(ProjectFile,self).notify(project,attribute,new=new,old=old)
97         else:
98             super(ProjectFile,self).notify(project,attribute,new=new,old=old)
99     
100     def file_string(self):
101         lines = []
102         for info in self.project.infos:
103             lines.append(info.file_string())
104 #        self.sort_actions()
105         for action in self.project.actions:
106             lines.append(action.project_file_string())
107         return u'\n'.join(lines) 
108
109