Lazy import html2text and weasyprint
This commit is contained in:
@@ -11,12 +11,6 @@ from urllib.parse import (
|
||||
parse_qsl, quote, urlencode, urljoin, urlsplit, urlunsplit)
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
try:
|
||||
import html2text
|
||||
except ImportError:
|
||||
html2text = None
|
||||
|
||||
from genshi.core import END, START, Attrs, QName
|
||||
from genshi.template import MarkupTemplate
|
||||
from genshi.template import TemplateError as GenshiTemplateError
|
||||
@@ -31,7 +25,7 @@ from trytond.model import (
|
||||
fields)
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Eval, If, PYSONDecoder, TimeDelta
|
||||
from trytond.report import Report
|
||||
from trytond.report import Report, html_to_text
|
||||
from trytond.sendmail import SMTPDataManager, send_message_transactional
|
||||
from trytond.tools import grouped_slice, pairwise_longest, reduce_ids
|
||||
from trytond.tools.chart import sparkline
|
||||
@@ -750,9 +744,7 @@ class Activity(
|
||||
set_from_header(msg, from_, sender or from_)
|
||||
msg['To'] = to
|
||||
msg['Subject'] = subject
|
||||
if html2text:
|
||||
converter = html2text.HTML2Text()
|
||||
content_text = converter.handle(content)
|
||||
if content_text := html_to_text(content):
|
||||
msg.add_alternative(content_text, subtype='plain')
|
||||
if msg.is_multipart():
|
||||
msg.add_alternative(content, subtype='html')
|
||||
|
||||
@@ -14,11 +14,6 @@ from genshi.template import TemplateError as GenshiTemplateError
|
||||
from sql import Literal
|
||||
from sql.aggregate import Count
|
||||
|
||||
try:
|
||||
import html2text
|
||||
except ImportError:
|
||||
html2text = None
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.ir.session import token_hex
|
||||
@@ -26,7 +21,7 @@ from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, Unique, Workflow, fields)
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Eval
|
||||
from trytond.report import Report, get_email
|
||||
from trytond.report import Report, get_email, html_to_text
|
||||
from trytond.sendmail import SMTPDataManager, send_message_transactional
|
||||
from trytond.tools import grouped_slice, reduce_ids
|
||||
from trytond.tools.email_ import (
|
||||
@@ -506,9 +501,7 @@ class Message(Workflow, ModelSQL, ModelView):
|
||||
msg['List-Unsubscribe'] = (
|
||||
f'<{email.get_email_unsubscribe_url()}>')
|
||||
msg['List-Unsubscribe-Post'] = 'List-Unsubscribe=One-Click'
|
||||
if html2text:
|
||||
converter = html2text.HTML2Text()
|
||||
content_text = converter.handle(content)
|
||||
if content_text := html_to_text(content):
|
||||
msg.add_alternative(content_text, subtype='plain')
|
||||
if msg.is_multipart():
|
||||
msg.add_alternative(content, subtype='html')
|
||||
|
||||
@@ -147,3 +147,10 @@ Email reports must have ``HTML`` as output format.
|
||||
|
||||
.. warning::
|
||||
It may return the content unconverted if some dependencies are missing.
|
||||
|
||||
.. function:: html_to_text(content):
|
||||
|
||||
Converts ``HTML`` content to plain text.
|
||||
|
||||
.. warning::
|
||||
It may return ``None`` if some dependencies are missing.
|
||||
|
||||
@@ -6,10 +6,6 @@ import re
|
||||
from email.message import EmailMessage
|
||||
from email.utils import getaddresses
|
||||
|
||||
try:
|
||||
import html2text
|
||||
except ImportError:
|
||||
html2text = None
|
||||
from genshi.template import TextTemplate
|
||||
|
||||
import trytond.config as config
|
||||
@@ -18,7 +14,7 @@ from trytond.model import EvalEnvironment, ModelSQL, ModelView, fields
|
||||
from trytond.model.exceptions import AccessError, ValidationError
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Bool, Eval, PYSONDecoder
|
||||
from trytond.report import Report
|
||||
from trytond.report import Report, html_to_text
|
||||
from trytond.rpc import RPC
|
||||
from trytond.sendmail import send_message_transactional
|
||||
from trytond.tools import escape_wildcard, slugify
|
||||
@@ -107,16 +103,14 @@ class Email(ResourceAccessMixin, ModelSQL, ModelView):
|
||||
'body': body,
|
||||
'signature': user.signature or '',
|
||||
}
|
||||
if html2text:
|
||||
body_text = HTML_EMAIL % {
|
||||
'subject': subject,
|
||||
'body': body,
|
||||
'signature': '',
|
||||
}
|
||||
converter = html2text.HTML2Text()
|
||||
body_text = converter.handle(body_text)
|
||||
body_text = HTML_EMAIL % {
|
||||
'subject': subject,
|
||||
'body': body,
|
||||
'signature': '',
|
||||
}
|
||||
if body_text := html_to_text(body_text):
|
||||
if user.signature:
|
||||
body_text += '\n-- \n' + converter.handle(user.signature)
|
||||
body_text += '\n-- \n' + html_to_text(user.signature)
|
||||
msg.add_alternative(body_text, subtype='plain')
|
||||
if msg.is_multipart():
|
||||
msg.add_alternative(body_html, subtype='html')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from .report import Report, get_email, mjml_to_html
|
||||
from .report import Report, get_email, html_to_text, mjml_to_html
|
||||
|
||||
__all__ = [Report, get_email, mjml_to_html]
|
||||
__all__ = [Report, get_email, html_to_text, mjml_to_html]
|
||||
|
||||
@@ -21,17 +21,6 @@ from io import BytesIO
|
||||
from itertools import groupby
|
||||
|
||||
import dateutil.tz
|
||||
|
||||
try:
|
||||
import html2text
|
||||
except ImportError:
|
||||
html2text = None
|
||||
|
||||
try:
|
||||
import weasyprint
|
||||
except ImportError:
|
||||
weasyprint = None
|
||||
|
||||
from genshi.filters import Translator
|
||||
from genshi.template.text import TextTemplate
|
||||
|
||||
@@ -422,10 +411,10 @@ class Report(URLMixin, PoolBase):
|
||||
input_format = report.template_extension
|
||||
output_format = report.extension or report.template_extension
|
||||
|
||||
if (weasyprint
|
||||
and input_format in {'html', 'xhtml'}
|
||||
if (input_format in {'html', 'xhtml'}
|
||||
and output_format == 'pdf'):
|
||||
return output_format, weasyprint.HTML(string=data).write_pdf()
|
||||
if weasyprint := _lazy_import('weasyprint'):
|
||||
return output_format, weasyprint.HTML(string=data).write_pdf()
|
||||
|
||||
if (input_format == 'xml'
|
||||
and output_format == 'html'
|
||||
@@ -612,7 +601,6 @@ def get_email(report, record, languages):
|
||||
else:
|
||||
report_name = report
|
||||
Report_ = pool.get(report_name, type='report')
|
||||
converter = None
|
||||
title = None
|
||||
msg = EmailMessage()
|
||||
header_factory = msg.policy.header_factory
|
||||
@@ -631,13 +619,11 @@ def get_email(report, record, languages):
|
||||
break
|
||||
else:
|
||||
maintype, subtype = 'application', ext
|
||||
if maintype == 'text' and subtype == 'html' and html2text:
|
||||
if not converter:
|
||||
converter = html2text.HTML2Text()
|
||||
content_text = converter.handle(content)
|
||||
msg.add_alternative(content_text, subtype='plain', headers=[
|
||||
header_factory('Content-Language', language.code),
|
||||
])
|
||||
if maintype == 'text' and subtype == 'html':
|
||||
if content_text := html_to_text(content):
|
||||
msg.add_alternative(content_text, subtype='plain', headers=[
|
||||
header_factory('Content-Language', language.code),
|
||||
])
|
||||
types = {
|
||||
'subtype': subtype,
|
||||
}
|
||||
@@ -663,3 +649,8 @@ def mjml_to_html(content):
|
||||
if mrml := _lazy_import('mrml'):
|
||||
content = mrml.to_html(content).content
|
||||
return content
|
||||
|
||||
|
||||
def html_to_text(content):
|
||||
if html2text := _lazy_import('html2text'):
|
||||
return html2text.HTML2Text().handle(content)
|
||||
|
||||
@@ -136,9 +136,9 @@ class ReportTestCase(TestCase):
|
||||
'<!doctype html><title>Test</title>')
|
||||
|
||||
@with_transaction()
|
||||
@patch('trytond.report.report.html2text')
|
||||
def test_get_email_html_without_html2text(self, html2text):
|
||||
html2text.__bool__.side_effect = lambda: False
|
||||
@patch('trytond.report.report.html_to_text')
|
||||
def test_get_email_html_without_html2text(self, html_to_text):
|
||||
html_to_text.side_effect = lambda content: None
|
||||
|
||||
class FakeReport(Report):
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user