Example #1
0
def new_mesg(self, s, tn=None, secs=None):
            if secs is None:
                secs = time.time()
            if tn is None:
                tn = threading.currentThread().getName()
            tm = time.strftime('%M:%S', time.localtime(secs))
            getglobalui().debug('imap', '  %s.%02d %s %s' % (tm, (secs*100)%100, tn, s))
Example #2
0
def prime_gpg_agent():
    ret = False
    count = 1
    while not ret:
        ret = (mailpasswd("prime")=="prime")
        if count>2:
            from offlineimap.ui import getglobalui
            sys.stderr.write("Error reading in passwords. Terminating.\n")
            getglobalui().terminate()
        count += 1
    return ret
Example #3
0
def prime_gpg_agent():
    # echo "prime" | gpg -e -r <recipient> > ~/.offlineimap/prime.gpg
    ret = False
    i = 1
    while not ret:
        ret = (mailpasswd("prime") == "prime")
        if i > 2:
            from offlineimap.ui import getglobalui
            sys.stderr.write("Error reading in passwords. Terminating.\n")
            getglobalui().terminate()
        i += 1
    return ret
Example #4
0
 def sig_handler(sig, frame):
     if sig == signal.SIGUSR1 or sig == signal.SIGHUP:
         # tell each account to stop sleeping
         accounts.Account.set_abort_event(self.config, 1)
     elif sig == signal.SIGUSR2:
         # tell each account to stop looping
         getglobalui().warn("Terminating after this sync...")
         accounts.Account.set_abort_event(self.config, 2)
     elif sig == signal.SIGTERM or sig == signal.SIGINT:
         # tell each account to ABORT ASAP (ctrl-c)
         getglobalui().warn("Terminating NOW (this may "\
                            "take a few seconds)...")
         accounts.Account.set_abort_event(self.config, 3)
Example #5
0
 def sig_handler(sig, frame):
     if sig == signal.SIGUSR1:
         # tell each account to stop sleeping
         accounts.Account.set_abort_event(self.config, 1)
     elif sig == signal.SIGUSR2:
         # tell each account to stop looping
         getglobalui().warn("Terminating after this sync...")
         accounts.Account.set_abort_event(self.config, 2)
     elif sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP):
         # tell each account to ABORT ASAP (ctrl-c)
         getglobalui().warn("Terminating NOW (this may " "take a few seconds)...")
         accounts.Account.set_abort_event(self.config, 3)
     elif sig == signal.SIGQUIT:
         stacktrace.dump(sys.stderr)
         os.abort()
Example #6
0
    def __init__(self, name, repository):
        """
        :param name: Path & name of folder minus root or reference
        :param repository: Repository() in which the folder is.
        """

        self.ui = getglobalui()
        self.messagelist = {}
        # Save original name for folderfilter operations.
        self.ffilter_name = name
        # Top level dir name is always ''.
        self.root = None
        self.name = name if not name == self.getsep() else ''
        self.newmail_hook = None
        # Only set the newmail_hook if the IMAP folder is named 'INBOX'.
        if self.name == 'INBOX':
            self.newmail_hook = repository.newmail_hook
        self.have_newmail = False
        self.copy_ignoreUIDs = None # List of UIDs to ignore.
        self.repository = repository
        self.visiblename = repository.nametrans(name)
        # In case the visiblename becomes '.' or '/' (top-level) we use
        # '' as that is the name that e.g. the Maildir scanning will
        # return for the top-level dir.
        if self.visiblename == self.getsep():
            self.visiblename = ''

        self.repoconfname = "Repository " + repository.name

        self.config = repository.getconfig()

        # Do we need to use mail timestamp for filename prefix?
        filename_use_mail_timestamp_global = self.config.getdefaultboolean(
            "general", "filename_use_mail_timestamp", False)
        self._filename_use_mail_timestamp = self.config.getdefaultboolean(
            self.repoconfname,
            "filename_use_mail_timestamp",
            filename_use_mail_timestamp_global)

        self._sync_deletes = self.config.getdefaultboolean(
            self.repoconfname, "sync_deletes", True)

        # Determine if we're running static or dynamic folder filtering
        # and check filtering status.
        self._dynamic_folderfilter = self.config.getdefaultboolean(
            self.repoconfname, "dynamic_folderfilter", False)
        self._sync_this = repository.should_sync_folder(self.ffilter_name)
        if self._dynamic_folderfilter:
            self.ui.debug('', "Running dynamic folder filtering on '%s'[%s]"%
                (self.ffilter_name, repository))
        elif not self._sync_this:
            self.ui.debug('', "Filtering out '%s'[%s] due to folderfilter"%
                (self.ffilter_name, repository))

        # Passes for syncmessagesto.
        self.syncmessagesto_passes = [
            self.__syncmessagesto_copy,
            self.__syncmessagesto_delete,
            self.__syncmessagesto_flags,
        ]
Example #7
0
def prime_gpg_agent():
    ret = False
    i = 1
    while not ret:
        x = ""
        try:
            x = subprocess.check_output(["pass", "show", "prime"]).strip()
        except subprocess.CalledProcessError:
            x = ""
        ret = (x == "prime")
        if i > 2:
            from offlineimap.ui import getglobalui
            sys.stderr.write("Error reading in passwords. Terminating.\n")
            getglobalui().terminate()
        i += 1
        return ret
Example #8
0
 def __init__(self, repos):
     self.ui = getglobalui()
     self.repos = repos
     self.config = repos.getconfig()
     self.tunnel = repos.getpreauthtunnel()
     self.usessl = repos.getssl()
     self.username = None if self.tunnel else repos.getuser()
     self.password = None
     self.passworderror = None
     self.goodpassword = None
     self.hostname = None if self.tunnel else repos.gethost()
     self.port = repos.getport()
     if self.port == None:
         self.port = 993 if self.usessl else 143
     self.sslclientcert = repos.getsslclientcert()
     self.sslclientkey = repos.getsslclientkey()
     self.sslcacertfile = repos.getsslcacertfile()
     if self.sslcacertfile is None:
         self.verifycert = None  # disable cert verification
     self.delim = None
     self.root = None
     self.maxconnections = repos.getmaxconnections()
     self.availableconnections = []
     self.assignedconnections = []
     self.lastowner = {}
     self.semaphore = BoundedSemaphore(self.maxconnections)
     self.connectionlock = Lock()
     self.reference = repos.getreference()
     self.idlefolders = repos.getidlefolders()
     self.gss_step = self.GSS_STATE_STEP
     self.gss_vc = None
     self.gssapi = False
Example #9
0
    def __init__(self, name, repository):
        """
        :para name: Path & name of folder minus root or reference
        :para repository: Repository() in which the folder is.
        """
        self.ui = getglobalui()
        """Should this folder be included in syncing?"""
        self._sync_this = repository.should_sync_folder(name)
        if not self._sync_this:
            self.ui.debug('', "Filtering out '%s'[%s] due to folderfilter" \
                          % (name, repository))
        # Top level dir name is always ''
        self.name = name if not name == self.getsep() else ''
        self.repository = repository
        self.visiblename = repository.nametrans(name)
        # In case the visiblename becomes '.' or '/' (top-level) we use
        # '' as that is the name that e.g. the Maildir scanning will
        # return for the top-level dir.
        if self.visiblename == self.getsep():
            self.visiblename = ''
        self.config = repository.getconfig()

        # Passes for syncmessagesto
        self.syncmessagesto_passes = [('copying messages'       , self.syncmessagesto_copy),
                                      ('deleting messages'      , self.syncmessagesto_delete),
                                      ('syncing flags'          , self.syncmessagesto_flags)]
Example #10
0
    def __init__(self, config, name):
        """
        :param config: Representing the offlineimap configuration file.
        :type config: :class:`offlineimap.CustomConfig.CustomConfigParser`

        :param name: A (str) string denoting the name of the Account
                     as configured.
        """

        self.config = config
        self.name = name
        self.metadatadir = config.getmetadatadir()
        self.localeval = config.getlocaleval()
        # Current :mod:`offlineimap.ui`, can be used for logging:
        self.ui = getglobalui()
        self.refreshperiod = self.getconffloat('autorefresh', 0.0)
        self.dryrun = self.config.getboolean('general', 'dry-run')
        self.quicknum = 0
        if self.refreshperiod < 0:
            self.ui.warn("autorefresh for %s is negative, fixing it to 0."%
                    name)
            self.refreshperiod = 0.0
        if self.refreshperiod == 0.0:
            self.refreshperiod = None
        self.remoterepos = None
        self.localrepos = None
        self.statusrepos = None
Example #11
0
    def __init__(self, name, repository):
        """
        :para name: Path & name of folder minus root or reference
        :para repository: Repository() in which the folder is.
        """
        self.ui = getglobalui()
        """Should this folder be included in syncing?"""
        self._sync_this = repository.should_sync_folder(name)
        if not self._sync_this:
            self.ui.debug("", "Filtering out '%s'[%s] due to folderfilter" % (name, repository))
        # Top level dir name is always ''
        self.name = name if not name == self.getsep() else ""
        self.repository = repository
        self.visiblename = repository.nametrans(name)
        # In case the visiblename becomes '.' or '/' (top-level) we use
        # '' as that is the name that e.g. the Maildir scanning will
        # return for the top-level dir.
        if self.visiblename == self.getsep():
            self.visiblename = ""
        self.config = repository.getconfig()

        # Passes for syncmessagesto
        self.syncmessagesto_passes = [
            ("copying messages", self.syncmessagesto_copy),
            ("deleting messages", self.syncmessagesto_delete),
            ("syncing flags", self.syncmessagesto_flags),
        ]
Example #12
0
 def __init__(self, name, repository):
     """
     :para name: Path & name of folder minus root or reference
     :para repository: Repository() in which the folder is.
     """
     self.ui = getglobalui()
     """Should this folder be included in syncing?"""
     self._sync_this = repository.should_sync_folder(name)
     if not self._sync_this:
         self.ui.debug('', "Filtering out '%s'[%s] due to folderfilter" \
                       % (name, repository))
     # Top level dir name is always ''
     self.name = name if not name == self.getsep() else ''
     self.repository = repository
     self.visiblename = repository.nametrans(name)
     # In case the visiblename becomes '.' or '/' (top-level) we use
     # '' as that is the name that e.g. the Maildir scanning will
     # return for the top-level dir.
     if self.visiblename == self.getsep():
         self.visiblename = ''
     self.config = repository.getconfig()
     utime_from_message_global = \
       self.config.getdefaultboolean("general",
       "utime_from_message", False)
     repo = "Repository " + repository.name
     self._utime_from_message = \
       self.config.getdefaultboolean(repo,
       "utime_from_message", utime_from_message_global)
Example #13
0
def prime_gpg_agent():
    ret = False
    i = 1
    while not ret:
        x = ""
        try:
            x = subprocess.check_output(["pass", "show", "prime"]).strip()
        except subprocess.CalledProcessError:
            x = ""
        ret = (x == "prime")
        if i > 2:
            from offlineimap.ui import getglobalui
            sys.stderr.write("Error reading in passwords. Terminating.\n")
            getglobalui().terminate()
        i += 1
        return ret
Example #14
0
 def __init__(self, repos):
     self.ui = getglobalui()
     self.repos = repos
     self.config = repos.getconfig()
     self.tunnel = repos.getpreauthtunnel()
     self.usessl = repos.getssl()
     self.username = repos.getuser()
     self.password = None
     self.passworderror = None
     self.goodpassword = None
     self.hostname = repos.gethost()
     self.port = repos.getport()
     if self.port == None:
         self.port = 993 if self.usessl else 143
     self.sslclientcert = repos.getsslclientcert()
     self.sslclientkey = repos.getsslclientkey()
     self.sslcacertfile = repos.getsslcacertfile()
     if self.sslcacertfile is None:
         self.verifycert = None # disable cert verification
     self.delim = None
     self.root = None
     self.maxconnections = repos.getmaxconnections()
     self.availableconnections = []
     self.assignedconnections = []
     self.lastowner = {}
     self.semaphore = BoundedSemaphore(self.maxconnections)
     self.connectionlock = Lock()
     self.reference = repos.getreference()
     self.idlefolders = repos.getidlefolders()
     self.gss_step = self.GSS_STATE_STEP
     self.gss_vc = None
     self.gssapi = False
Example #15
0
 def __init__(self, name, repository):
     """
     :para name: Path & name of folder minus root or reference
     :para repository: Repository() in which the folder is.
     """
     self.ui = getglobalui()
     """Should this folder be included in syncing?"""
     self._sync_this = repository.should_sync_folder(name)
     if not self._sync_this:
         self.ui.debug('', "Filtering out '%s'[%s] due to folderfilter" \
                       % (name, repository))
     # Top level dir name is always ''
     self.name = name if not name == self.getsep() else ''
     self.repository = repository
     self.visiblename = repository.nametrans(name)
     # In case the visiblename becomes '.' or '/' (top-level) we use
     # '' as that is the name that e.g. the Maildir scanning will
     # return for the top-level dir.
     if self.visiblename == self.getsep():
         self.visiblename = ''
     self.config = repository.getconfig()
     utime_from_message_global = \
       self.config.getdefaultboolean("general",
       "utime_from_message", False)
     repo = "Repository " + repository.name
     self._utime_from_message = \
       self.config.getdefaultboolean(repo,
       "utime_from_message", utime_from_message_global)
Example #16
0
    def __init__(self, reposname, account):
        self.ui = getglobalui()
        self.account = account
        self.config = account.getconfig()
        self.name = reposname
        self.localeval = account.getlocaleval()
        self._accountname = self.account.getname()
        self._readonly = self.getconfboolean('readonly', False)
        self.uiddir = os.path.join(self.config.getmetadatadir(), 'Repository-' + self.name)
        if not os.path.exists(self.uiddir):
            os.mkdir(self.uiddir, 0o700)
        self.mapdir = os.path.join(self.uiddir, 'UIDMapping')
        if not os.path.exists(self.mapdir):
            os.mkdir(self.mapdir, 0o700)
        self.uiddir = os.path.join(self.uiddir, 'FolderValidity')
        if not os.path.exists(self.uiddir):
            os.mkdir(self.uiddir, 0o700)

        self.nametrans = lambda foldername: foldername
        self.folderfilter = lambda foldername: 1
        self.folderincludes = []
        self.foldersort = None
        if self.config.has_option(self.getsection(), 'nametrans'):
            self.nametrans = self.localeval.eval(
                self.getconf('nametrans'), {'re': re})
        if self.config.has_option(self.getsection(), 'folderfilter'):
            self.folderfilter = self.localeval.eval(
                self.getconf('folderfilter'), {'re': re})
        if self.config.has_option(self.getsection(), 'folderincludes'):
            self.folderincludes = self.localeval.eval(
                self.getconf('folderincludes'), {'re': re})
        if self.config.has_option(self.getsection(), 'foldersort'):
            self.foldersort = self.localeval.eval(
                self.getconf('foldersort'), {'re': re})
Example #17
0
    def __init__(self, config, name):
        """
        :param config: Representing the offlineimap configuration file.
        :type config: :class:`offlineimap.CustomConfig.CustomConfigParser`

        :param name: A (str) string denoting the name of the Account
                     as configured.
        """

        self.config = config
        self.name = name
        self.metadatadir = config.getmetadatadir()
        self.localeval = config.getlocaleval()
        # Current :mod:`offlineimap.ui`, can be used for logging:
        self.ui = getglobalui()
        self.refreshperiod = self.getconffloat('autorefresh', 0.0)
        self.dryrun = self.config.getboolean('general', 'dry-run')
        self.quicknum = 0
        if self.refreshperiod < 0:
            self.ui.warn("autorefresh for %s is negative, fixing it to 0." %
                         name)
            self.refreshperiod = 0.0
        if self.refreshperiod == 0.0:
            self.refreshperiod = None
        self.remoterepos = None
        self.localrepos = None
        self.statusrepos = None
Example #18
0
    def __init__(self, reposname, account):
        self.ui = getglobalui()
        self.account = account
        self.config = account.getconfig()
        self.name = reposname
        self.localeval = account.getlocaleval()
        self._accountname = self.account.getname()
        self._readonly = self.getconfboolean('readonly', False)
        self.uiddir = os.path.join(self.config.getmetadatadir(),
                                   'Repository-' + self.name)
        if not os.path.exists(self.uiddir):
            os.mkdir(self.uiddir, 0o700)
        self.mapdir = os.path.join(self.uiddir, 'UIDMapping')
        if not os.path.exists(self.mapdir):
            os.mkdir(self.mapdir, 0o700)
        self.uiddir = os.path.join(self.uiddir, 'FolderValidity')
        if not os.path.exists(self.uiddir):
            os.mkdir(self.uiddir, 0o700)

        self.nametrans = lambda foldername: foldername
        self.folderfilter = lambda foldername: 1
        self.folderincludes = []
        self.foldersort = None
        if self.config.has_option(self.getsection(), 'nametrans'):
            self.nametrans = self.localeval.eval(self.getconf('nametrans'),
                                                 {'re': re})
        if self.config.has_option(self.getsection(), 'folderfilter'):
            self.folderfilter = self.localeval.eval(
                self.getconf('folderfilter'), {'re': re})
        if self.config.has_option(self.getsection(), 'folderincludes'):
            self.folderincludes = self.localeval.eval(
                self.getconf('folderincludes'), {'re': re})
        if self.config.has_option(self.getsection(), 'foldersort'):
            self.foldersort = self.localeval.eval(self.getconf('foldersort'),
                                                  {'re': re})
Example #19
0
 def sig_handler(sig, frame):
     if sig == signal.SIGUSR1:
         # tell each account to stop sleeping
         accounts.Account.set_abort_event(self.config, 1)
     elif sig == signal.SIGUSR2:
         # tell each account to stop looping
         getglobalui().warn("Terminating after this sync...")
         accounts.Account.set_abort_event(self.config, 2)
     elif sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP):
         # tell each account to ABORT ASAP (ctrl-c)
         getglobalui().warn("Terminating NOW (this may "\
                            "take a few seconds)...")
         accounts.Account.set_abort_event(self.config, 3)
     elif sig == signal.SIGQUIT:
         stacktrace.dump(sys.stderr)
         os.abort()
Example #20
0
 def __init__(self, config, name):
     self.config = config
     self.name = name
     self.metadatadir = config.getmetadatadir()
     self.localeval = config.getlocaleval()
     self.ui = getglobalui()
     self.refreshperiod = self.getconffloat('autorefresh', 0.0)
     self.quicknum = 0
     if self.refreshperiod == 0.0:
         self.refreshperiod = None
Example #21
0
 def __init__(self, config, name):
     self.config = config
     self.name = name
     self.metadatadir = config.getmetadatadir()
     self.localeval = config.getlocaleval()
     self.ui = getglobalui()
     self.refreshperiod = self.getconffloat('autorefresh', 0.0)
     self.quicknum = 0
     if self.refreshperiod == 0.0:
         self.refreshperiod = None
Example #22
0
 def dosync(self):
     remoterepos = self.parent.repos
     account = remoterepos.account
     localrepos = account.localrepos
     remoterepos = account.remoterepos
     statusrepos = account.statusrepos
     remotefolder = remoterepos.getfolder(self.folder)
     offlineimap.accounts.syncfolder(account.name, remoterepos, remotefolder, localrepos, statusrepos, quick=False)
     ui = getglobalui()
     ui.unregisterthread(currentThread())
Example #23
0
 def dosync(self):
     remoterepos = self.parent.repos
     account = remoterepos.account
     localrepos = account.localrepos
     remoterepos = account.remoterepos
     statusrepos = account.statusrepos
     remotefolder = remoterepos.getfolder(self.folder)
     offlineimap.accounts.syncfolder(account, remotefolder, quick=False)
     ui = getglobalui()
     ui.unregisterthread(currentThread())  #syncfolder registered the thread
Example #24
0
    def __init__(self, repos):
        self.ui = getglobalui()
        self.repos = repos
        self.config = repos.getconfig()

        self.preauth_tunnel = repos.getpreauthtunnel()
        self.transport_tunnel = repos.gettransporttunnel()
        if self.preauth_tunnel and self.transport_tunnel:
            raise OfflineImapError('%s: ' % repos + \
              'you must enable precisely one '
              'type of tunnel (preauth or transport), '
              'not both', OfflineImapError.ERROR.REPO)
        self.tunnel = \
          self.preauth_tunnel if self.preauth_tunnel \
          else self.transport_tunnel

        self.username = \
          None if self.preauth_tunnel else repos.getuser()
        self.user_identity = repos.get_remote_identity()
        self.authmechs = repos.get_auth_mechanisms()
        self.password = None
        self.oauth2 = repos.getoauth2()
        self.oauth2url = repos.getoauth2url() if self.oauth2 else None
        self.oauth2clientid = repos.getoauth2clientid() if self.oauth2 else None
        self.oauth2clientsecret = repos.getoauth2clientsecret() if self.oauth2 else None
        self.oauth2refreshtoken = repos.getoauth2refreshtoken() if self.oauth2 else None
        self.passworderror = None
        self.goodpassword = None

        self.usessl = repos.getssl()
        self.hostname = \
          None if self.preauth_tunnel else repos.gethost()
        self.port = repos.getport()
        if self.port == None:
            self.port = 993 if self.usessl else 143
        self.sslclientcert = repos.getsslclientcert()
        self.sslclientkey = repos.getsslclientkey()
        self.sslcacertfile = repos.getsslcacertfile()
        self.sslversion = repos.getsslversion()
        if self.sslcacertfile is None:
            self.__verifycert = None # disable cert verification

        self.delim = None
        self.root = None
        self.maxconnections = repos.getmaxconnections()
        self.availableconnections = []
        self.assignedconnections = []
        self.lastowner = {}
        self.semaphore = BoundedSemaphore(self.maxconnections)
        self.connectionlock = Lock()
        self.reference = repos.getreference()
        self.idlefolders = repos.getidlefolders()
        self.gss_step = self.GSS_STATE_STEP
        self.gss_vc = None
        self.gssapi = False
Example #25
0
    def __init__(self, reposname, account):
        """Initialize a MaildirRepository object.  Takes a path name
        to the directory holding all the Maildir directories."""
        BaseRepository.__init__(self, reposname, account)

        self.mailpath = self.getconf("mailpath", reposname)
        self.db_url = self.getconf("database")
        self.folders = None
        self.ui = getglobalui()

        self.connect()
Example #26
0
def processcachemessagelist(folder):
    """Function used only when config syncflagsignoremaxage is True and
    the operation is sync."""
    ui = getglobalui()
    ml = getcachemessagelist(folder.repository.name, folder, True)
    if ml == None:
        ui.cachingmessagesnomaxage(folder.repository.name, folder)
        folder.cachemessagelist()
        addcachemessagelist(folder.repository.name, folder, True, folder.getmessagelist())
    else:
        folder.setmessagelist(ml)
Example #27
0
def monitor():
    """An infinite "monitoring" loop watching for finished ExitNotifyThread's.

    This one is supposed to run in the main thread.
    :param callback: the function to call when a thread terminated. That
                     function is called with a single argument -- the
                     ExitNotifyThread that has terminated. The monitor will
                     not continue to monitor for other threads until
                     'callback' returns, so if it intends to perform long
                     calculations, it should start a new thread itself -- but
                     NOT an ExitNotifyThread, or else an infinite loop
                     may result.
                     Furthermore, the monitor will hold the lock all the
                     while the other thread is waiting.
    :type callback:  a callable function
    """

    global exitedThreads
    ui = getglobalui()

    while True:
        # Loop forever and call 'callback' for each thread that exited
        try:
            # We need a timeout in the get() call, so that ctrl-c can throw a
            # SIGINT (http://bugs.python.org/issue1360). A timeout with empty
            # Queue will raise `Empty`.
            #
            # ExitNotifyThread add themselves to the exitedThreads queue once
            # they are done (normally or with exception).
            thread = exitedThreads.get(True, 60)
            # Request to abort when callback returns True.

            if thread.exit_exception is not None:
                if isinstance(thread.exit_exception, SystemExit):
                    # Bring a SystemExit into the main thread.
                    # Do not send it back to UI layer right now.
                    # Maybe later send it to ui.terminate?
                    raise SystemExit
                ui.threadException(
                    thread)  # Expected to terminate the program.
                # Should never hit this line.
                raise AssertionError(
                    "thread has 'exit_exception' set to"
                    " '%s' [%s] but this value is unexpected"
                    " and the ui did not stop the program." %
                    (repr(thread.exit_exception), type(thread.exit_exception)))

            # Only the monitor thread has this exit message set.
            elif thread.exit_message == STOP_MONITOR:
                break  # Exit the loop here.
            else:
                ui.threadExited(thread)
        except Empty:
            pass
Example #28
0
 def dosync(self):
     remoterepos = self.parent.repos
     account = remoterepos.account
     localrepos = account.localrepos
     remoterepos = account.remoterepos
     statusrepos = account.statusrepos
     remotefolder = remoterepos.getfolder(self.folder)
     offlineimap.accounts.syncfolder(account, remotefolder, quick=False)
     ui = getglobalui()
     hook = account.getconf('postsynchook', '')
     account.callhook(hook)
     ui.unregisterthread(currentThread()) #syncfolder registered the thread
Example #29
0
        def sig_handler(sig, frame):
            if sig == signal.SIGUSR1:
                # tell each account to stop sleeping
                accounts.Account.set_abort_event(self.config, 1)
            elif sig in (signal.SIGUSR2, signal.SIGABRT):
                # tell each account to stop looping
                getglobalui().warn("Terminating after this sync...")
                accounts.Account.set_abort_event(self.config, 2)
            elif sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP):
                # tell each account to ABORT ASAP (ctrl-c)
                getglobalui().warn("Preparing to shutdown after sync (this may "
                                   "take some time), press CTRL-C three "
                                   "times to shutdown immediately")
                accounts.Account.set_abort_event(self.config, 3)
                if 'thread' in self.ui.debuglist:
                    self.__dumpstacks(5)

                # Abort after three Ctrl-C keystrokes
                self.num_sigterm += 1
                if self.num_sigterm >= 3:
                    getglobalui().warn("Signaled thrice. Aborting!")
                    sys.exit(1)
            elif sig == signal.SIGQUIT:
                stacktrace.dump(sys.stderr)
                os.abort()
Example #30
0
        def sig_handler(sig, frame):
            if sig == signal.SIGUSR1:
                # tell each account to stop sleeping
                accounts.Account.set_abort_event(self.config, 1)
            elif sig in (signal.SIGUSR2, signal.SIGABRT):
                # tell each account to stop looping
                getglobalui().warn("Terminating after this sync...")
                accounts.Account.set_abort_event(self.config, 2)
            elif sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP):
                # tell each account to ABORT ASAP (ctrl-c)
                getglobalui().warn("Preparing to shutdown after sync (this may "\
                                   "take some time), press CTRL-C three "\
                                   "times to shutdown immediately")
                accounts.Account.set_abort_event(self.config, 3)
                if 'thread' in self.ui.debuglist:
                    self.__dumpstacks(5)

                # Abort after three Ctrl-C keystrokes
                self.num_sigterm += 1
                if self.num_sigterm >= 3:
                    getglobalui().warn("Signaled thrice. Aborting!")
                    sys.exit(1)
            elif sig == signal.SIGQUIT:
                stacktrace.dump(sys.stderr)
                os.abort()
Example #31
0
def monitor():
    """An infinite "monitoring" loop watching for finished ExitNotifyThread's.

    This one is supposed to run in the main thread.
    :param callback: the function to call when a thread terminated. That
                     function is called with a single argument -- the
                     ExitNotifyThread that has terminated. The monitor will
                     not continue to monitor for other threads until
                     'callback' returns, so if it intends to perform long
                     calculations, it should start a new thread itself -- but
                     NOT an ExitNotifyThread, or else an infinite loop
                     may result.
                     Furthermore, the monitor will hold the lock all the
                     while the other thread is waiting.
    :type callback:  a callable function
    """

    global exitedThreads
    ui = getglobalui()

    while True:
        # Loop forever and call 'callback' for each thread that exited
        try:
            # We need a timeout in the get() call, so that ctrl-c can throw a
            # SIGINT (http://bugs.python.org/issue1360). A timeout with empty
            # Queue will raise `Empty`.
            #
            # ExitNotifyThread add themselves to the exitedThreads queue once
            # they are done (normally or with exception).
            thread = exitedThreads.get(True, 60)
            # Request to abort when callback returns True.

            if thread.exit_exception is not None:
                if isinstance(thread.exit_exception, SystemExit):
                    # Bring a SystemExit into the main thread.
                    # Do not send it back to UI layer right now.
                    # Maybe later send it to ui.terminate?
                    raise SystemExit
                ui.threadException(thread) # Expected to terminate the program.
                # Should never hit this line.
                raise AssertionError("thread has 'exit_exception' set to"
                    " '%s' [%s] but this value is unexpected"
                    " and the ui did not stop the program."%
                    (repr(thread.exit_exception), type(thread.exit_exception)))

            # Only the monitor thread has this exit message set.
            elif thread.exit_message == STOP_MONITOR:
                break # Exit the loop here.
            else:
                ui.threadExited(thread)
        except Empty:
            pass
Example #32
0
    def __init__(self, name, repository):
        """
        :param name: Path & name of folder minus root or reference
        :param repository: Repository() in which the folder is.
        """

        self.ui = getglobalui()
        # Save original name for folderfilter operations
        self.ffilter_name = name
        # Top level dir name is always ''
        self.root = None
        self.name = name if not name == self.getsep() else ''
        self.newmail_hook = None
        # Only set the newmail_hook if the IMAP folder is named 'INBOX'
        if self.name == 'INBOX':
            self.newmail_hook = repository.newmail_hook
        self.have_newmail = False
        self.repository = repository
        self.visiblename = repository.nametrans(name)
        # In case the visiblename becomes '.' or '/' (top-level) we use
        # '' as that is the name that e.g. the Maildir scanning will
        # return for the top-level dir.
        if self.visiblename == self.getsep():
            self.visiblename = ''

        self.config = repository.getconfig()
        utime_from_header_global = self.config.getdefaultboolean(
            "general", "utime_from_header", False)
        repo = "Repository " + repository.name
        self._utime_from_header = self.config.getdefaultboolean(
            repo, "utime_from_header", utime_from_header_global)

        # Determine if we're running static or dynamic folder filtering
        # and check filtering status
        self._dynamic_folderfilter = self.config.getdefaultboolean(
            repo, "dynamic_folderfilter", False)
        self._sync_this = repository.should_sync_folder(self.ffilter_name)
        if self._dynamic_folderfilter:
            self.ui.debug(
                '', "Running dynamic folder filtering on '%s'[%s]" %
                (self.ffilter_name, repository))
        elif not self._sync_this:
            self.ui.debug(
                '', "Filtering out '%s'[%s] due to folderfilter" %
                (self.ffilter_name, repository))

        # Passes for syncmessagesto
        self.syncmessagesto_passes = [
            ('copying messages', self.__syncmessagesto_copy),
            ('deleting messages', self.__syncmessagesto_delete),
            ('syncing flags', self.__syncmessagesto_flags)
        ]
Example #33
0
 def __init__(self, parent, folder=None):
     """If invoked without 'folder', perform a NOOP and wait for
     self.stop() to be called. If invoked with folder, switch to IDLE
     mode and synchronize once we have a new message"""
     self.parent = parent
     self.folder = folder
     self.stop_sig = Event()
     self.ui = getglobalui()
     if folder is None:
         self.thread = Thread(target=self.noop)
     else:
         self.thread = Thread(target=self.idle)
     self.thread.setDaemon(1)
Example #34
0
 def __init__(self, parent, folder=None):
     """If invoked without 'folder', perform a NOOP and wait for
     self.stop() to be called. If invoked with folder, switch to IDLE
     mode and synchronize once we have a new message"""
     self.parent = parent
     self.folder = folder
     self.stop_sig = Event()
     self.ui = getglobalui()
     if folder is None:
         self.thread = Thread(target=self.noop)
     else:
         self.thread = Thread(target=self.idle)
     self.thread.setDaemon(1)
Example #35
0
    def __init__(self, reposname, account):
        """Initialize a MaildirRepository object.  Takes a path name
        to the directory holding all the Maildir directories."""
        BaseRepository.__init__(self, reposname, account)

        self.root = self.getlocalroot()
        self.folders = None
        self.ui = getglobalui()
        self.debug("MaildirRepository initialized, sep is " + repr(self.getsep()))
        self.folder_atimes = []

        # Create the top-level folder if it doesn't exist
        if not os.path.isdir(self.root):
            os.mkdir(self.root, 0o700)
Example #36
0
    def __init__(self, reposname, account):
        """Initialize a MaildirRepository object.  Takes a path name
        to the directory holding all the Maildir directories."""
        BaseRepository.__init__(self, reposname, account)

        self.root = self.getlocalroot()
        self.folders = None
        self.ui = getglobalui()
        self.debug("MaildirRepository initialized, sep is " + repr(self.getsep()))
        self.folder_atimes = []

        # Create the top-level folder if it doesn't exist
        if not os.path.isdir(self.root):
            os.mkdir(self.root, 0700)
Example #37
0
    def __init__(self, repos):
        self.ui = getglobalui()
        self.repos = repos
        self.config = repos.getconfig()

        self.preauth_tunnel = repos.getpreauthtunnel()
        self.transport_tunnel = repos.gettransporttunnel()
        if self.preauth_tunnel and self.transport_tunnel:
            raise OfflineImapError('%s: ' % repos + \
              'you must enable precisely one '
              'type of tunnel (preauth or transport), '
              'not both', OfflineImapError.ERROR.REPO)
        self.tunnel = \
          self.preauth_tunnel if self.preauth_tunnel \
          else self.transport_tunnel

        self.username = \
          None if self.preauth_tunnel else repos.getuser()
        self.user_identity = repos.get_remote_identity()
        self.authmechs = repos.get_auth_mechanisms()
        self.password = None
        self.passworderror = None
        self.goodpassword = None

        self.usessl = repos.getssl()
        self.hostname = \
          None if self.preauth_tunnel else repos.gethost()
        self.port = repos.getport()
        if self.port == None:
            self.port = 993 if self.usessl else 143
        self.sslclientcert = repos.getsslclientcert()
        self.sslclientkey = repos.getsslclientkey()
        self.sslcacertfile = repos.getsslcacertfile()
        self.sslversion = repos.getsslversion()
        if self.sslcacertfile is None:
            self.verifycert = None  # disable cert verification

        self.delim = None
        self.root = None
        self.maxconnections = repos.getmaxconnections()
        self.availableconnections = []
        self.assignedconnections = []
        self.lastowner = {}
        self.semaphore = BoundedSemaphore(self.maxconnections)
        self.connectionlock = Lock()
        self.reference = repos.getreference()
        self.idlefolders = repos.getidlefolders()
        self.gss_step = self.GSS_STATE_STEP
        self.gss_vc = None
        self.gssapi = False
Example #38
0
    def __dosync(self):
        remoterepos = self.parent.repos
        account = remoterepos.account
        remoterepos = account.remoterepos
        remotefolder = remoterepos.getfolder(self.folder, decode=False)

        hook = account.getconf('presynchook', '')
        account.callhook(hook)
        offlineimap.accounts.syncfolder(account, remotefolder, quick=False)
        hook = account.getconf('postsynchook', '')
        account.callhook(hook)

        ui = getglobalui()
        ui.unregisterthread(currentThread())  # syncfolder registered the thread
Example #39
0
    def syncfoldersto(self, dest, copyfolders):
        """Syncs the folders in this repository to those in dest.
        It does NOT sync the contents of those folders.

        For every time dest.makefolder() is called, also call makefolder()
        on each folder in copyfolders."""
        src = self
        srcfolders = src.getfolders()
        destfolders = dest.getfolders()

        # Create hashes with the names, but convert the source folders
        # to the dest folder's sep.

        srchash = {}
        for folder in srcfolders:
            srchash[folder.getvisiblename().replace(src.getsep(), dest.getsep())] = \
                                                           folder
        desthash = {}
        for folder in destfolders:
            desthash[folder.getvisiblename()] = folder

        #
        # Find new folders.
        #
        
        for key in srchash.keys():
            if not key in desthash:
                try:
                    dest.makefolder(key)
                    for copyfolder in copyfolders:
                        copyfolder.makefolder(key.replace(dest.getsep(), copyfolder.getsep()))
                except (KeyboardInterrupt):
                    raise
                except:
                    getglobalui().warn("ERROR Attempting to make folder " \
                        + key + ":"  +str(sys.exc_info()[1]))
Example #40
0
    def __init__(self, name, repository):
        """
        :param name: Path & name of folder minus root or reference
        :param repository: Repository() in which the folder is.
        """

        self.ui = getglobalui()
        # Save original name for folderfilter operations
        self.ffilter_name = name
        # Top level dir name is always ''
        self.root = None
        self.name = name if not name == self.getsep() else ''
        self.newmail_hook = None
        # Only set the newmail_hook if the IMAP folder is named 'INBOX'
        if self.name == 'INBOX':
            self.newmail_hook = repository.newmail_hook
        self.have_newmail = False
        self.repository = repository
        self.visiblename = repository.nametrans(name)
        # In case the visiblename becomes '.' or '/' (top-level) we use
        # '' as that is the name that e.g. the Maildir scanning will
        # return for the top-level dir.
        if self.visiblename == self.getsep():
            self.visiblename = ''

        self.config = repository.getconfig()
        utime_from_header_global = self.config.getdefaultboolean(
            "general", "utime_from_header", False)
        repo = "Repository " + repository.name
        self._utime_from_header = self.config.getdefaultboolean(repo,
            "utime_from_header", utime_from_header_global)

        # Determine if we're running static or dynamic folder filtering
        # and check filtering status
        self._dynamic_folderfilter = self.config.getdefaultboolean(
            repo, "dynamic_folderfilter", False)
        self._sync_this = repository.should_sync_folder(self.ffilter_name)
        if self._dynamic_folderfilter:
            self.ui.debug('', "Running dynamic folder filtering on '%s'[%s]"%
                (self.ffilter_name, repository))
        elif not self._sync_this:
            self.ui.debug('', "Filtering out '%s'[%s] due to folderfilter"%
                (self.ffilter_name, repository))

        # Passes for syncmessagesto
        self.syncmessagesto_passes = [('copying messages'       , self.__syncmessagesto_copy),
                                      ('deleting messages'      , self.__syncmessagesto_delete),
                                      ('syncing flags'          , self.__syncmessagesto_flags)]
Example #41
0
 def __init__(self, reposname, account):
     self.ui = getglobalui()
     self.account = account
     self.config = account.getconfig()
     self.name = reposname
     self.localeval = account.getlocaleval()
     self.accountname = self.account.getname()
     self.uiddir = os.path.join(self.config.getmetadatadir(), 'Repository-' + self.name)
     if not os.path.exists(self.uiddir):
         os.mkdir(self.uiddir, 0700)
     self.mapdir = os.path.join(self.uiddir, 'UIDMapping')
     if not os.path.exists(self.mapdir):
         os.mkdir(self.mapdir, 0700)
     self.uiddir = os.path.join(self.uiddir, 'FolderValidity')
     if not os.path.exists(self.uiddir):
         os.mkdir(self.uiddir, 0700)
Example #42
0
 def __init__(self, reposname, account):
     self.ui = getglobalui()
     self.account = account
     self.config = account.getconfig()
     self.name = reposname
     self.localeval = account.getlocaleval()
     self.accountname = self.account.getname()
     self.uiddir = os.path.join(self.config.getmetadatadir(), 'Repository-' + self.name)
     if not os.path.exists(self.uiddir):
         os.mkdir(self.uiddir, 0700)
     self.mapdir = os.path.join(self.uiddir, 'UIDMapping')
     if not os.path.exists(self.mapdir):
         os.mkdir(self.mapdir, 0700)
     self.uiddir = os.path.join(self.uiddir, 'FolderValidity')
     if not os.path.exists(self.uiddir):
         os.mkdir(self.uiddir, 0700)
Example #43
0
 def __init__(self,
              config,
              reposname,
              username=None,
              password=None,
              hostname=None,
              port=None,
              ssl=1,
              maxconnections=1,
              tunnel=None,
              reference='""',
              sslclientcert=None,
              sslclientkey=None,
              sslcacertfile=None,
              idlefolders=[]):
     self.ui = getglobalui()
     self.reposname = reposname
     self.config = config
     self.username = username
     self.password = password
     self.passworderror = None
     self.goodpassword = None
     self.hostname = hostname
     self.tunnel = tunnel
     self.port = port
     self.usessl = ssl
     self.sslclientcert = sslclientcert
     self.sslclientkey = sslclientkey
     self.sslcacertfile = sslcacertfile
     self.delim = None
     self.root = None
     if port == None:
         if ssl:
             self.port = 993
         else:
             self.port = 143
     self.maxconnections = maxconnections
     self.availableconnections = []
     self.assignedconnections = []
     self.lastowner = {}
     self.semaphore = BoundedSemaphore(self.maxconnections)
     self.connectionlock = Lock()
     self.reference = reference
     self.idlefolders = idlefolders
     self.gss_step = self.GSS_STATE_STEP
     self.gss_vc = None
     self.gssapi = False
Example #44
0
    def savemessage(self, uid, content, flags, rtime):
        """Writes a new message, with the specified uid.

        See folder/Base for detail. Note that savemessage() does not
        check against dryrun settings, so you need to ensure that
        savemessage is never called in a dryrun mode."""
        # This function only ever saves to tmp/,
        # but it calls savemessageflags() to actually save to cur/ or new/.
        self.ui.savemessage('maildir', uid, flags, self)
        if uid < 0:
            # We cannot assign a new uid.
            return uid

        if uid in self.messagelist:
            # We already have it, just update flags.
            self.savemessageflags(uid, flags)
            return uid

        # Otherwise, save the message in tmp/ and then call savemessageflags()
        # to give it a permanent home.
        tmpdir = os.path.join(self.getfullname(), 'tmp')
        messagename = self.new_message_filename(uid, flags)
        tmpname = self.save_to_tmp_file(messagename, content)

        if self.utime_from_header:
            try:
                date = emailutil.get_message_date(content, 'Date')
                if date is not None:
                    os.utime(os.path.join(self.getfullname(), tmpname),
                        (date, date))
            # In case date is wrongly so far into the future as to be > max int32
            except Exception as e:
                from email.Parser import Parser
                from offlineimap.ui import getglobalui
                datestr = Parser().parsestr(content, True).get("Date")
                ui = getglobalui()
                ui.warn("UID %d has invalid date %s: %s\n"
                    "Not changing file modification time" % (uid, datestr, e))

        self.messagelist[uid] = self.msglist_item_initializer(uid)
        self.messagelist[uid]['flags'] = flags
        self.messagelist[uid]['filename'] = tmpname
        # savemessageflags moves msg to 'cur' or 'new' as appropriate
        self.savemessageflags(uid, flags)
        self.ui.debug('maildir', 'savemessage: returning uid %d' % uid)
        return uid
Example #45
0
 def __init__(self, name, repository):
     """
     :para name: Path & name of folder minus root or reference
     :para repository: Repository() in which the folder is.
     """
     self.sync_this = True
     """Should this folder be included in syncing?"""
     self.ui = getglobalui()
     self.name = name
     self.repository = repository
     self.visiblename = repository.nametrans(name)
     # In case the visiblename becomes '.' (top-level) we use '' as
     # that is the name that e.g. the Maildir scanning will return
     # for the top-level dir.
     if self.visiblename == '.':
         self.visiblename = ''
     self.config = repository.getconfig()
Example #46
0
    def __init__(self, config, name):
        """
        :param config: Representing the offlineimap configuration file.
        :type config: :class:`offlineimap.CustomConfig.CustomConfigParser`

        :param name: A string denoting the name of the Account
                     as configured"""
        self.config = config
        self.name = name
        self.metadatadir = config.getmetadatadir()
        self.localeval = config.getlocaleval()
        #Contains the current :mod:`offlineimap.ui`, and can be used for logging etc.
        self.ui = getglobalui()
        self.refreshperiod = self.getconffloat('autorefresh', 0.0)
        self.quicknum = 0
        if self.refreshperiod == 0.0:
            self.refreshperiod = None
Example #47
0
    def __init__(self, config, name):
        """
        :param config: Representing the offlineimap configuration file.
        :type config: :class:`offlineimap.CustomConfig.CustomConfigParser`

        :param name: A string denoting the name of the Account
                     as configured"""
        self.config = config
        self.name = name
        self.metadatadir = config.getmetadatadir()
        self.localeval = config.getlocaleval()
        #Contains the current :mod:`offlineimap.ui`, and can be used for logging etc.
        self.ui = getglobalui()
        self.refreshperiod = self.getconffloat('autorefresh', 0.0)
        self.quicknum = 0
        if self.refreshperiod == 0.0:
            self.refreshperiod = None
Example #48
0
def threadexited(thread):
    """Called when a thread exits."""
    ui = getglobalui()
    if thread.getExitCause() == 'EXCEPTION':
        if isinstance(thread.getExitException(), SystemExit):
            # Bring a SystemExit into the main thread.
            # Do not send it back to UI layer right now.
            # Maybe later send it to ui.terminate?
            raise SystemExit
        ui.threadException(thread)  # Expected to terminate
        sys.exit(100)  # Just in case...
    elif thread.getExitMessage() == 'SYNC_WITH_TIMER_TERMINATE':
        ui.terminate()
        # Just in case...
        sys.exit(100)
    else:
        ui.threadExited(thread)
Example #49
0
def threadexited(thread):
    """Called when a thread exits."""
    ui = getglobalui()
    if thread.getExitCause() == 'EXCEPTION':
        if isinstance(thread.getExitException(), SystemExit):
            # Bring a SystemExit into the main thread.
            # Do not send it back to UI layer right now.
            # Maybe later send it to ui.terminate?
            raise SystemExit
        ui.threadException(thread)      # Expected to terminate
        sys.exit(100)                   # Just in case...
    elif thread.getExitMessage() == 'SYNC_WITH_TIMER_TERMINATE':
        ui.terminate()
        # Just in case...
        sys.exit(100)
    else:
        ui.threadExited(thread)
Example #50
0
    def savemessage(self, uid, content, flags, rtime):
        """Writes a new message, with the specified uid.

        See folder/Base for detail. Note that savemessage() does not
        check against dryrun settings, so you need to ensure that
        savemessage is never called in a dryrun mode."""
        # This function only ever saves to tmp/,
        # but it calls savemessageflags() to actually save to cur/ or new/.
        self.ui.savemessage("maildir", uid, flags, self)
        if uid < 0:
            # We cannot assign a new uid.
            return uid

        if uid in self.messagelist:
            # We already have it, just update flags.
            self.savemessageflags(uid, flags)
            return uid

        # Otherwise, save the message in tmp/ and then call savemessageflags()
        # to give it a permanent home.
        tmpdir = os.path.join(self.getfullname(), "tmp")
        messagename = self.new_message_filename(uid, flags)
        tmpname = self.save_to_tmp_file(messagename, content)

        if self.utime_from_header:
            try:
                date = emailutil.get_message_date(content, "Date")
                if date is not None:
                    os.utime(os.path.join(self.getfullname(), tmpname), (date, date))
            # In case date is wrongly so far into the future as to be > max int32
            except Exception as e:
                from email.Parser import Parser
                from offlineimap.ui import getglobalui

                datestr = Parser().parsestr(content, True).get("Date")
                ui = getglobalui()
                ui.warn("UID %d has invalid date %s: %s\n" "Not changing file modification time" % (uid, datestr, e))

        self.messagelist[uid] = self.msglist_item_initializer(uid)
        self.messagelist[uid]["flags"] = flags
        self.messagelist[uid]["filename"] = tmpname
        # savemessageflags moves msg to 'cur' or 'new' as appropriate
        self.savemessageflags(uid, flags)
        self.ui.debug("maildir", "savemessage: returning uid %d" % uid)
        return uid
Example #51
0
def threadexited(thread):
    """Called when a thread exits.

    Main thread is aborted when this returns True."""
    ui = getglobalui()
    if thread.exit_exception:
        if isinstance(thread.exit_exception, SystemExit):
            # Bring a SystemExit into the main thread.
            # Do not send it back to UI layer right now.
            # Maybe later send it to ui.terminate?
            raise SystemExit
        ui.threadException(thread)      # Expected to terminate
        sys.exit(100)                   # Just in case...
    elif thread.exit_message == 'SYNCRUNNER_EXITED_NORMALLY':
        return True
    else:
        ui.threadExited(thread)
        return False
Example #52
0
def threadexited(thread):
    """Called when a thread exits.

    Main thread is aborted when this returns True."""
    ui = getglobalui()
    if thread.exit_exception:
        if isinstance(thread.exit_exception, SystemExit):
            # Bring a SystemExit into the main thread.
            # Do not send it back to UI layer right now.
            # Maybe later send it to ui.terminate?
            raise SystemExit
        ui.threadException(thread)  # Expected to terminate
        sys.exit(100)  # Just in case...
    elif thread.exit_message == 'SYNCRUNNER_EXITED_NORMALLY':
        return True
    else:
        ui.threadExited(thread)
        return False
Example #53
0
    def __init__(self, config, name):
        """
        :param config: Representing the offlineimap configuration file.
        :type config: :class:`offlineimap.CustomConfig.CustomConfigParser`

        :param name: A string denoting the name of the Account
                     as configured"""
        self.config = config
        self.name = name
        self.metadatadir = config.getmetadatadir()
        self.localeval = config.getlocaleval()
        # current :mod:`offlineimap.ui`, can be used for logging:
        self.ui = getglobalui()
        self.refreshperiod = self.getconffloat('autorefresh', 0.0)
        # should we run in "dry-run" mode?
        self.dryrun = self.config.getboolean('general', 'dry-run')
        self.quicknum = 0
        if self.refreshperiod == 0.0:
            self.refreshperiod = None
Example #54
0
def monitor():
    """An infinite "monitoring" loop watching for finished ExitNotifyThread's.

    This one is supposed to run in the main thread.
    """

    global exitedThreads
    ui = getglobalui()

    while True:
        # Loop forever and call 'callback' for each thread that exited
        try:
            # We need a timeout in the get() call, so that ctrl-c can throw a
            # SIGINT (http://bugs.python.org/issue1360). A timeout with empty
            # Queue will raise `Empty`.
            #
            # ExitNotifyThread add themselves to the exitedThreads queue once
            # they are done (normally or with exception).
            thread = exitedThreads.get(True, 60)
            # Request to abort when callback returns True.

            if thread.exit_exception is not None:
                if isinstance(thread.exit_exception, SystemExit):
                    # Bring a SystemExit into the main thread.
                    # Do not send it back to UI layer right now.
                    # Maybe later send it to ui.terminate?
                    raise SystemExit
                ui.threadException(thread)  # Expected to terminate the program.
                # Should never hit this line.
                raise AssertionError("thread has 'exit_exception' set to"
                                     " '%s' [%s] but this value is unexpected"
                                     " and the ui did not stop the program." %
                                     (repr(thread.exit_exception), type(thread.exit_exception)))

            # Only the monitor thread has this exit message set.
            elif thread.exit_message == STOP_MONITOR:
                break  # Exit the loop here.
            else:
                ui.threadExited(thread)
        except Empty:
            pass
Example #55
0
    def idle(self):
        while True:
            if self.event.isSet():
                return
            self.needsync = False
            self.imapaborted = False

            def callback(args):
                result, cb_arg, exc_data = args
                if exc_data is None:
                    if not self.event.isSet():
                        self.needsync = True
                        self.event.set()
                else:
                    # We got an "abort" signal.
                    self.imapaborted = True
                    self.stop()

            imapobj = self.parent.acquireconnection()
            imapobj.select(self.folder)
            if "IDLE" in imapobj.capabilities:
                imapobj.idle(callback=callback)
            else:
                ui = getglobalui()
                ui.warn("IMAP IDLE not supported on connection to %s."
                        "Falling back to old behavior: sleeping until next"
                        "refresh cycle." % (imapobj.identifier, ))
                imapobj.noop()
            self.event.wait()
            if self.event.isSet():
                # Can't NOOP on a bad connection.
                if not self.imapaborted:
                    imapobj.noop()
                    # We don't do event.clear() so that we'll fall out
                    # of the loop next time around.
            self.parent.releaseconnection(imapobj)
            if self.needsync:
                self.event.clear()
                self.dosync()
Example #56
0
    def __init__(self, name, repository):
        """
        :para name: Path & name of folder minus root or reference
        :para repository: Repository() in which the folder is.
        """
        self.ui = getglobalui()
        # Save original name for folderfilter operations
        self.ffilter_name = name
        # Top level dir name is always ''
        self.name = name if not name == self.getsep() else ''
        self.repository = repository
        self.visiblename = repository.nametrans(name)
        # In case the visiblename becomes '.' or '/' (top-level) we use
        # '' as that is the name that e.g. the Maildir scanning will
        # return for the top-level dir.
        if self.visiblename == self.getsep():
            self.visiblename = ''

        self.config = repository.getconfig()
        utime_from_message_global = \
          self.config.getdefaultboolean("general",
          "utime_from_message", False)
        repo = "Repository " + repository.name
        self._utime_from_message = \
          self.config.getdefaultboolean(repo,
          "utime_from_message", utime_from_message_global)

        # Determine if we're running static or dynamic folder filtering
        # and check filtering status
        self._dynamic_folderfilter = \
          self.config.getdefaultboolean(repo, "dynamic_folderfilter", False)
        self._sync_this = repository.should_sync_folder(self.ffilter_name)
        if self._dynamic_folderfilter:
            self.ui.debug('', "Running dynamic folder filtering on '%s'[%s]" \
                          % (self.ffilter_name, repository))
        elif not self._sync_this:
            self.ui.debug('', "Filtering out '%s'[%s] due to folderfilter" \
                          % (self.ffilter_name, repository))
Example #57
0
    def __init__(self, reposname, account):
        """Initialize a MaildirRepository object.  Takes a path name
        to the directory holding all the Maildir directories."""

        BaseRepository.__init__(self, reposname, account)

        self.root = self.getlocalroot()
        self.folders = None
        self.ui = getglobalui()
        self.debug("MaildirRepository initialized, sep is %s" %
                   repr(self.getsep()))
        self.folder_atimes = []

        # Create the top-level folder if it doesn't exist
        if not os.path.isdir(self.root):
            os.makedirs(self.root, 0o700)

        # Create the keyword->char mapping
        self.keyword2char = dict()
        for c in 'abcdefghijklmnopqrstuvwxyz':
            confkey = 'customflag_' + c
            keyword = self.getconf(confkey, None)
            if keyword is not None:
                self.keyword2char[keyword] = c
Example #58
0
        def sig_handler(sig, frame):
            if sig == signal.SIGUSR1:
                # tell each account to stop sleeping
                accounts.Account.set_abort_event(self.config, 1)
            elif sig == signal.SIGUSR2:
                # tell each account to stop looping
                getglobalui().warn("Terminating after this sync...")
                accounts.Account.set_abort_event(self.config, 2)
            elif sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP):
                # tell each account to ABORT ASAP (ctrl-c)
                getglobalui().warn("Terminating NOW (this may "\
                                   "take a few seconds)...")
                accounts.Account.set_abort_event(self.config, 3)
                if 'thread' in self.ui.debuglist:
                    self.__dumpstacks(5)

                # Abort after three Ctrl-C keystrokes
                self.num_sigterm += 1
                if self.num_sigterm >= 3:
                    getglobalui().warn("Signaled thrice. Aborting!")
                    sys.exit(1)
            elif sig == signal.SIGQUIT:
                stacktrace.dump(sys.stderr)
                os.abort()