Commit bbbfd022 authored by Carlos Ramos Carreño's avatar Carlos Ramos Carreño Committed by Arnaud Fontaine

Fix encode/decode mistakes in corporate identity.

Instead of using encode/decode is it better to use str2bytes and
bytes2str, so that the types in Python 2 are unchanged. More important,
this prevents the double encoding of bytes, which causes problems
when they have non-ASCII data encoded.
parent 3ee35440
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
from erp5.component.document.Document import DocumentConversionServerProxy from erp5.component.document.Document import DocumentConversionServerProxy
from base64 import b64encode, b64decode from base64 import b64encode, b64decode
from zExceptions import Unauthorized from zExceptions import Unauthorized
from Products.ERP5Type.Utils import bytes2str
def convertDocumentByConversionServer( def convertDocumentByConversionServer(
self, self,
...@@ -48,7 +49,7 @@ def convertDocumentByConversionServer( ...@@ -48,7 +49,7 @@ def convertDocumentByConversionServer(
proxy = DocumentConversionServerProxy(self) proxy = DocumentConversionServerProxy(self)
return b64decode( return b64decode(
proxy.convertFile( proxy.convertFile(
b64encode(data).decode(), bytes2str(b64encode(data)),
source_mimetype, source_mimetype,
destination_mimetype, destination_mimetype,
zip, zip,
......
...@@ -9,6 +9,7 @@ Return local parameters that require proxy role to access ...@@ -9,6 +9,7 @@ Return local parameters that require proxy role to access
# pass_source_data followup uid or context for retrieving info # pass_source_data followup uid or context for retrieving info
# pass_flag_site whether called from a web site (no follow-up) # pass_flag_site whether called from a web site (no follow-up)
from base64 import b64encode from base64 import b64encode
from Products.ERP5Type.Utils import bytes2str
portal_type_valid_template_list = ["Web Site", "Web Section", "Web Page", "Letter", "Test Page"] portal_type_valid_template_list = ["Web Site", "Web Section", "Web Page", "Letter", "Test Page"]
portal_type_valid_report_list = ["Project", "Sale Order", "Sale Opportunity", "Requirement Document", "Person"] portal_type_valid_report_list = ["Project", "Sale Order", "Sale Opportunity", "Requirement Document", "Person"]
portal_type = context.getPortalType() portal_type = context.getPortalType()
...@@ -128,7 +129,7 @@ def populateOrganisationDict(my_organisation_list): ...@@ -128,7 +129,7 @@ def populateOrganisationDict(my_organisation_list):
if organisation_default_image: if organisation_default_image:
output_dict["logo_url"] = organisation_default_image.getRelativeUrl() output_dict["logo_url"] = organisation_default_image.getRelativeUrl()
output_dict["logo_data_url"] = 'data:image/png;;base64,%s' % ( output_dict["logo_data_url"] = 'data:image/png;;base64,%s' % (
b64encode(organisation_default_image.convert(format="png", display="thumbnail")[1]).decode() bytes2str(b64encode(organisation_default_image.convert(format="png", display="thumbnail")[1]))
) )
else: else:
output_dict["logo_url"] = err("logo_url") output_dict["logo_url"] = err("logo_url")
......
...@@ -28,6 +28,7 @@ MAIN FILE: generate letter in different output formats ...@@ -28,6 +28,7 @@ MAIN FILE: generate letter in different output formats
import re import re
from base64 import b64encode from base64 import b64encode
from Products.ERP5Type.Utils import str2bytes, bytes2str
blank = '' blank = ''
pref = context.getPortalObject().portal_preferences pref = context.getPortalObject().portal_preferences
...@@ -256,9 +257,9 @@ if letter_format == "pdf": ...@@ -256,9 +257,9 @@ if letter_format == "pdf":
) )
# ================ encode and build cloudoo elements ========================= # ================ encode and build cloudoo elements =========================
embedded_html_data = letter.Base_convertHtmlToSingleFile(letter_content, allow_script=True).encode('utf-8') embedded_html_data = str2bytes(letter.Base_convertHtmlToSingleFile(letter_content, allow_script=True))
header_embedded_html_data = letter.Base_convertHtmlToSingleFile(letter_head, allow_script=True).encode('utf-8') header_embedded_html_data = str2bytes(letter.Base_convertHtmlToSingleFile(letter_head, allow_script=True))
footer_embedded_html_data = letter.Base_convertHtmlToSingleFile(letter_foot, allow_script=True).encode('utf-8') footer_embedded_html_data = str2bytes(letter.Base_convertHtmlToSingleFile(letter_foot, allow_script=True))
pdf_file = letter.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict( pdf_file = letter.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict(
encoding="utf8", encoding="utf8",
margin_top=letter_header_margin_to_top, margin_top=letter_header_margin_to_top,
...@@ -266,8 +267,8 @@ if letter_format == "pdf": ...@@ -266,8 +267,8 @@ if letter_format == "pdf":
margin_left=0, margin_left=0,
margin_right=0, margin_right=0,
header_spacing=1, header_spacing=1,
header_html_data=b64encode(header_embedded_html_data).decode(), header_html_data=bytes2str(b64encode(header_embedded_html_data)),
footer_html_data=b64encode(footer_embedded_html_data).decode(), footer_html_data=bytes2str(b64encode(footer_embedded_html_data)),
) )
) )
......
...@@ -36,7 +36,7 @@ MAIN FILE: generate report (book header/footer and report content) ...@@ -36,7 +36,7 @@ MAIN FILE: generate report (book header/footer and report content)
# report_title report title # report_title report title
# report_header custom report header # report_header custom report header
from Products.ERP5Type.Utils import str2bytes from Products.ERP5Type.Utils import str2bytes, bytes2str
from Products.PythonScripts.standard import html_quote from Products.PythonScripts.standard import html_quote
from base64 import b64encode from base64 import b64encode
...@@ -261,7 +261,7 @@ if doc_format == "pdf": ...@@ -261,7 +261,7 @@ if doc_format == "pdf":
# ================ encode and build cloudoo elements ========================= # ================ encode and build cloudoo elements =========================
header_embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_head, allow_script=True)) header_embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_head, allow_script=True))
before_toc_data_list = [] before_toc_data_list = []
xsl_style_sheet_data = blank.encode() xsl_style_sheet_data = str2bytes(blank)
embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_content, allow_script=True)) embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_content, allow_script=True))
footer_embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_foot, allow_script=True)) footer_embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_foot, allow_script=True))
default_conversion_kw = dict( default_conversion_kw = dict(
...@@ -270,10 +270,10 @@ if doc_format == "pdf": ...@@ -270,10 +270,10 @@ if doc_format == "pdf":
margin_bottom=20, margin_bottom=20,
toc=False, toc=False,
before_toc_data_list=before_toc_data_list, before_toc_data_list=before_toc_data_list,
xsl_style_sheet_data=b64encode(xsl_style_sheet_data).decode(), xsl_style_sheet_data=bytes2str(b64encode(xsl_style_sheet_data)),
header_html_data=b64encode(header_embedded_html_data).decode(), header_html_data=bytes2str(b64encode(header_embedded_html_data)),
header_spacing=10, header_spacing=10,
footer_html_data=b64encode(footer_embedded_html_data).decode(), footer_html_data=bytes2str(b64encode(footer_embedded_html_data)),
footer_spacing=3, footer_spacing=3,
) )
default_conversion_kw.update(conversion_dict) default_conversion_kw.update(conversion_dict)
......
...@@ -13,6 +13,7 @@ Try to convert old OpenOffice presentations into slideshows ...@@ -13,6 +13,7 @@ Try to convert old OpenOffice presentations into slideshows
import re import re
from io import BytesIO from io import BytesIO
from zipfile import ZipFile from zipfile import ZipFile
from Products.ERP5Type.Utils import bytes2str
blank = '' blank = ''
flags = re.MULTILINE|re.DOTALL|re.IGNORECASE flags = re.MULTILINE|re.DOTALL|re.IGNORECASE
...@@ -32,7 +33,7 @@ def getSlideList(zip_content): ...@@ -32,7 +33,7 @@ def getSlideList(zip_content):
name.replace('img', '').replace('text', ''))): name.replace('img', '').replace('text', ''))):
if name.endswith('.html'): if name.endswith('.html'):
slide_list.extend( slide_list.extend(
re.findall(r'<html>(.*?)</html>', zf.read(name).decode('utf-8'), flags=flags) re.findall(r'<html>(.*?)</html>', bytes2str(zf.read(name)), flags=flags)
) )
return slide_list return slide_list
......
...@@ -36,7 +36,7 @@ import re ...@@ -36,7 +36,7 @@ import re
import six import six
from Products.PythonScripts.standard import html_quote from Products.PythonScripts.standard import html_quote
from Products.ERP5Type.Utils import str2bytes from Products.ERP5Type.Utils import str2bytes bytes2str
from base64 import b64encode from base64 import b64encode
blank = '' blank = ''
...@@ -362,18 +362,18 @@ elif book_format == "pdf": ...@@ -362,18 +362,18 @@ elif book_format == "pdf":
# ================ encode and build cloudoo elements ========================= # ================ encode and build cloudoo elements =========================
header_embedded_html_data = str2bytes(book.Base_convertHtmlToSingleFile(book_head, allow_script=True)) header_embedded_html_data = str2bytes(book.Base_convertHtmlToSingleFile(book_head, allow_script=True))
before_toc_data_list = [ before_toc_data_list = [
b64encode(str2bytes(book.Base_convertHtmlToSingleFile(book_cover, allow_script=True))).decode(), bytes2str(b64encode(str2bytes(book.Base_convertHtmlToSingleFile(book_cover, allow_script=True)))),
] ]
after_toc_data_list = [] after_toc_data_list = []
if book_include_history_table: if book_include_history_table:
before_toc_data_list.append( before_toc_data_list.append(
b64encode(str2bytes(book.Base_convertHtmlToSingleFile(book_history, allow_script=True))).decode() bytes2str(b64encode(str2bytes(book.Base_convertHtmlToSingleFile(book_history, allow_script=True))))
) )
#if book_include_reference_table: #if book_include_reference_table:
# after_toc_data_list.append( # after_toc_data_list.append(
# b64encode(str2bytes(book.Base_convertHtmlToSingleFile(book_references, allow_script=True))).decode() # b64encode(str2bytes(book.Base_convertHtmlToSingleFile(book_references, allow_script=True))).decode()
# ) # )
xsl_style_sheet_data = book_table_of_content.encode('utf-8') xsl_style_sheet_data = str2bytes(book_table_of_content)
embedded_html_data = str2bytes(book.Base_convertHtmlToSingleFile(book_content, allow_script=True)) embedded_html_data = str2bytes(book.Base_convertHtmlToSingleFile(book_content, allow_script=True))
footer_embedded_html_data = str2bytes(book.Base_convertHtmlToSingleFile(book_foot, allow_script=True)) footer_embedded_html_data = str2bytes(book.Base_convertHtmlToSingleFile(book_foot, allow_script=True))
if margin_15mm: if margin_15mm:
...@@ -388,11 +388,11 @@ elif book_format == "pdf": ...@@ -388,11 +388,11 @@ elif book_format == "pdf":
margin_bottom=margin_bottom, margin_bottom=margin_bottom,
toc=True if book_include_content_table else False, toc=True if book_include_content_table else False,
before_toc_data_list=before_toc_data_list, before_toc_data_list=before_toc_data_list,
xsl_style_sheet_data=b64encode(xsl_style_sheet_data).decode(), xsl_style_sheet_data=bytes2str(b64encode(xsl_style_sheet_data)),
after_toc_data_list=after_toc_data_list, after_toc_data_list=after_toc_data_list,
header_html_data=b64encode(header_embedded_html_data).decode(), header_html_data=bytes2str(b64encode(header_embedded_html_data)),
header_spacing=10, header_spacing=10,
footer_html_data=b64encode(footer_embedded_html_data).decode(), footer_html_data=bytes2str(b64encode(footer_embedded_html_data)),
footer_spacing=3, footer_spacing=3,
) )
) )
......
...@@ -2,6 +2,7 @@ import re ...@@ -2,6 +2,7 @@ import re
import six import six
from base64 import b64encode from base64 import b64encode
from Products.ERP5Type.Utils import bytes2str, str2bytes
blank = b'' blank = b''
pref = context.getPortalObject().portal_preferences pref = context.getPortalObject().portal_preferences
...@@ -290,22 +291,22 @@ elif contract_format == "pdf": ...@@ -290,22 +291,22 @@ elif contract_format == "pdf":
) )
# ================ encode and build cloudoo elements ========================= # ================ encode and build cloudoo elements =========================
header_embedded_html_data = context.Base_convertHtmlToSingleFile(contract_head, allow_script=True).encode('utf-8') header_embedded_html_data = str2bytes(context.Base_convertHtmlToSingleFile(contract_head, allow_script=True))
before_toc_data_list = [ before_toc_data_list = [
b64encode(context.Base_convertHtmlToSingleFile(contract_cover, allow_script=True).encode('utf-8')).decode(), bytes2str(b64encode(str2bytes(context.Base_convertHtmlToSingleFile(contract_cover, allow_script=True)))),
] ]
after_toc_data_list = [] after_toc_data_list = []
if contract_include_history_table: if contract_include_history_table:
before_toc_data_list.append( before_toc_data_list.append(
b64encode(context.Base_convertHtmlToSingleFile(contract_history, allow_script=True).encode('utf-8')).decode() bytes2str(b64encode(str2bytes(context.Base_convertHtmlToSingleFile(contract_history, allow_script=True))))
) )
#if contract_include_reference_table: #if contract_include_reference_table:
# after_toc_data_list.append( # after_toc_data_list.append(
# b64encode(context.Base_convertHtmlToSingleFile(contract_references, allow_script=True)).decode() # bytes2str(b64encode(str2bytes(context.Base_convertHtmlToSingleFile(contract_references, allow_script=True))))
# ) # )
xsl_style_sheet_data = contract_table_of_content xsl_style_sheet_data = contract_table_of_content
embedded_html_data = context.Base_convertHtmlToSingleFile(contract_content, allow_script=True).encode('utf-8') embedded_html_data = str2bytes(context.Base_convertHtmlToSingleFile(contract_content, allow_script=True))
footer_embedded_html_data = context.Base_convertHtmlToSingleFile(contract_foot, allow_script=True).encode('utf-8') footer_embedded_html_data = str2bytes(context.Base_convertHtmlToSingleFile(contract_foot, allow_script=True))
margin_top = 40 margin_top = 40
margin_bottom = 20 margin_bottom = 20
pdf_file = context.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict( pdf_file = context.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict(
...@@ -314,11 +315,11 @@ elif contract_format == "pdf": ...@@ -314,11 +315,11 @@ elif contract_format == "pdf":
margin_bottom=margin_bottom, margin_bottom=margin_bottom,
toc=True if contract_include_content_table else False, toc=True if contract_include_content_table else False,
before_toc_data_list=before_toc_data_list, before_toc_data_list=before_toc_data_list,
xsl_style_sheet_data=b64encode(xsl_style_sheet_data).decode(), xsl_style_sheet_data=bytes2str(b64encode(xsl_style_sheet_data)),
after_toc_data_list=after_toc_data_list, after_toc_data_list=after_toc_data_list,
header_html_data=b64encode(header_embedded_html_data).decode(), header_html_data=bytes2str(b64encode(header_embedded_html_data)),
header_spacing=10, header_spacing=10,
footer_html_data=b64encode(footer_embedded_html_data).decode(), footer_html_data=bytes2str(b64encode(footer_embedded_html_data)),
footer_spacing=3, footer_spacing=3,
) )
) )
......
...@@ -26,6 +26,7 @@ import six ...@@ -26,6 +26,7 @@ import six
from Products.PythonScripts.standard import html_quote from Products.PythonScripts.standard import html_quote
from base64 import b64encode from base64 import b64encode
from Products.ERP5Type.Utils import bytes2str, str2bytes
blank = '' blank = ''
pref = context.getPortalObject().portal_preferences pref = context.getPortalObject().portal_preferences
...@@ -257,9 +258,9 @@ if leaflet_format == "pdf": ...@@ -257,9 +258,9 @@ if leaflet_format == "pdf":
) )
# ================ encode and build cloudoo elements ========================= # ================ encode and build cloudoo elements =========================
embedded_html_data = leaflet.Base_convertHtmlToSingleFile(leaflet_content, allow_script=True).encode('utf-8') embedded_html_data = str2bytes(leaflet.Base_convertHtmlToSingleFile(leaflet_content, allow_script=True))
header_embedded_html_data = leaflet.Base_convertHtmlToSingleFile(leaflet_head, allow_script=True).encode('utf-8') header_embedded_html_data = str2bytes(leaflet.Base_convertHtmlToSingleFile(leaflet_head, allow_script=True))
footer_embedded_html_data = leaflet.Base_convertHtmlToSingleFile(leaflet_foot, allow_script=True).encode('utf-8') footer_embedded_html_data = str2bytes(leaflet.Base_convertHtmlToSingleFile(leaflet_foot, allow_script=True))
pdf_file = leaflet.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict( pdf_file = leaflet.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict(
encoding="utf8", encoding="utf8",
orientation="portrait", orientation="portrait",
...@@ -267,9 +268,9 @@ if leaflet_format == "pdf": ...@@ -267,9 +268,9 @@ if leaflet_format == "pdf":
margin_bottom=20, margin_bottom=20,
margin_left=0, margin_left=0,
margin_right=0, margin_right=0,
header_html_data=b64encode(header_embedded_html_data).decode(), header_html_data=bytes2str(b64encode(header_embedded_html_data)),
header_spacing=10, header_spacing=10,
footer_html_data=b64encode(footer_embedded_html_data).decode(), footer_html_data=bytes2str(b64encode(footer_embedded_html_data)),
footer_spacing=3 footer_spacing=3
) )
) )
......
...@@ -23,6 +23,7 @@ MAIN FILE: render press release in different output formats ...@@ -23,6 +23,7 @@ MAIN FILE: render press release in different output formats
import re import re
import six import six
from base64 import b64encode from base64 import b64encode
from Products.ERP5Type.Utils import bytes2str, str2bytes
blank = '' blank = ''
pref = context.getPortalObject().portal_preferences pref = context.getPortalObject().portal_preferences
...@@ -228,9 +229,9 @@ if release_format == "pdf": ...@@ -228,9 +229,9 @@ if release_format == "pdf":
) )
# ================ encode and build cloudoo elements ========================= # ================ encode and build cloudoo elements =========================
embedded_html_data = release.Base_convertHtmlToSingleFile(release_content, allow_script=True).encode('utf-8') embedded_html_data = str2bytes(release.Base_convertHtmlToSingleFile(release_content, allow_script=True))
header_embedded_html_data = release.Base_convertHtmlToSingleFile(release_head, allow_script=True).encode('utf-8') header_embedded_html_data = str2bytes(release.Base_convertHtmlToSingleFile(release_head, allow_script=True))
footer_embedded_html_data = release.Base_convertHtmlToSingleFile(release_foot, allow_script=True).encode('utf-8') footer_embedded_html_data = str2bytes(release.Base_convertHtmlToSingleFile(release_foot, allow_script=True))
pdf_file = release.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict( pdf_file = release.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict(
encoding="utf8", encoding="utf8",
orientation="portrait", orientation="portrait",
...@@ -238,9 +239,9 @@ if release_format == "pdf": ...@@ -238,9 +239,9 @@ if release_format == "pdf":
margin_bottom=20, margin_bottom=20,
margin_left=0, margin_left=0,
margin_right=0, margin_right=0,
header_html_data=b64encode(header_embedded_html_data).decode(), header_html_data=bytes2str(b64encode(header_embedded_html_data)),
header_spacing=10, header_spacing=10,
footer_html_data=b64encode(footer_embedded_html_data).decode(), footer_html_data=bytes2str(b64encode(footer_embedded_html_data)),
footer_spacing=3 footer_spacing=3
) )
) )
......
...@@ -27,6 +27,7 @@ import re ...@@ -27,6 +27,7 @@ import re
from Products.PythonScripts.standard import html_quote from Products.PythonScripts.standard import html_quote
from base64 import b64encode from base64 import b64encode
from Products.ERP5Type.Utils import bytes2str, str2bytes
blank = '' blank = ''
slide_content = blank slide_content = blank
...@@ -421,23 +422,23 @@ if doc_format == "pdf" or doc_format == "mhtml": ...@@ -421,23 +422,23 @@ if doc_format == "pdf" or doc_format == "mhtml":
) )
# ================ encode and build cloudoo elements ========================= # ================ encode and build cloudoo elements =========================
footer_embedded_html_data = doc.Base_convertHtmlToSingleFile(doc_slideshow_footer, allow_script=True).encode('utf-8') footer_embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_slideshow_footer, allow_script=True))
#embedded_html_data = doc.Base_convertHtmlToSingleFile(doc_slideshow_content, allow_script=True).encode('utf-8') #embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_slideshow_content, allow_script=True))
cover = doc.Base_convertHtmlToSingleFile(doc_slideshow_cover, allow_script=True).encode('utf-8') cover = str2bytes(doc.Base_convertHtmlToSingleFile(doc_slideshow_cover, allow_script=True))
before_body_data_list = [ before_body_data_list = [
b64encode(cover).decode(), bytes2str(b64encode(cover)),
] ]
if doc_format == "mhtml": if doc_format == "mhtml":
context.REQUEST.RESPONSE.setHeader("Content-Type", "text/html;") context.REQUEST.RESPONSE.setHeader("Content-Type", "text/html;")
return doc.Base_convertHtmlToSingleFile(doc_slideshow_cover, allow_script=True) return doc.Base_convertHtmlToSingleFile(doc_slideshow_cover, allow_script=True)
if doc_display_notes: if doc_display_notes:
#after_body_data_list = [ #after_body_data_list = [
# b64encode(doc.Base_convertHtmlToSingleFile(doc_slideshow_notes, allow_script=True).encode('utf-8')).decode(), # bytes2str(b64encode(str2bytes(doc.Base_convertHtmlToSingleFile(doc_slideshow_notes, allow_script=True)))),
#] #]
embedded_html_data = doc.Base_convertHtmlToSingleFile(doc_slideshow_notes, allow_script=True).encode('utf-8') embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_slideshow_notes, allow_script=True))
after_body_data_list = [] after_body_data_list = []
else: else:
embedded_html_data = doc.Base_convertHtmlToSingleFile(doc_slideshow_content, allow_script=True).encode('utf-8') embedded_html_data = str2bytes(doc.Base_convertHtmlToSingleFile(doc_slideshow_content, allow_script=True))
after_body_data_list = [] after_body_data_list = []
#after_body_data_list = [] #after_body_data_list = []
pdf_file = doc.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict( pdf_file = doc.Base_cloudoooDocumentConvert(embedded_html_data, "html", "pdf", conversion_kw=dict(
...@@ -448,7 +449,7 @@ if doc_format == "pdf" or doc_format == "mhtml": ...@@ -448,7 +449,7 @@ if doc_format == "pdf" or doc_format == "mhtml":
before_body_data_list=before_body_data_list, before_body_data_list=before_body_data_list,
after_body_data_list=after_body_data_list, after_body_data_list=after_body_data_list,
header_spacing=10, header_spacing=10,
footer_html_data=b64encode(footer_embedded_html_data).decode(), footer_html_data=bytes2str(b64encode(footer_embedded_html_data)),
footer_spacing=3 footer_spacing=3
) )
) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment