Previously we did not catch KeyboardInterrupts explicitly as all of the
code was executed in forked child threads which would never receive
Ctrl-c exceptions. With the upcoming single threaded modus, this code
can be run in the main thread however, so we need to take care of
KeyboardInterrupts explicitly.
This was done wherever we would catch *ALL* exceptions universally and
print out an error message.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
We already import threadutil, so no need to also import
threadutil.InstanceLimitedThread separately.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Rather than regetting the ui with UIBase.getglobalui() all the time, we get it once in the base class and let all derivative classes just make use of self.ui rather than refetching the ui all the time, this makes for a bit less code and shorter lines.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Move central constant definitions into __init__.py. This does away
with version.py which contained nothing else and __init__.py is where
things like __VERSION__ are usually defined.
This commit also changes code to use offlineimap.__version__ rather
than offlineimap.version.__version__ as was before. Cleaned up some
duplicate or unneeded imports while touching those, formatting import
statements per PEP8 (one import per row).
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Change the X-OfflineIMAP header to work around possible Exchange MAPI
table overflow problem described in
http://article.gmane.org/gmane.mail.imap.offlineimap.general/1699
(It is unknown whether this problem still exits in current
Exchange versions, but let's assume the worst.)
The X-OfflineIMAP header is neccessary with some IMAP servers to
reliably determine the UID of a new messages uploaded to the server
by using the "UID SEARCH HEADER name string" command. Since this
command compares header name and value it is sufficient to have
a unique header value and a non-unique header name.
Note that a message can have more than one X-OfflineIMAP header if
the message was copied between IMAP folders multiple times.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
After tens of thousands of messages on the IMAP server were deleted it
takes offlineimap extremely long time (several hours of high CPU usage)
to delete them locally. It spends almost all the time modifying
LocalStatus. It processes the messages one by one, rewriting the
folder's status file in LocalStatus after each message.
It is much more efficient to save the status file only once, after
removing all the messages from the messagelist.
Deleting lots of messages now takes seconds instead of hours.
This should solve Debian bug #518093:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=518093
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
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
Dear All,
Attached is the patch that I have developed to provide maxage and
maxsize options. You can thus sync only the last x days of messages and
exclude large messages. All details in the attached git file.
Regards,
-Mike
-- Attached file included as plaintext by Ecartis --
-- File: submit
From 04fead2b46a79675a5b29de6f2b4088b9c9448e5 Mon Sep 17 00:00:00 2001
From: mike <mike@mikelaptop.(none)>
Date: Sun, 16 Aug 2009 17:00:49 +0430
Subject: [PATCH] Patch to provide maxage and maxsize account options to exclude old/large messages
This is designed to make offlineimap even better for low bandwidth connections.
maxage allows you to specify a number of days and only messages within
that range will be considered by offlineimap for the sync. This can be
useful if you would like to start using offlineimap with a large
existing account and do not want to import large archives of mail.
maxsize allows you to specify the maximum size of a message to consider so
that you can exclude messages with large attachments etc.
In both cases the cachemessagelist function of the folder was modified to ignore
messages that do not meet the criteria. If the criteria are not specified
then the existing code will be executed the same as before. If a message
does not meet the criteria it will be as though this message does not exist
- offlineimap will completely ignore it. It will not have flags updated,
it will not be deleted, it will not be considered at all.
When operating against an IMAP repository a server side search function
is used. This of course requires support for server side search.
I have tested this with either option, no options etc. against IMAP, Maildir
and Gmail. I have run variations of this patch here for the last 3 weeks or
so syncing about 4 accounts normally.
Closes: #535160
Bug#535160: offlineimap fails on encfs (FUSE) due to hard linking
Package: offlineimap
Version: 6.0.3
Severity: normal
Tags: patch
Hi,
if the localrepository is stored on an encfs, offlineimap fails as follows:
OfflineIMAP 6.0.3
Copyright (C) 2002 - 2008 John Goerzen <jgoerzen@complete.org>
This software comes with ABSOLUTELY NO WARRANTY; see the file
COPYING for details. This is free software, and you are welcome
to distribute it under the conditions laid out in COPYING.
***** Processing account pleione
Copying folder structure from IMAP to Maildir
Establishing connection to tunnel:eval `keychain --quiet --eval` && ssh -q mymailhost /usr/sbin/dovecot --exec-mail imap.
Syncing Drafts: IMAP -> Maildir
Syncing INBOX: IMAP -> Maildir
----------8<----------
Syncing net: IMAP -> Maildir
Copy message 360 IMAP[net] -> Maildir[net], LocalStatus[net]
Syncing personal: IMAP -> Maildir
Thread 'Copy message 360 from net' terminated with exception:
Traceback (most recent call last):
File "/var/lib/python-support/python2.4/offlineimap/threadutil.py", line 149, in run
Thread.run(self)
File "threading.py", line 422, in run
self.__target(*self.__args, **self.__kwargs)
File "/var/lib/python-support/python2.4/offlineimap/folder/Base.py", line 282, in copymessageto
newuid = object.savemessage(uid, message, flags, rtime)
File "/var/lib/python-support/python2.4/offlineimap/folder/Maildir.py", line 198, in savemessage
os.path.join(tmpdir, messagename))
OSError: [Errno 1] Operation not permitted
Last 4 debug messages logged for Copy message 360 from net prior to exception:
----------8<----------
As encfs does not support hard linking, the rename of the temporary
message file fails.
This is the only occurrence of hard linking in offlineimap and can be
fixed by using an atomic `os.rename` instead of `os.link`+`os.unlink`.
I have been using the attached patch for more than 1.5 years and have
never again had any problems with offlineimap on encfs.
Regards,
Peter
Paul Hinze <paul.t.hinze@gmail.com> on 2008-12-22 at 19:16:
> I did a bit of debugging and asking around in #python and it turns out
> that because Maildir.py uses a conditional import of md5 from either
> hashlib or the md5 module, the md5.new() call is not always correct.
> The attached patch should fix this problem.
Thanks to Daniel Rall for pointing out that the attachment got stripped
off my last message. Patch follows.
Paul
----
From e01fdfbf62c61c31b514e826e6cc00fb98d88808 Mon Sep 17 00:00:00 2001
From: Paul Hinze <paul.t.hinze@gmail.com>
Date: Mon, 22 Dec 2008 18:42:44 -0600
Subject: [PATCH] Fixing md5 import when hashlib is available
Thanks to habnabit and Rhamphoryncus in #python for help debugging
I created new IMAP folders on my server. In some moment I found offlineimap
crashed. The reason were empty LocalStatus files. From looking at the code I
have no explanation how those files came into existence.
refs deb#469598
Bug report received in Debian. User is having occasional trouble with Gmail
driver crashing, indicates problem may have started after switching to Gmail.
Gmail driver merged to tree in 81b86fb74 on 2008-01-03 and recently released
in beta tarballs.
BT shows:
File "/var/lib/python-support/python2.4/offlineimap/folder/Gmail.py", line 102, in processmessagesflags
attributehash = imaputil.flags2hash(imaputil.imapsplit(result)[1])
File "/var/lib/python-support/python2.4/offlineimap/imaputil.py", line 88, in imapsplit
for i in range(len(imapstring)):
TypeError: len() of unsized object
imap debug log shows:
imap: 29:58.16 > BEAL75 UID STORE 4887 +FLAGS (\Deleted)
imap: 29:58.47 < BEAL75 OK Success
imap: 29:58.47 matched r'(?P<tag>BEAL\d+) (?P<type>[A-Z]+) (?P<data>.*)' => ('BEAL75', 'OK', 'Success')
imap: imapsplit() called with input: None
imap: imapsplit() got a non-string input; working around.
looking at code for Gmail.py processmessagesflags, comments from Ricardo
indicate it was copied from the same function in folder/IMAP.py.
However, folder/IMAP.py has checks for this, added 2002-07-12 in
5342dacc & 817a10ce. Suspect that Gmail author believed those checks
superfluous for Gmail.
Copied checks from folder/IMAP.py to folder/Gmail.py.
This reverts commit 71a76d9a61.
Zak Smith reported a problem at:
self.processmessagesflags('+', uidlist, flags)
File "/usr/lib/python2.5/site-packages/offlineimap/folder/IMAP.py",
line 372, in processmessagesflags
myrights = imapobj.myrights(self.getfullname())[1][0].split()[1]
IndexError: list index out of range
Conflicts:
offlineimap/folder/IMAP.py
closes#22
from pistore in OfflineIMAP #22:
When an IMAP flag update is performed for multiple messages, some IMAP
servers (e.g. Exchange) return the UID attribute only for some of the
FETCH untagged responses, as shown in the following log:
21:19.04 > DCKF8 UID STORE 66050,50613,52164,40043,40055,25874 +FLAGS
(\Deleted)
21:19.36 < * 35 FETCH (FLAGS (\Seen \Deleted) UID 25874)
21:19.36 < * 321 FETCH (FLAGS (\Seen \Deleted))
21:19.57 < * 322 FETCH (FLAGS (\Seen \Deleted))
21:19.57 < * 560 FETCH (FLAGS (\Seen \Deleted))
21:19.57 < * 581 FETCH (FLAGS (\Seen \Deleted) UID 52164)
21:19.62 < * 1022 FETCH (FLAGS (\Seen \Deleted))
21:19.62 < DCKF8 OK STORE completed.
Function IMAPFolder.processmessagesflags is able to manage the servers
which return the UID and the servers which do not return it, but is
not able to deal with the mixed behavior shown above.
The problem is that the fragment of function
IMAPFolder.processmessagesflags that handles the responses with UID
attribute uses variable flags to store the list of flags of the
message in the IMAP format ("flags = attributehashFLAGS?"), while the
fragment that handles the responses without UID expects variable
"flags" to contain the list of modified flags passed to the function
in Maildir format ("self.messagelist[uid]flags?.append(flag)").
As a consequence, the wrong list of flags is used for the messages
without UID, leading to the addition of "strange" flags to the Maildir
messages:
Syncing messages IMAP[INBOX] -> Maildir[.]
Adding flags to 4 messages on Maildir[.]
Adding flags e to 4 messages on Maildir[.]
Adding flags d to 4 messages on Maildir[.]
Adding flags ) to 4 messages on Maildir[.]
Adding flags ( to 4 messages on Maildir[.]
Adding flags l to 4 messages on Maildir[.]
Adding flags n to 4 messages on Maildir[.]
Adding flags t to 4 messages on Maildir[.]
Adding flags \ to 4 messages on Maildir[.]
Adding flags D to 4 messages on Maildir[.]
Deleting flags T to 4 messages on Maildir[.]
Adding flags to 4 messages on LocalStatus[.]
Adding flags e to 4 messages on LocalStatus[.]
Adding flags d to 4 messages on LocalStatus[.]
Adding flags ) to 4 messages on LocalStatus[.]
Adding flags ( to 4 messages on LocalStatus[.]
Adding flags l to 4 messages on LocalStatus[.]
Adding flags n to 4 messages on LocalStatus[.]
Adding flags t to 4 messages on LocalStatus[.]
Adding flags \ to 4 messages on LocalStatus[.]
Adding flags D to 4 messages on LocalStatus[.]
Deleting flags T to 4 messages on LocalStatus[.]
Fix: use a different variable to store IMAP flags when managing
messages corresponding to responses with UID attribute, e.g.:
*** IMAP.py.orig Wed Aug 22 18:23:17 2007
--- IMAP.py Wed Aug 22 18:22:38 2007
*************** class IMAPFolder(BaseFolder):
*** 340,348 ****
if not ('UID' in attributehash and 'FLAGS' in
attributehash):
# Compensate for servers that don't return a UID
attribute.
continue
! flags = attributehash['FLAGS']
uid = long(attributehash['UID'])
! self.messagelist[uid]['flags'] =
imaputil.flagsimap2maildir(flags)
try:
needupdate.remove(uid)
except ValueError: # Let it slide if it's not
in the list
--- 340,348 ----
if not ('UID' in attributehash and 'FLAGS' in
attributehash):
# Compensate for servers that don't return a UID
attribute.
continue
! lflags = attributehash['FLAGS']
uid = long(attributehash['UID'])
! self.messagelist[uid]['flags'] =
imaputil.flagsimap2maildir(lflags)
try:
needupdate.remove(uid)
except ValueError: # Let it slide if it's not
in the list
02/03/08 14:04:35 changed by js
* attachment flags-fix.patch added.
Delete 02/03/08 14:05:24 changed by js
Unfortunately I have to fetch some of my mail from an Exchange server
(Microsoft Exchange Server 2003 IMAP4rev1 server version 6.5.7638.1)
and I can confirm that the analysis of the problem is correct, and the
patch given here fixes the problem.
Looking at the code of the processmessagesflags() method I think it
generally is a bug that the "flags" parameter is reused as a local
variable, since the final "for uid in needupdate:" loop needs the
original value of "flags". This only worked by accident.
I'm attaching a unidiff version of the patch which applies cleanly
against Debian unstable's offlineimap 5.99.4.
New repository/folder classes to support "real deletion" of messages
thorugh Gmail's IMAP interface: to really delete a message in Gmail,
one has to move it to the Trash folder, rather than EXPUNGE it.
This patch maneuvers around python imaplib's mysterious read-only detection
algorithm and correctly calls the UI's deletetoreadonly(), when trying to
delete/expunge in a mailbox without having the necessary rights.
fixes deb#439384
From: martin f krafft
Subject: race condition in Maildir writing
The offlineimap Maildir code checks for file existence and then
opens a file. That's open to a race condition. It's better to open
the file and fail if it already exists. The following patch does
this. It catches OSError 17 (file exists) and re-raises all others.
I'll leave it up to you to decide whether this is appropriate.
fixes deb#433732
Date: Sun, 30 Sep 2007 13:54:56 -0400
From: Daniel Jacobowitz <drow@false.org>
To: offlineimap@complete.org
Subject: Assorted patches
Here's the result of a lazy Sunday hacking on offlineimap. Sorry for
not breaking this into multiple patches. They're mostly logically
independent so just ask if that would make a difference.
First, a new -q (quick) option. The quick option means to only update
folders that seem to have had significant changes. For Maildir, any
change to any message UID or flags is significant, because checking
the flags doesn't add a significant cost. For IMAP, only a change to
the total number of messages or a change in the UID of the most recent
message is significant. This should catch everything except for
flags changes.
The difference in bandwidth is astonishing: a quick sync takes 80K
instead of 5.3MB, and 28 seconds instead of 90.
There's a configuration variable that lets you say every tenth sync
should update flags, but let all the intervening ones be lighter.
Second, a fix to the UID validity problems many people have been
reporting with Courier. As discussed in Debian bug #433732, I changed
the UID validity check to use SELECT unless the server complains that
the folder is read-only. This avoids the Courier bug (see the Debian
log for more details). This won't fix existing validity errors, you
need to remove the local status and validity files by hand and resync.
Third, some speedups in Maildir checking. It's still pretty slow
due to a combination of poor performance in os.listdir (never reads
more than 4K of directory entries at a time) and some semaphore that
leads to lots of futex wake operations, but at least this saves
20% or so of the CPU time running offlineimap on a single folder:
Time with quick refresh and md5 in loop: 4.75s user 0.46s system 12%
cpu 41.751 total
Time with quick refresh and md5 out of loop: 4.38s user 0.50s system
14% cpu 34.799 total
Time using string compare to check folder: 4.11s user 0.47s system 13%
cpu 34.788 total
And fourth, some display fixes for Curses.Blinkenlights. I made
warnings more visible, made the new quick sync message cyan, and
made all not explicitly colored messages grey. That last one was
really bugging me. Any time OfflineIMAP printed a warning in
this UI, it had even odds of coming out black on black!
Anyway, I hope these are useful. I'm happy to revise them if you see
a problem.
--
Daniel Jacobowitz
CodeSourcery
patch from Mike Gerber
Two times today I have found my offlineimap to have died with this same
situation. It appears as if certain types of messages (both spam in my
situation), cause offlineimap to choke. When it does it cannot proceed.
This means that when I run offlineimap, it pulls in messages from some
folders, then it hits the folder with the bad message and dies, leaving
undownloaded mail on the server. The only fix to this problem is to find
the problem message on the server and remove it by hand. This isn't such
a huge deal for me, since I run the server, but other people have to
come to me to ask me to delete these messages, and until I do they
cannot download their email.
I have captured the output by running script during one of these
incidents, this has been attached. Additionally, I have also attach the
problematic message.
The patch seems to work for me, might need some Python wizard and better
testing, though.
fixes deb#396443
r[1] is a list. In case it contains more than one 'str' they are concatenated
using '. '. In processmessagesflags the join is tested, for savemessagesflags I
assume that it is also needed.
I have tested this and Dovecot no longer beats offlineimap
to the punch. (-:
I achieved that by keeping the renames in tmp/ until it finally does
one last rename in new/ or cur/.
fsync the Maildir file, its final directory when writing a new message.
fsync the localstatus file and its final directory when writing the
local status cache.
This should reduce duplication in the event of hardware trouble.
fixes#8
see thread at http://lists.complete.org/offlineimap@complete.org/2007/03/threads.html.gz
The attached patch adds syncing the INTERNALDATE of IMAP folders with
the mtime of messages in maildir folders.
I want this to happen, because I'm running a dovecot over the maildirs
synced by offlineimap, and that uses the mtime as the INTERNALDATE.
When using mutt to view messages I generally sort based on the received
date, which for IMAP folders is the INTERNALDATE.
Since this is the first real coding I've done in Python the patch may
need to be cleaned up some, but it's working pretty well for me. I've
added new messages to each side, and the received date has been
preserved going both ways.
Patch from Nikita V. Youshchenko
From: "Nikita V. Youshchenko"
To: Debian Bug Tracking System
Subject: offlineimap: exception on mail with broken headers (+fix)
Date: Wed, 24 Aug 2005 13:41:08 +0400
Package: offlineimap
Version: 4.0.10
Severity: normal
Tags: patch
Recently I've got an exception (see below) while using offlineimap.
Exception was probably caused by invalid Date header of (likely spam)
message:
Date: Sat, 20 Aug 2005 4294967295:43:18 -0700
From: "Nikita V. Youshchenko"
I trued to use offlineimap and found that while being quite fast on
small folders, it takes up to several minutes (of 100% busy CPU and
almost no network traffic) to sync a folder with 2000+ messages.
While looking into the code, I found why this happens.
In folder/Base.py, in method BaseFolder.syncmessagesto_copy(),
dest.getmessagelist() is called inside a loop, while being a loop
invariant. Similar thing happens in BaseFolder.syncmessagesto_delete()
for self.getmessagelist().
This causes quadratic complexity over folder size.
Moving these calls out of loops make large folder sync fast (several
seconds instead of several minutes for folder with 2000 messages on
700MHz P3).