У программистов иногда стоит задача скриптами отправлять почту ( я не про спам ;) ), это может быть как контактная форма, так и какая то служебная информация от скриптов. Например скрипт оповещает о завершении какой-либо задачи, это могут быть какие то периодические отчеты, либо в случае ошибки отправлять письмо с данными о "происшествии".
Так вот для последнего в Python есть такая библиотека которая называется, как не сложно догадаться, logging. У нее есть много возможностей, но основная ее задача это логирование сообщений со скриптов. Вот так выглядит простейшее использование этой библиотеки:
import logging logging.basicConfig(level=logging.DEBUG, filename='/tmp/my_demo.log', filemode='a')
Потом в любом месте скрипта делаем так
import logging
logging.debug('My demo log string...')и в файле /tmp/my_demo.log мы увидем строчку
DEBUG:root:Demom log string...
Так вот когда я сказал что у модуля logging есть много возможностей, я не имел ввиду что логировать так как показано в примере это круто. По умолчанию да, сообщения логируются просто в файл. Но изначально существуют обработчики, назовем их логерами.
- StreamHandler посылает логируемое сообщение в поток (файл подобные объекты).
- FileHandler – в файл на диске.
- BaseRotatingHandler - это базовый класс для обработчиков которые "ротируют" лог файлы. Не рекомендуется использовать его напрямую, используйте вместо него TimedRotatingFileHandler.
- RotatingFileHandler - сообщения пишутся в файл на диске, ротируются по достижении указанного размера файла.
- TimedRotatingFileHandler тоже самое что и предыдущий, только ротируется при определенных временных интервалах.
- SocketHandler пишет сообщение в TCP/IP сокет.
- DatagramHandler – в UDP сокет.
- SMTPHandler отправляет сообщение по на почту.
- SysLogHandler отправляет сообщение демону syslog в Unix, возможно и на удаленную машину.
- NTEventLogHandler посылает сообщение логу событий Windows NT/2000/XP (о винде даже позаботились, хотя зачем ей это :) ).
- MemoryHandler пишем в буфер в памяти который сбрасывается при определенных критериях.
- HTTPHandler отправляет сообщение в виде "GET" или "POST" HTTP запроса на сервер.
Вот какой богатый набор. Но и этого бывает недостаточно иногда. Об этом сегодня и говорим, и мне недостаточно стандартного SMTPHandler, т.к. у него есть один недостаток - он не может авторизоваться на сервере. Но и для того чтобы отсылать через smtp сервер gmail, нужно еще небольшое дополнение.
Все что нам потребуется, это расширить стандартный SMTPHandler, немножко дописав метод __init__ чтобы он принимал наши логин и пароль, и переписать метод emit, так, чтобы он правильно отправил сообщение через гмыло. Вот что получилось.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import logging, logging.handlers, types, smtplib
from email.MIMEText import MIMEText
class GmailHandler(logging.handlers.SMTPHandler):
def __init__(self, mailhost, fromaddr, toaddrs, subject, *args, **kwargs):
logging.Handler.__init__(self)
if type(mailhost) == types.TupleType:
host, port = mailhost
self.mailhost = host
self.mailport = port
else:
self.mailhost = mailhost
self.mailport = None
self.fromaddr = fromaddr
if type(toaddrs) == types.StringType:
toaddrs = [toaddrs]
self.toaddrs = toaddrs
self.subject = subject
# added this lines
self.auth_username = kwargs.get('auth_username', None)
self.auth_password = kwargs.get('auth_password', None)
if self.auth_username and self.auth_password:
self.auth_required = True
else:
self.auth_required = False
def emit(self, record):
try:
msg = MIMEText(self.format(record), 'html', 'utf-8')
msg['Subject'] = self.getSubject(record)
msg['From'] = self.fromaddr
msg['Sender'] = self.fromaddr
msg['To'] = ','.join(self.toaddrs)
port = self.mailport
if not port:
port = smtplib.SMTP_PORT
session = smtplib.SMTP(self.mailhost, port)
session.ehlo()
# TLS
session.starttls()
session.ehlo()
if self.auth_required:
session.login(self.auth_username, self.auth_password)
session.sendmail(self.fromaddr, ','.join(self.toaddrs), msg.as_string())
session.quit()
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)Пользоваться вот так
import logging
from gmail_logging_handler import GmailHandler
rootLogger = logging.getLogger('')
gmail_handler = GmailHandler(
('smtp.gmail.com', 587),
'from_email@gmail.com',
'to_email@gmail.com',
"Error at site.com",
auth_username="GMAIL_EMAIL",
auth_password="PASSWORD"
)
rootLogger.addHandler(gmail_handler)
logging.error('This is an error message that should be sent by mail.')Естественно вам надо вставить свои логин и пароль от gmail.
Скачать GmailLoggingHandler одним файлом.
Пользуйтесь наздоровье.
Вот тут например есть реализация обработчика который отсылает сообщения на Jabber аккаунт (он же Google Talk). А куда вам еще надо отсылать лог сообщения?
1 comments:
[...] Если вы пишите скрипты на продажу либо на заказ рано или поздно встает вопрос как скрыть код скрипта который вы продаете и не отдавать исходный код. Зачем это надо? Например для того чтобы скрипт сам по себе не пошел по рукам, за что вы будете получать 0$ со скрипта, который вы сделали для продажи. Для PHP был создан Zend Encoder. Но я уже не сижу на PHP, поэтому сегодня расскажу как скрыть код скрипта на Python. [...]
Post a Comment