/head: changeset 90
Commited changes for 2.0.6
This commit is contained in:
parent
bd9873632c
commit
097d30e987
@ -1,3 +1,22 @@
|
||||
2002-07-09 20:17 jgoerzen
|
||||
|
||||
* offlineimap.conf, offlineimap.py, debian/changelog,
|
||||
offlineimap/imapserver.py, offlineimap/version.py,
|
||||
offlineimap/folder/IMAP.py: Commited changes for 2.0.6
|
||||
|
||||
2002-07-09 13:13 jgoerzen
|
||||
|
||||
* offlineimap/folder/IMAP.py: Another attempt at the read-only bug
|
||||
|
||||
2002-07-08 12:05 jgoerzen
|
||||
|
||||
* offlineimap/folder/IMAP.py: Another attempt at fixing read-only
|
||||
folders
|
||||
|
||||
2002-07-08 11:38 jgoerzen
|
||||
|
||||
* ChangeLog: Updated for 2.0.5
|
||||
|
||||
2002-07-08 11:32 jgoerzen
|
||||
|
||||
* debian/changelog, offlineimap/folder/IMAP.py,
|
||||
|
@ -1,3 +1,16 @@
|
||||
offlineimap (2.0.6) unstable; urgency=low
|
||||
|
||||
* Added support for holdconnectionopen and keepalive. This feature
|
||||
allows for an IMAP server connection(s) to be held open until
|
||||
the next sync process, permitting faster restart times.
|
||||
* Another try at read-only folder support. This is nasty because I
|
||||
have no way to test it and imaplib's read-only support is weird.
|
||||
* Closing out old bug; fixed in 1.0.2. Closes: #150803.
|
||||
* Optimized algorithm so that a SELECT is never issued for folders
|
||||
that contain no messages.
|
||||
|
||||
-- John Goerzen <jgoerzen@complete.org> Tue, 9 Jul 2002 20:05:24 -0500
|
||||
|
||||
offlineimap (2.0.5) unstable; urgency=low
|
||||
|
||||
* Fixed a folderfilter example. Partially fixes #152079.
|
||||
|
@ -215,3 +215,19 @@ remoteuser = username
|
||||
|
||||
maxconnections = 1
|
||||
|
||||
# OfflineIMAP normally closes IMAP server connections between refreshes if
|
||||
# the global option autorefresh is specified. If you wish it to keep the
|
||||
# connection open, set this to true. If not specified, the default is
|
||||
# false. Keeping the connection open means a faster sync start the
|
||||
# next time and may use fewer server resources on connection, but uses
|
||||
# more server memory. This setting has no effect if autorefresh is not set.
|
||||
|
||||
holdconnectionopen = no
|
||||
|
||||
# If you want to have "keepalives" sent while waiting between syncs,
|
||||
# specify the amount of time IN SECONDS between keepalives here. Note that
|
||||
# sometimes more than this amount of time might pass, so don't make it
|
||||
# tight. This setting has no effect if autorefresh and holdconnectionopen
|
||||
# are not both set.
|
||||
|
||||
# keepalive = 60
|
||||
|
@ -74,6 +74,8 @@ for account in accounts:
|
||||
|
||||
mailboxes = []
|
||||
mailboxlock = Lock()
|
||||
servers = {}
|
||||
|
||||
def addmailbox(accountname, remotefolder):
|
||||
mailboxlock.acquire()
|
||||
mailboxes.append({'accountname' : accountname,
|
||||
@ -88,28 +90,14 @@ def syncaccount(accountname, *args):
|
||||
accountmetadata = os.path.join(metadatadir, accountname)
|
||||
if not os.path.exists(accountmetadata):
|
||||
os.mkdir(accountmetadata, 0700)
|
||||
host = config.get(accountname, "remotehost")
|
||||
user = config.get(accountname, "remoteuser")
|
||||
port = None
|
||||
if config.has_option(accountname, "remoteport"):
|
||||
port = config.getint(accountname, "remoteport")
|
||||
ssl = config.getboolean(accountname, "ssl")
|
||||
usetunnel = config.has_option(accountname, "preauthtunnel")
|
||||
reference = '""'
|
||||
if config.has_option(accountname, "reference"):
|
||||
reference = config.get(accountname, "reference")
|
||||
|
||||
server = None
|
||||
# Connect to the remote server.
|
||||
if usetunnel:
|
||||
server = imapserver.IMAPServer(tunnel = tunnels[accountname],
|
||||
reference = reference,
|
||||
maxconnections = config.getint(accountname, "maxconnections"))
|
||||
if accountname in servers:
|
||||
server = servers[accountname]
|
||||
else:
|
||||
server = imapserver.IMAPServer(user, passwords[accountname],
|
||||
host, port, ssl,
|
||||
config.getint(accountname, "maxconnections"),
|
||||
reference = reference)
|
||||
server = imapserver.ConfigedIMAPServer(config, accountname, passwords)
|
||||
servers[accountname] = server
|
||||
|
||||
remoterepos = repository.IMAP.IMAPRepository(config, accountname, server)
|
||||
|
||||
# Connect to the Maildirs.
|
||||
@ -134,6 +122,8 @@ def syncaccount(accountname, *args):
|
||||
thread.start()
|
||||
folderthreads.append(thread)
|
||||
threadutil.threadsreset(folderthreads)
|
||||
if not (config.has_option(accountname, 'holdconnectionopen') and \
|
||||
config.getboolean(accountname, 'holdconnectionopen')):
|
||||
server.close()
|
||||
finally:
|
||||
pass
|
||||
@ -213,9 +203,31 @@ def sync_with_timer():
|
||||
if config.has_option('general', 'autorefresh'):
|
||||
refreshperiod = config.getint('general', 'autorefresh') * 60
|
||||
while 1:
|
||||
# Set up keep-alives.
|
||||
kaevents = {}
|
||||
kathreads = {}
|
||||
for accountname in accounts:
|
||||
if config.has_option(accountname, 'holdconnectionopen') and \
|
||||
config.getboolean(accountname, 'holdconnectionopen') and \
|
||||
config.has_option(accountname, 'keepalive'):
|
||||
event = Event()
|
||||
kaevents[accountname] = event
|
||||
thread = ExitNotifyThread(target = servers[accountname].keepalive,
|
||||
args = (config.getint(accountname, 'keepalive'), event))
|
||||
thread.setDaemon(1)
|
||||
thread.start()
|
||||
kathreads[accountname] = thread
|
||||
if ui.sleep(refreshperiod) == 2:
|
||||
# Cancel keep-alives, but don't bother terminating threads
|
||||
for event in kaevents.values():
|
||||
event.set()
|
||||
break
|
||||
else:
|
||||
# Cancel keep-alives and wait for threads to terminate.
|
||||
for event in kaevents.values():
|
||||
event.set()
|
||||
for thread in kathreads.values():
|
||||
thread.join()
|
||||
syncitall()
|
||||
|
||||
def threadexited(thread):
|
||||
|
@ -59,8 +59,6 @@ class IMAPFolder(BaseFolder):
|
||||
def cachemessagelist(self):
|
||||
imapobj = self.imapserver.acquireconnection()
|
||||
try:
|
||||
# Needed for fetch below
|
||||
imapobj.select(self.getfullname(), readonly = 1)
|
||||
self.messagelist = {}
|
||||
response = imapobj.status(self.getfullname(), '(MESSAGES)')[1][0]
|
||||
result = imaputil.imapsplit(response)[1]
|
||||
@ -69,6 +67,8 @@ class IMAPFolder(BaseFolder):
|
||||
# No messages? return.
|
||||
return
|
||||
|
||||
# Needed for fetch below
|
||||
imapobj.select(self.getfullname(), readonly = 1)
|
||||
# Now, get the flags and UIDs for these.
|
||||
response = imapobj.fetch('1:%d' % maxmsgid, '(FLAGS UID)')[1]
|
||||
finally:
|
||||
|
@ -28,13 +28,14 @@ class UsefulIMAPMixIn:
|
||||
return None
|
||||
|
||||
def select(self, mailbox='INBOX', readonly=None):
|
||||
if self.getselectedfolder() == mailbox and not readonly:
|
||||
if self.getselectedfolder() == mailbox:
|
||||
self.is_readonly = readonly
|
||||
# No change; return.
|
||||
return
|
||||
result = self.__class__.__bases__[1].select(self, mailbox, readonly)
|
||||
if result[0] != 'OK':
|
||||
raise ValueError, "Error from select: %s" % str(result)
|
||||
if self.getstate() == 'SELECTED' and not readonly:
|
||||
if self.getstate() == 'SELECTED':
|
||||
self.selectedfolder = mailbox
|
||||
else:
|
||||
self.selectedfolder = None
|
||||
@ -147,4 +148,70 @@ class IMAPServer:
|
||||
self.availableconnections = []
|
||||
self.connectionlock.release()
|
||||
|
||||
def keepalive(self, timeout, event):
|
||||
"""Sends a NOOP to each connection recorded. It will wait a maximum
|
||||
of timeout seconds between doing this, and will continue to do so
|
||||
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
|
||||
the event is set."""
|
||||
while 1:
|
||||
event.wait(timeout)
|
||||
if event.isSet():
|
||||
return
|
||||
self.connectionlock.acquire()
|
||||
numconnections = len(self.assignedconnections) + \
|
||||
len(self.availableconnections)
|
||||
self.connectionlock.release()
|
||||
threads = []
|
||||
imapobjs = []
|
||||
|
||||
for i in range(numconnections):
|
||||
imapobj = self.acquireconnection()
|
||||
imapobjs.append(imapobj)
|
||||
thread = threadutil.ExitNotifyThread(target = imapobj.noop)
|
||||
thread.setDaemon(1)
|
||||
thread.start()
|
||||
threads.append(thread)
|
||||
|
||||
for thread in threads:
|
||||
# Make sure all the commands have completed.
|
||||
thread.join()
|
||||
|
||||
for imapobj in imapobjs:
|
||||
self.releaseconnection(imapobj)
|
||||
|
||||
class ConfigedIMAPServer(IMAPServer):
|
||||
"""This class is designed for easier initialization given a ConfigParser
|
||||
object and an account name. The passwordhash is used if
|
||||
passwords for certain accounts are known. If the password for this
|
||||
account is listed, it will be obtained from there."""
|
||||
def __init__(self, config, accountname, passwordhash = {}):
|
||||
"""Initialize the object. If the account is not a tunnel,
|
||||
the password is required."""
|
||||
host = config.get(accountname, "remotehost")
|
||||
user = config.get(accountname, "remoteuser")
|
||||
port = None
|
||||
if config.has_option(accountname, "remoteport"):
|
||||
port = config.getint(accountname, "remoteport")
|
||||
ssl = config.getboolean(accountname, "ssl")
|
||||
usetunnel = config.has_option(accountname, "preauthtunnel")
|
||||
reference = '""'
|
||||
if config.has_option(accountname, "reference"):
|
||||
reference = config.get(accountname, "reference")
|
||||
server = None
|
||||
password = None
|
||||
if accountname in passwordhash:
|
||||
password = passwordhash[accountname]
|
||||
|
||||
# Connect to the remote server.
|
||||
if usetunnel:
|
||||
IMAPServer.__init__(self,
|
||||
tunnel = config.get(accountname, "preauthtunnel"),
|
||||
reference = reference,
|
||||
maxconnections = config.getint(accountname, "maxconnections"))
|
||||
else:
|
||||
if not password:
|
||||
password = config.get(accountname, 'remotepass')
|
||||
IMAPServer.__init__(self, user, password, host, port, ssl,
|
||||
config.getint(accountname, "maxconnections"),
|
||||
reference = reference)
|
||||
|
@ -1,5 +1,5 @@
|
||||
productname = 'OfflineIMAP'
|
||||
versionstr = "2.0.5"
|
||||
versionstr = "2.0.6"
|
||||
|
||||
versionlist = versionstr.split(".")
|
||||
major = versionlist[0]
|
||||
|
Loading…
Reference in New Issue
Block a user