Remove Gmail realdelete option

It can lead to potential dataloss (see recent commit log where I added a
scary warning about it to offlineimap.conf).

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2012-02-04 21:08:44 +01:00
parent e351ab736c
commit 51728ed815
3 changed files with 9 additions and 52 deletions

View File

@ -531,21 +531,6 @@ type = Gmail
# Specify the Gmail user name. This is the only mandatory parameter. # Specify the Gmail user name. This is the only mandatory parameter.
remoteuser = username@gmail.com remoteuser = username@gmail.com
# WARNING: READ THIS BEFORE CONSIDERING TO CHANGE IT! Deleting a
# message from a Gmail folder via the IMAP interface will just remove
# that folder's label from the message: the message will continue to
# exist in the '[Gmail]/All Mail' folder. If `realdelete` is set to
# `True`, then deleted messages will be moved to the '[Gmail]/Trash'
# folder. BEWARE: this will immediately delete a messages from *all
# folders* it belongs to! AS OFFLINEIMAP IMPLEMENTS FOLDER MOVES AS 1)
# AN ADD and 2) A DELETE (the order can vary), THIS MEANS THAT A FOLDER
# MOVE CAN CAUSE DATALOSS. DO NOT USE IT AND MOVE MAIL TO
# "[Gmail]/Trash" TO DELETE MAIL FROM "[Gmail]/All Mail"! See the
# analysis at
# http://article.gmane.org/gmane.mail.imap.offlineimap.general/5265 See
# http://mail.google.com/support/bin/answer.py?answer=77657&topic=12815
# realdelete = no !!!READ ABOVE BEFORE USING
# The trash folder name may be different from [Gmail]/Trash # The trash folder name may be different from [Gmail]/Trash
# for example on german googlemail, this setting should be # for example on german googlemail, this setting should be
# #

View File

@ -18,16 +18,18 @@
"""Folder implementation to support features of the Gmail IMAP server. """Folder implementation to support features of the Gmail IMAP server.
""" """
from IMAP import IMAPFolder from IMAP import IMAPFolder
from offlineimap import imaputil
class GmailFolder(IMAPFolder): class GmailFolder(IMAPFolder):
"""Folder implementation to support features of the Gmail IMAP server. """Folder implementation to support features of the Gmail IMAP server.
Specifically, deleted messages are moved to folder `Gmail.TRASH_FOLDER`
(by default: ``[Gmail]/Trash``) prior to expunging them, since Removing a message from a folder will only remove the "label" from
Gmail maps to IMAP ``EXPUNGE`` command to "remove label". the message and keep it in the "All mails" folder. To really delete
a message it needs to be copied to the Trash folder. However, this
is dangerous as our folder moves are implemented as a 1) delete in
one folder and 2) append to the other. If 2 comes before 1, this
will effectively delete the message from all folders. So we cannot
do that until we have a smarter folder move mechanism.
For more information on the Gmail IMAP server: For more information on the Gmail IMAP server:
http://mail.google.com/support/bin/answer.py?answer=77657&topic=12815 http://mail.google.com/support/bin/answer.py?answer=77657&topic=12815
@ -35,31 +37,6 @@ class GmailFolder(IMAPFolder):
def __init__(self, imapserver, name, repository): def __init__(self, imapserver, name, repository):
super(GmailFolder, self).__init__(imapserver, name, repository) super(GmailFolder, self).__init__(imapserver, name, repository)
self.realdelete = repository.getrealdelete(name)
self.trash_folder = repository.gettrashfolder(name) self.trash_folder = repository.gettrashfolder(name)
#: Gmail will really delete messages upon EXPUNGE in these folders # Gmail will really delete messages upon EXPUNGE in these folders
self.real_delete_folders = [ self.trash_folder, repository.getspamfolder() ] self.real_delete_folders = [ self.trash_folder, repository.getspamfolder() ]
def deletemessages_noconvert(self, uidlist):
uidlist = [uid for uid in uidlist if uid in self.messagelist]
if not len(uidlist):
return
if self.realdelete and not (self.getname() in self.real_delete_folders):
# IMAP expunge is just "remove label" in this folder,
# so map the request into a "move into Trash"
imapobj = self.imapserver.acquireconnection()
try:
imapobj.select(self.getfullname())
result = imapobj.uid('copy',
imaputil.uid_sequence(uidlist),
self.trash_folder)
assert result[0] == 'OK', \
"Bad IMAPlib result: %s" % result[0]
finally:
self.imapserver.releaseconnection(imapobj)
for uid in uidlist:
del self.messagelist[uid]
else:
IMAPFolder.deletemessages_noconvert(self, uidlist)

View File

@ -64,11 +64,6 @@ class GmailRepository(IMAPRepository):
def getfoldertype(self): def getfoldertype(self):
return folder.Gmail.GmailFolder return folder.Gmail.GmailFolder
def getrealdelete(self, foldername):
# XXX: `foldername` is currently ignored - the `realdelete`
# setting is repository-wide
return self.getconfboolean('realdelete', 0)
def gettrashfolder(self, foldername): def gettrashfolder(self, foldername):
#: Where deleted mail should be moved #: Where deleted mail should be moved
return self.getconf('trashfolder','[Gmail]/Trash') return self.getconf('trashfolder','[Gmail]/Trash')