Another way of locating UID of just saved message
It works by fetching all headers of new messages from IMAP server and searching for our X-OfflineIMAP marker by using regular expression. Signed-off-by: Vladimir Marek <vlmarek@volny.cz> Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
parent
6f9b171ffd
commit
b6ac1aecb1
@ -318,6 +318,74 @@ class IMAPFolder(BaseFolder):
|
|||||||
matchinguids.sort()
|
matchinguids.sort()
|
||||||
return long(matchinguids[0])
|
return long(matchinguids[0])
|
||||||
|
|
||||||
|
def savemessage_fetchheaders(self, imapobj, headername, headervalue):
|
||||||
|
""" We fetch all new mail headers and search for the right
|
||||||
|
X-OfflineImap line by hand. The response from the server has form:
|
||||||
|
(
|
||||||
|
'OK',
|
||||||
|
[
|
||||||
|
(
|
||||||
|
'185 (RFC822.HEADER {1789}',
|
||||||
|
'... mail headers ...'
|
||||||
|
),
|
||||||
|
' UID 2444)',
|
||||||
|
(
|
||||||
|
'186 (RFC822.HEADER {1789}',
|
||||||
|
'... 2nd mail headers ...'
|
||||||
|
),
|
||||||
|
' UID 2445)'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
We need to locate the UID just after mail headers containing our
|
||||||
|
X-OfflineIMAP line.
|
||||||
|
|
||||||
|
Returns UID when found, 0 when not found.
|
||||||
|
"""
|
||||||
|
self.ui.debug('imap', 'savemessage_fetchheaders called for %s: %s' % \
|
||||||
|
(headername, headervalue))
|
||||||
|
|
||||||
|
# run "fetch X:* rfc822.header"
|
||||||
|
# since we stored the mail we are looking for just recently, it would
|
||||||
|
# not be optimal to fetch all messages. So we'll find highest message
|
||||||
|
# UID in our local messagelist and search from there (exactly from
|
||||||
|
# UID+1). That works because UIDs are guaranteed to be unique and
|
||||||
|
# ascending.
|
||||||
|
|
||||||
|
if self.getmessagelist():
|
||||||
|
start = 1+max(self.getmessagelist().keys())
|
||||||
|
else:
|
||||||
|
# Folder was empty - start from 1
|
||||||
|
start = 1
|
||||||
|
|
||||||
|
# Imaplib quotes all parameters of a string type. That must not happen
|
||||||
|
# with the range X:*. So we use bytearray to stop imaplib from getting
|
||||||
|
# in our way
|
||||||
|
|
||||||
|
result = imapobj.uid('FETCH', bytearray('%d:*' % start), 'rfc822.header')
|
||||||
|
if result[0] != 'OK':
|
||||||
|
raise OfflineImapError('Error fetching mail headers: ' + '. '.join(result[1]),
|
||||||
|
OfflineImapError.ERROR.MESSAGE)
|
||||||
|
|
||||||
|
result = result[1]
|
||||||
|
|
||||||
|
found = 0
|
||||||
|
for item in result:
|
||||||
|
if found == 0 and type(item) == type( () ):
|
||||||
|
# Walk just tuples
|
||||||
|
if re.search("(?:^|\\r|\\n)%s:\s*%s(?:\\r|\\n)" % (headername, headervalue),
|
||||||
|
item[1], flags=re.IGNORECASE):
|
||||||
|
found = 1
|
||||||
|
elif found == 1:
|
||||||
|
if type(item) == type (""):
|
||||||
|
uid = re.search("UID\s+(\d+)", item, flags=re.IGNORECASE)
|
||||||
|
if uid:
|
||||||
|
return int(uid.group(1))
|
||||||
|
else:
|
||||||
|
self.ui.warn("Can't parse FETCH response, can't find UID: %s", result.__repr__())
|
||||||
|
else:
|
||||||
|
self.ui.warn("Can't parse FETCH response, we awaited string: %s", result.__repr__())
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
def getmessageinternaldate(self, content, rtime=None):
|
def getmessageinternaldate(self, content, rtime=None):
|
||||||
"""Parses mail and returns an INTERNALDATE string
|
"""Parses mail and returns an INTERNALDATE string
|
||||||
@ -491,10 +559,15 @@ class IMAPFolder(BaseFolder):
|
|||||||
headervalue)
|
headervalue)
|
||||||
# See docs for savemessage in Base.py for explanation of this and other return values
|
# See docs for savemessage in Base.py for explanation of this and other return values
|
||||||
if uid == 0:
|
if uid == 0:
|
||||||
self.ui.debug('imap', 'savemessage: first attempt to get new UID failed. Going to run a NOOP and try again.')
|
self.ui.debug('imap', 'savemessage: first attempt to get new UID failed. \
|
||||||
|
Going to run a NOOP and try again.')
|
||||||
assert(imapobj.noop()[0] == 'OK')
|
assert(imapobj.noop()[0] == 'OK')
|
||||||
uid = self.savemessage_searchforheader(imapobj, headername,
|
uid = self.savemessage_searchforheader(imapobj, headername,
|
||||||
headervalue)
|
headervalue)
|
||||||
|
if uid == 0:
|
||||||
|
self.ui.debug('imap', 'savemessage: second attempt to get new UID failed. \
|
||||||
|
Going to try search headers manually')
|
||||||
|
uid = self.savemessage_fetchheaders(imapobj, headername, headervalue)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self.imapserver.releaseconnection(imapobj)
|
self.imapserver.releaseconnection(imapobj)
|
||||||
|
Loading…
Reference in New Issue
Block a user