from django.views.generic.base import ContextMixin from django.template.loader import render_to_string from django.template.exceptions import TemplateDoesNotExist from django.core.mail import EmailMultiAlternatives from django.conf import settings from html.parser import HTMLParser from bs4 import BeautifulSoup class MailView(ContextMixin): template_name = None @property def html_template_name(self): if self.template_name: if self.template_name.split("/")[-1].split(".")[-1] in ("html", "txt"): basename = template_name.rsplit(".", 1)[0] else: basename = template_name try: path = f"{basename}.html" render_to_string(path) return path except TemplateDoesNotExist: pass return False @property def text_template_name(self): if self.template_name: if self.template_name.split("/")[-1].split(".")[-1] in ("html", "txt"): basename = template_name.rsplit(".", 1)[0] else: basename = template_name try: path = f"{basename}.txt" render_to_string(path) return path except TemplateDoesNotExist: pass return False def render_to_html(self, **kwargs): if self.html_template_name: context = self.get_context_data(**kwargs) return render_to_string(self.html_template_name, context) else: return None def render_to_text(self, from_html=False, **kwargs): if self.text_template_name: context = self.get_context_data(**kwargs) return render_to_string(self.text_template_name, context) else: if from_html and (html := self.render_to_html(**kwargs)): return BeautifulSoup(html).get_text() return None def send(self, subject, recipient, context={}, attachments=[], sender=None, cc=[], bcc=[], text_from_html=False): text = self.render_to_text(text_from_html, **context) email = EmailMultiAlternatives(subject, text, sender, [recipient], cc=cc, bcc=bcc + DEFAULT_BCC_EMAILS, attachments=attachments) if html := self.render_to_html(**context): email.attach_alternative(html, "text/html") email.send()