Reformat offlineimap/bundled_imaplib2.py

Add/remove whitespaces, lines,...
This commit is contained in:
Rodolfo García Peñas (kix) 2020-08-30 10:47:34 +02:00
parent e77440552c
commit 3fafc3a46d

View File

@ -13,7 +13,6 @@ Public functions: Internaldate2Time
Time2Internaldate Time2Internaldate
""" """
__all__ = ("IMAP4", "IMAP4_SSL", "IMAP4_stream", __all__ = ("IMAP4", "IMAP4_SSL", "IMAP4_stream",
"Internaldate2Time", "ParseFlags", "Time2Internaldate", "Internaldate2Time", "ParseFlags", "Time2Internaldate",
"MonthNames", "InternalDate") "MonthNames", "InternalDate")
@ -138,12 +137,12 @@ UID_direct = ('SEARCH', 'SORT', 'THREAD')
def Int2AP(num): def Int2AP(num):
"""string = Int2AP(num) """string = Int2AP(num)
Return 'num' converted to bytes using characters from the set 'A'..'P' Return 'num' converted to bytes using characters from the set 'A'..'P'
""" """
val = b''; AP = b'ABCDEFGHIJKLMNOP' val = b'';
AP = b'ABCDEFGHIJKLMNOP'
num = int(abs(num)) num = int(abs(num))
while num: while num:
num, mod = divmod(num, 16) num, mod = divmod(num, 16)
@ -151,9 +150,7 @@ def Int2AP(num):
return val return val
class Request(object): class Request(object):
"""Private class to represent a request awaiting response.""" """Private class to represent a request awaiting response."""
def __init__(self, parent, name=None, callback=None, cb_arg=None, cb_self=False): def __init__(self, parent, name=None, callback=None, cb_arg=None, cb_self=False):
@ -173,12 +170,10 @@ class Request(object):
self.aborted = None self.aborted = None
self.data = None self.data = None
def abort(self, typ, val): def abort(self, typ, val):
self.aborted = (typ, val) self.aborted = (typ, val)
self.deliver(None) self.deliver(None)
def get_response(self, exc_fmt=None): def get_response(self, exc_fmt=None):
self.callback = None self.callback = None
if __debug__: self.parent._log(3, '%s:%s.ready.wait' % (self.name, self.tag)) if __debug__: self.parent._log(3, '%s:%s.ready.wait' % (self.name, self.tag))
@ -192,7 +187,6 @@ class Request(object):
return self.response return self.response
def deliver(self, response): def deliver(self, response):
if self.callback is not None: if self.callback is not None:
self.callback((response, self.callback_arg, self.aborted)) self.callback((response, self.callback_arg, self.aborted))
@ -203,10 +197,7 @@ class Request(object):
if __debug__: self.parent._log(3, '%s:%s.ready.set' % (self.name, self.tag)) if __debug__: self.parent._log(3, '%s:%s.ready.set' % (self.name, self.tag))
class IMAP4(object): class IMAP4(object):
"""Threaded IMAP4 client class. """Threaded IMAP4 client class.
Instantiate with: Instantiate with:
@ -276,9 +267,14 @@ class IMAP4(object):
discarding an instance. discarding an instance.
""" """
class error(Exception): pass # Logical errors - debug required class error(Exception):
class abort(error): pass # Service errors - close and retry pass # Logical errors - debug required
class readonly(abort): pass # Mailbox status changed to READ-ONLY
class abort(error):
pass # Service errors - close and retry
class readonly(abort):
pass # Mailbox status changed to READ-ONLY
# These must be encoded according to utf8 setting in _mode_xxx(): # These must be encoded according to utf8 setting in _mode_xxx():
_literal = br'.*{(?P<size>\d+)}$' _literal = br'.*{(?P<size>\d+)}$'
@ -289,8 +285,8 @@ class IMAP4(object):
response_code_cre = re.compile(br'\[(?P<type>[A-Z-]+)( (?P<data>[^\]]*))?\]') response_code_cre = re.compile(br'\[(?P<type>[A-Z-]+)( (?P<data>[^\]]*))?\]')
untagged_response_cre = re.compile(br'\* (?P<type>[A-Z-]+)( (?P<data>.*))?') untagged_response_cre = re.compile(br'\* (?P<type>[A-Z-]+)( (?P<data>.*))?')
def __init__(self, host=None, port=None, debug=None, debug_file=None, identifier=None, timeout=None,
def __init__(self, host=None, port=None, debug=None, debug_file=None, identifier=None, timeout=None, debug_buf_lvl=None): debug_buf_lvl=None):
self.state = NONAUTH # IMAP4 protocol state self.state = NONAUTH # IMAP4 protocol state
self.literal = None # A literal argument to a command self.literal = None # A literal argument to a command
@ -372,7 +368,8 @@ class IMAP4(object):
# request and store CAPABILITY response. # request and store CAPABILITY response.
try: try:
self.welcome = self._request_push(name='welcome', tag='continuation').get_response('IMAP4 protocol error: %s')[1] self.welcome = \
self._request_push(name='welcome', tag='continuation').get_response('IMAP4 protocol error: %s')[1]
if self._get_untagged_response('PREAUTH'): if self._get_untagged_response('PREAUTH'):
self.state = AUTH self.state = AUTH
@ -396,14 +393,12 @@ class IMAP4(object):
self._close_threads() self._close_threads()
raise raise
def __getattr__(self, attr): def __getattr__(self, attr):
# Allow UPPERCASE variants of IMAP4 command methods. # Allow UPPERCASE variants of IMAP4 command methods.
if attr in Commands: if attr in Commands:
return getattr(self, attr.lower()) return getattr(self, attr.lower())
raise AttributeError("Unknown IMAP4 command: '%s'" % attr) raise AttributeError("Unknown IMAP4 command: '%s'" % attr)
def __enter__(self): def __enter__(self):
return self return self
@ -413,25 +408,20 @@ class IMAP4(object):
except OSError: except OSError:
pass pass
def _mode_ascii(self): def _mode_ascii(self):
self.utf8_enabled = False self.utf8_enabled = False
self._encoding = 'ascii' self._encoding = 'ascii'
self.literal_cre = re.compile(self._literal, re.ASCII) self.literal_cre = re.compile(self._literal, re.ASCII)
self.untagged_status_cre = re.compile(self._untagged_status, re.ASCII) self.untagged_status_cre = re.compile(self._untagged_status, re.ASCII)
def _mode_utf8(self): def _mode_utf8(self):
self.utf8_enabled = True self.utf8_enabled = True
self._encoding = 'utf-8' self._encoding = 'utf-8'
self.literal_cre = re.compile(self._literal) self.literal_cre = re.compile(self._literal)
self.untagged_status_cre = re.compile(self._untagged_status) self.untagged_status_cre = re.compile(self._untagged_status)
# Overridable methods # Overridable methods
def open(self, host=None, port=None): def open(self, host=None, port=None):
"""open(host=None, port=None) """open(host=None, port=None)
Setup connection to remote server on "host:port" Setup connection to remote server on "host:port"
@ -444,14 +434,12 @@ class IMAP4(object):
self.sock = self.open_socket() self.sock = self.open_socket()
self.read_fd = self.sock.fileno() self.read_fd = self.sock.fileno()
def open_socket(self): def open_socket(self):
"""open_socket() """open_socket()
Open socket choosing first address family available.""" Open socket choosing first address family available."""
return socket.create_connection((self.host, self.port)) return socket.create_connection((self.host, self.port))
def ssl_wrap_socket(self): def ssl_wrap_socket(self):
try: try:
@ -488,7 +476,8 @@ class IMAP4(object):
raise RuntimeError("unknown tls_level: %s" % self.tls_level) raise RuntimeError("unknown tls_level: %s" % self.tls_level)
if self.ssl_version not in TLS_MAP[self.tls_level]: if self.ssl_version not in TLS_MAP[self.tls_level]:
raise socket.sslerror("Invalid SSL version '%s' requested for tls_version '%s'" % (self.ssl_version, self.tls_level)) raise socket.sslerror(
"Invalid SSL version '%s' requested for tls_version '%s'" % (self.ssl_version, self.tls_level))
ssl_version = TLS_MAP[self.tls_level][self.ssl_version] ssl_version = TLS_MAP[self.tls_level][self.ssl_version]
@ -501,7 +490,8 @@ class IMAP4(object):
ctx.load_cert_chain(self.certfile, self.keyfile) ctx.load_cert_chain(self.certfile, self.keyfile)
self.sock = ctx.wrap_socket(self.sock, server_hostname=self.host) self.sock = ctx.wrap_socket(self.sock, server_hostname=self.host)
else: else:
self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, ca_certs=self.ca_certs, cert_reqs=cert_reqs, ssl_version=ssl_version) self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, ca_certs=self.ca_certs,
cert_reqs=cert_reqs, ssl_version=ssl_version)
ssl_exc = ssl.SSLError ssl_exc = ssl.SSLError
self.read_fd = self.sock.fileno() self.read_fd = self.sock.fileno()
@ -518,8 +508,6 @@ class IMAP4(object):
# from closing SSL, leading to deadlocks. # from closing SSL, leading to deadlocks.
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
def start_compressing(self): def start_compressing(self):
"""start_compressing() """start_compressing()
Enable deflate compression on the socket (RFC 4978).""" Enable deflate compression on the socket (RFC 4978)."""
@ -528,7 +516,6 @@ class IMAP4(object):
self.decompressor = zlib.decompressobj(-15) self.decompressor = zlib.decompressobj(-15)
self.compressor = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, -15) self.compressor = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, -15)
def read(self, size): def read(self, size):
"""data = read(size) """data = read(size)
Read at most 'size' bytes from remote.""" Read at most 'size' bytes from remote."""
@ -543,7 +530,6 @@ class IMAP4(object):
return self.decompressor.decompress(data, size) return self.decompressor.decompress(data, size)
def send(self, data): def send(self, data):
"""send(data) """send(data)
Send 'data' to remote.""" Send 'data' to remote."""
@ -554,7 +540,6 @@ class IMAP4(object):
self.sock.sendall(data) self.sock.sendall(data)
def shutdown(self): def shutdown(self):
"""shutdown() """shutdown()
Close I/O established in "open".""" Close I/O established in "open"."""
@ -568,18 +553,14 @@ class IMAP4(object):
finally: finally:
self.sock.close() self.sock.close()
def socket(self): def socket(self):
"""socket = socket() """socket = socket()
Return socket instance used to connect to IMAP4 server.""" Return socket instance used to connect to IMAP4 server."""
return self.sock return self.sock
# Utility methods # Utility methods
def enable_compression(self): def enable_compression(self):
"""enable_compression() """enable_compression()
Ask the server to start compressing the connection. Ask the server to start compressing the connection.
@ -595,7 +576,6 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
def pop_untagged_responses(self): def pop_untagged_responses(self):
""" for typ,data in pop_untagged_responses(): pass """ for typ,data in pop_untagged_responses(): pass
Generator for any remaining untagged responses. Generator for any remaining untagged responses.
@ -609,7 +589,6 @@ class IMAP4(object):
finally: finally:
self.commands_lock.release() self.commands_lock.release()
def recent(self, **kw): def recent(self, **kw):
"""(typ, [data]) = recent() """(typ, [data]) = recent()
Return 'RECENT' responses if any exist, Return 'RECENT' responses if any exist,
@ -624,7 +603,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self.noop(**kw) # Prod server for response return self.noop(**kw) # Prod server for response
def response(self, code, **kw): def response(self, code, **kw):
"""(code, [data]) = response(code) """(code, [data]) = response(code)
Return data for response 'code' if received, or None. Return data for response 'code' if received, or None.
@ -633,12 +611,8 @@ class IMAP4(object):
typ, dat = self._untagged_response(code, [None], code.upper()) typ, dat = self._untagged_response(code, [None], code.upper())
return self._deliver_dat(typ, dat, kw) return self._deliver_dat(typ, dat, kw)
# IMAP4 commands # IMAP4 commands
def append(self, mailbox, flags, date_time, message, **kw): def append(self, mailbox, flags, date_time, message, **kw):
"""(typ, [data]) = append(mailbox, flags, date_time, message) """(typ, [data]) = append(mailbox, flags, date_time, message)
Append message to named mailbox. Append message to named mailbox.
@ -667,7 +641,6 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
def authenticate(self, mechanism, authobject, **kw): def authenticate(self, mechanism, authobject, **kw):
"""(typ, [data]) = authenticate(mechanism, authobject) """(typ, [data]) = authenticate(mechanism, authobject)
Authenticate command - requires response processing. Authenticate command - requires response processing.
@ -697,7 +670,6 @@ class IMAP4(object):
self._release_state_change() self._release_state_change()
return self._deliver_dat(typ, dat, kw) return self._deliver_dat(typ, dat, kw)
def capability(self, **kw): def capability(self, **kw):
"""(typ, [data]) = capability() """(typ, [data]) = capability()
Fetch capabilities list from server.""" Fetch capabilities list from server."""
@ -706,14 +678,12 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, **kw) return self._simple_command(name, **kw)
def check(self, **kw): def check(self, **kw):
"""(typ, [data]) = check() """(typ, [data]) = check()
Checkpoint mailbox on server.""" Checkpoint mailbox on server."""
return self._simple_command('CHECK', **kw) return self._simple_command('CHECK', **kw)
def close(self, **kw): def close(self, **kw):
"""(typ, [data]) = close() """(typ, [data]) = close()
Close currently selected mailbox. Close currently selected mailbox.
@ -731,35 +701,30 @@ class IMAP4(object):
self._release_state_change() self._release_state_change()
return self._deliver_dat(typ, dat, kw) return self._deliver_dat(typ, dat, kw)
def copy(self, message_set, new_mailbox, **kw): def copy(self, message_set, new_mailbox, **kw):
"""(typ, [data]) = copy(message_set, new_mailbox) """(typ, [data]) = copy(message_set, new_mailbox)
Copy 'message_set' messages onto end of 'new_mailbox'.""" Copy 'message_set' messages onto end of 'new_mailbox'."""
return self._simple_command('COPY', message_set, new_mailbox, **kw) return self._simple_command('COPY', message_set, new_mailbox, **kw)
def create(self, mailbox, **kw): def create(self, mailbox, **kw):
"""(typ, [data]) = create(mailbox) """(typ, [data]) = create(mailbox)
Create new mailbox.""" Create new mailbox."""
return self._simple_command('CREATE', mailbox, **kw) return self._simple_command('CREATE', mailbox, **kw)
def delete(self, mailbox, **kw): def delete(self, mailbox, **kw):
"""(typ, [data]) = delete(mailbox) """(typ, [data]) = delete(mailbox)
Delete old mailbox.""" Delete old mailbox."""
return self._simple_command('DELETE', mailbox, **kw) return self._simple_command('DELETE', mailbox, **kw)
def deleteacl(self, mailbox, who, **kw): def deleteacl(self, mailbox, who, **kw):
"""(typ, [data]) = deleteacl(mailbox, who) """(typ, [data]) = deleteacl(mailbox, who)
Delete the ACLs (remove any rights) set for who on mailbox.""" Delete the ACLs (remove any rights) set for who on mailbox."""
return self._simple_command('DELETEACL', mailbox, who, **kw) return self._simple_command('DELETEACL', mailbox, who, **kw)
def enable(self, capability): def enable(self, capability):
"""Send an RFC5161 enable string to the server. """Send an RFC5161 enable string to the server.
@ -772,7 +737,6 @@ class IMAP4(object):
self._mode_utf8() self._mode_utf8()
return typ, data return typ, data
def examine(self, mailbox='INBOX', **kw): def examine(self, mailbox='INBOX', **kw):
"""(typ, [data]) = examine(mailbox='INBOX') """(typ, [data]) = examine(mailbox='INBOX')
Select a mailbox for READ-ONLY access. (Flushes all untagged responses.) Select a mailbox for READ-ONLY access. (Flushes all untagged responses.)
@ -782,7 +746,6 @@ class IMAP4(object):
return self.select(mailbox=mailbox, readonly=True, **kw) return self.select(mailbox=mailbox, readonly=True, **kw)
def expunge(self, **kw): def expunge(self, **kw):
"""(typ, [data]) = expunge() """(typ, [data]) = expunge()
Permanently remove deleted items from selected mailbox. Permanently remove deleted items from selected mailbox.
@ -793,7 +756,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, **kw) return self._simple_command(name, **kw)
def fetch(self, message_set, message_parts, **kw): def fetch(self, message_set, message_parts, **kw):
"""(typ, [data, ...]) = fetch(message_set, message_parts) """(typ, [data, ...]) = fetch(message_set, message_parts)
Fetch (parts of) messages. Fetch (parts of) messages.
@ -806,7 +768,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, message_set, message_parts, **kw) return self._simple_command(name, message_set, message_parts, **kw)
def getacl(self, mailbox, **kw): def getacl(self, mailbox, **kw):
"""(typ, [data]) = getacl(mailbox) """(typ, [data]) = getacl(mailbox)
Get the ACLs for a mailbox.""" Get the ACLs for a mailbox."""
@ -814,7 +775,6 @@ class IMAP4(object):
kw['untagged_response'] = 'ACL' kw['untagged_response'] = 'ACL'
return self._simple_command('GETACL', mailbox, **kw) return self._simple_command('GETACL', mailbox, **kw)
def getannotation(self, mailbox, entry, attribute, **kw): def getannotation(self, mailbox, entry, attribute, **kw):
"""(typ, [data]) = getannotation(mailbox, entry, attribute) """(typ, [data]) = getannotation(mailbox, entry, attribute)
Retrieve ANNOTATIONs.""" Retrieve ANNOTATIONs."""
@ -822,7 +782,6 @@ class IMAP4(object):
kw['untagged_response'] = 'ANNOTATION' kw['untagged_response'] = 'ANNOTATION'
return self._simple_command('GETANNOTATION', mailbox, entry, attribute, **kw) return self._simple_command('GETANNOTATION', mailbox, entry, attribute, **kw)
def getquota(self, root, **kw): def getquota(self, root, **kw):
"""(typ, [data]) = getquota(root) """(typ, [data]) = getquota(root)
Get the quota root's resource usage and limits. Get the quota root's resource usage and limits.
@ -831,7 +790,6 @@ class IMAP4(object):
kw['untagged_response'] = 'QUOTA' kw['untagged_response'] = 'QUOTA'
return self._simple_command('GETQUOTA', root, **kw) return self._simple_command('GETQUOTA', root, **kw)
def getquotaroot(self, mailbox, **kw): def getquotaroot(self, mailbox, **kw):
# Hmmm, this is non-std! Left for backwards-compatibility, sigh. # Hmmm, this is non-std! Left for backwards-compatibility, sigh.
# NB: usage should have been defined as: # NB: usage should have been defined as:
@ -845,7 +803,6 @@ class IMAP4(object):
typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT') typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT')
return self._deliver_dat(typ, [quotaroot, quota], kw) return self._deliver_dat(typ, [quotaroot, quota], kw)
def id(self, *kv_pairs, **kw): def id(self, *kv_pairs, **kw):
"""(typ, [data]) = <instance>.id(kv_pairs) """(typ, [data]) = <instance>.id(kv_pairs)
'kv_pairs' is a possibly empty list of keys and values. 'kv_pairs' is a possibly empty list of keys and values.
@ -867,7 +824,6 @@ class IMAP4(object):
return self._simple_command(name, data, **kw) return self._simple_command(name, data, **kw)
def idle(self, timeout=None, **kw): def idle(self, timeout=None, **kw):
""""(typ, [data]) = idle(timeout=None) """"(typ, [data]) = idle(timeout=None)
Put server into IDLE mode until server notifies some change, Put server into IDLE mode until server notifies some change,
@ -881,7 +837,6 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
def list(self, directory='""', pattern='*', **kw): def list(self, directory='""', pattern='*', **kw):
"""(typ, [data]) = list(directory='""', pattern='*') """(typ, [data]) = list(directory='""', pattern='*')
List mailbox names in directory matching pattern. List mailbox names in directory matching pattern.
@ -895,7 +850,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, directory, pattern, **kw) return self._simple_command(name, directory, pattern, **kw)
def login(self, user, password, **kw): def login(self, user, password, **kw):
"""(typ, [data]) = login(user, password) """(typ, [data]) = login(user, password)
Identify client using plaintext password. Identify client using plaintext password.
@ -911,7 +865,6 @@ class IMAP4(object):
self._release_state_change() self._release_state_change()
return self._deliver_dat(typ, dat, kw) return self._deliver_dat(typ, dat, kw)
def login_cram_md5(self, user, password, **kw): def login_cram_md5(self, user, password, **kw):
"""(typ, [data]) = login_cram_md5(user, password) """(typ, [data]) = login_cram_md5(user, password)
Force use of CRAM-MD5 authentication.""" Force use of CRAM-MD5 authentication."""
@ -919,7 +872,6 @@ class IMAP4(object):
self.user, self.password = user, password self.user, self.password = user, password
return self.authenticate('CRAM-MD5', self._CRAM_MD5_AUTH, **kw) return self.authenticate('CRAM-MD5', self._CRAM_MD5_AUTH, **kw)
def _CRAM_MD5_AUTH(self, challenge): def _CRAM_MD5_AUTH(self, challenge):
"""Authobject to use with CRAM-MD5 authentication.""" """Authobject to use with CRAM-MD5 authentication."""
import hmac import hmac
@ -927,7 +879,6 @@ class IMAP4(object):
else self.password) else self.password)
return self.user + " " + hmac.HMAC(pwd, challenge, 'md5').hexdigest() return self.user + " " + hmac.HMAC(pwd, challenge, 'md5').hexdigest()
def logout(self, **kw): def logout(self, **kw):
"""(typ, [data]) = logout() """(typ, [data]) = logout()
Shutdown connection to server. Shutdown connection to server.
@ -955,7 +906,6 @@ class IMAP4(object):
typ, dat = 'BYE', bye typ, dat = 'BYE', bye
return self._deliver_dat(typ, dat, kw) return self._deliver_dat(typ, dat, kw)
def lsub(self, directory='""', pattern='*', **kw): def lsub(self, directory='""', pattern='*', **kw):
"""(typ, [data, ...]) = lsub(directory='""', pattern='*') """(typ, [data, ...]) = lsub(directory='""', pattern='*')
List 'subscribed' mailbox names in directory matching pattern. List 'subscribed' mailbox names in directory matching pattern.
@ -965,7 +915,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, directory, pattern, **kw) return self._simple_command(name, directory, pattern, **kw)
def myrights(self, mailbox, **kw): def myrights(self, mailbox, **kw):
"""(typ, [data]) = myrights(mailbox) """(typ, [data]) = myrights(mailbox)
Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).""" Show my ACLs for a mailbox (i.e. the rights that I have on mailbox)."""
@ -974,7 +923,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, mailbox, **kw) return self._simple_command(name, mailbox, **kw)
def namespace(self, **kw): def namespace(self, **kw):
"""(typ, [data, ...]) = namespace() """(typ, [data, ...]) = namespace()
Returns IMAP namespaces ala rfc2342.""" Returns IMAP namespaces ala rfc2342."""
@ -983,7 +931,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, **kw) return self._simple_command(name, **kw)
def noop(self, **kw): def noop(self, **kw):
"""(typ, [data]) = noop() """(typ, [data]) = noop()
Send NOOP command.""" Send NOOP command."""
@ -991,7 +938,6 @@ class IMAP4(object):
if __debug__: self._dump_ur(3) if __debug__: self._dump_ur(3)
return self._simple_command('NOOP', **kw) return self._simple_command('NOOP', **kw)
def partial(self, message_num, message_part, start, length, **kw): def partial(self, message_num, message_part, start, length, **kw):
"""(typ, [data, ...]) = partial(message_num, message_part, start, length) """(typ, [data, ...]) = partial(message_num, message_part, start, length)
Fetch truncated part of a message. Fetch truncated part of a message.
@ -1002,7 +948,6 @@ class IMAP4(object):
kw['untagged_response'] = 'FETCH' kw['untagged_response'] = 'FETCH'
return self._simple_command(name, message_num, message_part, start, length, **kw) return self._simple_command(name, message_num, message_part, start, length, **kw)
def proxyauth(self, user, **kw): def proxyauth(self, user, **kw):
"""(typ, [data]) = proxyauth(user) """(typ, [data]) = proxyauth(user)
Assume authentication as 'user'. Assume authentication as 'user'.
@ -1013,14 +958,12 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
def rename(self, oldmailbox, newmailbox, **kw): def rename(self, oldmailbox, newmailbox, **kw):
"""(typ, [data]) = rename(oldmailbox, newmailbox) """(typ, [data]) = rename(oldmailbox, newmailbox)
Rename old mailbox name to new.""" Rename old mailbox name to new."""
return self._simple_command('RENAME', oldmailbox, newmailbox, **kw) return self._simple_command('RENAME', oldmailbox, newmailbox, **kw)
def search(self, charset, *criteria, **kw): def search(self, charset, *criteria, **kw):
"""(typ, [data]) = search(charset, criterion, ...) """(typ, [data]) = search(charset, criterion, ...)
Search mailbox for matching messages. Search mailbox for matching messages.
@ -1035,7 +978,6 @@ class IMAP4(object):
return self._simple_command(name, 'CHARSET', charset, *criteria, **kw) return self._simple_command(name, 'CHARSET', charset, *criteria, **kw)
return self._simple_command(name, *criteria, **kw) return self._simple_command(name, *criteria, **kw)
def select(self, mailbox='INBOX', readonly=False, **kw): def select(self, mailbox='INBOX', readonly=False, **kw):
"""(typ, [data]) = select(mailbox='INBOX', readonly=False) """(typ, [data]) = select(mailbox='INBOX', readonly=False)
Select a mailbox. (Flushes all untagged responses.) Select a mailbox. (Flushes all untagged responses.)
@ -1058,7 +1000,8 @@ class IMAP4(object):
self.state = AUTH self.state = AUTH
if __debug__: self._log(1, 'state => AUTH') if __debug__: self._log(1, 'state => AUTH')
if typ == 'BAD': if typ == 'BAD':
self._deliver_exc(self.error, '%s command error: %s %s. Data: %.100s' % (name, typ, dat, mailbox), kw) self._deliver_exc(self.error, '%s command error: %s %s. Data: %.100s' % (name, typ, dat, mailbox),
kw)
return self._deliver_dat(typ, dat, kw) return self._deliver_dat(typ, dat, kw)
self.state = SELECTED self.state = SELECTED
if __debug__: self._log(1, 'state => SELECTED') if __debug__: self._log(1, 'state => SELECTED')
@ -1071,7 +1014,6 @@ class IMAP4(object):
typ, dat = self._untagged_response(typ, [None], 'EXISTS') typ, dat = self._untagged_response(typ, [None], 'EXISTS')
return self._deliver_dat(typ, dat, kw) return self._deliver_dat(typ, dat, kw)
def setacl(self, mailbox, who, what, **kw): def setacl(self, mailbox, who, what, **kw):
"""(typ, [data]) = setacl(mailbox, who, what) """(typ, [data]) = setacl(mailbox, who, what)
Set a mailbox acl.""" Set a mailbox acl."""
@ -1081,7 +1023,6 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
def setannotation(self, *args, **kw): def setannotation(self, *args, **kw):
"""(typ, [data]) = setannotation(mailbox[, entry, attribute]+) """(typ, [data]) = setannotation(mailbox[, entry, attribute]+)
Set ANNOTATIONs.""" Set ANNOTATIONs."""
@ -1089,7 +1030,6 @@ class IMAP4(object):
kw['untagged_response'] = 'ANNOTATION' kw['untagged_response'] = 'ANNOTATION'
return self._simple_command('SETANNOTATION', *args, **kw) return self._simple_command('SETANNOTATION', *args, **kw)
def setquota(self, root, limits, **kw): def setquota(self, root, limits, **kw):
"""(typ, [data]) = setquota(root, limits) """(typ, [data]) = setquota(root, limits)
Set the quota root's resource limits.""" Set the quota root's resource limits."""
@ -1100,7 +1040,6 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
def sort(self, sort_criteria, charset, *search_criteria, **kw): def sort(self, sort_criteria, charset, *search_criteria, **kw):
"""(typ, [data]) = sort(sort_criteria, charset, search_criteria, ...) """(typ, [data]) = sort(sort_criteria, charset, search_criteria, ...)
IMAP4rev1 extension SORT command.""" IMAP4rev1 extension SORT command."""
@ -1111,8 +1050,8 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, sort_criteria, charset, *search_criteria, **kw) return self._simple_command(name, sort_criteria, charset, *search_criteria, **kw)
def starttls(self, keyfile=None, certfile=None, ca_certs=None, cert_verify_cb=None, ssl_version="ssl23",
def starttls(self, keyfile=None, certfile=None, ca_certs=None, cert_verify_cb=None, ssl_version="ssl23", tls_level=TLS_COMPAT, **kw): tls_level=TLS_COMPAT, **kw):
"""(typ, [data]) = starttls(keyfile=None, certfile=None, ca_certs=None, cert_verify_cb=None, ssl_version="ssl23", tls_level="tls_compat") """(typ, [data]) = starttls(keyfile=None, certfile=None, ca_certs=None, cert_verify_cb=None, ssl_version="ssl23", tls_level="tls_compat")
Start TLS negotiation as per RFC 2595.""" Start TLS negotiation as per RFC 2595."""
@ -1166,7 +1105,6 @@ class IMAP4(object):
typ, dat = self._untagged_response(typ, dat, name) typ, dat = self._untagged_response(typ, dat, name)
return self._deliver_dat(typ, dat, kw) return self._deliver_dat(typ, dat, kw)
def status(self, mailbox, names, **kw): def status(self, mailbox, names, **kw):
"""(typ, [data]) = status(mailbox, names) """(typ, [data]) = status(mailbox, names)
Request named status conditions for mailbox.""" Request named status conditions for mailbox."""
@ -1175,7 +1113,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, mailbox, names, **kw) return self._simple_command(name, mailbox, names, **kw)
def store(self, message_set, command, flags, **kw): def store(self, message_set, command, flags, **kw):
"""(typ, [data]) = store(message_set, command, flags) """(typ, [data]) = store(message_set, command, flags)
Alters flag dispositions for messages in mailbox.""" Alters flag dispositions for messages in mailbox."""
@ -1185,7 +1122,6 @@ class IMAP4(object):
kw['untagged_response'] = 'FETCH' kw['untagged_response'] = 'FETCH'
return self._simple_command('STORE', message_set, command, flags, **kw) return self._simple_command('STORE', message_set, command, flags, **kw)
def subscribe(self, mailbox, **kw): def subscribe(self, mailbox, **kw):
"""(typ, [data]) = subscribe(mailbox) """(typ, [data]) = subscribe(mailbox)
Subscribe to new mailbox.""" Subscribe to new mailbox."""
@ -1195,7 +1131,6 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
def thread(self, threading_algorithm, charset, *search_criteria, **kw): def thread(self, threading_algorithm, charset, *search_criteria, **kw):
"""(type, [data]) = thread(threading_alogrithm, charset, search_criteria, ...) """(type, [data]) = thread(threading_alogrithm, charset, search_criteria, ...)
IMAPrev1 extension THREAD command.""" IMAPrev1 extension THREAD command."""
@ -1204,7 +1139,6 @@ class IMAP4(object):
kw['untagged_response'] = name kw['untagged_response'] = name
return self._simple_command(name, threading_algorithm, charset, *search_criteria, **kw) return self._simple_command(name, threading_algorithm, charset, *search_criteria, **kw)
def uid(self, command, *args, **kw): def uid(self, command, *args, **kw):
"""(typ, [data]) = uid(command, arg, ...) """(typ, [data]) = uid(command, arg, ...)
Execute "command arg ..." with messages identified by UID, Execute "command arg ..." with messages identified by UID,
@ -1220,7 +1154,6 @@ class IMAP4(object):
kw['untagged_response'] = resp kw['untagged_response'] = resp
return self._simple_command('UID', command, *args, **kw) return self._simple_command('UID', command, *args, **kw)
def unsubscribe(self, mailbox, **kw): def unsubscribe(self, mailbox, **kw):
"""(typ, [data]) = unsubscribe(mailbox) """(typ, [data]) = unsubscribe(mailbox)
Unsubscribe from old mailbox.""" Unsubscribe from old mailbox."""
@ -1230,7 +1163,6 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
def xatom(self, name, *args, **kw): def xatom(self, name, *args, **kw):
"""(typ, [data]) = xatom(name, arg, ...) """(typ, [data]) = xatom(name, arg, ...)
Allow simple extension commands notified by server in CAPABILITY response. Allow simple extension commands notified by server in CAPABILITY response.
@ -1245,11 +1177,8 @@ class IMAP4(object):
finally: finally:
self._release_state_change() self._release_state_change()
# Internal methods # Internal methods
def _append_untagged(self, typ, dat): def _append_untagged(self, typ, dat):
# Append new 'dat' to end of last untagged response if same 'typ', # Append new 'dat' to end of last untagged response if same 'typ',
@ -1276,14 +1205,12 @@ class IMAP4(object):
if __debug__: self._log(5, 'untagged_responses[%s] %s += ["%.80r"]' % (typ, len(urd) - 1, dat)) if __debug__: self._log(5, 'untagged_responses[%s] %s += ["%.80r"]' % (typ, len(urd) - 1, dat))
def _check_bye(self): def _check_bye(self):
bye = self._get_untagged_response('BYE', leave=True) bye = self._get_untagged_response('BYE', leave=True)
if bye: if bye:
raise self.abort(bye[-1].decode('ASCII', 'replace')) raise self.abort(bye[-1].decode('ASCII', 'replace'))
def _choose_nonull_or_dflt(self, dflt, *args): def _choose_nonull_or_dflt(self, dflt, *args):
if isinstance(dflt, str): if isinstance(dflt, str):
dflttyp = str # Allow any string type dflttyp = str # Allow any string type
@ -1296,7 +1223,6 @@ class IMAP4(object):
if __debug__: self._log(0, 'bad arg is %s, expecting %s' % (type(arg), dflttyp)) if __debug__: self._log(0, 'bad arg is %s, expecting %s' % (type(arg), dflttyp))
return dflt return dflt
def _command(self, name, *args, **kw): def _command(self, name, *args, **kw):
if Commands[name][CMD_VAL_ASYNC]: if Commands[name][CMD_VAL_ASYNC]:
@ -1421,7 +1347,6 @@ class IMAP4(object):
return rqb return rqb
def _command_complete(self, rqb, kw): def _command_complete(self, rqb, kw):
# Called for non-callback commands # Called for non-callback commands
@ -1435,7 +1360,6 @@ class IMAP4(object):
return self._untagged_response(typ, dat, kw['untagged_response']) return self._untagged_response(typ, dat, kw['untagged_response'])
return typ, dat return typ, dat
def _command_completer(self, cb_arg_list): def _command_completer(self, cb_arg_list):
# Called for callback commands # Called for callback commands
@ -1462,21 +1386,18 @@ class IMAP4(object):
response = self._untagged_response(typ, dat, kw['untagged_response']) response = self._untagged_response(typ, dat, kw['untagged_response'])
rqb.deliver(response) rqb.deliver(response)
def _deliver_dat(self, typ, dat, kw): def _deliver_dat(self, typ, dat, kw):
if 'callback' in kw: if 'callback' in kw:
kw['callback'](((typ, dat), kw.get('cb_arg'), None)) kw['callback'](((typ, dat), kw.get('cb_arg'), None))
return typ, dat return typ, dat
def _deliver_exc(self, exc, dat, kw): def _deliver_exc(self, exc, dat, kw):
if 'callback' in kw: if 'callback' in kw:
kw['callback']((None, kw.get('cb_arg'), (exc, dat))) kw['callback']((None, kw.get('cb_arg'), (exc, dat)))
raise exc(dat) raise exc(dat)
def _end_idle(self): def _end_idle(self):
self.idle_lock.acquire() self.idle_lock.acquire()
@ -1491,7 +1412,6 @@ class IMAP4(object):
self.ouq.put(irqb) self.ouq.put(irqb)
if __debug__: self._log(2, 'server IDLE finished') if __debug__: self._log(2, 'server IDLE finished')
def _get_capabilities(self): def _get_capabilities(self):
typ, dat = self.capability() typ, dat = self.capability()
if dat == [None]: if dat == [None]:
@ -1500,7 +1420,6 @@ class IMAP4(object):
dat = dat.upper() dat = dat.upper()
self.capabilities = tuple(dat.split()) self.capabilities = tuple(dat.split())
def _get_untagged_response(self, name, leave=False): def _get_untagged_response(self, name, leave=False):
self.commands_lock.acquire() self.commands_lock.acquire()
@ -1516,7 +1435,6 @@ class IMAP4(object):
self.commands_lock.release() self.commands_lock.release()
return None return None
def _match(self, cre, s): def _match(self, cre, s):
# Run compiled regular expression 'cre' match method on 's'. # Run compiled regular expression 'cre' match method on 's'.
@ -1525,7 +1443,6 @@ class IMAP4(object):
self.mo = cre.match(s) self.mo = cre.match(s)
return self.mo is not None return self.mo is not None
def _put_response(self, resp): def _put_response(self, resp):
if self._expecting_data: if self._expecting_data:
@ -1634,19 +1551,16 @@ class IMAP4(object):
self.Terminate = True self.Terminate = True
if __debug__: self._log(1, '%s response: %r' % (typ, dat)) if __debug__: self._log(1, '%s response: %r' % (typ, dat))
def _quote(self, arg): def _quote(self, arg):
return '"%s"' % arg.replace('\\', '\\\\').replace('"', '\\"') return '"%s"' % arg.replace('\\', '\\\\').replace('"', '\\"')
def _release_state_change(self): def _release_state_change(self):
if self.state_change_pending.locked(): if self.state_change_pending.locked():
self.state_change_pending.release() self.state_change_pending.release()
if __debug__: self._log(3, 'state_change_pending.release') if __debug__: self._log(3, 'state_change_pending.release')
def _request_pop(self, name, data): def _request_pop(self, name, data):
self.commands_lock.acquire() self.commands_lock.acquire()
@ -1664,7 +1578,6 @@ class IMAP4(object):
if __debug__: self._log(3, 'state_change_free.set') if __debug__: self._log(3, 'state_change_free.set')
self.state_change_free.set() self.state_change_free.set()
def _request_push(self, tag=None, name=None, **kw): def _request_push(self, tag=None, name=None, **kw):
self.commands_lock.acquire() self.commands_lock.acquire()
@ -1676,7 +1589,6 @@ class IMAP4(object):
if __debug__: self._log(4, '_request_push(%s, %s, %s) = %s' % (tag, name, repr(kw), rqb.tag)) if __debug__: self._log(4, '_request_push(%s, %s, %s) = %s' % (tag, name, repr(kw), rqb.tag))
return rqb return rqb
def _simple_command(self, name, *args, **kw): def _simple_command(self, name, *args, **kw):
if 'callback' in kw: if 'callback' in kw:
@ -1685,7 +1597,6 @@ class IMAP4(object):
return (None, None) return (None, None)
return self._command_complete(self._command(name, *args), kw) return self._command_complete(self._command(name, *args), kw)
def _untagged_response(self, typ, dat, name): def _untagged_response(self, typ, dat, name):
if typ == 'NO': if typ == 'NO':
@ -1701,11 +1612,8 @@ class IMAP4(object):
if __debug__: self._log(4, '_untagged_response(%s, ?, %s) => %.80r' % (typ, name, data)) if __debug__: self._log(4, '_untagged_response(%s, ?, %s) => %.80r' % (typ, name, data))
return typ, data return typ, data
# Threads # Threads
def _close_threads(self): def _close_threads(self):
if __debug__: self._log(1, '_close_threads') if __debug__: self._log(1, '_close_threads')
@ -1720,7 +1628,6 @@ class IMAP4(object):
self.rdth.join() self.rdth.join()
self.inth.join() self.inth.join()
def _handler(self): def _handler(self):
resp_timeout = self.resp_timeout resp_timeout = self.resp_timeout
@ -1798,7 +1705,6 @@ class IMAP4(object):
if __debug__: self._log(1, 'finished') if __debug__: self._log(1, 'finished')
if hasattr(select_module, "poll"): if hasattr(select_module, "poll"):
def _reader(self): def _reader(self):
@ -1942,7 +1848,6 @@ class IMAP4(object):
if __debug__: self._log(1, 'finished') if __debug__: self._log(1, 'finished')
def _writer(self): def _writer(self):
threading.currentThread().setName(self.identifier + 'writer') threading.currentThread().setName(self.identifier + 'writer')
@ -1973,11 +1878,8 @@ class IMAP4(object):
if __debug__: self._log(1, 'finished') if __debug__: self._log(1, 'finished')
# Debugging # Debugging
if __debug__: if __debug__:
def _init_debug(self, debug=None, debug_file=None, debug_buf_lvl=None): def _init_debug(self, debug=None, debug_file=None, debug_buf_lvl=None):
@ -1994,7 +1896,6 @@ class IMAP4(object):
self._mesg('imaplib2 version %s' % __version__) self._mesg('imaplib2 version %s' % __version__)
self._mesg('imaplib2 debug level %s, buffer level %s' % (self.debug, self.debug_buf_lvl)) self._mesg('imaplib2 debug level %s, buffer level %s' % (self.debug, self.debug_buf_lvl))
def _dump_ur(self, lvl): def _dump_ur(self, lvl):
if lvl > self.debug: if lvl > self.debug:
return return
@ -2009,7 +1910,6 @@ class IMAP4(object):
self._mesg('untagged responses dump:%s%s' % (t, t.join(l))) self._mesg('untagged responses dump:%s%s' % (t, t.join(l)))
self.debug_lock.release() self.debug_lock.release()
def _log(self, lvl, line): def _log(self, lvl, line):
if lvl > self.debug: if lvl > self.debug:
return return
@ -2034,7 +1934,6 @@ class IMAP4(object):
self._cmd_log_idx = 0 self._cmd_log_idx = 0
self.debug_lock.release() self.debug_lock.release()
def _mesg(self, s, tn=None, secs=None): def _mesg(self, s, tn=None, secs=None):
if secs is None: if secs is None:
secs = time.time() secs = time.time()
@ -2047,7 +1946,6 @@ class IMAP4(object):
finally: finally:
pass pass
def _print_log(self): def _print_log(self):
self.debug_lock.acquire() self.debug_lock.acquire()
i, n = self._cmd_log_idx, self._cmd_log_len i, n = self._cmd_log_idx, self._cmd_log_len
@ -2064,9 +1962,7 @@ class IMAP4(object):
self.debug_lock.release() self.debug_lock.release()
class IMAP4_SSL(IMAP4): class IMAP4_SSL(IMAP4):
"""IMAP4 client class over SSL connection """IMAP4 client class over SSL connection
Instantiate with: Instantiate with:
@ -2094,8 +1990,9 @@ class IMAP4_SSL(IMAP4):
For more documentation see the docstring of the parent class IMAP4. For more documentation see the docstring of the parent class IMAP4.
""" """
def __init__(self, host=None, port=None, keyfile=None, certfile=None, ca_certs=None, cert_verify_cb=None,
def __init__(self, host=None, port=None, keyfile=None, certfile=None, ca_certs=None, cert_verify_cb=None, ssl_version="ssl23", debug=None, debug_file=None, identifier=None, timeout=None, debug_buf_lvl=None, tls_level=TLS_COMPAT): ssl_version="ssl23", debug=None, debug_file=None, identifier=None, timeout=None, debug_buf_lvl=None,
tls_level=TLS_COMPAT):
self.keyfile = keyfile self.keyfile = keyfile
self.certfile = certfile self.certfile = certfile
self.ca_certs = ca_certs self.ca_certs = ca_certs
@ -2104,7 +2001,6 @@ class IMAP4_SSL(IMAP4):
self.tls_level = tls_level self.tls_level = tls_level
IMAP4.__init__(self, host, port, debug, debug_file, identifier, timeout, debug_buf_lvl) IMAP4.__init__(self, host, port, debug, debug_file, identifier, timeout, debug_buf_lvl)
def open(self, host=None, port=None): def open(self, host=None, port=None):
"""open(host=None, port=None) """open(host=None, port=None)
Setup secure connection to remote server on "host:port" Setup secure connection to remote server on "host:port"
@ -2117,7 +2013,6 @@ class IMAP4_SSL(IMAP4):
self.sock = self.open_socket() self.sock = self.open_socket()
self.ssl_wrap_socket() self.ssl_wrap_socket()
def read(self, size): def read(self, size):
"""data = read(size) """data = read(size)
Read at most 'size' bytes from remote.""" Read at most 'size' bytes from remote."""
@ -2132,7 +2027,6 @@ class IMAP4_SSL(IMAP4):
return self.decompressor.decompress(data, size) return self.decompressor.decompress(data, size)
def send(self, data): def send(self, data):
"""send(data) """send(data)
Send 'data' to remote.""" Send 'data' to remote."""
@ -2152,7 +2046,6 @@ class IMAP4_SSL(IMAP4):
data = data[sent:] data = data[sent:]
dlen = dlen - sent dlen = dlen - sent
def ssl(self): def ssl(self):
"""ssl = ssl() """ssl = ssl()
Return ssl instance used to communicate with the IMAP4 server.""" Return ssl instance used to communicate with the IMAP4 server."""
@ -2160,9 +2053,7 @@ class IMAP4_SSL(IMAP4):
return self.sock return self.sock
class IMAP4_stream(IMAP4): class IMAP4_stream(IMAP4):
"""IMAP4 client class over a stream """IMAP4 client class over a stream
Instantiate with: Instantiate with:
@ -2178,7 +2069,6 @@ class IMAP4_stream(IMAP4):
For more documentation see the docstring of the parent class IMAP4. For more documentation see the docstring of the parent class IMAP4.
""" """
def __init__(self, command, debug=None, debug_file=None, identifier=None, timeout=None, debug_buf_lvl=None): def __init__(self, command, debug=None, debug_file=None, identifier=None, timeout=None, debug_buf_lvl=None):
self.command = command self.command = command
self.host = command self.host = command
@ -2188,7 +2078,6 @@ class IMAP4_stream(IMAP4):
self.read_fd = None self.read_fd = None
IMAP4.__init__(self, None, None, debug, debug_file, identifier, timeout, debug_buf_lvl) IMAP4.__init__(self, None, None, debug, debug_file, identifier, timeout, debug_buf_lvl)
def open(self, host=None, port=None): def open(self, host=None, port=None):
"""open(host=None, port=None) """open(host=None, port=None)
Setup a stream connection via 'self.command'. Setup a stream connection via 'self.command'.
@ -2203,7 +2092,6 @@ class IMAP4_stream(IMAP4):
self.writefile, self.readfile = self._P.stdin, self._P.stdout self.writefile, self.readfile = self._P.stdin, self._P.stdout
self.read_fd = self.readfile.fileno() self.read_fd = self.readfile.fileno()
def read(self, size): def read(self, size):
"""Read 'size' bytes from remote.""" """Read 'size' bytes from remote."""
@ -2217,7 +2105,6 @@ class IMAP4_stream(IMAP4):
return self.decompressor.decompress(data, size) return self.decompressor.decompress(data, size)
def send(self, data): def send(self, data):
"""Send data to remote.""" """Send data to remote."""
@ -2228,7 +2115,6 @@ class IMAP4_stream(IMAP4):
self.writefile.write(data) self.writefile.write(data)
self.writefile.flush() self.writefile.flush()
def shutdown(self): def shutdown(self):
"""Close I/O established in "open".""" """Close I/O established in "open"."""
@ -2238,7 +2124,6 @@ class IMAP4_stream(IMAP4):
class _Authenticator(object): class _Authenticator(object):
"""Private class to provide en/de-coding """Private class to provide en/de-coding
for base64 authentication conversation.""" for base64 authentication conversation."""
@ -2281,10 +2166,7 @@ class _Authenticator(object):
return binascii.a2b_base64(inp) return binascii.a2b_base64(inp)
class _IdleCont(object): class _IdleCont(object):
"""When process is called, server is in IDLE state """When process is called, server is in IDLE state
and will send asynchronous changes.""" and will send asynchronous changes."""
@ -2302,7 +2184,6 @@ class _IdleCont(object):
return None return None
MonthNames = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', MonthNames = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
@ -2314,7 +2195,6 @@ InternalDate = re.compile(r'.*INTERNALDATE "'
def Internaldate2Time(resp): def Internaldate2Time(resp):
"""time_tuple = Internaldate2Time(resp) """time_tuple = Internaldate2Time(resp)
Parse an IMAP4 INTERNALDATE string. Parse an IMAP4 INTERNALDATE string.
@ -2349,12 +2229,11 @@ def Internaldate2Time(resp):
tt = (year, mon, day, hour, min, sec, -1, -1, -1) tt = (year, mon, day, hour, min, sec, -1, -1, -1)
return time.localtime(calendar.timegm(tt) - zone) return time.localtime(calendar.timegm(tt) - zone)
Internaldate2tuple = Internaldate2Time # (Backward compatible) Internaldate2tuple = Internaldate2Time # (Backward compatible)
def Time2Internaldate(date_time): def Time2Internaldate(date_time):
"""'"DD-Mmm-YYYY HH:MM:SS +HHMM"' = Time2Internaldate(date_time) """'"DD-Mmm-YYYY HH:MM:SS +HHMM"' = Time2Internaldate(date_time)
Convert 'date_time' to IMAP4 INTERNALDATE representation. Convert 'date_time' to IMAP4 INTERNALDATE representation.
@ -2396,11 +2275,10 @@ def Time2Internaldate(date_time):
return dt.strftime(fmt) return dt.strftime(fmt)
FLAGS_cre = re.compile(br'.*FLAGS \((?P<flags>[^\)]*)\)') FLAGS_cre = re.compile(br'.*FLAGS \((?P<flags>[^\)]*)\)')
def ParseFlags(resp):
def ParseFlags(resp):
"""('flag', ...) = ParseFlags(line) """('flag', ...) = ParseFlags(line)
Convert IMAP4 flags response to python tuple.""" Convert IMAP4 flags response to python tuple."""
@ -2411,7 +2289,6 @@ def ParseFlags(resp):
return tuple(mo.group('flags').split()) return tuple(mo.group('flags').split())
if __name__ == '__main__': if __name__ == '__main__':
# To test: invoke either as 'python imaplib2.py [IMAP4_server_hostname]', # To test: invoke either as 'python imaplib2.py [IMAP4_server_hostname]',
@ -2495,9 +2372,9 @@ if __name__ == '__main__':
('recent', ()), ('recent', ()),
) )
AsyncError, M = None, None AsyncError, M = None, None
def responder(cb_arg_list): def responder(cb_arg_list):
response, cb_arg, error = cb_arg_list response, cb_arg, error = cb_arg_list
global AsyncError global AsyncError
@ -2511,6 +2388,7 @@ if __name__ == '__main__':
if typ == 'NO': if typ == 'NO':
AsyncError = (Exception, dat[0]) AsyncError = (Exception, dat[0])
def run(cmd, args, cb=True): def run(cmd, args, cb=True):
if AsyncError: if AsyncError:
M._log(1, 'AsyncError %s' % repr(AsyncError)) M._log(1, 'AsyncError %s' % repr(AsyncError))
@ -2535,13 +2413,15 @@ if __name__ == '__main__':
raise Exception(dat[0]) raise Exception(dat[0])
return dat return dat
try: try:
threading.currentThread().setName('main') threading.currentThread().setName('main')
if keyfile is not None: if keyfile is not None:
if not keyfile: keyfile = None if not keyfile: keyfile = None
if not certfile: certfile = None if not certfile: certfile = None
M = IMAP4_SSL(host=host, port=port, keyfile=keyfile, certfile=certfile, ssl_version="tls1", debug=debug, identifier='', timeout=10, debug_buf_lvl=debug_buf_lvl, tls_level="tls_no_ssl") M = IMAP4_SSL(host=host, port=port, keyfile=keyfile, certfile=certfile, ssl_version="tls1", debug=debug,
identifier='', timeout=10, debug_buf_lvl=debug_buf_lvl, tls_level="tls_no_ssl")
elif stream_command: elif stream_command:
M = IMAP4_stream(stream_command, debug=debug, identifier='', timeout=10, debug_buf_lvl=debug_buf_lvl) M = IMAP4_stream(stream_command, debug=debug, identifier='', timeout=10, debug_buf_lvl=debug_buf_lvl)
else: else:
@ -2558,8 +2438,10 @@ if __name__ == '__main__':
for ml in run('list', ('""', '"imaplib2_test%"'), cb=False): for ml in run('list', ('""', '"imaplib2_test%"'), cb=False):
mo = re.match(br'.*"([^"]+)"$', ml) mo = re.match(br'.*"([^"]+)"$', ml)
if mo: path = mo.group(1) if mo:
else: path = ml.split()[-1] path = mo.group(1)
else:
path = ml.split()[-1]
run('delete', (path,)) run('delete', (path,))
if 'ID' in M.capabilities: if 'ID' in M.capabilities: