pb.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. from twisted.spread import pb
  4. import os
  5. class Maildir(pb.Referenceable):
  6. def __init__(self, directory, rootDirectory):
  7. self.virtualDirectory = directory
  8. self.rootDirectory = rootDirectory
  9. self.directory = os.path.join(rootDirectory, directory)
  10. def getFolderMessage(self, folder, name):
  11. if '/' in name:
  12. raise IOError("can only open files in '%s' directory'" % folder)
  13. with open(os.path.join(self.directory, 'new', name)) as fp:
  14. return fp.read()
  15. def deleteFolderMessage(self, folder, name):
  16. if '/' in name:
  17. raise IOError("can only delete files in '%s' directory'" % folder)
  18. os.rename(os.path.join(self.directory, folder, name),
  19. os.path.join(self.rootDirectory, '.Trash', folder, name))
  20. def deleteNewMessage(self, name):
  21. return self.deleteFolderMessage('new', name)
  22. remote_deleteNewMessage = deleteNewMessage
  23. def deleteCurMessage(self, name):
  24. return self.deleteFolderMessage('cur', name)
  25. remote_deleteCurMessage = deleteCurMessage
  26. def getNewMessages(self):
  27. return os.listdir(os.path.join(self.directory, 'new'))
  28. remote_getNewMessages = getNewMessages
  29. def getCurMessages(self):
  30. return os.listdir(os.path.join(self.directory, 'cur'))
  31. remote_getCurMessages = getCurMessages
  32. def getNewMessage(self, name):
  33. return self.getFolderMessage('new', name)
  34. remote_getNewMessage = getNewMessage
  35. def getCurMessage(self, name):
  36. return self.getFolderMessage('cur', name)
  37. remote_getCurMessage = getCurMessage
  38. def getSubFolder(self, name):
  39. if name[0] == '.':
  40. raise IOError("subfolder name cannot begin with a '.'")
  41. name = name.replace('/', ':')
  42. if self.virtualDirectoy == '.':
  43. name = '.'+name
  44. else:
  45. name = self.virtualDirectory+':'+name
  46. if not self._isSubFolder(name):
  47. raise IOError("not a subfolder")
  48. return Maildir(name, self.rootDirectory)
  49. remote_getSubFolder = getSubFolder
  50. def _isSubFolder(self, name):
  51. return (not os.path.isdir(os.path.join(self.rootDirectory, name)) or
  52. not os.path.isfile(os.path.join(self.rootDirectory, name,
  53. 'maildirfolder')))
  54. class MaildirCollection(pb.Referenceable):
  55. def __init__(self, root):
  56. self.root = root
  57. def getSubFolders(self):
  58. return os.listdir(self.getRoot())
  59. remote_getSubFolders = getSubFolders
  60. def getSubFolder(self, name):
  61. if '/' in name or name[0] == '.':
  62. raise IOError("invalid name")
  63. return Maildir('.', os.path.join(self.getRoot(), name))
  64. remote_getSubFolder = getSubFolder
  65. class MaildirBroker(pb.Broker):
  66. def proto_getCollection(self, requestID, name, domain, password):
  67. collection = self._getCollection()
  68. if collection is None:
  69. self.sendError(requestID, "permission denied")
  70. else:
  71. self.sendAnswer(requestID, collection)
  72. def getCollection(self, name, domain, password):
  73. if domain not in self.domains:
  74. return
  75. domain = self.domains[domain]
  76. if (name in domain.dbm and
  77. domain.dbm[name] == password):
  78. return MaildirCollection(domain.userDirectory(name))
  79. class MaildirClient(pb.Broker):
  80. def getCollection(self, name, domain, password, callback, errback):
  81. requestID = self.newRequestID()
  82. self.waitingForAnswers[requestID] = callback, errback
  83. self.sendCall("getCollection", requestID, name, domain, password)