| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
| 2 # See LICENSE for details. | |
| 3 | |
| 4 | |
| 5 from twisted.spread import pb | |
| 6 from twisted.spread import banana | |
| 7 | |
| 8 import os | |
| 9 import types | |
| 10 | |
| 11 class Maildir(pb.Referenceable): | |
| 12 | |
| 13 def __init__(self, directory, rootDirectory): | |
| 14 self.virtualDirectory = directory | |
| 15 self.rootDirectory = rootDirectory | |
| 16 self.directory = os.path.join(rootDirectory, directory) | |
| 17 | |
| 18 def getFolderMessage(self, folder, name): | |
| 19 if '/' in name: | |
| 20 raise IOError("can only open files in '%s' directory'" % folder) | |
| 21 fp = open(os.path.join(self.directory, 'new', name)) | |
| 22 try: | |
| 23 return fp.read() | |
| 24 finally: | |
| 25 fp.close() | |
| 26 | |
| 27 def deleteFolderMessage(self, folder, name): | |
| 28 if '/' in 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)) | |
| 32 | |
| 33 def deleteNewMessage(self, name): | |
| 34 return self.deleteFolderMessage('new', name) | |
| 35 remote_deleteNewMessage = deleteNewMessage | |
| 36 | |
| 37 def deleteCurMessage(self, name): | |
| 38 return self.deleteFolderMessage('cur', name) | |
| 39 remote_deleteCurMessage = deleteCurMessage | |
| 40 | |
| 41 def getNewMessages(self): | |
| 42 return os.listdir(os.path.join(self.directory, 'new')) | |
| 43 remote_getNewMessages = getNewMessages | |
| 44 | |
| 45 def getCurMessages(self): | |
| 46 return os.listdir(os.path.join(self.directory, 'cur')) | |
| 47 remote_getCurMessages = getCurMessages | |
| 48 | |
| 49 def getNewMessage(self, name): | |
| 50 return self.getFolderMessage('new', name) | |
| 51 remote_getNewMessage = getNewMessage | |
| 52 | |
| 53 def getCurMessage(self, name): | |
| 54 return self.getFolderMessage('cur', name) | |
| 55 remote_getCurMessage = getCurMessage | |
| 56 | |
| 57 def getSubFolder(self, name): | |
| 58 if name[0] == '.': | |
| 59 raise IOError("subfolder name cannot begin with a '.'") | |
| 60 name = name.replace('/', ':') | |
| 61 if self.virtualDirectoy == '.': | |
| 62 name = '.'+name | |
| 63 else: | |
| 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 | |
| 69 | |
| 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, | |
| 73 'maildirfolder'))) | |
| 74 | |
| 75 | |
| 76 class MaildirCollection(pb.Referenceable): | |
| 77 | |
| 78 def __init__(self, root): | |
| 79 self.root = root | |
| 80 | |
| 81 def getSubFolders(self): | |
| 82 return os.listdir(self.getRoot()) | |
| 83 remote_getSubFolders = getSubFolders | |
| 84 | |
| 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 | |
| 90 | |
| 91 | |
| 92 class MaildirBroker(pb.Broker): | |
| 93 | |
| 94 def proto_getCollection(self, requestID, name, domain, password): | |
| 95 collection = self._getCollection() | |
| 96 if collection is None: | |
| 97 self.sendError(requestID, "permission denied") | |
| 98 else: | |
| 99 self.sendAnswer(requestID, collection) | |
| 100 | |
| 101 def getCollection(self, name, domain, password): | |
| 102 if not self.domains.has_key(domain): | |
| 103 return | |
| 104 domain = self.domains[domain] | |
| 105 if (domain.dbm.has_key(name) and | |
| 106 domain.dbm[name] == password): | |
| 107 return MaildirCollection(domain.userDirectory(name)) | |
| 108 | |
| 109 | |
| 110 class MaildirClient(pb.Broker): | |
| 111 | |
| 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) | |
| OLD | NEW |