Do not ignore gmail labels if header appears multiple times

There should be just one header storing gmail labels, but due to a bug,
multiple X-Keywords (or equivalent) headers may be found on the local
messages.

Now we, when extracting the labels from a message, we read all label
headers, instead of just the first one.

This has the consequence that some old labels stored locally in a second
X-Keywords (or third...) header, which effectively was rendered
invisible to offlineimap until now, may pop back up again and be pushed
to gmail. No labels will be removed by the changes in this commit,
though.

Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
This commit is contained in:
Abdo Roig-Maranges 2014-11-20 14:03:15 +01:00
parent e51ed80ecc
commit fc4c7549d6
3 changed files with 37 additions and 12 deletions

View File

@ -512,8 +512,8 @@ class BaseFolder(object):
def getmessageheader(self, content, name): def getmessageheader(self, content, name):
""" """
Searches for the given header and returns its value. Searches for the first occurence of the given header and returns
Header name is case-insensitive. its value. Header name is case-insensitive.
Arguments: Arguments:
- contents: message itself - contents: message itself
@ -535,6 +535,27 @@ class BaseFolder(object):
return None return None
def getmessageheaderlist(self, content, name):
"""
Searches for the given header and returns a list of values for
that header.
Arguments:
- contents: message itself
- name: name of the header to be searched
Returns: list of header values or emptylist if no such header was found
"""
self.ui.debug('', 'getmessageheaderlist: called to get %s' % name)
eoh = self.__find_eoh(content)
self.ui.debug('', 'getmessageheaderlist: eoh = %d' % eoh)
headers = content[0:eoh]
self.ui.debug('', 'getmessageheaderlist: headers = %s' % repr(headers))
return re.findall('^%s:(.*)$' % name, headers, flags = re.MULTILINE | re.IGNORECASE)
def deletemessageheaders(self, content, header_list): def deletemessageheaders(self, content, header_list):
""" """
Deletes headers in the given list from the message content. Deletes headers in the given list from the message content.

View File

@ -189,8 +189,9 @@ class GmailFolder(IMAPFolder):
if not self.synclabels: if not self.synclabels:
return super(GmailFolder, self).savemessage(uid, content, flags, rtime) return super(GmailFolder, self).savemessage(uid, content, flags, rtime)
labels = imaputil.labels_from_header(self.labelsheader, labels = set()
self.getmessageheader(content, self.labelsheader)) for hstr in self.getmessageheaderlist(content, self.labelsheader):
labels.update(imaputil.labels_from_header(self.labelsheader, hstr))
ret = super(GmailFolder, self).savemessage(uid, content, flags, rtime) ret = super(GmailFolder, self).savemessage(uid, content, flags, rtime)
self.savemessagelabels(ret, labels) self.savemessagelabels(ret, labels)

View File

@ -87,9 +87,10 @@ class GmailMaildirFolder(MaildirFolder):
content = file.read() content = file.read()
file.close() file.close()
self.messagelist[uid]['labels'] = \ self.messagelist[uid]['labels'] = set()
imaputil.labels_from_header(self.labelsheader, for hstr in self.getmessageheaderlist(content, self.labelsheader):
self.getmessageheader(content, self.labelsheader)) self.messagelist[uid]['labels'].update(
imaputil.labels_from_header(self.labelsheader, hstr))
self.messagelist[uid]['labels_cached'] = True self.messagelist[uid]['labels_cached'] = True
return self.messagelist[uid]['labels'] return self.messagelist[uid]['labels']
@ -111,8 +112,10 @@ class GmailMaildirFolder(MaildirFolder):
if not self.synclabels: if not self.synclabels:
return super(GmailMaildirFolder, self).savemessage(uid, content, flags, rtime) return super(GmailMaildirFolder, self).savemessage(uid, content, flags, rtime)
labels = imaputil.labels_from_header(self.labelsheader, labels = set()
self.getmessageheader(content, self.labelsheader)) for hstr in self.getmessageheaderlist(content, self.labelsheader):
labels.update(imaputil.labels_from_header(self.labelsheader, hstr))
ret = super(GmailMaildirFolder, self).savemessage(uid, content, flags, rtime) ret = super(GmailMaildirFolder, self).savemessage(uid, content, flags, rtime)
# Update the mtime and labels # Update the mtime and labels
@ -135,9 +138,9 @@ class GmailMaildirFolder(MaildirFolder):
content = file.read() content = file.read()
file.close() file.close()
oldlabels = imaputil.labels_from_header(self.labelsheader, oldlabels = set()
self.getmessageheader(content, self.labelsheader)) for hstr in self.getmessageheaderlist(content, self.labelsheader):
oldlabels.update(imaputil.labels_from_header(self.labelsheader, hstr))
labels = labels - ignorelabels labels = labels - ignorelabels
ignoredlabels = oldlabels & ignorelabels ignoredlabels = oldlabels & ignorelabels