Merge branch 'ss/ui' into next
Conflicts: offlineimap/folder/IMAP.py Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
commit
ee8a00cce2
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
from offlineimap import threadutil, mbnames, CustomConfig
|
from offlineimap import threadutil, mbnames, CustomConfig
|
||||||
import offlineimap.repository.Base, offlineimap.repository.LocalStatus
|
import offlineimap.repository.Base, offlineimap.repository.LocalStatus
|
||||||
from offlineimap.ui import UIBase
|
from offlineimap.ui import getglobalui
|
||||||
from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
|
from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
from threading import Event, Lock
|
from threading import Event, Lock
|
||||||
@ -110,7 +110,7 @@ class Account(CustomConfig.ConfigHelperMixin):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.metadatadir = config.getmetadatadir()
|
self.metadatadir = config.getmetadatadir()
|
||||||
self.localeval = config.getlocaleval()
|
self.localeval = config.getlocaleval()
|
||||||
self.ui = UIBase.getglobalui()
|
self.ui = getglobalui()
|
||||||
self.refreshperiod = self.getconffloat('autorefresh', 0.0)
|
self.refreshperiod = self.getconffloat('autorefresh', 0.0)
|
||||||
self.quicknum = 0
|
self.quicknum = 0
|
||||||
if self.refreshperiod == 0.0:
|
if self.refreshperiod == 0.0:
|
||||||
@ -288,7 +288,7 @@ class SyncableAccount(Account, AccountSynchronizationMixin):
|
|||||||
def syncfolder(accountname, remoterepos, remotefolder, localrepos,
|
def syncfolder(accountname, remoterepos, remotefolder, localrepos,
|
||||||
statusrepos, quick):
|
statusrepos, quick):
|
||||||
global mailboxes
|
global mailboxes
|
||||||
ui = UIBase.getglobalui()
|
ui = getglobalui()
|
||||||
ui.registerthread(accountname)
|
ui.registerthread(accountname)
|
||||||
try:
|
try:
|
||||||
# Load local folder.
|
# Load local folder.
|
||||||
|
@ -19,13 +19,15 @@
|
|||||||
from threading import *
|
from threading import *
|
||||||
from offlineimap import threadutil
|
from offlineimap import threadutil
|
||||||
from offlineimap.threadutil import InstanceLimitedThread
|
from offlineimap.threadutil import InstanceLimitedThread
|
||||||
from offlineimap.ui import UIBase
|
from offlineimap.ui import getglobalui
|
||||||
import os.path, re
|
import os.path
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class BaseFolder:
|
class BaseFolder:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.uidlock = Lock()
|
self.uidlock = Lock()
|
||||||
|
self.ui = getglobalui()
|
||||||
|
|
||||||
def getname(self):
|
def getname(self):
|
||||||
"""Returns name"""
|
"""Returns name"""
|
||||||
@ -202,8 +204,8 @@ class BaseFolder:
|
|||||||
|
|
||||||
def syncmessagesto_neguid_msg(self, uid, dest, applyto, register = 1):
|
def syncmessagesto_neguid_msg(self, uid, dest, applyto, register = 1):
|
||||||
if register:
|
if register:
|
||||||
UIBase.getglobalui().registerthread(self.getaccountname())
|
self.ui.registerthread(self.getaccountname())
|
||||||
UIBase.getglobalui().copyingmessage(uid, self, applyto)
|
self.ui.copyingmessage(uid, self, applyto)
|
||||||
successobject = None
|
successobject = None
|
||||||
successuid = None
|
successuid = None
|
||||||
message = self.getmessage(uid)
|
message = self.getmessage(uid)
|
||||||
@ -269,8 +271,8 @@ class BaseFolder:
|
|||||||
# really needed.
|
# really needed.
|
||||||
try:
|
try:
|
||||||
if register:
|
if register:
|
||||||
UIBase.getglobalui().registerthread(self.getaccountname())
|
self.ui.registerthread(self.getaccountname())
|
||||||
UIBase.getglobalui().copyingmessage(uid, self, applyto)
|
self.ui.copyingmessage(uid, self, applyto)
|
||||||
message = ''
|
message = ''
|
||||||
# If any of the destinations actually stores the message body,
|
# If any of the destinations actually stores the message body,
|
||||||
# load it up.
|
# load it up.
|
||||||
@ -289,7 +291,7 @@ class BaseFolder:
|
|||||||
self.deletemessage(uid)
|
self.deletemessage(uid)
|
||||||
uid = newuid
|
uid = newuid
|
||||||
except:
|
except:
|
||||||
UIBase.getglobalui().warn("ERROR attempting to copy message " + str(uid) \
|
self.ui.warn("ERROR attempting to copy message " + str(uid) \
|
||||||
+ " for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
|
+ " for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
|
||||||
|
|
||||||
|
|
||||||
@ -334,7 +336,7 @@ class BaseFolder:
|
|||||||
if not uid in self_messagelist:
|
if not uid in self_messagelist:
|
||||||
deletelist.append(uid)
|
deletelist.append(uid)
|
||||||
if len(deletelist):
|
if len(deletelist):
|
||||||
UIBase.getglobalui().deletingmessages(deletelist, applyto)
|
self.ui.deletingmessages(deletelist, applyto)
|
||||||
for object in applyto:
|
for object in applyto:
|
||||||
object.deletemessages(deletelist)
|
object.deletemessages(deletelist)
|
||||||
|
|
||||||
@ -375,10 +377,10 @@ class BaseFolder:
|
|||||||
|
|
||||||
for object in applyto:
|
for object in applyto:
|
||||||
for flag in addflaglist.keys():
|
for flag in addflaglist.keys():
|
||||||
UIBase.getglobalui().addingflags(addflaglist[flag], flag, [object])
|
self.ui.addingflags(addflaglist[flag], flag, [object])
|
||||||
object.addmessagesflags(addflaglist[flag], [flag])
|
object.addmessagesflags(addflaglist[flag], [flag])
|
||||||
for flag in delflaglist.keys():
|
for flag in delflaglist.keys():
|
||||||
UIBase.getglobalui().deletingflags(delflaglist[flag], flag, [object])
|
self.ui.deletingflags(delflaglist[flag], flag, [object])
|
||||||
object.deletemessagesflags(delflaglist[flag], [flag])
|
object.deletemessagesflags(delflaglist[flag], [flag])
|
||||||
|
|
||||||
def syncmessagesto(self, dest, applyto = None):
|
def syncmessagesto(self, dest, applyto = None):
|
||||||
@ -394,7 +396,7 @@ class BaseFolder:
|
|||||||
try:
|
try:
|
||||||
self.syncmessagesto_neguid(dest, applyto)
|
self.syncmessagesto_neguid(dest, applyto)
|
||||||
except:
|
except:
|
||||||
UIBase.getglobalui().warn("ERROR attempting to handle negative uids " \
|
self.ui.warn("ERROR attempting to handle negative uids " \
|
||||||
+ "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
|
+ "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
|
||||||
|
|
||||||
#all threads launched here are in try / except clauses when they copy anyway...
|
#all threads launched here are in try / except clauses when they copy anyway...
|
||||||
@ -403,7 +405,7 @@ class BaseFolder:
|
|||||||
try:
|
try:
|
||||||
self.syncmessagesto_delete(dest, applyto)
|
self.syncmessagesto_delete(dest, applyto)
|
||||||
except:
|
except:
|
||||||
UIBase.getglobalui().warn("ERROR attempting to delete messages " \
|
self.ui.warn("ERROR attempting to delete messages " \
|
||||||
+ "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
|
+ "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
|
||||||
|
|
||||||
# Now, the message lists should be identical wrt the uids present.
|
# Now, the message lists should be identical wrt the uids present.
|
||||||
@ -413,7 +415,7 @@ class BaseFolder:
|
|||||||
try:
|
try:
|
||||||
self.syncmessagesto_flags(dest, applyto)
|
self.syncmessagesto_flags(dest, applyto)
|
||||||
except:
|
except:
|
||||||
UIBase.getglobalui().warn("ERROR attempting to sync flags " \
|
self.ui.warn("ERROR attempting to sync flags " \
|
||||||
+ "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
|
+ "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,12 +22,11 @@ import string
|
|||||||
import random
|
import random
|
||||||
import binascii
|
import binascii
|
||||||
import re
|
import re
|
||||||
|
import time
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
from copy import copy
|
from copy import copy
|
||||||
import time
|
|
||||||
from Base import BaseFolder
|
from Base import BaseFolder
|
||||||
from offlineimap import imaputil, imaplibutil, __version__
|
from offlineimap import imaputil, imaplibutil, __version__
|
||||||
from offlineimap.ui import UIBase
|
|
||||||
|
|
||||||
class IMAPFolder(BaseFolder):
|
class IMAPFolder(BaseFolder):
|
||||||
def __init__(self, imapserver, name, visiblename, accountname, repository):
|
def __init__(self, imapserver, name, visiblename, accountname, repository):
|
||||||
@ -43,6 +42,7 @@ class IMAPFolder(BaseFolder):
|
|||||||
self.repository = repository
|
self.repository = repository
|
||||||
self.randomgenerator = random.Random()
|
self.randomgenerator = random.Random()
|
||||||
BaseFolder.__init__(self)
|
BaseFolder.__init__(self)
|
||||||
|
#self.ui is set in BaseFolder
|
||||||
|
|
||||||
def selectro(self, imapobj):
|
def selectro(self, imapobj):
|
||||||
"""Select this folder when we do not need write access.
|
"""Select this folder when we do not need write access.
|
||||||
@ -190,7 +190,7 @@ class IMAPFolder(BaseFolder):
|
|||||||
messagestr = string.split(messagestr, maxsplit = 1)[1]
|
messagestr = string.split(messagestr, maxsplit = 1)[1]
|
||||||
options = imaputil.flags2hash(messagestr)
|
options = imaputil.flags2hash(messagestr)
|
||||||
if not options.has_key('UID'):
|
if not options.has_key('UID'):
|
||||||
UIBase.getglobalui().warn('No UID in message with options %s' %\
|
self.ui.warn('No UID in message with options %s' %\
|
||||||
str(options),
|
str(options),
|
||||||
minor = 1)
|
minor = 1)
|
||||||
else:
|
else:
|
||||||
@ -203,12 +203,11 @@ class IMAPFolder(BaseFolder):
|
|||||||
return self.messagelist
|
return self.messagelist
|
||||||
|
|
||||||
def getmessage(self, uid):
|
def getmessage(self, uid):
|
||||||
ui = UIBase.getglobalui()
|
|
||||||
imapobj = self.imapserver.acquireconnection()
|
imapobj = self.imapserver.acquireconnection()
|
||||||
try:
|
try:
|
||||||
imapobj.select(self.getfullname(), readonly = 1)
|
imapobj.select(self.getfullname(), readonly = 1)
|
||||||
initialresult = imapobj.uid('fetch', '%d' % uid, '(BODY.PEEK[])')
|
initialresult = imapobj.uid('fetch', '%d' % uid, '(BODY.PEEK[])')
|
||||||
ui.debug('imap', 'Returned object from fetching %d: %s' % \
|
self.ui.debug('imap', 'Returned object from fetching %d: %s' % \
|
||||||
(uid, str(initialresult)))
|
(uid, str(initialresult)))
|
||||||
return initialresult[1][0][1].replace("\r\n", "\n")
|
return initialresult[1][0][1].replace("\r\n", "\n")
|
||||||
|
|
||||||
@ -232,31 +231,29 @@ class IMAPFolder(BaseFolder):
|
|||||||
return (headername, headervalue)
|
return (headername, headervalue)
|
||||||
|
|
||||||
def savemessage_addheader(self, content, headername, headervalue):
|
def savemessage_addheader(self, content, headername, headervalue):
|
||||||
ui = UIBase.getglobalui()
|
self.ui.debug('imap',
|
||||||
ui.debug('imap',
|
|
||||||
'savemessage_addheader: called to add %s: %s' % (headername,
|
'savemessage_addheader: called to add %s: %s' % (headername,
|
||||||
headervalue))
|
headervalue))
|
||||||
insertionpoint = content.find("\r\n")
|
insertionpoint = content.find("\r\n")
|
||||||
ui.debug('imap', 'savemessage_addheader: insertionpoint = %d' % insertionpoint)
|
self.ui.debug('imap', 'savemessage_addheader: insertionpoint = %d' % insertionpoint)
|
||||||
leader = content[0:insertionpoint]
|
leader = content[0:insertionpoint]
|
||||||
ui.debug('imap', 'savemessage_addheader: leader = %s' % repr(leader))
|
self.ui.debug('imap', 'savemessage_addheader: leader = %s' % repr(leader))
|
||||||
if insertionpoint == 0 or insertionpoint == -1:
|
if insertionpoint == 0 or insertionpoint == -1:
|
||||||
newline = ''
|
newline = ''
|
||||||
insertionpoint = 0
|
insertionpoint = 0
|
||||||
else:
|
else:
|
||||||
newline = "\r\n"
|
newline = "\r\n"
|
||||||
newline += "%s: %s" % (headername, headervalue)
|
newline += "%s: %s" % (headername, headervalue)
|
||||||
ui.debug('imap', 'savemessage_addheader: newline = ' + repr(newline))
|
self.ui.debug('imap', 'savemessage_addheader: newline = ' + repr(newline))
|
||||||
trailer = content[insertionpoint:]
|
trailer = content[insertionpoint:]
|
||||||
ui.debug('imap', 'savemessage_addheader: trailer = ' + repr(trailer))
|
self.ui.debug('imap', 'savemessage_addheader: trailer = ' + repr(trailer))
|
||||||
return leader + newline + trailer
|
return leader + newline + trailer
|
||||||
|
|
||||||
def savemessage_searchforheader(self, imapobj, headername, headervalue):
|
def savemessage_searchforheader(self, imapobj, headername, headervalue):
|
||||||
if imapobj.untagged_responses.has_key('APPENDUID'):
|
if imapobj.untagged_responses.has_key('APPENDUID'):
|
||||||
return long(imapobj.untagged_responses['APPENDUID'][-1].split(' ')[1])
|
return long(imapobj.untagged_responses['APPENDUID'][-1].split(' ')[1])
|
||||||
|
|
||||||
ui = UIBase.getglobalui()
|
self.ui.debug('imap', 'savemessage_searchforheader called for %s: %s' % \
|
||||||
ui.debug('imap', 'savemessage_searchforheader called for %s: %s' % \
|
|
||||||
(headername, headervalue))
|
(headername, headervalue))
|
||||||
# Now find the UID it got.
|
# Now find the UID it got.
|
||||||
headervalue = imapobj._quote(headervalue)
|
headervalue = imapobj._quote(headervalue)
|
||||||
@ -264,16 +261,16 @@ class IMAPFolder(BaseFolder):
|
|||||||
matchinguids = imapobj.uid('search', 'HEADER', headername, headervalue)[1][0]
|
matchinguids = imapobj.uid('search', 'HEADER', headername, headervalue)[1][0]
|
||||||
except imapobj.error, err:
|
except imapobj.error, err:
|
||||||
# IMAP server doesn't implement search or had a problem.
|
# IMAP server doesn't implement search or had a problem.
|
||||||
ui.debug('imap', "savemessage_searchforheader: got IMAP error '%s' while attempting to UID SEARCH for message with header %s" % (err, headername))
|
self.ui.debug('imap', "savemessage_searchforheader: got IMAP error '%s' while attempting to UID SEARCH for message with header %s" % (err, headername))
|
||||||
return 0
|
return 0
|
||||||
ui.debug('imap', 'savemessage_searchforheader got initial matchinguids: ' + repr(matchinguids))
|
self.ui.debug('imap', 'savemessage_searchforheader got initial matchinguids: ' + repr(matchinguids))
|
||||||
|
|
||||||
if matchinguids == '':
|
if matchinguids == '':
|
||||||
ui.debug('imap', "savemessage_searchforheader: UID SEARCH for message with header %s yielded no results" % headername)
|
self.ui.debug('imap', "savemessage_searchforheader: UID SEARCH for message with header %s yielded no results" % headername)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
matchinguids = matchinguids.split(' ')
|
matchinguids = matchinguids.split(' ')
|
||||||
ui.debug('imap', 'savemessage_searchforheader: matchinguids now ' + \
|
self.ui.debug('imap', 'savemessage_searchforheader: matchinguids now ' + \
|
||||||
repr(matchinguids))
|
repr(matchinguids))
|
||||||
if len(matchinguids) != 1 or matchinguids[0] == None:
|
if len(matchinguids) != 1 or matchinguids[0] == None:
|
||||||
raise ValueError, "While attempting to find UID for message with header %s, got wrong-sized matchinguids of %s" % (headername, str(matchinguids))
|
raise ValueError, "While attempting to find UID for message with header %s, got wrong-sized matchinguids of %s" % (headername, str(matchinguids))
|
||||||
@ -282,13 +279,12 @@ class IMAPFolder(BaseFolder):
|
|||||||
|
|
||||||
def savemessage(self, uid, content, flags, rtime):
|
def savemessage(self, uid, content, flags, rtime):
|
||||||
imapobj = self.imapserver.acquireconnection()
|
imapobj = self.imapserver.acquireconnection()
|
||||||
ui = UIBase.getglobalui()
|
self.ui.debug('imap', 'savemessage: called')
|
||||||
ui.debug('imap', 'savemessage: called')
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
imapobj.select(self.getfullname()) # Needed for search
|
imapobj.select(self.getfullname()) # Needed for search
|
||||||
except imapobj.readonly:
|
except imapobj.readonly:
|
||||||
ui.msgtoreadonly(self, uid, content, flags)
|
self.ui.msgtoreadonly(self, uid, content, flags)
|
||||||
# Return indicating message taken, but no UID assigned.
|
# Return indicating message taken, but no UID assigned.
|
||||||
# Fudge it.
|
# Fudge it.
|
||||||
return 0
|
return 0
|
||||||
@ -326,17 +322,17 @@ class IMAPFolder(BaseFolder):
|
|||||||
# but some IMAP servers nonetheless choke on 1902.
|
# but some IMAP servers nonetheless choke on 1902.
|
||||||
date = imaplib.Time2Internaldate(time.localtime())
|
date = imaplib.Time2Internaldate(time.localtime())
|
||||||
|
|
||||||
ui.debug('imap', 'savemessage: using date ' + str(date))
|
self.ui.debug('imap', 'savemessage: using date ' + str(date))
|
||||||
content = re.sub("(?<!\r)\n", "\r\n", content)
|
content = re.sub("(?<!\r)\n", "\r\n", content)
|
||||||
ui.debug('imap', 'savemessage: initial content is: ' + repr(content))
|
self.ui.debug('imap', 'savemessage: initial content is: ' + repr(content))
|
||||||
|
|
||||||
(headername, headervalue) = self.savemessage_getnewheader(content)
|
(headername, headervalue) = self.savemessage_getnewheader(content)
|
||||||
ui.debug('imap', 'savemessage: new headers are: %s: %s' % \
|
self.ui.debug('imap', 'savemessage: new headers are: %s: %s' % \
|
||||||
(headername, headervalue))
|
(headername, headervalue))
|
||||||
content = self.savemessage_addheader(content, headername,
|
content = self.savemessage_addheader(content, headername,
|
||||||
headervalue)
|
headervalue)
|
||||||
ui.debug('imap', 'savemessage: new content is: ' + repr(content))
|
self.ui.debug('imap', 'savemessage: new content is: ' + repr(content))
|
||||||
ui.debug('imap', 'savemessage: new content length is ' + \
|
self.ui.debug('imap', 'savemessage: new content length is ' + \
|
||||||
str(len(content)))
|
str(len(content)))
|
||||||
|
|
||||||
assert(imapobj.append(self.getfullname(),
|
assert(imapobj.append(self.getfullname(),
|
||||||
@ -347,12 +343,12 @@ class IMAPFolder(BaseFolder):
|
|||||||
assert(imapobj.check()[0] == 'OK')
|
assert(imapobj.check()[0] == 'OK')
|
||||||
|
|
||||||
# Keep trying until we get the UID.
|
# Keep trying until we get the UID.
|
||||||
ui.debug('imap', 'savemessage: first attempt to get new UID')
|
self.ui.debug('imap', 'savemessage: first attempt to get new UID')
|
||||||
uid = self.savemessage_searchforheader(imapobj, headername,
|
uid = self.savemessage_searchforheader(imapobj, headername,
|
||||||
headervalue)
|
headervalue)
|
||||||
# See docs for savemessage in Base.py for explanation of this and other return values
|
# See docs for savemessage in Base.py for explanation of this and other return values
|
||||||
if uid <= 0:
|
if uid <= 0:
|
||||||
ui.debug('imap', 'savemessage: first attempt to get new UID failed. Going to run a NOOP and try again.')
|
self.ui.debug('imap', 'savemessage: first attempt to get new UID failed. Going to run a NOOP and try again.')
|
||||||
assert(imapobj.noop()[0] == 'OK')
|
assert(imapobj.noop()[0] == 'OK')
|
||||||
uid = self.savemessage_searchforheader(imapobj, headername,
|
uid = self.savemessage_searchforheader(imapobj, headername,
|
||||||
headervalue)
|
headervalue)
|
||||||
@ -362,7 +358,7 @@ class IMAPFolder(BaseFolder):
|
|||||||
if uid: # avoid UID FETCH 0 crash happening later on
|
if uid: # avoid UID FETCH 0 crash happening later on
|
||||||
self.messagelist[uid] = {'uid': uid, 'flags': flags}
|
self.messagelist[uid] = {'uid': uid, 'flags': flags}
|
||||||
|
|
||||||
ui.debug('imap', 'savemessage: returning %d' % uid)
|
self.ui.debug('imap', 'savemessage: returning %d' % uid)
|
||||||
return uid
|
return uid
|
||||||
|
|
||||||
def savemessageflags(self, uid, flags):
|
def savemessageflags(self, uid, flags):
|
||||||
@ -371,7 +367,7 @@ class IMAPFolder(BaseFolder):
|
|||||||
try:
|
try:
|
||||||
imapobj.select(self.getfullname())
|
imapobj.select(self.getfullname())
|
||||||
except imapobj.readonly:
|
except imapobj.readonly:
|
||||||
UIBase.getglobalui().flagstoreadonly(self, [uid], flags)
|
self.ui.flagstoreadonly(self, [uid], flags)
|
||||||
return
|
return
|
||||||
result = imapobj.uid('store', '%d' % uid, 'FLAGS',
|
result = imapobj.uid('store', '%d' % uid, 'FLAGS',
|
||||||
imaputil.flagsmaildir2imap(flags))
|
imaputil.flagsmaildir2imap(flags))
|
||||||
@ -415,7 +411,7 @@ class IMAPFolder(BaseFolder):
|
|||||||
try:
|
try:
|
||||||
imapobj.select(self.getfullname())
|
imapobj.select(self.getfullname())
|
||||||
except imapobj.readonly:
|
except imapobj.readonly:
|
||||||
UIBase.getglobalui().flagstoreadonly(self, uidlist, flags)
|
self.ui.flagstoreadonly(self, uidlist, flags)
|
||||||
return
|
return
|
||||||
r = imapobj.uid('store',
|
r = imapobj.uid('store',
|
||||||
imaputil.listjoin(uidlist),
|
imaputil.listjoin(uidlist),
|
||||||
@ -474,7 +470,7 @@ class IMAPFolder(BaseFolder):
|
|||||||
try:
|
try:
|
||||||
imapobj.select(self.getfullname())
|
imapobj.select(self.getfullname())
|
||||||
except imapobj.readonly:
|
except imapobj.readonly:
|
||||||
UIBase.getglobalui().deletereadonly(self, uidlist)
|
self.ui.deletereadonly(self, uidlist)
|
||||||
return
|
return
|
||||||
if self.expunge:
|
if self.expunge:
|
||||||
assert(imapobj.expunge()[0] == 'OK')
|
assert(imapobj.expunge()[0] == 'OK')
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
import os.path, os, re, time, socket
|
import os.path, os, re, time, socket
|
||||||
from Base import BaseFolder
|
from Base import BaseFolder
|
||||||
from offlineimap import imaputil
|
from offlineimap import imaputil
|
||||||
from offlineimap.ui import UIBase
|
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -61,6 +60,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
self.repository = repository
|
self.repository = repository
|
||||||
self.accountname = accountname
|
self.accountname = accountname
|
||||||
BaseFolder.__init__(self)
|
BaseFolder.__init__(self)
|
||||||
|
#self.ui is set in BaseFolder.init()
|
||||||
|
|
||||||
def getaccountname(self):
|
def getaccountname(self):
|
||||||
return self.accountname
|
return self.accountname
|
||||||
@ -193,8 +193,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
def savemessage(self, uid, content, flags, rtime):
|
def savemessage(self, uid, content, flags, rtime):
|
||||||
# This function only ever saves to tmp/,
|
# This function only ever saves to tmp/,
|
||||||
# but it calls savemessageflags() to actually save to cur/ or new/.
|
# but it calls savemessageflags() to actually save to cur/ or new/.
|
||||||
ui = UIBase.getglobalui()
|
self.ui.debug('maildir', 'savemessage: called to write with flags %s and content %s' % \
|
||||||
ui.debug('maildir', 'savemessage: called to write with flags %s and content %s' % \
|
|
||||||
(repr(flags), repr(content)))
|
(repr(flags), repr(content)))
|
||||||
if uid < 0:
|
if uid < 0:
|
||||||
# We cannot assign a new uid.
|
# We cannot assign a new uid.
|
||||||
@ -226,7 +225,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
tmpmessagename = messagename.split(',')[0]
|
tmpmessagename = messagename.split(',')[0]
|
||||||
ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
self.ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
||||||
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
|
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
|
||||||
file.write(content)
|
file.write(content)
|
||||||
|
|
||||||
@ -238,7 +237,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
file.close()
|
file.close()
|
||||||
if rtime != None:
|
if rtime != None:
|
||||||
os.utime(os.path.join(tmpdir,tmpmessagename), (rtime,rtime))
|
os.utime(os.path.join(tmpdir,tmpmessagename), (rtime,rtime))
|
||||||
ui.debug('maildir', 'savemessage: moving from %s to %s' % \
|
self.ui.debug('maildir', 'savemessage: moving from %s to %s' % \
|
||||||
(tmpmessagename, messagename))
|
(tmpmessagename, messagename))
|
||||||
if tmpmessagename != messagename: # then rename it
|
if tmpmessagename != messagename: # then rename it
|
||||||
os.rename(os.path.join(tmpdir, tmpmessagename),
|
os.rename(os.path.join(tmpdir, tmpmessagename),
|
||||||
@ -256,7 +255,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
self.messagelist[uid] = {'uid': uid, 'flags': [],
|
self.messagelist[uid] = {'uid': uid, 'flags': [],
|
||||||
'filename': os.path.join(tmpdir, messagename)}
|
'filename': os.path.join(tmpdir, messagename)}
|
||||||
self.savemessageflags(uid, flags)
|
self.savemessageflags(uid, flags)
|
||||||
ui.debug('maildir', 'savemessage: returning uid %d' % uid)
|
self.ui.debug('maildir', 'savemessage: returning uid %d' % uid)
|
||||||
return uid
|
return uid
|
||||||
|
|
||||||
def getmessageflags(self, uid):
|
def getmessageflags(self, uid):
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
import re, socket, time, subprocess
|
import re, socket, time, subprocess
|
||||||
from offlineimap.ui import UIBase
|
from offlineimap.ui import getglobalui
|
||||||
from imaplib import *
|
from imaplib import *
|
||||||
|
|
||||||
# Import the symbols we need that aren't exported by default
|
# Import the symbols we need that aren't exported by default
|
||||||
@ -67,7 +67,7 @@ def new_mesg(self, s, secs=None):
|
|||||||
if secs is None:
|
if secs is None:
|
||||||
secs = time.time()
|
secs = time.time()
|
||||||
tm = time.strftime('%M:%S', time.localtime(secs))
|
tm = time.strftime('%M:%S', time.localtime(secs))
|
||||||
UIBase.getglobalui().debug('imap', ' %s.%02d %s' % (tm, (secs*100)%100, s))
|
getglobalui().debug('imap', ' %s.%02d %s' % (tm, (secs*100)%100, s))
|
||||||
|
|
||||||
class WrappedIMAP4_SSL(IMAP4_SSL):
|
class WrappedIMAP4_SSL(IMAP4_SSL):
|
||||||
"""Provides an improved version of the standard IMAP4_SSL
|
"""Provides an improved version of the standard IMAP4_SSL
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
import imaplib
|
import imaplib
|
||||||
from offlineimap import imaplibutil, imaputil, threadutil
|
from offlineimap import imaplibutil, imaputil, threadutil
|
||||||
from offlineimap.ui import UIBase
|
from offlineimap.ui import getglobalui
|
||||||
from threading import *
|
from threading import *
|
||||||
import thread, hmac, os, time
|
import thread, hmac, os, time
|
||||||
import base64
|
import base64
|
||||||
@ -102,6 +102,7 @@ class IMAPServer:
|
|||||||
port = None, ssl = 1, maxconnections = 1, tunnel = None,
|
port = None, ssl = 1, maxconnections = 1, tunnel = None,
|
||||||
reference = '""', sslclientcert = None, sslclientkey = None,
|
reference = '""', sslclientcert = None, sslclientkey = None,
|
||||||
sslcacertfile= None):
|
sslcacertfile= None):
|
||||||
|
self.ui = getglobalui()
|
||||||
self.reposname = reposname
|
self.reposname = reposname
|
||||||
self.config = config
|
self.config = config
|
||||||
self.username = username
|
self.username = username
|
||||||
@ -140,7 +141,7 @@ class IMAPServer:
|
|||||||
if self.password != None and self.passworderror == None:
|
if self.password != None and self.passworderror == None:
|
||||||
return self.password
|
return self.password
|
||||||
|
|
||||||
self.password = UIBase.getglobalui().getpass(self.reposname,
|
self.password = self.ui.getpass(self.reposname,
|
||||||
self.config,
|
self.config,
|
||||||
self.passworderror)
|
self.passworderror)
|
||||||
self.passworderror = None
|
self.passworderror = None
|
||||||
@ -167,18 +168,16 @@ class IMAPServer:
|
|||||||
self.semaphore.release()
|
self.semaphore.release()
|
||||||
|
|
||||||
def md5handler(self, response):
|
def md5handler(self, response):
|
||||||
ui = UIBase.getglobalui()
|
|
||||||
challenge = response.strip()
|
challenge = response.strip()
|
||||||
ui.debug('imap', 'md5handler: got challenge %s' % challenge)
|
self.ui.debug('imap', 'md5handler: got challenge %s' % challenge)
|
||||||
|
|
||||||
passwd = self.getpassword()
|
passwd = self.getpassword()
|
||||||
retval = self.username + ' ' + hmac.new(passwd, challenge).hexdigest()
|
retval = self.username + ' ' + hmac.new(passwd, challenge).hexdigest()
|
||||||
ui.debug('imap', 'md5handler: returning %s' % retval)
|
self.ui.debug('imap', 'md5handler: returning %s' % retval)
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def plainauth(self, imapobj):
|
def plainauth(self, imapobj):
|
||||||
UIBase.getglobalui().debug('imap',
|
self.ui.debug('imap', 'Attempting plain authentication')
|
||||||
'Attempting plain authentication')
|
|
||||||
imapobj.login(self.username, self.getpassword())
|
imapobj.login(self.username, self.getpassword())
|
||||||
|
|
||||||
def gssauth(self, response):
|
def gssauth(self, response):
|
||||||
@ -201,8 +200,7 @@ class IMAPServer:
|
|||||||
except kerberos.GSSError, err:
|
except kerberos.GSSError, err:
|
||||||
# Kerberos errored out on us, respond with None to cancel the
|
# Kerberos errored out on us, respond with None to cancel the
|
||||||
# authentication
|
# authentication
|
||||||
UIBase.getglobalui().debug('imap',
|
self.ui.debug('imap', '%s: %s' % (err[0][0], err[1][0]))
|
||||||
'%s: %s' % (err[0][0], err[1][0]))
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not response:
|
if not response:
|
||||||
@ -249,16 +247,16 @@ class IMAPServer:
|
|||||||
while not success:
|
while not success:
|
||||||
# Generate a new connection.
|
# Generate a new connection.
|
||||||
if self.tunnel:
|
if self.tunnel:
|
||||||
UIBase.getglobalui().connecting('tunnel', self.tunnel)
|
self.ui.connecting('tunnel', self.tunnel)
|
||||||
imapobj = UsefulIMAP4_Tunnel(self.tunnel)
|
imapobj = UsefulIMAP4_Tunnel(self.tunnel)
|
||||||
success = 1
|
success = 1
|
||||||
elif self.usessl:
|
elif self.usessl:
|
||||||
UIBase.getglobalui().connecting(self.hostname, self.port)
|
self.ui.connecting(self.hostname, self.port)
|
||||||
imapobj = UsefulIMAP4_SSL(self.hostname, self.port,
|
imapobj = UsefulIMAP4_SSL(self.hostname, self.port,
|
||||||
self.sslclientkey, self.sslclientcert,
|
self.sslclientkey, self.sslclientcert,
|
||||||
cacertfile = self.sslcacertfile)
|
cacertfile = self.sslcacertfile)
|
||||||
else:
|
else:
|
||||||
UIBase.getglobalui().connecting(self.hostname, self.port)
|
self.ui.connecting(self.hostname, self.port)
|
||||||
imapobj = UsefulIMAP4(self.hostname, self.port)
|
imapobj = UsefulIMAP4(self.hostname, self.port)
|
||||||
|
|
||||||
imapobj.mustquote = imaplibutil.mustquote
|
imapobj.mustquote = imaplibutil.mustquote
|
||||||
@ -267,13 +265,13 @@ class IMAPServer:
|
|||||||
try:
|
try:
|
||||||
# Try GSSAPI and continue if it fails
|
# Try GSSAPI and continue if it fails
|
||||||
if 'AUTH=GSSAPI' in imapobj.capabilities and have_gss:
|
if 'AUTH=GSSAPI' in imapobj.capabilities and have_gss:
|
||||||
UIBase.getglobalui().debug('imap',
|
self.ui.debug('imap',
|
||||||
'Attempting GSSAPI authentication')
|
'Attempting GSSAPI authentication')
|
||||||
try:
|
try:
|
||||||
imapobj.authenticate('GSSAPI', self.gssauth)
|
imapobj.authenticate('GSSAPI', self.gssauth)
|
||||||
except imapobj.error, val:
|
except imapobj.error, val:
|
||||||
self.gssapi = False
|
self.gssapi = False
|
||||||
UIBase.getglobalui().debug('imap',
|
self.ui.debug('imap',
|
||||||
'GSSAPI Authentication failed')
|
'GSSAPI Authentication failed')
|
||||||
else:
|
else:
|
||||||
self.gssapi = True
|
self.gssapi = True
|
||||||
@ -282,7 +280,7 @@ class IMAPServer:
|
|||||||
|
|
||||||
if not self.gssapi:
|
if not self.gssapi:
|
||||||
if 'AUTH=CRAM-MD5' in imapobj.capabilities:
|
if 'AUTH=CRAM-MD5' in imapobj.capabilities:
|
||||||
UIBase.getglobalui().debug('imap',
|
self.ui.debug('imap',
|
||||||
'Attempting CRAM-MD5 authentication')
|
'Attempting CRAM-MD5 authentication')
|
||||||
try:
|
try:
|
||||||
imapobj.authenticate('CRAM-MD5', self.md5handler)
|
imapobj.authenticate('CRAM-MD5', self.md5handler)
|
||||||
@ -357,47 +355,46 @@ class IMAPServer:
|
|||||||
until the Event object as passed is true. This method is expected
|
until the Event object as passed is true. This method is expected
|
||||||
to be invoked in a separate thread, which should be join()'d after
|
to be invoked in a separate thread, which should be join()'d after
|
||||||
the event is set."""
|
the event is set."""
|
||||||
ui = UIBase.getglobalui()
|
self.ui.debug('imap', 'keepalive thread started')
|
||||||
ui.debug('imap', 'keepalive thread started')
|
|
||||||
while 1:
|
while 1:
|
||||||
ui.debug('imap', 'keepalive: top of loop')
|
self.ui.debug('imap', 'keepalive: top of loop')
|
||||||
time.sleep(timeout)
|
time.sleep(timeout)
|
||||||
ui.debug('imap', 'keepalive: after wait')
|
self.ui.debug('imap', 'keepalive: after wait')
|
||||||
if event.isSet():
|
if event.isSet():
|
||||||
ui.debug('imap', 'keepalive: event is set; exiting')
|
self.ui.debug('imap', 'keepalive: event is set; exiting')
|
||||||
return
|
return
|
||||||
ui.debug('imap', 'keepalive: acquiring connectionlock')
|
self.ui.debug('imap', 'keepalive: acquiring connectionlock')
|
||||||
self.connectionlock.acquire()
|
self.connectionlock.acquire()
|
||||||
numconnections = len(self.assignedconnections) + \
|
numconnections = len(self.assignedconnections) + \
|
||||||
len(self.availableconnections)
|
len(self.availableconnections)
|
||||||
self.connectionlock.release()
|
self.connectionlock.release()
|
||||||
ui.debug('imap', 'keepalive: connectionlock released')
|
self.ui.debug('imap', 'keepalive: connectionlock released')
|
||||||
threads = []
|
threads = []
|
||||||
imapobjs = []
|
imapobjs = []
|
||||||
|
|
||||||
for i in range(numconnections):
|
for i in range(numconnections):
|
||||||
ui.debug('imap', 'keepalive: processing connection %d of %d' % (i, numconnections))
|
self.ui.debug('imap', 'keepalive: processing connection %d of %d' % (i, numconnections))
|
||||||
imapobj = self.acquireconnection()
|
imapobj = self.acquireconnection()
|
||||||
ui.debug('imap', 'keepalive: connection %d acquired' % i)
|
self.ui.debug('imap', 'keepalive: connection %d acquired' % i)
|
||||||
imapobjs.append(imapobj)
|
imapobjs.append(imapobj)
|
||||||
thr = threadutil.ExitNotifyThread(target = imapobj.noop)
|
thr = threadutil.ExitNotifyThread(target = imapobj.noop)
|
||||||
thr.setDaemon(1)
|
thr.setDaemon(1)
|
||||||
thr.start()
|
thr.start()
|
||||||
threads.append(thr)
|
threads.append(thr)
|
||||||
ui.debug('imap', 'keepalive: thread started')
|
self.ui.debug('imap', 'keepalive: thread started')
|
||||||
|
|
||||||
ui.debug('imap', 'keepalive: joining threads')
|
self.ui.debug('imap', 'keepalive: joining threads')
|
||||||
|
|
||||||
for thr in threads:
|
for thr in threads:
|
||||||
# Make sure all the commands have completed.
|
# Make sure all the commands have completed.
|
||||||
thr.join()
|
thr.join()
|
||||||
|
|
||||||
ui.debug('imap', 'keepalive: releasing connections')
|
self.ui.debug('imap', 'keepalive: releasing connections')
|
||||||
|
|
||||||
for imapobj in imapobjs:
|
for imapobj in imapobjs:
|
||||||
self.releaseconnection(imapobj)
|
self.releaseconnection(imapobj)
|
||||||
|
|
||||||
ui.debug('imap', 'keepalive: bottom of loop')
|
self.ui.debug('imap', 'keepalive: bottom of loop')
|
||||||
|
|
||||||
class ConfigedIMAPServer(IMAPServer):
|
class ConfigedIMAPServer(IMAPServer):
|
||||||
"""This class is designed for easier initialization given a ConfigParser
|
"""This class is designed for easier initialization given a ConfigParser
|
||||||
|
@ -17,14 +17,14 @@
|
|||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
import re, string, types
|
import re, string, types
|
||||||
from offlineimap.ui import UIBase
|
from offlineimap.ui import getglobalui
|
||||||
quotere = re.compile('^("(?:[^"]|\\\\")*")')
|
quotere = re.compile('^("(?:[^"]|\\\\")*")')
|
||||||
|
|
||||||
def debug(*args):
|
def debug(*args):
|
||||||
msg = []
|
msg = []
|
||||||
for arg in args:
|
for arg in args:
|
||||||
msg.append(str(arg))
|
msg.append(str(arg))
|
||||||
UIBase.getglobalui().debug('imap', " ".join(msg))
|
getglobalui().debug('imap', " ".join(msg))
|
||||||
|
|
||||||
def dequote(string):
|
def dequote(string):
|
||||||
"""Takes a string which may or may not be quoted and returns it, unquoted.
|
"""Takes a string which may or may not be quoted and returns it, unquoted.
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
from offlineimap import CustomConfig
|
from offlineimap import CustomConfig
|
||||||
from offlineimap.ui import UIBase
|
from offlineimap.ui import getglobalui
|
||||||
import os.path
|
import os.path
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ class BaseRepository(CustomConfig.ConfigHelperMixin):
|
|||||||
for copyfolder in copyfolders:
|
for copyfolder in copyfolders:
|
||||||
copyfolder.makefolder(key.replace(dest.getsep(), copyfolder.getsep()))
|
copyfolder.makefolder(key.replace(dest.getsep(), copyfolder.getsep()))
|
||||||
except:
|
except:
|
||||||
UIBase.getglobalui().warn("ERROR Attempting to make folder " \
|
getglobalui().warn("ERROR Attempting to make folder " \
|
||||||
+ key + ":" +str(sys.exc_info()[1]))
|
+ key + ":" +str(sys.exc_info()[1]))
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
from Base import BaseRepository
|
from Base import BaseRepository
|
||||||
from offlineimap import folder, imaputil
|
from offlineimap import folder, imaputil
|
||||||
from offlineimap.ui import UIBase
|
from offlineimap.ui import getglobalui
|
||||||
from mailbox import Maildir
|
from mailbox import Maildir
|
||||||
import os
|
import os
|
||||||
from stat import *
|
from stat import *
|
||||||
@ -31,7 +31,7 @@ class MaildirRepository(BaseRepository):
|
|||||||
|
|
||||||
self.root = self.getlocalroot()
|
self.root = self.getlocalroot()
|
||||||
self.folders = None
|
self.folders = None
|
||||||
self.ui = UIBase.getglobalui()
|
self.ui = getglobalui()
|
||||||
self.debug("MaildirRepository initialized, sep is " + repr(self.getsep()))
|
self.debug("MaildirRepository initialized, sep is " + repr(self.getsep()))
|
||||||
self.folder_atimes = []
|
self.folder_atimes = []
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ from threading import *
|
|||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
from Queue import Queue, Empty
|
from Queue import Queue, Empty
|
||||||
import sys, traceback, thread, time
|
import sys, traceback, thread, time
|
||||||
from offlineimap.ui import UIBase # for getglobalui()
|
from offlineimap.ui import getglobalui
|
||||||
|
|
||||||
profiledir = None
|
profiledir = None
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ def exitnotifymonitorloop(callback):
|
|||||||
|
|
||||||
def threadexited(thread):
|
def threadexited(thread):
|
||||||
"""Called when a thread exits."""
|
"""Called when a thread exits."""
|
||||||
ui = UIBase.getglobalui()
|
ui = getglobalui()
|
||||||
if thread.getExitCause() == 'EXCEPTION':
|
if thread.getExitCause() == 'EXCEPTION':
|
||||||
if isinstance(thread.getExitException(), SystemExit):
|
if isinstance(thread.getExitException(), SystemExit):
|
||||||
# Bring a SystemExit into the main thread.
|
# Bring a SystemExit into the main thread.
|
||||||
@ -297,5 +297,3 @@ class MultiLock:
|
|||||||
self.lock.release()
|
self.lock.release()
|
||||||
finally:
|
finally:
|
||||||
self.statuslock.release()
|
self.statuslock.release()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user