/head: changeset 62
Initial work on threading support
This commit is contained in:
		@@ -17,9 +17,10 @@
 | 
				
			|||||||
#    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 offlineimap import imaplib, imaputil, imapserver, repository, folder, mbnames
 | 
					from offlineimap import imaplib, imaputil, imapserver, repository, folder, mbnames, threadutil
 | 
				
			||||||
import re, os, os.path, offlineimap, sys
 | 
					import re, os, os.path, offlineimap, sys
 | 
				
			||||||
from ConfigParser import ConfigParser
 | 
					from ConfigParser import ConfigParser
 | 
				
			||||||
 | 
					from threading import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# imaplib.Debug = 5
 | 
					# imaplib.Debug = 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,6 +46,17 @@ accounts = accounts.split(",")
 | 
				
			|||||||
server = None
 | 
					server = None
 | 
				
			||||||
remoterepos = None
 | 
					remoterepos = None
 | 
				
			||||||
localrepos = None
 | 
					localrepos = None
 | 
				
			||||||
 | 
					passwords = {}
 | 
				
			||||||
 | 
					accountsemaphore = BoundedSemaphore(config.getint("general", "maxsyncaccounts"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# We have to gather passwords here -- don't want to have two threads
 | 
				
			||||||
 | 
					# asking for passwords simultaneously.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for account in accounts:
 | 
				
			||||||
 | 
					    if config.has_option(accountname, "remotepass"):
 | 
				
			||||||
 | 
					        passwords[account] = config.get(accountname, "remotepass")
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        passwords[account] = ui.getpass(accountname, config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def syncitall():
 | 
					def syncitall():
 | 
				
			||||||
    mailboxes = []
 | 
					    mailboxes = []
 | 
				
			||||||
@@ -58,17 +70,11 @@ def syncitall():
 | 
				
			|||||||
        port = None
 | 
					        port = None
 | 
				
			||||||
        if config.has_option(accountname, "remoteport"):
 | 
					        if config.has_option(accountname, "remoteport"):
 | 
				
			||||||
            port = config.getint(accountname, "remoteport")
 | 
					            port = config.getint(accountname, "remoteport")
 | 
				
			||||||
        password = None
 | 
					 | 
				
			||||||
        if config.has_option(accountname, "remotepass"):
 | 
					 | 
				
			||||||
            password = config.get(accountname, "remotepass")
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            password = ui.getpass(accountname, host, port, user)
 | 
					 | 
				
			||||||
            # Save it for future reference.
 | 
					 | 
				
			||||||
            config.set(accountname, "remotepass", password)
 | 
					 | 
				
			||||||
        ssl = config.getboolean(accountname, "ssl")
 | 
					        ssl = config.getboolean(accountname, "ssl")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Connect to the remote server.
 | 
					        # Connect to the remote server.
 | 
				
			||||||
        server = imapserver.IMAPServer(user, password, host, port, ssl)
 | 
					        server = imapserver.IMAPServer(user, passwords[accountname],
 | 
				
			||||||
 | 
					                                       host, port, ssl)
 | 
				
			||||||
        remoterepos = repository.IMAP.IMAPRepository(config, accountname, server)
 | 
					        remoterepos = repository.IMAP.IMAPRepository(config, accountname, server)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Connect to the Maildirs.
 | 
					        # Connect to the Maildirs.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +1,2 @@
 | 
				
			|||||||
import ui, folder, repository, mbnames
 | 
					import ui, folder, repository, mbnames, threadutil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@
 | 
				
			|||||||
#    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 offlineimap import imaplib, imaputil
 | 
					from offlineimap import imaplib, imaputil, threadutil
 | 
				
			||||||
from threading import *
 | 
					from threading import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UsefulIMAPMixIn:
 | 
					class UsefulIMAPMixIn:
 | 
				
			||||||
@@ -129,21 +129,17 @@ class IMAPServer:
 | 
				
			|||||||
        to copy messages, then have them all wait for 3 available connections.
 | 
					        to copy messages, then have them all wait for 3 available connections.
 | 
				
			||||||
        It's OK if we have maxconnections + 1 or 2 threads, which is what
 | 
					        It's OK if we have maxconnections + 1 or 2 threads, which is what
 | 
				
			||||||
        this will help us do."""
 | 
					        this will help us do."""
 | 
				
			||||||
        self.semaphore.acquire()
 | 
					        threadutil.semaphorewait(self.semaphore)
 | 
				
			||||||
        self.semaphore.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def close(self):
 | 
					    def close(self):
 | 
				
			||||||
        # Make sure I own all the semaphores.  Let the threads finish
 | 
					        # Make sure I own all the semaphores.  Let the threads finish
 | 
				
			||||||
        # their stuff.  This is a blocking method.
 | 
					        # their stuff.  This is a blocking method.
 | 
				
			||||||
        self.connectionlock.acquire()
 | 
					        self.connectionlock.acquire()
 | 
				
			||||||
        for i in range(self.maxconnections):
 | 
					        threadutil.semaphorereset(self.semaphore, self.maxconnections)
 | 
				
			||||||
            self.semaphore.acquire()
 | 
					 | 
				
			||||||
        for imapobj in self.assignedconnections + self.availableconnections:
 | 
					        for imapobj in self.assignedconnections + self.availableconnections:
 | 
				
			||||||
            imapobj.logout()
 | 
					            imapobj.logout()
 | 
				
			||||||
        self.assignedconnections = []
 | 
					        self.assignedconnections = []
 | 
				
			||||||
        self.availableconnections = []
 | 
					        self.availableconnections = []
 | 
				
			||||||
        for i in range(self.maxconnections):
 | 
					 | 
				
			||||||
            self.semaphore.release()
 | 
					 | 
				
			||||||
        self.connectionlock.release()
 | 
					        self.connectionlock.release()
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								head/offlineimap/threadutil.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								head/offlineimap/threadutil.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					# Copyright (C) 2002 John Goerzen
 | 
				
			||||||
 | 
					# Thread support module
 | 
				
			||||||
 | 
					# <jgoerzen@complete.org>
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					#    it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					#    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					#    (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					#    GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from Threading import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def semaphorewait(semaphore, originalstate):
 | 
				
			||||||
 | 
					    """Wait until the semaphore gets back to its original state -- all acquired
 | 
				
			||||||
 | 
					    resources released."""
 | 
				
			||||||
 | 
					    for i in range(originalstate):
 | 
				
			||||||
 | 
					        semaphore.acquire()
 | 
				
			||||||
 | 
					    # Now release these.
 | 
				
			||||||
 | 
					    for i in range(originalstate):
 | 
				
			||||||
 | 
					        semaphore.release()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
@@ -9,9 +9,10 @@ class TTYUI(UIBase):
 | 
				
			|||||||
    def _msg(s, msg):
 | 
					    def _msg(s, msg):
 | 
				
			||||||
        print msg
 | 
					        print msg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getpass(s, accountname, host, port, user):
 | 
					    def getpass(s, accountname, config):
 | 
				
			||||||
        return getpass("%s: Enter password for %s on %s: " %
 | 
					        return getpass("%s: Enter password for %s on %s: " %
 | 
				
			||||||
                       (accountname, user, host))
 | 
					                       (accountname, config.get(accountname, "remoteuser"),
 | 
				
			||||||
 | 
					                        config.get(accountname, "remotehost")))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def syncingmessages(s, sr, sf, dr, df):
 | 
					    def syncingmessages(s, sr, sf, dr, df):
 | 
				
			||||||
        if s.verbose:
 | 
					        if s.verbose:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ class UIBase:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ################################################## INPUT
 | 
					    ################################################## INPUT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getpass(s, accountname, host, port, user):
 | 
					    def getpass(s, accountname, config):
 | 
				
			||||||
        raise NotImplementedException
 | 
					        raise NotImplementedException
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def folderlist(s, list):
 | 
					    def folderlist(s, list):
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user