93cee59e8d59809ba4c967b3bd277bb7bc37eb4f
[doneit] / src / file_backend.py
1 import uuid
2 import pickle
3 import datetime
4
5 import toolbox
6
7
8 class FileManager(object):
9
10         def __init__(self, filename):
11                 self._filename = filename
12                 self._projects = {}
13                 self._items = {}
14                 self._locations = {}
15
16         def save(self):
17                 state = {
18                         "projects": self._projects,
19                         "items": self._items,
20                         "locations": self._locations,
21                 }
22                 pickle.dump(state, self._filename)
23
24         def load(self):
25                 state = pickle.load(self._filename)
26                 self._projects = state["projects"]
27                 self._items = state["items"]
28                 self._locations = state["locations"]
29
30         def add_project(self, name):
31                 projId = uuid.uuid4().hex
32                 projDetails = {
33                         "name": name,
34                         "id": projId,
35                         "isVisible": True,
36                         "isMeta": False,
37                 }
38                 assert projId not in self._projects, "How did uuid %r repeat?" % projId
39                 self._projects[projId] = projDetails
40
41         def set_project_name(self, projId, name):
42                 projDetails = self._projects[projId]
43                 projDetails["name"] = name
44
45         def set_project_visibility(self, projId, visibility):
46                 projDetails = self._projects[projId]
47                 projDetails["isVisible"] = False
48
49         def get_projects(self):
50                 return (projectDetails for projectDetails in self._projects.itervalues())
51
52         def get_project(self, projId):
53                 return self._projects[projId]
54
55         def lookup_project(self, projName):
56                 """
57                 From a project's name, returns the project's details
58                 """
59                 todoList = [
60                         projectDetails
61                         for projectDetails in self._projects.itervalues()
62                                 if projectDetails["name"] == projName
63                 ]
64                 assert len(todoList) == 1, "Wrong number of lists found for %s, in %r" % (projName, todoList)
65                 return todoList[0]
66
67         def get_locations(self):
68                 return (locDetails for locDetails in self._locations.itervalues())
69
70         def get_tasks_with_details(self, projId):
71                 return (
72                         taskDetails
73                         for taskDetails in self._items
74                                 if taskDetails["projId"] == projId
75                 )
76
77         def get_task_details(self, taskId):
78                 return self._items[taskId]
79
80         def add_task(self, projId, taskName):
81                 taskId = uuid.uuid4().hex
82                 assert taskId not in self._items, "How did uuid %r repeat?" % taskId
83                 taskDetails = {
84                         "id": taskId,
85                         "projId": projId,
86                         "name": taskName,
87                         "url": "",
88                         "locationId": toolbox.Optional(),
89                         "dueDate": toolbox.Optional(),
90                         "isCompleted": False,
91                         "completedDate": toolbox.Optional(),
92                         "priority": toolbox.Optional(),
93                         "estimate": toolbox.Optional(),
94                         "notes": {},
95                 }
96                 self._items[taskId] = taskDetails
97
98         def set_project(self, taskId, newProjId):
99                 taskDetails = self._items[taskId]
100                 taskDetails["projId"] = newProjId
101
102         def set_name(self, taskId, name):
103                 taskDetails = self._items[taskId]
104                 taskDetails["name"] = name
105
106         def set_duedate(self, taskId, dueDate):
107                 taskDetails = self._items[taskId]
108                 taskDetails["dueDate"] = dueDate
109
110         def set_priority(self, taskId, priority):
111                 taskDetails = self._items[taskId]
112                 taskDetails["priority"] = priority
113
114         def complete_task(self, taskId):
115                 taskDetails = self._items[taskId]
116                 taskDetails["isCompleted"] = True
117                 taskDetails["completionDate"] = toolbox.Optional(datetime.datetime.now())
118
119         def add_note(self, taskId, noteTitle, noteBody):
120                 partialNoteId = uuid.uuid4().hex
121                 noteId = self._pack_ids(taskId, partialNoteId)
122                 note = {
123                         "id": noteId,
124                         "title": noteTitle,
125                         "body": noteBody,
126                 }
127                 assert noteId not in self._items[taskId]["notes"]
128                 self._items[taskId]["notes"][noteId] = note
129
130         def update_note(self, noteId, noteTitle, noteBody):
131                 taskId, partialNoteId = self._unpack_ids(noteId)
132                 self._items[taskId]["notes"][noteId]["title"] = noteTitle
133                 self._items[taskId]["notes"][noteId]["body"] = noteBody
134
135         def delete_note(self, noteId):
136                 taskId, partialNoteId = self._unpack_ids(noteId)
137                 del self._items[taskId]["notes"][noteId]
138
139         @staticmethod
140         def _pack_ids(*ids):
141                 return "-".join((str(id) for id in ids))
142
143         @staticmethod
144         def _unpack_ids(ids):
145                 return ids.split("-")