From d6b790a7da5bbf005e57bba58bc186767ca3db7a Mon Sep 17 00:00:00 2001 From: jgoerzen Date: Mon, 6 Jan 2003 00:07:58 +0100 Subject: [PATCH] /offlineimap/head: changeset 308 More progress at debugging. The curses blinkenlights is now working well, though it still has an occasional tendency to corrupt the light display with comments from the log. I suspect a locking problem -- need to be more strict with iolock I suspect. Updated various modules to register the threads' account names, etc. --- offlineimap/head/offlineimap/accounts.py | 4 +- offlineimap/head/offlineimap/folder/Base.py | 6 ++- offlineimap/head/offlineimap/folder/IMAP.py | 3 ++ .../head/offlineimap/folder/LocalStatus.py | 8 +++- .../head/offlineimap/folder/Maildir.py | 6 ++- .../offlineimap/repository/LocalStatus.py | 7 ++-- .../head/offlineimap/repository/Maildir.py | 4 +- offlineimap/head/offlineimap/ui/Curses.py | 37 +++++++++++++------ offlineimap/head/offlineimap/ui/UIBase.py | 7 ++-- 9 files changed, 57 insertions(+), 25 deletions(-) diff --git a/offlineimap/head/offlineimap/accounts.py b/offlineimap/head/offlineimap/accounts.py index 40a1611..ce28a95 100644 --- a/offlineimap/head/offlineimap/accounts.py +++ b/offlineimap/head/offlineimap/accounts.py @@ -81,6 +81,7 @@ class Account: class AccountSynchronizationMixin: def syncrunner(self): + self.ui.registerthread(self.name) self.ui.acct(self.name) if not self.refreshperiod: self.sync() @@ -109,7 +110,7 @@ class AccountSynchronizationMixin: localrepos = repository.Maildir.MaildirRepository(os.path.expanduser(self.config.get(self.name, "localfolders")), self.name, self.config) # Connect to the local cache. - statusrepos = repository.LocalStatus.LocalStatusRepository(accountmetadata) + statusrepos = repository.LocalStatus.LocalStatusRepository(accountmetadata, self.name) self.ui.syncfolders(remoterepos, localrepos) remoterepos.syncfoldersto(localrepos) @@ -139,6 +140,7 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos, statusrepos): global mailboxes ui = UIBase.getglobalui() + ui.registerthread(accountname) # Load local folder. localfolder = localrepos.\ getfolder(remotefolder.getvisiblename().\ diff --git a/offlineimap/head/offlineimap/folder/Base.py b/offlineimap/head/offlineimap/folder/Base.py index 8643eeb..06d61a5 100644 --- a/offlineimap/head/offlineimap/folder/Base.py +++ b/offlineimap/head/offlineimap/folder/Base.py @@ -186,12 +186,14 @@ class BaseFolder: # Did not find any server to take this message. Ignore. pass - def copymessageto(self, uid, applyto): + def copymessageto(self, uid, applyto, register = 1): # Sometimes, it could be the case that if a sync takes awhile, # a message might be deleted from the maildir before it can be # synced to the status cache. This is only a problem with # self.getmessage(). So, don't call self.getmessage unless # really needed. + if register: + UIBase.getglobalui().registerthread(self.getaccountname()) UIBase.getglobalui().copyingmessage(uid, self, applyto) message = '' # If any of the destinations actually stores the message body, @@ -233,7 +235,7 @@ class BaseFolder: thread.start() threads.append(thread) else: - self.copymessageto(uid, applyto) + self.copymessageto(uid, applyto, register = 0) for thread in threads: thread.join() diff --git a/offlineimap/head/offlineimap/folder/IMAP.py b/offlineimap/head/offlineimap/folder/IMAP.py index d2e518b..87a8644 100644 --- a/offlineimap/head/offlineimap/folder/IMAP.py +++ b/offlineimap/head/offlineimap/folder/IMAP.py @@ -39,6 +39,9 @@ class IMAPFolder(BaseFolder): self.accountname = accountname self.repository = repository + def getaccountname(self): + return self.accountname + def suggeststhreads(self): return 1 diff --git a/offlineimap/head/offlineimap/folder/LocalStatus.py b/offlineimap/head/offlineimap/folder/LocalStatus.py index c7760fe..5370971 100644 --- a/offlineimap/head/offlineimap/folder/LocalStatus.py +++ b/offlineimap/head/offlineimap/folder/LocalStatus.py @@ -1,5 +1,5 @@ # Local status cache virtual folder -# Copyright (C) 2002 John Goerzen +# Copyright (C) 2002 - 2003 John Goerzen # # # This program is free software; you can redistribute it and/or modify @@ -22,7 +22,7 @@ import os, threading magicline = "OFFLINEIMAP LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT 1" class LocalStatusFolder(BaseFolder): - def __init__(self, root, name, repository): + def __init__(self, root, name, repository, accountname): self.name = name self.root = root self.sep = '.' @@ -31,6 +31,10 @@ class LocalStatusFolder(BaseFolder): self.repository = repository self.savelock = threading.Lock() self.doautosave = 1 + self.accountname = accountname + + def getaccountname(self): + return self.accountname def storesmessages(self): return 0 diff --git a/offlineimap/head/offlineimap/folder/Maildir.py b/offlineimap/head/offlineimap/folder/Maildir.py index 6f2f5d7..468e226 100644 --- a/offlineimap/head/offlineimap/folder/Maildir.py +++ b/offlineimap/head/offlineimap/folder/Maildir.py @@ -39,13 +39,17 @@ def gettimeseq(): return timeseq class MaildirFolder(BaseFolder): - def __init__(self, root, name, sep, repository): + def __init__(self, root, name, sep, repository, accountname): self.name = name self.root = root self.sep = sep self.uidfilename = os.path.join(self.getfullname(), "offlineimap.uidvalidity") self.messagelist = None self.repository = repository + self.accountname = accountname + + def getaccountname(self): + return self.accountname def getfullname(self): return os.path.join(self.getroot(), self.getname()) diff --git a/offlineimap/head/offlineimap/repository/LocalStatus.py b/offlineimap/head/offlineimap/repository/LocalStatus.py index 4d3caaa..840c09e 100644 --- a/offlineimap/head/offlineimap/repository/LocalStatus.py +++ b/offlineimap/head/offlineimap/repository/LocalStatus.py @@ -21,9 +21,10 @@ from offlineimap import folder import os class LocalStatusRepository(BaseRepository): - def __init__(self, directory): + def __init__(self, directory, accountname): self.directory = directory self.folders = None + self.accountname = accountname def getsep(self): return '.' @@ -42,12 +43,12 @@ class LocalStatusRepository(BaseRepository): retval = [] for folder in os.listdir(self.directory): retval.append(folder.LocalStatus.LocalStatusFolder(self.directory, - folder, self)) + folder, self, self.accountname)) return retval def getfolder(self, foldername): return folder.LocalStatus.LocalStatusFolder(self.directory, foldername, - self) + self, self.accountname) diff --git a/offlineimap/head/offlineimap/repository/Maildir.py b/offlineimap/head/offlineimap/repository/Maildir.py index 33b2ba8..066486f 100644 --- a/offlineimap/head/offlineimap/repository/Maildir.py +++ b/offlineimap/head/offlineimap/repository/Maildir.py @@ -87,7 +87,7 @@ class MaildirRepository(BaseRepository): def getfolder(self, foldername): return folder.Maildir.MaildirFolder(self.root, foldername, - self.getsep(), self) + self.getsep(), self, self.accountname) def _getfolders_scandir(self, root, extension = None): self.debug("_GETFOLDERS_SCANDIR STARTING. root = %s, extension = %s" \ @@ -131,7 +131,7 @@ class MaildirRepository(BaseRepository): self.debug(" foldername = %s" % foldername) retval.append(folder.Maildir.MaildirFolder(self.root, foldername, - self.getsep(), self)) + self.getsep(), self, self.accountname)) if self.getsep() == '/': # Check sub-directories for folders. retval.extend(self._getfolders_scandir(root, foldername)) diff --git a/offlineimap/head/offlineimap/ui/Curses.py b/offlineimap/head/offlineimap/ui/Curses.py index 54560a0..0f613e6 100644 --- a/offlineimap/head/offlineimap/ui/Curses.py +++ b/offlineimap/head/offlineimap/ui/Curses.py @@ -84,19 +84,23 @@ class CursesUtil: self.start() class CursesAccountFrame: - def __init__(s, master): + def __init__(s, master, accountname): s.c = master s.children = [] + s.accountname = accountname def setwindow(s, window): s.window = window - location = 0 + acctstr = '%15.15s: ' % s.accountname + s.window.addstr(0, 0, acctstr) + s.location = len(acctstr) for child in s.children: - child.update(window, 0, location) - location += 1 + child.update(window, 0, s.location) + s.location += 1 def getnewthreadframe(s): - tf = CursesThreadFrame(s.c, s.window, 0, len(s.children)) + tf = CursesThreadFrame(s.c, s.window, 0, s.location) + s.location += 1 s.children.append(tf) return tf @@ -120,21 +124,32 @@ class CursesThreadFrame: 'orange': s.c.getpair(curses.COLOR_YELLOW, bg), 'yellow': curses.A_BOLD | s.c.getpair(curses.COLOR_YELLOW, bg), 'pink': curses.A_BOLD | s.c.getpair(curses.COLOR_RED, bg)} - s.setcolor('gray') + #s.setcolor('gray') + s.setcolor('black') def setcolor(self, color): self.color = self.colormap[color] + self.display() + + def display(self): self.window.addstr(self.y, self.x, '.', self.color) self.window.refresh() def getcolor(self): return self.color + def update(self, window, y, x): + self.window = window + self.y = y + self.x = x + self.display() + def setthread(self, newthread): - if newthread: - self.setcolor('gray') - else: - self.setcolor('black') + self.setcolor('black') + #if newthread: + # self.setcolor('gray') + #else: + # self.setcolor('black') class InputHandler: def __init__(s, util): @@ -293,7 +308,7 @@ class Blinkenlights(BlinkenBase, UIBase): return s.af[accountname] # New one. - s.af[accountname] = CursesAccountFrame(s.c) + s.af[accountname] = CursesAccountFrame(s.c, accountname) #s.iolock.acquire() s.c.reset() s.setupwindows(dolock = 0) diff --git a/offlineimap/head/offlineimap/ui/UIBase.py b/offlineimap/head/offlineimap/ui/UIBase.py index 2c31773..c27981c 100644 --- a/offlineimap/head/offlineimap/ui/UIBase.py +++ b/offlineimap/head/offlineimap/ui/UIBase.py @@ -55,8 +55,9 @@ class UIBase: """Provides a hint to UIs about which account this particular thread is processing.""" if s.threadaccounts.has_key(threading.currentThread()): - raise ValueError, "Thread already registered (old %s, new %s)" % \ - (s.getthreadaccount(s), account) + raise ValueError, "Thread %s already registered (old %s, new %s)" %\ + (threading.currentThread().getName(), + s.getthreadaccount(s), account) s.threadaccounts[threading.currentThread()] = account def unregisterthread(s, thr): @@ -69,7 +70,7 @@ class UIBase: thr = threading.currentThread() if s.threadaccounts.has_key(thr): return s.threadaccounts[thr] - return None + return '*Control' def debug(s, debugtype, msg): thisthread = threading.currentThread()