/offlineimap/head: changeset 205

Better handling of read-only folders. We will now warn if there is a
change, but not propogate it. New config variable ignore-readonly can
suppress the warnings. This fixes [complete.org #10] and, for Debian,
Closes: #154769. changelog: noted the change IMAP.py: trap
imapobj.readonly more often UIBase.py: new methods to handle the
warnings offlineimap.conf: new ignore-readonly variable.
This commit is contained in:
jgoerzen 2002-08-08 02:57:17 +01:00
parent 3b4c306f5d
commit a3f422cf98
4 changed files with 50 additions and 4 deletions

View File

@ -3,6 +3,10 @@ offlineimap (3.2.2) unstable; urgency=low
* Updated manual to show new Gray color. * Updated manual to show new Gray color.
* Scrolling behavior is better now; sometimes, with fast-scrolling text, * Scrolling behavior is better now; sometimes, with fast-scrolling text,
the log would stop scrolling. the log would stop scrolling.
* Better handling of read-only folders. We will now warn if there is
a change, but not propogate it. New config variable ignore-readonly
can suppress the warnings. This fixes [complete.org #10] and,
for Debian, Closes: #154769.
-- John Goerzen <jgoerzen@complete.org> Thu, 25 Jul 2002 08:22:25 -0500 -- John Goerzen <jgoerzen@complete.org> Thu, 25 Jul 2002 08:22:25 -0500

View File

@ -66,6 +66,14 @@ maxsyncaccounts = 1
ui = Tk.Blinkenlights, Tk.VerboseUI, TTY.TTYUI, Noninteractive.Basic, ui = Tk.Blinkenlights, Tk.VerboseUI, TTY.TTYUI, Noninteractive.Basic,
Noninteractive.Quiet Noninteractive.Quiet
# If you try to synchronize messages to a read-only folder,
# OfflineIMAP will generate a warning. If you want to suppress these
# warnings, set ignore-readonly to yes. Read-only IMAP folders allow
# reading but not modification, so if you try to change messages in
# the local copy of such a folder, the IMAP server will prevent
# OfflineIMAP from propogating those changes to the IMAP server.
ignore-readonly = no
################################################## ##################################################
# Mailbox name recorder # Mailbox name recorder

View File

@ -98,7 +98,13 @@ class IMAPFolder(BaseFolder):
def savemessage(self, uid, content, flags): def savemessage(self, uid, content, flags):
imapobj = self.imapserver.acquireconnection() imapobj = self.imapserver.acquireconnection()
try: try:
imapobj.select(self.getfullname()) # Needed for search try:
imapobj.select(self.getfullname()) # Needed for search
except imapobj.readonly:
__main__.ui.msgtoreadonly(self, uid, content, flags)
# Return indicating message taken, but no UID assigned.
# Fudge it.
return 0
# This backend always assigns a new uid, so the uid arg is ignored. # This backend always assigns a new uid, so the uid arg is ignored.
# In order to get the new uid, we need to save off the message ID. # In order to get the new uid, we need to save off the message ID.
@ -147,7 +153,11 @@ class IMAPFolder(BaseFolder):
def savemessageflags(self, uid, flags): def savemessageflags(self, uid, flags):
imapobj = self.imapserver.acquireconnection() imapobj = self.imapserver.acquireconnection()
try: try:
imapobj.select(self.getfullname()) try:
imapobj.select(self.getfullname())
except imapobj.readonly:
__main__.ui.flagstoreadonly(self, [uid], flags)
return
result = imapobj.uid('store', '%d' % uid, 'FLAGS', result = imapobj.uid('store', '%d' % uid, 'FLAGS',
imaputil.flagsmaildir2imap(flags)) imaputil.flagsmaildir2imap(flags))
assert result[0] == 'OK', 'Error with store: ' + r[1] assert result[0] == 'OK', 'Error with store: ' + r[1]
@ -166,7 +176,11 @@ class IMAPFolder(BaseFolder):
def addmessagesflags(self, uidlist, flags): def addmessagesflags(self, uidlist, flags):
imapobj = self.imapserver.acquireconnection() imapobj = self.imapserver.acquireconnection()
try: try:
imapobj.select(self.getfullname()) try:
imapobj.select(self.getfullname())
except imapobj.readonly:
__main__.ui.flagstoreadonly(self, uidlist, flags)
return
r = imapobj.uid('store', r = imapobj.uid('store',
imaputil.listjoin(uidlist), imaputil.listjoin(uidlist),
'+FLAGS', '+FLAGS',
@ -213,7 +227,11 @@ class IMAPFolder(BaseFolder):
self.addmessagesflags(uidlist, ['T']) self.addmessagesflags(uidlist, ['T'])
imapobj = self.imapserver.acquireconnection() imapobj = self.imapserver.acquireconnection()
try: try:
imapobj.select(self.getfullname()) try:
imapobj.select(self.getfullname())
except imapobj.readonly:
__main__.ui.deletereadonly(self, uidlist)
return
assert(imapobj.expunge()[0] == 'OK') assert(imapobj.expunge()[0] == 'OK')
finally: finally:
self.imapserver.releaseconnection(imapobj) self.imapserver.releaseconnection(imapobj)

View File

@ -53,6 +53,22 @@ class UIBase:
def folderlist(s, list): def folderlist(s, list):
return ', '.join(["%s[%s]" % (s.getnicename(x), x.getname()) for x in list]) return ', '.join(["%s[%s]" % (s.getnicename(x), x.getname()) for x in list])
################################################## WARNINGS
def msgtoreadonly(s, destfolder, uid, content, flags):
if not (config.has_option('general', 'ignore-readonly') and config.getboolean("general", "ignore-readonly")):
s.warn("Attempted to synchronize message %d to folder %s[%s], but that folder is read-only. The message will not be copied to that folder." % \
(uid, s.getnicename(destfolder), destfolder.getname()))
def flagstoreadonly(s, destfolder, uidlist, flags):
if not (config.has_option('general', 'ignore-readonly') and config.getboolean("general", "ignore-readonly")):
s.warn("Attempted to modify flags for messages %s in folder %s[%s], but that folder is read-only. No flags have been modified for that message." % \
(str(uidlist), s.getnicename(destfolder), destfolder.getname()))
def deletereadonly(s, destfolder, uidlist):
if not (config.has_option('general', 'ignore-readonly') and config.getboolean("general", "ignore-readonly")):
s.warn("Attempted to delete messages %s in folder %s[%s], but that folder is read-only. No messages have been deleted in that folder." % \
(str(uidlist), s.getnicename(destfolder), destfolder.getname()))
################################################## MESSAGES ################################################## MESSAGES
def init_banner(s): def init_banner(s):