Previously, we would simply bail out in an ugly way, potentially leaving
temporary files around etc, or while writing status files. Hand SIGINT
and SIGTERM as an event to the Account class, and make that bail out
cleanly at predefined points. Stopping on ctrl-c can take a few seconds
(it will e.g. finish to transfer the ongoing message), but it will shut
down cleanly.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
As reported in https://github.com/spaetz/offlineimap/pull/2, we would
fail when files are empty because file.read() would throw attribute
errors.
Fix this by removing the superfluous read() check and additionally log
some warning message.
Reported-by: Ralf Schmitt
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
When sep='/' in a Maildir, we were doing a os.path.join(dirname,'') on
the top level maildir, which results in a "dirname/", so all our maildir
folder names had slashes appended. Which is pretty much wrong, so this
fixes it by only using os.path.join when we actually have something to
append.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
We need the list of folders and the folder delimiter, but it was not
always retrieved early enough. E.g. when doing IMAP<->IMAP sync and the
local IMAP being readonly, we would bunk out with a mysterious error
message become repository.getsel() would still return None.
This commit fixes this error.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
imapserver.getdelim() was not used at all, so remove this function. The
folder delimiter is available via the repository.getsep() call.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
The folder delimiter is only initialized after a call to
acquireconnection(), so we must never call this function too
early. Include an assert() to make sure we get notified when we do.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Rather than keeping a separate queue of all logged lines in memory, we
rely on the curses window scrolling functionality to scroll lines. On
resizing the terminal this means, we'll clear the screen and start
filling it afresh, but that should be acceptable.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
1) Rework the sleep abort request to set the skipsleep configuration
setting that the sleep() code checks.
2) Only output 15 rather than 50 debug messages on abort...
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
The remote|local|statusrepo is an anttribute of each SyncableAccount()
anyway, so we don't need to pass it in, we can simply get it from the
Account().
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Rename some variables, simplify the hotkeys treatment. Refresh/exit
signals still don't work as of yet, but will come.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Resizing a Blinkenlights terminal doesn't crash anymore, and actually
seems to be changing the size, with this patch.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
We were still referring to s.gettf() in sleeping(self, ...) causing each
attempt to sleep to crash. Fix this, and the CursesAccountFrame.sleeping()
method. I am sure, there is still wrong and broken but we are getting there.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This function can IMHO lead to possible deadlocks when waiting for the
connectionlock. Do add a comment to that regard, this will need to audit.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
The huge UI rework patch removed some obscure logic and special handling of
thread exit messages. It turns out that this was in fact still needed as a
specific exit message of the SyncRunner thread signified the threatmonitor
to quit.
We will want a nicer machinery for this in the future I guess, but fix the
eternal hang on exit by reintroducing a special exit message for the
SyncRunner thread, and return from the infinite monitor loop if SyncRunner
finishes.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
To make sure, the lock gets released even if we raise an exception between
acquire() and release()
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
All ExitNotifyThreads and InstanceLimitThreads are setDaemon(True) in their
constructor, so there is no need to do that again in the code.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
1) Differentiate error messages between imaplib.abort and imaplib.error
exceptions in the log.
2) Drop connections in the case of imapobj.error, it also might denote a
broken connection.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
During cleanup we often call releaseconnection in a finally: block. But
in cases of error, we might have dropped the connection earlier already
and set it to "None". In this case don't fail releaseconnection() but
make it a NOOP.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
The default parameter value was "None", and we were comparing that
directly to the imaplib2 value of is_readonly which is False or True, so
the comparison always returned "False".
Fix this by setting the default parameter to "False" and not
"None". Also convert all users of that function to use False/True.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
It is basically unused by now. Rework to be able to make use of it
later, no functional changes.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Logging was flawed as the output was e.g. heavily buffered and people
complained about missing log entries. Fix this by making use of the
standard logging facilities that offlineimap offers.
This is one big ugly patch that does many things. It fixes the
Blinkenlights backend to work again with the logging facilities.
Resize windows and hotkeys are still not handled absolut correctly, this
is left for future fixing. THe rest of the backends should be working fine.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
If folder creation failed, we would output the wrong repository and
folder name (copy'n paste error). Fix this so we actually output the
correct values.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Only import the lock, that we actually need. Also import the with statement
for use with python 2.5. We'll need it for sure in this file.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Drop a connection, if the NOOP to keep a connection open fails due to
broken connections.
Note that I believe this function is not working as intended. We grab
one random connection and send a NOOP. This is not enough to keep all
connections open, and if we invoke this function multiple times, we
might well always get the same connection to send a NOOP through.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
A repositories 'reference value is always prefixed to the full folder
path, so we should do so when creating a new one. The code had existed
but was commented out since 2003, I guess the "reference" option is not
too often used.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
If port is None, we would try to format an empty string with %d wich
fails. Fix it by using %s.
Reported-by: Iain Dalton <iain.dalton@gmail.com>
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This outputs a handy summary of your server configuration and version
strings etc, which is useful for bug reporting.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Was getting too large, split into an parse_cmd_options and a sync()
function. Moving config and ui to self.config and self.ui to make them
available through the OfflineImap instance.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
It happens quick, and clutters the log. So we can usually skip this. We
will output a log entry when we actually create a new folder anyway.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
If we create a new folder we would previously not update our folder
list, which led to us skipping the synchronization of those new folders
during the initial run (subsequent runs would pick it up).
Invalidate the folder cache when we create a folder during folder
structure sync. Regetting the whole list from an IMAP server might be
slightly suboptimal from a performance point, but it is easy and will
lead to consistent results. Hopefully we will not have to create new
folders on each new run.
Reported-by: Daniel Shahaf <d.s@daniel.shahaf.name>
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Modify the UI:acct and acctdone functions to keep tab of the time
inbetween. Put self.ui.acct() and acctdone() at the right places in
accounts.py so that the timing happens at the right places.
While modifying that loop, flatten the nested try: try: except: finally:
constructs, we require python 2.5 now which copes with that.
At the end of each account sync you will now see something like:
*** Finished account 'test' in 0:05
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Thread names are used to determine the logging header in the TTY ui. A
recent change made them too terse (basically only changing the account
name and not the folder names). Unbreak.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Output (2 of 500) when logging message copying. This required moving of
self.ui.copyingmessage into a different function where we actually have
the information about the progress handy.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Rather than setting a global threadutil/profiledir variable, we make
set_profiledir a class function that sets the class variable profiledir.
While touching theprofiledir code, add warning to the user if the
profile directory existed before.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Registering a thread (associating it with a certain account name) would
fail if it was already registered. However, as we a) never unregister most
threads (bad) and b) single-threaded mode reuses threads, we failed when
syncing multiple accounts in single-threading mode.
This commit cleans up the functions to not make re-registering a thread
fatal (it could be legitimate, however it *should* not occur). Future
work needs to be done to unregister new threads at the appropriate places.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
When checking for the IMAP4.abort() exception, we need of course to
perform:
except imapobj.abort:
and not
except imapobj.abort():
Thanks to Johannes Stezenbach <js@sig21.net> for pointing to the glitch.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
apply() has been deprecated since Python 2.3, and won't be working in
python 3 anymore. Use the functional equivalent throughout.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Dave identified a case where our new dropped connection handling did
not work out correctly: we use the retry_left variable to signify
success (0=success if no exception occured).
However, we were decrementing the variable AFTER all the exception
checks, so if there was one due to a dropped connection, it
could well be that we 1) did not raise an exception (because we want to
retry), and 2) then DECREMENTED retry_left, which indicated "all is
well, no need to retry".
The code then continued to check() the append, which failed with the
above message (because we obtained a new connection which had not even
selected the current folder and we were still in mode AUTH). The fix is
of course, to fix our logic: Decrement retry_left first, THEN decide
whether to raise() (retry_left==0) or retry (retry_left>0) which would
then correctly attempt another loop. I am sorry for this newbie type of
logic error. The retry count loop was too hastily slipped in, it seems.
Reported-by: Dave Abrahams <dave@boostpro.com>
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>