def form_valid(self, form): data = form.cleaned_data email = data['email'] try: user = User.objects.get(email=email) password = User.objects.make_random_password() user.set_password(password) user.save() t = loader.get_template('commerce/mails/recover-password.html') c = Context({ 'host': COMMERCE_URL, 'password': password, }) message = EmailMultiAlternatives( _(u'Password recover'), '', COMMERCE_EMAIL_FROM, [user.email]) message.attach_alternative(t.render(c), 'text/html') message.send() except ObjectDoesNotExist: pass messages.success( self.request, _(u'New password was successfully sent on your email.')) return super(RecoverView, self).form_valid(form)
def enviarEmailParaCandidato(self, vTipoEmail): try: iEmail = EmailMultiAlternatives() iEmail.subject = self.assunto iEmail.body = self.mensagem iEmail.from_email = self.email_remetente iEmail.to = [self.destinatario.email] iTemplate = loader.get_template('emails/nova-mensagem.html') if vTipoEmail == constantes.cntTipoEmailEnviadoPelaEmpresa: iContext = Context({'imagem':'%s/email/confirmar/%s/' % (settings.PROJECT_ROOT_URL, self.id), 'texto': self.mensagem, 'nome_empresa': self.remetente.empresa.nome_fantasia, 'logo_empresa': '%s%s%s' % (settings.PROJECT_ROOT_URL, settings.MEDIA_URL, self.remetente.empresa.imagem), 'nome_candidato': self.destinatario.nome}) elif vTipoEmail == constantes.cntTipoEmailEnviadoPeloRecrutase: iContext = Context({'imagem':'%s%s%s' % (settings.PROJECT_ROOT_URL, settings.MEDIA_URL, 'img/email/recrutase.jpg'), 'texto': self.mensagem, 'nome_empresa': self.remetente.empresa.nome_fantasia, 'logo_empresa': '%s%s%s' % (settings.PROJECT_ROOT_URL, settings.MEDIA_URL, 'img/email/recrutase-cabecalho.jpg'), 'nome_candidato': self.destinatario.nome}) iEmail.attach_alternative(iTemplate.render(iContext),'text/html') iEmail.send(fail_silently=True) return True except Exception, e: Erro().registraLog('enviarEmailParaCandidato', 'models.py', 'comunicacao', str(e), constantes.cntTipoLogErro) return False
def forget_password(self, request): email = request.DATA.get('email', False) # validate posted params errors = {} if not email: errors['email'] = 'Required' pattern = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" if not re.match(pattern, email): errors['email'] = 'Please input valid email address.' if not errors: user = User.objects.filter(username=email).first() if user: user_code, created = UserCode.objects.get_or_create(user=user, code=random_key(), is_signup=False) reg_url = settings.DOMAIN + 'api/password_reset/' + user_code.code + '/' plaintext = get_template('pw_reset.txt') htmly = get_template('pw_reset.html') d = Context({'url': reg_url}) subject, from_email, to = 'Password Reset [InAppTranslation]', '*****@*****.**', user.username text_content = plaintext.render(d) html_content = htmly.render(d) msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg.attach_alternative(html_content, "text/html") msg.send() return Response({'status': 'success'}) else: errors['email'] = "We can't find any user with the email." return Response(errors, status=status.HTTP_400_BAD_REQUEST)
def send(self): try: model_name = ContentType.objects.get_for_model(self.related_object) except: set_log('info', 'The related object has been deleted when trying to send mail to {0}'.format(self.email_addresses)) self.is_sent = True return True emails = self.email_addresses.split(',') sended = [] for email in emails: subject, text, html = getattr(self, '_'.join(['_pack', model_name.name.lower().replace(' ', '_')]))(email) message = EmailMultiAlternatives(subject, text, settings.DEFAULT_FROM_EMAIL, [email]) if html: message.attach_alternative(html, "text/html") try: message.send() except Exception, e: set_log('error', 'Mail Server eror: ' + str(e)) self.email_addresses = ','.join(set(emails) - set(sended)) return False else: sended.append(email) self.mark_sent()
def send_bulk_emails(cls, subject, body, from_email, to_email_list, dict_images=None): msg_list = [] for email in to_email_list: msg = EmailMultiAlternatives(subject, body, from_email, [email]) if dict_images: for key in dict_images.keys(): image_path = dict_images.get(key) fp = open(image_path, 'rb') mimeImage = MIMEImage(fp.read()) fp.close() mimeImage.add_header('Content-ID', '<'+ key +'>') msg.attach(mimeImage) msg.attach_alternative(body, "text/html") msg.encoding = "utf-8" msg.mixed_subtype = 'related' #msg.content_subtype = "html" # Doute msg_list.append(msg) connection = mail.get_connection() connection.open() ten_msg_list = [] while msg_list <> []: if len(ten_msg_list) < 1000: ten_msg_list.append(msg_list[0]) msg_list.pop(0) else: connection.send_messages(ten_msg_list) ten_msg_list = [] if ten_msg_list <> []: connection.send_messages(ten_msg_list) connection.close()
def save(self, domain_override=None, subject_template_name='authentication/password_reset_subject.txt', email_template_name='registration/password_reset_email.html', use_https=False, token_generator=default_token_generator, from_email=None, request=None): """ Generates a one-use only link for resetting password and sends to the user. """ for user in self.users_cache: if not domain_override: current_site = get_current_site(request) site_name = current_site.name domain = current_site.domain else: site_name = domain = domain_override c = { 'email': user.email, 'domain': domain, 'site_name': site_name, 'uid': int_to_base36(user.pk), 'user': user, 'token': token_generator.make_token(user), 'protocol': use_https and 'https' or 'http', } subject = loader.render_to_string('authentication/password_reset_subject.txt', c) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) message_text = loader.render_to_string('authentication/password_reset_email.txt', c) message_html = loader.render_to_string('authentication/password_reset_email.html', c) msg = EmailMultiAlternatives(subject, message_text, settings.DEFAULT_FROM_EMAIL, [self.user.email]) msg.attach_alternative(message_html, "text/html") msg.send()
def send_feedback(request): """send feedback.""" if request.method == "POST": form = FeedbackForm(request.POST) if form.is_valid(): html_message = render_to_string( "email/ask_admin.html", {"user": request.user, "url": form.cleaned_data["url"], "question": form.cleaned_data["question"]}, ) message = render_to_string( "email/ask_admin.txt", {"user": request.user, "url": form.cleaned_data["url"], "question": form.cleaned_data["question"]}, ) challenge = challenge_mgr.get_challenge() # Using adapted version from Django source code subject = u"[%s] %s asked a question" % (challenge.competition_name, request.user.get_profile().name) if challenge.email_enabled: mail = EmailMultiAlternatives( subject, message, FROM_EMAIL, [challenge.contact_email], headers={"Reply-To": request.user.email} ) mail.attach_alternative(html_message, "text/html") mail.send() # print "email sent %s" % html_message if request.is_ajax(): return HttpResponse(json.dumps({"success": True}), mimetype="application/json") raise Http404
def send_HTML_email(subject, recipient, html_content, text_content=None, cc=None, email_from=None): if not text_content: text_content = getattr(settings, 'NO_HTML_EMAIL_MESSAGE', NO_HTML_EMAIL_MESSAGE) # If you get the return_path header wrong, this may impede mail delivery. It appears that the SMTP server # has to recognize the return_path as being valid for the sending host. If we set it to, say, our SMTP # server, this will always be the case (as the server is explicitly serving the host). if email_from is None: #todo: verify that this is even necessary here since it seems like email_return_path == email_from email_return_path = getattr(settings, 'EMAIL_RETURN_PATH', None) if email_return_path is None: email_return_path = settings.EMAIL_LOGIN email_from = getattr(settings, 'EMAIL_FROM', None) if email_from is None: email_from = email_return_path else: email_return_path = email_from from_header = {'From': email_from} # From-header connection = get_connection() msg = EmailMultiAlternatives(subject, text_content, email_return_path, [recipient], headers=from_header, connection=connection, cc=cc) msg.attach_alternative(html_content, "text/html") msg.send()
def dispatch(self, object, *args, **kwargs): self.object = object languages = [get_language(), self.fallback_language] receivers = self.get_receiver_emails() context = self.get_context() context.update(kwargs) attachments = self.get_attachments() template = self.template_name subject = select_template([ 'emails/{}.{}.subject'.format(template, lang) for lang in languages ]) plaintext = select_template([ 'emails/{}.{}.txt'.format(template, lang) for lang in languages ]) html = select_template([ 'emails/{}.{}.html'.format(template, lang) for lang in languages ]) mail = EmailMultiAlternatives( subject=subject.render(context).strip(), body=plaintext.render(context), from_email=settings.DEFAULT_FROM_EMAIL, to=receivers, ) if len(attachments) > 0: mail.mixed_subtype = 'related' for attachment in attachments: mail.attach(attachment) mail.attach_alternative(html.render(context), 'text/html') mail.send() return mail
def send_email(self, prefix): subject_file = 'authemail/%s_subject.txt' % prefix txt_file = 'authemail/%s.txt' % prefix html_file = 'authemail/%s.html' % prefix subject = render_to_string(subject_file).strip() from_email = settings.DEFAULT_EMAIL_FROM to = self.user.email bcc_email = settings.DEFAULT_EMAIL_BCC # Make some context available ctxt = { 'email': self.user.email, 'first_name': self.user.first_name, 'last_name': self.user.last_name, 'code': self.code, 'MEDIA_URL': settings.MEDIA_URL, 'STATIC_URL': settings.STATIC_URL, 'BASE_URL': settings.BASE_URL } text_content = render_to_string(txt_file, ctxt) html_content = render_to_string(html_file, ctxt) msg = EmailMultiAlternatives(subject, text_content, from_email, [to], bcc=[bcc_email]) msg.attach_alternative(html_content, 'text/html') msg.send()
def send_mail(template_name, context, subject, to_addrs, bcc=None, from_addr=None): from tao.models import GlobalParameter if from_addr is None: from_addr = settings.EMAIL_FROM_ADDRESS if type(context) == dict: context = Context(context) try: html_mail = GlobalParameter.objects.get(parameter_name='{template_name}.html'.format(template_name=template_name)) html_content = Template(html_mail.parameter_value).render(context) except GlobalParameter.DoesNotExist: html_content = None try: text_mail = GlobalParameter.objects.get(parameter_name='{template_name}.txt'.format(template_name=template_name)) if len(text_mail.parameter_value.strip()) == 0: # Don't send the email if the txt template is empty # Just log the event for posterity logger.warn("Not sending template '{0}' to {1}".format(template_name, str(to_addrs))) return text_content = Template(text_mail.parameter_value).render(context) msg = EmailMultiAlternatives(subject, text_content, from_addr, to_addrs, bcc=bcc) if html_content is not None: msg.attach_alternative(html_content, 'text/html') msg.send(fail_silently=False) logger.info("Sent template '{0}' to {1}".format(template_name, str(to_addrs))) except GlobalParameter.DoesNotExist: msg = EmailMultiAlternatives("CONFIGURATION ERROR", "Template {template_name}.txt is not found".format(template_name=template_name), from_addr, (from_addr,)) msg.send(fail_silently=False)
def send_feedback(request): if request.method == "POST": form = FeedbackForm(request.POST) if form.is_valid(): html_message = render_to_string("email/ask_admin.html", { "user": request.user, "url": form.cleaned_data["url"], "question": form.cleaned_data["question"], }) message = render_to_string("email/ask_admin.txt", { "user": request.user, "url": form.cleaned_data["url"], "question": form.cleaned_data["question"], }) # Using adapted version from Django source code current_site = Site.objects.get(id=settings.SITE_ID) subject = u'[%s] %s asked a question' % (current_site.domain, request.user.get_profile().name) mail = EmailMultiAlternatives(subject, message, FROM_EMAIL, [settings.CONTACT_EMAIL,], headers={"Reply-To": request.user.email}) mail.attach_alternative(html_message, 'text/html') mail.send() # mail_admins("[%s] Message for admins" % current_site.domain, # message, html_message=html_message, headers={'Reply-To': request.user.email}) if request.is_ajax(): return HttpResponse(json.dumps({"success": True}), mimetype="application/json") return HttpResponseRedirect(form.cleaned_data["url"]) raise Http404
def execute(self): print >> sys.stdout, 'Executing DeferredNotificationsTask' start = time.time() notifications = Notification.objects.collection.find({'is_sent': False, 'send_date': {'$lte': timezone.now()} }).sort('send_date', -1) for notification in notifications: msg = EmailMultiAlternatives(notification['subject'], notification['message_text'], settings.EMAIL_HOST_USER, [notification['email'], ], []) if len(notification['message_html']): msg.attach_alternative(notification['message_html'], "text/html") # mustdo: implement attaches # attaches = NotificationAttaches.objects.filter(nid=notification) # sys.stdout.write(u' Find %d attache files\n' % attaches.count()) # # if attaches.count(): # for attache in attaches: # sys.stdout.write(u' Attache file: %s\n' % attache.file) # msg.attach_file(attache.file) msg.send() Notification.objects.update({'_id' : notification['_id']}, {'$set' : {'is_sent' : True}}) finish = time.time() run_time = finish - start if run_time > SECONDS_LIMIT: return
def contact_view(request): if request.method == "POST": form1 = ContactoForm(request.POST,request.FILES) form2 = MensajeContactoForm(request.POST,request.FILES) if form1.is_valid() and form2.is_valid() : nombre = form1.cleaned_data['nombre'] apellido = form1.cleaned_data['apellido'] email = form1.cleaned_data['email'] mensaje =form2.cleaned_data['mensaje'] email_context = { 'titulo': 'Has recibido un correo del usuario:', 'usuario': nombre +','+ apellido, 'mensaje': mensaje, } # se renderiza el template con el context email_html = render_to_string('email_contacto.html', email_context) email_text = strip_tags(email_html) correo = EmailMultiAlternatives('Mensaje de Usuario: '+nombre+', '+apellido, email_text, email,['*****@*****.**'],) # se especifica que el contenido es html correo.attach_alternative(email_html, 'text/html') # se envía el correo correo.send() return render_to_response('RecursosDeEmpresa/message_sent.html',context_instance=RequestContext(request)) else: form1 = ContactoForm() form2 = MensajeContactoForm() boton = 'Enviar Solicitud' ctx = {'form1': form1,'form2':form2,'boton':boton} return render_to_response('contacto.html',ctx,context_instance=RequestContext(request))
def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None): """ Easy wrapper for sending a single message to a recipient list. All members of the recipient list will see the other recipients in the 'To' field. If auth_user is None, the EMAIL_HOST_USER setting is used. If auth_password is None, the EMAIL_HOST_PASSWORD setting is used. Note: The API for this method is frozen. New code wanting to extend the functionality should use the EmailMessage class directly. """ connection = connection or get_connection( username=auth_user, password=auth_password, fail_silently=fail_silently) mail = EmailMultiAlternatives( subject, message, from_email, recipient_list, connection=connection) if html_message: mail.attach_alternative(html_message, 'text/html') return mail.send()
def send(self): try: mail = EmailMultiAlternatives(self.subject, self.html_body, self.sender, self.recipients, connection=self.connection) mail.attach_alternative(self.html_body, 'text/html') mail.send() except Exception as e: print "Unexpected error while sending email:", e
def contacto_view(request): info_enviado = False email = '' titulo = '' contenido = '' if request.method == 'POST': formulario = ContactoForm(request.POST) if formulario.is_valid(): info_enviado = True email = formulario.cleaned_data['email'] titulo = formulario.cleaned_data['titulo'] contenido = formulario.cleaned_data['contenido'] #configuracion para enviar el mensaje a GMAIL html_content = 'Informacion recibida <br/> <br/> <h3> ******* Mensaje de %s ******* </h3> <br/> <br/>' \ '<h4>Titulo: %s </h4>' \ '<p>%s</p>' % (email, titulo, contenido) to = '*****@*****.**' msje = EmailMultiAlternatives('Correo de contacto', html_content, '*****@*****.**', [to]) msje.attach_alternative(html_content, 'text/html') msje.send() else: formulario = ContactoForm() ctx = {'enviado': info_enviado, 'email': email, 'titulo': titulo, 'contenido': contenido, 'form': formulario} return render_to_response('contacto.html', ctx, context_instance=RequestContext(request))
def send_active_email(active_form,user_email): subject,form_email,to = u'数据服务平台-激活邮件','*****@*****.**',user_email text_content = u'数据服务平台-激活邮件' html_content = active_form msg = EmailMultiAlternatives(subject,text_content,form_email,[to]) msg.attach_alternative(html_content, 'text/html') msg.send()
def fixSizes(): from django.core.mail.message import EmailMultiAlternatives from django.template.loader import render_to_string from django.utils.html import strip_tags from rts.models import ReturnedItemDetails, rts_status for item in ReturnedItemDetails.objects.filter(status = rts_status.REFUNDED,isEmailSent=False): from_email = "<*****@*****.**>" from_name = str(FROM_EMAIL_NAME) #to = item.order_item.customer_email to = "*****@*****.**" subject = str(FROM_EMAIL_SUBJECT) html_content = render_to_string('zidaya_return_email_template_1.html', { 'billing_name':item.order_item.billing_name.title(), 'order_date': str(item.order_item.order_date.day).zfill(2)+"."+str(item.order_item.order_date.month).zfill(2)+"."+str(item.order_item.order_date.year), 'order_nr':item.order_item.order_nr, 'paid_price':item.order_item.paid_price, 'refund_reference_number':item.refund_reference_number, 'product_image':"http://static.zidaya.com/p/-"+str(item.order_item.id_catalog_config)[::-1]+"-1-catalog.jpg", 'name':item.order_item.name, 'new_coupon':item.new_coupon, 'sku':item.order_item.sku }) text_content = strip_tags(html_content) msg = EmailMultiAlternatives(subject, text_content, from_name+" "+from_email, [to]) msg.attach_alternative(html_content, "text/html") try: msg.send() item.isEmailSent = True item.save() except: pass
def deliver_to(self, user, context, notification, language): to_email = self.get_email(user) context.update({ 'to_email': to_email, }) subject = render_to_string( ( "notifyme/notification_types/%s/email/subject.txt" % notification.identifier, "notifyme/notification_types/generic/email/subject.txt", ), context_instance=context ) body = render_to_string( ( "notifyme/notification_types/%s/email/body.txt" % notification.identifier, "notifyme/notification_types/generic/email/body.txt", ), context_instance=context ) body_html = render_to_string( ( "notifyme/notification_types/%s/email/body.html" % notification.identifier, "notifyme/notification_types/generic/email/body.html", ), context_instance=context ) # send the HTML Email email_msg = EmailMultiAlternatives(subject, body, self.get_from_email(user), [to_email], headers={}) email_msg.attach_alternative(body_html, "text/html") email_msg.send()
def make_mail(ModelAdmin, request, queryset): """ Создаем рассылку и отправляем. """ from datetime import datetime if queryset.filter(status='n'): connection = mail.get_connection() connection.open() messages = list() for i in xrange(0, len(get_recipients(queryset))): rep_list = get_recipients(queryset) header = u'\'' + get_sender(queryset) + u'\'' msg = EmailMultiAlternatives( subject = unicode(get_subject(queryset)), body = unicode(get_body(queryset)), from_email = unicode(get_fullname(queryset)), to = [rep_list[i]], # attachments=unicode(get_attachment(queryset)), reply_to = [unicode(get_fullname(queryset))]) msg.attach_alternative(unicode(get_body(queryset)), 'text/html') # msg.attach_file(get_attachment(queryset)) msg.attach_file(os.path.join(settings.MEDIA_ROOT, str(get_attachment(queryset)))) msg.encoding = 'utf-8' messages.append(msg) connection.send_messages(messages) connection.close() ModelAdmin.message_user(request, u'Рассылка отправлена') # ModelAdmin.message_user(request, get_attachment(queryset)) queryset.update(status='f') queryset.update(send_date=datetime.now()) else: ModelAdmin.message_user(request, u'Рассылка уже выполняется или завершена', 'warning')
def send_mail(subject, message, recipient_list, from_email=None, **kwargs): """ Wrapper around Django's EmailMultiAlternatives as done in send_mail(). Custom from_email handling and special Auto-Submitted header. """ if not from_email: if hasattr(settings, 'WAGTAILADMIN_NOTIFICATION_FROM_EMAIL'): from_email = settings.WAGTAILADMIN_NOTIFICATION_FROM_EMAIL elif hasattr(settings, 'DEFAULT_FROM_EMAIL'): from_email = settings.DEFAULT_FROM_EMAIL else: from_email = 'webmaster@localhost' connection = kwargs.get('connection', False) or get_connection( username=kwargs.get('auth_user', None), password=kwargs.get('auth_password', None), fail_silently=kwargs.get('fail_silently', None), ) kwargs = { 'connection': connection, 'headers': { 'Auto-Submitted': 'auto-generated', } } mail = EmailMultiAlternatives(subject, message, from_email, recipient_list, **kwargs) html_message = kwargs.get('html_message', None) if html_message: mail.attach_alternative(html_message, 'text/html') return mail.send()
def handle(self, *args, **options): while True: last_hour = datetime.datetime.utcnow().replace(tzinfo=utc) - datetime.timedelta(hours=1) profiles = Profile.objects.select_related().filter( user__date_joined__gte=last_hour, user_referrer__profile__enable_email_updates=True, user_referrer__is_active=True, ) for profile in profiles: if not profile.user_referrer.email: continue try: FriendJoinedEmailLog.objects.get(user=profile.user_referrer, user_referred=profile.user) except FriendJoinedEmailLog.DoesNotExist: dict_context = { 'site': self.site, 'referred_profile': profile, 'referring_profile': profile.user_referrer.get_profile(), } email_subject = render_to_string('emails/friend-joined/subject.txt', dict_context).strip() email_txt = render_to_string('emails/friend-joined/message.txt', dict_context) email_html = render_to_string('emails/friend-joined/message.html', dict_context) email = EmailMultiAlternatives( email_subject, email_txt, settings.DEFAULT_FROM_EMAIL, [profile.user_referrer.email,] ) email.attach_alternative(email_html, 'text/html') email.send() FriendJoinedEmailLog.objects.create(user=profile.user_referrer, user_referred=profile.user) self.close_db_connection() time.sleep(600)
def mail_multiple( subject, message, email_addresses, from_email=settings.ORGANIZERS_EMAIL, cc=None, bcc=None, html_message=None, connection=None, fail_silently=True, ): """ Sends a message to multiple email addresses. Based on django.core.mail.mail_admins() """ for email_address in email_addresses: mail = EmailMultiAlternatives( u"%s%s" % (settings.EMAIL_SUBJECT_PREFIX, subject), message, bcc=bcc, cc=cc, connection=connection, from_email=from_email, to=[email_address], ) if html_message: mail.attach_alternative(html_message, "text/html") mail.send(fail_silently=fail_silently)
def index(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): t = loader.get_template('feedback/emails/body.txt') c = { 'data': form.cleaned_data, 'site': Site.objects.get_current(), 'date': datetime.now(), } subject = render_to_string('feedback/emails/subject.txt', c).replace('\n','') html_body = t.render(Context(c)) text_body = strip_tags(html_body) msg = EmailMultiAlternatives(subject, text_body, form.cleaned_data['email'], settings.MANAGERS) msg.attach_alternative(html_body, "text/html") msg.send() form = ContactForm() messages.success(request, "Ваше сообщение успешно отправлено!") else: form = ContactForm() return render(request, 'feedback/index.html', {'form':form})
def send_mail_with_template( subject, from_email, recipient_list, plaintext_template, html_template, context, fail_silently=False, auth_user=None, auth_password=None, connection=None, headers=None, bcc_list=None, ): connection = connection or get_connection(username=auth_user, password=auth_password, fail_silently=fail_silently) headers = headers or {"Reply-To": from_email} plaintext = get_template(plaintext_template) text_content = plaintext.render(context) msg = EmailMultiAlternatives(subject, text_content, from_email, recipient_list, bcc_list) if html_template is not None: html = get_template(html_template) html_content = html.render(context) msg.attach_alternative(html_content, "text/html") return msg.send()
def send(self, outbound_message): # Here there should be somewhere the contacts # Returns a tuple with the result_of_sending, fatal_error # so False, True means that there was an error sending and you should not try again try: writeitinstance = outbound_message.message.writeitinstance template = writeitinstance.mailit_template except: return False, False author_name = outbound_message.message.author_name context = { 'subject': outbound_message.message.subject, 'content': outbound_message.message.content, 'content_indented': process_content(outbound_message.message.content), 'person': outbound_message.contact.person.name, 'author': author_name, 'writeit_url': writeitinstance.get_absolute_url(), 'message_url': outbound_message.message.get_absolute_url(), 'writeit_name': writeitinstance.name, 'owner_email': writeitinstance.owner.email, } text_content = template.get_content_template().format(**context) html_content = template.content_html_template.format(**escape_dictionary_values(context)) subject = template.subject_template.format(**context) if settings.SEND_ALL_EMAILS_FROM_DEFAULT_FROM_EMAIL: from_email = author_name + " <" + settings.DEFAULT_FROM_EMAIL + ">" else: from_domain = writeitinstance.config.custom_from_domain or settings.DEFAULT_FROM_DOMAIN from_email = ( author_name + " <" + writeitinstance.slug + "+" + outbound_message.outboundmessageidentifier.key + '@' + from_domain + ">" ) # There there should be a try and except looking # for errors and stuff try: to_email = writeitinstance.owner.email if writeitinstance.config.testing_mode else outbound_message.contact.value msg = EmailMultiAlternatives( subject, text_content, from_email, [to_email], connection=writeitinstance.config.get_mail_connection(), ) if html_content: msg.attach_alternative(html_content, "text/html") msg.send(fail_silently=False) log = "Mail sent from %(from)s to %(to)s" log = log % { 'from': from_email, 'to': outbound_message.contact.value, } logging.info(log) except SMTPServerDisconnected, e: return False, False
def common_send_email(subject, text_template_path, html_template_path, context_data, recipients, from_email=None): """ This method is a common method to send email via the bhane system. """ coupon_obj = context_data['coupon_obj'] if not from_email: from_email = DEFAULT_FROM_EMAIL #get templates from file system text_raw_content = get_template(text_template_path) try: html_raw_content = get_template(coupon_obj.vendor.email_content.path)#will return absolute path except: html_raw_content = get_template(html_template_path)#else pickup common_vendor_email.html #render the raw data in the template d = Context(context_data) text_content = text_raw_content.render(d) html_content = html_raw_content.render(d) #contstruct the message and send it msg = EmailMultiAlternatives(subject, text_content, from_email, recipients) if coupon_obj.image.name: msg.attach_file(coupon_obj.image.path) msg.attach_alternative(html_content, "text/html") msg.send()
def send_HTML_email(subject, recipient, html_content, text_content=None, cc=None, email_from=settings.DEFAULT_FROM_EMAIL, file_attachments=None, bcc=None, smtp_exception_skip_list=None): recipient = list(recipient) if not isinstance(recipient, six.string_types) else [recipient] if not isinstance(html_content, six.text_type): html_content = html_content.decode('utf-8') if not text_content: text_content = getattr(settings, 'NO_HTML_EMAIL_MESSAGE', NO_HTML_EMAIL_MESSAGE) elif not isinstance(text_content, six.text_type): text_content = text_content.decode('utf-8') from_header = {'From': email_from} # From-header connection = get_connection() msg = EmailMultiAlternatives(subject, text_content, email_from, recipient, headers=from_header, connection=connection, cc=cc, bcc=bcc) for file in (file_attachments or []): if file: msg.attach(file["title"], file["file_obj"].getvalue(), file["mimetype"]) msg.attach_alternative(html_content, "text/html") try: msg.send() except SMTPSenderRefused as e: if smtp_exception_skip_list and e.smtp_code in smtp_exception_skip_list: raise e else: error_subject = _('ERROR: Could not send "%(subject)s"') % { 'subject': subject, } if e.smtp_code == 552: error_text = _('Could not send email: file size is too large.') else: error_text = e.smtp_error error_text = '%s\n\n%s' % ( error_text, _('Please contact %(support_email)s for assistance.') % { 'support_email': settings.SUPPORT_EMAIL, }, ) error_msg = EmailMultiAlternatives( error_subject, error_text, email_from, recipient, headers=from_header, connection=connection, cc=cc, bcc=bcc, ) error_msg.send()
def emit(self, record): """Send a log error over email. Args: The logging.LogRecord object. See http://docs.python.org/library/logging.html#logging.LogRecord """ from django.conf import settings if settings.DEBUG and record.levelno < logging.WARNING: # NOTE: You don't want to try this on dev_appserver. Trust me. return signature = self.__GetRecordSignature(record) try: from google.appengine.api import memcache if not memcache.add(signature, True, time=self.log_interval): return except Exception: pass formatted_record = self.format(record) request = None try: if sys.version_info < (2, 5): # A nasty workaround required because Python 2.4's logging # module doesn't support passing in extra context. # For this handler, the only extra data we need is the # request, and that's in the top stack frame. request = record.exc_info[2].tb_frame.f_locals['request'] else: request = record.request except Exception: pass try: for jid, params in self.recipients.items(): if record.levelno < params['level']: continue sender = 'errors@%s.appspotmail.com' % app_id subject = '(%s) error reported for %s, version %s' % (record.levelname, app_id, app_ver) message = formatted_record exc_info = record.exc_info if record.exc_info else (None, record.msg, None) reporter = ExceptionReporter(request, is_email=True, *exc_info) html_message = reporter.get_traceback_html() or None mail = EmailMultiAlternatives('%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject), message, sender, [jid]) if html_message: mail.attach_alternative(html_message, 'text/html') mail.send() except OverQuotaError: pass except Exception: self.handleError(record)
def email_users_view(request, template_name='studioadmin/email_users_form.html'): users_to_email = User.objects.filter( id__in=request.session['users_to_email']) if request.method == 'POST': form = EmailUsersForm(request.POST) if form.is_valid(): subject = '{} {}'.format(settings.ACCOUNT_EMAIL_SUBJECT_PREFIX, form.cleaned_data['subject']) from_address = form.cleaned_data['from_address'] message = form.cleaned_data['message'] cc = form.cleaned_data['cc'] # do this per email address so recipients are not visible to # each email_addresses = [user.email for user in users_to_email] for email_address in email_addresses: try: msg = EmailMultiAlternatives( subject, message, from_address, [email_address], cc=[from_address] if cc else [], reply_to=[from_address]) msg.attach_alternative( get_template( 'studioadmin/email/email_users.html').render({ 'subject': subject, 'message': message }), "text/html") msg.send(fail_silently=False) except Exception as e: # send mail to tech support with Exception send_support_email(e, __name__, "Bulk Email to students") ActivityLog.objects.create( log="Possible error with " "sending bulk email; notification sent to tech support" ) ActivityLog.objects.create( log='Bulk email with subject "{}" sent to users {} by ' 'admin user {}'.format(subject, email_addresses, request.user.username)) return render(request, 'studioadmin/email_users_confirmation.html') else: messages.error( request, mark_safe("Please correct errors in form: {}".format( form.errors))) else: form = EmailUsersForm() return TemplateResponse( request, template_name, { 'form': form, 'users_to_email': users_to_email, 'sidenav_selection': 'email_users', })
def forgot_password(self, request=None, **kwargs): ''' api for the user to create a new password. the user will be sent with new temp passsword to his email address. @param email: the email address of the user @return: 200 on success 401 on unuthorized (account not activated) 404 on account not found 500 if failed to send mail ''' #get the post params post = simplejson.loads(request.body) email = post.get('email') if (email): # make sure the email is an email of user in our system user = None try: User = get_user_model() user = User.objects.get(email=email, is_active=True) except User.DoesNotExist: return self.create_response( request, { 'success': False, 'message': 'Account not found or not active', }, HttpNotFound) #send the mail with the new password if is_send_grid(): # generate new password and set it to the user new_password = uuid.uuid4().hex[0:8] user.set_password(new_password) user.save() first_name = user.first_name.capitalize() # send the mail t = get_template('emails/forgot_password.html') html = t.render( Context({ 'new_password': new_password, 'first_name': first_name })) text_content = strip_tags(html) msg = EmailMultiAlternatives('Prep4GMAT - Forgot Password', text_content, settings.ADMIN_MAIL, [email]) msg.attach_alternative(html, "text/html") try: msg.send() except SMTPSenderRefused: return self.create_response( request, { 'success': False, 'message': 'Failed to send mail', }, HttpApplicationError) return self.create_response( request, { 'success': True, 'message': 'Mail was successfully sent', }, HttpAccepted) else: return self.create_response( request, { 'success': False, 'message': 'Mail server not defined', }, HttpApplicationError) else: return self.create_response( request, { 'success': False, 'message': 'You must pass an email address', }, HttpBadRequest)
def _send_sample_manifest(sample_manifest_rows, kit_id, original_filename, original_file_rows, user, project): # write out the sample manifest file wb = xl.Workbook() ws = wb.active ws.title = "Sample Info" ws.append( MergedPedigreeSampleManifestConstants.SAMPLE_MANIFEST_HEADER_ROW1) ws.append( MergedPedigreeSampleManifestConstants.SAMPLE_MANIFEST_HEADER_ROW2) for row in sample_manifest_rows: ws.append([ row[column_key] for column_key in MergedPedigreeSampleManifestConstants.SAMPLE_MANIFEST_COLUMN_NAMES ]) temp_sample_manifest_file = tempfile.NamedTemporaryFile() wb.save(temp_sample_manifest_file.name) temp_sample_manifest_file.seek(0) sample_manifest_filename = kit_id + ".xlsx" logger.info("Sending sample manifest file %s to %s" % (sample_manifest_filename, UPLOADED_PEDIGREE_FILE_RECIPIENTS)) original_table_attachment_filename = '{}.xlsx'.format('.'.join( os.path.basename(original_filename).split('.')[:-1])) email_body = "User {} just uploaded pedigree info to {}.<br />".format( user.email or user.username, project.name) email_body += """This email has 2 attached files:<br /> <br /> <b>%(sample_manifest_filename)s</b> is the sample manifest file in a format that can be sent to GP.<br /> <br /> <b>%(original_filename)s</b> is the original merged pedigree-sample-manifest file that the user uploaded.<br /> """ % locals() temp_original_file = tempfile.NamedTemporaryFile() wb_out = xl.Workbook() ws_out = wb_out.active for row in original_file_rows: ws_out.append(row) wb_out.save(temp_original_file.name) temp_original_file.seek(0) email_message = EmailMultiAlternatives( subject=kit_id + " Merged Sample Pedigree File", body=strip_tags(email_body), to=UPLOADED_PEDIGREE_FILE_RECIPIENTS, attachments=[ (sample_manifest_filename, temp_sample_manifest_file.read(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ), (original_table_attachment_filename, temp_original_file.read(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ), ], ) email_message.attach_alternative(email_body, 'text/html') email_message.send()
def send_email_to_publisher(course_run, user, site): """ Send email to publisher when course-run is marked as reviewed. Arguments: course_run (Object): CourseRun object user (Object): User object site (Site): Current site """ txt_template = 'publisher/email/course_run/mark_as_reviewed.txt' html_template = 'publisher/email/course_run/mark_as_reviewed.html' course_key = CourseKey.from_string(course_run.lms_course_id) subject = _('Review complete: {course_name} {run_number}').format( # pylint: disable=no-member course_name=course_run.course.title, run_number=course_key.run) recipient_user = course_run.course.publisher user_role = course_run.course.course_user_roles.get(user=user) sender_team = 'course team' if user_role.role == PublisherUserRole.MarketingReviewer: sender_team = 'marketing team' try: if is_email_notification_enabled(recipient_user): project_coordinator = course_run.course.project_coordinator to_addresses = [recipient_user.email] from_address = settings.PUBLISHER_FROM_EMAIL page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id}) context = { 'recipient_name': recipient_user.full_name or recipient_user.username if recipient_user else '', 'sender_name': user.full_name or user.username, 'course_name': course_run.course.title, 'run_number': course_key.run, 'org_name': course_run.course.organizations.all().first().name, 'sender_team': sender_team, 'contact_us_email': project_coordinator.email if project_coordinator else '', 'page_url': 'https://{host}{path}'.format(host=site.domain.strip('/'), path=page_path) } template = get_template(txt_template) plain_content = template.render(context) template = get_template(html_template) html_content = template.render(context) email_msg = EmailMultiAlternatives(subject, plain_content, from_address, to_addresses) email_msg.attach_alternative(html_content, 'text/html') email_msg.send() except Exception: # pylint: disable=broad-except logger.exception( 'Failed to send email notifications for mark as reviewed of course-run %s', course_run.id)
def handle(self, *args, **options): filename = options['filename'][0] self.file = open(filename, 'r') csv_file = csv.DictReader(self.file) if csv_file.fieldnames != self.NEEDED_FIELDS: raise CommandError("We're expecting these fields: %s" % self.NEEDED_FIELDS) # check group names all_groups = set(Group.objects.values_list('name', flat=True)) outstanding_group_names = set( map(lambda p: p['Group'], filter(lambda p: p['Group'] not in all_groups, csv_file))) if len(outstanding_group_names) > 0: warnings.warn("These groups are not setup yet: %s" % (', '.join(outstanding_group_names))) self._reset() # check phone numbers phone_numbers = map(lambda p: p['Phone'], csv_file) invalid_phone_numbers = [] for phone in phone_numbers: if not phone_digits_re.match(phone): invalid_phone_numbers.append(phone) if invalid_phone_numbers: warnings.warn("These phone numbers are not valid: %s" % (', '.join(invalid_phone_numbers))) self._reset() # check emails email_addresses = map(lambda p: p['Email'], csv_file) invalid_email_addresses = [] for email in email_addresses: try: validate_email(email) except: invalid_email_addresses.append(email) if invalid_email_addresses: warnings.warn("These email addresses are not valid: %s" % (', '.join(invalid_email_addresses))) self._reset() # check if email is already in system? existing_email = User.objects.filter(email__in=email_addresses) if existing_email.count(): warnings.warn( "These email addresses already have users: %s" % (', '.join(existing_email.values_list('email', flat=True)))) if not options['force']: print "Dry run complete! Run again with '-f' argument to run import." exit(0) keyify = { 'First Name': 'first_name', 'Last Name': 'last_name', 'Email': 'email' } group_names_and_ids = dict( (group[0], group[1]) for group in Group.objects.values_list('id', 'name')) for person in csv_file: phone_number = person.pop('Phone') group_name = person.pop('Group') person_kwargs = dict((keyify[k], v) for k, v in person.iteritems()) person_kwargs['username'] = ''.join( [person['First Name'], person['Last Name']]).lower().replace(" ", "") password = "******" % random.randint(20, 99) if group_name in self.STAFF_GROUPS: person_kwargs['is_staff'] = True # if group_name == 'Superusers': # person_kwargs['is_superuser'] = True new_user = User(**person_kwargs) new_user.set_password(password) new_user.save() Group.objects.get(name=group_name).user_set.add(new_user) if phone_number: PhoneNumber.objects.create(user=new_user, phone_number=phone_number) print "Created new user '%s' with email '%s' and password '%s'" % ( new_user.username, new_user.email, password) if options['send_email_invites']: operator_tpl = """Hi %(first_name)s, You've been invited to use Vincent, a new voter incident tracking system. Your username is %(username)s. Please use this one-time link to login and set a memorable password: https://vincent.berniesanders.com/?username=%(username)s&password=%(password)s After that, you'll be ready to go. Just log in here: https://vincent.berniesanders.com Feel free to respond to this email if you have any troubles and we'll get you sorted. Thank you! Jacob""" admin_tpl = """Hi %(first_name)s, You've been invited to use Vincent, a new voter incident tracking system. Your username is %(username)s and your password is %(password)s. As an admin, you can log in here to get a dashboard view of all incidents: https://vincent.berniesanders.com/admin/vincent/incidentreport/ Feel free to respond to this email if you have any troubles and we'll get you sorted. Thank you! Jacob""" email_body_tpl = admin_tpl if group_name == 'Admins' else operator_tpl plain_text_body = email_body_tpl % { 'first_name': new_user.first_name, 'username': new_user.username, 'password': password } html_body = linebreaks(urlize(plain_text_body)) email_message = EmailMultiAlternatives( subject= 'Welcome to Vincent, a new voter incident tracking system', body=plain_text_body, from_email='Jacob LeGrone <*****@*****.**>', to=[new_user.email], headers={'X-Mailgun-Track': False}) email_message.attach_alternative(html_body, "text/html") email_message.send(fail_silently=False) print "Users created!"
def send_course_run_published_email(course_run, site): """ Send email when course run is published by publisher. Arguments: course_run (Object): CourseRun object site (Site): Current site """ txt_template = 'publisher/email/course_run/published.txt' html_template = 'publisher/email/course_run/published.html' course_team_user = course_run.course.course_team_admin try: if is_email_notification_enabled(course_team_user): course_key = CourseKey.from_string(course_run.lms_course_id) subject = _( 'Publication complete: About page for {course_name} {run_number}' ).format( # pylint:disable=no-member course_name=course_run.course.title, run_number=course_key.run) from_address = settings.PUBLISHER_FROM_EMAIL project_coordinator = course_run.course.project_coordinator page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id}) course_page_path = reverse('publisher:publisher_course_detail', kwargs={'pk': course_run.course.id}) context = { 'sender_role': PublisherUserRole.Publisher, 'course_name': course_run.course.title, 'preview_url': course_run.preview_url, 'course_run_number': course_key.run, 'recipient_name': course_team_user.get_full_name() or course_team_user.username, 'contact_us_email': project_coordinator.email if project_coordinator else '', 'page_url': 'https://{host}{path}'.format(host=site.domain.strip('/'), path=page_path), 'course_page_url': 'https://{host}{path}'.format(host=site.domain.strip('/'), path=course_page_path), 'platform_name': settings.PLATFORM_NAME, } template = get_template(txt_template) plain_content = template.render(context) template = get_template(html_template) html_content = template.render(context) email_kwargs = { 'cc': [project_coordinator.email] if project_coordinator else [], } email_msg = EmailMultiAlternatives(subject, plain_content, from_address, to=[course_team_user.email], **email_kwargs) email_msg.attach_alternative(html_content, 'text/html') email_msg.send() except Exception: # pylint: disable=broad-except error_message = 'Failed to send email notifications for course published of course-run [{run_id}]'.format( run_id=course_run.id) logger.exception(error_message) raise Exception(error_message)
def send_email_preview_accepted(course_run, site): """ Send email for preview approved to publisher and project coordinator. Arguments: course_run (Object): CourseRun object site (Site): Current site """ txt_template = 'publisher/email/course_run/preview_accepted.txt' html_template = 'publisher/email/course_run/preview_accepted.html' course = course_run.course publisher_user = course.publisher try: if is_email_notification_enabled(publisher_user): course_key = CourseKey.from_string(course_run.lms_course_id) subject = _( 'Publication requested: {course_name} {run_number}').format( # pylint: disable=no-member course_name=course.title, run_number=course_key.run) project_coordinator = course.project_coordinator to_addresses = [publisher_user.email] if is_email_notification_enabled(project_coordinator): to_addresses.append(project_coordinator.email) from_address = settings.PUBLISHER_FROM_EMAIL page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id}) course_page_path = reverse('publisher:publisher_course_detail', kwargs={'pk': course_run.course.id}) context = { 'course_name': course.title, 'run_number': course_key.run, 'publisher_role_name': PublisherUserRole.Publisher, 'course_team': course.course_team_admin, 'org_name': course.organizations.all().first().name, 'contact_us_email': project_coordinator.email if project_coordinator else '', 'page_url': 'https://{host}{path}'.format(host=site.domain.strip('/'), path=page_path), 'course_page_url': 'https://{host}{path}'.format(host=site.domain.strip('/'), path=course_page_path) } template = get_template(txt_template) plain_content = template.render(context) template = get_template(html_template) html_content = template.render(context) email_msg = EmailMultiAlternatives(subject, plain_content, from_address, to=[from_address], bcc=to_addresses) email_msg.attach_alternative(html_content, 'text/html') email_msg.send() except Exception: # pylint: disable=broad-except message = 'Failed to send email notifications for preview approved of course-run [{id}].'.format( id=course_run.id) logger.exception(message) raise Exception(message)
def send_change_role_assignment_email(course_role, former_user, site): """ Send email for role assignment changed. Arguments: course_role (Object): CourseUserRole object former_user (Object): User object site (Site): Current site """ txt_template = 'publisher/email/role_assignment_changed.txt' html_template = 'publisher/email/role_assignment_changed.html' course = course_role.course project_coordinator = course.project_coordinator course_team_admin = course.course_team_admin from_address = settings.PUBLISHER_FROM_EMAIL try: role_name = course_role.get_role_display() subject = _('{role_name} changed for {course_title}').format( # pylint: disable=no-member role_name=role_name.lower(), course_title=course.title) to_addresses = course.get_course_users_emails() if former_user.email not in to_addresses: to_addresses.append(former_user.email) if course_team_admin and course_team_admin.email in to_addresses: to_addresses.remove(course_team_admin.email) page_path = reverse('publisher:publisher_course_detail', kwargs={'pk': course.id}) course_url = 'https://{host}{path}'.format(host=site.domain.strip('/'), path=page_path) context = { 'course_title': course.title, 'role_name': role_name.lower(), 'former_user_name': former_user.get_full_name() or former_user.username, 'current_user_name': course_role.user.get_full_name() or course_role.user.username, 'contact_us_email': getattr(project_coordinator, 'email', ''), 'course_url': course_url, 'platform_name': settings.PLATFORM_NAME, } template = get_template(txt_template) plain_content = template.render(context) template = get_template(html_template) html_content = template.render(context) email_msg = EmailMultiAlternatives(subject, plain_content, from_address, to=to_addresses) email_msg.attach_alternative(html_content, 'text/html') email_msg.send() except Exception: # pylint: disable=broad-except error_message = 'Failed to send email notifications for change role assignment of role: [{role_id}]'.format( role_id=course_role.id) logger.exception(error_message) raise Exception(error_message)
def send_email_for_comment(comment, created=False): """ Send the emails for a comment. Arguments: comment (Comment): Comment object created (Bool): Value indicating comment is created or updated """ try: object_pk = comment.object_pk publisher_obj = comment.content_type.get_object_for_this_type(pk=object_pk) comment_class = comment.content_type.model_class() subject_desc = _('Comment added:') comment_date = comment.submit_date if not created: subject_desc = _('Comment updated:') comment_date = comment.modified if comment_class == CourseRun: course = publisher_obj.course object_path = reverse('publisher:publisher_course_run_detail', args=[publisher_obj.id]) start_date_temporary = publisher_obj.start_date_temporary # Translators: subject_desc will be choice from ('New comment added', 'Comment updated'), # 'pacing_type' will be choice from ('instructor-paced', 'self-paced'), # 'title' and 'start' will be the value of course title & start date fields. pacing_type = publisher_obj.get_pacing_type_temporary_display() subject = _('{subject_desc} {title} {start} - {pacing_type}').format( subject_desc=subject_desc, title=course.title, pacing_type=pacing_type, start=start_date_temporary.strftime('%B %d, %Y') if start_date_temporary else '' ) course_name = '{title} {start} - {pacing_type}'.format( title=course.title, pacing_type=pacing_type, start=start_date_temporary.strftime('%B %d, %Y') if start_date_temporary else '' ) else: course = publisher_obj object_path = reverse('publisher:publisher_course_detail', args=[publisher_obj.id]) # Translators: 'subject_desc' will be choice from ('New comment added', 'Comment updated') # and 'title' will be the value of course title field. subject = _('{subject_desc} {title}').format( subject_desc=subject_desc, title=course.title ) course_name = course.title to_addresses = course.get_course_users_emails() # remove email of comment owner if exists if comment.user_email in to_addresses: to_addresses.remove(comment.user_email) from_address = settings.PUBLISHER_FROM_EMAIL context = { 'comment_message': comment.comment, 'user_name': comment.user.username, 'course_name': course_name, 'comment_date': comment_date, 'page_url': 'https://{host}{path}'.format(host=comment.site.domain.strip('/'), path=object_path) } txt_template = 'publisher/email/comment.txt' html_template = 'publisher/email/comment.html' template = get_template(txt_template) plain_content = template.render(context) template = get_template(html_template) html_content = template.render(context) email_msg = EmailMultiAlternatives( subject, plain_content, from_address, to_addresses ) email_msg.attach_alternative(html_content, 'text/html') email_msg.send() except Exception: # pylint: disable=broad-except log.exception('Failed to send email notifications for comment %s', comment.id)
def send_mail(recipient_list, template, context=None, from_email=None, send_mail=True, on_commit=False, *args, **kwargs): """ Wrapper around ``django.core.mail.send_mail`` that generates the subject and message body from a template. Usage:: >>> from email_from_template import send_mail >>> send_mail([user.email], 'path/to/my_email.email', { 'a': 1, 'user': user, }) path/to/my_email.email:: {% extends email_from_template %} {% block subject %} Hi {{ user.username }} {% endblock %} {% block body %} Hi {{ user.username }}. Did you know that a = {{ a }} ? {% endblock %} """ # Explicitly check that we have been installed as an app, otherwise we get # a confusing traceback that `template` does not exist, rather than # `email_from_template/component.email`. if 'email_from_template' not in settings.INSTALLED_APPS: raise ImproperlyConfigured( "'email_from_template' missing from INSTALLED_APPS") context = Context(context) for fn in [import_string(x) for x in app_settings.CONTEXT_PROCESSORS]: context.update(fn()) render_fn = import_string(app_settings.RENDER_METHOD) def render(component, fail_silently=False): context.push({ 'email_from_template': 'email_from_template/%s.email' % component, }) txt = render_fn(template, context.flatten()).strip() if not fail_silently: assert txt, "Refusing to send mail with empty %s - did you forget to" \ " add a {%% block %s %%} to %s?" % (component, component, template) context.pop() return txt kwargs.setdefault( 'connection', get_connection( username=kwargs.get('auth_user', None), password=kwargs.get('auth_password', None), fail_silently=kwargs.get('fail_silently', False), )) mail = EmailMultiAlternatives( render('subject').split('\n')[0], render('body'), from_email, recipient_list, *args, **kwargs) html_message = render('html', fail_silently=True) if html_message: mail.attach_alternative(html_message, 'text/html') if not send_mail: return mail if on_commit: transaction.on_commit(mail.send) return None return mail.send()
def send_HTML_email(subject, recipient, html_content, text_content=None, cc=None, email_from=settings.DEFAULT_FROM_EMAIL, file_attachments=None, bcc=None, ga_track=False, ga_tracking_info=None): recipient = list(recipient) if not isinstance(recipient, basestring) else [ recipient ] if not isinstance(html_content, unicode): html_content = html_content.decode('utf-8') if not text_content: text_content = getattr(settings, 'NO_HTML_EMAIL_MESSAGE', NO_HTML_EMAIL_MESSAGE) elif not isinstance(text_content, unicode): text_content = text_content.decode('utf-8') if ga_track and settings.ANALYTICS_IDS.get('GOOGLE_ANALYTICS_API_ID'): ga_data = { 'v': 1, 'tid': settings.ANALYTICS_IDS.get('GOOGLE_ANALYTICS_API_ID'), 'cid': uuid.uuid4().hex, 'dt': subject.encode('utf-8'), 't': 'event', 'ec': 'email' } extra_data = ga_tracking_info if ga_tracking_info else {} ga_data.update(extra_data) post_data = urlencode(ga_data) url = "https://www.google-analytics.com/collect?" + post_data new_content = '<img src="{url}&ea=open"/>\n</body>'.format(url=url) html_content, count = re.subn(r'(.*)</body>', r'\1' + new_content, html_content) assert count != 0, 'Attempted to add tracking to HTML Email with no closing body tag' from_header = {'From': email_from} # From-header connection = get_connection() msg = EmailMultiAlternatives(subject, text_content, email_from, recipient, headers=from_header, connection=connection, cc=cc, bcc=bcc) for file in (file_attachments or []): if file: msg.attach(file["title"], file["file_obj"].getvalue(), file["mimetype"]) msg.attach_alternative(html_content, "text/html") try: msg.send() except SMTPSenderRefused as e: error_subject = _('ERROR: Could not send "%(subject)s"') % { 'subject': subject, } if e.smtp_code == 552: error_text = _('Could not send email: file size is too large.') else: error_text = e.smtp_error error_text = '%s\n\n%s' % ( error_text, _('Please contact %(support_email)s for assistance.') % { 'support_email': settings.SUPPORT_EMAIL, }, ) error_msg = EmailMultiAlternatives( error_subject, error_text, email_from, recipient, headers=from_header, connection=connection, cc=cc, bcc=bcc, ) error_msg.send() if ga_track and settings.ANALYTICS_IDS.get('GOOGLE_ANALYTICS_API_ID'): try: try: requests.get(url + "&ea=send") except SSLError: # if we get an ssl error try without verification requests.get(url + "&ea=send", verify=False) except Exception as e: # never fail hard on analytics logging.exception( u'Unable to send google analytics request for tracked email: {}' .format(e))
def registration_principal_inv(request): if request.method == 'POST': formulario = PrincipalInvestigatorForm(request.POST) userForm = UserForm(request.POST) if userForm.is_valid(): if (formulario.is_valid() and userForm.is_valid()): first_name = userForm.cleaned_data['first_name'] last_name = userForm.cleaned_data['last_name'] username = userForm.cleaned_data['username'] email = userForm.cleaned_data['email'] telephone = formulario.cleaned_data['telephone'] # research_field=formulario.cleaned_data['research_field'] # research_speciality=formulario.cleaned_data['research_speciality'] # h_index=formulario.cleaned_data['h_index'] # country=formulario.cleaned_data['country'] # city=formulario.cleaned_data['city'] # facebook_link=formulario.cleaned_data['facebook_link'] # twitter_link=formulario.cleaned_data['twitter_link'] # linkedIn_link=formulario.cleaned_data['linkedIn_link'] # principal_text=formulario.cleaned_data['principal_text'] # other_text=formulario.cleaned_data['specialty'] # number_of_authorisating=formulario.cleaned_data['number_of_authorisating'] # offers_text=formulario.cleaned_data['offers_text'] # interested_in_premium=formulario.cleaned_data['interested_in_premium'] # autogenerado token= ##Creacion de usuario user1 = User( username=userForm.cleaned_data['username'], first_name=userForm.cleaned_data['first_name'], last_name=userForm.cleaned_data['last_name'], email=userForm.cleaned_data['email'], is_active=0, ) #Le asignamos la clave encriptada user1.set_password(userForm.cleaned_data['password']) user1.save() ##Activation Link activation_key = ''.join( random.choice('123456789abcdefghijklmnopqrstuvwxyz') for _ in range(20)) ctx_dict = { 'activation_key': activation_key, 'first_name': first_name, 'last_name': last_name, 'username': username, 'email': email, 'telephone': telephone, } ##Editor principal = PrincipalInvestigator.objects.create( user=user1, telephone=formulario.cleaned_data['telephone'], research_field=formulario.cleaned_data['research_field'], research_speciality=formulario. cleaned_data['research_speciality'], h_index=formulario.cleaned_data['h_index'], country=formulario.cleaned_data['country'], city=formulario.cleaned_data['city'], facebook_link=formulario.cleaned_data['facebook_link'], twitter_link=formulario.cleaned_data['twitter_link'], linkedIn_link=formulario.cleaned_data['linkedIn_link'], principal_text=formulario.cleaned_data['principal_text'], other_text=formulario.cleaned_data['other_text'], number_of_authorisating=formulario. cleaned_data['number_of_authorisating'], offers_text=formulario.cleaned_data['offers_text'], interested_in_premium=formulario. cleaned_data['interested_in_premium'], token=activation_key, ) ##envio correo al editor mail_text = striptags('') from_email = '*****@*****.**' html_content = render_to_string( 'users/activation_email_for_user.txt', ctx_dict) msg1 = EmailMultiAlternatives( "User registration request for ScienceWeb", mail_text, from_email, [email]) msg1.attach_alternative(html_content, "text/html") msg1.send() return render_to_response('users/registration_complete.html') else: formulario = PrincipalInvestigatorForm() userForm = UserForm() return render_to_response('users/registration_form.html', { 'formulario': formulario, 'userForm': userForm, 'urlRequest': "/users/register_pi" }, context_instance=RequestContext(request))
def send(self, request): sender_email = self.email if self.email else self.user.email sender = "%s <%s>" % (self.channel.name, sender_email) recipient = User.objects.filter( following__curatorChannel=self.channel, following__subscribed=True).values_list('email', flat=True) if self.template: file_path = self.template.file.name else: file_path = FeedEmailTemplate.objects.first().file.name template = loader.get_template(file_path) images = [] for image in self.images.all(): currentImage = {'url': image.image.url, 'type': 'image'} images.append(currentImage) if self.playlist: videoImage = { 'url': self.playlist.link.real_thumbnail, 'type': 'video' } if self.video_position == 0: images.insert(0, videoImage) elif self.video_position == 1: if len(images) == 0: images.append(None) images.insert(1, videoImage) # print images request_context = RequestContext(request, { 'c': self.channel, 'images': images, 'mail': self }) html_message = template.render(request_context) unsubscribe_message = u'<br><p style="color:#888;text-align:center;font-size:12px">' \ u'คุณได้รับจดหมายฉบับนี้เพราะคุณได้ติดตามรับข่าวสารช่อง ' \ u'<a href="%s" style="text-decoration:none">%s</a> ผ่าน ' \ u'<a href="www.pentachennel.com/th/" style="text-decoration:none">PentaChannel</a><br>' \ u'คุณสามารถยกเลิกรับข่าวสารได้โดยคลิกที่นี่ ' \ u'<a href="%s" style="text-decoration:none">ยกเลิกการรับข่าวสาร</a></p>' %\ (request.build_absolute_uri(reverse('feed:feed_channel_view', args=(self.channel.id,))) + u'?utm_source=newsletter&utm_medium=email&utm_content=' + str(self.id) + u'&utm_campaign=email_follow', self.channel.name, request.build_absolute_uri(reverse('feed:feed_channel_view', args=(self.channel.id,)) + u'?unsubscribe=true&utm_source=newsletter&utm_medium=email&' u'utm_content=' + str(self.id) + u'&utm_campaign=email_unsubscribe')) splited = html_message.split('</body>') html_message = ''.join( [splited[0], unsubscribe_message, '</body>', splited[1]]) # print html_message mail_subject = "[%s] %s" % (self.channel.name, self.subject) try: if not recipient: raise ValueError("No recipient") mail = EmailMultiAlternatives(mail_subject, self.message, sender, []) mail.bcc = list(recipient) + [sender] mail.attach_alternative(html_message, "text/html") ret = mail.send() except BadHeaderError as e: raise e if not ret: return False self.sent_at = timezone.now() self.state = self.STATE.sent self.save() return True
def handle(self, *args, **options): tickets = models.TicketbutlerTicket.objects.filter(refunded=False) if not options['reinvite']: tickets = tickets.filter( invited=False ) else: tickets = tickets.filter( Q(invited_when__lte=timezone.now() - timedelta(days=2)) | Q(invited_when=None) ) domain = '127.0.0.1:8000' if settings.DEBUG else 'members.2019.djangocon.eu' invited = 0 for ticket in tickets: if ticket.user.has_usable_password(): self.stdout.write(self.style.SUCCESS("Already active {}".format(ticket.user.email))) continue context = { 'email': ticket.user.email, 'domain': domain, 'site_name': "members.2019.djangocon.eu", 'uid': urlsafe_base64_encode(force_bytes(ticket.user.pk)).decode(), 'user': ticket.user, 'token': PasswordResetView.token_generator.make_token(ticket.user), 'protocol': 'http' if settings.DEBUG else 'https', } if not ticket.invited: body = loader.render_to_string("ticketholders/auth/invite_email.txt", context) subject = "Welcome to DjangoCon Europe Ticket holder's area!" else: body = loader.render_to_string("ticketholders/auth/reinvite_email.txt", context) subject = "Re-invite to DjangoCon Europe Ticket holder's area" subject = ''.join(subject.splitlines()) email_message = EmailMultiAlternatives(subject, body, "*****@*****.**", [ticket.user.email]) if PasswordResetView.html_email_template_name is not None: html_email = loader.render_to_string(PasswordResetView.html_email_template_name, context) email_message.attach_alternative(html_email, 'text/html') email_message.send(fail_silently=False) if not ticket.invited: self.stdout.write(self.style.SUCCESS("Invited {}".format(ticket.user.email))) else: self.stdout.write(self.style.SUCCESS("Re-invited {}".format(ticket.user.email))) ticket.invited = True ticket.invited_when = timezone.now() ticket.save() invited += 1 self.stdout.write(self.style.SUCCESS("Invited {} new users".format(invited)))
def mail_admins(subject, message, fail_silently=False, connection=None, html_message=None): <<<<<<< HEAD """Sends a message to the admins, as defined by the ADMINS setting.""" ======= """Send a message to the admins, as defined by the ADMINS setting.""" >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 if not settings.ADMINS: return mail = EmailMultiAlternatives( '%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject), message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS], connection=connection, ) if html_message: mail.attach_alternative(html_message, 'text/html') mail.send(fail_silently=fail_silently) def mail_managers(subject, message, fail_silently=False, connection=None, html_message=None): <<<<<<< HEAD """Sends a message to the managers, as defined by the MANAGERS setting.""" ======= """Send a message to the managers, as defined by the MANAGERS setting.""" >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 if not settings.MANAGERS: return mail = EmailMultiAlternatives( '%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject), message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS],
def send_email(template_name, subject, to_users, recipient_name, course_run=None, course=None, context=None, project_coordinator=None): """ Send an email template out to the given users with some standard context variables. Arguments: template_name (str): path to template without filename extension subject (str): subject line for the email to_users (list(Object)): a list of User objects to send the email to, if they have notifications enabled recipient_name (str): a string to use to greet the user (use a team name if multiple users) course_run (Object): CourseRun object course (Object): Course object context (dict): additional context for the template project_coordinator (Object): optional optimization if you have the PC User already, to prevent a lookup """ course = course or course_run.course partner = course.partner org = course.authoring_organizations.first() project_coordinator = project_coordinator or get_project_coordinator(org) if not project_coordinator: log_missing_project_coordinator(course_run.course.key, org, template_name) return publisher_url = partner.publisher_url if not publisher_url: logger.info( _('Not sending notification email for template {template} because no publisher URL is defined ' 'for partner {partner}').format(template=template_name, partner=partner.short_code)) return studio_url = partner.studio_url if not studio_url: logger.info( _('Not sending notification email for template {template} because no studio URL is defined ' 'for partner {partner}').format(template=template_name, partner=partner.short_code)) return base_context = {} if course_run: run_studio_url = urljoin(studio_url, 'course/{}'.format(course_run.key)) review_url = urljoin(publisher_url, 'courses/{}'.format(course.uuid)) base_context.update({ 'course_name': course_run.title, 'course_key': course_run.key, 'course_run_number': CourseKey.from_string(course_run.key).run, 'recipient_name': recipient_name, 'platform_name': settings.PLATFORM_NAME, 'org_name': org.name, 'contact_us_email': project_coordinator.email, 'course_page_url': review_url, 'studio_url': run_studio_url, 'preview_url': course_run.marketing_url, }) elif course: base_context.update({ 'course_name': course.title, 'course_key': course.key, 'recipient_name': recipient_name, 'platform_name': settings.PLATFORM_NAME, 'org_name': org.name, 'contact_us_email': project_coordinator.email, }) if context: base_context.update(context) txt_template = template_name + '.txt' html_template = template_name + '.html' template = get_template(txt_template) plain_content = template.render(base_context) template = get_template(html_template) html_content = template.render(base_context) to_addresses = [ u.email for u in to_users if is_email_notification_enabled(u) ] if not to_addresses: return email_msg = EmailMultiAlternatives(subject, plain_content, settings.PUBLISHER_FROM_EMAIL, to_addresses) email_msg.attach_alternative(html_content, 'text/html') try: email_msg.send() except Exception: # pylint: disable=broad-except logger.exception( 'Failed to send email notification for template %s, with subject "%s"', template_name, subject)
def send(self): email = EmailMultiAlternatives(self.subject, striptags(self.content), to=self.to_email) email.attach_alternative(self.content, "text/html") email.send()
from_email = "*****@*****.**" recipient_list = [answerer_user.email] #We also want to inform the caller of the other unresolved calls. resolve_protoype = FixedObject.objects.get( name="TaskPrototype__resolve_phone_call").object number_of_unresolved_calls = resolve_protoype.instances.filter( resolutions__isnull=True).exclude(id=2686).count( ) #TODO: Explain to the people WHY the f**k we are excluding 2686. message = '<a href="http://slashrootcafe.com%s">Resolve This Call</a>\n\n<a href="http://slashrootcafe.com/comm/resolve_calls/">(%s other unresolved calls)</a>' % ( task.get_absolute_url(), number_of_unresolved_calls) msg = EmailMultiAlternatives(subject, message, from_email, recipient_list) msg.attach_alternative(message, "text/html") msg.send() return r.render() @csrf_exempt def handle_hangup(request, conference_id, number_id): r = get_provider_and_response_for_request(request)[1] phone_call_object = PhoneCall.objects.get(call_id=conference_id) number_object = PhoneNumber.objects.get(id=number_id) #If the number object has an owner, their participation needs to be ended. if number_object.owner: participation = CommunicationInvolvement.objects.filter( communication__phonecall__call_id=conference_id,
def create_text_and_html_mail(self, html_message, text_message): msg = EmailMultiAlternatives(self.subject, text_message, self.from_email, self.recipient_list) msg.attach_alternative(html_message, 'text/html') return msg
def frontpage(request): # pricings = Pricing_Fiat.objects.filter(only_available_using_key=False) pricings_credit_card = Pricing_Fiat.objects.filter( show_on_page=True, only_available_using_key=False) pricings_crypto = [] for price in pricings_credit_card: cost_eth = price.get_crypto_value(currency='ETH') cost_btc = price.get_crypto_value(currency='BTC') new_dict = { 'cost': round(price.cost_cent * Decimal(10**-2)), 'cost_ethereum': cost_eth if cost_eth else '', 'cost_bitcoin': cost_btc if cost_btc else '', 'subscription_time_in_days': price.subscription_time_in_days, 'show_name': price.show_name, 'id': price.id, 'savings': price.saving, } pricings_crypto.append(new_dict) pricings_crypto = sorted(pricings_crypto, key=lambda k: k['subscription_time_in_days']) if request.method == 'POST': UCform = CustomUserCreationForm(request.POST) if 'UCform_Button' in request.POST: if UCform.is_valid(): user = UCform.save(commit=False) user.is_active = False TokenObject = None if user.signup_token is not None and user.signup_token is not '': from referral.models import Referral, SignedUpUserReferral try: TokenObject = Referral.objects.get( Token=user.signup_token) TokenObject.AmountSignups += 1 TokenObject.save() except Exception: messages.error( request, 'Error with the entered referral token!') return redirect(frontpage) user.save() if TokenObject is not None: try: ref_user_wrapper_object = SignedUpUserReferral( RefToken=TokenObject, User=user) ref_user_wrapper_object.save() UserMethods.extendUserTrialByUserObject( user, timedelta(days=14)) except Exception: messages.error( request, 'Error with the entered referral token!') return redirect(frontpage) from django.contrib.sites.shortcuts import get_current_site current_site = get_current_site(request) mail_subject = 'Activate your Provisn.com account.' from django.utils.encoding import force_bytes from django.template.loader import render_to_string from django.utils.http import urlsafe_base64_encode from userdashboard.tokens import account_activation_token message = render_to_string( 'registration/acc_active_email.html', { 'user': user, 'domain': current_site.domain, 'uid': urlsafe_base64_encode(force_bytes(user.pk)), 'token': account_activation_token.make_token(user), }) text_content = strip_tags(message) to_email = UCform.cleaned_data.get('email') email = EmailMultiAlternatives(mail_subject, text_content, to=[to_email]) email.attach_alternative(message, 'text/html') from smtplib import SMTPAuthenticationError try: email.send() except SMTPAuthenticationError: messages.error( 'An error occured when sending the confirmation mail! Please write a Support Ticker, thanks.' ) messages.success( request, "Successfully signed up! Please confirm your e-mail address to complete the registration!" ) MTAform = SupportTicketForm() return render( request, 'frontpage/main.html', { 'MTAform': MTAform, 'UCform': UCform, 'pricings': pricings_crypto, 'SIGNUP_ENABLED': SIGNUP_ENABLED }) else: for error in UCform.errors.items(): messages.error(request, error[1]) else: if 'reftoken' in request.GET: UCform = CustomUserCreationForm( initial={'signup_token': request.GET['reftoken']}) else: UCform = CustomUserCreationForm() if request.method == 'POST' and 'MTAform_Button' in request.POST: MTAform = SupportTicketForm(request.POST) if UCform.is_valid(): UCform.clean() if MTAform.is_valid(): MTAform.save() messages.success( request, "The form has been sent successfully! We'll contact you as soon as possible." ) return render( request, 'frontpage/main.html', { 'MTAform': MTAform, 'UCform': UCform, 'pricings': pricings_crypto, 'SIGNUP_ENABLED': SIGNUP_ENABLED }) else: MTAform = SupportTicketForm() if 'reftoken' in request.GET: UCform = CustomUserCreationForm( initial={'signup_token': request.GET['reftoken']}) else: UCform = CustomUserCreationForm() return render( request, 'frontpage/main.html', { 'MTAform': MTAform, 'UCform': UCform, 'pricings': pricings_crypto, 'SIGNUP_ENABLED': SIGNUP_ENABLED })
def send_HTML_email(subject, recipient, html_content, text_content=None, cc=None, email_from=settings.DEFAULT_FROM_EMAIL, file_attachments=None, bcc=None, smtp_exception_skip_list=None, messaging_event_id=None): recipients = list(recipient) if not isinstance(recipient, str) else [ recipient ] filtered_recipients = get_valid_recipients(recipients) bounced_addresses = list(set(recipients) - set(filtered_recipients)) if bounced_addresses and messaging_event_id: mark_subevent_bounced(bounced_addresses, messaging_event_id) if not filtered_recipients: # todo address root issues by throwing a real error to catch upstream # fail silently for now to fix time-sensitive SES issue return if not isinstance(html_content, str): html_content = html_content.decode('utf-8') if not text_content: text_content = getattr(settings, 'NO_HTML_EMAIL_MESSAGE', NO_HTML_EMAIL_MESSAGE) elif not isinstance(text_content, str): text_content = text_content.decode('utf-8') headers = {'From': email_from} # From-header if settings.RETURN_PATH_EMAIL: headers['Return-Path'] = settings.RETURN_PATH_EMAIL if messaging_event_id is not None: headers[COMMCARE_MESSAGE_ID_HEADER] = messaging_event_id if settings.SES_CONFIGURATION_SET is not None: headers[SES_CONFIGURATION_SET_HEADER] = settings.SES_CONFIGURATION_SET connection = get_connection() msg = EmailMultiAlternatives(subject, text_content, email_from, filtered_recipients, headers=headers, connection=connection, cc=cc, bcc=bcc) for file in (file_attachments or []): if file: msg.attach(file["title"], file["file_obj"].getvalue(), file["mimetype"]) msg.attach_alternative(html_content, "text/html") try: msg.send() except SMTPDataError as e: # If the SES configuration has not been properly set up, resend the message if ("Configuration Set does not exist" in e.smtp_error and SES_CONFIGURATION_SET_HEADER in msg.extra_headers): del msg.extra_headers[SES_CONFIGURATION_SET_HEADER] msg.send() notify_exception(None, message="SES Configuration Set missing", details={'error': e}) else: raise except SMTPSenderRefused as e: if smtp_exception_skip_list and e.smtp_code in smtp_exception_skip_list: raise e else: error_subject = _('ERROR: Could not send "%(subject)s"') % { 'subject': subject, } if e.smtp_code in LARGE_FILE_SIZE_ERROR_CODES: error_text = _('Could not send email: file size is too large.') else: error_text = e.smtp_error error_text = '%s\n\n%s' % ( error_text, _('Please contact %(support_email)s for assistance.') % { 'support_email': settings.SUPPORT_EMAIL, }, ) error_msg = EmailMultiAlternatives( error_subject, error_text, email_from, filtered_recipients, headers=headers, connection=connection, cc=cc, bcc=bcc, ) error_msg.send()
def send_email_for_studio_instance_created(course_run, updated_text=_('created')): """ Send an email to course team on studio instance creation. Arguments: course_run (CourseRun): CourseRun object updated_text (String): String object """ try: object_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id}) subject = _('Studio instance {updated_text}').format( updated_text=updated_text) # pylint: disable=no-member to_addresses = course_run.course.get_course_users_emails() from_address = settings.PUBLISHER_FROM_EMAIL course_user_roles = course_run.course.course_user_roles.all() course_team = course_user_roles.filter( role=PublisherUserRole.CourseTeam).first() project_coordinator = course_user_roles.filter( role=PublisherUserRole.ProjectCoordinator).first() context = { 'updated_text': updated_text, 'course_run': course_run, 'course_run_page_url': 'https://{host}{path}'.format( host=Site.objects.get_current().domain.strip('/'), path=object_path), 'course_name': course_run.course.title, 'from_address': from_address, 'course_team_name': course_team.user.full_name if course_team else '', 'project_coordinator_name': project_coordinator.user.full_name if project_coordinator else '', 'contact_us_email': project_coordinator.user.email if project_coordinator else '' } txt_template_path = 'publisher/email/studio_instance_created.txt' html_template_path = 'publisher/email/studio_instance_created.html' txt_template = get_template(txt_template_path) plain_content = txt_template.render(context) html_template = get_template(html_template_path) html_content = html_template.render(context) email_msg = EmailMultiAlternatives(subject, plain_content, from_address, to=[settings.PUBLISHER_FROM_EMAIL], bcc=to_addresses) email_msg.attach_alternative(html_content, 'text/html') email_msg.send() except Exception: # pylint: disable=broad-except logger.exception( 'Failed to send email notifications for course_run [%s]', course_run.id)