Fix pep8 support in src/plugins.

This commit is contained in:
Emmanuel Gil Peyrot 2013-01-18 17:55:35 +01:00
commit 0dca274360

View file

@ -21,54 +21,54 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from logging import debug, info, error
import warnings
warnings.filterwarnings('ignore','the MimeWriter',DeprecationWarning,'twisted' ) #FIXME: to be removed, see http://twistedmatrix.com/trac/ticket/4038
warnings.filterwarnings('ignore', 'the MimeWriter', DeprecationWarning, 'twisted') # FIXME: to be removed, see http://twistedmatrix.com/trac/ticket/4038
from twisted.internet import protocol
from twisted.words.protocols.jabber import error as jab_error
from twisted.cred import portal,checkers
from twisted.mail import imap4,maildir
from twisted.cred import portal, checkers
from twisted.mail import imap4, maildir
from email.parser import Parser
import email.message
from email.charset import Charset
import os,os.path
import os
from cStringIO import StringIO
from twisted.internet import reactor
import pdb
from sat.core.exceptions import ProfileUnknownError
from sat.memory.persistent import PersistentBinaryDict
from zope.interface import implements
PLUGIN_INFO = {
"name": "Maildir Plugin",
"import_name": "Maildir",
"type": "Misc",
"protocols": [],
"dependencies": [],
"main": "MaildirBox",
"handler": "no",
"description": _("""Intercept "normal" type messages, and put them in a Maildir type box""")
"name": "Maildir Plugin",
"import_name": "Maildir",
"type": "Misc",
"protocols": [],
"dependencies": [],
"main": "MaildirBox",
"handler": "no",
"description": _("""Intercept "normal" type messages, and put them in a Maildir type box""")
}
MAILDIR_PATH = "Maildir"
class MaildirError(Exception):
pass
class MaildirBox(object):
def __init__(self, host):
info(_("Plugin Maildir initialization"))
self.host = host
self.__observed={}
self.data={} #list of profile spectific data. key = profile, value = PersistentBinaryDict where key=mailbox name,
self.__observed = {}
self.data = {} # list of profile spectific data. key = profile, value = PersistentBinaryDict where key=mailbox name,
# and value is a dictionnary with the following value
# - cur_idx: value of the current unique integer increment (UID)
# - message_id (as returned by MaildirMailbox): a tuple of (UID, [flag1, flag2, ...])
pList=host.memory.getProfilesList #shorter :)
self.__mailboxes={} #key: profile, value: {boxname: MailboxUser instance}
pList = host.memory.getProfilesList # shorter :)
self.__mailboxes = {} # key: profile, value: {boxname: MailboxUser instance}
#the triggers
host.trigger.add("MessageReceived", self.messageReceivedTrigger)
@ -76,11 +76,12 @@ class MaildirBox(object):
def profileConnected(self, profile):
"""Called on profile connection, create profile data"""
self.data[profile] = PersistentBinaryDict("plugin_maildir", profile)
self.__mailboxes[profile]={}
self.__mailboxes[profile] = {}
def dataLoaded(ignore):
if not self.data[profile]:
#the mailbox is new, we initiate the data
self.data[profile]["INBOX"] = {"cur_idx":0}
self.data[profile]["INBOX"] = {"cur_idx": 0}
self.data[profile].load().addCallback(dataLoaded)
def profileDisconnected(self, profile):
@ -108,8 +109,8 @@ class MaildirBox(object):
profile = self.host.memory.getProfileName(profile_key)
if not profile:
raise ProfileUnknownError(profile_key)
if not self.__mailboxes[profile].has_key(boxname):
self.__mailboxes[profile][boxname]=MailboxUser(self, boxname, observer, profile=profile)
if boxname not in self.__mailboxes[profile]:
self.__mailboxes[profile][boxname] = MailboxUser(self, boxname, observer, profile=profile)
else:
if observer:
self.addObserver(observer, profile, boxname)
@ -118,33 +119,33 @@ class MaildirBox(object):
def _getProfilePath(self, profile):
"""Return a unique path for profile's mailbox
The path must be unique, usable as a dir name, and bijectional"""
return profile.replace('/','_').replace('..','_') #FIXME: this is too naive to work well, must be improved
return profile.replace('/', '_').replace('..', '_') # FIXME: this is too naive to work well, must be improved
def _removeBoxAccess(self, boxname, mailboxUser, profile):
"""Remove a reference to a box
@param name: name of the box
@param mailboxUser: MailboxUser instance"""
if not self.__mailboxes.has_key(boxname):
err_msg=_("Trying to remove an mailboxUser not referenced")
if boxname not in self.__mailboxes:
err_msg = _("Trying to remove an mailboxUser not referenced")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
assert self.__mailboxes[profile][boxname]==mailboxUser
assert self.__mailboxes[profile][boxname] == mailboxUser
del __mailboxes[profile][boxname]
def _checkBoxReference(self, boxname, profile):
"""Check if there is a reference on a box, and return it
@param boxname: name of the box to check
@return: MailboxUser instance or None"""
if self.__mailboxes.has_key(profile):
if self.__mailboxes[profile].has_key(boxname):
if profile in self.__mailboxes:
if boxname in self.__mailboxes[profile]:
return self.__mailboxes[profile][boxname]
def __getBoxData(self, boxname, profile):
"""Return the date of a box"""
try:
return self.data[profile][boxname] #the boxname MUST exist in the data
return self.data[profile][boxname] # the boxname MUST exist in the data
except KeyError:
err_msg=_("Boxname doesn't exist in internal data")
err_msg = _("Boxname doesn't exist in internal data")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
@ -155,11 +156,11 @@ class MaildirBox(object):
@param message_id: unique id of the message as given by MaildirMailbox
@return: Integer UID"""
box_data = self.__getBoxData(boxname, profile)
if box_data.has_key(message_id):
if message_id in box_data:
ret = box_data[message_id][0]
else:
box_data['cur_idx']+=1
box_data[message_id]=[box_data['cur_idx'],[]]
box_data['cur_idx'] += 1
box_data[message_id] = [box_data['cur_idx'], []]
ret = box_data[message_id]
self.data[profile].force(boxname)
return ret
@ -170,7 +171,7 @@ class MaildirBox(object):
@param boxname: name of the box where the message is
@return: Integer UID"""
box_data = self.__getBoxData(boxname, profile)
return box_data['cur_idx']+1
return box_data['cur_idx'] + 1
def getNextExistingUid(self, boxname, uid, profile):
"""Give the next uid of existing message
@ -178,10 +179,10 @@ class MaildirBox(object):
@param uid: uid to start from
@return: uid or None if the is no more message"""
box_data = self.__getBoxData(boxname, profile)
idx=uid+1
while self.getIdFromUid(boxname, idx, profile) == None: #TODO: this is highly inefficient because getIdfromUid is inefficient, fix this
idx+=1
if idx>box_data['cur_idx']:
idx = uid + 1
while self.getIdFromUid(boxname, idx, profile) is None: # TODO: this is highly inefficient because getIdfromUid is inefficient, fix this
idx += 1
if idx > box_data['cur_idx']:
return None
return idx
@ -198,7 +199,7 @@ class MaildirBox(object):
@param message_uid: unique integer identifier
@return: unique id of the message as given by MaildirMailbox or None if not found"""
box_data = self.__getBoxData(boxname, profile)
for message_id in box_data.keys(): #TODO: this is highly inefficient on big mailbox, must be replaced in the future
for message_id in box_data.keys(): # TODO: this is highly inefficient on big mailbox, must be replaced in the future
if message_id == 'cur_idx':
continue
if box_data[message_id][0] == message_uid:
@ -211,7 +212,7 @@ class MaildirBox(object):
@param message_idx: message id as given by MaildirMailbox
@return: list of strings"""
box_data = self.__getBoxData(boxname, profile)
if not box_data.has_key(mess_id):
if mess_id not in box_data:
raise MailboxException("Trying to get flags from an unexisting message")
return box_data[mess_id][1]
@ -222,11 +223,11 @@ class MaildirBox(object):
@param flags: list of strings
"""
box_data = self.__getBoxData(boxname, profile)
assert(type(flags)==list)
flags=[flag.upper() for flag in flags] #we store every flag UPPERCASE
if not box_data.has_key(mess_id):
assert(type(flags) == list)
flags = [flag.upper() for flag in flags] # we store every flag UPPERCASE
if mess_id not in box_data:
raise MailboxException("Trying to set flags for an unexisting message")
box_data[mess_id][1]=flags
box_data[mess_id][1] = flags
self.data[profile].force(boxname)
def getMessageIdsWithFlag(self, boxname, flag, profile):
@ -235,11 +236,11 @@ class MaildirBox(object):
@param flag: flag to check
@return: list of id (as given by MaildirMailbox)"""
box_data = self.__getBoxData(boxname, profile)
assert(isinstance(flag,basestring))
flag=flag.upper()
assert(isinstance(flag, basestring))
flag = flag.upper()
result = []
for key in box_data:
if key=='cur_idx':
if key == 'cur_idx':
continue
if flag in box_data[key][1]:
result.append(key)
@ -250,8 +251,8 @@ class MaildirBox(object):
@param boxname: name of the box where the message is
"""
box_data = self.__getBoxData(boxname, profile)
for mess_id in self.getMessageIdsWithFlag(boxname,"\\Deleted", profile):
del(box_data[mess_id])
for mess_id in self.getMessageIdsWithFlag(boxname, "\\Deleted", profile):
del(box_data[mess_id])
self.data[profile].force(boxname)
def cleanTable(self, boxname, existant_id, profile):
@ -259,9 +260,9 @@ class MaildirBox(object):
@param boxname: name of the box to clean
@param existant_id: list of id which actually exist"""
box_data = self.__getBoxData(boxname, profile)
to_remove=[]
to_remove = []
for key in box_data:
if key not in existant_id and key!="cur_idx":
if key not in existant_id and key != "cur_idx":
to_remove.append(key)
for key in to_remove:
del box_data[key]
@ -271,34 +272,34 @@ class MaildirBox(object):
@param callback: method to call when the the box is updated
@param boxname: name of the box to observe
@param signal: which signal is observed by the caller"""
if not self.__observed.has_key((profile,boxname)):
self.__observed[(profile,boxname)]={}
if not self.__observed[(profile,boxname)].has_key(signal):
self.__observed[(profile,boxname)][signal]=set()
self.__observed[(profile,boxname)][signal].add(callback)
if (profile, boxname) not in self.__observed:
self.__observed[(profile, boxname)] = {}
if signal not in self.__observed[(profile, boxname)]:
self.__observed[(profile, boxname)][signal] = set()
self.__observed[(profile, boxname)][signal].add(callback)
def removeObserver(self, callback, profile, boxname, signal="NEW_MESSAGE"):
"""Remove an observer of maildir box changes
@param callback: method to remove from obervers
@param boxname: name of the box which was observed
@param signal: which signal was observed by the caller"""
if not self.__observed.has_key((profile,boxname)):
err_msg=_("Trying to remove an observer for an inexistant mailbox")
if (profile, boxname) not in self.__observed:
err_msg = _("Trying to remove an observer for an inexistant mailbox")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
if not self.__observed[(profile,boxname)].has_key(signal):
err_msg=_("Trying to remove an inexistant observer, no observer for this signal")
if signal not in self.__observed[(profile, boxname)]:
err_msg = _("Trying to remove an inexistant observer, no observer for this signal")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
if not callback in self.__observed[(profile,boxname)][signal]:
err_msg=_("Trying to remove an inexistant observer")
if not callback in self.__observed[(profile, boxname)][signal]:
err_msg = _("Trying to remove an inexistant observer")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
self.__observed[(profile,boxname)][signal].remove(callback)
self.__observed[(profile, boxname)][signal].remove(callback)
def emitSignal(self, profile, boxname, signal_name):
"""Emit the signal to observer"""
debug('emitSignal %s %s %s' %(profile, boxname, signal_name))
debug('emitSignal %s %s %s' % (profile, boxname, signal_name))
try:
for observer_cb in self.__observed[(profile, boxname)][signal_name]:
observer_cb()
@ -325,7 +326,7 @@ class MailboxUser(object):
if e.name == "body":
mail.set_payload(e.children[0].encode('utf-8'))
elif e.name == "subject":
mail['Subject'] = e.children[0].encode('utf-8')
mail['Subject'] = e.children[0].encode('utf-8')
return mail.as_string()
def __init__(self, _maildir, name, observer=None, profile="@NONE@"):
@ -334,36 +335,35 @@ class MailboxUser(object):
@param profile: real profile (ie not a profile_key)
THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead"""
if _maildir._checkBoxReference(name, profile):
error ("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly")
error("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly")
raise MailboxException('double MailboxUser instanciation')
if name!="INBOX":
if name != "INBOX":
raise NotImplementedError
self.name=name
self.profile=profile
self.maildir=_maildir
self.name = name
self.profile = profile
self.maildir = _maildir
profile_path = self.maildir._getProfilePath(profile)
full_profile_path = os.path.join(self.maildir.host.memory.getConfig('','local_dir'), profile_path)
full_profile_path = os.path.join(self.maildir.host.memory.getConfig('', 'local_dir'), profile_path)
if not os.path.exists(full_profile_path):
os.makedirs(full_profile_path,0700)
os.makedirs(full_profile_path, 0700)
mailbox_path = os.path.join(full_profile_path, MAILDIR_PATH)
self.mailbox_path=mailbox_path
self.mailbox_path = mailbox_path
self.mailbox = maildir.MaildirMailbox(mailbox_path)
self.observer=observer
self.observer = observer
self.__uid_table_update()
if observer:
debug("adding observer for %s (%s)" % (name,profile))
debug("adding observer for %s (%s)" % (name, profile))
self.maildir.addObserver(observer, profile, name, "NEW_MESSAGE")
def __uid_table_update(self):
existant_id=[]
for mess_idx in range (self.getMessageCount()):
existant_id = []
for mess_idx in range(self.getMessageCount()):
#we update the uid table
existant_id.append(self.getId(mess_idx))
self.getUid(mess_idx)
self.maildir.cleanTable(self.name, existant_id, profile=self.profile)
def __del__(self):
if observer:
debug("removing observer for %s" % self.name)
@ -377,8 +377,8 @@ class MailboxUser(object):
def emitSignal(self, ignore, signal):
"""Emit the signal to the observers"""
if signal=="NEW_MESSAGE":
self.getUid(self.getMessageCount()-1) #XXX: we make an uid for the last message added
if signal == "NEW_MESSAGE":
self.getUid(self.getMessageCount() - 1) # XXX: we make an uid for the last message added
self.maildir.emitSignal(self.profile, self.name, signal)
def getId(self, mess_idx):
@ -388,8 +388,8 @@ class MailboxUser(object):
def getUid(self, mess_idx):
"""Return a unique interger id for the message, always ascending"""
mess_id=self.getId(mess_idx)
return self.maildir.getUid(self.name,mess_id, profile=self.profile)
mess_id = self.getId(mess_idx)
return self.maildir.getUid(self.name, mess_id, profile=self.profile)
def getNextUid(self):
return self.maildir.getNextUid(self.name, profile=self.profile)
@ -413,7 +413,7 @@ class MailboxUser(object):
"""Return the message index from the uid
@param mess_uid: message unique identifier
@return: message index, as managed by MaildirMailbox"""
for mess_idx in range (self.getMessageCount()):
for mess_idx in range(self.getMessageCount()):
if self.getUid(mess_idx) == mess_uid:
return mess_idx
raise IndexError
@ -422,7 +422,7 @@ class MailboxUser(object):
"""Return the message index from the unique index
@param mess_id: message unique index as given by MaildirMailbox
@return: message sequence index"""
for mess_idx in range (self.getMessageCount()):
for mess_idx in range(self.getMessageCount()):
if self.mailbox.getUidl(mess_idx) == mess_id:
return mess_idx
raise IndexError
@ -448,7 +448,7 @@ class MailboxUser(object):
"""Return the flags of the message
@param mess_uid: message unique identifier
@return: list of strings"""
id = self.maildir.getIdFromUid(self.name,mess_uid, profile=self.profile)
id = self.maildir.getIdFromUid(self.name, mess_uid, profile=self.profile)
return self.maildir.getFlags(self.name, id, profile=self.profile)
def setFlags(self, mess_idx, flags):
@ -464,14 +464,14 @@ class MailboxUser(object):
@param mess_uid: message unique identifier
@param flags: list of strings
"""
id = self.maildir.getIdFromUid(self.name,mess_uid, profile=self.profile)
id = self.maildir.getIdFromUid(self.name, mess_uid, profile=self.profile)
return self.maildir.setFlags(self.name, id, flags, profile=self.profile)
def getMessageIdsWithFlag(self, flag):
"""Return ids of messages where a flag is set
@param flag: flag to check
@return: list of id (as given by MaildirMailbox)"""
return self.maildir.getMessageIdsWithFlag(self.name,flag, profile=self.profile)
return self.maildir.getMessageIdsWithFlag(self.name, flag, profile=self.profile)
def removeDeleted(self):
"""Actually delete message flagged "\\Deleted"
@ -480,11 +480,10 @@ class MailboxUser(object):
for mess_id in self.getMessageIdsWithFlag("\\Deleted"):
print ("Deleting %s" % mess_id)
self.mailbox.deleteMessage(self.getIdxFromId(mess_id))
self.mailbox = maildir.MaildirMailbox(self.mailbox_path) #We need to reparse the dir to have coherent indexing
self.mailbox = maildir.MaildirMailbox(self.mailbox_path) # We need to reparse the dir to have coherent indexing
self.maildir.purgeDeleted(self.name, profile=self.profile)
def emptyTrash(self):
"""Delete everything in the .Trash dir"""
import shutils
pdb.set_trace()