示例#1
0
    def savemessageflags(self, uid, flags):
        """Change a message's flags to `flags`.

        Note that this function does not check against dryrun settings,
        so you need to ensure that it is never called in a
        dryrun mode."""
        imapobj = self.imapserver.acquireconnection()
        try:
            try:
                imapobj.select(self.getfullname())
            except imapobj.readonly:
                self.ui.flagstoreadonly(self, [uid], flags)
                return
            result = imapobj.uid('store', '%d' % uid, 'FLAGS',
                                 imaputil.flagsmaildir2imap(flags))
            assert result[0] == 'OK', 'Error with store: ' + '. '.join(
                result[1])
        finally:
            self.imapserver.releaseconnection(imapobj)
        result = result[1][0]
        if not result:
            self.messagelist[uid]['flags'] = flags
        else:
            flags = imaputil.flags2hash(imaputil.imapsplit(result)[1])['FLAGS']
            self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags)
示例#2
0
    def cachemessagelist(self):
        if not self.synclabels:
            return super(GmailFolder, self).cachemessagelist()

        self.messagelist = {}

        self.ui.collectingdata(None, self)
        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj)
            if not msgsToFetch:
                return  # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            #
            # NB: msgsToFetch are sequential numbers, not UID's
            res_type, response = imapobj.fetch("'%s'" % msgsToFetch,
                                               '(FLAGS X-GM-LABELS UID)')
            if res_type != 'OK':
                raise OfflineImapError("FETCHING UIDs in folder [%s]%s failed. " % \
                  (self.getrepository(), self) + \
                  "Server responded '[%s] %s'" % \
                  (res_type, response), OfflineImapError.ERROR.FOLDER), \
                  None, exc_info()[2]
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) X-GM-LABELS (\\Inbox \\Favorites) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not 'UID' in options:
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                self.messagelist[uid] = self.msglist_item_initializer(uid)
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                m = re.search('\(([^\)]*)\)', options['X-GM-LABELS'])
                if m:
                    labels = set([
                        imaputil.dequote(lb)
                        for lb in imaputil.imapsplit(m.group(1))
                    ])
                else:
                    labels = set()
                labels = labels - self.ignorelabels
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {
                    'uid': uid,
                    'flags': flags,
                    'labels': labels,
                    'time': rtime
                }
示例#3
0
    def cachemessagelist(self, min_date=None, min_uid=None):
        if not self.synclabels:
            return super(GmailFolder, self).cachemessagelist(
                min_date=min_date, min_uid=min_uid)

        self.dropmessagelistcache()

        self.ui.collectingdata(None, self)
        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(
                imapobj, min_date=min_date, min_uid=min_uid)
            if not msgsToFetch:
                return # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            #
            # NB: msgsToFetch are sequential numbers, not UID's
            res_type, response = imapobj.fetch("'%s'"% msgsToFetch,
              '(FLAGS X-GM-LABELS UID)')
            if res_type != 'OK':
                six.reraise(OfflineImapError,
                            OfflineImapError(
                                "FETCHING UIDs in folder [%s]%s failed. "%
                                (self.getrepository(), self) +
                                "Server responded '[%s] %s'"%
                                (res_type, response),
                                OfflineImapError.ERROR.FOLDER),
                            exc_info()[2])
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) X-GM-LABELS (\\Inbox \\Favorites) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            # e.g.: {'X-GM-LABELS': '("Webserver (RW.net)" "\\Inbox" GInbox)', 'FLAGS': '(\\Seen)', 'UID': '275440'}
            options = imaputil.flags2hash(messagestr)
            if not 'UID' in options:
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = int(options['UID'])
                self.messagelist[uid] = self.msglist_item_initializer(uid)
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                # e.g.: '("Webserver (RW.net)" "\\Inbox" GInbox)'
                m = re.search('^[(](.*)[)]', options['X-GM-LABELS'])
                if m:
                    labels = set([imaputil.dequote(lb) for lb in imaputil.imapsplit(m.group(1))])
                else:
                    labels = set()
                labels = labels - self.ignorelabels
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {'uid': uid, 'flags': flags, 'labels': labels, 'time': rtime}
示例#4
0
    def cachemessagelist(self, min_date=None, min_uid=None):
        self.ui.loadmessagelist(self.repository, self)
        self.dropmessagelistcache()

        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj,
                                              min_date=min_date,
                                              min_uid=min_uid)
            if not msgsToFetch:
                return  # No messages to sync.

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            fetch_msg = "%s" % msgsToFetch
            self.ui.debug(
                'imap', "calling imaplib2 fetch command: %s %s" %
                (fetch_msg, '(FLAGS UID INTERNALDATE)'))
            res_type, response = imapobj.fetch(fetch_msg,
                                               '(FLAGS UID INTERNALDATE)')
            if res_type != 'OK':
                raise OfflineImapError(
                    "FETCHING UIDs in folder [%s]%s failed. "
                    "Server responded '[%s] %s'" %
                    (self.getrepository(), self, res_type, response),
                    OfflineImapError.ERROR.FOLDER)
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # Looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg.
            # Discard initial message number.
            if messagestr is None:
                continue
            messagestr = messagestr.decode('utf-8').split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if 'UID' not in options:
                self.ui.warn('No UID in message with options %s' %
                             str(options),
                             minor=1)
            else:
                uid = int(options['UID'])
                self.messagelist[uid] = self.msglist_item_initializer(uid)
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                keywords = imaputil.flagsimap2keywords(options['FLAGS'])
                rtime = imaplibutil.Internaldate2epoch(
                    messagestr.encode('utf-8'))
                self.messagelist[uid] = {
                    'uid': uid,
                    'flags': flags,
                    'time': rtime,
                    'keywords': keywords
                }
        self.ui.messagelistloaded(self.repository, self,
                                  self.getmessagecount())
示例#5
0
    def new_message_filename(self, uid, flags=set()):
        """Creates a new unique Maildir filename

        :param uid: The UID`None`, or a set of maildir flags
        :param flags: A set of maildir flags
        :returns: String containing unique message filename"""
        timeval, timeseq = gettimeseq()
        return '%d_%d.%d.%s,U=%d,FMD5=%s%s2,%s' % \
            (timeval, timeseq, os.getpid(), socket.gethostname(),
             uid, self._foldermd5, self.infosep,
             ''.join(sorted(imaputil.flagsimap2maildir(flags))))
示例#6
0
    def new_message_filename(self, uid, flags=set()):
        """Creates a new unique Maildir filename

        :param uid: The UID`None`, or a set of maildir flags
        :param flags: A set of maildir flags
        :returns: String containing unique message filename"""
        timeval, timeseq = gettimeseq()
        return '%d_%d.%d.%s,U=%d,FMD5=%s%s2,%s' % \
            (timeval, timeseq, os.getpid(), socket.gethostname(),
             uid, self._foldermd5, self.infosep,
             ''.join(sorted(imaputil.flagsimap2maildir(flags))))
示例#7
0
    def processmessagesflags(self, operation, uidlist, flags):
        # XXX: the imapobj.myrights(...) calls dies with an error
        # report from Gmail server stating that IMAP command
        # 'MYRIGHTS' is not implemented.  So, this
        # `processmessagesflags` is just a copy from `IMAPFolder`,
        # with the references to `imapobj.myrights()` deleted This
        # shouldn't hurt, however, Gmail users always have full
        # control over all their mailboxes (apparently).
        if len(uidlist) > 101:
            # Hack for those IMAP ervers with a limited line length
            self.processmessagesflags(operation, uidlist[:100], flags)
            self.processmessagesflags(operation, uidlist[100:], flags)
            return
        
        imapobj = self.imapserver.acquireconnection()
        try:
            imapobj.select(self.getfullname())
            r = imapobj.uid('store',
                            imaputil.listjoin(uidlist),
                            operation + 'FLAGS',
                            imaputil.flagsmaildir2imap(flags))
            assert r[0] == 'OK', 'Error with store: ' + '. '.join(r[1])
            r = r[1]
        finally:
            self.imapserver.releaseconnection(imapobj)

        needupdate = copy(uidlist)
        for result in r:
            if result == None:
                # Compensate for servers that don't return anything from
                # STORE.
                continue
            attributehash = imaputil.flags2hash(imaputil.imapsplit(result)[1])
            if not ('UID' in attributehash and 'FLAGS' in attributehash):
                # Compensate for servers that don't return a UID attribute.
                continue
            flags = attributehash['FLAGS']
            uid = long(attributehash['UID'])
            self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags)
            try:
                needupdate.remove(uid)
            except ValueError:          # Let it slide if it's not in the list
                pass
        for uid in needupdate:
            if operation == '+':
                for flag in flags:
                    if not flag in self.messagelist[uid]['flags']:
                        self.messagelist[uid]['flags'].append(flag)
                    self.messagelist[uid]['flags'].sort()
            elif operation == '-':
                for flag in flags:
                    if flag in self.messagelist[uid]['flags']:
                        self.messagelist[uid]['flags'].remove(flag)
示例#8
0
    def processmessagesflags(self, operation, uidlist, flags):
        # XXX: the imapobj.myrights(...) calls dies with an error
        # report from Gmail server stating that IMAP command
        # 'MYRIGHTS' is not implemented.  So, this
        # `processmessagesflags` is just a copy from `IMAPFolder`,
        # with the references to `imapobj.myrights()` deleted This
        # shouldn't hurt, however, Gmail users always have full
        # control over all their mailboxes (apparently).
        if len(uidlist) > 101:
            # Hack for those IMAP ervers with a limited line length
            self.processmessagesflags(operation, uidlist[:100], flags)
            self.processmessagesflags(operation, uidlist[100:], flags)
            return
        
        imapobj = self.imapserver.acquireconnection()
        try:
            imapobj.select(self.getfullname())
            r = imapobj.uid('store',
                            imaputil.listjoin(uidlist),
                            operation + 'FLAGS',
                            imaputil.flagsmaildir2imap(flags))
            assert r[0] == 'OK', 'Error with store: ' + '. '.join(r[1])
            r = r[1]
        finally:
            self.imapserver.releaseconnection(imapobj)

        needupdate = copy(uidlist)
        for result in r:
            if result == None:
                # Compensate for servers that don't return anything from
                # STORE.
                continue
            attributehash = imaputil.flags2hash(imaputil.imapsplit(result)[1])
            if not ('UID' in attributehash and 'FLAGS' in attributehash):
                # Compensate for servers that don't return a UID attribute.
                continue
            flags = attributehash['FLAGS']
            uid = long(attributehash['UID'])
            self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags)
            try:
                needupdate.remove(uid)
            except ValueError:          # Let it slide if it's not in the list
                pass
        for uid in needupdate:
            if operation == '+':
                for flag in flags:
                    if not flag in self.messagelist[uid]['flags']:
                        self.messagelist[uid]['flags'].append(flag)
                    self.messagelist[uid]['flags'].sort()
            elif operation == '-':
                for flag in flags:
                    if flag in self.messagelist[uid]['flags']:
                        self.messagelist[uid]['flags'].remove(flag)
示例#9
0
 def processmessagesflags(self, operation, uidlist, flags):
     if len(uidlist) > 101:
         # Hack for those IMAP ervers with a limited line length
         self.processmessagesflags(operation, uidlist[:100], flags)
         self.processmessagesflags(operation, uidlist[100:], flags)
         return
     
     imapobj = self.imapserver.acquireconnection()
     try:
         try:
             imapobj.select(self.getfullname())
         except imapobj.readonly:
             UIBase.getglobalui().flagstoreadonly(self, uidlist, flags)
             return
         r = imapobj.uid('store',
                         imaputil.listjoin(uidlist),
                         operation + 'FLAGS',
                         imaputil.flagsmaildir2imap(flags))
         assert r[0] == 'OK', 'Error with store: ' + '. '.join(r[1])
         r = r[1]
     finally:
         self.imapserver.releaseconnection(imapobj)
     # Some IMAP servers do not always return a result.  Therefore,
     # only update the ones that it talks about, and manually fix
     # the others.
     needupdate = copy(uidlist)
     for result in r:
         if result == None:
             # Compensate for servers that don't return anything from
             # STORE.
             continue
         attributehash = imaputil.flags2hash(imaputil.imapsplit(result)[1])
         if not ('UID' in attributehash and 'FLAGS' in attributehash):
             # Compensate for servers that don't return a UID attribute.
             continue
         lflags = attributehash['FLAGS']
         uid = long(attributehash['UID'])
         self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(lflags)
         try:
             needupdate.remove(uid)
         except ValueError:          # Let it slide if it's not in the list
             pass
     for uid in needupdate:
         if operation == '+':
             for flag in flags:
                 if not flag in self.messagelist[uid]['flags']:
                     self.messagelist[uid]['flags'].append(flag)
                 self.messagelist[uid]['flags'].sort()
         elif operation == '-':
             for flag in flags:
                 if flag in self.messagelist[uid]['flags']:
                     self.messagelist[uid]['flags'].remove(flag)
示例#10
0
    def cachemessagelist(self):
        if not self.synclabels:
            return super(GmailFolder, self).cachemessagelist()

        self.ui.collectingdata(None, self)
        self.messagelist = {}

        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj)
            if not msgsToFetch:
                return # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            # Note: msgsToFetch are sequential numbers, not UID's
            res_type, response = imapobj.fetch("'%s'" % msgsToFetch,
                                               '(FLAGS X-GM-LABELS UID)')
            if res_type != 'OK':
                raise OfflineImapError("FETCHING UIDs in folder [%s]%s failed. "
                                       "Server responded '[%s] %s'" % (
                            self.getrepository(), self,
                            res_type, response),
                        OfflineImapError.ERROR.FOLDER)

        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not 'UID' in options:
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                m = re.search('\(([^\)]*)\)', options['X-GM-LABELS'])
                if m:
                    labels = set([imaputil.dequote(lb) for lb in imaputil.imapsplit(m.group(1))])
                else:
                    labels = set()
                labels = labels - self.ignorelabels
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {'uid': uid, 'flags': flags, 'labels': labels, 'time': rtime}
示例#11
0
    def cachemessagelist(self):
        if not self.synclabels:
            return super(GmailFolder, self).cachemessagelist()

        self.ui.collectingdata(None, self)
        self.messagelist = {}
        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj)
            if not msgsToFetch:
                return  # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            data = self._fetch_from_imap(imapobj, "'%s'" % msgsToFetch,
                                         '(FLAGS X-GM-LABELS UID)')
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in data:
            # looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not 'UID' in options:
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                m = re.search('\(([^\)]*)\)', options['X-GM-LABELS'])
                if m:
                    labels = set([
                        imaputil.dequote(lb)
                        for lb in imaputil.imapsplit(m.group(1))
                    ])
                else:
                    labels = set()
                labels = labels - self.ignorelabels
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {
                    'uid': uid,
                    'flags': flags,
                    'labels': labels,
                    'time': rtime
                }
示例#12
0
    def processmessagesflags(self, operation, uidlist, flags):
        if len(uidlist) > 101:
            # Hack for those IMAP ervers with a limited line length
            self.processmessagesflags(operation, uidlist[:100], flags)
            self.processmessagesflags(operation, uidlist[100:], flags)
            return

        imapobj = self.imapserver.acquireconnection()
        try:
            try:
                imapobj.select(self.getfullname())
            except imapobj.readonly:
                self.ui.flagstoreadonly(self, uidlist, flags)
                return
            r = imapobj.uid(
                "store", imaputil.uid_sequence(uidlist), operation + "FLAGS", imaputil.flagsmaildir2imap(flags)
            )
            assert r[0] == "OK", "Error with store: " + ". ".join(r[1])
            r = r[1]
        finally:
            self.imapserver.releaseconnection(imapobj)
        # Some IMAP servers do not always return a result.  Therefore,
        # only update the ones that it talks about, and manually fix
        # the others.
        needupdate = list(uidlist)
        for result in r:
            if result == None:
                # Compensate for servers that don't return anything from
                # STORE.
                continue
            attributehash = imaputil.flags2hash(imaputil.imapsplit(result)[1])
            if not ("UID" in attributehash and "FLAGS" in attributehash):
                # Compensate for servers that don't return a UID attribute.
                continue
            flagstr = attributehash["FLAGS"]
            uid = long(attributehash["UID"])
            self.messagelist[uid]["flags"] = imaputil.flagsimap2maildir(flagstr)
            try:
                needupdate.remove(uid)
            except ValueError:  # Let it slide if it's not in the list
                pass
        for uid in needupdate:
            if operation == "+":
                self.messagelist[uid]["flags"] |= flags
            elif operation == "-":
                self.messagelist[uid]["flags"] -= flags
示例#13
0
 def savemessageflags(self, uid, flags):
     imapobj = self.imapserver.acquireconnection()
     try:
         try:
             imapobj.select(self.getfullname())
         except imapobj.readonly:
             self.ui.flagstoreadonly(self, [uid], flags)
             return
         result = imapobj.uid("store", "%d" % uid, "FLAGS", imaputil.flagsmaildir2imap(flags))
         assert result[0] == "OK", "Error with store: " + ". ".join(result[1])
     finally:
         self.imapserver.releaseconnection(imapobj)
     result = result[1][0]
     if not result:
         self.messagelist[uid]["flags"] = flags
     else:
         flags = imaputil.flags2hash(imaputil.imapsplit(result)[1])["FLAGS"]
         self.messagelist[uid]["flags"] = imaputil.flagsimap2maildir(flags)
示例#14
0
    def cachemessagelist(self, min_date=None, min_uid=None):
        self.ui.loadmessagelist(self.repository, self)
        self.dropmessagelistcache()

        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(
                imapobj, min_date=min_date, min_uid=min_uid)
            if not msgsToFetch:
                return # No messages to sync.

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            fetch_msg = "'%s'"% msgsToFetch
            self.ui.debug('imap', "calling imaplib2 fetch command: %s %s"%
                (fetch_msg, '(FLAGS UID INTERNALDATE)'))
            res_type, response = imapobj.fetch(
                fetch_msg, '(FLAGS UID INTERNALDATE)')
            if res_type != 'OK':
                raise OfflineImapError("FETCHING UIDs in folder [%s]%s failed. "
                    "Server responded '[%s] %s'"% (self.getrepository(), self,
                    res_type, response), OfflineImapError.ERROR.FOLDER)
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # Looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg.
            # Discard initial message number.
            if messagestr is None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if 'UID' not in options:
                self.ui.warn('No UID in message with options %s'%
                    str(options), minor=1)
            else:
                uid = int(options['UID'])
                self.messagelist[uid] = self.msglist_item_initializer(uid)
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                keywords = imaputil.flagsimap2keywords(options['FLAGS'])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {'uid': uid, 'flags': flags, 'time': rtime,
                    'keywords': keywords}
        self.ui.messagelistloaded(self.repository, self, self.getmessagecount())
示例#15
0
 def __processmessagesflags_real(self, operation, uidlist, flags):
     imapobj = self.imapserver.acquireconnection()
     try:
         try:
             imapobj.select(self.getfullname())
         except imapobj.readonly:
             self.ui.flagstoreadonly(self, uidlist, flags)
             return
         response = imapobj.uid('store', imaputil.uid_sequence(uidlist),
                                operation + 'FLAGS',
                                imaputil.flagsmaildir2imap(flags))
         if response[0] != 'OK':
             raise OfflineImapError(
                 'Error with store: %s' % '. '.join(response[1]),
                 OfflineImapError.ERROR.MESSAGE)
         response = response[1]
     finally:
         self.imapserver.releaseconnection(imapobj)
     # Some IMAP servers do not always return a result.  Therefore,
     # only update the ones that it talks about, and manually fix
     # the others.
     needupdate = list(uidlist)
     for result in response:
         if result is None:
             # Compensate for servers that don't return anything from
             # STORE.
             continue
         attributehash = imaputil.flags2hash(imaputil.imapsplit(result)[1])
         if not ('UID' in attributehash and 'FLAGS' in attributehash):
             # Compensate for servers that don't return a UID attribute.
             continue
         flagstr = attributehash['FLAGS']
         uid = int(attributehash['UID'])
         self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(
             flagstr)
         try:
             needupdate.remove(uid)
         except ValueError:  # Let it slide if it's not in the list.
             pass
     for uid in needupdate:
         if operation == '+':
             self.messagelist[uid]['flags'] |= flags
         elif operation == '-':
             self.messagelist[uid]['flags'] -= flags
示例#16
0
 def __processmessagesflags_real(self, operation, uidlist, flags):
     imapobj = self.imapserver.acquireconnection()
     try:
         try:
             imapobj.select(self.getfullname())
         except imapobj.readonly:
             self.ui.flagstoreadonly(self, uidlist, flags)
             return
         response = imapobj.uid('store',
             imaputil.uid_sequence(uidlist), operation + 'FLAGS',
                 imaputil.flagsmaildir2imap(flags))
         if response[0] != 'OK':
             raise OfflineImapError(
                 'Error with store: %s'% '. '.join(response[1]),
                 OfflineImapError.ERROR.MESSAGE)
         response = response[1]
     finally:
         self.imapserver.releaseconnection(imapobj)
     # Some IMAP servers do not always return a result.  Therefore,
     # only update the ones that it talks about, and manually fix
     # the others.
     needupdate = list(uidlist)
     for result in response:
         if result is None:
             # Compensate for servers that don't return anything from
             # STORE.
             continue
         attributehash = imaputil.flags2hash(imaputil.imapsplit(result)[1])
         if not ('UID' in attributehash and 'FLAGS' in attributehash):
             # Compensate for servers that don't return a UID attribute.
             continue
         flagstr = attributehash['FLAGS']
         uid = int(attributehash['UID'])
         self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flagstr)
         try:
             needupdate.remove(uid)
         except ValueError:  # Let it slide if it's not in the list.
             pass
     for uid in needupdate:
         if operation == '+':
             self.messagelist[uid]['flags'] |= flags
         elif operation == '-':
             self.messagelist[uid]['flags'] -= flags
示例#17
0
    def cachemessagelist(self):
        self.messagelist = {}

        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj)
            if not msgsToFetch:
                return  # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            res_type, response = imapobj.fetch("'%s'" % msgsToFetch,
                                               '(FLAGS UID)')
            if res_type != 'OK':
                raise OfflineImapError(
                    "FETCHING UIDs in folder [%s]%s failed. "
                    "Server responded '[%s] %s'" %
                    (self.getrepository(), self, res_type, response),
                    OfflineImapError.ERROR.FOLDER)
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not 'UID' in options:
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                self.messagelist[uid] = self.msglist_item_initializer(uid)
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {
                    'uid': uid,
                    'flags': flags,
                    'time': rtime
                }
示例#18
0
 def savemessageflags(self, uid, flags):
     imapobj = self.imapserver.acquireconnection()
     try:
         try:
             imapobj.select(self.getfullname())
         except imapobj.readonly:
             self.ui.flagstoreadonly(self, [uid], flags)
             return
         result = imapobj.uid('store', '%d' % uid, 'FLAGS',
                              imaputil.flagsmaildir2imap(flags))
         assert result[0] == 'OK', 'Error with store: ' + '. '.join(r[1])
     finally:
         self.imapserver.releaseconnection(imapobj)
     result = result[1][0]
     if not result:
         self.messagelist[uid]['flags'] = flags
     else:
         flags = imaputil.flags2hash(imaputil.imapsplit(result)[1])['FLAGS']
         self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags)
示例#19
0
 def savemessageflags(self, uid, flags):
     imapobj = self.imapserver.acquireconnection()
     try:
         try:
             imapobj.select(self.getfullname())
         except imapobj.readonly:
             self.ui.flagstoreadonly(self, [uid], flags)
             return
         result = imapobj.uid('store', '%d' % uid, 'FLAGS',
                              imaputil.flagsmaildir2imap(flags))
         assert result[0] == 'OK', 'Error with store: ' + '. '.join(result[1])
     finally:
         self.imapserver.releaseconnection(imapobj)
     result = result[1][0]
     if not result:
         self.messagelist[uid]['flags'] = flags
     else:
         flags = imaputil.flags2hash(imaputil.imapsplit(result)[1])['FLAGS']
         self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags)
示例#20
0
    def savemessageflags(self, uid, flags):
        """Sets the specified message's flags to the given set.

        This function moves the message to the cur or new subdir,
        depending on the 'S'een flag.

        Note that this function does not check against dryrun settings,
        so you need to ensure that it is never called in a
        dryrun mode."""
        oldfilename = self.messagelist[uid]['filename']
        dir_prefix, filename = os.path.split(oldfilename)
        # If a message has been seen, it goes into 'cur'
        dir_prefix = 'cur' if '\\Seen' in flags else 'new'

        if flags != self.messagelist[uid]['flags']:
            # Flags have actually changed, construct new filename Strip
            # off existing infostring (possibly discarding small letter
            # flags that dovecot uses TODO)
            infomatch = self.re_flagmatch.search(filename)
            if infomatch:
                filename = filename[:-len(infomatch.group())]  #strip off
            infostr = '%s2,%s' % (self.infosep, ''.join(
                sorted(imaputil.flagsimap2maildir(flags))))
            filename += infostr

        newfilename = os.path.join(dir_prefix, filename)
        if (newfilename != oldfilename):
            try:
                os.rename(os.path.join(self.getfullname(), oldfilename),
                          os.path.join(self.getfullname(), newfilename))
            except OSError as e:
                raise OfflineImapError(
                    "Can't rename file '%s' to '%s': %s" %
                    (oldfilename, newfilename, e[1]),
                    OfflineImapError.ERROR.FOLDER)

            self.messagelist[uid]['filename'] = newfilename

        self.messagelist[uid]['flags'] = flags
        xattr.set(os.path.join(self.getfullname(), newfilename),
                  'org.offlineimap.flags',
                  ' '.join(flags),
                  namespace=xattr.NS_USER)
示例#21
0
    def savemessageflags(self, uid, flags):
        """Sets the specified message's flags to the given set.

        This function moves the message to the cur or new subdir,
        depending on the 'S'een flag.

        Note that this function does not check against dryrun settings,
        so you need to ensure that it is never called in a
        dryrun mode."""
        oldfilename = self.messagelist[uid]['filename']
        dir_prefix, filename = os.path.split(oldfilename)
        # If a message has been seen, it goes into 'cur'
        dir_prefix = 'cur' if '\\Seen' in flags else 'new'

        if flags != self.messagelist[uid]['flags']:
            # Flags have actually changed, construct new filename Strip
            # off existing infostring (possibly discarding small letter
            # flags that dovecot uses TODO)
            infomatch = self.re_flagmatch.search(filename)
            if infomatch:
                filename = filename[:-len(infomatch.group())] #strip off
            infostr = '%s2,%s' % (self.infosep,
                                  ''.join(sorted(imaputil.flagsimap2maildir(flags))))
            filename += infostr

        newfilename = os.path.join(dir_prefix, filename)
        if (newfilename != oldfilename):
            try:
                os.rename(os.path.join(self.getfullname(), oldfilename),
                          os.path.join(self.getfullname(), newfilename))
            except OSError as e:
                raise OfflineImapError("Can't rename file '%s' to '%s': %s" % (
                                       oldfilename, newfilename, e[1]),
                                       OfflineImapError.ERROR.FOLDER)

            self.messagelist[uid]['filename'] = newfilename

        self.messagelist[uid]['flags'] = flags
        xattr.set(os.path.join(self.getfullname(), newfilename),
                  'org.offlineimap.flags', ' '.join(flags),
                  namespace=xattr.NS_USER)
示例#22
0
    def cachemessagelist(self):
        if not self.synclabels:
            return super(GmailFolder, self).cachemessagelist()

        self.ui.collectingdata(None, self)
        self.messagelist = {}
        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj)
            if not msgsToFetch:
                return # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            data = self._fetch_from_imap(imapobj, "'%s'" % msgsToFetch,
                                             '(FLAGS X-GM-LABELS UID)')
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in data:
            # looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not 'UID' in options:
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                m = re.search('\(([^\)]*)\)', options['X-GM-LABELS'])
                if m:
                    labels = set([imaputil.dequote(lb) for lb in imaputil.imapsplit(m.group(1))])
                else:
                    labels = set()
                labels = labels - self.ignorelabels
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {'uid': uid, 'flags': flags, 'labels': labels, 'time': rtime}
示例#23
0
文件: IMAP.py 项目: cro/offlineimap
    def savemessageflags(self, uid, flags):
        """Change a message's flags to `flags`.

        Note that this function does not check against dryrun settings,
        so you need to ensure that it is never called in a
        dryrun mode."""
        imapobj = self.imapserver.acquireconnection()
        try:
            result = self._store_to_imap(imapobj, str(uid), 'FLAGS',
                imaputil.flagsmaildir2imap(flags))
        except imapobj.readonly:
            self.ui.flagstoreadonly(self, [uid], flags)
            return
        finally:
            self.imapserver.releaseconnection(imapobj)

        if not result:
            self.messagelist[uid]['flags'] = flags
        else:
            flags = imaputil.flags2hash(imaputil.imapsplit(result)[1])['FLAGS']
            self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags)
示例#24
0
    def savemessageflags(self, uid, flags):
        """Change a message's flags to `flags`.

        Note that this function does not check against dryrun settings,
        so you need to ensure that it is never called in a
        dryrun mode."""
        imapobj = self.imapserver.acquireconnection()
        try:
            result = self._store_to_imap(imapobj, str(uid), 'FLAGS',
                                         imaputil.flagsmaildir2imap(flags))
        except imapobj.readonly:
            self.ui.flagstoreadonly(self, [uid], flags)
            return
        finally:
            self.imapserver.releaseconnection(imapobj)

        if not result:
            self.messagelist[uid]['flags'] = flags
        else:
            flags = imaputil.flags2hash(imaputil.imapsplit(result)[1])['FLAGS']
            self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags)
示例#25
0
    def cachemessagelist(self):
        self.messagelist = {}

        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj)
            if not msgsToFetch:
                return # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            res_type, response = imapobj.fetch("'%s'" % msgsToFetch,
                                               '(FLAGS UID)')
            if res_type != 'OK':
                raise OfflineImapError("FETCHING UIDs in folder [%s]%s failed. "
                                       "Server responded '[%s] %s'" % (
                            self.getrepository(), self,
                            res_type, response),
                        OfflineImapError.ERROR.FOLDER)
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not 'UID' in options:
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                self.messagelist[uid] = self.msglist_item_initializer(uid)
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {'uid': uid, 'flags': flags, 'time': rtime}
示例#26
0
    def cachemessagelist(self, min_date=None, min_uid=None):
        self.ui.loadmessagelist(self.repository, self)
        self.messagelist = {}

        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj, min_date=min_date, min_uid=min_uid)
            if not msgsToFetch:
                return  # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            res_type, response = imapobj.fetch("'%s'" % msgsToFetch, "(FLAGS UID INTERNALDATE)")
            if res_type != "OK":
                raise OfflineImapError(
                    "FETCHING UIDs in folder [%s]%s failed. "
                    "Server responded '[%s] %s'" % (self.getrepository(), self, res_type, response),
                    OfflineImapError.ERROR.FOLDER,
                )
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(" ", 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not "UID" in options:
                self.ui.warn("No UID in message with options %s" % str(options), minor=1)
            else:
                uid = long(options["UID"])
                self.messagelist[uid] = self.msglist_item_initializer(uid)
                flags = imaputil.flagsimap2maildir(options["FLAGS"])
                keywords = imaputil.flagsimap2keywords(options["FLAGS"])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {"uid": uid, "flags": flags, "time": rtime, "keywords": keywords}
        self.ui.messagelistloaded(self.repository, self, self.getmessagecount())
示例#27
0
    def savemessageflags(self, uid, flags):
        """Change a message's flags to `flags`.

        Note that this function does not check against dryrun settings,
        so you need to ensure that it is never called in a
        dryrun mode."""
        imapobj = self.imapserver.acquireconnection()
        try:
            try:
                imapobj.select(self.getfullname())
            except imapobj.readonly:
                self.ui.flagstoreadonly(self, [uid], flags)
                return
            result = imapobj.uid('store', '%d' % uid, 'FLAGS',
                                 imaputil.flagsmaildir2imap(flags))
            assert result[0] == 'OK', 'Error with store: ' + '. '.join(result[1])
        finally:
            self.imapserver.releaseconnection(imapobj)
        result = result[1][0]
        if not result:
            self.messagelist[uid]['flags'] = flags
        else:
            flags = imaputil.flags2hash(imaputil.imapsplit(result)[1])['FLAGS']
            self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags)
示例#28
0
    def cachemessagelist(self):
        imapobj = self.imapserver.acquireconnection()
        self.messagelist = {}

        try:
            # Primes untagged_responses
            imapobj.select(self.getfullname(), readonly = 1, force = 1)
            try:
                # Some mail servers do not return an EXISTS response if
                # the folder is empty.
                maxmsgid = long(imapobj.untagged_responses['EXISTS'][0])
            except KeyError:
                return
            if maxmsgid < 1:
                # No messages; return
                return

            # Now, get the flags and UIDs for these.
            # We could conceivably get rid of maxmsgid and just say
            # '1:*' here.
            response = imapobj.fetch('1:%d' % maxmsgid, '(FLAGS UID INTERNALDATE)')[1]
        finally:
            self.imapserver.releaseconnection(imapobj)
        for messagestr in response:
            # Discard the message number.
            messagestr = string.split(messagestr, maxsplit = 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not options.has_key('UID'):
                UIBase.getglobalui().warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {'uid': uid, 'flags': flags, 'time': rtime}
示例#29
0
    def cachemessagelist(self):
        maxage = self.config.getdefaultint("Account %s" % self.accountname,
                                           "maxage", -1)
        maxsize = self.config.getdefaultint("Account %s" % self.accountname,
                                            "maxsize", -1)
        self.messagelist = {}

        imapobj = self.imapserver.acquireconnection()
        try:
            res_type, imapdata = imapobj.select(self.getfullname(), True, True)
            if imapdata == [None] or imapdata[0] == '0':
                # Empty folder, no need to populate message list
                return
            # By default examine all UIDs in this folder
            msgsToFetch = '1:*'

            if (maxage != -1) | (maxsize != -1):
                search_cond = "("

                if (maxage != -1):
                    #find out what the oldest message is that we should look at
                    oldest_struct = time.gmtime(time.time() -
                                                (60 * 60 * 24 * maxage))
                    if oldest_struct[0] < 1900:
                        raise OfflineImapError(
                            "maxage setting led to year %d. "
                            "Abort syncing." % oldest_struct[0],
                            OfflineImapError.ERROR.REPO)
                    search_cond += "SINCE %02d-%s-%d" % (
                        oldest_struct[2], MonthNames[oldest_struct[1]],
                        oldest_struct[0])

                if (maxsize != -1):
                    if (maxage != -1):  # There are two conditions, add space
                        search_cond += " "
                    search_cond += "SMALLER %d" % maxsize

                search_cond += ")"

                res_type, res_data = imapobj.search(None, search_cond)
                if res_type != 'OK':
                    raise OfflineImapError(
                        "SEARCH in folder [%s]%s failed. "
                        "Search string was '%s'. Server responded '[%s] %s'" %
                        (self.getrepository(), self, search_cond, res_type,
                         res_data), OfflineImapError.ERROR.FOLDER)

                # Result UIDs are seperated by space, coalesce into ranges
                msgsToFetch = imaputil.uid_sequence(res_data[0].split())
                if not msgsToFetch:
                    return  # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            res_type, response = imapobj.fetch("'%s'" % msgsToFetch,
                                               '(FLAGS UID)')
            if res_type != 'OK':
                raise OfflineImapError(
                    "FETCHING UIDs in folder [%s]%s failed. "
                    "Server responded '[%s] %s'" %
                    (self.getrepository(), self, res_type, response),
                    OfflineImapError.ERROR.FOLDER)
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not 'UID' in options:
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {
                    'uid': uid,
                    'flags': flags,
                    'time': rtime
                }
示例#30
0
    def cachemessagelist(self):
        imapobj = self.imapserver.acquireconnection()
        self.messagelist = {}

        try:
            # Primes untagged_responses
            imaptype, imapdata = imapobj.select(self.getfullname(),
                                                readonly=1,
                                                force=1)

            maxage = self.config.getdefaultint("Account " + self.accountname,
                                               "maxage", -1)
            maxsize = self.config.getdefaultint("Account " + self.accountname,
                                                "maxsize", -1)

            if (maxage != -1) | (maxsize != -1):
                try:
                    search_condition = "("

                    if (maxage != -1):
                        #find out what the oldest message is that we should look at
                        oldest_time_struct = time.gmtime(time.time() -
                                                         (60 * 60 * 24 *
                                                          maxage))

                        #format this manually - otherwise locales could cause problems
                        monthnames_standard = ["Jan", "Feb", "Mar", "Apr", "May", \
                            "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"]

                        our_monthname = monthnames_standard[
                            oldest_time_struct[1] - 1]
                        daystr = "%(day)02d" % {'day': oldest_time_struct[2]}
                        date_search_str = "SINCE " + daystr + "-" + our_monthname \
                            + "-" + str(oldest_time_struct[0])

                        search_condition += date_search_str

                    if (maxsize != -1):
                        if (maxage !=
                                1):  #There are two conditions - add a space
                            search_condition += " "

                        search_condition += "SMALLER " + self.config.getdefault(
                            "Account " + self.accountname, "maxsize", -1)

                    search_condition += ")"
                    searchresult = imapobj.search(None, search_condition)

                    #result would come back seperated by space - to change into a fetch
                    #statement we need to change space to comma
                    messagesToFetch = searchresult[1][0].replace(" ", ",")
                except KeyError:
                    return
                if len(messagesToFetch) < 1:
                    # No messages; return
                    return
            else:
                # 1. Some mail servers do not return an EXISTS response
                # if the folder is empty.  2. ZIMBRA servers can return
                # multiple EXISTS replies in the form 500, 1000, 1500,
                # 1623 so check for potentially multiple replies.
                if imapdata == [None]:
                    return

                maxmsgid = 0
                for msgid in imapdata:
                    maxmsgid = max(long(msgid), maxmsgid)

                maxmsgid = long(imapdata[0])
                messagesToFetch = '1:%d' % maxmsgid

                if maxmsgid < 1:
                    #no messages; return
                    return
            # Now, get the flags and UIDs for these.
            # We could conceivably get rid of maxmsgid and just say
            # '1:*' here.
            response = imapobj.fetch(messagesToFetch, '(FLAGS UID)')[1]
        finally:
            self.imapserver.releaseconnection(imapobj)
        for messagestr in response:
            # Discard the message number.
            messagestr = messagestr.split(' ', 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not options.has_key('UID'):
                self.ui.warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {
                    'uid': uid,
                    'flags': flags,
                    'time': rtime
                }
示例#31
0
    def cachemessagelist(self, min_date=None, min_uid=None):
        if not self.synclabels:
            return super(GmailFolder, self).cachemessagelist(min_date=min_date,
                                                             min_uid=min_uid)

        self.dropmessagelistcache()

        self.ui.collectingdata(None, self)
        imapobj = self.imapserver.acquireconnection()
        try:
            msgsToFetch = self._msgs_to_fetch(imapobj,
                                              min_date=min_date,
                                              min_uid=min_uid)
            if not msgsToFetch:
                return  # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            #
            # NB: msgsToFetch are sequential numbers, not UID's
            res_type, response = imapobj.fetch("%s" % msgsToFetch,
                                               '(FLAGS X-GM-LABELS UID)')
            if res_type != 'OK':
                raise OfflineImapError(
                    "FETCHING UIDs in folder [%s]%s failed. " %
                    (self.getrepository(), self) +
                    "Server responded '[%s] %s'" % (res_type, response),
                    OfflineImapError.ERROR.FOLDER,
                    exc_info()[2])
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) X-GM-LABELS (\\Inbox \\Favorites) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr is None:
                continue
            messagestr = messagestr.decode('utf-8').split(' ', 1)[1]
            # e.g.: {'X-GM-LABELS': '("Webserver (RW.net)" "\\Inbox" GInbox)', 'FLAGS': '(\\Seen)', 'UID': '275440'}
            options = imaputil.flags2hash(messagestr)
            if 'UID' not in options:
                self.ui.warn('No UID in message with options %s' %
                             str(options),
                             minor=1)
            else:
                uid = int(options['UID'])
                self.messagelist[uid] = self.msglist_item_initializer(uid)
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                # e.g.: '("Webserver (RW.net)" "\\Inbox" GInbox)'
                m = re.search('^[(](.*)[)]', options['X-GM-LABELS'])
                if m:
                    labels = set([
                        imaputil.dequote(lb)
                        for lb in imaputil.imapsplit(m.group(1))
                    ])
                else:
                    labels = set()
                labels = labels - self.ignorelabels
                rtime = imaplibutil.Internaldate2epoch(messagestr.encode())
                self.messagelist[uid] = {
                    'uid': uid,
                    'flags': flags,
                    'labels': labels,
                    'time': rtime
                }
示例#32
0
    def cachemessagelist(self):
        imapobj = self.imapserver.acquireconnection()
        self.messagelist = {}

        try:
            # Primes untagged_responses
            imaptype, imapdata = imapobj.select(self.getfullname(), readonly=1, force=1)

            maxage = self.config.getdefaultint("Account " + self.accountname, "maxage", -1)
            maxsize = self.config.getdefaultint("Account " + self.accountname, "maxsize", -1)

            if (maxage != -1) | (maxsize != -1):
                try:
                    search_condition = "("

                    if maxage != -1:
                        # find out what the oldest message is that we should look at
                        oldest_time_struct = time.gmtime(time.time() - (60 * 60 * 24 * maxage))

                        # format this manually - otherwise locales could cause problems
                        monthnames_standard = [
                            "Jan",
                            "Feb",
                            "Mar",
                            "Apr",
                            "May",
                            "Jun",
                            "Jul",
                            "Aug",
                            "Sep",
                            "Oct",
                            "Nov",
                            "Dec",
                        ]

                        our_monthname = monthnames_standard[oldest_time_struct[1] - 1]
                        daystr = "%(day)02d" % {"day": oldest_time_struct[2]}
                        date_search_str = "SINCE " + daystr + "-" + our_monthname + "-" + str(oldest_time_struct[0])

                        search_condition += date_search_str

                    if maxsize != -1:
                        if maxage != -1:  # There are two conditions - add a space
                            search_condition += " "

                        search_condition += "SMALLER " + self.config.getdefault(
                            "Account " + self.accountname, "maxsize", -1
                        )

                    search_condition += ")"
                    searchresult = imapobj.search(None, search_condition)

                    # result would come back seperated by space - to change into a fetch
                    # statement we need to change space to comma
                    messagesToFetch = searchresult[1][0].replace(" ", ",")
                except KeyError:
                    return
                if len(messagesToFetch) < 1:
                    # No messages; return
                    return
            else:
                # 1. Some mail servers do not return an EXISTS response
                # if the folder is empty.  2. ZIMBRA servers can return
                # multiple EXISTS replies in the form 500, 1000, 1500,
                # 1623 so check for potentially multiple replies.
                if imapdata == [None]:
                    return

                maxmsgid = 0
                for msgid in imapdata:
                    maxmsgid = max(long(msgid), maxmsgid)
                if maxmsgid < 1:
                    # no messages; return
                    return
                messagesToFetch = "1:%d" % maxmsgid

            # Now, get the flags and UIDs for these.
            # We could conceivably get rid of maxmsgid and just say
            # '1:*' here.
            response = imapobj.fetch(messagesToFetch, "(FLAGS UID)")[1]
        finally:
            self.imapserver.releaseconnection(imapobj)
        for messagestr in response:
            # Discard the message number.
            messagestr = messagestr.split(" ", 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not options.has_key("UID"):
                self.ui.warn("No UID in message with options %s" % str(options), minor=1)
            else:
                uid = long(options["UID"])
                flags = imaputil.flagsimap2maildir(options["FLAGS"])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {"uid": uid, "flags": flags, "time": rtime}
示例#33
0
    def cachemessagelist(self):
        maxage = self.config.getdefaultint("Account %s" % self.accountname, "maxage", -1)
        maxsize = self.config.getdefaultint("Account %s" % self.accountname, "maxsize", -1)
        self.messagelist = {}

        imapobj = self.imapserver.acquireconnection()
        try:
            res_type, imapdata = imapobj.select(self.getfullname(), True)
            if imapdata == [None] or imapdata[0] == "0":
                # Empty folder, no need to populate message list
                return
            # By default examine all UIDs in this folder
            msgsToFetch = "1:*"

            if (maxage != -1) | (maxsize != -1):
                search_cond = "("

                if maxage != -1:
                    # find out what the oldest message is that we should look at
                    oldest_struct = time.gmtime(time.time() - (60 * 60 * 24 * maxage))
                    if oldest_struct[0] < 1900:
                        raise OfflineImapError(
                            "maxage setting led to year %d. " "Abort syncing." % oldest_struct[0],
                            OfflineImapError.ERROR.REPO,
                        )
                    search_cond += "SINCE %02d-%s-%d" % (
                        oldest_struct[2],
                        MonthNames[oldest_struct[1]],
                        oldest_struct[0],
                    )

                if maxsize != -1:
                    if maxage != -1:  # There are two conditions, add space
                        search_cond += " "
                    search_cond += "SMALLER %d" % maxsize

                search_cond += ")"

                res_type, res_data = imapobj.search(None, search_cond)
                if res_type != "OK":
                    raise OfflineImapError(
                        "SEARCH in folder [%s]%s failed. "
                        "Search string was '%s'. Server responded '[%s] %s'"
                        % (self.getrepository(), self, search_cond, res_type, res_data),
                        OfflineImapError.ERROR.FOLDER,
                    )

                # Result UIDs are seperated by space, coalesce into ranges
                msgsToFetch = imaputil.uid_sequence(res_data[0].split())
                if not msgsToFetch:
                    return  # No messages to sync

            # Get the flags and UIDs for these. single-quotes prevent
            # imaplib2 from quoting the sequence.
            res_type, response = imapobj.fetch("'%s'" % msgsToFetch, "(FLAGS UID)")
            if res_type != "OK":
                raise OfflineImapError(
                    "FETCHING UIDs in folder [%s]%s failed. "
                    "Server responded '[%s] %s'" % (self.getrepository(), self, res_type, response),
                    OfflineImapError.ERROR.FOLDER,
                )
        finally:
            self.imapserver.releaseconnection(imapobj)

        for messagestr in response:
            # looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
            # Discard initial message number.
            if messagestr == None:
                continue
            messagestr = messagestr.split(" ", 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not options.has_key("UID"):
                self.ui.warn("No UID in message with options %s" % str(options), minor=1)
            else:
                uid = long(options["UID"])
                flags = imaputil.flagsimap2maildir(options["FLAGS"])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {"uid": uid, "flags": flags, "time": rtime}
示例#34
0
 def test_05_flagsimap2maildir(self):
     """Test imaputil.flagsimap2maildir()"""
     res = imaputil.flagsimap2maildir(b'(\\Draft \\Deleted)')
     self.assertEqual(res, set(b'DT'))
 def test_05_flagsimap2maildir(self):
     """Test imaputil.flagsimap2maildir()"""
     res = imaputil.flagsimap2maildir(b'(\\Draft \\Deleted)')
     self.assertEqual(res, set(b'DT'))
示例#36
0
    def cachemessagelist(self):
        imapobj = self.imapserver.acquireconnection()
        self.messagelist = {}

        try:
            # Primes untagged_responses
            imapobj.select(self.getfullname(), readonly = 1, force = 1)

            maxage = self.config.getdefaultint("Account " + self.accountname, "maxage", -1)
            maxsize = self.config.getdefaultint("Account " + self.accountname, "maxsize", -1)

            if (maxage != -1) | (maxsize != -1):
                try:
                    search_condition = "(";

                    if(maxage != -1):
                        #find out what the oldest message is that we should look at
                        oldest_time_struct = time.gmtime(time.time() - (60*60*24*maxage))

                        #format this manually - otherwise locales could cause problems
                        monthnames_standard = ["Jan", "Feb", "Mar", "Apr", "May", \
                            "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"]

                        our_monthname = monthnames_standard[oldest_time_struct[1]-1]
                        daystr = "%(day)02d" % {'day' : oldest_time_struct[2]}
                        date_search_str = "SINCE " + daystr + "-" + our_monthname \
                            + "-" + str(oldest_time_struct[0])

                        search_condition += date_search_str

                    if(maxsize != -1):
                        if(maxage != 1): #There are two conditions - add a space
                            search_condition += " "

                        search_condition += "SMALLER " + self.config.getdefault("Account " + self.accountname, "maxsize", -1)

                    search_condition += ")"
                    searchresult = imapobj.search(None, search_condition)

                    #result would come back seperated by space - to change into a fetch
                    #statement we need to change space to comma
                    messagesToFetch = searchresult[1][0].replace(" ", ",")
                except KeyError:
                    return
                if len(messagesToFetch) < 1:
                    # No messages; return
                    return
            else:
                try:
                    # Some mail servers do not return an EXISTS response if
                    # the folder is empty.

                    maxmsgid = long(imapobj.untagged_responses['EXISTS'][0])
                    messagesToFetch = '1:%d' % maxmsgid;
                except KeyError:
                    return
                if maxmsgid < 1:
                    #no messages; return
                    return
            # Now, get the flags and UIDs for these.
            # We could conceivably get rid of maxmsgid and just say
            # '1:*' here.
            response = imapobj.fetch(messagesToFetch, '(FLAGS UID)')[1]
        finally:
            self.imapserver.releaseconnection(imapobj)
        for messagestr in response:
            # Discard the message number.
            messagestr = string.split(messagestr, maxsplit = 1)[1]
            options = imaputil.flags2hash(messagestr)
            if not options.has_key('UID'):
                UIBase.getglobalui().warn('No UID in message with options %s' %\
                                          str(options),
                                          minor = 1)
            else:
                uid = long(options['UID'])
                flags = imaputil.flagsimap2maildir(options['FLAGS'])
                rtime = imaplibutil.Internaldate2epoch(messagestr)
                self.messagelist[uid] = {'uid': uid, 'flags': flags, 'time': rtime}