docker-offlineimap/offlineimap/repository/Base.py

170 lines
5.4 KiB
Python
Raw Normal View History

2002-06-19 06:39:00 +02:00
# Base repository support
2007-07-05 06:04:14 +02:00
# Copyright (C) 2002-2007 John Goerzen
2002-06-19 06:39:00 +02:00
# <jgoerzen@complete.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
2002-06-19 06:39:00 +02:00
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
2006-08-12 06:15:55 +02:00
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2002-06-19 06:39:00 +02:00
import os.path
import traceback
from offlineimap import CustomConfig
from offlineimap.ui import getglobalui
class BaseRepository(CustomConfig.ConfigHelperMixin):
def __init__(self, reposname, account):
self.account = account
self.config = account.getconfig()
self.name = reposname
self.localeval = account.getlocaleval()
self.accountname = self.account.getname()
self.uiddir = os.path.join(self.config.getmetadatadir(), 'Repository-' + self.name)
if not os.path.exists(self.uiddir):
os.mkdir(self.uiddir, 0700)
self.mapdir = os.path.join(self.uiddir, 'UIDMapping')
if not os.path.exists(self.mapdir):
os.mkdir(self.mapdir, 0700)
self.uiddir = os.path.join(self.uiddir, 'FolderValidity')
if not os.path.exists(self.uiddir):
os.mkdir(self.uiddir, 0700)
# The 'restoreatime' config parameter only applies to local Maildir
# mailboxes.
def restore_atime(self):
if self.config.get('Repository ' + self.name, 'type').strip() != \
'Maildir':
return
if not self.config.has_option('Repository ' + self.name, 'restoreatime') or not self.config.getboolean('Repository ' + self.name, 'restoreatime'):
return
return self.restore_folder_atimes()
2007-07-05 06:04:14 +02:00
def connect(self):
"""Establish a connection to the remote, if necessary. This exists
so that IMAP connections can all be established up front, gathering
passwords as needed. It was added in order to support the
error recovery -- we need to connect first outside of the error
trap in order to validate the password, and that's the point of
this function."""
pass
def holdordropconnections(self):
pass
def dropconnections(self):
pass
def getaccount(self):
return self.account
def getname(self):
return self.name
def getuiddir(self):
return self.uiddir
def getmapdir(self):
return self.mapdir
def getaccountname(self):
return self.accountname
def getsection(self):
return 'Repository ' + self.name
def getconfig(self):
return self.config
def getlocaleval(self):
return self.account.getlocaleval()
2002-06-19 06:39:00 +02:00
def getfolders(self):
"""Returns a list of ALL folders on this server."""
return []
2002-06-19 08:16:19 +02:00
def forgetfolders(self):
"""Forgets the cached list of folders, if any. Useful to run
after a sync run."""
pass
2002-06-19 08:16:19 +02:00
def getsep(self):
raise NotImplementedError
2002-06-20 04:55:24 +02:00
def makefolder(self, foldername):
2002-06-19 08:16:19 +02:00
raise NotImplementedError
2002-06-20 04:55:24 +02:00
def deletefolder(self, foldername):
raise NotImplementedError
def getfolder(self, foldername):
2002-06-19 08:16:19 +02:00
raise NotImplementedError
2002-06-19 06:39:00 +02:00
def syncfoldersto(self, dest, copyfolders):
2002-06-19 08:16:19 +02:00
"""Syncs the folders in this repository to those in dest.
It does NOT sync the contents of those folders.
For every time dest.makefolder() is called, also call makefolder()
on each folder in copyfolders."""
2002-06-19 08:16:19 +02:00
src = self
srcfolders = src.getfolders()
destfolders = dest.getfolders()
# Create hashes with the names, but convert the source folders
# to the dest folder's sep.
srchash = {}
for folder in srcfolders:
2002-06-21 08:51:21 +02:00
srchash[folder.getvisiblename().replace(src.getsep(), dest.getsep())] = \
2002-06-19 08:16:19 +02:00
folder
desthash = {}
for folder in destfolders:
2002-06-21 08:51:21 +02:00
desthash[folder.getvisiblename()] = folder
2002-06-19 08:16:19 +02:00
#
# Find new folders.
#
for key in srchash.keys():
if not key in desthash:
Patch for error handling / separation of accounts etc. Dear All, I have made the attached patch to try and make offlineimap a bit more stable in challenging situations. It's extremely useful in slow connection environments - but sometimes if one account had the wrong password or the connection went down then unfortunately the whole program would crash. I have tested this on our connection and tried throwing at it just about every situation - connection, up down, up, down again, change password, error whilst copying one message, etc. I have been running this patch for the last 5 days or so syncing 6 accounts at the moment... It seems to work and stay alive nicely (even if your connection does not)... Hope that this can go in for the next release... Please let me know if anyone notices any problems with this... Regards, -Mike -- Attached file included as plaintext by Ecartis -- -- File: submit From 1d6777cab23637eb830031c7cab0ae9b8589afd6 Mon Sep 17 00:00:00 2001 From: mike <mike@mikelaptop.(none)> Date: Mon, 24 Aug 2009 19:37:59 +0430 Subject: [PATCH] This patch attempts to introduce a little more error handling - e.g. if one account has an error because of a changed password or something that should not affect the other accounts. Specifically: If one sync run has an issue this is in a try-except clause - if it has an auto refresh period the thread will sleep and try again - this could be quite useful in the event of the connection going down for a little while, changed password etc. If one folder cannot be created an error message will be displayed through the UI and the program will continue (e.g. permission denied to create a folder) If one message does not want to copy for whatever resaon an error message will be displayed through the UI and at least the other messages will be copied If one folder run has an exception then the others will still run
2009-08-24 17:17:57 +02:00
try:
dest.makefolder(key)
for copyfolder in copyfolders:
copyfolder.makefolder(key.replace(dest.getsep(), copyfolder.getsep()))
except (KeyboardInterrupt):
raise
Patch for error handling / separation of accounts etc. Dear All, I have made the attached patch to try and make offlineimap a bit more stable in challenging situations. It's extremely useful in slow connection environments - but sometimes if one account had the wrong password or the connection went down then unfortunately the whole program would crash. I have tested this on our connection and tried throwing at it just about every situation - connection, up down, up, down again, change password, error whilst copying one message, etc. I have been running this patch for the last 5 days or so syncing 6 accounts at the moment... It seems to work and stay alive nicely (even if your connection does not)... Hope that this can go in for the next release... Please let me know if anyone notices any problems with this... Regards, -Mike -- Attached file included as plaintext by Ecartis -- -- File: submit From 1d6777cab23637eb830031c7cab0ae9b8589afd6 Mon Sep 17 00:00:00 2001 From: mike <mike@mikelaptop.(none)> Date: Mon, 24 Aug 2009 19:37:59 +0430 Subject: [PATCH] This patch attempts to introduce a little more error handling - e.g. if one account has an error because of a changed password or something that should not affect the other accounts. Specifically: If one sync run has an issue this is in a try-except clause - if it has an auto refresh period the thread will sleep and try again - this could be quite useful in the event of the connection going down for a little while, changed password etc. If one folder cannot be created an error message will be displayed through the UI and the program will continue (e.g. permission denied to create a folder) If one message does not want to copy for whatever resaon an error message will be displayed through the UI and at least the other messages will be copied If one folder run has an exception then the others will still run
2009-08-24 17:17:57 +02:00
except:
getglobalui().warn("ERROR Attempting to create folder " \
+ key + ":" +traceback.format_exc())
2002-06-19 08:16:19 +02:00
#
# Find deleted folders.
#
# We don't delete folders right now.
2002-06-19 08:16:19 +02:00
#for key in desthash.keys():
# if not key in srchash:
# dest.deletefolder(key)
2002-06-19 08:16:19 +02:00
##### Keepalive
def startkeepalive(self):
"""The default implementation will do nothing."""
pass
def stopkeepalive(self):
"""Stop keep alive, but don't bother waiting
for the threads to terminate."""
pass