@@ -77,9 +77,16 @@ class IMAP4:
7777 port - port number (default: standard IMAP4 port).
7878
7979 All IMAP4rev1 commands are supported by methods of the same
80- name (in lower-case). Each command returns a tuple: (type, [data, ...])
81- where 'type' is usually 'OK' or 'NO', and 'data' is either the
82- text from the tagged response, or untagged results from command.
80+ name (in lower-case).
81+
82+ All arguments to commands are converted to strings, except for
83+ the last argument to APPEND which is passed as an IMAP4
84+ literal. If necessary (the string isn't enclosed with either
85+ parentheses or double quotes) each converted string is quoted.
86+
87+ Each command returns a tuple: (type, [data, ...]) where 'type'
88+ is usually 'OK' or 'NO', and 'data' is either the text from the
89+ tagged response, or untagged results from command.
8390
8491 Errors raise the exception class <instance>.error("<reason>").
8592 IMAP4 server errors raise <instance>.abort("<reason>"),
@@ -95,6 +102,7 @@ def __init__(self, host = '', port = IMAP4_PORT):
95102 self .port = port
96103 self .debug = Debug
97104 self .state = 'LOGOUT'
105+ self .literal = None # A literal argument to a command
98106 self .tagged_commands = {} # Tagged commands awaiting response
99107 self .untagged_responses = {} # {typ: [data, ...], ...}
100108 self .continuation_response = '' # Last continuation response
@@ -109,7 +117,7 @@ def __init__(self, host = '', port = IMAP4_PORT):
109117 # Create unique tag for this session,
110118 # and compile tagged response matcher.
111119
112- self .tagpre = Int2AP (random .random () * 32000 )
120+ self .tagpre = Int2AP (random .randint ( 0 , 31999 ) )
113121 self .tagre = re .compile (r'(?P<tag>'
114122 + self .tagpre
115123 + r'\d+) (?P<type>[A-Z]+) (?P<data>.*)' )
@@ -172,7 +180,8 @@ def append(self, mailbox, flags, date_time, message):
172180 date_time = Time2Internaldate (date_time )
173181 else :
174182 date_time = None
175- return self ._simple_command (name , mailbox , flags , date_time , message )
183+ self .literal = message
184+ return self ._simple_command (name , mailbox , flags , date_time )
176185
177186
178187 def authenticate (self , func ):
@@ -310,10 +319,18 @@ def lsub(self, directory='""', pattern='*'):
310319 return self ._untagged_response (typ , name )
311320
312321
313- def recent (self ):
314- """Prompt server for an update .
322+ def noop (self ):
323+ """Send NOOP command .
315324
316- Flush all untagged responses.
325+ (typ, data) = <instance>.noop()
326+ """
327+ return self ._simple_command ('NOOP' )
328+
329+
330+ def recent (self ):
331+ """Return most recent 'RECENT' response if it exists,
332+ else prompt server for an update using the 'NOOP' command,
333+ and flush all untagged responses.
317334
318335 (typ, [data]) = <instance>.recent()
319336
@@ -468,15 +485,16 @@ def _append_untagged(self, typ, dat):
468485 print '\t untagged_responses[%s] += %.20s..' % (typ , `dat` )
469486
470487
471- def _command (self , name , dat1 = None , dat2 = None , dat3 = None , literal = None ):
488+ def _command (self , name , * args ):
472489
473490 if self .state not in Commands [name ]:
491+ self .literal = None
474492 raise self .error (
475493 'command %s illegal in state %s' % (name , self .state ))
476494
477495 tag = self ._new_tag ()
478496 data = '%s %s' % (tag , name )
479- for d in ( dat1 , dat2 , dat3 ) :
497+ for d in args :
480498 if d is None : continue
481499 if type (d ) is type ('' ):
482500 l = len (string .split (d ))
@@ -486,7 +504,10 @@ def _command(self, name, dat1=None, dat2=None, dat3=None, literal=None):
486504 data = '%s "%s"' % (data , d )
487505 else :
488506 data = '%s %s' % (data , d )
507+
508+ literal = self .literal
489509 if literal is not None :
510+ self .literal = None
490511 data = '%s {%s}' % (data , len (literal ))
491512
492513 try :
0 commit comments