Lines Matching refs:self
188 def __init__(self, host='', port=IMAP4_PORT, timeout=None):
189 self.debug = Debug
190 self.state = 'LOGOUT'
191 self.literal = None # A literal argument to a command
192 self.tagged_commands = {} # Tagged commands awaiting response
193 self.untagged_responses = {} # {typ: [data, ...], ...}
194 self.continuation_response = '' # Last continuation response
195 self.is_readonly = False # READ-ONLY desired state
196 self.tagnum = 0
197 self._tls_established = False
198 self._mode_ascii()
202 self.open(host, port, timeout)
205 self._connect()
208 self.shutdown()
213 def _mode_ascii(self):
214 self.utf8_enabled = False
215 self._encoding = 'ascii'
216 self.Literal = re.compile(_Literal, re.ASCII)
217 self.Untagged_status = re.compile(_Untagged_status, re.ASCII)
220 def _mode_utf8(self):
221 self.utf8_enabled = True
222 self._encoding = 'utf-8'
223 self.Literal = re.compile(_Literal)
224 self.Untagged_status = re.compile(_Untagged_status)
227 def _connect(self):
231 self.tagpre = Int2AP(random.randint(4096, 65535))
232 self.tagre = re.compile(br'(?P<tag>'
233 + self.tagpre
240 self._cmd_log_len = 10
241 self._cmd_log_idx = 0
242 self._cmd_log = {} # Last `_cmd_log_len' interactions
243 if self.debug >= 1:
244 self._mesg('imaplib version %s' % __version__)
245 self._mesg('new IMAP4 connection, tag=%s' % self.tagpre)
247 self.welcome = self._get_response()
248 if 'PREAUTH' in self.untagged_responses:
249 self.state = 'AUTH'
250 elif 'OK' in self.untagged_responses:
251 self.state = 'NONAUTH'
253 raise self.error(self.welcome)
255 self._get_capabilities()
257 if self.debug >= 3:
258 self._mesg('CAPABILITIES: %r' % (self.capabilities,))
261 if not version in self.capabilities:
263 self.PROTOCOL_VERSION = version
266 raise self.error('server not IMAP4 compliant')
269 def __getattr__(self, attr):
272 return getattr(self, attr.lower())
275 def __enter__(self):
276 return self
278 def __exit__(self, *args):
279 if self.state == "LOGOUT":
283 self.logout()
291 def _create_socket(self, timeout):
297 host = None if not self.host else self.host
298 sys.audit("imaplib.open", self, self.host, self.port)
299 address = (host, self.port)
304 def open(self, host='', port=IMAP4_PORT, timeout=None):
310 self.host = host
311 self.port = port
312 self.sock = self._create_socket(timeout)
313 self.file = self.sock.makefile('rb')
316 def read(self, size):
318 return self.file.read(size)
321 def readline(self):
323 line = self.file.readline(_MAXLINE + 1)
325 raise self.error("got more than %d bytes" % _MAXLINE)
329 def send(self, data):
331 sys.audit("imaplib.send", self, data)
332 self.sock.sendall(data)
335 def shutdown(self):
337 self.file.close()
339 self.sock.shutdown(socket.SHUT_RDWR)
348 self.sock.close()
351 def socket(self):
356 return self.sock
363 def recent(self):
373 typ, dat = self._untagged_response('OK', [None], name)
376 typ, dat = self.noop() # Prod server for response
377 return self._untagged_response(typ, dat, name)
380 def response(self, code):
387 return self._untagged_response(code, [None], code.upper())
394 def append(self, mailbox, flags, date_time, message):
414 if self.utf8_enabled:
416 self.literal = literal
417 return self._simple_command(name, mailbox, flags, date_time)
420 def authenticate(self, mechanism, authobject):
439 #if not cap in self.capabilities: # Let the server decide!
440 # raise self.error("Server doesn't allow %s authentication." % mech)
441 self.literal = _Authenticator(authobject).process
442 typ, dat = self._simple_command('AUTHENTICATE', mech)
444 raise self.error(dat[-1].decode('utf-8', 'replace'))
445 self.state = 'AUTH'
449 def capability(self):
454 typ, dat = self._simple_command(name)
455 return self._untagged_response(typ, dat, name)
458 def check(self):
463 return self._simple_command('CHECK')
466 def close(self):
475 typ, dat = self._simple_command('CLOSE')
477 self.state = 'AUTH'
481 def copy(self, message_set, new_mailbox):
486 return self._simple_command('COPY', message_set, new_mailbox)
489 def create(self, mailbox):
494 return self._simple_command('CREATE', mailbox)
497 def delete(self, mailbox):
502 return self._simple_command('DELETE', mailbox)
504 def deleteacl(self, mailbox, who):
509 return self._simple_command('DELETEACL', mailbox, who)
511 def enable(self, capability):
516 if 'ENABLE' not in self.capabilities:
518 typ, data = self._simple_command('ENABLE', capability)
520 self._mode_utf8()
523 def expunge(self):
533 typ, dat = self._simple_command(name)
534 return self._untagged_response(typ, dat, name)
537 def fetch(self, message_set, message_parts):
548 typ, dat = self._simple_command(name, message_set, message_parts)
549 return self._untagged_response(typ, dat, name)
552 def getacl(self, mailbox):
557 typ, dat = self._simple_command('GETACL', mailbox)
558 return self._untagged_response(typ, dat, 'ACL')
561 def getannotation(self, mailbox, entry, attribute):
565 typ, dat = self._simple_command('GETANNOTATION', mailbox, entry, attribute)
566 return self._untagged_response(typ, dat, 'ANNOTATION')
569 def getquota(self, root):
576 typ, dat = self._simple_command('GETQUOTA', root)
577 return self._untagged_response(typ, dat, 'QUOTA')
580 def getquotaroot(self, mailbox):
585 typ, dat = self._simple_command('GETQUOTAROOT', mailbox)
586 typ, quota = self._untagged_response(typ, dat, 'QUOTA')
587 typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT')
591 def list(self, directory='""', pattern='*'):
599 typ, dat = self._simple_command(name, directory, pattern)
600 return self._untagged_response(typ, dat, name)
603 def login(self, user, password):
610 typ, dat = self._simple_command('LOGIN', user, self._quote(password))
612 raise self.error(dat[-1])
613 self.state = 'AUTH'
617 def login_cram_md5(self, user, password):
622 self.user, self.password = user, password
623 return self.authenticate('CRAM-MD5', self._CRAM_MD5_AUTH)
626 def _CRAM_MD5_AUTH(self, challenge):
629 pwd = (self.password.encode('utf-8') if isinstance(self.password, str)
630 else self.password)
631 return self.user + " " + hmac.HMAC(pwd, challenge, 'md5').hexdigest()
634 def logout(self):
641 self.state = 'LOGOUT'
642 typ, dat = self._simple_command('LOGOUT')
643 self.shutdown()
647 def lsub(self, directory='""', pattern='*'):
655 typ, dat = self._simple_command(name, directory, pattern)
656 return self._untagged_response(typ, dat, name)
658 def myrights(self, mailbox):
663 typ,dat = self._simple_command('MYRIGHTS', mailbox)
664 return self._untagged_response(typ, dat, 'MYRIGHTS')
666 def namespace(self):
672 typ, dat = self._simple_command(name)
673 return self._untagged_response(typ, dat, name)
676 def noop(self):
682 if self.debug >= 3:
683 self._dump_ur(self.untagged_responses)
684 return self._simple_command('NOOP')
687 def partial(self, message_num, message_part, start, length):
695 typ, dat = self._simple_command(name, message_num, message_part, start, length)
696 return self._untagged_response(typ, dat, 'FETCH')
699 def proxyauth(self, user):
709 return self._simple_command('PROXYAUTH', user)
712 def rename(self, oldmailbox, newmailbox):
717 return self._simple_command('RENAME', oldmailbox, newmailbox)
720 def search(self, charset, *criteria):
730 if self.utf8_enabled:
732 typ, dat = self._simple_command(name, 'CHARSET', charset, *criteria)
734 typ, dat = self._simple_command(name, *criteria)
735 return self._untagged_response(typ, dat, name)
738 def select(self, mailbox='INBOX', readonly=False):
750 self.untagged_responses = {} # Flush old responses.
751 self.is_readonly = readonly
756 typ, dat = self._simple_command(name, mailbox)
758 self.state = 'AUTH' # Might have been 'SELECTED'
760 self.state = 'SELECTED'
761 if 'READ-ONLY' in self.untagged_responses \
764 if self.debug >= 1:
765 self._dump_ur(self.untagged_responses)
766 raise self.readonly('%s is not writable' % mailbox)
767 return typ, self.untagged_responses.get('EXISTS', [None])
770 def setacl(self, mailbox, who, what):
775 return self._simple_command('SETACL', mailbox, who, what)
778 def setannotation(self, *args):
782 typ, dat = self._simple_command('SETANNOTATION', *args)
783 return self._untagged_response(typ, dat, 'ANNOTATION')
786 def setquota(self, root, limits):
791 typ, dat = self._simple_command('SETQUOTA', root, limits)
792 return self._untagged_response(typ, dat, 'QUOTA')
795 def sort(self, sort_criteria, charset, *search_criteria):
801 #if not name in self.capabilities: # Let the server decide!
802 # raise self.error('unimplemented extension command: %s' % name)
805 typ, dat = self._simple_command(name, sort_criteria, charset, *search_criteria)
806 return self._untagged_response(typ, dat, name)
809 def starttls(self, ssl_context=None):
812 raise self.error('SSL support missing')
813 if self._tls_established:
814 raise self.abort('TLS session already established')
815 if name not in self.capabilities:
816 raise self.abort('TLS not supported by server')
820 typ, dat = self._simple_command(name)
822 self.sock = ssl_context.wrap_socket(self.sock,
823 server_hostname=self.host)
824 self.file = self.sock.makefile('rb')
825 self._tls_established = True
826 self._get_capabilities()
828 raise self.error("Couldn't establish TLS session")
829 return self._untagged_response(typ, dat, name)
832 def status(self, mailbox, names):
838 #if self.PROTOCOL_VERSION == 'IMAP4': # Let the server decide!
839 # raise self.error('%s unimplemented in IMAP4 (obtain IMAP4rev1 server, or re-code)' % name)
840 typ, dat = self._simple_command(name, mailbox, names)
841 return self._untagged_response(typ, dat, name)
844 def store(self, message_set, command, flags):
851 typ, dat = self._simple_command('STORE', message_set, command, flags)
852 return self._untagged_response(typ, dat, 'FETCH')
855 def subscribe(self, mailbox):
860 return self._simple_command('SUBSCRIBE', mailbox)
863 def thread(self, threading_algorithm, charset, *search_criteria):
869 typ, dat = self._simple_command(name, threading_algorithm, charset, *search_criteria)
870 return self._untagged_response(typ, dat, name)
873 def uid(self, command, *args):
883 raise self.error("Unknown IMAP4 UID command: %s" % command)
884 if self.state not in Commands[command]:
885 raise self.error("command %s illegal in state %s, "
887 (command, self.state,
890 typ, dat = self._simple_command(name, command, *args)
895 return self._untagged_response(typ, dat, name)
898 def unsubscribe(self, mailbox):
903 return self._simple_command('UNSUBSCRIBE', mailbox)
906 def unselect(self):
916 typ, data = self._simple_command('UNSELECT')
918 self.state = 'AUTH'
922 def xatom(self, name, *args):
933 #if not name in self.capabilities: # Let the server decide!
934 # raise self.error('unknown extension command: %s' % name)
936 Commands[name] = (self.state,)
937 return self._simple_command(name, *args)
944 def _append_untagged(self, typ, dat):
947 ur = self.untagged_responses
949 if self.debug >= 5:
950 self._mesg('untagged_responses[%s] %s += ["%r"]' %
958 def _check_bye(self):
959 bye = self.untagged_responses.get('BYE')
961 raise self.abort(bye[-1].decode(self._encoding, 'replace'))
964 def _command(self, name, *args):
966 if self.state not in Commands[name]:
967 self.literal = None
968 raise self.error("command %s illegal in state %s, "
970 (name, self.state,
974 if typ in self.untagged_responses:
975 del self.untagged_responses[typ]
977 if 'READ-ONLY' in self.untagged_responses \
978 and not self.is_readonly:
979 raise self.readonly('mailbox status changed to READ-ONLY')
981 tag = self._new_tag()
982 name = bytes(name, self._encoding)
987 arg = bytes(arg, self._encoding)
990 literal = self.literal
992 self.literal = None
993 if type(literal) is type(self._command):
997 data = data + bytes(' {%s}' % len(literal), self._encoding)
1000 if self.debug >= 4:
1001 self._mesg('> %r' % data)
1003 self._log('> %r' % data)
1006 self.send(data + CRLF)
1008 raise self.abort('socket error: %s' % val)
1016 while self._get_response():
1017 if self.tagged_commands[tag]: # BAD/NO?
1023 literal = literator(self.continuation_response)
1026 if self.debug >= 4:
1027 self._mesg('write literal size %s' % len(literal))
1030 self.send(literal)
1031 self.send(CRLF)
1033 raise self.abort('socket error: %s' % val)
1041 def _command_complete(self, name, tag):
1045 self._check_bye()
1047 typ, data = self._get_tagged_response(tag, expect_bye=logout)
1048 except self.abort as val:
1049 raise self.abort('command: %s => %s' % (name, val))
1050 except self.error as val:
1051 raise self.error('command: %s => %s' % (name, val))
1053 self._check_bye()
1055 raise self.error('%s command error: %s %s' % (name, typ, data))
1059 def _get_capabilities(self):
1060 typ, dat = self.capability()
1062 raise self.error('no CAPABILITY response from server')
1063 dat = str(dat[-1], self._encoding)
1065 self.capabilities = tuple(dat.split())
1068 def _get_response(self):
1075 resp = self._get_line()
1079 if self._match(self.tagre, resp):
1080 tag = self.mo.group('tag')
1081 if not tag in self.tagged_commands:
1082 raise self.abort('unexpected tagged response: %r' % resp)
1084 typ = self.mo.group('type')
1085 typ = str(typ, self._encoding)
1086 dat = self.mo.group('data')
1087 self.tagged_commands[tag] = (typ, [dat])
1093 if not self._match(Untagged_response, resp):
1094 if self._match(self.Untagged_status, resp):
1095 dat2 = self.mo.group('data2')
1097 if self.mo is None:
1100 if self._match(Continuation, resp):
1101 self.continuation_response = self.mo.group('data')
1104 raise self.abort("unexpected response: %r" % resp)
1106 typ = self.mo.group('type')
1107 typ = str(typ, self._encoding)
1108 dat = self.mo.group('data')
1114 while self._match(self.Literal, dat):
1118 size = int(self.mo.group('size'))
1120 if self.debug >= 4:
1121 self._mesg('read literal size %s' % size)
1122 data = self.read(size)
1126 self._append_untagged(typ, (dat, data))
1130 dat = self._get_line()
1132 self._append_untagged(typ, dat)
1136 if typ in ('OK', 'NO', 'BAD') and self._match(Response_code, dat):
1137 typ = self.mo.group('type')
1138 typ = str(typ, self._encoding)
1139 self._append_untagged(typ, self.mo.group('data'))
1142 if self.debug >= 1 and typ in ('NO', 'BAD', 'BYE'):
1143 self._mesg('%s response: %r' % (typ, dat))
1148 def _get_tagged_response(self, tag, expect_bye=False):
1151 result = self.tagged_commands[tag]
1153 del self.tagged_commands[tag]
1158 bye = self.untagged_responses.pop(typ, None)
1165 self._check_bye()
1173 self._get_response()
1174 except self.abort as val:
1176 if self.debug >= 1:
1177 self.print_log()
1181 def _get_line(self):
1183 line = self.readline()
1185 raise self.abort('socket error: EOF')
1189 raise self.abort('socket error: unterminated line: %r' % line)
1193 if self.debug >= 4:
1194 self._mesg('< %r' % line)
1196 self._log('< %r' % line)
1200 def _match(self, cre, s):
1205 self.mo = cre.match(s)
1207 if self.mo is not None and self.debug >= 5:
1208 self._mesg("\tmatched %r => %r" % (cre.pattern, self.mo.groups()))
1209 return self.mo is not None
1212 def _new_tag(self):
1214 tag = self.tagpre + bytes(str(self.tagnum), self._encoding)
1215 self.tagnum = self.tagnum + 1
1216 self.tagged_commands[tag] = None
1220 def _quote(self, arg):
1228 def _simple_command(self, name, *args):
1230 return self._command_complete(name, self._command(name, *args))
1233 def _untagged_response(self, typ, dat, name):
1236 if not name in self.untagged_responses:
1238 data = self.untagged_responses.pop(name)
1240 if self.debug >= 5:
1241 self._mesg('untagged_responses[%s] => %s' % (name, data))
1247 def _mesg(self, s, secs=None):
1254 def _dump_ur(self, untagged_resp_dict):
1259 self._mesg('untagged responses dump:' + '\n\t\t'.join(items))
1261 def _log(self, line):
1263 self._cmd_log[self._cmd_log_idx] = (line, time.time())
1264 self._cmd_log_idx += 1
1265 if self._cmd_log_idx >= self._cmd_log_len:
1266 self._cmd_log_idx = 0
1268 def print_log(self):
1269 self._mesg('last %d IMAP4 interactions:' % len(self._cmd_log))
1270 i, n = self._cmd_log_idx, self._cmd_log_len
1273 self._mesg(*self._cmd_log[i])
1277 if i >= self._cmd_log_len:
1305 def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None,
1317 self.keyfile = keyfile
1318 self.certfile = certfile
1322 self.ssl_context = ssl_context
1323 IMAP4.__init__(self, host, port, timeout)
1325 def _create_socket(self, timeout):
1326 sock = IMAP4._create_socket(self, timeout)
1327 return self.ssl_context.wrap_socket(sock,
1328 server_hostname=self.host)
1330 def open(self, host='', port=IMAP4_SSL_PORT, timeout=None):
1336 IMAP4.open(self, host, port, timeout)
1353 def __init__(self, command):
1354 self.command = command
1355 IMAP4.__init__(self)
1358 def open(self, host=None, port=None, timeout=None):
1363 self.host = None # For compatibility with parent class
1364 self.port = None
1365 self.sock = None
1366 self.file = None
1367 self.process = subprocess.Popen(self.command,
1371 self.writefile = self.process.stdin
1372 self.readfile = self.process.stdout
1374 def read(self, size):
1376 return self.readfile.read(size)
1379 def readline(self):
1381 return self.readfile.readline()
1384 def send(self, data):
1386 self.writefile.write(data)
1387 self.writefile.flush()
1390 def shutdown(self):
1392 self.readfile.close()
1393 self.writefile.close()
1394 self.process.wait()
1404 def __init__(self, mechinst):
1405 self.mech = mechinst # Callable object to provide/process data
1407 def process(self, data):
1408 ret = self.mech(self.decode(data))
1411 return self.encode(ret)
1413 def encode(self, inp):
1437 def decode(self, inp):