Correcting an issue where dbg_output was not defined when the server was
unreachable due to an optimization in PR#56. Since message-id is more useful to better pin point the correct message, removing dbg_output. Also fixing https://github.com/OfflineIMAP/offlineimap3/issues/62 by correcting broken multipart boundaries or raising an error if as_bytes() fails. Related python bug submitted: https://bugs.python.org/issue43818 although this workaround should be sufficent in the interim. Signed-off-by: Joseph Ishac <jishac@nasa.gov>
This commit is contained in:
parent
f024bb9e4c
commit
a4532294ae
@ -26,7 +26,6 @@ from email import policy
|
|||||||
from email.parser import BytesParser
|
from email.parser import BytesParser
|
||||||
from email.generator import BytesGenerator
|
from email.generator import BytesGenerator
|
||||||
from email.utils import parsedate_tz, mktime_tz
|
from email.utils import parsedate_tz, mktime_tz
|
||||||
from email.errors import NoBoundaryInMultipartDefect
|
|
||||||
|
|
||||||
from offlineimap import threadutil
|
from offlineimap import threadutil
|
||||||
from offlineimap.ui import getglobalui
|
from offlineimap.ui import getglobalui
|
||||||
|
@ -25,6 +25,7 @@ from threading import Lock
|
|||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from offlineimap import OfflineImapError
|
from offlineimap import OfflineImapError
|
||||||
from .Base import BaseFolder
|
from .Base import BaseFolder
|
||||||
|
from email.errors import NoBoundaryInMultipartDefect
|
||||||
|
|
||||||
# Find the UID in a message filename
|
# Find the UID in a message filename
|
||||||
re_uidmatch = re.compile(',U=(\d+)')
|
re_uidmatch = re.compile(',U=(\d+)')
|
||||||
@ -297,24 +298,29 @@ class MaildirFolder(BaseFolder):
|
|||||||
filename = self.messagelist[uid]['filename']
|
filename = self.messagelist[uid]['filename']
|
||||||
filepath = os.path.join(self.getfullname(), filename)
|
filepath = os.path.join(self.getfullname(), filename)
|
||||||
fd = open(filepath, 'rb')
|
fd = open(filepath, 'rb')
|
||||||
retval = self.parser['8bit'].parse(fd)
|
_fd_bytes = fd.read()
|
||||||
try:
|
fd.close()
|
||||||
|
retval = self.parser['8bit'].parsebytes(_fd_bytes)
|
||||||
if len(retval.defects) > 0:
|
if len(retval.defects) > 0:
|
||||||
ui.warn("Message has defects: {}".format(retval.defects))
|
# We don't automatically apply fixes as to attempt to preserve the original message
|
||||||
# See if the defects are preventing us from obtaining bytes and
|
self.ui.warn("UID {} has defects: {}".format(uid, retval.defects))
|
||||||
# handle known issues
|
if any(isinstance(defect, NoBoundaryInMultipartDefect) for defect in retval.defects):
|
||||||
|
# (Hopefully) Rare defect from a broken client where multipart boundary is
|
||||||
|
# not properly quoted. Attempt to solve by fixing the boundary and parsing
|
||||||
|
self.ui.warn(" ... applying multipart boundary fix.")
|
||||||
|
retval = self.parser['8bit'].parsebytes(self._quote_boundary_fix(_fd_bytes))
|
||||||
|
try:
|
||||||
|
# See if the defects after fixes are preventing us from obtaining bytes
|
||||||
_ = retval.as_bytes(policy=self.policy['8bit'])
|
_ = retval.as_bytes(policy=self.policy['8bit'])
|
||||||
except UnicodeEncodeError as err:
|
except UnicodeEncodeError as err:
|
||||||
if any(isinstance(defect, NoBoundaryInMultipartDefect) for defect in retval.defects):
|
|
||||||
# (Hopefully) Rare instance where multipart boundary is not
|
|
||||||
# properly quoted. Solve by fixing the boundary and parsing
|
|
||||||
fd.seek(0)
|
|
||||||
_buffer = fd.read()
|
|
||||||
retval = self.parser['8bit'].parsebytes(_quote_boundary_fix(_buffer))
|
|
||||||
else:
|
|
||||||
# Unknown issue which is causing failure of as_bytes()
|
# Unknown issue which is causing failure of as_bytes()
|
||||||
ui.warn("Message has defects preventing it from being processed!")
|
msg_id = self.getmessageheader(retval, "message-id")
|
||||||
fd.close()
|
if msg_id is None:
|
||||||
|
msg_id = '<unknown-message-id>'
|
||||||
|
raise OfflineImapError(
|
||||||
|
"UID {} ({}) has defects preventing it from being processed!\n {}: {}".format(
|
||||||
|
uid, msg_id, type(err).__name__, err),
|
||||||
|
OfflineImapError.ERROR.MESSAGE)
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
# Interface from BaseFolder
|
# Interface from BaseFolder
|
||||||
|
Loading…
Reference in New Issue
Block a user