X-Git-Url: https://code.delx.au/offlineimap/blobdiff_plain/405275f541ffb3bd4af427f7307d91fd59d91807..f58ebe390d281e6fe526e70451e2377b77f68183:/offlineimap/accounts.py diff --git a/offlineimap/accounts.py b/offlineimap/accounts.py index 34d7f9d..fe536a7 100644 --- a/offlineimap/accounts.py +++ b/offlineimap/accounts.py @@ -13,7 +13,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA from offlineimap import threadutil, mbnames, CustomConfig import offlineimap.repository.Base, offlineimap.repository.LocalStatus @@ -45,6 +45,7 @@ class Account(CustomConfig.ConfigHelperMixin): self.localeval = config.getlocaleval() self.ui = UIBase.getglobalui() self.refreshperiod = self.getconffloat('autorefresh', 0.0) + self.quicknum = 0 if self.refreshperiod == 0.0: self.refreshperiod = None @@ -94,6 +95,16 @@ class Account(CustomConfig.ConfigHelperMixin): return sleepresult class AccountSynchronizationMixin: + def __init__(self, config, name, folderhash, folderhashlock): + Account.__init__(self, config, name) + self.folderhash = folderhash + self.folderhashlock = folderhashlock + self.folderhashlock.acquire() + try: + self.folderhash[name] = {} + finally: + self.folderhashlock.release() + def syncrunner(self): self.ui.registerthread(self.name) self.ui.acct(self.name) @@ -108,6 +119,18 @@ class AccountSynchronizationMixin: # Connect to the local cache. self.statusrepos = offlineimap.repository.LocalStatus.LocalStatusRepository(self.getconf('localrepository'), self) + + # FIXME: need new UI here? + self.ui.syncfolders(self.remoterepos, self.localrepos) + srcfolders = self.remoterepos.getfolders() + destfolders = self.localrepos.getfolders() + + self.folderhashlock.acquire() + try: + self.folderhash[name] = {'src': srcfolders, 'dest': destfolders} + self.folderhash['___sem'].release() + finally: + self.folderhashlock.release() if not self.refreshperiod: self.sync() @@ -125,12 +148,26 @@ class AccountSynchronizationMixin: def sync(self): # We don't need an account lock because syncitall() goes through # each account once, then waits for all to finish. + + quickconfig = self.getconfint('quick', 0) + if quickconfig < 0: + quick = True + elif quickconfig > 0: + if self.quicknum == 0 or self.quicknum > quickconfig: + self.quicknum = 1 + quick = False + else: + self.quicknum = self.quicknum + 1 + quick = True + else: + quick = False + try: remoterepos = self.remoterepos localrepos = self.localrepos statusrepos = self.statusrepos self.ui.syncfolders(remoterepos, localrepos) - remoterepos.syncfoldersto(localrepos) + remoterepos.syncfoldersto(localrepos, [statusrepos]) folderthreads = [] for remotefolder in remoterepos.getfolders(): @@ -140,12 +177,14 @@ class AccountSynchronizationMixin: name = "Folder sync %s[%s]" % \ (self.name, remotefolder.getvisiblename()), args = (self.name, remoterepos, remotefolder, localrepos, - statusrepos)) + statusrepos, quick)) thread.setDaemon(1) thread.start() folderthreads.append(thread) threadutil.threadsreset(folderthreads) mbnames.write() + localrepos.forgetfolders() + remoterepos.forgetfolders() localrepos.holdordropconnections() remoterepos.holdordropconnections() finally: @@ -154,14 +193,8 @@ class AccountSynchronizationMixin: class SyncableAccount(Account, AccountSynchronizationMixin): pass -from stat import * - -def reset_time(folder, atime, mtime): - t = atime, mtime - os.utime(folder, t) - def syncfolder(accountname, remoterepos, remotefolder, localrepos, - statusrepos): + statusrepos, quick): global mailboxes ui = UIBase.getglobalui() ui.registerthread(accountname) @@ -169,17 +202,8 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos, localfolder = localrepos.\ getfolder(remotefolder.getvisiblename().\ replace(remoterepos.getsep(), localrepos.getsep())) - if localrepos.getrestoreatime(): - cur_atime = os.stat(localfolder.getfullname() + "/cur")[ST_ATIME] - new_atime = os.stat(localfolder.getfullname() + "/new")[ST_ATIME] # Write the mailboxes mbnames.add(accountname, localfolder.getvisiblename()) - # Load local folder - ui.syncingfolder(remoterepos, remotefolder, localrepos, localfolder) - ui.loadmessagelist(localrepos, localfolder) - localfolder.cachemessagelist() - ui.messagelistloaded(localrepos, localfolder, len(localfolder.getmessagelist().keys())) - # Load status folder. statusfolder = statusrepos.getfolder(remotefolder.getvisiblename().\ @@ -192,28 +216,31 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos, statusfolder.cachemessagelist() + if quick: + if not localfolder.quickchanged(statusfolder) \ + and not remotefolder.quickchanged(statusfolder): + ui.skippingfolder(remotefolder) + localrepos.restore_atime() + return + + # Load local folder + ui.syncingfolder(remoterepos, remotefolder, localrepos, localfolder) + ui.loadmessagelist(localrepos, localfolder) + localfolder.cachemessagelist() + ui.messagelistloaded(localrepos, localfolder, len(localfolder.getmessagelist().keys())) + # If either the local or the status folder has messages and there is a UID # validity problem, warn and abort. If there are no messages, UW IMAPd # loses UIDVALIDITY. But we don't really need it if both local folders are # empty. So, in that case, just save it off. if len(localfolder.getmessagelist()) or len(statusfolder.getmessagelist()): if not localfolder.isuidvalidityok(): - ui.validityproblem(localfolder, localfolder.getsaveduidvalidity(), - localfolder.getuidvalidity()) - if localrepos.getrestoreatime(): - reset_time(localfolder.getfullname() + "/new", new_atime, \ - os.stat(localfolder.getfullname() + "/new")[ST_MTIME]) - reset_time(localfolder.getfullname() + "/cur", new_atime, \ - os.stat(localfolder.getfullname() + "/cur")[ST_MTIME]) + ui.validityproblem(localfolder) + localrepos.restore_atime() return if not remotefolder.isuidvalidityok(): - ui.validityproblem(remotefolder, remotefolder.getsaveduidvalidity(), - remotefolder.getuidvalidity()) - if localrepos.getrestoreatime(): - reset_time(localfolder.getfullname() + "/new", new_atime, \ - os.stat(localfolder.getfullname() + "/new")[ST_MTIME]) - reset_time(localfolder.getfullname() + "/cur", new_atime, \ - os.stat(localfolder.getfullname() + "/cur")[ST_MTIME]) + ui.validityproblem(remotefolder) + localrepos.restore_atime() return else: localfolder.saveuidvalidity() @@ -249,9 +276,5 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos, ui.syncingmessages(localrepos, localfolder, statusrepos, statusfolder) localfolder.syncmessagesto(statusfolder) statusfolder.save() - if localrepos.getrestoreatime(): - reset_time(localfolder.getfullname() + "/new", new_atime, \ - os.stat(localfolder.getfullname() + "/new")[ST_MTIME]) - reset_time(localfolder.getfullname() + "/cur", new_atime, \ - os.stat(localfolder.getfullname() + "/cur")[ST_MTIME]) + localrepos.restore_atime()