def __init__(self, hostname, username=None, password=None, ssl=True, port=None, ssl_context=None, policy=None, starttls=False): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context, starttls=starttls) self.hostname = hostname self.username = username self.password = password self.parser_policy = policy self.connection = self.server.connect(username, password) logger.info( "Connected to IMAP Server with user {username} on {hostname}{ssl}". format(hostname=hostname, username=username, ssl=(" over SSL" if ssl or starttls else "")))
def __init__(self, hostname, username=None, password=None, ssl=True, port=None, ssl_context=None, policy=None, starttls=False, vendor=None): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context, starttls=starttls) self.hostname = hostname self.username = username self.password = password self.parser_policy = policy self.vendor = vendor or hostname_vendorname_dict.get(self.hostname) if self.vendor is not None: self.authentication_error_message = name_authentication_string_dict.get( self.vendor) try: self.connection = self.server.connect(username, password) except imaplib.IMAP4.error as e: if self.authentication_error_message is None: raise raise imaplib.IMAP4.error(self.authentication_error_message + '\n' + str(e))
def __init__(self, hostname, username=None, password=None, ssl=True): self.server = ImapTransport(hostname, ssl=ssl) self.hostname = hostname self.username = username self.password = password self.connection = self.server.connect(username, password) logger.info("Connected to IMAP Server with user {username} on {hostname}{ssl}".format( hostname=hostname, username=username, ssl=(" over SSL" if ssl else "")))
def __init__(self, hostname, username=None, password=None, ssl=True, port=None, ssl_context=None, policy=None, starttls=False, vendor=None): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context, starttls=starttls) self.hostname = hostname self.username = username self.password = password self.parser_policy = policy self.vendor = vendor or hostname_vendorname_dict.get(self.hostname) if self.vendor is not None: self.authentication_error_message = name_authentication_string_dict.get( self.vendor) try: self.connection = self.server.connect(username, password) except imaplib.IMAP4.error as e: if self.authentication_error_message is None: raise raise imaplib.IMAP4.error( self.authentication_error_message + '\n' + str(e)) logger.info("Connected to IMAP Server with user {username} on {hostname}{ssl}".format( hostname=hostname, username=username, ssl=(" over SSL" if ssl or starttls else "")))
class Imbox(object): def __init__(self, hostname, username=None, password=None, ssl=True): self.server = ImapTransport(hostname, ssl=ssl) self.username = username self.password = password self.connection = self.server.connect(username, password) def logout(self): self.connection.close() self.connection.logout() def query_uids(self, **kwargs): query = build_search_query(**kwargs) message, data = self.connection.uid('search', None, query) if data[0] is None: return [] return data[0].split() def fetch_by_uid(self, uid): message, data = self.connection.uid('fetch', uid, '(BODY.PEEK[])') raw_email = data[0][1] email_object = parse_email(raw_email) return email_object def fetch_list(self, **kwargs): uid_list = self.query_uids(**kwargs) for uid in uid_list: yield (uid, self.fetch_by_uid(uid)) def mark_seen(self, uid): self.connection.uid('STORE', uid, '+FLAGS', '(\\Seen)') def delete(self, uid): mov, data = self.connection.uid('STORE', uid, '+FLAGS', '(\\Deleted)') self.connection.expunge() def copy(self, uid, destination_folder): return self.connection.uid('COPY', uid, destination_folder) def move(self, uid, destination_folder): if self.copy(uid, destination_folder): self.delete(uid) def messages(self, *args, **kwargs): folder = kwargs.get('folder', False) if folder: self.connection.select(folder) return self.fetch_list(**kwargs) def folders(self): return self.connection.list()
def __init__(self, hostname, username=None, password=None, ssl=True, port=None, gmail=False, zimbra=False): self.server = ImapTransport(hostname, port=port, ssl=ssl) self.connection = self.server.connect(username, password) self.username = username self.password = password self.gmail = gmail self.zimbra = zimbra
def __init__(self, hostname, username=None, password=None, ssl=True): self.server = ImapTransport(hostname, ssl=ssl) self.username = username self.password = password self.connection = self.server.connect(username, password) logger.info("Connected to IMAP Server with user {username} on {hostname}{ssl}".format( hostname=hostname, username=username, ssl=(" over SSL" if ssl else "")))
def __init__(self, imap_connection=None, hostname=None, username=None, password=None, ssl=True): if imap_connection is not None: self.connection = imap_connection elif hostname is not None: self.server = ImapTransport(hostname, ssl=ssl) self.connection = self.server.connect(username, password) else: raise Exception('Insufficient parameters', 'Specify imap_connection or hostname')
def __init__(self, hostname, username=None, password=None, ssl=True, port=None, ssl_context=None, policy=None, starttls=False, vendor=None, timeout_per_msg=None): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context, starttls=starttls) self.hostname = hostname self.username = username self.password = password self.parser_policy = policy self.timeout_per_msg = timeout_per_msg self.vendor = vendor or hostname_vendorname_dict.get(self.hostname) if self.vendor is not None: self.authentication_error_message = name_authentication_string_dict.get( self.vendor) try: self.connection = self.server.connect(username, password) except imaplib.IMAP4.error as e: if self.authentication_error_message is None: raise raise imaplib.IMAP4.error(self.authentication_error_message + '\n' + str(e)) logger.info( "Connected to IMAP Server with user {username} on {hostname}{ssl}". format(hostname=hostname, username=username, ssl=(" over SSL" if ssl or starttls else "")))
class Imbox: authentication_error_message = None def __init__(self, hostname, username=None, password=None, ssl=True, port=None, ssl_context=None, policy=None, starttls=False, vendor=None): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context, starttls=starttls) self.hostname = hostname self.username = username self.password = password self.parser_policy = policy self.vendor = vendor or hostname_vendorname_dict.get(self.hostname) if self.vendor is not None: self.authentication_error_message = name_authentication_string_dict.get( self.vendor) try: self.connection = self.server.connect(username, password) except imaplib.IMAP4.error as e: if self.authentication_error_message is None: raise raise imaplib.IMAP4.error(self.authentication_error_message + '\n' + str(e)) logger.info( "Connected to IMAP Server with user {username} on {hostname}{ssl}". format(hostname=hostname, username=username, ssl=(" over SSL" if ssl or starttls else ""))) def __enter__(self): return self def __exit__(self, type, value, traceback): self.logout() def logout(self): self.connection.close() self.connection.logout() logger.info( "Disconnected from IMAP Server {username}@{hostname}".format( hostname=self.hostname, username=self.username)) def mark_seen(self, uid): logger.info("Mark UID {} with \\Seen FLAG".format(int(uid))) self.connection.uid('STORE', uid, '+FLAGS', '(\\Seen)') def mark_flag(self, uid): logger.info("Mark UID {} with \\Flagged FLAG".format(int(uid))) self.connection.uid('STORE', uid, '+FLAGS', '(\\Flagged)') def delete(self, uid): logger.info("Mark UID {} with \\Deleted FLAG and expunge.".format( int(uid))) self.connection.expunge() def copy(self, uid, destination_folder): logger.info("Copy UID {} to {} folder".format(int(uid), str(destination_folder))) return self.connection.uid('COPY', uid, destination_folder) def move(self, uid, destination_folder): logger.info("Move UID {} to {} folder".format(int(uid), str(destination_folder))) if self.copy(uid, destination_folder): self.delete(uid) def messages(self, **kwargs): folder = kwargs.get('folder', False) messages_class = Messages if self.vendor == 'gmail': messages_class = GmailMessages if folder: self.connection.select( messages_class.FOLDER_LOOKUP.get((folder.lower())) or folder) msg = " from folder '{}'".format(folder) del kwargs['folder'] else: msg = " from inbox" logger.info("Fetch list of messages{}".format(msg)) return messages_class(connection=self.connection, parser_policy=self.parser_policy, **kwargs) def folders(self): return self.connection.list()
def __init__(self, hostname, username=None, password=None, ssl=True): self.server = ImapTransport(hostname, ssl=ssl) self.username = username self.password = password self.connection = self.server.connect(username, password)
class Imbox: def __init__(self, hostname, username=None, password=None, ssl=True, port=None, ssl_context=None, policy=None): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context) self.hostname = hostname self.username = username self.password = password self.parser_policy = policy self.connection = self.server.connect(username, password) logger.info("Connected to IMAP Server with user {username} on {hostname}{ssl}".format( hostname=hostname, username=username, ssl=(" over SSL" if ssl else ""))) def __enter__(self): return self def __exit__(self, type, value, traceback): self.logout() def logout(self): self.connection.close() self.connection.logout() logger.info("Disconnected from IMAP Server {username}@{hostname}".format( hostname=self.hostname, username=self.username)) def query_uids(self, **kwargs): query = build_search_query(**kwargs) message, data = self.connection.uid('search', None, query) if data[0] is None: return [] return data[0].split() def fetch_by_uid(self, uid): message, data = self.connection.uid('fetch', uid, '(BODY.PEEK[])') logger.debug("Fetched message for UID {}".format(int(uid))) raw_email = data[0][1] email_object = parse_email(raw_email, policy=self.parser_policy) return email_object def fetch_list(self, **kwargs): uid_list = self.query_uids(**kwargs) logger.debug("Fetch all messages for UID in {}".format(uid_list)) for uid in uid_list: yield (uid, self.fetch_by_uid(uid)) def mark_seen(self, uid): logger.info("Mark UID {} with \\Seen FLAG".format(int(uid))) self.connection.uid('STORE', uid, '+FLAGS', '(\\Seen)') def mark_flag(self, uid): logger.info("Mark UID {} with \\Flagged FLAG".format(int(uid))) self.connection.uid('STORE', uid, '+FLAGS', '(\\Flagged)') def delete(self, uid): logger.info("Mark UID {} with \\Deleted FLAG and expunge.".format(int(uid))) mov, data = self.connection.uid('STORE', uid, '+FLAGS', '(\\Deleted)') self.connection.expunge() def copy(self, uid, destination_folder): logger.info("Copy UID {} to {} folder".format(int(uid), str(destination_folder))) return self.connection.uid('COPY', uid, destination_folder) def move(self, uid, destination_folder): logger.info("Move UID {} to {} folder".format(int(uid), str(destination_folder))) if self.copy(uid, destination_folder): self.delete(uid) def messages(self, *args, **kwargs): folder = kwargs.get('folder', False) msg = "" if folder: self.connection.select(folder) msg = " from folder '{}'".format(folder) logger.info("Fetch list of messages{}".format(msg)) return self.fetch_list(**kwargs) def folders(self): return self.connection.list()
class Imbox(object): def __init__(self, hostname, username=None, password=None, ssl=True): self.server = ImapTransport(hostname, ssl=ssl) self.username = username self.password = password self.connection = self.server.connect(username, password) logger.info("Connected to IMAP Server with user {username} on {hostname}{ssl}".format( hostname=hostname, username=username, ssl=(" over SSL" if ssl else ""))) def logout(self): self.connection.close() self.connection.logout() logger.info("Disconnected from IMAP Server {username}@{hostname}".format( hostname=self.hostname, username=self.username)) def query_uids(self, **kwargs): query = build_search_query(**kwargs) message, data = self.connection.uid('search', None, query) if data[0] is None: return [] return data[0].split() def fetch_by_uid(self, uid): message, data = self.connection.uid('fetch', uid, '(BODY.PEEK[])') logger.debug("Fetched message for UID {}".format(int(uid))) raw_email = data[0][1] email_object = parse_email(raw_email) return email_object def fetch_list(self, **kwargs): uid_list = self.query_uids(**kwargs) logger.debug("Fetch all messages for UID in {}".format(uid_list)) for uid in uid_list: yield (uid, self.fetch_by_uid(uid)) def mark_seen(self, uid): logger.info("Mark UID {} with \\Seen FLAG".format(int(uid))) self.connection.uid('STORE', uid, '+FLAGS', '(\\Seen)') def delete(self, uid): logger.info("Mark UID {} with \\Deleted FLAG and expunge.".format(int(uid))) mov, data = self.connection.uid('STORE', uid, '+FLAGS', '(\\Deleted)') self.connection.expunge() def copy(self, uid, destination_folder): logger.info("Copy UID {} to {} folder".format(int(uid), str(destination_folder))) return self.connection.uid('COPY', uid, destination_folder) def move(self, uid, destination_folder): logger.info("Move UID {} to {} folder".format(int(uid), str(destination_folder))) if self.copy(uid, destination_folder): self.delete(uid) def messages(self, *args, **kwargs): folder = kwargs.get('folder', False) msg = "" if folder: self.connection.select(folder) msg = " from folder '{}'".format(folder) logger.info("Fetch list of massages{}".format(msg)) return self.fetch_list(**kwargs) def folders(self): return self.connection.list()
class Imbox(object): Error = imaplib.IMAP4.error AbortError = imaplib.IMAP4.abort ReadOnlyError = imaplib.IMAP4.readonly def __init__(self, hostname, username=None, password=None, ssl=True, port=None, gmail=False, zimbra=False): self.server = ImapTransport(hostname, port=port, ssl=ssl) self.connection = self.server.connect(username, password) self.username = username self.password = password self.gmail = gmail self.zimbra = zimbra def __enter__(self): self.connection() def __exit__(self, type, value, traceback): self.logout() def logout(self): self.connection.close() self.connection.logout() def select_folder(self, name, **kwargs): folder = encode_utf7(name) read_only = kwargs.get('readonly', True) self.connection.select(folder, readonly=read_only) def query_uids(self, **kwargs): query = build_search_query(**kwargs) message, data = self.connection.uid('search', None, query) return data[0].split() def fetch_by_uid(self, uid, **kwargs): folder = kwargs.get('folder', None) if folder: self.select_folder(folder) try: if self.gmail: message, data = self.connection.uid('fetch', uid, '(X-GM-MSGID X-GM-THRID UID FLAGS BODY.PEEK[])') # Don't mark the messages as read, save bandwidth with PEEK else: message, data = self.connection.uid('fetch', uid, '(UID FLAGS BODY.PEEK[])') except imaplib.IMAP4.abort: self.select_folder(folder) if self.gmail: message, data = self.connection.uid('fetch', uid, '(X-GM-MSGID X-GM-THRID UID FLAGS BODY.PEEK[])') else: message, data = self.connection.uid('fetch', uid, '(UID FLAGS BODY.PEEK[])') raw_email = data[0][1] self.maildata = {} groups = None if self.gmail and data is not None: pattern = re.compile("^(\d+) \(X-GM-THRID (?P<gthrid>\d+) X-GM-MSGID (?P<gmsgid>\d+) UID (?P<uid>\d+) FLAGS \((?P<flags>[^\)]*)\)") headers = data[0][0] groups = pattern.match(headers).groups() self.maildata['GTHRID'] = groups[1] self.maildata['GMSGID'] = groups[2] self.maildata['UID'] = groups[3] self.maildata['FLAGS'] = groups[4] if not self.gmail and data is not None: # Try this pattern first pattern = re.compile("^(\d+) \(UID (?P<uid>\d+) FLAGS \((?P<flags>[^\)]*)\)") match = pattern.search(data[0][0]) if match: groups = pattern.search(data[0][0]).groupdict() self.maildata['FLAGS'] = groups.get('flags', None) self.maildata['UID'] = groups.get('uid', None) # If no match, try this pattern (its usually yahoo f*****g things up) else: pattern = re.compile("^(\d+) \(FLAGS \((?P<flags>[^\)]*)\) UID (?P<uid>\d+)") match = pattern.search(data[0][0]) if match: groups = pattern.search(data[0][0]).groupdict() self.maildata['FLAGS'] = groups.get('flags', None) self.maildata['UID'] = groups.get('uid', None) # Last resort else: pattern = re.compile("^(\d+) \(UID (?P<uid>\d+)") groups = pattern.search(data[0][0]).groupdict() self.maildata['UID'] = groups.get('uid', None) self.maildata['FLAGS'] = groups.get('flags', None) self.maildata['data'] = raw_email email_object = parse_email(self.maildata) return email_object def fetch_list(self, **kwargs): print kwargs uid_list = self.query_uids(**kwargs) for uid in uid_list: yield (uid, self.fetch_by_uid(uid)) def mark_seen(self, uid): self.connection.uid('STORE', uid, '+FLAGS', '\\Seen') def delete(self, uid): mov, data = self.connection.uid('STORE', uid, '+FLAGS', '(\\Deleted)') self.connection.expunge() def copy(self, uid, destination_folder): return self.connection.uid('COPY', uid, destination_folder) def move(self, uid, destination_folder): if self.copy(uid, destination_folder): self.delete(uid) def messages(self, *args, **kwargs): folder = kwargs.get('folder', False) read_only = kwargs.get('readonly', True) if folder: self.select_folder(folder, readonly=read_only) return self.fetch_list(**kwargs) @property def folders(self): response = self.connection.list() status, folders = response[0], response[1] ignore_folder = r'\Noselect' flist = [] for folder in folders: if not ignore_folder in folder: flist.append(folder) folders = parse_folders(flist) folder_list = [] for box in folders: if self.zimbra: bad_folders = ['"Contacts"', '"Emailed Contacts"', '"Chats"',] # ignore these if box not in bad_folders: folder_list.append(box) else: if not ignore_folder in box: folder_list.append(box) return folder_list
class Imbox: authentication_error_message = None def __init__(self, hostname, username=None, password=None, ssl=True, port=None, ssl_context=None, policy=None, starttls=False, vendor=None): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context, starttls=starttls) self.hostname = hostname self.username = username self.password = password self.parser_policy = policy self.vendor = vendor or hostname_vendorname_dict.get(self.hostname) if self.vendor is not None: self.authentication_error_message = name_authentication_string_dict.get( self.vendor) try: self.connection = self.server.connect(username, password) except imaplib.IMAP4.error as e: if self.authentication_error_message is None: raise raise imaplib.IMAP4.error(self.authentication_error_message + '\n' + str(e)) def __enter__(self): return self def __exit__(self, type, value, traceback): self.logout() def logout(self): self.connection.close() self.connection.logout() def list(self): return self.connection.list() def check_success(self, response): if 'OK' in str(response): return True else: return False def is_contain_chinese(self, check_str): for ch in check_str: if u'\u4e00' <= ch <= u'\u9fff': return True return False def mark_seen(self, folder, uids): if uids == '' or uids == None: return self.select(folder) r1 = self.connection.uid('STORE', (uids), '-FLAGS', '(\\UNSEEN)') r2 = self.connection.uid('STORE', (uids), '+FLAGS', '(\\SEEN)') return self.check_success(r1) & self.check_success(r2) def mark_unseen(self, folder, uids): if uids == '' or uids == None: return self.select(folder) r1 = self.connection.uid('STORE', (uids), '-FLAGS', '(\\SEEN)') r2 = self.connection.uid('STORE', (uids), '+FLAGS', '(\\UNSEEN)') return self.check_success(r1) & self.check_success(r2) def mark_flag(self, folder, uids): if uids == '' or uids == None: return self.select(folder) r1 = self.connection.uid('STORE', (uids), '-FLAGS', '(\\UNFLAGGED)') r2 = self.connection.uid('STORE', (uids), '+FLAGS', '(\\FLAGGED)') return self.check_success(r1) & self.check_success(r2) def mark_unflag(self, folder, uids): if uids == '' or uids == None: return self.select(folder) r1 = self.connection.uid('STORE', (uids), '-FLAGS', '(\\FLAGGED)') r2 = self.connection.uid('STORE', (uids), '+FLAGS', '(\\UNFLAGGED)') return self.check_success(r1) & self.check_success(r2) def copy(self, origin_folder, uids, target_folder): if uids == '' or uids == None: return self.select(origin_folder) r = self.connection.uid('COPY', (uids), self.get_folder(target_folder)) return self.check_success(r) def move(self, source_folder, uids, target_folder): if uids == '' or uids == None: return if self.copy(source_folder, uids, target_folder): return self.permanently_delete(source_folder, uids) def delete(self, origin_folder, uids): if uids == '' or uids == None: return if self.copy(origin_folder, (uids), 'deleted'): return self.permanently_delete(origin_folder, (uids)) def permanently_delete(self, folder, uids): if uids == '' or uids == None: return self.select(folder) r1 = self.connection.uid('STORE', (uids), '+FLAGS', '(\\Deleted)') r2 = self.connection.expunge() return self.check_success(r1) & self.check_success(r2) def draft(self, receivers, mail_subject, mail_content, cc=None, bcc=None, attachment_names=None, illustrate_names=None): receivers = str(receivers).split(',') attachment_name_list = [] if attachment_names != None: attachment_name_list = str(attachment_names).split(',') illustrate_name_list = [] if illustrate_names != None: illustrate_name_list = str(illustrate_names).split(',') if len(attachment_name_list) == 0 and len(illustrate_name_list) == 0: message = MIMEText(mail_content, 'html', 'utf-8') message['From'] = self.username message['To'] = ','.join(receivers) message['Subject'] = mail_subject if cc != None: cc = str(cc).split(',') receivers.extend(cc) message['Cc'] = ','.join(cc) if bcc != None: bcc = str(bcc).split(',') receivers.extend(bcc) message['Bcc'] = ','.join(bcc) r = self.connection.append(self.get_folder('drafts'), None, None, message.as_string().encode('utf-8')) return self.check_success(r) if len(attachment_name_list) != 0 and len(illustrate_name_list) == 0: # 创建一个带附件的实例 message = MIMEMultipart() message['From'] = self.username message['To'] = ','.join(receivers) message['Subject'] = mail_subject if cc != None: cc = str(cc).split(',') receivers.extend(cc) message['Cc'] = ','.join(cc) if bcc != None: bcc = str(bcc).split(',') receivers.extend(bcc) message['Bcc'] = ','.join(bcc) # 邮件正文内容 message.attach(MIMEText(mail_content, 'html', 'utf-8')) # 构造附件 for attach_name in attachment_name_list: if self.is_contain_chinese(attach_name): attach = MIMEText( open(attachment_path + "/" + attach_name, 'rb').read(), 'base64', 'utf-8') attach["Content-Type"] = 'application/octet-stream' attach.add_header("Content-Disposition", "attachment", filename=("gbk", "", attach_name)) message.attach(attach) else: attach = MIMEText( open(attachment_path + "/" + attach_name, 'rb').read(), 'base64', 'utf-8') attach["Content-Type"] = 'application/octet-stream' attach[ "Content-Disposition"] = 'attachment; filename="' + attach_name + '"' message.attach(attach) r = self.connection.append(self.get_folder('drafts'), None, None, message.as_string().encode('utf-8')) return self.check_success(r) if len(attachment_name_list) == 0 and len(illustrate_name_list) != 0: # 创建一个带插图的实例 msg_root = MIMEMultipart('related') msg_root['From'] = self.username msg_root['To'] = ','.join(receivers) msg_root['Subject'] = mail_subject if cc != None: cc = str(cc).split(',') receivers.extend(cc) msg_root['Cc'] = ','.join(cc) if bcc != None: bcc = str(bcc).split(',') receivers.extend(bcc) msg_root['Bcc'] = ','.join(bcc) # 邮件正文内容 msg_alternative = MIMEMultipart('alternative') msg_alternative.attach(MIMEText(mail_content, 'html', 'utf-8')) msg_root.attach(msg_alternative) # 构造插图 for illustrate_name in illustrate_name_list: if not self.is_contain_chinese(illustrate_name): fp = open(illustrate_path + "/" + illustrate_name, 'rb') msg_image = MIMEImage(fp.read()) fp.close() msg_image.add_header('Content-ID', '<' + illustrate_name + '>') msg_root.attach(msg_image) else: raise ValueError("Illustration's name can not be chinese!") r = self.connection.append(self.get_folder('drafts'), None, None, msg_root.as_string().encode('utf-8')) return self.check_success(r) if len(attachment_name_list) != 0 and len(illustrate_name_list) != 0: # 创建一个带附件的实例 msg_root = MIMEMultipart('related') # msg_root['From'] = formataddr([sender, sender], charset='utf-8') # msg_root['To'] = formataddr([receiver, receiver], charset='utf-8') msg_root['From'] = self.username msg_root['To'] = ','.join(receivers) msg_root['Subject'] = mail_subject if cc != None: cc = str(cc).split(',') receivers.extend(cc) msg_root['Cc'] = ','.join(cc) if bcc != None: bcc = str(bcc).split(',') receivers.extend(bcc) msg_root['Bcc'] = ','.join(bcc) # 邮件正文内容 msg_alternative = MIMEMultipart('alternative') msg_alternative.attach(MIMEText(mail_content, 'html', 'utf-8')) msg_root.attach(msg_alternative) # 构造附件 for attach_name in attachment_name_list: if self.is_contain_chinese(attach_name): attach = MIMEText( open(attachment_path + "/" + attach_name, 'rb').read(), 'base64', 'utf-8') attach["Content-Type"] = 'application/octet-stream' attach.add_header("Content-Disposition", "attachment", filename=("gbk", "", attach_name)) msg_root.attach(attach) else: attach = MIMEText( open(attachment_path + "/" + attach_name, 'rb').read(), 'base64', 'utf-8') attach["Content-Type"] = 'application/octet-stream' attach[ "Content-Disposition"] = 'attachment; filename="' + attach_name + '"' msg_root.attach(attach) # 构造插图 for illustrate_name in illustrate_name_list: if not self.is_contain_chinese(illustrate_name): fp = open(illustrate_path + "/" + illustrate_name, 'rb') msg_image = MIMEImage(fp.read()) fp.close() msg_image.add_header('Content-ID', '<' + illustrate_name + '>') msg_root.attach(msg_image) else: raise ValueError("Illustration's name can not be chinese!") r = self.connection.append(self.get_folder('drafts'), None, None, msg_root.as_string().encode('utf-8')) return self.check_success(r) return False def messages(self, **kwargs): folder = kwargs.get('folder', False) messages_class = Messages if self.vendor == 'gmail': messages_class = GmailMessages if self.vendor == 'qq': messages_class = QQmailMessages if folder: self.connection.select( messages_class.FOLDER_LOOKUP.get((folder.lower())) or folder) del kwargs['folder'] else: self.connection.select('INBOX') return messages_class(connection=self.connection, parser_policy=self.parser_policy, **kwargs) def folders(self): return self.connection.list() def get_folder(self, folder): messages_class = Messages if self.vendor == 'gmail': messages_class = GmailMessages if self.vendor == 'qq': messages_class = QQmailMessages if folder: return messages_class.FOLDER_LOOKUP.get((folder.lower())) or folder def select(self, folder): if folder: self.connection.select(self.get_folder(folder))
class Imbox: authentication_error_message = None def __init__(self, hostname, username=None, password=None, ssl=True, port=None, ssl_context=None, policy=None, starttls=False, vendor=None): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context, starttls=starttls) self.hostname = hostname self.username = username self.password = password self.parser_policy = policy self.vendor = vendor or hostname_vendorname_dict.get(self.hostname) if self.vendor is not None: self.authentication_error_message = name_authentication_string_dict.get( self.vendor) try: self.connection = self.server.connect(username, password) except imaplib.IMAP4.error as e: if self.authentication_error_message is None: raise raise imaplib.IMAP4.error( self.authentication_error_message + '\n' + str(e)) logger.info("Connected to IMAP Server with user {username} on {hostname}{ssl}".format( hostname=hostname, username=username, ssl=(" over SSL" if ssl or starttls else ""))) def __enter__(self): return self def __exit__(self, type, value, traceback): self.logout() def logout(self): self.connection.close() self.connection.logout() logger.info("Disconnected from IMAP Server {username}@{hostname}".format( hostname=self.hostname, username=self.username)) def mark_seen(self, uid): logger.info("Mark UID {} with \\Seen FLAG".format(int(uid))) self.connection.uid('STORE', uid, '+FLAGS', '(\\Seen)') def mark_flag(self, uid): logger.info("Mark UID {} with \\Flagged FLAG".format(int(uid))) self.connection.uid('STORE', uid, '+FLAGS', '(\\Flagged)') def delete(self, uid): logger.info( "Mark UID {} with \\Deleted FLAG and expunge.".format(int(uid))) self.connection.expunge() def copy(self, uid, destination_folder): logger.info("Copy UID {} to {} folder".format( int(uid), str(destination_folder))) return self.connection.uid('COPY', uid, destination_folder) def move(self, uid, destination_folder): logger.info("Move UID {} to {} folder".format( int(uid), str(destination_folder))) if self.copy(uid, destination_folder): self.delete(uid) def messages(self, **kwargs): folder = kwargs.get('folder', False) messages_class = Messages if self.vendor == 'gmail': messages_class = GmailMessages if folder: self.connection.select( messages_class.FOLDER_LOOKUP.get((folder.lower())) or folder) msg = " from folder '{}'".format(folder) del kwargs['folder'] else: msg = " from inbox" logger.info("Fetch list of messages{}".format(msg)) return messages_class(connection=self.connection, parser_policy=self.parser_policy, **kwargs) def folders(self): return self.connection.list()