It is more readable and returns a list.
This continues work done in 19c4330.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This was causing the error message "not all arguments converted during
string formatting." Specifically:
```
% offlineimap -u machineui
OfflineIMAP 7.0.4
Licensed under the GNU GPL v2 or any later version (with an OpenSSL exception)
msg:protocol:MainThread:7.2.0
msg:initbanner:MainThread:OfflineIMAP+7.0.4%0A++Licensed+under+the+GNU+GPL+v2+or+any+later+version+%28with+an+OpenSSL+exception%29
msg:registerthread:Account+sync+MYHOST:MYHOST
msg:acct:Account+sync+MYHOST:MYHOST
error::Account+sync+MYHOST:ERROR%3A+While+attempting+to+sync+account+%27MYHOST%27%0A++not+all+arguments+converted+during+string+formatting
msg:acctdone:Account+sync+MYHOST:MYHOST
msg:threadExited:MainThread:Account+sync+MYHOST
msg:unregisterthread:MainThread:Account+sync+MYHOST
msg:terminate:MainThread:0%0A%0A
```
Signed-off-by: Christopher League <league@contrapunctus.net>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Otherwise, it might be impossible to know which account is connecting when more
than one is syncing.
Code style.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
They introduce a regression not allowing to discard the XOAUTH2 method when
expected.
The default lambda did not take the "account_name" argument.
Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/362
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
OfflineIMAP frequently delivers mail files to the Maildir consisting exclusively
of a single ASCII digit in IDLE mode. IMAPFolder.getmessage expects 'data' to be
of the form
[(fetch-info, message-body)]
However, the imapobj.uid call in getmessage returns a list of *all* pending
untagged FETCH responses. If any message flags were changed in the selected
IMAP folder since the last command (by another client or another thread in
OfflineIMAP itself), the IMAP server will issue unsolicited FETCH responses
indicating these flag changes (RFC3501, section 7). When this happens, 'data'
will look like, for example
['1231 (FLAGS (\\Seen) UID 5300)',
'1238 (FLAGS (\\Seen) UID 5318)',
('1242 (UID 5325 BODY[] {7976}', message-body)]
Unfortunately, getmessage retrieves the message body as data[0][1], which in
this example is just the string "2", and this is what gets stored in the mail
file.
Multi-threaded OfflineIMAP with IDLE or holdconnectionopen is particularly
susceptible to this problem because flag changes synced back to the IMAP server
on one thread will appear as unsolicited FETCH responses on another thread if it
happens to have the same folder selected. This can also happen without IDLE or
holdconnectionopen or even in single-threaded OfflineIMAP with concurrent access
from other IMAP clients (webmail clients, etc.), though the window for the bug
is much smaller.
Ideally, either imaplib2 or getmessage would parse the fetch responses to find
the response for the requested UID. However, since IMAP only specifies
unilateral FETCH responses for flag changes, it's almost certainly safe to
simply find the element of 'data' that is a tuple (perhaps aborting if there is
more than one tuple) and use that.
Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/162
Based-on-patch-by: Austin Clements <amdragon@MIT.EDU>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Commit 6b28071b0f makes the check once nametrans is applied. This is wrong
because separators are valid characters in names returned by nametrans. E.g:
"Sent" -> "[Gmail]/Sent"
Make the check against the raw name of the folder, instead.
Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/353
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
1. There is one database per folder and sqlite requires to serialize the
writings. Instead of locking at LocalStatusSQLiteFolder object level, introduce
a new DatabaseFileLock object which is shared across threads. This fixes the
concurrent writes issues that some users might experience by duplications or
flags restored to the previous state.
2. Close the database only when we are sure no other threads will use the
connection on a *per-file* basis. Previous fix 677afb8d8f is wrong
because the same lock is shared for all the databases.
Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/350
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
1. There is one database per folder and sqlite requires to serialize the
writings. Instead of locking at LocalStatusSQLiteFolder instance level,
introduce a new DatabaseFileLock object which is shared across threads. This
fixes the concurrent writes issues that some users might experience by
duplications or flags restored to the previous state.
2. Close the database only when we are sure no other threads will use the
connection on a *per-file* basis. Previous fix 677afb8d8f is wrong
because the same lock is shared for all the database files.
Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/350
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This did not work and is not usefull since the purge() method was introduced in
1410a391bc. Actually, the purge() does what deletemessagelist() was supposed to
achieve.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
It's required to have more than one connection to the database for the
maxconnections configuration option to work with threads. However,
connection.close() is closing all the connections. Only close the connection
when no more thread need it.
Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/350
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
It's required to have more than one connection to the database for the
maxconnections configuration option to work with threads. However,
connection.close() is closing all the connections. Only close the connection
when no more thread need it.
Backported-from: 856b74407bd7f634cae5a8c2d9b84e13d14c12d2
Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/350
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This is usefull to remove dangling entries for removed accounts or if mbnames is
not enabled anymore.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Output a warning so that we can dig into this. For now, the patch doesn't fix
the root cause. If the server returns UID 0 as valid UID number, this must be
ignored as soon as possible.
Github-ref: https://github.com/OfflineIMAP/offlineimap/issues/336
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
When a maildir is removed it must be considered new for the sync. However, the
local cache of the folder remains. This means the sync of the folder removes all
the missing emails.
Avoid loosing of data for users not aware of the local cache by removing any
pre-existing status cache of a folder when we actually want to create the
database.
Improve style.
Github-fix: https://github.com/OfflineIMAP/offlineimap/issues/333
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
- Learn to support UTF-8 characters where it was not supported for usernames and
passwords (but for netrc).
- Fix the types in the code for both py2 and py3: we now expect unicode for
usernames and passwords.
Unicode (UTF-8) is required only for variables with non-ASCII characters.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Make mbnames to work with intermediate files, one per account, in the JSON
format. The mbnames target is built from those intermediate files.
Github-Fix: https://github.com/OfflineIMAP/offlineimap/issues/66
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
- Expose more literals.
- Fix a type to bytes.
- Fix comment.
Changes submitted upstream by Łukasz and me.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Backported from 8e995a69bfa003ab822b55731429d84b3bc5626f.
We currently close the database as soon as possible while we handle the status
backend but this is still too early because autorefresh induces looping on this
code block.
Instead of delaying the closing outside of the loop, it's easier to delay the
opening as late as possible (inside the loop). The downside is that the database
is opened/closed more than once when autorefresh is enabled. The good news is
that this make the code much easier.
Fixes regression introduces by 6fb5700.
Reported-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The virtual imaplib2 first try to import imaplib2 when provided by the system.
If not provided or if the version is not supported, fallback on the bundled
imaplib2 version.
Distribution maintainers can now easily remove the bundled imaplib2 version if
they want to get it packaged outside of offlineimap.
We still want to provide imaplib2 by default because:
- this library is neither in Python core nor packaged by a lot of distributions;
- users expect to be able to run offlineimap by just downloading the tarball or
after a git clone.
In order to avoid unexpected (too old) versions of imaplib2, we restrict the
supported versions of this librabry.
Reviewed-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Be aware upstream has two versions of both 2.52 and 2.53.
This bump change is from
commit a205409a0047732840505e534c07d8d85d2644a1
Author: Piers Lauder <piers@janeelix.com>
Date: Sun Dec 27 20:55:04 2015 +1100
Back out BINARY changes - not implemented correctly.
to
commit 0596e7372fd3556d27ea55510b1e8cfa8370ec43
Author: Piers Lauder <piers@janeelix.com>
Date: Fri Jun 3 11:58:40 2016 +1000
new version of imaplib2.py
Original-imaplib2-patch-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This patch fixes the situation when "localfolders" specifies path that
is more that one level deep and top directory does not exists. Example
would be "localfolders = ~/Mail/a". This especially relevant on the
first run.
In that case we would end up with unhandled exception causing
unexpected termination of the program.
Thread 'Account sync test' terminated with exception:
Traceback (most recent call last):
File "/offlineimap/offlineimap/threadutil.py", line 172, in run
Thread.run(self)
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/offlineimap/offlineimap/accounts.py", line 258, in syncrunner
self.localrepos = Repository(self, 'local')
File "/offlineimap/offlineimap/repository/__init__.py", line 82, in __new__
return repo(name, account)
File "/offlineimap/offlineimap/repository/Maildir.py", line 40, in __init__
os.mkdir(self.root, 0o700)
OSError: [Errno 2] No such file or directory: '/Mail/a'
By replacing call to "mkdir" with "makedirs" we can simply create
directories recursively.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Some servers are broken: they return zero as valid UID and respond "BAD invalid
parameter: 0" on the FETCH command.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
There is no other way to make Python2 and Python3 happy, because syntax
raise E, V, T is incompatible with the latter.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Python3 accepts binary input for md5 function.
This patch is known to break setups using folder names not strictly conforming
the IMAP UTF-7 encoding. We always made it clear that such setup is unsupported
and might be broken at some point in time. See documentation about
'decodefoldernames' in the provided configuration file. This is why this patch
is considered introducing no regression for this use case.
Patches to support both Python 3 and Python 2 by re-encoding the MD5 in the
filenames are welcome. This likely requires a new CLI option to allow
backporting the feature for users downgrading or changing of Python environment.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
We currently close the database as soon as possible while we handle the status
backend but this is still too early because autorefresh induces looping on this
code block.
Instead of delaying the closing outside of the loop, it's easier to delay the
opening as late as possible (inside the loop). The downside is that the database
is opened/closed more than once when autorefresh is enabled. The good news is
that this make the code much easier.
Fixes regression introduces by 6fb5700.
Reported-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
With a maxsize to the Queue of threads we are introducing a blocking call while
adding new threads.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
In Python3, zip returns iterator instead of list.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
xrange was removed in Python3 while range exists in boths versions.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
There is no such method in Python3 any more.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
It is more readable and returns a list therefore it is compatible both
with Python 2 and 3.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
"imapobj.search" returns a list with one string element of numbers
separated by one whitespace character for regular box (GMail, AOL...).
['1 2 3 4 5 6 7 8 9 10 11 12']
But if we would like to sync from Davmail it would return a list of
numbers.
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'].
The code "return res_data[0].split()" in the first case will return what
we already have when using Davmail, hence only one email will be
fetched. But if only the first sync would be with maxage the emails
will be removed, because offlineimap will think that they were removed
by us.
The patch distinguishes between syncing with Davmail and regular box and
applies split on the first element only when it finds whitespace
character. It also handles the case when the first element is empty on
first sync.
Closes#327
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Sometimes it might happen that you put wrong date and you except emails
to be fetched, but they are not and you do not have an idea why.
By raising exception the user will see a proper message telling that he
used the wrong date for maxage/startdate property.
If someone wants to set a future date intentionally might as well sync
in the future.
Signed-off-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This enables the "append" mode feature. Configuration option is sync_deletes in
both local and remote repositories. Marked EXPERIMENTAL and UNTESTED.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Introduce the '--migrate-fmd5-using-nametrans' option which migrates the
FMD5 hashes from versions prior to 6.3.5.
It seems that commit 'Apply nametrans to all Foldertypes' (6b2ec956cf)
introduced a regression because it changed the FMD5 part of the filename
calculated by OfflineIMAP. Thus, OfflineIMAP believes that the messages
has been removed and adds them back.
For more information, see:
http://www.offlineimap.org/configuration/2016/02/12/debian-upgrade-from-jessie-to-stretch.html
Bug-Debian: https://bugs.debian.org/812108
Reported-by: François <francois@avalenn.eu>
Signed-off-by: Ilias Tsitsimpis <i.tsitsimpis@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Some environments that return AAAA records for their IMAP servers can pose
problems for clients that do not have end-to-end IPv6 connectivity for a number
of reasons (e.g. policy, lack of full routing, security, etc..)
Even with a fallback mechanism in place, you can still arrive at IMAP
implementations that could prevent authentication from unknown IPv6 space. This
in itself is not enough to fallback to IPv4 since there is an actual connection
on that socket.
This change is for introducing a user-defined value:
[Repository imap-remote]
ipv6 = no
to create a preference per repository on which AF to connect to the remote
server on
ipv6 = yes (AF_INET6)
ipv6 = no (AF_INET)
unspecified = default
Signed-off-by: Ebben Aries <e@dscp.org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Since this is used in an except calse, we first don't mask the real cause and
raise the original error.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
By default, OfflineIMAP catches SIGTERM/SIGHUP/SIGINT and attempts to
gracefully terminate as soon as possible. Allow the user to abort
immediately, by hitting Ctrl-C several times.
Bug-Debian: https://bugs.debian.org/679975
Signed-off-by: Ilias Tsitsimpis <i.tsitsimpis@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This reverts commit a1dc76ae91.
Causes a crash when using Blinkenlights UI with -l CLI option.
$ ./offlineimap.py -c offlineimap.conf.minimal -u blinkenlights -l foo
Traceback (most recent call last):
File "./offlineimap.py", line 36, in <module>
oi.run()
File "/tmp/offlineimap/offlineimap/init.py", line 50, in run
options, args = self.__parse_cmd_options()
File "/tmp/offlineimap/offlineimap/init.py", line 205, in __parse_cmd_options
self.ui.setlogfile(options.logfile)
File "/tmp/offlineimap/offlineimap/ui/UIBase.py", line 119, in setlogfile
self.logger.info(msg)
File "/usr/lib/python2.7/logging/__init__.py", line 1159, in info
self._log(INFO, msg, args, **kwargs)
File "/usr/lib/python2.7/logging/__init__.py", line 1278, in _log
self.handle(record)
File "/usr/lib/python2.7/logging/__init__.py", line 1288, in handle
self.callHandlers(record)
File "/usr/lib/python2.7/logging/__init__.py", line 1328, in callHandlers
hdlr.handle(record)
File "/usr/lib/python2.7/logging/__init__.py", line 751, in handle
self.emit(record)
File "/tmp/offlineimap/offlineimap/ui/Curses.py", line 305, in emit
color = self.ui.gettf().curses_color
AttributeError: 'CursesLogHandler' object has no attribute 'ui'
Reported-by: iliastsi
Github-issue: #293
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The retry loop would release connection that would get
re-released upon ``finally`` clause. In consequence, an
exception would be cast.
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This fix does not apply when any keyword in configured which is already
harmless.
Written-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Extract the flag/keyword translation and combination logic to a
function.
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This uses the destination folder's keyword mapping to translate the
message's keywords into some appropriate format.
Tested only with local Maildir.
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The keywords are in the flag string, so imaputil can just strip the
usual \Flags.
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit assembles a dictionary mapping user-specified IMAP keywords
to Maildir lower-case flags, similar to Dovecot's format
http://wiki2.dovecot.org/MailboxFormat/Maildir
Configuration example:
[Repository Local]
type = Maildir
localfolders = ~/Maildir/
customflag_a = $label1
customflag_b = $Forwarded
customflag_c = Junk
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Remove filtering that was previously done to avoid errors in flag
handling.
Signed-off-by: Igor Almeida <igor.contato@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Note that the stacks are grouped if similar, and the current
process (the one handling the signal) is identified and reports
where it was before the signal.
This can be quite handy when wanting to debug thread locks for
instance.
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
If this value is true, use (if possible) a timestamp based on message
Date or Delivery-date headers. The current system time is used
otherwise.
filename_use_mail_timestamp and utime_from_header are now completely
separated option that do not interfere one with other.
To handle this feature in a multithread context we use a hash to count
the number of mail with the same timestamp. This method is more accurate
than using the old lasttime and timeseq variables.
Signed-off-by: Sébastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Rather than having an option for syslog output, make a separate UI
option.
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Handle case where email's internal time is erroneously so large as to
cause overflow errors when setting file modification time with
utime_from_header = true.
Reported-by: Cameron Simpson <cs@zip.com.au>
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Allow the user to block usage of known-bad versions of SSL and TLS.
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Return value set to 1 if sync failed and error is thrown. Otherwise set to 0 if successful.
Signed-off-by: Prashant Sachdeva <sachdevp@cs.ubc.ca>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
When new mail arrives, this hook is triggered, allowing the user to
play a sound, or launch a popup.
Signed-off-by: Matthew Krafczyk <krafczyk.matthew@gmail.com>
Since skipping a folder means no new data is downloaded, the UID validity
problem is a backup failure. Make it possible to alert or work around
it in scripts by signaling with the exit code.
Signed-off-by: Alex Kapranoff <alex@kapranoff.ru>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Now it is possible to handle failed syncs in scripts.
Signed-off-by: Alex Kapranoff <alex@kapranoff.ru>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
1. When using maxage, local and remote messagelists are supposed to only
contain messages from at most maxage days ago. But local and remote used
different timezones to calculate what "maxage days ago" means, resulting
in removals on one side. Now, we ask the local folder for maxage days'
worth of mail, find the lowest UID, and then ask the remote folder for
all UID's starting with that lowest one.
2. maxage was fundamentally wrong in the IMAP-IMAP case: it assumed that
remote messages have UIDs in the same order as their local counterparts,
which could be false, e.g. when messages are copied in quick succession.
So, remove support for maxage in the IMAP-IMAP case.
3. Add startdate option for IMAP-IMAP syncs: use messages from the given
repository starting at startdate, and all messages from the other
repository. In the first sync, the other repository must be empty.
4. Allow maxage to be specified either as number of days to sync (as
previously) or as a fixed date.
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Previously, syncing labels on a message always resulted in updating the
file modification time, even with utime_from_headers=true
This patch restores the file mtime to the previous value when
utime_from_headers=true, preventing a label synchronization from
breaking the promise that the file mtimes coincide with the header date.
Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
We were using rtime for two different purposes:
- to store remote internal date
- to use in the utime_from_header option
Let's decouple the utime_from_header logic from rtime, now rtime means
remote internal date.
Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Upstream bug has been fixed, since imaplib2 v2.42 the untagged responses are
flushed (as stated by the documentation).
See https://sourceforge.net/p/imaplib2/bugs/7/
Signed-off-by: Pierre-Louis Bonicoli <pierre-louis.bonicoli@gmx.fr>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This partially reverts commit 25513e9038.
Only changes about dates and times are reverted. The changes about the style are
kept.
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The basic problem is in the context of syncing multiple accounts where
one is fast and the others are slower (due to the number of folders).
When the fast account completes, the other accounts are partially written
through the list and if the file is read during this time, the list can
be useless. However, in the general case, the file is probably left
around from a previous run of offlineimap and is more correct, so add an
option to leave it alone until all syncing is done.
Incremental is still the default since this running offlineimap using
its own timer setup is likely the most common setup. Turning it off
works best with one-shot mode triggered by cron or systemd timers.
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Fix regresssion introduced in 428349e3.
Prevent messages with UID's already in the destination folder from getting
excluded from the copy list.
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Some messages were excluded from the copy/delete list after the UI message said
they were copied/deleted.
Also fix Internaldate2epoch(), which was wrong.
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Suppose messages A and B were delivered to the remote folder at
"maxage + 1" days ago.
A was downloaded to the local folder "maxage + 1" days ago, but B was only
downloaded "maxage - 1" days ago (contrived scenario to illustrate the two
things that could happen). The behavior was that B gets deleted from the local
folder, but A did not. The expected behavior is that neither is deleted.
Starting where Base.py: __syncmessagesto_delete(self, dstfolder, statusfolder)
is called where:
- self is the remote folder
and
- dstfolder is the local folder.
It defines deletelist to be the list of messages in the status folder
messagelist that aren't in the remote folder messagelist with
not self.uidexists(uid)
A and B are both in the status folder. They're also both *NOT* in the remote
folder messagelist: this list is formed in IMAP.py: cachemessagelist(), which
calls _msgs_to_fetch(), which only asks the IMAP server for messages that are
"< maxage" days old.
Back to Base.py __syncmessagesto_delete(), look at the call
folder.deletemessages(deletelist), where folder is the local folder. This ends
up calling Maildir.py deletemessage() for each message on the deletelist. But we
see that this methods returns (instead of deleting anything) if the message is
in the local folder's messagelist. This messagelist was created by Maildir.py's
cachemessagelist(), which calls _scanfolder(), which tries to exclude messages
based on maxage. So at this point, we *WANT* A and B to be excluded -- then they
will be spared from deletion. This maxage check calls _iswithinmaxage(), and
actually does the date comparison based on the time found at the beginning of
the message's filename. These filenames were originally created in Maildir.py's
new_message_filename(), which calls _gettimeseq() to get the current time (i.e.
the time of retrieval).
Upshot: A's filename has an older timestamp than B's filename. A is excluded
from the local folder messagelist in _scanfolder(), hence spared from deletion
in deletemessage(); B is not excluded, and is deleted.
This patch does not address the timezone issue. As for the IMAP/timezone issue,
a similar issue is discussed in the thunderbird bug tracker here:
https://bugzilla.mozilla.org/show_bug.cgi?id=886534
In the end, they're solving a different problem, but they agree that
there is really no reliable way of guessing the IMAP server's internal
timezone.
Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Read proxy option in imapserver, instantiate a class in imaplibutil
using a self-defined keyword and a socket instance, and use this socket
instance to substitute the default socket instance used in imaplib2.
Signed-off-by: 夏恺(Xia Kai) <xiaket@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Get real tracebacks (at the point that calls Request.abort()
and not from the point that handles collected abort requests)
and pass them to our calling functions to ease debugging
of user problems.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This simplifies logics for the user, especially if he uses both
fingerprint and certificate validation: it is hard to maintain
the compatibility with the prior behaviour and to avoid getting
default CA bundle to be disabled when fingerprint verification
is requested.
See
http://thread.gmane.org/gmane.mail.imap.offlineimap.general/6695
for discussion about this change.
Default CA bundle is requested via 'sslcertfile = OS-DEFAULT'.
I had also enforced all cases where explicitely-requested CA bundles
are non-existent to be hard errors: when users asks us to use CA
bundle (and, thus, certificate validation), but we can't find one,
we must error out rather than happily continue and downgrade to
no validation.
Reported-By: Edd Barrett <edd@theunixzoo.co.uk>
Reviewed-By: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
We have no variable "fullname", it must have been slipped in
unintentionally.
Blame commit:
0f40ca4799 more style consistency
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
The note tells people to look at the source of the method, which
spinx.ext.viewcode conveniently links right next to the methods
signature.
Signed-off-by: Wieland Hoffmann <themineo@gmail.com>
We usually mutate some exceptions to OfflineImapError() and it is
a whole lot better if such exception will show up with the original
traceback, so all valid occurrences of such mutations were transformed
to the 3-tuple form of "raise". Had also added coding guidelines
document where this re-raise strategy is documented.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
CustomConfigParser.getlocaleval() loads "pythonfile" at each call.
Besides unnecessary IO, in case that dynamic_folderfilter is true, the
code in "pythonfile" would behave stateless, since it is re-initialized
at each call of getlocaleval(), i.e., at every sync. Fix that by keeping
a singleton copy of localeval in CustomConfigParser after the first call
of getlocaleval().
Signed-off-by: Stefan Huber <shuber@sthu.org>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
Otherwise, messages logged through UIBase.error would only be passed to
UIBase._msg, which only logs at INFO. This causes error to not get
logged at all for the quit UI.
Signed-off-by: Wieland Hoffmann <themineo@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This fixes a bug in which a message ended up with multiple gmail labels
header (X-Keywords or so). Fix fix it by removing all labels headers
before adding the updated one.
Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
There should be just one header storing gmail labels, but due to a bug,
multiple X-Keywords (or equivalent) headers may be found on the local
messages.
Now we, when extracting the labels from a message, we read all label
headers, instead of just the first one.
This has the consequence that some old labels stored locally in a second
X-Keywords (or third...) header, which effectively was rendered
invisible to offlineimap until now, may pop back up again and be pushed
to gmail. No labels will be removed by the changes in this commit,
though.
Signed-off-by: Abdo Roig-Maranges <abdo.roig@gmail.com>
It is a bit cleaner than making chains of calls like
{{{
value = os.path.expanduser(value)
value = os.path.abspath(value)
}}}
since we do see all transformations to be applied in a single
iterable and have no repeated code like in the above example.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
- Multi-line documentation for functions and methods
now has ending triple-double-quotes on an own line,
as per PEP 257.
- Added documentation and comments to almost all functions
and methods.
- Added stub implementations for getconfig() and getsection()
inside CustomConfig.ConfigHelperMixin to provide sane
run-time diagnostics for classes that doesn't implement them.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
The GNU GPL and the OpenSSL license are incompatible. Some distributions
take a hardline stance and do not consider OpenSSL to be a systems library
(which would permit the usage/distribution of OpenSSL) when distributing
apps such as OfflineImap from the same repository. In order to solve these
distributions dilemma, we add the OpenSSL exception to our GNU GPL v2+ license.
This allows for unambiguous use/distribution of our GNU GPL'ed application
with a python linking to openssl.
Consent of all contributors has been requested via email by
Sebastian@SSpaeth.de. With very few exceptions of minor contributions (which
might or might not by copyright-worthy) all past contributors have consented
to adding the OpenSSL exception. None of the replying authors has disagreed
with adding the exception.
The corresponding issues at question:
https://github.com/OfflineIMAP/offlineimap/issues/104
Debian bug #747033
We are still missing consent from:
1 Asheesh Laroia
2 Bart Kerkvliet
4 Daniel Burrows
5 David Favro
1 David Logie
1 Eric Dorland
1 Ethan Schoonover
49 Eygene Ryabinkin
1 Loui Chang
1 Luca Capello
1 Michael Witten
2 Mike Dawson
1 Peter Colberg
1 Scott Henson
1 Tom Lawton
1 W. Trevor King
2 X-Ryl669
1 buergi
2 dtk
5 mj
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Commit 7df765cfdb introduced regression:
GmailMaildir caches labels in its own function and it was testing the
presence of the 'labels' key in message descriptor. But 7df765cf
changed descriptor initialization and this key is always present.
So now we have 'labels_cached' flag that tells us if labels were
already cached or not.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Create initializer function that puts default values to all fields
of message list item. Fix all code that directly assigns some hash
to the elements of messagelist: for direct assignments only initializer
is now permitted, all other modification are done in-place.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
The example illustrations were slightly cryptic;
modify them to be more obvious.
Fix case #2 (message starts with two line breaks)
where additional line break was shown and coded.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
The parameter's value is a string representing the linebreak,
and can sometimes contain just '\n', in which case naming it
crlf is slightly misleading.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
For cases like
http://article.gmane.org/gmane.mail.imap.offlineimap.general/6468
it is beneficial to see that folder name was translated and the result
of this translation on a single line: having log like
{{{
Folder Boring/Wreck [acc: tmarble@info9.net]:
Syncing Boring/Breck: Gmail -> Maildir
}}}
with translated name on the "Folder" line and original one on the
"Syncing" line isn't very intuitive.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
It is always good to see which version we're talking about, so I had
added explicit marker for -devel, -release, -rcX and other states of
the OfflineIMAP.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
For servers without UIDPLUS we are inserting additional header
just after transformation '\n' -> CRLF was done. addmessageheaders()
was written to work with just '\n' as the separator, so X-OfflineIMAP
header wasn't preceeded by the CRLF, but just by '\n'.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
private methods prevent them from being overriden on derived classes. In
GmailFolder we need to override copymessageto, so it can't be private.
Before this commit, copymessageto was made private in Base but not in
GmailFolder. The end result was that labels were not set when copying
the message content, and always needed to be set on the label copying
pass.
Pointyhat-to: Eygene Ryabinkin
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
... and not self.filterheaders. With the current code this change
is no-op (since self.filterheaders is always passed as header_list),
but it is a bug in general.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
If when we request a LocalStatus folder, the folder has to be created,
we look whether the other backend has data, and if it does we migrate
it to the new backend.
The old backend data is left untouched, so that if you change back say
from sqlite to plaintext, the older data is still there. That should
not lead to data loss, only a slower sync while the status folder gets
updated.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
* Do not inherit LocalStatusSQLiteFolder class from the plaintext
one.
* Use some functions already in BaseFolder in both, plaintext and
sqlite classes.
* Add a saveall method. The idea is that saveall dumps the entire
messagelist to disk, while save only commits the uncommited
changes. Right now, save is noop for sqlite, and equivalent to
saveall for plaintext, but it enables to be more clever on when we
commit to disk in the future.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
* Implements Status Folder format v2, with a mechanism to upgrade an
old statusfolder.
* Do not warn about Gmail and GmailMaildir needing sqlite backend
anymore.
* Clean repository.LocalStatus reusing some code from
folder.LocalStatus.
* Change field separator in the plaintext file from ':' to '|'. Now
the local status stores gmail labels. If they contain field
separator character (formerly ':'), they get messed up. The new
character '|' is less likely to appear in a label.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Format headers X-Label and Keywords as a space separated list and all
other ones as comma-separated entities. This makes OfflineIMAP label
handling to be compatible with some user agents that recognise these
headers.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
When synclabels config flag is set to "yes" for the GMail repo,
offlineimap fetches the message labels along with the messages, and
embeds them into the body under the header X-Keywords (or whatever
'labelsheader' was set to), as a comma separated list.
It also adds an extra pass to savemessageto, that performs label
synchronization on existing messages from GMail to local, the same way
it is done with flags.
We also introduce GmailMaildir repository that adds functionality to
change message labels. It keeps track of messages modification time,
so one can quickly detect when the labels may have changed.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
In preparation for GMail label sync, we had split our some functionality
that will be needed further into their own functions. This also permitted
the code to look more compact and concise.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
When filterheaders is set to a comma-separated list of headers,
OfflineIMAP removes those headers from messages before uploading them
to the server.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Since we just do multiple passes for saving the message without
actually modifying its content (apart from header insertion that
is CRLF-clean), we can change line ends to the proper CRLF just
once.
And we can also get message's date only once too.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Added the configuration setting usecompression for the IMAP repositories.
When enabled, the data from and to the IMAP server is compressed.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Make external API of class/module to be smaller, explicitely mark
all internal functions. Also annotate methods that are implemented
as the part of the parent class interface.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Allow people who want folder filtering to depend on the external
conditions or to make it dynamic for other reasons, to do what
they want.
New repository configuration knob 'dynamic_folderfilter' was
introduced; it defaults to 'False' that matches historical behaviour.
GitHub: #73
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This commit fixes the case when we're invoking releaseconnection()
for a given imapobj twice.
This bug manifests itself as
{{{
ValueError: list.remove(x): x not in list
File "[...]/offlineimap/folder/IMAP.py", line 615, in savemessage
self.imapserver.releaseconnection(imapobj)
File "[...]/offlineimap/imapserver.py", line 130, in releaseconnection
self.assignedconnections.remove(connection)
}}}
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
When imaputil was parsing quoted strings, it treated "abcd\\"
as incomplete quoted string having escaped quote, rather than
properly-quoted string having escaped backslash.
GitHub issue: https://github.com/OfflineIMAP/offlineimap/issues/53
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
2.36 it includes support for SSL version override that was integrated
into our code before, no other changes.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
- Fix for Gmail sending a BYE response after reading >100 messages
in a session.
- Includes fix for GitHub#15: patch was accepted upstream.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Second argument is exception traceback, not the message; without this
tracebacks like mentioned in
http://permalink.gmane.org/gmane.mail.imap.offlineimap.general/5712
were happening when this exception handling block was hit.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This greatly simplifies developer's life and will, possibly, allow
users familiar with Python to debug and fix the problems by
themselves.
We, possibly, should not give tracebacks for the problems like
"can't open connection", but this is up to the caller of this
routine not to provide traceback in this case.
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
self._expecting_data was used both as the expected data length and the
flag that we expect some data. This obviously fails when advertized
data length is zero, so self._expecting_data_len was introduced to
hold the length of the expected data and self._expecting_data was left
as the flag that we expect the data to come.
GitHub issue: https://github.com/OfflineIMAP/offlineimap/issues/15
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
It is called localfolders and holds expanded name for the same
variable for the local repository of the account that is being
processed.
GitHub issue: https://github.com/OfflineIMAP/offlineimap/issues/21
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Bring the description in the template offlineimap.conf in sync to the
actual implementation: pass folder names to the sorting function, not
the offlineimap.folder.IMAP.IMAPFolder objects themselves.
GitHub issue: https://github.com/OfflineIMAP/offlineimap/issues/27
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Global or per-repository option utime_from_message tells OfflineIMAP
to set file modification time of messages pushed from one repository
to another basing on the message's "Date" header.
This is useful if you are doing some processing/finding on your
Maildir (for example, finding messages older than 3 months),
without parsing each file/message content.
From: Cyril RUSSO <boite.pour.spam@gmail.com>
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
Added configuration option "auth_mechanisms" to the config file:
it is a list of mechanisms that will be tried in the specified order.
Author: Andreas Mack <andreas.mack@konsec.com>
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
It's nice to set up an ssh tunnel command which forwards an IMAP tcp
port inside an encrypted session, e.g. with ssh's "-W" flag. In this
case the tunnelled connection still requires authentication inside
IMAP session, because this is transport-only tunnel that substitutes
normal TCP/SSL connection.
New directive, 'transporttunnel' was added: it specifies the command
that will create the tunnel. Only one type of tunnel must be
specified for a single repository: we can't have both preauthenticated
and transport-type tunnels, they won't chain together.
From: Steve Purcell <steve@sanityinc.com>
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>