rev 305 - offlineimap/head/offlineimap/ui

[email protected] Sat, 4 Jan 2003 23:50:08 -0600 (CST)
Newsgroups gmane.mail.imap.offlineimap.subversion
Message-ID <[email protected]>
Author: jgoerzen
Date: 2003-01-04 23:50:01 -0600 (Sat, 04 Jan 2003)
New Revision: 305

Modified:
   offlineimap/head/offlineimap/ui/Blinkenlights.py
   offlineimap/head/offlineimap/ui/Curses.py
   offlineimap/head/offlineimap/ui/UIBase.py
Log:
Believed to be somewhat working now


Modified: offlineimap/head/offlineimap/ui/UIBase.py
==============================================================================
--- offlineimap/head/offlineimap/ui/UIBase.py	(original)
+++ offlineimap/head/offlineimap/ui/UIBase.py	Sat Jan  4 23:50:06 2003
@@ -17,7 +17,7 @@
 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 import offlineimap.version
-import re, time, sys, traceback, threading
+import re, time, sys, traceback, threading, thread
 from StringIO import StringIO
 
 debugtypes = {'imap': 'IMAP protocol debugging',
@@ -38,6 +38,7 @@
         s.debuglist = []
         s.debugmessages = {}
         s.debugmsglen = 50
+        s.threadaccounts = {}
     
     ################################################## UTILS
     def _msg(s, msg):
@@ -50,6 +51,24 @@
         else:
             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):
         thisthread = threading.currentThread()
         if s.debugmessages.has_key(thisthread):
@@ -258,6 +277,7 @@
         """Called when a thread has exited normally.  Many UIs will
         just ignore this."""
         s.delThreadDebugLog(thread)
+        s.unregisterthread(thread)
 
     ################################################## Other
 

Modified: offlineimap/head/offlineimap/ui/Blinkenlights.py
==============================================================================
--- offlineimap/head/offlineimap/ui/Blinkenlights.py	(original)
+++ offlineimap/head/offlineimap/ui/Blinkenlights.py	Sat Jan  4 23:50:06 2003
@@ -16,6 +16,9 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+from threading import *
+import thread
+
 class BlinkenBase:
     """This is a mix-in class that should be mixed in with either UIBase
     or another appropriate base class.  The Tk interface, for instance,
@@ -66,4 +69,59 @@
         s.gettf().setcolor('pink')
         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()
+        
 

Modified: offlineimap/head/offlineimap/ui/Curses.py
==============================================================================
--- offlineimap/head/offlineimap/ui/Curses.py	(original)
+++ offlineimap/head/offlineimap/ui/Curses.py	Sat Jan  4 23:50:06 2003
@@ -79,14 +79,35 @@
         curses.endwin()
         del self.stdscr
 
-    def resize(self):
+    def reset(self):
         self.stop()
         self.start()
 
-class CursesThreadFrame:
+class CursesAccountFrame:
     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."""
         s.c = master
+        s.window = window
+        s.x = x
+        s.y = y
+        s.colors = []
         bg = curses.COLOR_BLACK
         s.colormap = {'black': s.c.getpair(curses.COLOR_BLACK, bg),
                          'gray': s.c.getpair(curses.COLOR_WHITE, bg),
@@ -100,13 +121,21 @@
                          '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')
-                         
+
     def setcolor(self, color):
         self.color = self.colormap[color]
+        self.window.addstr(self.y, self.x, '.', self.color)
+        self.window.refresh()
 
     def getcolor(self):
         return self.color
 
+    def setthread(self, newthread):
+        if newthread:
+            self.setcolor('gray')
+        else:
+            self.setcolor('black')
+
 class InputHandler:
     def __init__(s, util):
         s.c = util
@@ -181,12 +210,18 @@
 class Blinkenlights(BlinkenBase, UIBase):
     def init_banner(s):
         s.iolock = Lock()
+        s.af = {}
+        s.aflock = Lock()
         s.c = CursesUtil()
-        s.accounts = []
         s.text = []
-        s.tf = CursesThreadFrame(s.c)
-        s.setupwindows()
+        BlinkenBase.init_banner(s)
+        print 217
+        s.setupwindows(dolock = 0)
+        print '219a'
         s.inputhandler = InputHandler(s.c)
+        print 219
+        print 221
+        
         s._msg(version.banner)
         s._msg(str(dir(s.c.stdscr)))
         s.inputhandler.set_bgchar(s.keypress)
@@ -209,17 +244,43 @@
             s.inputhandler.input_release()
         return password
 
-    def setupwindows(s):
-        s.bannerwindow = curses.newwin(1, s.c.width, 0, 0)
-        s.drawbanner()
-        s.logheight = s.c.height - 1 - len(s.accounts) * 2
-        s.logwindow = curses.newwin(s.logheight, s.c.width, 1, 0)
-        s.logwindow.idlok(1)
-        s.logwindow.scrollok(1)
-        s.drawlog()
-        curses.doupdate()
+    def setupwindows(s, dolock = 1):
+        print 244
+        if dolock:
+            s.iolock.acquire()
+        try:
+            s.bannerwindow = curses.newwin(1, s.c.width, 0, 0)
+            s.setupwindow_drawbanner()
+            s.logheight = s.c.height - 1 - len(s.af.keys())
+            s.logwindow = curses.newwin(s.logheight, s.c.width, 1, 0)
+            s.logwindow.idlok(1)
+            s.logwindow.scrollok(1)
+            s.setupwindow_drawlog()
+
+            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()
 
-    def drawbanner(s):
+            print 276
+        finally:
+            if dolock:
+                s.iolock.release()
+
+    def setupwindow_drawbanner(s):
         s.bannerwindow.bkgd(' ', curses.A_BOLD | \
                             s.c.getpair(curses.COLOR_WHITE,
                                         curses.COLOR_BLUE))
@@ -227,21 +288,36 @@
                                          version.versionstr))
         s.bannerwindow.addstr(0, s.bannerwindow.getmaxyx()[1] - len(version.copyright) - 1,
                               version.copyright)
-
+        
         s.bannerwindow.noutrefresh()
 
-    def drawlog(s):
-        s.iolock.acquire()
+    def setupwindow_drawlog(s):
+        s.logwindow.bkgd(' ', s.c.getpair(curses.COLOR_WHITE, curses.COLOR_BLACK))
+        for line, color in s.text:
+            s.logwindow.addstr(line + "\n", color)
+            s.logwindow.noutrefresh()
+
+    def getaccountframe(s):
+        accountname = s.getthreadaccount()
+        print 'c302: ', accountname
+        s.aflock.acquire()
+        print 'c304'
         try:
-            s.logwindow.bkgd(' ', s.c.getpair(curses.COLOR_WHITE, curses.COLOR_BLACK))
-            for line, color in s.text:
-                s.logwindow.addstr(line + "\n", color)
-                s.logwindow.noutrefresh()
+            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.iolock.release()
+            s.aflock.release()
+        return s.af[accountname]
 
-    def gettf(s):
-        return s.tf
 
     def _msg(s, msg, color = None):
         if "\n" in msg:
@@ -249,6 +325,7 @@
                 s._msg(thisline)
             return
         s.iolock.acquire()
+        print 326
         try:
             if not s.c.isactive():
                 # For dumping out exceptions and stuff.
@@ -258,6 +335,7 @@
                 s.gettf().setcolor(color)
             s._addline_unlocked(msg, s.gettf().getcolor())
             s.logwindow.refresh()
+            print 336
         finally:
             s.iolock.release()