Beispiel #1
0
    def change_message_uid(self, uid, new_uid):
        """Change the message from existing uid to new_uid

        This will not update the statusfolder UID, you need to do that yourself.
        :param new_uid: (optional) If given, the old UID will be changed
                        to a new UID. The Maildir backend can implement this as
                        an efficient rename.
        """

        if not uid in self.messagelist:
            raise OfflineImapError("Cannot change unknown Maildir UID %s" %
                                   uid)
        if uid == new_uid: return

        oldfilename = self.messagelist[uid]['filename']
        dir_prefix, filename = os.path.split(oldfilename)
        flags = self.getmessageflags(uid)
        content = self.getmessage(uid)
        rtime = emailutil.get_message_date(content)
        newfilename = os.path.join(
            dir_prefix, self.new_message_filename(new_uid, flags, rtime=rtime))
        os.rename(os.path.join(self.getfullname(), oldfilename),
                  os.path.join(self.getfullname(), newfilename))
        self.messagelist[new_uid] = self.messagelist[uid]
        self.messagelist[new_uid]['filename'] = newfilename
        del self.messagelist[uid]
Beispiel #2
0
    def change_message_uid(self, uid, new_uid):
        """Change the message from existing uid to new_uid

        This will not update the statusfolder UID, you need to do that yourself.
        :param new_uid: (optional) If given, the old UID will be changed
                        to a new UID. The Maildir backend can implement this as
                        an efficient rename.
        """

        if not uid in self.messagelist:
            raise OfflineImapError("Cannot change unknown Maildir UID %s"% uid)
        if uid == new_uid: return

        oldfilename = self.messagelist[uid]['filename']
        dir_prefix, filename = os.path.split(oldfilename)
        flags = self.getmessageflags(uid)
        content = self.getmessage(uid)
        rtime = emailutil.get_message_date(content)
        newfilename = os.path.join(dir_prefix,
          self.new_message_filename(new_uid, flags, rtime=rtime))
        os.rename(os.path.join(self.getfullname(), oldfilename),
                  os.path.join(self.getfullname(), newfilename))
        self.messagelist[new_uid] = self.messagelist[uid]
        self.messagelist[new_uid]['filename'] = newfilename
        del self.messagelist[uid]
Beispiel #3
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
Beispiel #4
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
Beispiel #5
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')
        # Make sure rtime is the internal date, so it can be put in the filename
        if rtime is None:
            rtime = emailutil.get_message_date(content)
        messagename = self.new_message_filename(uid, flags, rtime=rtime)
        tmpname = self.save_to_tmp_file(messagename, content)
        if rtime != None:
            os.utime(os.path.join(self.getfullname(), tmpname), (rtime, rtime))

        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
Beispiel #6
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:
            date = emailutil.get_message_date(content, 'Date')
            if date != None:
                os.utime(os.path.join(self.getfullname(), tmpname), (date, date))

        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
Beispiel #7
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

        # Use the mail timestamp given by either Date or Delivery-date mail
        # headers.
        message_timestamp = None
        if self._filename_use_mail_timestamp is not False:
            try:
                message_timestamp = emailutil.get_message_date(content, 'Date')
                if message_timestamp is None:
                    # Give a try with Delivery-date
                    message_timestamp = emailutil.get_message_date(
                        content, 'Delivery-date')
            except Exception as e:
                # This should never happen.
                from offlineimap.ui import getglobalui
                datestr = emailutil.get_message_date(content)
                ui = getglobalui()
                ui.warn("UID %d has invalid date %s: %s\n"
                        "Not using message timestamp as file prefix" %
                        (uid, datestr, e))
                # No need to check if message_timestamp is None here since it
                # would be overridden by _gettimeseq.
        messagename = self.new_message_filename(uid,
                                                flags,
                                                date=message_timestamp)
        tmpname = self.save_to_tmp_file(messagename, content)

        if self._utime_from_header is True:
            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 offlineimap.ui import getglobalui
                datestr = emailutil.get_message_date(content)
                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
Beispiel #8
0
    def copymessageto(self, uid, dstfolder, statusfolder, register = 1):
        """Copies a message from self to dst if needed, updating the status

        Note that this function does not check against dryrun settings,
        so you need to ensure that it is never called in a
        dryrun mode.

        :param uid: uid of the message to be copied.
        :param dstfolder: A BaseFolder-derived instance
        :param statusfolder: A LocalStatusFolder instance
        :param register: whether we should register a new thread."
        :returns: Nothing on success, or raises an Exception."""
        # Sometimes, it could be the case that if a sync takes awhile,
        # a message might be deleted from the maildir before it can be
        # synced to the status cache.  This is only a problem with
        # self.getmessage().  So, don't call self.getmessage unless
        # really needed.
        if register: # output that we start a new thread
            self.ui.registerthread(self.repository.account)

        try:
            message = None
            flags = self.getmessageflags(uid)
            rtime = self.getmessagetime(uid)
            if dstfolder.utime_from_message:
                content = self.getmessage(uid)
                rtime = emailutil.get_message_date(content, 'Date')

            if uid > 0 and dstfolder.uidexists(uid):
                # dst has message with that UID already, only update status
                statusfolder.savemessage(uid, None, flags, rtime)
                return

            # If any of the destinations actually stores the message body,
            # load it up.
            if dstfolder.storesmessages():
                message = self.getmessage(uid)
            #Succeeded? -> IMAP actually assigned a UID. If newid
            #remained negative, no server was willing to assign us an
            #UID. If newid is 0, saving succeeded, but we could not
            #retrieve the new UID. Ignore message in this case.
            new_uid = dstfolder.savemessage(uid, message, flags, rtime)
            if new_uid > 0:
                if new_uid != uid:
                    # Got new UID, change the local uid to match the new one.
                    self.change_message_uid(uid, new_uid)
                    statusfolder.deletemessage(uid)
                    # Got new UID, change the local uid.
                # Save uploaded status in the statusfolder
                statusfolder.savemessage(new_uid, message, flags, rtime)
            elif new_uid == 0:
                # Message was stored to dstfolder, but we can't find it's UID
                # This means we can't link current message to the one created
                # in IMAP. So we just delete local message and on next run
                # we'll sync it back
                # XXX This could cause infinite loop on syncing between two
                # IMAP servers ...
                self.deletemessage(uid)
            else:
                raise OfflineImapError("Trying to save msg (uid %d) on folder "
                                       "%s returned invalid uid %d" % (uid,
                                       dstfolder.getvisiblename(), new_uid),
                                       OfflineImapError.ERROR.MESSAGE)
        except (KeyboardInterrupt): # bubble up CTRL-C
            raise
        except OfflineImapError as e:
            if e.severity > OfflineImapError.ERROR.MESSAGE:
                raise # bubble severe errors up
            self.ui.error(e, exc_info()[2])
        except Exception as e:
            self.ui.error(e, exc_info()[2],
              msg="Copying message %s [acc: %s]" %\
                              (uid, self.accountname))
            raise    #raise on unknown errors, so we can fix those
Beispiel #9
0
    def __getmessageinternaldate(self, content, rtime=None):
        """Parses mail and returns an INTERNALDATE string

        It will use information in the following order, falling back as an
        attempt fails:
          - rtime parameter
          - Date header of email

        We return None, if we couldn't find a valid date. In this case
        the IMAP server will use the server local time when appening
        (per RFC).

        Note, that imaplib's Time2Internaldate is inherently broken as
        it returns localized date strings which are invalid for IMAP
        servers. However, that function is called for *every* append()
        internally. So we need to either pass in `None` or the correct
        string (in which case Time2Internaldate() will do nothing) to
        append(). The output of this function is designed to work as
        input to the imapobj.append() function.

        TODO: We should probably be returning a bytearray rather than a
        string here, because the IMAP server will expect plain
        ASCII. However, imaplib.Time2INternaldate currently returns a
        string so we go with the same for now.

        :param rtime: epoch timestamp to be used rather than analyzing
                  the email.
        :returns: string in the form of "DD-Mmm-YYYY HH:MM:SS +HHMM"
                  (including double quotes) or `None` in case of failure
                  (which is fine as value for append)."""

        if rtime is None:
            rtime = emailutil.get_message_date(content)
            if rtime == None:
                return None
        datetuple = time.localtime(rtime)

        try:
            # Check for invalid dates.
            if datetuple[0] < 1981:
                raise ValueError

            # Check for invalid dates.
            datetuple_check = time.localtime(time.mktime(datetuple))
            if datetuple[:2] != datetuple_check[:2]:
                raise ValueError

        except (ValueError, OverflowError):
            # Argh, sometimes it's a valid format but year is 0102
            # or something.  Argh.  It seems that Time2Internaldate
            # will rause a ValueError if the year is 0102 but not 1902,
            # but some IMAP servers nonetheless choke on 1902.
            self.ui.debug('imap', "Message with invalid date %s. "
                "Server will use local time."% datetuple)
            return None

        # Produce a string representation of datetuple that works as
        # INTERNALDATE.
        num2mon = {1:'Jan', 2:'Feb', 3:'Mar', 4:'Apr', 5:'May', 6:'Jun',
                   7:'Jul', 8:'Aug', 9:'Sep', 10:'Oct', 11:'Nov', 12:'Dec'}

        # tm_isdst coming from email.parsedate is not usable, we still use it
        # here, mhh.
        if datetuple.tm_isdst == 1:
            zone = -time.altzone
        else:
            zone = -time.timezone
        offset_h, offset_m = divmod(zone//60, 60)

        internaldate = '"%02d-%s-%04d %02d:%02d:%02d %+03d%02d"'% \
            (datetuple.tm_mday, num2mon[datetuple.tm_mon], datetuple.tm_year, \
             datetuple.tm_hour, datetuple.tm_min, datetuple.tm_sec, offset_h, offset_m)

        return internaldate
Beispiel #10
0
    def __getmessageinternaldate(self, content, rtime=None):
        """Parses mail and returns an INTERNALDATE string

        It will use information in the following order, falling back as an
        attempt fails:
          - rtime parameter
          - Date header of email

        We return None, if we couldn't find a valid date. In this case
        the IMAP server will use the server local time when appening
        (per RFC).

        Note, that imaplib's Time2Internaldate is inherently broken as
        it returns localized date strings which are invalid for IMAP
        servers. However, that function is called for *every* append()
        internally. So we need to either pass in `None` or the correct
        string (in which case Time2Internaldate() will do nothing) to
        append(). The output of this function is designed to work as
        input to the imapobj.append() function.

        TODO: We should probably be returning a bytearray rather than a
        string here, because the IMAP server will expect plain
        ASCII. However, imaplib.Time2INternaldate currently returns a
        string so we go with the same for now.

        :param rtime: epoch timestamp to be used rather than analyzing
                  the email.
        :returns: string in the form of "DD-Mmm-YYYY HH:MM:SS +HHMM"
                  (including double quotes) or `None` in case of failure
                  (which is fine as value for append)."""

        if rtime is None:
            rtime = emailutil.get_message_date(content)
            if rtime == None:
                return None
        datetuple = time.localtime(rtime)

        try:
            # Check for invalid dates.
            if datetuple[0] < 1981:
                raise ValueError

            # Check for invalid dates.
            datetuple_check = time.localtime(time.mktime(datetuple))
            if datetuple[:2] != datetuple_check[:2]:
                raise ValueError

        except (ValueError, OverflowError):
            # Argh, sometimes it's a valid format but year is 0102
            # or something.  Argh.  It seems that Time2Internaldate
            # will rause a ValueError if the year is 0102 but not 1902,
            # but some IMAP servers nonetheless choke on 1902.
            self.ui.debug(
                'imap', "Message with invalid date %s. "
                "Server will use local time." % datetuple)
            return None

        # Produce a string representation of datetuple that works as
        # INTERNALDATE.
        num2mon = {
            1: 'Jan',
            2: 'Feb',
            3: 'Mar',
            4: 'Apr',
            5: 'May',
            6: 'Jun',
            7: 'Jul',
            8: 'Aug',
            9: 'Sep',
            10: 'Oct',
            11: 'Nov',
            12: 'Dec'
        }

        # tm_isdst coming from email.parsedate is not usable, we still use it
        # here, mhh.
        if datetuple.tm_isdst == 1:
            zone = -time.altzone
        else:
            zone = -time.timezone
        offset_h, offset_m = divmod(zone // 60, 60)

        internaldate = '"%02d-%s-%04d %02d:%02d:%02d %+03d%02d"'% \
            (datetuple.tm_mday, num2mon[datetuple.tm_mon], datetuple.tm_year, \
             datetuple.tm_hour, datetuple.tm_min, datetuple.tm_sec, offset_h, offset_m)

        return internaldate
Beispiel #11
0
    def copymessageto(self, uid, dstfolder, statusfolder, register = 1):
        """Copies a message from self to dst if needed, updating the status

        Note that this function does not check against dryrun settings,
        so you need to ensure that it is never called in a
        dryrun mode.

        :param uid: uid of the message to be copied.
        :param dstfolder: A BaseFolder-derived instance
        :param statusfolder: A LocalStatusFolder instance
        :param register: whether we should register a new thread."
        :returns: Nothing on success, or raises an Exception."""

        # Sometimes, it could be the case that if a sync takes awhile,
        # a message might be deleted from the maildir before it can be
        # synced to the status cache.  This is only a problem with
        # self.getmessage().  So, don't call self.getmessage unless
        # really needed.
        if register: # output that we start a new thread
            self.ui.registerthread(self.repository.account)

        try:
            message = None
            flags = self.getmessageflags(uid)
            rtime = self.getmessagetime(uid)
            if dstfolder.utime_from_message:
                content = self.getmessage(uid)
                rtime = emailutil.get_message_date(content, 'Date')

            if uid > 0 and dstfolder.uidexists(uid):
                # dst has message with that UID already, only update status
                statusfolder.savemessage(uid, None, flags, rtime)
                return

            # If any of the destinations actually stores the message body,
            # load it up.
            if dstfolder.storesmessages():
                message = self.getmessage(uid)
            # Succeeded? -> IMAP actually assigned a UID. If newid
            # remained negative, no server was willing to assign us an
            # UID. If newid is 0, saving succeeded, but we could not
            # retrieve the new UID. Ignore message in this case.
            new_uid = dstfolder.savemessage(uid, message, flags, rtime)
            if new_uid > 0:
                if new_uid != uid:
                    # Got new UID, change the local uid to match the new one.
                    self.change_message_uid(uid, new_uid)
                    statusfolder.deletemessage(uid)
                    # Got new UID, change the local uid.
                # Save uploaded status in the statusfolder
                statusfolder.savemessage(new_uid, message, flags, rtime)
            elif new_uid == 0:
                # Message was stored to dstfolder, but we can't find it's UID
                # This means we can't link current message to the one created
                # in IMAP. So we just delete local message and on next run
                # we'll sync it back
                # XXX This could cause infinite loop on syncing between two
                # IMAP servers ...
                self.deletemessage(uid)
            else:
                raise OfflineImapError("Trying to save msg (uid %d) on folder "
                    "%s returned invalid uid %d"% (uid, dstfolder.getvisiblename(),
                    new_uid), OfflineImapError.ERROR.MESSAGE)
        except (KeyboardInterrupt): # bubble up CTRL-C
            raise
        except OfflineImapError as e:
            if e.severity > OfflineImapError.ERROR.MESSAGE:
                raise # bubble severe errors up
            self.ui.error(e, exc_info()[2])
        except Exception as e:
            self.ui.error(e, exc_info()[2],
              msg = "Copying message %s [acc: %s]"% (uid, self.accountname))
            raise    #raise on unknown errors, so we can fix those
Beispiel #12
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')

        # use the mail timestamp given by either Date or Delivery-date mail
        # headers.
        message_timestamp = None
        if self._filename_use_mail_timestamp:
            try:
                message_timestamp = emailutil.get_message_date(content, 'Date')
                if message_timestamp is None:
                    # Give a try with Delivery-date
                    date = emailutil.get_message_date(content, 'Delivery-date')
            except:
                # This should never happen
                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 using message timestamp as file prefix" % (uid, datestr, e))
                # No need to check if date is None here since it would
                # be overridden by _gettimeseq.
        messagename = self.new_message_filename(uid, flags, date=message_timestamp)
        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