def refuse(self, m, mylist, reason): deepdbg('Refuse mail for %s' % unicode(mylist)) msgfrom = mylist.list_address_extended('owner') msgto = m['From'] reason = u"\n\nYour message to the list %s has been refused\n\n" % unicode(mylist) + reason # create mail mail = MIMEMultipart() mail['Subject'] = u"Your message to the list %s has been refused " % unicode(mylist) mail['From'] = msgfrom mail['To'] = msgto mail.attach(MIMEText(reason, 'plain', 'utf8')) # error msg mail.attach(m) # previous mail # ugly hack we need to add headers at the TOP # items = m.items() # for key,val in items: m.__delitem__(key) # delete them all # for key,val in items: m.add_header(key,val) # re-add them all # mail.attach(m) # add original mail # send it try: connection = SMTPConnection() # we use the django one, configured with stuff from settings connection.open() if not connection.connection: raise SMTPException, "Fail to create SMTPConnection.connection" connection.connection.sendmail( mylist.list_address_extended('owner'), # from, will be set in Return-Path [ msgto ], # to mail.as_string()) # content except SMTPException, detail: err('refuse: SMTP Error while sending the email: %s'%detail) return # TODO : prevent loops if smtp fails : the mail stays in incoming and will be tried again in loop
def render_email_and_send(context=None, message_template='', subject='', recipients=None, sender=None): """ Sends an e-mail based on the given parameters. Takes a context (as a dictionary), a template path (as a string), a subject (as a string) and recipients (as a list or tuple). E-mail templates SHOULD (see RFC 2119 for the meaning of SHOULD) be plain text. (I have no idea what will happen if you pass HTML.) """ t = loader.get_template(message_template) c = Context(context) message = t.render(c) # Not sure why, but there's a random bug somewhere that causes e-mail # socket errors. It's puzzled some other people, but this line seems to # more or less fix it: # http://mail.python.org/pipermail/python-list/2006-December/420357.html mimetools._prefix = 'x' if not sender: sender = settings.SERVER_EMAIL # send_mail(subject, message, sender, recipients) connection = SMTPConnection(fail_silently=True) email_to_send = EmailMessage( subject = subject, body = message, from_email = sender, to = recipients, connection = connection ) email_to_send.send(fail_silently=True) connection.close()
def send_all(block_size=500): """ Send all non-deferred messages in the queue. A lock file is used to ensure that this process can not be started again while it is already running. The ``block_size`` argument allows for queued messages to be iterated in blocks, allowing new prioritised messages to be inserted during iteration of a large number of queued messages. """ lock = FileLock(LOCK_PATH) logger.debug("Acquiring lock...") try: # lockfile has a bug dealing with a negative LOCK_WAIT_TIMEOUT (which # is the default if it's not provided) systems which use a LinkFileLock # so ensure that it is never a negative number. lock.acquire(LOCK_WAIT_TIMEOUT and max(0, LOCK_WAIT_TIMEOUT)) except AlreadyLocked: logger.debug("Lock already in place. Exiting.") return except LockTimeout: logger.debug("Waiting for the lock timed out. Exiting.") return logger.debug("Lock acquired.") start_time = time.time() sent = deferred = skipped = 0 connection = None try: connection = SMTPConnection() blacklist = models.Blacklist.objects.values_list("email", flat=True) connection.open() for message in _message_queue(block_size): result = send_message(message, smtp_connection=connection, blacklist=blacklist) if result == constants.RESULT_SENT: sent += 1 elif result == constants.RESULT_FAILED: deferred += 1 elif result == constants.RESULT_SKIPPED: skipped += 1 connection.close() finally: logger.debug("Releasing lock...") lock.release() logger.debug("Lock released.") logger.debug("") if sent or deferred or skipped: log = logger.warning else: log = logger.info log("%s sent, %s deferred, %s skipped." % (sent, deferred, skipped)) logger.debug("Completed in %.2f seconds." % (time.time() - start_time))
def send_message(queued_message, smtp_connection=None, blacklist=None, log=True): """ Send a queued message, returning a response code as to the action taken. The response codes can be found in ``django_mailer.constants``. The response will be either ``RESULT_SKIPPED`` for a blacklisted email, ``RESULT_FAILED`` for a deferred message or ``RESULT_SENT`` for a successful sent message. To allow optimizations if multiple messages are to be sent, an SMTP connection can be provided and a list of blacklisted email addresses. Otherwise an SMTP connection will be opened to send this message and the email recipient address checked against the ``Blacklist`` table. If the message recipient is blacklisted, the message will be removed from the queue without being sent. Otherwise, the message is attempted to be sent with an SMTP failure resulting in the message being flagged as deferred so it can be tried again later. By default, a log is created as to the action. Either way, the original message is not deleted. """ message = queued_message.message if smtp_connection is None: smtp_connection = SMTPConnection() opened_connection = False if blacklist is None: blacklisted = models.Blacklist.objects.filter(email=message.to_address) else: blacklisted = message.to_address in blacklist log_message = '' if blacklisted: logger.info("Not sending to blacklisted email: %s" % message.to_address.encode("utf-8")) queued_message.delete() result = constants.RESULT_SKIPPED else: try: logger.info("Sending message to %s: %s" % (message.to_address.encode("utf-8"), message.subject.encode("utf-8"))) opened_connection = smtp_connection.open() smtp_connection.connection.sendmail(message.from_address, [message.to_address], message.encoded_message) queued_message.delete() result = constants.RESULT_SENT except (SocketError, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError), err: queued_message.defer() logger.warning("Message to %s deferred due to failure: %s" % (message.to_address.encode("utf-8"), err)) log_message = unicode(err) result = constants.RESULT_FAILED
def _our_send_mass_mail(datatuple, form_address, fail_silently=False, auth_user=None, auth_password=None): """Our hacked version of the django send_mass_mail function, which relies on django having this patch: http://code.djangoproject.com/attachment/ticket/9214/9214-EmailMessage-r9084.diff """ connection = SMTPConnection(username=auth_user, password=auth_password, fail_silently=fail_silently) headers = {'From': form_address} messages = [EmailMessage(subject, message, sender, recipient, headers=headers) for subject, message, sender, recipient in datatuple] return connection.send_messages(messages)
def mass_mail_sending_view(request): m1 = EmailMessage('First Test message', 'This is the first test email', '*****@*****.**', ['*****@*****.**', '*****@*****.**']) m2 = EmailMessage('Second Test message', 'This is the second test email', '*****@*****.**', ['*****@*****.**', '*****@*****.**']) c = SMTPConnection() c.send_messages([m1, m2]) return HttpResponse("Mail sent")
def forward_mail_to_subscribers(self, mail, subscribers, mylist): # actually forward it try: connection = SMTPConnection() # we use the django one, configured with stuff from settings connection.open() if not connection.connection: raise SMTPException, "Fail to create SMTPConnection.connection" connection.connection.sendmail( mylist.list_address_extended('owner'), # from, will be set in Return-Path subscribers, # to mail.as_string()) # content except SMTPException, detail: err('SMTP Error while sending the email: %s'%detail) return # TODO : prevent loops if smtp fails : the mail stays in incoming and will be tried again in loop
def handle_noargs(self, **options): dummy_request = HttpRequest() dummy_request.GET['for_email'] = 'true' self.set_content(dummy_request) self.subject = self.get_subject() self.sent_str = self.get_sent_str() self.connection = SMTPConnection() self.errors = {} print 'starting: ' + datetime.datetime.now().strftime("%c") # try up to four times, if necessary for i in range(4): not_sent = self.subscriber_base.exclude(last_sent=self.sent_str) if len(not_sent): # intentionally resolve the query if i != 0: print datetime.datetime.now().strftime('%c'), print '- sleeping before retrying %s emails...' % len( not_sent) time.sleep(self.WAIT_TIME) for subscriber in not_sent: self.try_sending_to_subscriber(subscriber) # any that *still* didn't work? error_output = [] for sub in self.subscriber_base.exclude(last_sent=self.sent_str): errors = [ '%d %s' % (len(data), kind) for kind, data in self.errors[sub.email].items() ] error_output.append('errors with %s: %s' % (sub.email, '\t'.join(errors))) if error_output: print '\n', '\n'.join(error_output), '\n' mail_admins( 'Errors sending out', "Got the following errors while sending the email:\n" + '\n'.join(error_output) + '\n\nMore information is available by loading the pickled log file.' ) if self.errors: print 'more info available in the pickle file' pickle.dump(self.errors, sys.stderr) print 'finished: ' + datetime.datetime.now().strftime("%c")
def send_mail(subject, message_txt, message_html, sender, recipients): """Similar to django's send_mass_mail, but use EmailMultiAlternatives for email messages. Also, avoid creating a list with all the messages, use an iterator instead. """ connection = SMTPConnection(fail_silently=False) def messages_iterator(): for recipient in recipients: email = EmailMultiAlternatives(subject, message_txt, sender, recipient) email.attach_alternative(message_html, "text/html") yield email return connection.send_messages(messages_iterator())
def renew_connection(self, subscriber, retries=5, sleep_time_base=2): # close the old one self.connection.fail_silently = True self.connection.close() # get a new one for i in range(retries): try: self.connection = SMTPConnection() self.connection.open() except socket.timeout: self.add_error(subscriber, 'timeout while opening connection') time.sleep(sleep_time_base**i) else: return
def save(self, subject=None): if subject is None: subject = '%s wants you to learn more about out this Vibha Project' % self.cleaned_data[ 'name'] message = self.cleaned_data['body'] + self.cleaned_data['project_info'] from_email = settings.DEFAULT_FROM_EMAIL # Split into several messages so recipients dont see the other recipients msg = [] for recipient in self.cleaned_data['to_email']: m = EmailMessage(subject, message, from_email, [recipient]) m.content_subtype = "html" msg.append(m) connection = SMTPConnection() connection.send_messages(msg)
def mass_mail_sending_view(request): m1 = EmailMessage( 'First Test message', 'This is the first test email', '*****@*****.**', ['*****@*****.**', '*****@*****.**']) m2 = EmailMessage( 'Second Test message', 'This is the second test email', '*****@*****.**', ['*****@*****.**', '*****@*****.**']) c = SMTPConnection() c.send_messages([m1,m2]) return HttpResponse("Mail sent")
def forward_mail_to_subscribers(self, mail, subscribers, mylist): # actually forward it try: connection = SMTPConnection( ) # we use the django one, configured with stuff from settings connection.open() if not connection.connection: raise SMTPException, "Fail to create SMTPConnection.connection" connection.connection.sendmail( mylist.list_address_extended( 'owner'), # from, will be set in Return-Path subscribers, # to mail.as_string()) # content except SMTPException, detail: err('SMTP Error while sending the email: %s' % detail) return # TODO : prevent loops if smtp fails : the mail stays in incoming and will be tried again in loop
def send_verification_email(email, task): domain = get_metro()['short_name'] + '.' + settings.EB_DOMAIN url = 'http://%s%s' % (domain, verification_url(email, task)) template_name = { CREATE_TASK: 'register', RESET_TASK: 'password_reset' }[task] text_content = render_to_string('accounts/%s_email.txt' % template_name, { 'url': url, 'email': email }) html_content = render_to_string('accounts/%s_email.html' % template_name, { 'url': url, 'email': email }) if settings.DEBUG: print text_content print html_content else: subject = { CREATE_TASK: 'Please confirm account', RESET_TASK: 'Password reset request' }[task] conn = SMTPConnection() # Use default settings. message = EmailMultiAlternatives(subject, text_content, settings.GENERIC_EMAIL_SENDER, [email], connection=conn) message.attach_alternative(html_content, 'text/html') message.send()
def refuse(self, m, mylist, reason): deepdbg('Refuse mail for %s' % unicode(mylist)) msgfrom = mylist.list_address_extended('owner') msgto = m['From'] reason = u"\n\nYour message to the list %s has been refused\n\n" % unicode( mylist) + reason # create mail mail = MIMEMultipart() mail[ 'Subject'] = u"Your message to the list %s has been refused " % unicode( mylist) mail['From'] = msgfrom mail['To'] = msgto mail.attach(MIMEText(reason, 'plain', 'utf8')) # error msg mail.attach(m) # previous mail # ugly hack we need to add headers at the TOP # items = m.items() # for key,val in items: m.__delitem__(key) # delete them all # for key,val in items: m.add_header(key,val) # re-add them all # mail.attach(m) # add original mail # send it try: connection = SMTPConnection( ) # we use the django one, configured with stuff from settings connection.open() if not connection.connection: raise SMTPException, "Fail to create SMTPConnection.connection" connection.connection.sendmail( mylist.list_address_extended( 'owner'), # from, will be set in Return-Path [msgto], # to mail.as_string()) # content except SMTPException, detail: err('refuse: SMTP Error while sending the email: %s' % detail) return # TODO : prevent loops if smtp fails : the mail stays in incoming and will be tried again in loop
def handle(self, *args, **options): if not options['group_slug']: sys.exit(__doc__) self._set_language(options['lang']) group = self._get_group(options['group_slug']) accounts = self._get_accounts(group) emails = self._build_emails(accounts) if not options['yes'] and not options['debug']: answer = raw_input(u"Send emails y/N ".encode('utf-8')) if answer.lower() != 'y': print "Canceled sending" sys.exit(0) if emails: if options['debug']: self._print_debug(emails) else: connection = SMTPConnection() connection.send_messages(emails)
def handle(self, *args, **options): if not options['group_slug']: sys.exit(__doc__) self._set_language(options['lang']) group = self._get_group(options['group_slug']) accounts = self._get_accounts(group) emails = self._build_emails(accounts) if not options['yes'] and not options['debug']: answer = raw_input(u"Send emails y/N ".encode('utf-8')) if answer.lower() != 'y': print "Canceled sending" sys.exit(0) if emails: if options['debug']: self._print_debug(emails) else: connection = SMTPConnection() connection.send_messages(emails)
def handle(self, *args, **options): if not options["group_slug"]: sys.exit(__doc__) self._set_language(options["lang"]) group = self._get_group(options["group_slug"]) accounts = self._get_accounts(group) emails = self._build_emails(accounts) if not options["yes"] and not options["debug"]: answer = input("Send emails y/N ") if answer.lower() != "y": print("Canceled sending") sys.exit(0) if emails: if options["debug"]: self._print_debug(emails) else: connection = SMTPConnection() connection.send_messages(emails)
def renew_connection(self, subscriber, retries=5, sleep_time_base=2): # close the old one self.connection.fail_silently = True self.connection.close() # get a new one for i in range(retries): try: self.connection = SMTPConnection() self.connection.open() except socket.timeout: self.add_error(subscriber, 'timeout while opening connection') time.sleep(sleep_time_base ** i) else: return
def _send_email(runinfo): "Send the email for a specific runinfo entry" subject = runinfo.subject translation.activate(subject.language) tmpl = loader.get_template(settings.QUESTIONNAIRE_EMAIL_TEMPLATE) c = Context() c['surname'] = subject.surname c['givenname'] = subject.givenname c['gender'] = subject.gender c['email'] = subject.email c['random'] = runinfo.random c['runid'] = runinfo.runid c['created'] = runinfo.created c['site'] = getattr(settings, 'QUESTIONNAIRE_URL', '(settings.QUESTIONNAIRE_URL not set)') email = tmpl.render(c) emailFrom = settings.QUESTIONNAIRE_EMAIL_FROM emailSubject, email = email.split("\n", 1) # subject must be on first line emailSubject = emailSubject.strip() emailFrom = emailFrom.replace("$RUNINFO", runinfo.random) emailTo = '"%s, %s" <%s>' % (subject.surname, subject.givenname, subject.email) emailTo = encode_emailaddress(emailTo) emailFrom = encode_emailaddress(emailFrom) try: conn = SMTPConnection() msg = EmailMessage(emailSubject, email, emailFrom, [emailTo], connection=conn) msg.send() runinfo.emailcount = 1 + runinfo.emailcount runinfo.emailsent = datetime.now() runinfo.lastemailerror = "OK, accepted by server" runinfo.save() return True except smtplib.SMTPRecipientsRefused: runinfo.lastemailerror = "SMTP Recipient Refused" except smtplib.SMTPHeloError: runinfo.lastemailerror = "SMTP Helo Error" except smtplib.SMTPSenderRefused: runinfo.lastemailerror = "SMTP Sender Refused" except smtplib.SMTPDataError: runinfo.lastemailerror = "SMTP Data Error" runinfo.save() return False
def render_to_mail(template_path, params, subject, from_email=None, recipient_list=[], auth_user=None, auth_password=None, fail_silently=False, content_subtype=None, attachments=[], **kwargs): """ Sends a e-mail message with content parsed from a template. The syntax is the same of render_to_response function. Returns then boolean of mail sending, using core.mail.send_mail function. """ content_subtype = content_subtype or getattr( settings, 'DEFAULT_EMAIL_CONTENT_SUBTYPE', 'html') from_email = from_email or getattr(settings, 'DEFAULT_FROM_EMAIL', None) if not recipient_list: return False # Loads template for mail content t = get_template(template_path) # Render content message = t.render(Context(params)) # SMTP connection connection = SMTPConnection(username=auth_user, password=auth_password, fail_silently=fail_silently) # Email object email_obj = EmailMessage(subject, message, from_email, [r.strip() for r in recipient_list], connection=connection) email_obj.content_subtype = content_subtype if attachments: for att in attachments: email_obj.attach_file(att) return email_obj.send()
def send_all(frequency): """ Sends an e-mail to all subscribers in the system with data with the given frequency. """ conn = SMTPConnection() # Use default settings. count = 0 start_date = datetime.date.today() - datetime.timedelta(days=frequency) for alert in EmailAlert.active_objects.filter(frequency=frequency): try: place_name, text_content, html_content = email_for_subscription(alert, start_date, frequency) except NoNews: continue subject = 'Update: %s' % place_name message = EmailMultiAlternatives(subject, text_content, settings.GENERIC_EMAIL_SENDER, [alert.user.email], connection=conn) message.attach_alternative(html_content, 'text/html') message.send() count += 1
def handle_noargs(self, **options): dummy_request = HttpRequest() dummy_request.GET['for_email'] = 'true' self.set_content(dummy_request) self.subject = self.get_subject() self.sent_str = self.get_sent_str() self.connection = SMTPConnection() self.errors = {} print 'starting: ' + datetime.datetime.now().strftime("%c") # try up to four times, if necessary for i in range(4): not_sent = self.subscriber_base.exclude(last_sent=self.sent_str) if len(not_sent): # intentionally resolve the query if i != 0: print datetime.datetime.now().strftime('%c'), print '- sleeping before retrying %s emails...' % len(not_sent) time.sleep(self.WAIT_TIME) for subscriber in not_sent: self.try_sending_to_subscriber(subscriber) # any that *still* didn't work? error_output = [] for sub in self.subscriber_base.exclude(last_sent=self.sent_str): errors = [ '%d %s' % (len(data), kind) for kind, data in self.errors[sub.email].items() ] error_output.append('errors with %s: %s' % (sub.email, '\t'.join(errors))) if error_output: print '\n', '\n'.join(error_output), '\n' mail_admins('Errors sending out', "Got the following errors while sending the email:\n" + '\n'.join(error_output) + '\n\nMore information is available by loading the pickled log file.' ) if self.errors: print 'more info available in the pickle file' pickle.dump(self.errors, sys.stderr) print 'finished: ' + datetime.datetime.now().strftime("%c")
def bcc_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None): from django.core.mail import SMTPConnection, EmailMessage ''' Sends mail with recipient_list BCC'ed. Follows BCC convention and sets "to" to from_email. ''' conn = SMTPConnection(username=auth_user, password=auth_password, fail_silently=fail_silently) return EmailMessage(subject, message, from_email, [from_email], recipient_list, conn).send()
def handle_trial_account(document, pdf_file_contents): """ Special handling for trial accounts: Instead of creating a PDF assert we're sending the PDF file as attachment in email. The document (and all dependent assets) are deleted """ try: # use is_active flag to determine the trial account if document.owner.is_active: return False subject = render_to_string('core/trial_return_email_subject.txt') # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) body = render_to_string('core/trial_return_email.txt', { 'user': document.owner.email, 'free_pages': "100" }) #TODO parametrize message = EmailMessage(subject, body, settings.UPLOAD_NOTIFICATION_EMAIL, [document.owner.email], connection=SMTPConnection()) # walk up the tree of asset dependencies, find the original asset that stores # the filename page_original_asset = document.pages.all()[0].get_asset( models.AssetClass.PAGE_ORIGINAL) original = page_original_asset.parent message.attach(original.orig_file_name + '-digitised.pdf', pdf_file_contents) message.send() return True except Exception, e: logging.error(e) import traceback logging.error(traceback.format_stack())
def send_invites(): count = 0 try: count = sys.argv[1] except: pass invites = Email_Invite.objects.filter(invited=False).order_by('created_date')[:count] messages = [ ] subject = 'Welcome to the Portrit preview!' html_content = '<p>We are happy to announce the launch of the Portrit preview</p>' \ '<a href="http://portrit.com/">' \ '<img src="http://portrit.com/site_media/img/invite/invite.jpg"/>' \ '</a>' \ '<p>Please go to <a href="http://portrit.com">portrit.com</a> and login with the email address this message was sent to.</p>' \ '<p>With great power comes great responsibilty. With this in mind, we ask that you help us with any feedback you may have.<br>You can email us at <a href="mailto:[email protected]">[email protected]</a> or use the built in feedback control at the top of Portrit.</p>' \ '<br><br>' \ '<p style="color: #aeaeae; text-align: center; font-size: 12px;">You are receiving this email because you asked to receive an invite to portrit.com<br>' \ 'Note: This email address is for distribution purposes only. Please do not reply to this email because your message will not be received.</p>' from_email = '*****@*****.**' from django.core.mail import SMTPConnection from django.core import mail connection = SMTPConnection() # Manually open the connection connection.open() for invite in invites: email = mail.EmailMessage(subject, html_content, from_email, [invite.email], connection=connection) email.content_subtype = "html" messages.append(email) invite.invited = True invite.save() connection.send_messages(messages) connection.close()
def handle_noargs(self, **options): current_site = Site.objects.get_current() # use low level SMTP object to improve performance smtp = SMTPConnection() smtp.open() notices_count = 0 for user in User.objects.filter(email__isnull=False): notices = {} for notice in Notice.objects.notices_for(user).order_by('-notice_type__default', 'notice_type'): if should_send(user, notice.notice_type, DIGEST_MEDIUM): if notice.notice_type.display in notices: notices[notice.notice_type.display].append(notice) else: notices[notice.notice_type.display] = [notice] notices_count += 1 notice.archive() if notices: context = Context({'notices': notices, 'user': user}) body = render_to_string ('notification/digest_email_body.html', context_instance=context) subject = render_to_string ('notification/digest_email_subject.txt', {'count': notices_count}) msg = EmailMessage(subject, body, settings.DEFAULT_FROM_EMAIL, [user.email]) msg.content_subtype = "html" # Main content is now text/html smtp._send(msg) smtp.close()
import smtplib import logging from lockfile import FileLock, AlreadyLocked, LockTimeout from socket import error as socket_error from django.conf import settings from django.core.mail import send_mail as core_send_mail from django.core.mail import mail_admins try: # Django 1.2 from django.core.mail import get_connection except ImportError: # ImportError: cannot import name get_connection from django.core.mail import SMTPConnection get_connection = lambda backend=None, fail_silently=False, **kwds: SMTPConnection( fail_silently=fail_silently) from mailer.models import Message, DontSendEntry, MessageLog # when queue is empty, how long to wait (in seconds) before checking again EMPTY_QUEUE_SLEEP = getattr(settings, "MAILER_EMPTY_QUEUE_SLEEP", 30) # lock timeout value. how long to wait for the lock to become available. # default behavior is to never wait for the lock to be available. LOCK_WAIT_TIMEOUT = getattr(settings, "MAILER_LOCK_WAIT_TIMEOUT", -1) # The actual backend to use for sending, defaulting to the Django default. EMAIL_BACKEND = getattr(settings, "MAILER_EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend")
def handle_noargs(self, **options): from django.db.models import Count, Sum from django.template.defaultfilters import filesizeformat from django.core.mail import EmailMessage, SMTPConnection from django.conf import settings from django.template.loader import render_to_string from baruwa.accounts.models import UserProfile, UserAddresses from baruwa.messages.models import Message from baruwa.messages.templatetags.messages_extras import tds_trunc from baruwa.messages.models import MessageTotals from baruwa.utils.graphs import PieChart, PIE_CHART_COLORS, BarChart from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.units import inch from reportlab.platypus import SimpleDocTemplate, Spacer, Table, \ TableStyle, Paragraph, Image, PageBreak try: from django.forms.fields import email_re except ImportError: from django.core.validators import email_re try: from cStringIO import StringIO except: from StringIO import StringIO table_style = TableStyle([ ('FONT', (0, 0), (-1, -1), 'Helvetica'), ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('GRID', (0, 0), (-1, -1), 0.15, colors.black), ('ALIGN', (0, 0), (-1, 0), 'CENTER'), ('ALIGN', (4, 1), (-1, -1), 'CENTER'), ('ALIGN', (0, 0), (0, -1), 'CENTER'), ('VALIGN', (4, 1), (-1, -1), 'MIDDLE'), ('SPAN', (4, 1), (-1, -1)), ]) styles = getSampleStyleSheet() reports = [ [ 'from_address', {'from_address__exact':""}, 'num_count', 'Top senders by quantity'], [ 'from_address', {'from_address__exact':""}, 'size', 'Top senders by volume'], [ 'from_domain', {'from_domain__exact':""}, 'num_count', 'Top sender domains by quantity'], [ 'from_domain', {'from_domain__exact':""}, 'size', 'Top sender domains by volume'], [ 'to_address', {'to_address__exact':""}, 'num_count', 'Top recipients by quantity'], [ 'to_address', {'to_address__exact':""}, 'size', 'Top recipients by volume'], [ 'to_domain', {'to_domain__exact':"", 'to_domain__isnull':False}, 'num_count', 'Top recipient domains by quantity'], [ 'to_domain', {'to_domain__exact':"", 'to_domain__isnull':False}, 'size', 'Top recipient domains by volume'], ] emails = [] from_email = getattr(settings, 'DEFAULT_FROM_EMAIL', 'postmaster@localhost') url = getattr(settings, 'QUARANTINE_REPORT_HOSTURL','') logo_dir = getattr(settings, 'MEDIA_ROOT', '') img = Image(logo_dir + '/imgs/css/logo.jpg') profiles = UserProfile.objects.filter(send_report=1) print "=================== Processing reports ======================" for profile in profiles: user = profile.user if email_re.match(user.email) or email_re.match(user.username): pdf = StringIO() doc = SimpleDocTemplate(pdf, topMargin=50, bottomMargin=18) logo = [(img, 'Baruwa mail report')] logo_table = Table(logo, [2.0 * inch, 5.4 * inch]) logo_table.setStyle(TableStyle([ ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ('ALIGN', (0, 0), (-1, 0), 'LEFT'), ('ALIGN', (1, 0), (-1, 0), 'RIGHT'), ('FONTSIZE', (1, 0), (-1, 0), 10), ('LINEBELOW', (0, 0),(-1, -1), 0.15, colors.black), ])) parts = [logo_table] parts.append(Spacer(1, 20)) sentry = 0 for report in reports: column = report[0] exclude_kwargs = report[1] order_by = "-%s" % report[2] order = report[2] title = report[3] data = Message.report.all(user).values(column).\ exclude(**exclude_kwargs).annotate( num_count=Count(column), size=Sum('size') ).order_by(order_by)[:10] if data: sentry += 1 headings = [('', 'Address', 'Count', 'Volume', '')] rows = [[draw_square(PIE_CHART_COLORS[index]), tds_trunc(row[column], 45), row['num_count'], filesizeformat(row['size']),''] for index,row in enumerate(data)] if len(rows) != 10: missing = 10 - len(rows) add_rows = [ ('', '', '', '', '') for ind in range(missing) ] rows.extend(add_rows) headings.extend(rows) dat = [row[order] for row in data] total = sum(dat) labels = [ ("%.1f%%" % ((1.0 * row[order] / total) * 100)) for row in data ] pie = PieChart() pie.chart.labels = labels pie.chart.data = dat headings[1][4] = pie table_with_style = Table(headings, [0.2 * inch, 2.8 * inch, 0.5 * inch, 0.7 * inch, 3.2 * inch]) table_with_style.setStyle(table_style) paragraph = Paragraph(title, styles['Heading1']) parts.append(paragraph) parts.append(table_with_style) parts.append(Spacer(1, 70)) if (sentry % 2) == 0: parts.append(PageBreak()) # parts.append(Paragraph('Message Totals', styles['Heading1'])) addrs = [ addr.address for addr in UserAddresses.objects.filter( user=user ).exclude(enabled__exact=0)] msg_totals = MessageTotals.objects.all( user, [], addrs, profile.account_type) mail_total = [] spam_total = [] virus_total = [] dates = [] for ind, msgt in enumerate(msg_totals): if ind % 10: dates.append('') else: dates.append(str(msgt.date)) mail_total.append(int(msgt.mail_total)) spam_total.append(int(msgt.spam_total)) virus_total.append(int(msgt.virus_total)) #graph = MessageTotalsGraph() graph = BarChart() graph.chart.data = [ tuple(mail_total), tuple(spam_total), tuple(virus_total) ] graph.chart.categoryAxis.categoryNames = dates graph_table = Table([[graph],], [7.4 * inch]) parts.append(graph_table) if not sentry: sentry += 1 if sentry: doc.build(parts) text_content = render_to_string('reports/pdf_report.txt', {'user':user, 'url':url}) subject = 'Baruwa usage report for: %s' % user.username if email_re.match(user.username): toaddr = user.username if email_re.match(user.email): toaddr = user.email msg = EmailMessage(subject, text_content, from_email, [toaddr]) msg.attach('baruwa.pdf', pdf.getvalue(), "application/pdf") #msg.send() emails.append(msg) print "* Queue "+user.username+"'s report to: "+toaddr pdf.close() if emails: try: conn = SMTPConnection() conn.send_messages(emails) print "====== sending "+str(len(emails))+" messages =======" except Exception, exception: print "Sending failed ERROR: %s" % str(exception)
class SendingOutCommand(NoArgsCommand): subscriber_base = None # Subscriber.rsd or whatever from_email = 'The Daily Gazette <*****@*****.**>' WAIT_TIME = 60 def set_content(self, dummy_request): raise NotImplemented def get_subject(self): today = datetime.date.today() return today.strftime("%%A, %%B %d, %%Y" % today.day) def get_sent_str(self): return datetime.date.today().strftime('%Y-%m-%d') def contents_for_subscriber(self, subscriber): return (self.text_content, self.html_content) def send_to_subscriber(self, subscriber): subj = self.subject frm = self.from_email text_content, html_content = self.contents_for_subscriber(subscriber) if subscriber.plain_text: msg = EmailMessage(subj, text_content, frm, [subscriber.email]) else: msg = EmailMessage(subj, html_content, frm, [subscriber.email]) msg.content_subtype = "html" # msg = EmailMessage(self.subject, text_content, self.from_email, [subscriber.email]) # if not subscriber.plain_text: # msg.multipart_subtype = 'alternative' # msg.attach(content=html_content, mimetype='text/html') self.connection.send_messages([msg]) # if it didn't just crash, sending was successful :) subscriber.last_sent = self.sent_str subscriber.save() def renew_connection(self, subscriber, retries=5, sleep_time_base=2): # close the old one self.connection.fail_silently = True self.connection.close() # get a new one for i in range(retries): try: self.connection = SMTPConnection() self.connection.open() except socket.timeout: self.add_error(subscriber, 'timeout while opening connection') time.sleep(sleep_time_base**i) else: return def try_sending_to_subscriber(self, subscriber, repeat_index=0, max_repeats=2): if repeat_index >= max_repeats: return try: self.send_to_subscriber(subscriber) except smtplib.SMTPRecipientsRefused: self.add_error(subscriber, 'recipient refused') except smtplib.SMTPServerDisconnected: self.add_error(subscriber, 'server disconnected') self.renew_connection(subscriber) self.try_sending_to_subscriber(subscriber, repeat_index + 1, max_repeats) except socket.sslerror: self.add_error(subscriber, 'ssl error') # probably timeout self.renew_connection(subscriber) self.try_sending_to_subscriber(subscriber, repeat_index + 1, max_repeats) except socket.timeout: self.add_error(subscriber, 'timeout') self.renew_connection(subscriber) self.try_sending_to_subscriber(subscriber, repeat_index + 1, max_repeats) except smtplib.SMTPException: self.add_error(subscriber, 'smtp error') except Exception: self.add_error(subscriber, 'generic error') def add_error(self, subscriber, key): self.errors.setdefault(subscriber.email, {}) self.errors[subscriber.email].setdefault(key, []) exc_type, exc_val, exc_trace = sys.exc_info() self.errors[subscriber.email][key].append({ 'type': exc_type, 'val': exc_val, 'traceback': ''.join(traceback.format_exception(exc_type, exc_val, exc_trace)), 'time': datetime.datetime.now() }) def handle_noargs(self, **options): dummy_request = HttpRequest() dummy_request.GET['for_email'] = 'true' self.set_content(dummy_request) self.subject = self.get_subject() self.sent_str = self.get_sent_str() self.connection = SMTPConnection() self.errors = {} print 'starting: ' + datetime.datetime.now().strftime("%c") # try up to four times, if necessary for i in range(4): not_sent = self.subscriber_base.exclude(last_sent=self.sent_str) if len(not_sent): # intentionally resolve the query if i != 0: print datetime.datetime.now().strftime('%c'), print '- sleeping before retrying %s emails...' % len( not_sent) time.sleep(self.WAIT_TIME) for subscriber in not_sent: self.try_sending_to_subscriber(subscriber) # any that *still* didn't work? error_output = [] for sub in self.subscriber_base.exclude(last_sent=self.sent_str): errors = [ '%d %s' % (len(data), kind) for kind, data in self.errors[sub.email].items() ] error_output.append('errors with %s: %s' % (sub.email, '\t'.join(errors))) if error_output: print '\n', '\n'.join(error_output), '\n' mail_admins( 'Errors sending out', "Got the following errors while sending the email:\n" + '\n'.join(error_output) + '\n\nMore information is available by loading the pickled log file.' ) if self.errors: print 'more info available in the pickle file' pickle.dump(self.errors, sys.stderr) print 'finished: ' + datetime.datetime.now().strftime("%c")
def handle(self, *args, **options): if len(args) != 0: raise CommandError(_("Command doesn't accept any arguments")) by_domain = options.get('by_domain') domain_name = options.get('domain_name') copy_admin = options.get('copy_admin') period = options.get('period') include_daily = options.get('include_daily') enddate = None period_re = re.compile(r"(?P<num>(\d+))\s+(?P<period>(day|week|month))(?:s)?") if period: match = period_re.match(period) if not match: raise CommandError(_("The period you specified is invalid")) num = match.group('num') ptype = match.group('period') if not ptype.endswith('s'): ptype = ptype + 's' delta = datetime.timedelta(**{ptype: int(num)}) enddate = datetime.date.today() - delta from django.db.models import Count, Sum, Q from django.template.defaultfilters import filesizeformat from django.core.mail import EmailMessage, SMTPConnection from django.contrib.auth.models import User from django.conf import settings from django.template.loader import render_to_string from baruwa.accounts.models import UserProfile, UserAddresses from baruwa.messages.models import Message from baruwa.messages.templatetags.messages_extras import tds_trunc from baruwa.messages.models import MessageTotals from baruwa.utils.graphs import PieChart, PIE_CHART_COLORS, BarChart from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.units import inch from reportlab.platypus import SimpleDocTemplate, Spacer, Table, \ TableStyle, Paragraph, Image, PageBreak try: from django.forms.fields import email_re except ImportError: from django.core.validators import email_re try: from cStringIO import StringIO except ImportError: from StringIO import StringIO table_style = TableStyle([ ('FONT', (0, 0), (-1, -1), 'Helvetica'), ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('GRID', (0, 0), (-1, -1), 0.15, colors.black), ('ALIGN', (0, 0), (-1, 0), 'CENTER'), ('ALIGN', (4, 1), (-1, -1), 'CENTER'), ('ALIGN', (0, 0), (0, -1), 'CENTER'), ('VALIGN', (4, 1), (-1, -1), 'MIDDLE'), ('SPAN', (4, 1), (-1, -1)), ]) styles = getSampleStyleSheet() reports = [ [ 'from_address', {'from_address__exact': ""}, 'num_count', 'Top senders by quantity'], [ 'from_address', {'from_address__exact': ""}, 'total_size', 'Top senders by volume'], [ 'from_domain', {'from_domain__exact': ""}, 'num_count', 'Top sender domains by quantity'], [ 'from_domain', {'from_domain__exact': ""}, 'total_size', 'Top sender domains by volume'], [ 'to_address', {'to_address__exact': ""}, 'num_count', 'Top recipients by quantity'], [ 'to_address', {'to_address__exact': ""}, 'total_size', 'Top recipients by volume'], [ 'to_domain', {'to_domain__exact': "", 'to_domain__isnull': False}, 'num_count', 'Top recipient domains by quantity'], [ 'to_domain', {'to_domain__exact': "", 'to_domain__isnull': False}, 'total_size', 'Top recipient domains by volume'], ] emails = [] admin_addrs = [] if copy_admin: mails = User.objects.values('email').filter(is_superuser=True) admin_addrs = [mail['email'] for mail in mails] from_email = getattr(settings, 'DEFAULT_FROM_EMAIL', 'postmaster@localhost') url = getattr(settings, 'QUARANTINE_REPORT_HOSTURL', '') logo_dir = getattr(settings, 'MEDIA_ROOT', '') img = Image(logo_dir + '/imgs/css/logo.jpg') def build_chart(data, column, order, title): "build chart" headings = [('', _('Address'), _('Count'), _('Volume'), '')] rows = [[draw_square(PIE_CHART_COLORS[index]), tds_trunc(row[column], 45), row['num_count'], filesizeformat(row['total_size']), ''] for index, row in enumerate(data)] if len(rows) != 10: missing = 10 - len(rows) add_rows = [ ('', '', '', '', '') for ind in range(missing) ] rows.extend(add_rows) headings.extend(rows) dat = [row[order] for row in data] total = sum(dat) labels = [ ("%.1f%%" % ((1.0 * row[order] / total) * 100)) for row in data ] pie = PieChart() pie.chart.labels = labels pie.chart.data = dat headings[1][4] = pie table_with_style = Table(headings, [0.2 * inch, 2.8 * inch, 0.5 * inch, 0.7 * inch, 3.2 * inch]) table_with_style.setStyle(table_style) paragraph = Paragraph(title, styles['Heading1']) return [paragraph, table_with_style] def build_parts(account, enddate, isdom=None): "build parts" parts = [] sentry = 0 for report in reports: column = report[0] exclude_kwargs = report[1] order_by = "-%s" % report[2] order = report[2] title = report[3] if isdom: #dom data = Message.objects.values(column).\ filter(Q(from_domain=account.address) | \ Q(to_domain=account.address)).\ exclude(**exclude_kwargs).annotate( num_count=Count(column), total_size=Sum('size') ).order_by(order_by) if enddate: data.filter(date__gt=enddate) data = data[:10] else: #all users data = Message.report.all(user, enddate).values(column).\ exclude(**exclude_kwargs).annotate( num_count=Count(column), total_size=Sum('size') ).order_by(order_by) data = data[:10] if data: sentry += 1 pgraphs = build_chart(data, column, order, title) parts.extend(pgraphs) parts.append(Spacer(1, 70)) if (sentry % 2) == 0: parts.append(PageBreak()) parts.append(Paragraph(_('Message Totals'), styles['Heading1'])) if isdom: #doms msg_totals = MessageTotals.objects.doms(account.address, enddate) else: #norm filters = [] addrs = [ addr.address for addr in UserAddresses.objects.filter( user=account ).exclude(enabled__exact=0)] if enddate: efilter = { 'filter': 3, 'field': 'date', 'value': str(enddate) } filters.append(efilter) msg_totals = MessageTotals.objects.all( account, filters, addrs, profile.account_type) mail_total = [] spam_total = [] virus_total = [] dates = [] if include_daily: rows = [( Table([[draw_square(colors.white), Paragraph('Date', styles["Heading6"])]], [0.35 * inch, 1.50 * inch,]), Table([[draw_square(colors.green), Paragraph('Mail totals', styles["Heading6"])]], [0.35 * inch, 1.50 * inch,]), Table([[draw_square(colors.pink), Paragraph('Spam totals', styles["Heading6"])]], [0.35 * inch, 1.50 * inch,]), Table([[draw_square(colors.red), Paragraph('Virus totals', styles["Heading6"])]], [0.35 * inch, 1.50 * inch,]), )] for ind, msgt in enumerate(msg_totals): if ind % 10: dates.append('') else: dates.append(str(msgt.date)) mail_total.append(int(msgt.mail_total)) spam_total.append(int(msgt.spam_total)) virus_total.append(int(msgt.virus_total)) if include_daily: rows.append((str(msgt.date), msgt.mail_total, msgt.spam_total, msgt.virus_total)) graph = BarChart() graph.chart.data = [ tuple(mail_total), tuple(spam_total), tuple(virus_total) ] graph.chart.categoryAxis.categoryNames = dates graph_table = Table([[graph]], [7.4 * inch]) parts.append(graph_table) if include_daily: rows.append(('Totals', sum(mail_total), sum(spam_total), sum(virus_total))) parts.append(Spacer(1, 20)) graph_table = Table(rows, [1.85 * inch, 1.85 * inch, 1.85 * inch, 1.85 * inch,]) graph_table.setStyle(TableStyle([ ('FONTSIZE', (0, 0), (-1, -1), 8), ('FONT', (0, 0), (-1, -1), 'Helvetica'), ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ('GRID', (0, 0), (-1, -1), 0.15, colors.black), ('FONT', (0, -1), (-1, -1), 'Helvetica-Bold'), #('BACKGROUND', (0, -1), (-1, -1), colors.green), ])) parts.append(graph_table) return parts def build_pdf(charts): "Build a PDF" pdf = StringIO() doc = SimpleDocTemplate(pdf, topMargin=50, bottomMargin=18) logo = [(img, _('Baruwa mail report'))] logo_table = Table(logo, [2.0 * inch, 5.4 * inch]) logo_table.setStyle(TableStyle([ ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ('ALIGN', (0, 0), (-1, 0), 'LEFT'), ('ALIGN', (1, 0), (-1, 0), 'RIGHT'), ('FONTSIZE', (1, 0), (-1, 0), 10), ('LINEBELOW', (0, 0), (-1, -1), 0.15, colors.black), ])) parts = [logo_table] parts.append(Spacer(1, 20)) parts.extend(charts) try: doc.build(parts) except IndexError: pass return pdf def gen_email(pdf, user, owner): "generate and return email" text_content = render_to_string('reports/pdf_report.txt', {'user': user, 'url': url}) subject = _('Baruwa usage report for: %(user)s') % { 'user': owner} if email_re.match(user.username): toaddr = user.username if email_re.match(user.email): toaddr = user.email if admin_addrs: msg = EmailMessage(subject, text_content, from_email, [toaddr], admin_addrs) else: msg = EmailMessage(subject, text_content, from_email, [toaddr]) msg.attach('baruwa.pdf', pdf.getvalue(), "application/pdf") print _("* Queue %(user)s's report to: %(addr)s") % { 'user': owner, 'addr': toaddr} pdf.close() return msg print _("=================== Processing reports ======================") if by_domain: #do domain query #print "camacamlilone" domains = UserAddresses.objects.filter(Q(enabled=1), Q(address_type=1)) if domain_name != 'all': domains = domains.filter(address=domain_name) if not domains: print _("========== domain name %(dom)s does not exist ==========") % { 'dom': domain_name } for domain in domains: if email_re.match(domain.user.email) or email_re.match(domain.user.username): parts = build_parts(domain, enddate, True) if parts: pdf = build_pdf(parts) email = gen_email(pdf, domain.user, domain.address) emails.append(email) else: #do normal query profiles = UserProfile.objects.filter(send_report=1) for profile in profiles: try: user = profile.user if email_re.match(user.email) or email_re.match(user.username): parts = build_parts(user, enddate, False) if parts: pdf = build_pdf(parts) email = gen_email(pdf, user, user.username) emails.append(email) except User.DoesNotExist: pass if emails: try: conn = SMTPConnection() conn.send_messages(emails) print _("====== sending %(num)s messages =======") % { 'num': str(len(emails))} except Exception, exception: print _("Sending failed ERROR: %(error)s") % {'error': str(exception)}
def _send_verify_email(request, preferences, db_entry, rnd_hash, new_entry): """ Send a verify email """ location = reverse("KursAnmeldung-verify_email", kwargs={"hash": rnd_hash}) verify_link = request.build_absolute_uri(location) # FIXME: convert to users local time. now = datetime.datetime.utcnow() email_context = { "verify_link": verify_link, "db_entry": db_entry, "now": now, } # Render the internal page emailtext = render_to_string("kurs_anmeldung/verify_mailtext.txt", email_context) # Get the preferences from the database: raw_notify_list = preferences["notify"] notify_list = raw_notify_list.splitlines() notify_list = [i.strip() for i in notify_list if i] email_kwargs = { "from_email": preferences["from_email"], "subject": preferences["email_subject"], "body": emailtext, "to": [db_entry.email], "bcc": notify_list, } if MAIL_DEBUG == True: msg = u"MAIL_DEBUG is on: No Email was sended!" request.page_msg(msg) db_entry.log(request, msg) db_entry.mail_sended = False request.page_msg("django.core.mail.EmailMessage kwargs:") request.page_msg(email_kwargs) request.page_msg("debug mail text:") request.page_msg(mark_safe("<pre>%s</pre>" % emailtext)) return # We can't use django.core.mail.send_mail, because all members # of the recipient list will see the others in the 'To' field. # But we would like to notify the admins via 'Bcc' field. connection = SMTPConnection(fail_silently=False) email = EmailMessage(**email_kwargs) try: sended = email.send(fail_silently=False) except Exception, err: msg = "Error sending mail: %s" % err LogEntry.objects.log_action(app_label="kurs_anmeldung", action="error", message=msg) db_entry.log(request, msg) db_entry.mail_sended = False if settings.DEBUG or request.user.is_staff: db_entry.save() raise
def send_mass_mail_em(email_message_list, fail_silently=False, auth_user=None, auth_password=None): connection = SMTPConnection(username=auth_user, password=auth_password, fail_silently=fail_silently) return connection.send_messages(email_message_list)
def create_campaign_message(request): if request.method == 'POST': if not 'project' in request.session: project = Project.objects.get(id=int(request.POST['pid'])) funding_detail = project.projectfundingdetail_set.latest( 'end_date') funding_detail_value = long(funding_detail.budget) to_session = {'project': project, 'funding_detail': funding_detail} request.session.update(to_session) else: project = request.session['project'] funding_detail = request.session['funding_detail'] funding_detail_value = long(funding_detail.budget) ''' if request.POST.has_key('confirmed'): form = DonationAmountForm(data=request.POST,request=request,total_amount=request.session['donating_amount']) if not form.is_valid(): return render_to_response('donorportal/create_campaign2.html',{'form':form},RequestContext(request)) assert form.cleaned_data['amount'] == request.session['donating_amount'] request.session['donated_amount'] = form.cleaned_data['amount'] ''' #Message form post request form = MessageForm() if request.POST.get('form-type') == 'message-form': form = MessageForm(request.POST) if form.is_valid(): values = {} values.update(request.session) values.update(form.cleaned_data) camp_values = { 'user': request.user, 'amount': int(values['campaign_amount']), #This is 0, but the added donation, auto adds that value to donated. 'amount_collected': 0, 'description': values['description'], 'project': values['project'], 'end_date': values['campaign_end_date'] } del request.session['project'] camp = Campaign.objects.create(**camp_values) #donation = Donation() #donation.campaign = camp #donation.user = request.user #donation.amount = long(values['donated_amount']) #donation.save() extra_context = { 'site': Site.objects.get_current(), 'campaign': camp } extra_context.update(values) mail_context = RequestContext(request, extra_context) mail_message = loader.render_to_string( 'email_templates/campaign_mail.txt', mail_context) subject = '%s is raising funds for %s project on Vibha' % ( request.user.get_full_name(), values['project'].name) from_email = settings.DEFAULT_FROM_EMAIL # Split into several messages so recipients dont see the other recipients msg = [] for recipient in form.cleaned_data['to_email_field']: m = EmailMessage(subject, mail_message, from_email, [recipient]) m.content_subtype = "html" msg.append(m) connection = SMTPConnection() connection.send_messages(msg) return HttpResponseRedirect('../campaign/%s/' % (camp.id)) payload = locals() return render_to_response('donorportal/create_campaign3.html', payload, RequestContext(request)) else: return HttpResponseRedirect(reverse('list_projects'))
allowed = 1 logit("not set") elif len(mail_sett)==0: allowed = 1 elif (mail_sett[c[1]-1] == '1'): logit("%s %d" % (mail_set,c[1],)) allowed = 1 if allowed == 1: messages.append(msg) cursor.execute("update comm_queue_app_commd set end_at=NOW(),status=2 where id="+str(c[0])) else: cursor.execute("update comm_queue_app_commd set end_at=NOW(),status=3 where id="+str(c[0])) if len(messages)!=0: #connection = SMTPConnection(host='smtp.gmail.com',port=587,username=username,password=password,use_tls=True) if mailer_count==0: connection = SMTPConnection(host='mail.messagingengine.com',port=587,username='******',password='******',use_tls=True) elif mailer_count==1: connection = SMTPConnection(host='mail.messagingengine.com',port=587,username='******',password='******',use_tls=True) elif mailer_count==2: connection = SMTPConnection(host='mail.messagingengine.com',port=587,username='******',password='******',use_tls=True) elif mailer_count==3: connection = SMTPConnection(host='mail.messagingengine.com',port=587,username='******',password='******',use_tls=True) elif mailer_count==4: connection = SMTPConnection(host='mail.messagingengine.com',port=587,username='******',password='******',use_tls=True) # connection = SMTPConnection() logit(username) try: connection.send_messages(messages) curr_msg=curr_msg+len(messages) mailer_count=mailer_count + 1 conn.commit()
class SendingOutCommand(NoArgsCommand): subscriber_base = None # Subscriber.rsd or whatever from_email = 'The Daily Gazette <*****@*****.**>' WAIT_TIME = 60 def set_content(self, dummy_request): raise NotImplemented def get_subject(self): today = datetime.date.today() return today.strftime("%%A, %%B %d, %%Y" % today.day) def get_sent_str(self): return datetime.date.today().strftime('%Y-%m-%d') def contents_for_subscriber(self, subscriber): return (self.text_content, self.html_content) def send_to_subscriber(self, subscriber): subj = self.subject frm = self.from_email text_content, html_content = self.contents_for_subscriber(subscriber) if subscriber.plain_text: msg = EmailMessage(subj, text_content, frm, [subscriber.email]) else: msg = EmailMessage(subj, html_content, frm, [subscriber.email]) msg.content_subtype = "html" # msg = EmailMessage(self.subject, text_content, self.from_email, [subscriber.email]) # if not subscriber.plain_text: # msg.multipart_subtype = 'alternative' # msg.attach(content=html_content, mimetype='text/html') self.connection.send_messages([msg]) # if it didn't just crash, sending was successful :) subscriber.last_sent = self.sent_str subscriber.save() def renew_connection(self, subscriber, retries=5, sleep_time_base=2): # close the old one self.connection.fail_silently = True self.connection.close() # get a new one for i in range(retries): try: self.connection = SMTPConnection() self.connection.open() except socket.timeout: self.add_error(subscriber, 'timeout while opening connection') time.sleep(sleep_time_base ** i) else: return def try_sending_to_subscriber(self, subscriber, repeat_index=0, max_repeats=2): if repeat_index >= max_repeats: return try: self.send_to_subscriber(subscriber) except smtplib.SMTPRecipientsRefused: self.add_error(subscriber, 'recipient refused') except smtplib.SMTPServerDisconnected: self.add_error(subscriber, 'server disconnected') self.renew_connection(subscriber) self.try_sending_to_subscriber(subscriber, repeat_index + 1, max_repeats) except socket.sslerror: self.add_error(subscriber, 'ssl error') # probably timeout self.renew_connection(subscriber) self.try_sending_to_subscriber(subscriber, repeat_index + 1, max_repeats) except socket.timeout: self.add_error(subscriber, 'timeout') self.renew_connection(subscriber) self.try_sending_to_subscriber(subscriber, repeat_index + 1, max_repeats) except smtplib.SMTPException: self.add_error(subscriber, 'smtp error') except Exception: self.add_error(subscriber, 'generic error') def add_error(self, subscriber, key): self.errors.setdefault(subscriber.email, {}) self.errors[subscriber.email].setdefault(key, []) exc_type, exc_val, exc_trace = sys.exc_info() self.errors[subscriber.email][key].append({ 'type': exc_type, 'val': exc_val, 'traceback': ''.join(traceback.format_exception(exc_type, exc_val, exc_trace)), 'time': datetime.datetime.now() }) def handle_noargs(self, **options): dummy_request = HttpRequest() dummy_request.GET['for_email'] = 'true' self.set_content(dummy_request) self.subject = self.get_subject() self.sent_str = self.get_sent_str() self.connection = SMTPConnection() self.errors = {} print 'starting: ' + datetime.datetime.now().strftime("%c") # try up to four times, if necessary for i in range(4): not_sent = self.subscriber_base.exclude(last_sent=self.sent_str) if len(not_sent): # intentionally resolve the query if i != 0: print datetime.datetime.now().strftime('%c'), print '- sleeping before retrying %s emails...' % len(not_sent) time.sleep(self.WAIT_TIME) for subscriber in not_sent: self.try_sending_to_subscriber(subscriber) # any that *still* didn't work? error_output = [] for sub in self.subscriber_base.exclude(last_sent=self.sent_str): errors = [ '%d %s' % (len(data), kind) for kind, data in self.errors[sub.email].items() ] error_output.append('errors with %s: %s' % (sub.email, '\t'.join(errors))) if error_output: print '\n', '\n'.join(error_output), '\n' mail_admins('Errors sending out', "Got the following errors while sending the email:\n" + '\n'.join(error_output) + '\n\nMore information is available by loading the pickled log file.' ) if self.errors: print 'more info available in the pickle file' pickle.dump(self.errors, sys.stderr) print 'finished: ' + datetime.datetime.now().strftime("%c")