def send_email(recipients, subject, message, message_type='plain'): """ Sends email.""" # TODO: put mail configs in a config file # TODO: add attachments # TODO: find a way to change the sender (gmail security makes it hard) username = '******' password = '******' if isinstance(recipients, basestring): recipients = recipients.split(',') msg = MIMEMultipart('alternative') msg.add_header('Subject', subject) msg.add_header('From', 'Resumebabel <*****@*****.**>') for recipient in recipients: msg.add_header('To', recipient) body = MIMEText(message.encode('utf-8'), message_type, 'utf-8') msg.attach(body) # The actual mail send server = smtplib.SMTP('smtp.gmail.com:587') server.starttls() server.login(username, password) server.sendmail(username, msg.get_all('To'), msg.as_string()) server.quit()
def logHandler(email=[]): #rename file with timestamp Filepath = 'C:\Projects\Python\CDK_DW DAB\DATA_MIGRATION_DAB.log' modifiedTime = os.path.getmtime(Filepath) timestamp = datetime.fromtimestamp(modifiedTime).strftime("%b-%d-%Y") prevName = 'C:\Projects\Python\CDK_DW DAB\DATA_MIGRATION_DAB.log' newName = 'C:\Projects\Python\CDK_DW DAB\DATA_MIGRATION_DAB' os.rename(prevName, newName + "_" + timestamp + ".log") filename = 'DATA_MIGRATION_DAB' + "_" + timestamp + ".log" #Email body = "Nightly DATA Pull. Please Review Log for Errors" # Log in to server using secure context and send email msg = MIMEMultipart('alternative') msg['Subject'] = ' DATA PULL REPORT' msg['From'] = 'Systems <*****@*****.**>' to = email for item in to: msg.add_header('To', item) part1 = (MIMEText(body, "plain")) # Open log file in binary mode with open(filename, "rb") as attachment: # Add file as application/octet-stream # Email client can usually download this automatically as attachment part = MIMEBase("application", "octet-stream") part.set_payload(attachment.read()) # Encode file in ASCII characters to send by email encoders.encode_base64(part) # Add header as key/value pair to attachment part part.add_header( "Content-Disposition", f"attachment; filename= {filename}", ) msg.attach(part1) # Add attachment to message msg.attach(part) s = smtplib.SMTP('mail_server') # s.send_message(msg) s.send_message(msg, to_addrs=msg.get_all('To')) s.close() #compress logs os.chdir("C:\Projects\Python\CDK_DW DAB") zip1 = zipfile.ZipFile('DAB_LOGS.zip', 'a') zip1.write(filename, compress_type=zipfile.ZIP_DEFLATED) zip1.close() os.remove(filename)
def sendmail(mailto, subject, message, subtype='html', charset='utf-8', smtpconfig=None, attachments={}, use_starttls=False, **headers): ''' Send an email to the given address. Additional SMTP headers may be specified as keyword arguments. ''' if not smtpconfig: # we support both smtp and mail for legacy reasons # smtp is the correct usage. smtpconfig = config.get('smtp') or config.get('mail') # mailto arg is explicit to ensure that it's always set, but it's processed # mostly the same way as all other headers headers['To'] = _string_or_list(mailto) msg = MIMEMultipart('alternative') msg['Subject'] = subject for key, value in six.iteritems(headers): for val in _string_or_list(value): msg.add_header(key, val) text = MIMEText(message, subtype, charset) msg.attach(text) # Add attachments for file_name, file_payload in attachments.items(): part = MIMEBase('application', 'octet-stream') part.set_payload(file_payload.encode(charset)) Encoders.encode_base64(part) part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % file_name ) msg.attach(part) if not 'From' in msg: msg['From'] = smtpconfig.get('from') mailfrom = msg['From'] assert isinstance(mailfrom, six.string_types) recipients = [] for toheader in ('To', 'CC', 'BCC'): recipients += msg.get_all(toheader, []) if 'BCC' in msg: del msg['BCC'] smtp = smtplib.SMTP(smtpconfig.get('host'), smtpconfig.get('port')) if smtpconfig.get('username', None) is not None and smtpconfig.get('password', None) is not None: if use_starttls: smtp.elho() smtp.starttls() smtp.elho() smtp.login(smtpconfig.get('username'), smtpconfig.get('password')) smtp.sendmail(mailfrom, recipients, msg.as_string()) smtp.quit() log.info('Sent email to %s (Subject: %s)', recipients, subject)
def ic_sendmail(sender_address = '*****@*****.**',sender_name = 'rancid-centos',receiver_info= {},cc_info= {}, subject='',comments='',list_message=[],str_message='',layout='html_table'): receiver_list = '' cc_list = '' #receiver_addresses = '' msg = MIMEMultipart('alternative') for name,address in receiver_info.items(): receiver_list += " %(name)s <%(address)s>," % {'name': name,'address': address} for name,address in cc_info.items(): cc_list += " %(name)s <%(address)s>," % {'name': name,'address': address} for address in receiver_info.values(): msg.add_header('to',address) for address in cc_info.values(): msg.add_header('cc',address) txt_body = MIMEText(''.join(str_message), 'plain') html_body = MIMEText(generate_html_message(message_lines=list_message,comments=comments), 'html') fh = open('last_email','w') fh.write(html_body.as_string()) msg['Subject'] = subject msg['From'] = sender_address #msg['to'] = receiver_addresses #msg['cc'] = receiver_addresses msg.preamble = subject msg.attach(txt_body) msg.attach(html_body) try: smtpObj = smtplib.SMTP('localhost') if cc_info: smtpObj.sendmail(sender_address, msg.get_all('to') + msg.get_all('cc'), msg.as_string()) else: smtpObj.sendmail(sender_address, msg.get_all('to'), msg.as_string()) print "Successfully sent email" return 0 except Exception , e: print e print "Error: unable to send email" return 1
def sendmail(mailto, subject, message, subtype='html', charset='utf-8', smtpconfig=None, **headers): ''' Send an email to the given address. Additional SMTP headers may be specified as keyword arguments. ''' if not smtpconfig: # we support both smtp and mail for legacy reasons # smtp is the correct usage. smtpconfig = config.get('smtp') or config.get('mail') # mailto arg is explicit to ensure that it's always set, but it's processed # mostly the same way as all other headers headers['To'] = _string_or_list(mailto) msg = MIMEMultipart('alternative') msg['Subject'] = subject for key, value in six.iteritems(headers): for val in _string_or_list(value): msg.add_header(key, val) text = MIMEText(message, subtype, charset) msg.attach(text) if not 'From' in msg: msg['From'] = smtpconfig.get('from') mailfrom = msg['From'] assert isinstance(mailfrom, six.string_types) recipients = [] for toheader in ('To', 'CC', 'BCC'): recipients += msg.get_all(toheader, []) if 'BCC' in msg: del msg['BCC'] smtp = smtplib.SMTP(smtpconfig.get('host'), smtpconfig.get('port')) if smtpconfig.get('username', None) is not None and smtpconfig.get( 'password', None) is not None: smtp.login(smtpconfig.get('username'), smtpconfig.get('password')) smtp.sendmail(mailfrom, recipients, msg.as_string()) smtp.quit() log.info('Sent email to %s (Subject: %s)', recipients, subject)
def send_a_mail(number): body = 'test email ' + str(number) msg = MIMEMultipart('alternative') msg['Subject'] = str(number) msg['From'] = '*****@*****.**' msg.add_header('to','*****@*****.**') msg.preamble = str(number) txt_body = MIMEText(body, 'plain') msg.attach(txt_body) try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail('*****@*****.**', msg.get_all('to'), msg.as_string()) print "sent email " + str(number) return 0 except Exception , e: print e
def sendmail(mailto, subject, message, subtype='html', charset='utf-8', smtpconfig=None, **headers): ''' Send an email to the given address. Additional SMTP headers may be specified as keyword arguments. ''' if not smtpconfig: # we support both smtp and mail for legacy reasons # smtp is the correct usage. smtpconfig = config.get('smtp') or config.get('mail') # mailto arg is explicit to ensure that it's always set, but it's processed # mostly the same way as all other headers headers['To'] = _string_or_list(mailto) msg = MIMEMultipart('alternative') msg['Subject'] = subject for key, value in headers.iteritems(): for val in _string_or_list(value): msg.add_header(key, val) text = MIMEText(message, subtype, charset) msg.attach(text) if not 'From' in msg: msg['From'] = smtpconfig.get('from') mailfrom = msg['From'] assert isinstance(mailfrom, basestring) recipients = [] for toheader in ('To', 'CC', 'BCC'): recipients += msg.get_all(toheader, []) if 'BCC' in msg: del msg['BCC'] smtp = smtplib.SMTP(smtpconfig.get('host'), smtpconfig.get('port')) if smtpconfig.get('username', None) is not None and smtpconfig.get('password', None) is not None: smtp.login(smtpconfig.get('username'), smtpconfig.get('password')) smtp.sendmail(mailfrom, recipients, msg.as_string()) smtp.quit() log.info('Sent email to %s (Subject: %s)', recipients, subject)
def send_email(sender, recipients, subject, body): """ Send out an e-mail to recipient(s) """ # Create message container - the correct MIME type is multipart/alternative here! msg = MIMEMultipart('alternative') msg['subject'] = subject msg['From'] = sender msg['To'] = "" # Have to add to proper To recipient header for each e-mail recipient for addr in recipients: msg.add_header('To', addr) msg.preamble = "Your mail reader does not support the following HTML report format. Lame." # Record the MIME type text/html. html_body = MIMEText(body, 'html') # Attach parts into message container. # According to RFC 2046, the last part of a multipart message, in this case # the HTML message, is best and preferred. msg.attach(html_body) ### DEBUGGING SMTP handshake only #server.set_debuglevel(1) # The actual sending of the e-mail server = smtplib.SMTP('localhost') # use this if you have multiple recipients generated via list server.sendmail(sender, msg.get_all('To'), msg.as_string()) # use this if you're using a non-list (string) for e-mail recipient #server.sendmail(FROM, [TO], msg.as_string()) # Close smtp connection server.quit()
class SmartMail(object): """ Класс для работы с почтой по протоколам SMTP и IMAP. """ _public_methods_ = [ 'connect', 'set_filter', 'set_fields', 'get_messages', 'messages_count', 'get_message', 'files_count', 'save_file', 'get_file_name', 'set_dir', 'set_folder', 'add_recipient','send','add_file'] _public_attrs_ = ['date', 'sender', 'recipient', 'subject', 'body', 'type'] _readonly_attrs_ = ['detach_dir'] _reg_progid_ = "lkl.SmartMail" # NEVER copy the following ID # Use "print pythoncom.CreateGuid()" to make a new one. _reg_clsid_ = "{CC16108F-63D9-497F-8C26-D7861000192B}" def __init__(self): self.folder = "INBOX" def clear_current_data(self): pass #TODO: Вынести сюда очистку данных по текущему письму def connect(self, host, port, username, userpass, connection_type, use_ssl=0): """ Синтаксис: connect(host, port, username, userpass, connection_type, use_ssl=0): int, 1 or 0 Параметры: host - str, Строка - Имя или IP почтового сервера; port - str or int, Строка или Число - Порт почтового сервера; username - str, Строка - Имя пользователя, e-mail адрес; userpass - str, Строка - Пароль пользователя; connection_type - str, Строка, ('imap' or 'pop3' or 'smtp') - Тип подключения к серверу; use_ssl - int, Число, (1 or 0) - Использовать SSL (1) или нет (0); Описание: Инициализация подключения, установка первоначальных параметров. Возвращаемое значение: Результат, число, 1 - удачно, 0 - неудачно. """ self.host = str(host).strip() self.port = int(port) self.username = str(username).strip() self.userpass = str(userpass).strip() self.connection_type = str(connection_type).strip().lower() if int(use_ssl): self.use_ssl = True else: self.use_ssl = False self.detach_dir = os.getcwd() self._sender = None self._recipient = None self._date = None self.type = 1 # integer, "text/plain" (0) or "text/html" (1) self.coding = 'us-ascii' self._body = None self._attachments = [] self.current_mail = None ## ----------------IMAP----------------- self.filter_string = '' self.fields = [] self.items = [] self.folder = "INBOX" if self.connection_type == 'imap': if self.use_ssl: self.connection = imaplib.IMAP4_SSL(self.host, self.port) else: self.connection = imaplib.IMAP4(self.host, self.port) self.connection.login(self.username,self.userpass) self.connection.select(self.folder) ## ----------------SMTP----------------- elif self.connection_type == 'smtp': self.connection = smtplib.SMTP(self.host, self.port) if self.use_ssl: self.connection.ehlo() self.connection.starttls() self.connection.ehlo() self.connection.login(self.username, self.userpass) self.current_mail = MIMEMultipart() return 1 def set_dir(self, path): """ Синтаксис: set_dir(path): int, 1 or 0 Параметры: path - str, Строка - Каталог для сохранения вложений; Описание: Устанавливает путь к каталогу вложений. Возвращаемое значение: Результат, число, 1 - удачно, 0 - неудачно. """ if not path: return 0 norm_path = os.path.normpath(path) if os.path.isdir(norm_path): self.detach_dir = norm_path return 1 else: return 0 def set_filter(self, filter_string=""): """ Синтаксис: set_filter(filter_string): int, 1 or 0 Параметры: filter_string - str, Строка - Строка фильтра; Описание: Устанавливает строку фильтра IMAP перед выборкой, к примеру "(SINCE 01-Mar-2011 BEFORE 05-Mar-2011)" Возвращаемое значение: Результат, число, 1 - удачно, 0 - неудачно. """ if filter_string: self.filter_string = str(filter_string) return 1 def set_folder(self, folder_name="Inbox"): """ Синтаксис: set_folder(self, folder_name="Inbox"): int, 1 or 0 Параметры: folder_name - str, Строка - Название почтового каталога; Описание: Устанавливает текущий почтовый каталог, по-умолчанию - "Inbox" Возвращаемое значение: Результат, число, 1 - удачно, 0 - неудачно. """ if folder_name: self.folder = str(folder_name).strip() return 1 return 0 def set_fields(self, fields_string=""): """ (Пока не используется) """ self.fields = str(fields_string).split(',') return 1 def get_messages(self): """ Синтаксис: get_messages(): int, 1 or 0 Параметры: нет. Описание: Инициализирует выборку писем. Возвращаемое значение: Результат, число, 1 - удачно, 0 - неудачно. """ response, items = self.connection.search(None, self.filter_string) print response, items self.items = items[0].split(' ') return response def messages_count(self): """ Синтаксис: messages_count(): int Параметры: нет. Описание: Возвращает кол-во писем в выборке. Возвращаемое значение: Количество писем, число. """ return len(self.items) def get_message(self, message_number=1): """ Синтаксис: get_message(message_number): int, 1 or 0 Параметры: message_number - int, Число - Порядковый номер письма. Описание: Получает письмо из выборки по порядковому номеру. Нумерация идет с 1. Возвращаемое значение: Результат, число, 1 - удачно, 0 - неудачно. """ emailid = self.items[int(message_number)-1] try: resp, (data, internaldate) = self.connection.fetch(emailid, "(RFC822 INTERNALDATE)") except Exception as e: print e return -1 self._date = internalDate_to_datetime(internaldate) # сразу получаем дату сообщения #return "OK!" email_body = data[1] mail = email.message_from_string(email_body) mail2 = maillib.Message.from_message(mail) # if mail.get_content_maintype() != 'multipart': # return 0 # else: self.current_mail = mail self.current_mail2 = mail2 return 1 def files_count(self): """ Синтаксис: files_count(): int Параметры: нет. Описание: Возвращает кол-во вложений в текущем письме. Возвращаемое значение: Количество вложеных файлов, число. """ if not self.current_mail: return 0 files_count = 0 for part in self.current_mail.walk(): #### multipart/* are just containers if part.get_content_maintype() == 'multipart': continue if part.get('Content-Disposition') is None: continue files_count += 1 return files_count def save_file(self, file_number=1): """ Синтаксис: save_file(file_number): str Параметры: file_number - int, Число - Порядковый номер вложения. Описание: Сохраняет файл-вложение с порядковым номером <file_number> в каталог вложений. Возвращает имя файла. Нумерация идет с 1. Возвращаемое значение: Имя файла, строка. """ if not file_number: return 0 if not self.detach_dir: self.detach_dir = os.getcwd() num = 0 for part in self.current_mail.walk(): #### multipart/* are just containers if part.get_content_maintype() == 'multipart': continue if part.get('Content-Disposition') is None: continue num += 1 if num <> int(file_number): continue # получаем только нужный файл filename = decode_text(part.get_filename()) counter = 1 if not filename: filename = 'part-%03d%s' % (counter, 'bin') counter += 1 att_path = os.path.abspath(os.path.join(self.detach_dir, filename)) try: fp = open(att_path, 'wb+') # перезаписываем, если такой файл уже есть fp.write(part.get_payload(decode=True)) fp.close() return att_path except: return 0 def get_file_name(self, file_number=1): """ Синтаксис: get_file_name(file_number): str Параметры: file_number - int, Число - Порядковый номер вложения. Описание: Возвращает имя файла-вложения с порядковым номером <file_number>. Нумерация идет с 1. Возвращаемое значение: Имя файла, строка. """ if not file_number: return 0 if not self.detach_dir: self.detach_dir = os.getcwd() num = 0 for part in self.current_mail.walk(): #### multipart/* are just containers if part.get_content_maintype() == 'multipart': continue if part.get('Content-Disposition') is None: continue num += 1 if num <> int(file_number): continue # получаем только нужный файл filename = decode_text(part.get_filename()) counter = 1 if not filename: filename = 'part-%03d%s' % (counter, 'bin') counter += 1 return filename def get_body(self): """ Синтаксис: get_body(): str Параметры: нет. Описание: Возвращает тело текущего письма, приоритет - если есть HTML возвращается он, в противном случае возвращается PLAIN. Возвращаемое значение: Тело письма, строка. """ if not self.current_mail: return 0 # maintype = self.current_mail.get_content_maintype() # if maintype == 'multipart': # for part in self.current_mail.get_payload(): # if part.get_content_maintype() == 'text': # return part.get_payload(decode=True) # elif maintype == 'text': # return self.current_mail.get_payload(decode=True) text_html = self.current_mail2.html if not text_html: text_html = self.current_mail2.body self._body = text_html return self._body def add_recipient(self, recipient): """ Синтаксис: add_recipient(recipient): None Параметры: recipient - str, Строка, список получателей письма Описание: Возвращает тело текущего письма, приоритет - если есть HTML возвращается он, в противном случае возвращается PLAIN. Возвращаемое значение: Тело письма, строка. """ if (self.connection_type == 'smtp') and (self.current_mail): #self._recipient.append(recipient.strip()) self._recipient.extend(recipient.strip()) def send(self): """ Отправляет письмо по протоколу SMTP """ if self.connection_type != 'smtp': return -1 if not len(self._recipient): return -2 if not self._sender: self._sender = self.username if not self._date: self._date = formatdate(localtime=True) self.current_mail['From'] = self._sender self.current_mail['To'] = COMMASPACE.join(self._recipient) self.current_mail['Date'] = self._date self.current_mail['Subject'] = self._subject body_type = 'plain' if self.type == 1: body_type = 'html' self.current_mail.attach(MIMEText(self._body, body_type, self.coding)) for f in self._attachments: part = MIMEBase('application', "octet-stream") part.set_payload(open(f,"rb").read()) email.Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f)) self.current_mail.attach(part) self.connection.sendmail(self._sender, self._recipient, self.current_mail.as_string()) #self.connection.rset() #??? self.connection.close() def add_file(self, filename): if (self.connection_type != 'smtp') and (not self.current_mail): return -1 f = os.path.abspath(filename) if not (os.path.isfile(f)): return -2 self._attachments.append(f) #--------date attribute--------- @property def date(self): return self._date @date.getter def date(self): if not self.current_mail: return 0 else: return self._date @date.setter def date(self, value): if self.connection_type == 'smtp': self._date = str_to_internaldate(value.strip()) # date in format dd.mm.yyyy (%d.%m.%Y) #--------sender attribute------ @property def sender(self): return self._sender @sender.getter def sender(self): if self.connection_type == 'imap': if not self.current_mail: return "" else: return decode_email_header(self.current_mail, "From")[1] @sender.setter def sender(self, value): if self.connection_type == 'smtp': self._sender = value.strip() #--------recipient attribute---- @property def recipient(self): return self._recipient @recipient.getter def recipient(self): if not self.current_mail: return 0 else: tos = self.current_mail.get_all('to', []) tos = email.utils.getaddresses(tos) self._recipient = [i[1] for i in tos] return ';'.join(self._recipient) @recipient.setter def recipient(self, value): self._recipient = value.strip() #--------subject attribute------ @property def subject(self): # return self._subject pass @subject.getter def subject(self): if not self.current_mail: return 0 else: return decode_email_header(self.current_mail, "Subject") @subject.setter def subject(self, value): if self.connection_type == 'smtp': self._subject = value.strip() #--------body attribute--------- @property def body(self): pass @body.getter def body(self): if self.connection_type == 'imap': return self.get_body() elif self.connection_type == 'smtp': return self._body else: return None @body.setter def body(self, value): if self.connection_type == 'smtp': self._body = value