def render(profile, clear=True):
    """
    Render notification email for given profile; return (subject, text, html).

    If ``clear`` is set to ``False``, will not clear rendered notifications.

    Raise ``NothingToDo`` if there are no notifications to render.

    """
    collection = collect.NotificationCollection(profile, clear=clear)

    # bail out if there's nothing to do
    if not collection:
        raise NothingToDo()

    context = collection.context
    context['BASE_URL'] = settings.PORTFOLIYO_BASE_URL

    subject = render_to_string(collection.get_subject_template(), context)

    text = consecutive_newlines.sub('\n\n',
                                    render_to_string(TEXT_TEMPLATE, context))
    html = premailer.Premailer(
        render_to_string(HTML_TEMPLATE, context),
        base_url=settings.PORTFOLIYO_BASE_URL,
        output_xhtml=True,
    ).transform()

    return subject, text, html
Exemple #2
0
 def render_to_response(self, context, **response_kwargs):
     from django.contrib.staticfiles.storage import staticfiles_storage
     css = staticfiles_storage.path('css/email.css')
     response = super(EventAuthoriseRequestEmailPreview,
                      self).render_to_response(context, **response_kwargs)
     assert isinstance(response, HttpResponse)
     response.content = premailer.Premailer(
         response.rendered_content, external_styles=css).transform()
     return response
Exemple #3
0
 def to_email(self, *args, **kwargs):
     """Export a bulletin as an HTML file for emailing."""
     request = kwargs.get('request', None)
     template_string = render_to_string(
         "bulletins/bulletin_html_email.html", self.get_context(request))
     prepared_resp = premailer.Premailer(
         template_string,
         base_url=settings.BASE_URL,
         remove_classes=True,
         strip_important=True,
         cssutils_logging_level=logging.CRITICAL).transform()
     return prepared_resp
 def apply_css(self, text):
     """Bake CSS rules into text"""
     p = premailer.Premailer(html=text,
                             css_text=self.css,
                             remove_classes=True,
                             remove_unset_properties=True,
                             disable_leftover_css=True)
     out = p.transform()
     for tag in ['html', 'head', 'body']:
         out = out.replace('<%s>' % tag, '')
         out = out.replace('</%s>' % tag, '')
     return out
Exemple #5
0
    def markdown2html(self, markdown_str):
        if not isinstance(markdown_str, unicode):
            log.error('String is not unicode in markdown2html')
            return ''

        html = u'<style>' + self.css_str
        html += '.markdown-body {box-sizing: border-box;min-width: ' \
                '200px;max-width: 980px;margin: 0 auto;padding: 45px;}'
        html += '</style>'
        html += '<article class="markdown-body">'
        md_html = markdown2.markdown(
            markdown_str,
            extras=["tables", "fenced-code-blocks", "cuddled-lists"])
        html += md_html
        html += '</article>'

        if log.isEnabledFor(logging.DEBUG):
            pre_html_file_path = os.path.join(
                self.html_log_path,
                str(time.time()).replace('.', '') + '-pre_inline.html')
            with open(pre_html_file_path, 'w') as f:
                f.write(html.encode('utf-8-sig'))
                log.debug('Dump html file ' + pre_html_file_path)

        prem = premailer.Premailer(html,
                                   preserve_inline_attachments=False,
                                   base_path='article')
        html = prem.transform(pretty_print=True)

        if log.isEnabledFor(logging.DEBUG):
            html_file_path = os.path.join(
                self.html_log_path,
                str(time.time()).replace('.', '') + '-inline.html')
            with open(html_file_path, 'w') as f:
                f.write(html.encode('utf-8-sig'))
                log.debug('Dump inlined html file ' + html_file_path)

        html = html[html.find('<article'):]
        html = html[html.find('>') + 1:]
        html = html[:html.find('</article>')]

        if log.isEnabledFor(logging.DEBUG):
            cut_html_file_path = os.path.join(
                self.html_log_path,
                str(time.time()).replace('.', '') + '-cut_inline.html')
            with open(cut_html_file_path, 'w') as f:
                f.write(html.encode('utf-8-sig'))
                log.debug('Dump cutted inlined html file ' +
                          cut_html_file_path)

        log.debug("inline css over")
        return html
Exemple #6
0
    def transform_html(self, html):
        kwargs = {
            "html": html,
            "base_url": "https://glowstone.net"
        }

        p = premailer.Premailer(
            **kwargs
        )

        transformed = p.transform(pretty_print=False)
        transformed = transformed.replace("%24%7B", "${")
        return transformed.replace("%7D", "}")
Exemple #7
0
def parse(html):
    soup = BeautifulSoup(html, 'html.parser')
    head = soup.find('head')
    table = soup.find('div', {"class": "Search-list"})

 
    result_html = premailer.Premailer('<html>' + str(head) + '<body>' + str(table) + '</body></html>',
                                      cssutils_logging_level=logging.CRITICAL, base_url='https://www.fabrikant.ru/').transform()
    with open('result.html', 'w') as f_obj_out:
        f_obj_out.write(result_html)

    #print(table)
 
    send_mail()
Exemple #8
0
    def from_template(cls, email_name, context, *, request):
        subject = render(f"email/{email_name}/subject.txt", context, request=request)
        body_text = render(f"email/{email_name}/body.txt", context, request=request)

        try:
            body_html = render(
                f"email/{email_name}/body.html", context, request=request
            )
            body_html = premailer.Premailer(body_html, remove_classes=True).transform()
        # Catching TemplateNotFound here is a bit of a leaky abstraction, but there's
        # not much we can do about it.
        except TemplateNotFound:
            body_html = None

        return cls(subject=subject, body_text=body_text, body_html=body_html)
    def render(self):
        tpl = loader.get_template(self.template)

        context = self._default_context
        if getattr(settings, "TEMPLATE_EMAIL_USE_CONTEXT_PROCESSORS", False):
            if Engine:
                standard_processors = Engine.get_default().template_context_processors
            else:
                standard_processors = get_standard_processors()

            for processor in standard_processors:
                try:
                    context.update(processor(None))
                except:
                    pass

        context.update(self.context)
        context.update(self._override_context)

        context_subject = dict(context, _subject=True)
        context_body = dict(context, _body=True)
        context_html = dict(context, _bodyhtml=True)

        subject = tpl.render(Context(context_subject)).strip()
        body = tpl.render(Context(context_body)).strip()
        html = tpl.render(Context(context_html)).strip()

        if subject != '':
            self.subject = subject
        if body != '':
            self.body = body
        if html != '':
            html_doc = None
            base_url = getattr(settings, "TEMPLATE_EMAIL_BASE_URL", None)
            if base_url:
                html_doc = html_doc or lxml.html.fromstring(html)
                html_doc.make_links_absolute(base_url)
            if getattr(settings, "TEMPLATE_EMAIL_INLINE_CSS", False):
                html_doc = html_doc or lxml.html.fromstring(html)
                opts = getattr(
                    settings, "TEMPLATE_EMAIL_INLINE_CSS_OPTIONS", {})
                html_doc = premailer.Premailer(html_doc, **opts).transform()
            if html_doc:
                html = lxml.html.tostring(
                    html_doc, include_meta_content_type=True).decode('utf-8')
            self.html = html

        self._rendered = True
def prepare_email_body(context, css, template, title):

    #:  Before template is rendered, we verify that its content is secure
    env = SandboxedEnvironment()
    body = env.from_string(template).render(context)

    mylog = StringIO()
    myhandler = logging.StreamHandler(mylog)
    html_message = EMAIL_HTML_SQUELETON.format(title=title, css=css, body=body)

    p = premailer.Premailer(
        html=html_message,
        cssutils_logging_handler=myhandler,
        cssutils_logging_level=logging.INFO,
    )

    return p.transform()
Exemple #11
0
def report_to_html(report):
    template = report.get_template()
    report_env = report.environment()
    report_env[
        'EML_RENDER'] = True  # for exclude scripts and css-styles from message body
    html_text = template.render(**report_env)

    premailer_log = StringIO()
    premailer_log_handler = logging.StreamHandler(premailer_log)

    return premailer.Premailer(
        cssutils_logging_handler=premailer_log_handler,
        cssutils_logging_level=logging.CRITICAL,
        remove_classes=True,
        base_url=KeyChain.WEB_PATH,
        base_path=WEB_STATIC_PATH,
        external_styles=f'css/bootstrap.css',
    ).transform(html_text)
Exemple #12
0
def send_email(title, html_text, body_text, recipients):
    # Prepare email
    css = sass.compile(string=flask.render_template('email/base.scss'))
    html = flask.render_template('email/base.html',
                                 title=title,
                                 css=css,
                                 text=html_text)
    html = premailer.Premailer(html, strip_important=False).transform()

    body = flask.render_template('email/base.txt', title=title, text=body_text)

    # Send email
    mail = flask_mail.Mail(flask.current_app)
    msg = flask_mail.Message(title,
                             recipients=recipients,
                             body=body,
                             html=html)
    mail.send(msg)
Exemple #13
0
    def form_valid(self, form):
        email = form.cleaned_data['email']
        event = self.object
        event.auth_request_by = self.request.user
        event.auth_request_at = datetime.datetime.now()
        event.auth_request_to = email
        event.save()

        context = {
            'object':
            self.object,
            'request':
            self.request,
            'hmac':
            signing.dumps({
                'pk': self.object.pk,
                'email': email,
                'sent_by': self.request.user.pk,
            }),
        }
        if event.person is not None and email == event.person.email:
            context['to_name'] = event.person.name
        elif event.organisation is not None and email == event.organisation.email:
            context['to_name'] = event.organisation.name

        msg = EmailMultiAlternatives(
            "N%05d | %s - Event Authorisation Request" %
            (self.object.pk, self.object.name),
            get_template("RIGS/eventauthorisation_client_request.txt").render(
                context),
            to=[email],
            reply_to=[self.request.user.email],
        )
        css = staticfiles_storage.path('css/email.css')
        html = premailer.Premailer(get_template(
            "RIGS/eventauthorisation_client_request.html").render(context),
                                   external_styles=css).transform()
        msg.attach_alternative(html, 'text/html')

        msg.send()

        return super(EventAuthorisationRequest, self).form_valid(form)
Exemple #14
0
def premailer_transform(html):
    p = premailer.Premailer(html, base_url='https://downtownstimulus.com/')
    return p.transform()
Exemple #15
0
#!/bin/python3

import premailer, json, os, pathlib

REPO_PATH = pathlib.Path(os.environ['GITHUB_WORKSPACE'])
FILES_LIST = json.loads(os.environ['INPUT_FILES'])

pm = premailer.Premailer()

for file_path_str in FILES_LIST:
    file_path_list = REPO_PATH.glob(file_path_str)
    for file_path in file_path_list:
        with open(file_path, 'r') as file:
            html = pm.transform(file.read())
        with open(file_path, 'w') as file:
            file.write(html)
Exemple #16
0
def send_email_back(recipient, subject, attachments, text_content=None, html_content=None):
    from sendgrid.helpers import mail
    from sendgrid.helpers.mail import Attachment
    import premailer

    logging.info("sending mail to %s (%s/%s)", recipient, SENDGRID_API_KEY, SENDGRID_SENDER)

    to_email = mail.Email(recipient)
    from_email = mail.Email(SENDGRID_SENDER)

    message = mail.Mail()

    message.set_from(from_email)
    message.set_subject(subject)

    personalization = mail.Personalization()
    personalization.add_to(to_email)
    message.add_personalization(personalization)

    if not text_content and not html_content:
        message.add_content(mail.Content("text/plain", global_body))

    if text_content:
        message.add_content(mail.Content("text/plain", text_content))

    if html_content:
        message.add_content(mail.Content("text/html", html_content))

    for att in attachments:
        data = att["data"]
        file_name = att["name"]

        if file_name.endswith(".htm") or file_name.endswith(".html"):
            stub_css = "https://%s.appspot.com/css/stub.css" % app_identity.get_application_id()
            data = re.sub(
                r'\"D:\\ssis\\SecureMail\\SecureMailTest\\MailItemImages\\BankB1\.gifstyle\.css&#xA;.*\"',
                '"%s"' % stub_css,
                data)

            logging.info("before transform(%s) %s", type(data), data)

            logging.info("using premailer for %s", file_name)

            data = data.decode("utf8")

            p = premailer.Premailer(data)
            data = p.transform().encode("utf8")

            logging.info("after transform(%s) %s", type(data), data)

        attachment = Attachment()
        attachment.set_content(base64.b64encode(data))
        attachment.set_type(att["type"])
        attachment.set_filename(att["name"])
        attachment.set_disposition("attachment")
        attachment.set_content_id(att["name"])
        message.add_attachment(attachment)

    data = json.dumps(message.get())

    logging.debug("sending %s", data)

    headers = {
        "Authorization": 'Bearer {0}'.format(SENDGRID_API_KEY),
        "Content-Type": "application/json",
        "Accept": 'application/json'
    }

    response = urlfetch.fetch(
        url="https://api.sendgrid.com/v3/mail/send",
        payload=data,
        method=urlfetch.POST,
        headers=headers)

    if response.status_code > 299:
        logging.error("response %s(%s)", response.content, response.status_code)
    else:
        logging.info("response %s(%s)", response.content, response.status_code)

    if response.status_code > 299:
        raise Exception("Failed to call sendgrid API")
Exemple #17
0
def do_premailer(value, **kwargs):
    p = premailer.Premailer(value,
                            keep_style_tags=kwargs.get('keep_style_tags',
                                                       True),
                            remove_classes=kwargs.get('remove_classes', True))
    return p.transform()
Exemple #18
0
def premailer_transform(html):
    p = premailer.Premailer(html,
                            base_url=os.environ.get('FRONTEND_URL',
                                                    'NO ENV FOUND'))
    return p.transform()
Exemple #19
0
def prepare_html(html, inline_css=True):
    if inline_css:
        html = premailer.Premailer(html).transform()
    return html
Exemple #20
0
def transformExternalCssToInline(code):
  import premailer
  p = premailer.Premailer(code, strip_important=False, keep_style_tags=True,
    remove_classes=False)
  return p.transform()     
Exemple #21
0
import logging
import premailer
from io import StringIO
mylog = StringIO()
myhandler = logging.StreamHandler(mylog)
p = premailer.Premailer("""
    <html>
    <style type="text/css">
    @keyframes foo { from { opacity: 0; } to { opacity: 1; } }
    </style>
    <p>Hej</p>
    </html>""",
                        cssutils_logging_handler=myhandler,
                        cssutils_logging_level=logging.INFO)
result = p.transform()
mylog.getvalue()
Exemple #22
0
# FILENAME: css_inliner_tool.py
# DESCRIPTION: Retrieves an HTML file from a URL and outputs a new
#              HTML file that inlines all of its CSS.
#
#
# $Id$
####################################################################
# (C)2017 DigiTar, All Rights Reserved
####################################################################

import premailer, requests
from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("--page_url", dest="page_url", required=True)

if __name__ == "__main__":
    args = parser.parse_args()

    # Retrieve Main Page
    html_text = requests.get(args.page_url).text

    # Transform HTML
    html_inliner = premailer.Premailer(html_text,
                                       strip_important=False,
                                       remove_classes=True,
                                       remove_unset_properties=True)
    inlined_html = html_inliner.transform()

    print inlined_html.encode("utf-8")
Exemple #23
0
def generate(trello_list):
    articles = []

    pool = multiprocessing.Pool(processes=10)
    articles = pool.map(get_artice, trello_list)

    # Print status
    for number, (trello_card, article) in enumerate(zip(trello_list, articles),
                                                    start=1):
        print("\n" + str(number) + ".", trello_card["name"] + ":")

        if article is None:
            print(" - Status:", colorama.Fore.RED + "Warning (no content)",
                  colorama.Fore.RESET)
            continue

        images_str = ", ".join(map(lambda x: x["name"], article["images"]))
        print(" - Images:", colorama.Fore.CYAN + images_str,
              colorama.Fore.RESET)
        labels_str = ", ".join(article["labels"])
        print(" - Labels:", colorama.Fore.MAGENTA + labels_str,
              colorama.Fore.RESET)
        print(" - Status:", colorama.Fore.GREEN + "Ok", colorama.Fore.RESET)

    # Remove empty articles
    articles = list(filter(None, articles))

    # Create output folder
    if not os.path.exists(settings.get("folder")):
        os.makedirs(settings.get("folder"))

    # Generate html from articles
    html_section_template = Template(
        open(settings.get("template-section")).read())
    markdown_instance = markdown.Markdown(
        extensions=list(settings.get("extensions")),
        extension_configs=settings.get("extensions"),
        output_format="html5")
    html = ""
    for index, article in enumerate(articles):
        labels = ""
        if settings.get("features")["labels"]:
            labels = " ".join(article["labels"])

        open(
            os.path.join(settings.get("folder"),
                         ".t2w-temp-" + str(index) + ".md"),
            "w").write(article["content"])
        article_html = markdown_instance.reset().convert(article["content"])
        html += html_section_template.substitute(content=article_html,
                                                 labels=labels)

        if settings.get("features")["lines"] and "noline" not in article[
                "labels"] and index != len(articles) - 1:
            line_html = markdown_instance.reset().convert("\n\n---\n\n")
            html += html_section_template.substitute(content=line_html,
                                                     labels="")

    # Save images
    for article in articles:
        for image in article["images"]:
            image_filename = os.path.join(settings.get("folder"),
                                          image["name"])
            open(image_filename, "wb").write(image["content"])
            utilities.fix_image(image_filename,
                                settings.get("features")["width"])

    # Generate CSS
    css_generated = ""
    for css_file in settings.get("css"):
        css_generated += open(css_file).read() + "\n\n"

    # Add generated Markdown to HTML template
    html_template = Template(open(settings.get("template")).read())
    html_generated = html_template.safe_substitute(title=settings.get("title"),
                                                   content=html,
                                                   css=css_generated)

    result_template = Template(html_generated)
    extra_args = {}
    if "markdown_smarttoc" in settings.get("extensions"):
        extra_args["toc"] = markdown_instance.toc
    result_generated = result_template.safe_substitute(
        title=settings.get("title"),
        width=settings.get("features")["width"],
        **extra_args)

    # Run premailer
    if settings.get("features")["premailer"]:
        open(
            os.path.join(
                settings.get("folder"),
                ".t2w-temp-" + settings.get("basename") + "-orignal.html"),
            "w").write(result_generated)
        premail_instance = premailer.Premailer(result_generated,
                                               keep_style_tags=True)
        result_generated = premail_instance.transform()

    open(
        os.path.join(settings.get("folder"),
                     settings.get("basename") + ".html"),
        "w").write(result_generated)

    print("\nPreview: file://" + urllib.request.pathname2url(
        os.path.abspath(
            os.path.join(settings.get("folder"),
                         settings.get("basename") + ".html"))))
Exemple #24
0
def premailer_transform(html):
    cssutils.log.setLevel(logging.CRITICAL)
    p = premailer.Premailer(html, base_url=settings.BASE_URL)
    return p.transform()
Exemple #25
0
    def on_post(self, req, resp):
        # req.stream corresponds to the WSGI wsgi.input environ variable,
        # and allows you to read bytes from the request body.
        #
        # See also: PEP 3333
        if req.content_length in (None, 0):
            # Nothing to do
            return

        body = req.stream.read()
        if not body:
            raise falcon.HTTPBadRequest('Empty request body',
                                        'A valid JSON document is required.')
        body = json.loads(body.decode('utf-8'))

        url = None
        if body.get('url'):
            url = body.pop('url')
            html = self._download_url(url)
            if 'html' in body:
                body.pop('html')

        else:
            html = body.pop('html')
            if 'url' in body:
                body.pop('url')
        options = body

        row = insert_post(html, options, url=url, user_agent=req.user_agent)
        pretty_print = options.pop('pretty_print', True)

        mylog = StringIO()
        logging_handler = logging.StreamHandler(mylog)
        logging_handler.setFormatter(
            logging.Formatter('%(levelname)s %(message)s'))
        options['cssutils_logging_handler'] = logging_handler
        options['cssutils_logging_level'] = logging.WARNING

        try:
            p = premailer.Premailer(html, **options)
        except TypeError as exp:
            raise falcon.HTTPBadRequest('Invalid options to premailer',
                                        str(exp))
        error = None
        warnings = None
        t0 = time.time()
        try:
            result = p.transform(pretty_print=pretty_print)
        except Exception:
            exc_type, exc_value, __ = sys.exc_info()
            error = '{} ({})'.format(exc_type.__name__, exc_value)

        warnings = mylog.getvalue()
        t1 = time.time()

        if error is None:
            update_post(row, t1 - t0, result=result)
        else:
            update_post(row, t1 - t0, error=error)

        resp.status = falcon.HTTP_200
        resp.set_header('Access-Control-Allow-Origin', CORS_ORIGIN)
        resp.set_header('Content-Type', 'application/json')
        took = (t1 - t0) * 1000
        if error:
            resp.body = json.dumps({
                'errors': [error],
                'took': took,
            },
                                   indent=2)
        else:
            resp.body = json.dumps(
                {
                    'html': result,
                    'took': took,
                    'warnings': warnings,
                },
                indent=2)

        # cleaning up
        del p