def savemessagelabels(self, uid, labels, ignorelabels=None): """Change a message's labels to `labels`. Note that this function does not check against dryrun settings, so you need to ensure that it is never called in a dryrun mode.""" if ignorelabels is None: ignorelabels = set() filename = self.messagelist[uid]['filename'] filepath = os.path.join(self.getfullname(), filename) with codecs.open(filepath, 'r', errors='replace', encoding='utf-8') as f: content = f.read() oldlabels = set() for hstr in self.getmessageheaderlist(content, self.labelsheader): oldlabels.update(imaputil.labels_from_header(self.labelsheader, hstr)) labels = labels - ignorelabels ignoredlabels = oldlabels & ignorelabels oldlabels = oldlabels - ignorelabels # Nothing to change. if labels == oldlabels: return # Change labels into content. labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels | ignoredlabels)) # First remove old labels header, and then add the new one. content = self.deletemessageheaders(content, self.labelsheader) content = self.addmessageheader(content, '\n', self.labelsheader, labels_str) mtime = int(os.stat(filepath).st_mtime) # Write file with new labels to a unique file in tmp. messagename = self.new_message_filename(uid, set()) tmpname = self.save_to_tmp_file(messagename, content) tmppath = os.path.join(self.getfullname(), tmpname) # Move to actual location. try: os.rename(tmppath, filepath) except OSError as e: raise OfflineImapError("Can't rename file '%s' to '%s': %s" % (tmppath, filepath, e[1]), OfflineImapError.ERROR.FOLDER, exc_info()[2]) # If utime_from_header=true, we don't want to change the mtime. if self._utime_from_header and mtime: os.utime(filepath, (mtime, mtime)) # save the new mtime and labels self.messagelist[uid]['mtime'] = int(os.stat(filepath).st_mtime) self.messagelist[uid]['labels'] = labels
def savemessagelabels(self, uid, labels, ignorelabels=set()): """Change a message's labels to `labels`. Note that this function does not check against dryrun settings, so you need to ensure that it is never called in a dryrun mode.""" filename = self.messagelist[uid]['filename'] filepath = os.path.join(self.getfullname(), filename) file = open(filepath, 'rt') content = file.read() file.close() oldlabels = set() for hstr in self.getmessageheaderlist(content, self.labelsheader): oldlabels.update(imaputil.labels_from_header(self.labelsheader, hstr)) labels = labels - ignorelabels ignoredlabels = oldlabels & ignorelabels oldlabels = oldlabels - ignorelabels # Nothing to change. if labels == oldlabels: return # Change labels into content. labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels | ignoredlabels)) # First remove old labels header, and then add the new one. content = self.deletemessageheaders(content, self.labelsheader) content = self.addmessageheader(content, '\n', self.labelsheader, labels_str) mtime = int(os.stat(filepath).st_mtime) # Write file with new labels to a unique file in tmp. messagename = self.new_message_filename(uid, set()) tmpname = self.save_to_tmp_file(messagename, content) tmppath = os.path.join(self.getfullname(), tmpname) # Move to actual location. try: os.rename(tmppath, filepath) except OSError as e: six.reraise(OfflineImapError, OfflineImapError("Can't rename file '%s' to '%s': %s"% (tmppath, filepath, e[1]), OfflineImapError.ERROR.FOLDER), exc_info()[2]) # If utime_from_header=true, we don't want to change the mtime. if self._utime_from_header and mtime: os.utime(filepath, (mtime, mtime)) # save the new mtime and labels self.messagelist[uid]['mtime'] = int(os.stat(filepath).st_mtime) self.messagelist[uid]['labels'] = labels
def savemessagelabels(self, uid, labels, ignorelabels=set()): """Change a message's labels to `labels`. Note that this function does not check against dryrun settings, so you need to ensure that it is never called in a dryrun mode.""" filename = self.messagelist[uid]['filename'] filepath = os.path.join(self.getfullname(), filename) file = open(filepath, 'rt') content = file.read() file.close() oldlabels = set() for hstr in self.getmessageheaderlist(content, self.labelsheader): oldlabels.update(imaputil.labels_from_header(self.labelsheader, hstr)) labels = labels - ignorelabels ignoredlabels = oldlabels & ignorelabels oldlabels = oldlabels - ignorelabels # Nothing to change if labels == oldlabels: return # Change labels into content labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels | ignoredlabels)) # First remove old labels header, and then add the new one content = self.deletemessageheaders(content, self.labelsheader) content = self.addmessageheader(content, '\n', self.labelsheader, labels_str) rtime = self.messagelist[uid].get('rtime', None) # write file with new labels to a unique file in tmp messagename = self.new_message_filename(uid, set()) tmpname = self.save_to_tmp_file(messagename, content) tmppath = os.path.join(self.getfullname(), tmpname) # move to actual location try: os.rename(tmppath, filepath) except OSError as e: raise OfflineImapError("Can't rename file '%s' to '%s': %s" % \ (tmppath, filepath, e[1]), OfflineImapError.ERROR.FOLDER), \ None, exc_info()[2] if rtime != None: os.utime(filepath, (rtime, rtime)) # save the new mtime and labels self.messagelist[uid]['mtime'] = long(os.stat(filepath).st_mtime) self.messagelist[uid]['labels'] = labels
def getmessage(self, uid): """Retrieve message with UID from the IMAP server (incl body). Also gets Gmail labels and embeds them into the message. :returns: the message body or throws and OfflineImapError (probably severity MESSAGE) if e.g. no message with this UID could be found. """ imapobj = self.imapserver.acquireconnection() try: data = self._fetch_from_imap(imapobj, str(uid), 2) finally: self.imapserver.releaseconnection(imapobj) # data looks now e.g. #[('320 (X-GM-LABELS (...) UID 17061 BODY[] {2565}','msgbody....')] # we only asked for one message, and that msg is in data[0]. # msbody is in [0][1]. body = data[0][1].replace("\r\n", "\n") # Embed the labels into the message headers if self.synclabels: m = re.search('X-GM-LABELS\s*\(([^\)]*)\)', data[0][0]) if m: labels = set([ imaputil.dequote(lb) for lb in imaputil.imapsplit(m.group(1)) ]) else: labels = set() labels = labels - self.ignorelabels labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels)) # First remove old label headers that may be in the message content retrieved # from gmail Then add a labels header with current gmail labels. body = self.deletemessageheaders(body, self.labelsheader) body = self.addmessageheader(body, '\n', self.labelsheader, labels_str) if len(body) > 200: dbg_output = "%s...%s" % (str(body)[:150], str(body)[-50:]) else: dbg_output = body self.ui.debug( 'imap', "Returned object from fetching %d: '%s'" % (uid, dbg_output)) return body
def savemessagelabels(self, uid, labels, ignorelabels=set()): """Change a message's labels to `labels`. Note that this function does not check against dryrun settings, so you need to ensure that it is never called in a dryrun mode.""" filename = self.messagelist[uid]['filename'] filepath = os.path.join(self.getfullname(), filename) file = open(filepath, 'rt') content = file.read() file.close() oldlabels = imaputil.labels_from_header(self.labelsheader, self.getmessageheader(content, self.labelsheader)) labels = labels - ignorelabels ignoredlabels = oldlabels & ignorelabels oldlabels = oldlabels - ignorelabels # Nothing to change if labels == oldlabels: return # Change labels into content labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels | ignoredlabels)) content = self.addmessageheader(content, '\n', self.labelsheader, labels_str) rtime = self.messagelist[uid].get('rtime', None) # write file with new labels to a unique file in tmp messagename = self.new_message_filename(uid, set()) tmpname = self.save_to_tmp_file(messagename, content) tmppath = os.path.join(self.getfullname(), tmpname) # move to actual location try: os.rename(tmppath, filepath) except OSError as e: raise OfflineImapError("Can't rename file '%s' to '%s': %s" % \ (tmppath, filepath, e[1]), OfflineImapError.ERROR.FOLDER) if rtime != None: os.utime(filepath, (rtime, rtime)) # save the new mtime and labels self.messagelist[uid]['mtime'] = long(os.stat(filepath).st_mtime) self.messagelist[uid]['labels'] = labels
def getmessage(self, uid): """Retrieve message with UID from the IMAP server (incl body). Also gets Gmail labels and embeds them into the message. :returns: the message body or throws and OfflineImapError (probably severity MESSAGE) if e.g. no message with this UID could be found. """ data = self._fetch_from_imap(str(uid), self.retrycount) # data looks now e.g. # ['320 (X-GM-LABELS (...) UID 17061 BODY[] {2565}',<email.message.EmailMessage object>] # we only asked for one message, and that msg is in data[1]. msg = data[1] # Embed the labels into the message headers if self.synclabels: m = re.search('X-GM-LABELS\s*[(](.*)[)]', data[0]) if m: labels = set([ imaputil.dequote(lb) for lb in imaputil.imapsplit(m.group(1)) ]) else: labels = set() labels = labels - self.ignorelabels labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels)) # First remove old label headers that may be in the message body retrieved # from gmail Then add a labels header with current gmail labels. self.deletemessageheaders(msg, self.labelsheader) self.addmessageheader(msg, self.labelsheader, labels_str) if self.ui.is_debugging('imap'): # Optimization: don't create the debugging objects unless needed msg_s = msg.as_string(policy=self.policy['8bit-RFC']) if len(msg_s) > 200: dbg_output = "%s...%s" % (msg_s[:150], msg_s[-50:]) else: dbg_output = msg_s self.ui.debug( 'imap', "Returned object from fetching %d: '%s'" % (uid, dbg_output)) return msg
def getmessage(self, uid): """Retrieve message with UID from the IMAP server (incl body). Also gets Gmail labels and embeds them into the message. :returns: the message body or throws and OfflineImapError (probably severity MESSAGE) if e.g. no message with this UID could be found. """ imapobj = self.imapserver.acquireconnection() try: data = self._fetch_from_imap(imapobj, str(uid), 2) finally: self.imapserver.releaseconnection(imapobj) # data looks now e.g. #[('320 (X-GM-LABELS (...) UID 17061 BODY[] {2565}','msgbody....')] # we only asked for one message, and that msg is in data[0]. # msbody is in [0][1]. body = data[0][1].replace("\r\n", "\n") # Embed the labels into the message headers if self.synclabels: m = re.search('X-GM-LABELS\s*\(([^\)]*)\)', data[0][0]) if m: labels = set([imaputil.dequote(lb) for lb in imaputil.imapsplit(m.group(1))]) else: labels = set() labels = labels - self.ignorelabels labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels)) # First remove old label headers that may be in the message content retrieved # from gmail Then add a labels header with current gmail labels. body = self.deletemessageheaders(body, self.labelsheader) body = self.addmessageheader(body, '\n', self.labelsheader, labels_str) if len(body)>200: dbg_output = "%s...%s"% (str(body)[:150], str(body)[-50:]) else: dbg_output = body self.ui.debug('imap', "Returned object from fetching %d: '%s'"% (uid, dbg_output)) return body