Fixing some load/save issues with filebackend
[doneit] / src / file_backend.py
index 3cd2510..4d80fe5 100644 (file)
@@ -1,25 +1,76 @@
 import uuid
+import pickle
 import datetime
 
 import toolbox
 
 
-class FileManager(object):
+class FileBackend(object):
 
-       def __init__(self):
+       def __init__(self, filename):
+               self._filename = filename
                self._projects = {}
                self._items = {}
                self._locations = {}
 
+       def save(self):
+               state = {
+                       "projects": self._projects,
+                       "items": self._items,
+                       "locations": self._locations,
+               }
+               with open(self._filename, "wb") as pickleFile:
+                       pickle.dump(state, pickleFile)
+
+       def load(self):
+               state = {
+                       "projects": {},
+                       "items": {},
+                       "locations": {},
+               }
+               try:
+                       with open(self._filename, "rb") as pickleFile:
+                               state = pickle.load(pickleFile)
+               except IOError, e:
+                       if e.errno != 2:
+                               raise
+               except EOFError, e:
+                       pass
+               self._projects = state["projects"]
+               self._items = state["items"]
+               self._locations = state["locations"]
+
+               if len(self._projects) == 0:
+                       self.add_project("Inbox")
+
+       def add_project(self, name):
+               projId = uuid.uuid4().hex
+               projDetails = {
+                       "name": name,
+                       "id": projId,
+                       "isVisible": True,
+                       "isMeta": False,
+               }
+               assert projId not in self._projects, "How did uuid %r repeat?" % projId
+               self._projects[projId] = projDetails
+               if projId not in self._items:
+                       self._items[projId] = {}
+               return projId
+
+       def set_project_name(self, projId, name):
+               projDetails = self._projects[projId]
+               projDetails["name"] = name
+
+       def set_project_visibility(self, projId, visibility):
+               projDetails = self._projects[projId]
+               projDetails["isVisible"] = visibility
+
        def get_projects(self):
-               return (projectDetails for projectDetails in self._projects.itervalues())
+               return self._projects.itervalues()
 
        def get_project(self, projId):
                return self._projects[projId]
 
-       def get_project_names(self):
-               return (projectDetails["name"] for projectDetails in self._projects.itervalues())
-
        def lookup_project(self, projName):
                """
                From a project's name, returns the project's details
@@ -33,20 +84,18 @@ class FileManager(object):
                return todoList[0]
 
        def get_locations(self):
-               return (locDetails for locDetails in self._locations.itervalues())
+               return self._locations.itervalues()
 
        def get_tasks_with_details(self, projId):
-               return (
-                       taskDetails
-                       for taskDetails in self._items
-                               if taskDetails["projId"] == projId
-               )
+               return self._items[projId].itervalues()
 
        def get_task_details(self, taskId):
-               return self._items[taskId]
+               projId, partialTaskId = self._unpack_ids(taskId)
+               return self._items[projId][taskId]
 
        def add_task(self, projId, taskName):
-               taskId = uuid.uuid4()
+               partialTaskId = uuid.uuid4().hex
+               taskId = self._pack_ids(projId, partialTaskId)
                assert taskId not in self._items, "How did uuid %r repeat?" % taskId
                taskDetails = {
                        "id": taskId,
@@ -61,48 +110,58 @@ class FileManager(object):
                        "estimate": toolbox.Optional(),
                        "notes": {},
                }
-               self._items[taskId] = taskDetails
+               self._items[projId][taskId] = taskDetails
+               return taskId
 
        def set_project(self, taskId, newProjId):
-               taskDetails = self._items[taskId]
+               projId, partialTaskId = self._unpack_ids(taskId)
+               taskDetails = self._items[projId][taskId]
                taskDetails["projId"] = newProjId
 
        def set_name(self, taskId, name):
-               taskDetails = self._items[taskId]
+               projId, partialTaskId = self._unpack_ids(taskId)
+               taskDetails = self._items[projId][taskId]
                taskDetails["name"] = name
 
        def set_duedate(self, taskId, dueDate):
-               taskDetails = self._items[taskId]
+               projId, partialTaskId = self._unpack_ids(taskId)
+               taskDetails = self._items[projId][taskId]
                taskDetails["dueDate"] = dueDate
 
        def set_priority(self, taskId, priority):
-               taskDetails = self._items[taskId]
+               projId, partialTaskId = self._unpack_ids(taskId)
+               taskDetails = self._items[projId][taskId]
                taskDetails["priority"] = priority
 
        def complete_task(self, taskId):
-               taskDetails = self._items[taskId]
+               projId, partialTaskId = self._unpack_ids(taskId)
+               taskDetails = self._items[projId][taskId]
                taskDetails["isCompleted"] = True
                taskDetails["completionDate"] = toolbox.Optional(datetime.datetime.now())
 
        def add_note(self, taskId, noteTitle, noteBody):
-               partialNoteId = uuid.uuid4()
+               projId, partialTaskId = self._unpack_ids(taskId)
+               partialNoteId = uuid.uuid4().hex
                noteId = self._pack_ids(taskId, partialNoteId)
                note = {
                        "id": noteId,
                        "title": noteTitle,
                        "body": noteBody,
                }
-               assert noteId not in self._items[taskId]["notes"]
-               self._items[taskId]["notes"][noteId] = note
+               assert noteId not in self._items[projId][taskId]["notes"]
+               self._items[projId][taskId]["notes"][noteId] = note
+               return noteId
 
        def update_note(self, noteId, noteTitle, noteBody):
                taskId, partialNoteId = self._unpack_ids(noteId)
-               self._items[taskId]["notes"][noteId]["title"] = noteTitle
-               self._items[taskId]["notes"][noteId]["body"] = noteBody
+               projId, partialTaskId = self._unpack_ids(taskId)
+               self._items[projId][taskId]["notes"][noteId]["title"] = noteTitle
+               self._items[projId][taskId]["notes"][noteId]["body"] = noteBody
 
        def delete_note(self, noteId):
                taskId, partialNoteId = self._unpack_ids(noteId)
-               del self._items[taskId]["notes"][noteId]
+               projId, partialTaskId = self._unpack_ids(taskId)
+               del self._items[projId][taskId]["notes"][noteId]
 
        @staticmethod
        def _pack_ids(*ids):