diff --git a/offlineimap/folder/Base.py b/offlineimap/folder/Base.py index 58f4fcd..f871d6f 100644 --- a/offlineimap/folder/Base.py +++ b/offlineimap/folder/Base.py @@ -302,7 +302,15 @@ class BaseFolder: with open(uidfilename + ".tmp", "wt") as uidfile: uidfile.write("%d\n" % newval) - os.rename(uidfilename + ".tmp", uidfilename) + + # This is weird, os.rename on Windows raises an exception, + # But not in Linux. In linux the file is overwritten. + try: + os.rename(uidfilename + ".tmp", uidfilename) + except WindowsError: + os.remove(uidfilename) + os.rename(uidfilename + ".tmp", uidfilename) + self._base_saved_uidvalidity = newval def get_uidvalidity(self): diff --git a/offlineimap/folder/GmailMaildir.py b/offlineimap/folder/GmailMaildir.py index 1dfccc7..15c7623 100644 --- a/offlineimap/folder/GmailMaildir.py +++ b/offlineimap/folder/GmailMaildir.py @@ -183,7 +183,7 @@ class GmailMaildirFolder(MaildirFolder): os.rename(tmppath, filepath) except OSError as e: raise OfflineImapError("Can't rename file '%s' to '%s': %s" % - (tmppath, filepath, e[1]), + (tmppath, filepath, e.errno), OfflineImapError.ERROR.FOLDER, exc_info()[2]) diff --git a/offlineimap/folder/Maildir.py b/offlineimap/folder/Maildir.py index 3df4afa..f319b66 100644 --- a/offlineimap/folder/Maildir.py +++ b/offlineimap/folder/Maildir.py @@ -470,7 +470,7 @@ class MaildirFolder(BaseFolder): except OSError as e: raise OfflineImapError( "Can't rename file '%s' to '%s': %s" % - (oldfilename, newfilename, e[1]), + (oldfilename, newfilename, e.errno), OfflineImapError.ERROR.FOLDER, exc_info()[2]) @@ -556,7 +556,7 @@ class MaildirFolder(BaseFolder): except OSError as e: raise OfflineImapError( "Can't rename file '%s' to '%s': %s" % - (filename, newfilename, e[1]), + (filename, newfilename, e.errno), OfflineImapError.ERROR.FOLDER, exc_info()[2]) diff --git a/offlineimap/imaplibutil.py b/offlineimap/imaplibutil.py index b29b019..5f6f6f9 100644 --- a/offlineimap/imaplibutil.py +++ b/offlineimap/imaplibutil.py @@ -15,7 +15,6 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import datetime import os -import fcntl import time import subprocess import threading @@ -29,6 +28,14 @@ from offlineimap import OfflineImapError from offlineimap.ui import getglobalui from imaplib2 import IMAP4, IMAP4_SSL, InternalDate +try: + import portalocker +except: + try: + import fcntl + except: + pass # Ok if this fails, we can do without. + class UsefulIMAPMixIn: def __getselectedfolder(self): diff --git a/offlineimap/init.py b/offlineimap/init.py index 9f9592e..fe7aaae 100644 --- a/offlineimap/init.py +++ b/offlineimap/init.py @@ -26,6 +26,7 @@ import collections from optparse import OptionParser import offlineimap +from offlineimap.utils.distro_utils import get_os_name import imaplib2 as imaplib # Ensure that `ui` gets loaded before `threadutil` in order to @@ -72,7 +73,18 @@ class OfflineImap: """ def get_env_info(self): - info = "imaplib2 v%s, Python v%s" % (imaplib.__version__, PYTHON_VERSION) + # Transitional code between imaplib2 versions + try: + # imaplib2, previous versions, based on Python 2.x + l_imaplib_version = imaplib.__version__ + except AttributeError: + # New imaplib2, version >= 3.06 + l_imaplib_version = imaplib.version() + except: + # This should not happen + l_imaplib_version = " Unknown" + + info = "imaplib2 v%s, Python v%s" % (l_imaplib_version, PYTHON_VERSION) try: import ssl info = "%s, %s" % (info, ssl.OPENSSL_VERSION) @@ -446,13 +458,16 @@ class OfflineImap: try: self.num_sigterm = 0 - signal.signal(signal.SIGHUP, sig_handler) - signal.signal(signal.SIGUSR1, sig_handler) - signal.signal(signal.SIGUSR2, sig_handler) - signal.signal(signal.SIGABRT, sig_handler) - signal.signal(signal.SIGTERM, sig_handler) - signal.signal(signal.SIGINT, sig_handler) - signal.signal(signal.SIGQUIT, sig_handler) + + # We cannot use signals in Windows + if get_os_name() != 'windows': + signal.signal(signal.SIGHUP, sig_handler) + signal.signal(signal.SIGUSR1, sig_handler) + signal.signal(signal.SIGUSR2, sig_handler) + signal.signal(signal.SIGABRT, sig_handler) + signal.signal(signal.SIGTERM, sig_handler) + signal.signal(signal.SIGINT, sig_handler) + signal.signal(signal.SIGQUIT, sig_handler) # Various initializations that need to be performed: activeaccounts = self._get_activeaccounts(options)