/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.
This commit is contained in:
parent
c48d8d4fda
commit
d6b790a7da
@ -81,6 +81,7 @@ class Account:
|
|||||||
|
|
||||||
class AccountSynchronizationMixin:
|
class AccountSynchronizationMixin:
|
||||||
def syncrunner(self):
|
def syncrunner(self):
|
||||||
|
self.ui.registerthread(self.name)
|
||||||
self.ui.acct(self.name)
|
self.ui.acct(self.name)
|
||||||
if not self.refreshperiod:
|
if not self.refreshperiod:
|
||||||
self.sync()
|
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)
|
localrepos = repository.Maildir.MaildirRepository(os.path.expanduser(self.config.get(self.name, "localfolders")), self.name, self.config)
|
||||||
|
|
||||||
# Connect to the local cache.
|
# Connect to the local cache.
|
||||||
statusrepos = repository.LocalStatus.LocalStatusRepository(accountmetadata)
|
statusrepos = repository.LocalStatus.LocalStatusRepository(accountmetadata, self.name)
|
||||||
|
|
||||||
self.ui.syncfolders(remoterepos, localrepos)
|
self.ui.syncfolders(remoterepos, localrepos)
|
||||||
remoterepos.syncfoldersto(localrepos)
|
remoterepos.syncfoldersto(localrepos)
|
||||||
@ -139,6 +140,7 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos,
|
|||||||
statusrepos):
|
statusrepos):
|
||||||
global mailboxes
|
global mailboxes
|
||||||
ui = UIBase.getglobalui()
|
ui = UIBase.getglobalui()
|
||||||
|
ui.registerthread(accountname)
|
||||||
# Load local folder.
|
# Load local folder.
|
||||||
localfolder = localrepos.\
|
localfolder = localrepos.\
|
||||||
getfolder(remotefolder.getvisiblename().\
|
getfolder(remotefolder.getvisiblename().\
|
||||||
|
@ -186,12 +186,14 @@ class BaseFolder:
|
|||||||
# Did not find any server to take this message. Ignore.
|
# Did not find any server to take this message. Ignore.
|
||||||
pass
|
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,
|
# Sometimes, it could be the case that if a sync takes awhile,
|
||||||
# a message might be deleted from the maildir before it can be
|
# a message might be deleted from the maildir before it can be
|
||||||
# synced to the status cache. This is only a problem with
|
# synced to the status cache. This is only a problem with
|
||||||
# self.getmessage(). So, don't call self.getmessage unless
|
# self.getmessage(). So, don't call self.getmessage unless
|
||||||
# really needed.
|
# really needed.
|
||||||
|
if register:
|
||||||
|
UIBase.getglobalui().registerthread(self.getaccountname())
|
||||||
UIBase.getglobalui().copyingmessage(uid, self, applyto)
|
UIBase.getglobalui().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,
|
||||||
@ -233,7 +235,7 @@ class BaseFolder:
|
|||||||
thread.start()
|
thread.start()
|
||||||
threads.append(thread)
|
threads.append(thread)
|
||||||
else:
|
else:
|
||||||
self.copymessageto(uid, applyto)
|
self.copymessageto(uid, applyto, register = 0)
|
||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
|
@ -39,6 +39,9 @@ class IMAPFolder(BaseFolder):
|
|||||||
self.accountname = accountname
|
self.accountname = accountname
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
|
|
||||||
|
def getaccountname(self):
|
||||||
|
return self.accountname
|
||||||
|
|
||||||
def suggeststhreads(self):
|
def suggeststhreads(self):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Local status cache virtual folder
|
# Local status cache virtual folder
|
||||||
# Copyright (C) 2002 John Goerzen
|
# Copyright (C) 2002 - 2003 John Goerzen
|
||||||
# <jgoerzen@complete.org>
|
# <jgoerzen@complete.org>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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"
|
magicline = "OFFLINEIMAP LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT 1"
|
||||||
|
|
||||||
class LocalStatusFolder(BaseFolder):
|
class LocalStatusFolder(BaseFolder):
|
||||||
def __init__(self, root, name, repository):
|
def __init__(self, root, name, repository, accountname):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.root = root
|
self.root = root
|
||||||
self.sep = '.'
|
self.sep = '.'
|
||||||
@ -31,6 +31,10 @@ class LocalStatusFolder(BaseFolder):
|
|||||||
self.repository = repository
|
self.repository = repository
|
||||||
self.savelock = threading.Lock()
|
self.savelock = threading.Lock()
|
||||||
self.doautosave = 1
|
self.doautosave = 1
|
||||||
|
self.accountname = accountname
|
||||||
|
|
||||||
|
def getaccountname(self):
|
||||||
|
return self.accountname
|
||||||
|
|
||||||
def storesmessages(self):
|
def storesmessages(self):
|
||||||
return 0
|
return 0
|
||||||
|
@ -39,13 +39,17 @@ def gettimeseq():
|
|||||||
return timeseq
|
return timeseq
|
||||||
|
|
||||||
class MaildirFolder(BaseFolder):
|
class MaildirFolder(BaseFolder):
|
||||||
def __init__(self, root, name, sep, repository):
|
def __init__(self, root, name, sep, repository, accountname):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.root = root
|
self.root = root
|
||||||
self.sep = sep
|
self.sep = sep
|
||||||
self.uidfilename = os.path.join(self.getfullname(), "offlineimap.uidvalidity")
|
self.uidfilename = os.path.join(self.getfullname(), "offlineimap.uidvalidity")
|
||||||
self.messagelist = None
|
self.messagelist = None
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
|
self.accountname = accountname
|
||||||
|
|
||||||
|
def getaccountname(self):
|
||||||
|
return self.accountname
|
||||||
|
|
||||||
def getfullname(self):
|
def getfullname(self):
|
||||||
return os.path.join(self.getroot(), self.getname())
|
return os.path.join(self.getroot(), self.getname())
|
||||||
|
@ -21,9 +21,10 @@ from offlineimap import folder
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
class LocalStatusRepository(BaseRepository):
|
class LocalStatusRepository(BaseRepository):
|
||||||
def __init__(self, directory):
|
def __init__(self, directory, accountname):
|
||||||
self.directory = directory
|
self.directory = directory
|
||||||
self.folders = None
|
self.folders = None
|
||||||
|
self.accountname = accountname
|
||||||
|
|
||||||
def getsep(self):
|
def getsep(self):
|
||||||
return '.'
|
return '.'
|
||||||
@ -42,12 +43,12 @@ class LocalStatusRepository(BaseRepository):
|
|||||||
retval = []
|
retval = []
|
||||||
for folder in os.listdir(self.directory):
|
for folder in os.listdir(self.directory):
|
||||||
retval.append(folder.LocalStatus.LocalStatusFolder(self.directory,
|
retval.append(folder.LocalStatus.LocalStatusFolder(self.directory,
|
||||||
folder, self))
|
folder, self, self.accountname))
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def getfolder(self, foldername):
|
def getfolder(self, foldername):
|
||||||
return folder.LocalStatus.LocalStatusFolder(self.directory, foldername,
|
return folder.LocalStatus.LocalStatusFolder(self.directory, foldername,
|
||||||
self)
|
self, self.accountname)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class MaildirRepository(BaseRepository):
|
|||||||
|
|
||||||
def getfolder(self, foldername):
|
def getfolder(self, foldername):
|
||||||
return folder.Maildir.MaildirFolder(self.root, foldername,
|
return folder.Maildir.MaildirFolder(self.root, foldername,
|
||||||
self.getsep(), self)
|
self.getsep(), self, self.accountname)
|
||||||
|
|
||||||
def _getfolders_scandir(self, root, extension = None):
|
def _getfolders_scandir(self, root, extension = None):
|
||||||
self.debug("_GETFOLDERS_SCANDIR STARTING. root = %s, extension = %s" \
|
self.debug("_GETFOLDERS_SCANDIR STARTING. root = %s, extension = %s" \
|
||||||
@ -131,7 +131,7 @@ class MaildirRepository(BaseRepository):
|
|||||||
self.debug(" foldername = %s" % foldername)
|
self.debug(" foldername = %s" % foldername)
|
||||||
|
|
||||||
retval.append(folder.Maildir.MaildirFolder(self.root, foldername,
|
retval.append(folder.Maildir.MaildirFolder(self.root, foldername,
|
||||||
self.getsep(), self))
|
self.getsep(), self, self.accountname))
|
||||||
if self.getsep() == '/':
|
if self.getsep() == '/':
|
||||||
# Check sub-directories for folders.
|
# Check sub-directories for folders.
|
||||||
retval.extend(self._getfolders_scandir(root, foldername))
|
retval.extend(self._getfolders_scandir(root, foldername))
|
||||||
|
@ -84,19 +84,23 @@ class CursesUtil:
|
|||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
class CursesAccountFrame:
|
class CursesAccountFrame:
|
||||||
def __init__(s, master):
|
def __init__(s, master, accountname):
|
||||||
s.c = master
|
s.c = master
|
||||||
s.children = []
|
s.children = []
|
||||||
|
s.accountname = accountname
|
||||||
|
|
||||||
def setwindow(s, window):
|
def setwindow(s, window):
|
||||||
s.window = 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:
|
for child in s.children:
|
||||||
child.update(window, 0, location)
|
child.update(window, 0, s.location)
|
||||||
location += 1
|
s.location += 1
|
||||||
|
|
||||||
def getnewthreadframe(s):
|
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)
|
s.children.append(tf)
|
||||||
return tf
|
return tf
|
||||||
|
|
||||||
@ -120,21 +124,32 @@ class CursesThreadFrame:
|
|||||||
'orange': s.c.getpair(curses.COLOR_YELLOW, bg),
|
'orange': s.c.getpair(curses.COLOR_YELLOW, bg),
|
||||||
'yellow': curses.A_BOLD | 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)}
|
'pink': curses.A_BOLD | s.c.getpair(curses.COLOR_RED, bg)}
|
||||||
s.setcolor('gray')
|
#s.setcolor('gray')
|
||||||
|
s.setcolor('black')
|
||||||
|
|
||||||
def setcolor(self, color):
|
def setcolor(self, color):
|
||||||
self.color = self.colormap[color]
|
self.color = self.colormap[color]
|
||||||
|
self.display()
|
||||||
|
|
||||||
|
def display(self):
|
||||||
self.window.addstr(self.y, self.x, '.', self.color)
|
self.window.addstr(self.y, self.x, '.', self.color)
|
||||||
self.window.refresh()
|
self.window.refresh()
|
||||||
|
|
||||||
def getcolor(self):
|
def getcolor(self):
|
||||||
return self.color
|
return self.color
|
||||||
|
|
||||||
|
def update(self, window, y, x):
|
||||||
|
self.window = window
|
||||||
|
self.y = y
|
||||||
|
self.x = x
|
||||||
|
self.display()
|
||||||
|
|
||||||
def setthread(self, newthread):
|
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:
|
class InputHandler:
|
||||||
def __init__(s, util):
|
def __init__(s, util):
|
||||||
@ -293,7 +308,7 @@ class Blinkenlights(BlinkenBase, UIBase):
|
|||||||
return s.af[accountname]
|
return s.af[accountname]
|
||||||
|
|
||||||
# New one.
|
# New one.
|
||||||
s.af[accountname] = CursesAccountFrame(s.c)
|
s.af[accountname] = CursesAccountFrame(s.c, accountname)
|
||||||
#s.iolock.acquire()
|
#s.iolock.acquire()
|
||||||
s.c.reset()
|
s.c.reset()
|
||||||
s.setupwindows(dolock = 0)
|
s.setupwindows(dolock = 0)
|
||||||
|
@ -55,8 +55,9 @@ class UIBase:
|
|||||||
"""Provides a hint to UIs about which account this particular
|
"""Provides a hint to UIs about which account this particular
|
||||||
thread is processing."""
|
thread is processing."""
|
||||||
if s.threadaccounts.has_key(threading.currentThread()):
|
if s.threadaccounts.has_key(threading.currentThread()):
|
||||||
raise ValueError, "Thread already registered (old %s, new %s)" % \
|
raise ValueError, "Thread %s already registered (old %s, new %s)" %\
|
||||||
(s.getthreadaccount(s), account)
|
(threading.currentThread().getName(),
|
||||||
|
s.getthreadaccount(s), account)
|
||||||
s.threadaccounts[threading.currentThread()] = account
|
s.threadaccounts[threading.currentThread()] = account
|
||||||
|
|
||||||
def unregisterthread(s, thr):
|
def unregisterthread(s, thr):
|
||||||
@ -69,7 +70,7 @@ class UIBase:
|
|||||||
thr = threading.currentThread()
|
thr = threading.currentThread()
|
||||||
if s.threadaccounts.has_key(thr):
|
if s.threadaccounts.has_key(thr):
|
||||||
return s.threadaccounts[thr]
|
return s.threadaccounts[thr]
|
||||||
return None
|
return '*Control'
|
||||||
|
|
||||||
def debug(s, debugtype, msg):
|
def debug(s, debugtype, msg):
|
||||||
thisthread = threading.currentThread()
|
thisthread = threading.currentThread()
|
||||||
|
Loading…
Reference in New Issue
Block a user