Merge branch 'next'

Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This commit is contained in:
Eygene Ryabinkin 2014-06-24 18:58:14 +04:00
commit 6bd76fed5a
11 changed files with 60 additions and 16 deletions

View File

@ -5,6 +5,17 @@ ChangeLog
:website: http://offlineimap.org :website: http://offlineimap.org
OfflineIMAP v6.5.6.1 (YYYY-MM-DD)
=================================
* Fix mangled message headers for servers without UIDPLUS:
X-OfflineIMAP was added with preceeding '\n' instead of
'\r\n' just before message was uploaded to the IMAP server.
* Add missing version bump for 6.5.6 (it was released with
6.5.5 in setup.py and other places).
OfflineIMAP v6.5.6 (2014-05-14) OfflineIMAP v6.5.6 (2014-05-14)
=============================== ===============================

View File

@ -17,6 +17,19 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import os
import sys
if not 'DEVELOPING_OFFLINEIMAP_PYTHON3_SUPPORT' in os.environ:
if sys.version_info[0] > 2:
sys.stderr.write("""IIMAPS!
Sorry, OfflineIMAP currently doesn't support Python higher than 2.x.
We're doing our best to bring in support for 3.x really soon. You can
also join us at https://github.com/OfflineIMAP/offlineimap/ and help.
""")
sys.exit(1)
from offlineimap import OfflineImap from offlineimap import OfflineImap
oi = OfflineImap() oi = OfflineImap()

View File

@ -1,13 +1,15 @@
__all__ = ['OfflineImap'] __all__ = ['OfflineImap']
__productname__ = 'OfflineIMAP' __productname__ = 'OfflineIMAP'
__version__ = "6.5.5" __version__ = "6.5.6.1"
__revision__ = "-devel"
__bigversion__ = __version__ + __revision__
__copyright__ = "Copyright 2002-2013 John Goerzen & contributors" __copyright__ = "Copyright 2002-2013 John Goerzen & contributors"
__author__ = "John Goerzen" __author__ = "John Goerzen"
__author_email__= "john@complete.org" __author_email__= "john@complete.org"
__description__ = "Disconnected Universal IMAP Mail Synchronization/Reader Support" __description__ = "Disconnected Universal IMAP Mail Synchronization/Reader Support"
__license__ = "Licensed under the GNU GPL v2+ (v2 or any later version)" __license__ = "Licensed under the GNU GPL v2+ (v2 or any later version)"
__bigcopyright__ = """%(__productname__)s %(__version__)s __bigcopyright__ = """%(__productname__)s %(__bigversion__)s
%(__license__)s""" % locals() %(__license__)s""" % locals()
__homepage__ = "http://offlineimap.org" __homepage__ = "http://offlineimap.org"

View File

@ -326,7 +326,7 @@ class SyncableAccount(Account):
thread = InstanceLimitedThread(\ thread = InstanceLimitedThread(\
instancename = 'FOLDER_' + self.remoterepos.getname(), instancename = 'FOLDER_' + self.remoterepos.getname(),
target = syncfolder, target = syncfolder,
name = "Folder %s [acc: %s]" % (remotefolder, self), name = "Folder %s [acc: %s]" % (remotefolder.getexplainedname(), self),
args = (self, remotefolder, quick)) args = (self, remotefolder, quick))
thread.start() thread.start()
folderthreads.append(thread) folderthreads.append(thread)

View File

@ -132,6 +132,13 @@ class BaseFolder(object):
"""The nametrans-transposed name of the folder's name""" """The nametrans-transposed name of the folder's name"""
return self.visiblename return self.visiblename
def getexplainedname(self):
""" Name that shows both real and nametrans-mangled values"""
if self.name == self.visiblename:
return self.name
else:
return "%s [remote name %s]" % (self.visiblename, self.name)
def getrepository(self): def getrepository(self):
"""Returns the repository object that this folder is within.""" """Returns the repository object that this folder is within."""
return self.repository return self.repository
@ -413,16 +420,26 @@ next line\n
""" """
def addmessageheader(self, content, headername, headervalue): def addmessageheader(self, content, crlf, headername, headervalue):
"""
Adds new header to the provided message.
Arguments:
- content: message content, headers and body as a single string
- crlf: string that carries line ending
- headername: name of the header to add
- headervalue: value of the header to add
"""
self.ui.debug('', self.ui.debug('',
'addmessageheader: called to add %s: %s' % (headername, 'addmessageheader: called to add %s: %s' % (headername,
headervalue)) headervalue))
prefix = '\n' prefix = crlf
suffix = '' suffix = ''
insertionpoint = content.find('\n\n') insertionpoint = content.find(crlf + crlf)
if insertionpoint == 0 or insertionpoint == -1: if insertionpoint == 0 or insertionpoint == -1:
prefix = '' prefix = ''
suffix = '\n' suffix = crlf
if insertionpoint == -1: if insertionpoint == -1:
insertionpoint = 0 insertionpoint = 0
# When body starts immediately, without preceding '\n' # When body starts immediately, without preceding '\n'
@ -430,8 +447,8 @@ next line\n
# we seen many broken ones), we should add '\n' to make # we seen many broken ones), we should add '\n' to make
# new (and the only header, in this case) to be properly # new (and the only header, in this case) to be properly
# separated from the message body. # separated from the message body.
if content[0] != '\n': if content[0:len(crlf)] != crlf:
suffix = suffix + '\n' suffix = suffix + crlf
self.ui.debug('', 'addmessageheader: insertionpoint = %d' % insertionpoint) self.ui.debug('', 'addmessageheader: insertionpoint = %d' % insertionpoint)
headers = content[0:insertionpoint] headers = content[0:insertionpoint]

View File

@ -93,7 +93,7 @@ class GmailFolder(IMAPFolder):
labels = set() labels = set()
labels = labels - self.ignorelabels labels = labels - self.ignorelabels
labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels)) labels_str = imaputil.format_labels_string(self.labelsheader, sorted(labels))
body = self.addmessageheader(body, self.labelsheader, labels_str) body = self.addmessageheader(body, '\n', self.labelsheader, labels_str)
if len(body)>200: if len(body)>200:
dbg_output = "%s...%s" % (str(body)[:150], str(body)[-50:]) dbg_output = "%s...%s" % (str(body)[:150], str(body)[-50:])

View File

@ -141,7 +141,7 @@ class GmailMaildirFolder(MaildirFolder):
# Change labels into content # Change labels into content
labels_str = imaputil.format_labels_string(self.labelsheader, labels_str = imaputil.format_labels_string(self.labelsheader,
sorted(labels | ignoredlabels)) sorted(labels | ignoredlabels))
content = self.addmessageheader(content, self.labelsheader, labels_str) content = self.addmessageheader(content, '\n', self.labelsheader, labels_str)
rtime = self.messagelist[uid].get('rtime', None) rtime = self.messagelist[uid].get('rtime', None)
# write file with new labels to a unique file in tmp # write file with new labels to a unique file in tmp

View File

@ -526,6 +526,7 @@ class IMAPFolder(BaseFolder):
# NB: imapobj to None. # NB: imapobj to None.
try: try:
while retry_left: while retry_left:
# XXX: we can mangle message only once, out of the loop
# UIDPLUS extension provides us with an APPENDUID response. # UIDPLUS extension provides us with an APPENDUID response.
use_uidplus = 'UIDPLUS' in imapobj.capabilities use_uidplus = 'UIDPLUS' in imapobj.capabilities
@ -535,7 +536,7 @@ class IMAPFolder(BaseFolder):
content) content)
self.ui.debug('imap', 'savemessage: header is: %s: %s' %\ self.ui.debug('imap', 'savemessage: header is: %s: %s' %\
(headername, headervalue)) (headername, headervalue))
content = self.addmessageheader(content, headername, headervalue) content = self.addmessageheader(content, CRLF, headername, headervalue)
if len(content)>200: if len(content)>200:
dbg_output = "%s...%s" % (content[:150], content[-50:]) dbg_output = "%s...%s" % (content[:150], content[-50:])

View File

@ -50,7 +50,7 @@ class OfflineImap:
self.__sync(options) self.__sync(options)
def __parse_cmd_options(self): def __parse_cmd_options(self):
parser = OptionParser(version=offlineimap.__version__, parser = OptionParser(version=offlineimap.__bigversion__,
description="%s.\n\n%s" % description="%s.\n\n%s" %
(offlineimap.__copyright__, (offlineimap.__copyright__,
offlineimap.__license__)) offlineimap.__license__))

View File

@ -576,7 +576,7 @@ class Blinkenlights(UIBase, CursesUtil):
self.bannerwin.clear() # Delete old content (eg before resizes) self.bannerwin.clear() # Delete old content (eg before resizes)
self.bannerwin.bkgd(' ', color) # Fill background with that color self.bannerwin.bkgd(' ', color) # Fill background with that color
string = "%s %s" % (offlineimap.__productname__, string = "%s %s" % (offlineimap.__productname__,
offlineimap.__version__) offlineimap.__bigversion__)
self.bannerwin.addstr(0, 0, string, color) self.bannerwin.addstr(0, 0, string, color)
self.bannerwin.addstr(0, self.width -len(offlineimap.__copyright__) -1, self.bannerwin.addstr(0, self.width -len(offlineimap.__copyright__) -1,
offlineimap.__copyright__, color) offlineimap.__copyright__, color)

View File

@ -95,7 +95,7 @@ class UIBase(object):
# write out more verbose initial info blurb on the log file # write out more verbose initial info blurb on the log file
p_ver = ".".join([str(x) for x in sys.version_info[0:3]]) p_ver = ".".join([str(x) for x in sys.version_info[0:3]])
msg = "OfflineImap %s starting...\n Python: %s Platform: %s\n "\ msg = "OfflineImap %s starting...\n Python: %s Platform: %s\n "\
"Args: %s" % (offlineimap.__version__, p_ver, sys.platform, "Args: %s" % (offlineimap.__bigversion__, p_ver, sys.platform,
" ".join(sys.argv)) " ".join(sys.argv))
self.logger.info(msg) self.logger.info(msg)
@ -409,7 +409,7 @@ class UIBase(object):
#TODO: Debug and make below working, it hangs Gmail #TODO: Debug and make below working, it hangs Gmail
#res_type, response = conn.id(( #res_type, response = conn.id((
# 'name', offlineimap.__productname__, # 'name', offlineimap.__productname__,
# 'version', offlineimap.__version__)) # 'version', offlineimap.__bigversion__))
#self._msg("Server ID: %s %s" % (res_type, response[0])) #self._msg("Server ID: %s %s" % (res_type, response[0]))
self._msg("Server welcome string: %s" % str(conn.welcome)) self._msg("Server welcome string: %s" % str(conn.welcome))
self._msg("Server capabilities: %s\n" % str(conn.capabilities)) self._msg("Server capabilities: %s\n" % str(conn.capabilities))