[-]
[+]
|
Changed |
getmail.changes
|
|
[-]
[+]
|
Changed |
getmail.spec
^
|
|
[-]
[+]
|
Changed |
getmail-4.43.0.tar.bz2/PKG-INFO
^
|
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.0
Name: getmail
-Version: 4.42.0
+Version: 4.43.0
Summary: a mail retrieval, sorting, and delivering system
Home-page: http://pyropus.ca/software/getmail/
Author: Charles Cazabon
|
[-]
[+]
|
Changed |
getmail-4.43.0.tar.bz2/docs/CHANGELOG
^
|
@@ -1,3 +1,7 @@
+Version 4.43.0
+25 August 2013
+ -add IMAP IDLE support. Thanks: Jon Gjengset.
+
Version 4.42.0
3 August 2013
-fix problem with non-ascii characters in newly-added message header fields
|
[-]
[+]
|
Changed |
getmail-4.43.0.tar.bz2/docs/configuration.html
^
|
@@ -2730,6 +2730,13 @@
<li>--trace — print extended debugging information</li>
</ul>
<p>
+ If you are using a single getmailrc file with an IMAP server that understands
+ the IDLE extension from <a href="http://www.rfc-editor.org/rfc/rfc2177.txt">RFC 2177</a>,
+ you can use the --rcfile=<span class="meta">MAILBOX</span> option to specify
+ that getmail should wait on the server to notify getmail of new mail in the
+ specified mailbox after getmail is finished retrieving mail.
+</p>
+<p>
In addition, the following commandline options can be used to override any
values specified in the
<span class="file">[options]</span>
|
[-]
[+]
|
Changed |
getmail-4.43.0.tar.bz2/docs/getmail.1
^
|
@@ -33,6 +33,11 @@
.TP
\fB\-\-trace\fR
print extended trace information (extremely verbose)
+.TP
+\fB\-i\fIFOLDER\fR, \fB\-\-idle\fR=\fIFOLDER\fR
+maintain connection and listen for new messages in \fR\fIFOLDER\fI\fR.
+This flag will only work if a single rc file is given, and will only work on
+IMAP connections where the server supports IMAP4 IDLE (RFC 2177).
.PP
The following options override any in the configuration file(s).
.TP
|
[-]
[+]
|
Changed |
getmail-4.43.0.tar.bz2/getmail
^
|
@@ -106,7 +106,7 @@
'GNU GPL version 2.\n')
#######################################
-def go(configs):
+def go(configs, idle):
"""Main code.
Returns True if all goes well, False if any error condition occurs.
@@ -114,7 +114,27 @@
blurb()
summary = []
errorexit = False
+ idling = False
+
+ if len(configs) > 1 and idle:
+ log.info('more than one config file given with --idle, ignoring\n')
+ idle = False
+
for (configfile, retriever, _filters, destination, options) in configs:
+ if options['read_all'] and not options['delete']:
+ if idle:
+ # This is a nonsense combination of options; every time the
+ # server returns from IDLE, all messages will be re-retrieved.
+ log.error('%s: IDLE, read_all, and not delete - bad '
+ 'combination, skipping\n'
+ % retriever)
+ continue
+ else:
+ # Slightly less nonsensical, but still weird.
+ log.warning('%s: read_all and not delete -- all messages will '
+ 'be retrieved each time getmail is run\n'
+ % retriever)
+
oplevel = options['verbose']
logverbose = options['message_log_verbose']
now = int(time.time())
@@ -124,14 +144,16 @@
if options['message_log_syslog']:
syslog.openlog('getmail', 0, syslog.LOG_MAIL)
try:
- log.info('%s:\n' % retriever)
- logline = 'Initializing %s:' % retriever
- if options['logfile'] and logverbose:
- options['logfile'].write(logline)
- if options['message_log_syslog'] and logverbose:
- syslog.syslog(syslog.LOG_INFO, logline)
- retriever.initialize(options)
- destination.retriever_info(retriever)
+ if not idling:
+ log.info('%s:\n' % retriever)
+ logline = 'Initializing %s:' % retriever
+ if options['logfile'] and logverbose:
+ options['logfile'].write(logline)
+ if options['message_log_syslog'] and logverbose:
+ syslog.syslog(syslog.LOG_INFO, logline)
+ retriever.initialize(options)
+ destination.retriever_info(retriever)
+
for mailbox in retriever.mailboxes:
if mailbox:
# For POP this is None and uninteresting
@@ -370,6 +392,39 @@
)
log.debug('retriever %s finished\n' % retriever)
try:
+ if idle and not retriever.supports_idle:
+ log.info('--idle given, but chosen retriever does not support'
+ 'IDLE\n')
+ idle = False
+
+ if not errorexit and idle:
+ # TODO
+ # Okay, so what should really happen here is that when go_idle
+ # returns, getmail should use the *existing* connection to check
+ # for new messages and then call go_idle again once that is
+ # done. The current code layout doesn't lend itself very well to
+ # that since the message download code is coupled with the
+ # connection setup/teardown code.
+ #
+ # Therefore, we do a bit of a hack.
+ # We add the current config back into configs, so that when the
+ # main for loop over configs runs again, it will find the same
+ # config again, and thus download the new messages and then go
+ # back to IDLEing. Since the return value of go_idle changes the
+ # value of idling, a failed connection will cause it to become
+ # False, which will make the main go() loop reconnect, which is
+ # what we want.
+ try:
+ idling = retriever.go_idle(idle)
+ configs.append(configs[0])
+ continue
+ except KeyboardInterrupt, o:
+ # Because configs isn't appended to, this just means we'll
+ # quit, which is presumably what the user wanted
+ # The newline is to clear the ^C shown in terminal
+ log.info('\n')
+ pass
+
retriever.quit()
except getmailOperationError, o:
errorexit = True
@@ -413,6 +468,14 @@
dest='trace', action='store_true', default=False,
help='print extended trace information (extremely verbose)'
)
+ parser.add_option(
+ '-i', '--idle',
+ dest='idle', action='store', default='',
+ help='maintain connection and listen for new messages in FOLDER. '
+ 'Only applies if a single rc file is given with a connection '
+ 'to an IMAP server that supports the IDLE command',
+ metavar='FOLDER'
+ )
if gnomekeyring:
parser.add_option(
'--store-password-in-gnome-keyring',
@@ -786,7 +849,7 @@
sys.exit()
# Go!
- success = go(configs)
+ success = go(configs, options.idle)
if not success:
raise SystemExit(127)
|
[-]
[+]
|
Changed |
getmail-4.43.0.tar.bz2/getmail.spec
^
|
@@ -2,7 +2,7 @@
Summary: POP3 mail retriever with reliable Maildir delivery
Name: getmail
-Version: 4.42.0
+Version: 4.43.0
Release: 1
License: GPL
Group: Applications/Internet
@@ -52,6 +52,12 @@
%{python_sitelib}/getmailcore/
%changelog
+* Sun Aug 25 2013 Charles Cazabon <charlesc-getmail-rpm@pyropus.ca>
+-update to version 4.43.0
+
+* Sun Aug 25 2013 Charles Cazabon <charlesc-getmail-rpm@pyropus.ca>
+-update to version 4.43.0
+
* Sat Aug 03 2013 Charles Cazabon <charlesc-getmail-rpm@pyropus.ca>
-update to version 4.42.0
|
[-]
[+]
|
Changed |
getmail-4.43.0.tar.bz2/getmailcore/__init__.py
^
|
@@ -16,7 +16,7 @@
raise ImportError('getmail version 4 requires Python version 2.3.3'
' or later')
-__version__ = '4.42.0'
+__version__ = '4.43.0'
__all__ = [
'baseclasses',
|
[-]
[+]
|
Changed |
getmail-4.43.0.tar.bz2/getmailcore/_retrieverbases.py
^
|
@@ -42,6 +42,7 @@
import poplib
import imaplib
import re
+import select
try:
# do we have a recent pykerberos?
@@ -119,6 +120,7 @@
class POP3initMixIn(object):
'''Mix-In class to do POP3 non-SSL initialization.
'''
+ SSL = False
def _connect(self):
self.log.trace()
try:
@@ -144,6 +146,7 @@
'''Mix-In class to do POP3 over SSL initialization with Python 2.4's
poplib.POP3_SSL class.
'''
+ SSL = True
def _connect(self):
self.log.trace()
if not hasattr(socket, 'ssl'):
@@ -191,6 +194,7 @@
'''Mix-In class to do POP3 over SSL initialization with custom-implemented
code to support SSL with Python 2.3's poplib.POP3 class.
'''
+ SSL = True
def _connect(self):
self.log.trace()
if not hasattr(socket, 'ssl'):
@@ -237,6 +241,7 @@
class IMAPinitMixIn(object):
'''Mix-In class to do IMAP non-SSL initialization.
'''
+ SSL = False
def _connect(self):
self.log.trace()
try:
@@ -259,6 +264,7 @@
class IMAPSSLinitMixIn(object):
'''Mix-In class to do IMAP over SSL initialization.
'''
+ SSL = True
def _connect(self):
self.log.trace()
if not hasattr(socket, 'ssl'):
@@ -372,7 +378,6 @@
initialize(self, options)
checkconf(self)
'''
-
def __init__(self, **args):
self.headercache = {}
self.deleted = {}
@@ -382,6 +387,7 @@
self.gotmsglist = False
self._clear_state()
self.conn = None
+ self.supports_idle = False
ConfigurableBase.__init__(self, **args)
def _clear_state(self):
@@ -1275,7 +1281,11 @@
+ os.linesep)
del self.oldmail[msgid]
"""
-
+
+ if 'IDLE' in self.conn.capabilities:
+ self.supports_idle = True
+ imaplib.Commands['IDLE'] = ('AUTH', 'SELECTED')
+
if self.mailboxes == ('ALL', ):
# Special value meaning all mailboxes in account
self.mailboxes = tuple(self.list_mailboxes())
@@ -1294,6 +1304,72 @@
pass
self.conn = None
+ def go_idle(self, folder, timeout=29*60):
+ """Initiates IMAP's IDLE mode if the server supports it
+
+ Waits until state of current mailbox changes, and then returns. Returns
+ True if the connection still seems to be up, False otherwise.
+
+ May throw getmailOperationError if the server refuses the IDLE setup
+ (e.g. if the server does not support IDLE)
+
+ Default timeout is the maximum possible idle time according to RFC 2177.
+ """
+
+ if not self.supports_idle:
+ self.log.warning('IDLE not supported, so not idling')
+ raise getmailOperationError(
+ 'IMAP4 IDLE requested, but not supported by server'
+ )
+
+
+ if self.SSL:
+ sock = self.conn.ssl()
+ else:
+ sock = self.conn.socket()
+
+ # Based on current imaplib IDLE patch: http://bugs.python.org/issue11245
+ self.conn.untagged_responses = {}
+ self.conn.select(folder)
+ tag = self.conn._command('IDLE')
+ data = self.conn._get_response() # read continuation response
+
+ if data is not None:
+ raise getmailOperationError(
+ 'IMAP4 IDLE requested, but server refused IDLE request: %s'
+ % data
+ )
+
+ self.log.debug('Entering IDLE mode (server says "%s")\n'
+ % self.conn.continuation_response)
+
+ try:
+ aborted = None
+ (readable, unused, unused) = select.select([sock], [], [], timeout)
+ except KeyboardInterrupt, o:
+ # Delay raising this until we've stopped IDLE mode
+ aborted = o
+
+ if aborted is not None:
+ self.log.debug('IDLE mode cancelled\n')
+ elif readable:
+ # The socket has data waiting; server has updated status
+ self.log.info('IDLE message received\n')
+ else:
+ self.log.debug('IDLE timeout (%ds)\n' % timeout)
+
+ try:
+ self.conn.untagged_responses = {}
+ self.conn.send('DONE\r\n')
+ self.conn._command_complete('IDLE', tag)
+ except imaplib.IMAP4.error, o:
+ return False
+
+ if aborted:
+ raise aborted
+
+ return True
+
def quit(self):
self.log.trace()
if not self.conn:
|