1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
5 from twisted.spread import pb
6 from twisted.spread import banana
11 class Maildir(pb.Referenceable):
13 def __init__(self, directory, rootDirectory):
14 self.virtualDirectory = directory
15 self.rootDirectory = rootDirectory
16 self.directory = os.path.join(rootDirectory, directory)
18 def getFolderMessage(self, folder, name):
20 raise IOError("can only open files in '%s' directory'" % folder)
21 fp = open(os.path.join(self.directory, 'new', name))
27 def deleteFolderMessage(self, folder, name):
29 raise IOError("can only delete files in '%s' directory'" % folder)
30 os.rename(os.path.join(self.directory, folder, name),
31 os.path.join(self.rootDirectory, '.Trash', folder, name))
33 def deleteNewMessage(self, name):
34 return self.deleteFolderMessage('new', name)
35 remote_deleteNewMessage = deleteNewMessage
37 def deleteCurMessage(self, name):
38 return self.deleteFolderMessage('cur', name)
39 remote_deleteCurMessage = deleteCurMessage
41 def getNewMessages(self):
42 return os.listdir(os.path.join(self.directory, 'new'))
43 remote_getNewMessages = getNewMessages
45 def getCurMessages(self):
46 return os.listdir(os.path.join(self.directory, 'cur'))
47 remote_getCurMessages = getCurMessages
49 def getNewMessage(self, name):
50 return self.getFolderMessage('new', name)
51 remote_getNewMessage = getNewMessage
53 def getCurMessage(self, name):
54 return self.getFolderMessage('cur', name)
55 remote_getCurMessage = getCurMessage
57 def getSubFolder(self, name):
59 raise IOError("subfolder name cannot begin with a '.'")
60 name = name.replace('/', ':')
61 if self.virtualDirectoy == '.':
64 name = self.virtualDirectory+':'+name
65 if not self._isSubFolder(name):
66 raise IOError("not a subfolder")
67 return Maildir(name, self.rootDirectory)
68 remote_getSubFolder = getSubFolder
70 def _isSubFolder(self, name):
71 return (not os.path.isdir(os.path.join(self.rootDirectory, name)) or
72 not os.path.isfile(os.path.join(self.rootDirectory, name,
76 class MaildirCollection(pb.Referenceable):
78 def __init__(self, root):
81 def getSubFolders(self):
82 return os.listdir(self.getRoot())
83 remote_getSubFolders = getSubFolders
85 def getSubFolder(self, name):
86 if '/' in name or name[0] == '.':
87 raise IOError("invalid name")
88 return Maildir('.', os.path.join(self.getRoot(), name))
89 remote_getSubFolder = getSubFolder
92 class MaildirBroker(pb.Broker):
94 def proto_getCollection(self, requestID, name, domain, password):
95 collection = self._getCollection()
96 if collection is None:
97 self.sendError(requestID, "permission denied")
99 self.sendAnswer(requestID, collection)
101 def getCollection(self, name, domain, password):
102 if not self.domains.has_key(domain):
104 domain = self.domains[domain]
105 if (domain.dbm.has_key(name) and
106 domain.dbm[name] == password):
107 return MaildirCollection(domain.userDirectory(name))
110 class MaildirClient(pb.Broker):
112 def getCollection(self, name, domain, password, callback, errback):
113 requestID = self.newRequestID()
114 self.waitingForAnswers[requestID] = callback, errback
115 self.sendCall("getCollection", requestID, name, domain, password)