예제 #1
0
    def _messagelabels_aux(self, arg, uidlist, labels):
        """Common code to savemessagelabels and addmessagelabels"""
        labels = labels - self.ignorelabels
        uidlist = [uid for uid in uidlist if uid > 0]
        if len(uidlist) > 0:
            imapobj = self.imapserver.acquireconnection()
            try:
                labels_str = '(' + ' '.join(
                    [imaputil.quote(lb) for lb in labels]) + ')'
                # Coalesce uid's into ranges
                uid_str = imaputil.uid_sequence(uidlist)
                result = self._store_to_imap(imapobj, uid_str, arg, labels_str)

            except imapobj.readonly:
                self.ui.labelstoreadonly(self, uidlist, labels)
                return None

            finally:
                self.imapserver.releaseconnection(imapobj)

            if result:
                retlabels = imaputil.flags2hash(
                    imaputil.imapsplit(result)[1])['X-GM-LABELS']
                retlabels = set([
                    imaputil.dequote(lb)
                    for lb in imaputil.imapsplit(retlabels)
                ])
                return retlabels
        return None
예제 #2
0
파일: Gmail.py 프로젝트: mnick/offlineimap
    def _messagelabels_aux(self, arg, uidlist, labels):
        """Common code to savemessagelabels and addmessagelabels"""
        labels = labels - self.ignorelabels
        uidlist = [uid for uid in uidlist if uid > 0]
        if len(uidlist) > 0:
            imapobj = self.imapserver.acquireconnection()
            try:
                labels_str = '(' + ' '.join([imaputil.quote(lb) for lb in labels]) + ')'
                # Coalesce uid's into ranges
                uid_str = imaputil.uid_sequence(uidlist)
                result = self._store_to_imap(imapobj, uid_str, arg, labels_str)

            except imapobj.readonly:
                self.ui.labelstoreadonly(self, uidlist, data)
                return None

            finally:
                self.imapserver.releaseconnection(imapobj)

            if result:
                retlabels = imaputil.flags2hash(imaputil.imapsplit(result)[1])['X-GM-LABELS']
                retlabels = set([imaputil.dequote(lb) for lb in imaputil.imapsplit(retlabels)])
                return retlabels
        return None
예제 #3
0
def syncfolder(account, remotefolder, quick):
    """Synchronizes given remote folder for the specified account.

    Filtered folders on the remote side will not invoke this function."""
    remoterepos = account.remoterepos
    localrepos = account.localrepos
    statusrepos = account.statusrepos

    ui = getglobalui()
    ui.registerthread(account)
    try:
        # Load local folder.
        localfolder = account.get_local_folder(remotefolder)

        # Write the mailboxes
        mbnames.add(account.name, localfolder.getname(),
          localrepos.getlocalroot())

        # Load status folder.
        statusfolder = statusrepos.getfolder(remotefolder.getvisiblename().\
                                             replace(remoterepos.getsep(),
                                                     statusrepos.getsep()))
        if localfolder.get_uidvalidity() == None:
            # This is a new folder, so delete the status cache to be
            # sure we don't have a conflict.
            # TODO: This does not work. We always return a value, need
            # to rework this...
            statusfolder.deletemessagelist()

        statusfolder.cachemessagelist()

        if quick:
            if not localfolder.quickchanged(statusfolder) \
                   and not remotefolder.quickchanged(statusfolder):
                ui.skippingfolder(remotefolder)
                localrepos.restore_atime()
                return

        # Load local folder
        ui.syncingfolder(remoterepos, remotefolder, localrepos, localfolder)
        ui.loadmessagelist(localrepos, localfolder)
        localfolder.cachemessagelist()
        ui.messagelistloaded(localrepos, localfolder, localfolder.getmessagecount())

        # If either the local or the status folder has messages and
        # there is a UID validity problem, warn and abort.  If there are
        # no messages, UW IMAPd loses UIDVALIDITY.  But we don't really
        # need it if both local folders are empty.  So, in that case,
        # just save it off.
        if localfolder.getmessagecount() or statusfolder.getmessagecount():
            if not localfolder.check_uidvalidity():
                ui.validityproblem(localfolder)
                localrepos.restore_atime()
                print 'ACTION { "name" : "validityProblemLocal", "path" : %s }' % imaputil.quote( "%s" % self )
                sys.stdout.flush()
                return
            if not remotefolder.check_uidvalidity():
                ui.validityproblem(remotefolder)
                localrepos.restore_atime()
                print 'ACTION { "name" : "validityProblemRemote", "path" : %s }' % imaputil.quote( "%s" % self )
                sys.stdout.flush()
                return
        else:
            # Both folders empty, just save new UIDVALIDITY
            localfolder.save_uidvalidity()
            remotefolder.save_uidvalidity()

        # Load remote folder.
        ui.loadmessagelist(remoterepos, remotefolder)
        remotefolder.cachemessagelist()
        ui.messagelistloaded(remoterepos, remotefolder,
                             remotefolder.getmessagecount())

        # Synchronize remote changes.
        if not localrepos.getconfboolean('readonly', False):
            ui.syncingmessages(remoterepos, remotefolder, localrepos, localfolder)
            remotefolder.syncmessagesto(localfolder, statusfolder)
        else:
            ui.debug('imap', "Not syncing to read-only repository '%s'" \
                         % localrepos.getname())

        # Synchronize local changes
        if not remoterepos.getconfboolean('readonly', False):
            ui.syncingmessages(localrepos, localfolder, remoterepos, remotefolder)
            localfolder.syncmessagesto(remotefolder, statusfolder)
        else:
            ui.debug('', "Not syncing to read-only repository '%s'" \
                         % remoterepos.getname())

        statusfolder.save()
        localrepos.restore_atime()
    except (KeyboardInterrupt, SystemExit):
        raise
    except OfflineImapError as e:
        # bubble up severe Errors, skip folder otherwise
        if e.severity > OfflineImapError.ERROR.FOLDER:
            raise
        else:
            ui.error(e, exc_info()[2], msg = "Aborting sync, folder '%s' "
                     "[acc: '%s']" % (localfolder, account))
    except Exception as e:
        ui.error(e, msg = "ERROR in syncfolder for %s folder %s: %s" % \
                (account, remotefolder.getvisiblename(),
                 traceback.format_exc()))