/offlineimap/head: changeset 305
Believed to be somewhat working now
This commit is contained in:
parent
8301e3015f
commit
0b7d75de60
@ -16,6 +16,9 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
from threading import *
|
||||||
|
import thread
|
||||||
|
|
||||||
class BlinkenBase:
|
class BlinkenBase:
|
||||||
"""This is a mix-in class that should be mixed in with either UIBase
|
"""This is a mix-in class that should be mixed in with either UIBase
|
||||||
or another appropriate base class. The Tk interface, for instance,
|
or another appropriate base class. The Tk interface, for instance,
|
||||||
@ -66,4 +69,59 @@ class BlinkenBase:
|
|||||||
s.gettf().setcolor('pink')
|
s.gettf().setcolor('pink')
|
||||||
s.__class__.__bases__[-1].deletingflags(s, uid, flags, destlist)
|
s.__class__.__bases__[-1].deletingflags(s, uid, flags, destlist)
|
||||||
|
|
||||||
|
def init_banner(s):
|
||||||
|
s.availablethreadframes = {}
|
||||||
|
s.threadframes = {}
|
||||||
|
s.tflock = Lock()
|
||||||
|
|
||||||
|
def threadExited(s, thread):
|
||||||
|
threadid = thread.threadid
|
||||||
|
accountname = s.getthreadaccount(thread)
|
||||||
|
s.tflock.acquire()
|
||||||
|
try:
|
||||||
|
if threadid in s.threadframes[accountname]:
|
||||||
|
tf = s.threadframes[accountname][threadid]
|
||||||
|
del s.threadframes[accountname][threadid]
|
||||||
|
s.availablethreadframes[accountname].append(tf)
|
||||||
|
tf.setthread(None)
|
||||||
|
finally:
|
||||||
|
s.tflock.release()
|
||||||
|
|
||||||
|
UIBase.threadExited(s, thread)
|
||||||
|
|
||||||
|
def gettf(s):
|
||||||
|
threadid = thread.get_ident()
|
||||||
|
accountname = s.getthreadaccount()
|
||||||
|
|
||||||
|
s.tflock.acquire()
|
||||||
|
|
||||||
|
print "b98"
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not accountname in s.threadframes:
|
||||||
|
s.threadframes[accountname] = {}
|
||||||
|
|
||||||
|
if threadid in s.threadframes[accountname]:
|
||||||
|
return s.threadframes[accountname][threadid]
|
||||||
|
|
||||||
|
print 'b107'
|
||||||
|
|
||||||
|
if not accountname in s.availablethreadframes:
|
||||||
|
s.availablethreadframes[accountname] = []
|
||||||
|
|
||||||
|
print 'b112'
|
||||||
|
|
||||||
|
if len(s.availablethreadframes[accountname]):
|
||||||
|
tf = s.availablethreadframes[accountname].pop(0)
|
||||||
|
tf.setthread(currentThread())
|
||||||
|
else:
|
||||||
|
print 'b118'
|
||||||
|
tf = s.getaccountframe().getnewthreadframe()
|
||||||
|
print 'b120'
|
||||||
|
s.threadframes[accountname][threadid] = tf
|
||||||
|
return tf
|
||||||
|
|
||||||
|
finally:
|
||||||
|
s.tflock.release()
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,14 +79,35 @@ class CursesUtil:
|
|||||||
curses.endwin()
|
curses.endwin()
|
||||||
del self.stdscr
|
del self.stdscr
|
||||||
|
|
||||||
def resize(self):
|
def reset(self):
|
||||||
self.stop()
|
self.stop()
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
class CursesThreadFrame:
|
class CursesAccountFrame:
|
||||||
def __init__(s, master):
|
def __init__(s, master):
|
||||||
|
s.c = master
|
||||||
|
s.children = []
|
||||||
|
|
||||||
|
def setwindow(s, window):
|
||||||
|
s.window = window
|
||||||
|
location = 0
|
||||||
|
for child in s.children:
|
||||||
|
child.update(window, 0, location)
|
||||||
|
location += 1
|
||||||
|
|
||||||
|
def getnewthreadframe(s):
|
||||||
|
tf = CursesThreadFrame(s.c, s.window, 0, len(s.children))
|
||||||
|
s.children.append(tf)
|
||||||
|
return tf
|
||||||
|
|
||||||
|
class CursesThreadFrame:
|
||||||
|
def __init__(s, master, window, y, x):
|
||||||
"""master should be a CursesUtil object."""
|
"""master should be a CursesUtil object."""
|
||||||
s.c = master
|
s.c = master
|
||||||
|
s.window = window
|
||||||
|
s.x = x
|
||||||
|
s.y = y
|
||||||
|
s.colors = []
|
||||||
bg = curses.COLOR_BLACK
|
bg = curses.COLOR_BLACK
|
||||||
s.colormap = {'black': s.c.getpair(curses.COLOR_BLACK, bg),
|
s.colormap = {'black': s.c.getpair(curses.COLOR_BLACK, bg),
|
||||||
'gray': s.c.getpair(curses.COLOR_WHITE, bg),
|
'gray': s.c.getpair(curses.COLOR_WHITE, bg),
|
||||||
@ -100,13 +121,21 @@ class CursesThreadFrame:
|
|||||||
'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')
|
||||||
|
|
||||||
def setcolor(self, color):
|
def setcolor(self, color):
|
||||||
self.color = self.colormap[color]
|
self.color = self.colormap[color]
|
||||||
|
self.window.addstr(self.y, self.x, '.', self.color)
|
||||||
|
self.window.refresh()
|
||||||
|
|
||||||
def getcolor(self):
|
def getcolor(self):
|
||||||
return self.color
|
return self.color
|
||||||
|
|
||||||
|
def setthread(self, newthread):
|
||||||
|
if newthread:
|
||||||
|
self.setcolor('gray')
|
||||||
|
else:
|
||||||
|
self.setcolor('black')
|
||||||
|
|
||||||
class InputHandler:
|
class InputHandler:
|
||||||
def __init__(s, util):
|
def __init__(s, util):
|
||||||
s.c = util
|
s.c = util
|
||||||
@ -181,12 +210,18 @@ class InputHandler:
|
|||||||
class Blinkenlights(BlinkenBase, UIBase):
|
class Blinkenlights(BlinkenBase, UIBase):
|
||||||
def init_banner(s):
|
def init_banner(s):
|
||||||
s.iolock = Lock()
|
s.iolock = Lock()
|
||||||
|
s.af = {}
|
||||||
|
s.aflock = Lock()
|
||||||
s.c = CursesUtil()
|
s.c = CursesUtil()
|
||||||
s.accounts = []
|
|
||||||
s.text = []
|
s.text = []
|
||||||
s.tf = CursesThreadFrame(s.c)
|
BlinkenBase.init_banner(s)
|
||||||
s.setupwindows()
|
print 217
|
||||||
|
s.setupwindows(dolock = 0)
|
||||||
|
print '219a'
|
||||||
s.inputhandler = InputHandler(s.c)
|
s.inputhandler = InputHandler(s.c)
|
||||||
|
print 219
|
||||||
|
print 221
|
||||||
|
|
||||||
s._msg(version.banner)
|
s._msg(version.banner)
|
||||||
s._msg(str(dir(s.c.stdscr)))
|
s._msg(str(dir(s.c.stdscr)))
|
||||||
s.inputhandler.set_bgchar(s.keypress)
|
s.inputhandler.set_bgchar(s.keypress)
|
||||||
@ -209,17 +244,43 @@ class Blinkenlights(BlinkenBase, UIBase):
|
|||||||
s.inputhandler.input_release()
|
s.inputhandler.input_release()
|
||||||
return password
|
return password
|
||||||
|
|
||||||
def setupwindows(s):
|
def setupwindows(s, dolock = 1):
|
||||||
s.bannerwindow = curses.newwin(1, s.c.width, 0, 0)
|
print 244
|
||||||
s.drawbanner()
|
if dolock:
|
||||||
s.logheight = s.c.height - 1 - len(s.accounts) * 2
|
s.iolock.acquire()
|
||||||
s.logwindow = curses.newwin(s.logheight, s.c.width, 1, 0)
|
try:
|
||||||
s.logwindow.idlok(1)
|
s.bannerwindow = curses.newwin(1, s.c.width, 0, 0)
|
||||||
s.logwindow.scrollok(1)
|
s.setupwindow_drawbanner()
|
||||||
s.drawlog()
|
s.logheight = s.c.height - 1 - len(s.af.keys())
|
||||||
curses.doupdate()
|
s.logwindow = curses.newwin(s.logheight, s.c.width, 1, 0)
|
||||||
|
s.logwindow.idlok(1)
|
||||||
|
s.logwindow.scrollok(1)
|
||||||
|
s.setupwindow_drawlog()
|
||||||
|
|
||||||
def drawbanner(s):
|
print 258
|
||||||
|
|
||||||
|
accounts = s.af.keys()
|
||||||
|
accounts.sort()
|
||||||
|
accounts.reverse()
|
||||||
|
|
||||||
|
print 264
|
||||||
|
|
||||||
|
pos = s.c.height - 1
|
||||||
|
for account in accounts:
|
||||||
|
accountwindow = curses.newwin(1, s.c.width, pos, 0)
|
||||||
|
s.af[account].setwindow(accountwindow)
|
||||||
|
pos -= 1
|
||||||
|
|
||||||
|
print 272
|
||||||
|
|
||||||
|
curses.doupdate()
|
||||||
|
|
||||||
|
print 276
|
||||||
|
finally:
|
||||||
|
if dolock:
|
||||||
|
s.iolock.release()
|
||||||
|
|
||||||
|
def setupwindow_drawbanner(s):
|
||||||
s.bannerwindow.bkgd(' ', curses.A_BOLD | \
|
s.bannerwindow.bkgd(' ', curses.A_BOLD | \
|
||||||
s.c.getpair(curses.COLOR_WHITE,
|
s.c.getpair(curses.COLOR_WHITE,
|
||||||
curses.COLOR_BLUE))
|
curses.COLOR_BLUE))
|
||||||
@ -227,21 +288,36 @@ class Blinkenlights(BlinkenBase, UIBase):
|
|||||||
version.versionstr))
|
version.versionstr))
|
||||||
s.bannerwindow.addstr(0, s.bannerwindow.getmaxyx()[1] - len(version.copyright) - 1,
|
s.bannerwindow.addstr(0, s.bannerwindow.getmaxyx()[1] - len(version.copyright) - 1,
|
||||||
version.copyright)
|
version.copyright)
|
||||||
|
|
||||||
s.bannerwindow.noutrefresh()
|
s.bannerwindow.noutrefresh()
|
||||||
|
|
||||||
def drawlog(s):
|
def setupwindow_drawlog(s):
|
||||||
s.iolock.acquire()
|
s.logwindow.bkgd(' ', s.c.getpair(curses.COLOR_WHITE, curses.COLOR_BLACK))
|
||||||
try:
|
for line, color in s.text:
|
||||||
s.logwindow.bkgd(' ', s.c.getpair(curses.COLOR_WHITE, curses.COLOR_BLACK))
|
s.logwindow.addstr(line + "\n", color)
|
||||||
for line, color in s.text:
|
s.logwindow.noutrefresh()
|
||||||
s.logwindow.addstr(line + "\n", color)
|
|
||||||
s.logwindow.noutrefresh()
|
def getaccountframe(s):
|
||||||
finally:
|
accountname = s.getthreadaccount()
|
||||||
s.iolock.release()
|
print 'c302: ', accountname
|
||||||
|
s.aflock.acquire()
|
||||||
|
print 'c304'
|
||||||
|
try:
|
||||||
|
if accountname in s.af:
|
||||||
|
return s.af[accountname]
|
||||||
|
|
||||||
|
# New one.
|
||||||
|
s.af[accountname] = CursesAccountFrame(s.c)
|
||||||
|
#s.iolock.acquire()
|
||||||
|
print 297
|
||||||
|
s.c.reset()
|
||||||
|
s.setupwindows(dolock = 0)
|
||||||
|
print 300
|
||||||
|
#s.iolock.release()
|
||||||
|
finally:
|
||||||
|
s.aflock.release()
|
||||||
|
return s.af[accountname]
|
||||||
|
|
||||||
def gettf(s):
|
|
||||||
return s.tf
|
|
||||||
|
|
||||||
def _msg(s, msg, color = None):
|
def _msg(s, msg, color = None):
|
||||||
if "\n" in msg:
|
if "\n" in msg:
|
||||||
@ -249,6 +325,7 @@ class Blinkenlights(BlinkenBase, UIBase):
|
|||||||
s._msg(thisline)
|
s._msg(thisline)
|
||||||
return
|
return
|
||||||
s.iolock.acquire()
|
s.iolock.acquire()
|
||||||
|
print 326
|
||||||
try:
|
try:
|
||||||
if not s.c.isactive():
|
if not s.c.isactive():
|
||||||
# For dumping out exceptions and stuff.
|
# For dumping out exceptions and stuff.
|
||||||
@ -258,6 +335,7 @@ class Blinkenlights(BlinkenBase, UIBase):
|
|||||||
s.gettf().setcolor(color)
|
s.gettf().setcolor(color)
|
||||||
s._addline_unlocked(msg, s.gettf().getcolor())
|
s._addline_unlocked(msg, s.gettf().getcolor())
|
||||||
s.logwindow.refresh()
|
s.logwindow.refresh()
|
||||||
|
print 336
|
||||||
finally:
|
finally:
|
||||||
s.iolock.release()
|
s.iolock.release()
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
import offlineimap.version
|
import offlineimap.version
|
||||||
import re, time, sys, traceback, threading
|
import re, time, sys, traceback, threading, thread
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
debugtypes = {'imap': 'IMAP protocol debugging',
|
debugtypes = {'imap': 'IMAP protocol debugging',
|
||||||
@ -38,6 +38,7 @@ class UIBase:
|
|||||||
s.debuglist = []
|
s.debuglist = []
|
||||||
s.debugmessages = {}
|
s.debugmessages = {}
|
||||||
s.debugmsglen = 50
|
s.debugmsglen = 50
|
||||||
|
s.threadaccounts = {}
|
||||||
|
|
||||||
################################################## UTILS
|
################################################## UTILS
|
||||||
def _msg(s, msg):
|
def _msg(s, msg):
|
||||||
@ -50,6 +51,24 @@ class UIBase:
|
|||||||
else:
|
else:
|
||||||
s._msg("WARNING: " + msg)
|
s._msg("WARNING: " + msg)
|
||||||
|
|
||||||
|
def registerthread(s, account):
|
||||||
|
"""Provides a hint to UIs about which account this particular
|
||||||
|
thread is processing."""
|
||||||
|
if s.threadaccounts.has_key(thread.get_ident()):
|
||||||
|
raise ValueError, "Thread already registered (old %s, new %s)" % \
|
||||||
|
(s.getthreadaccount(s), account)
|
||||||
|
s.threadaccounts[thread.get_ident()] = account
|
||||||
|
|
||||||
|
def unregisterthread(s, thr):
|
||||||
|
"""Recognizes a thread has exited."""
|
||||||
|
if s.threadaccounts.has_key(thr):
|
||||||
|
del s.threadaccounts[thr]
|
||||||
|
|
||||||
|
def getthreadaccount(s):
|
||||||
|
if s.threadaccounts.has_key(thread.get_ident()):
|
||||||
|
return s.threadaccounts[thread.get_ident()]
|
||||||
|
return None
|
||||||
|
|
||||||
def debug(s, debugtype, msg):
|
def debug(s, debugtype, msg):
|
||||||
thisthread = threading.currentThread()
|
thisthread = threading.currentThread()
|
||||||
if s.debugmessages.has_key(thisthread):
|
if s.debugmessages.has_key(thisthread):
|
||||||
@ -258,6 +277,7 @@ class UIBase:
|
|||||||
"""Called when a thread has exited normally. Many UIs will
|
"""Called when a thread has exited normally. Many UIs will
|
||||||
just ignore this."""
|
just ignore this."""
|
||||||
s.delThreadDebugLog(thread)
|
s.delThreadDebugLog(thread)
|
||||||
|
s.unregisterthread(thread)
|
||||||
|
|
||||||
################################################## Other
|
################################################## Other
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user