Merge branch 'develop' into workflow-button-icon
This commit is contained in:
commit
7345da5dbf
8 changed files with 40 additions and 21 deletions
|
|
@ -9,33 +9,33 @@ from frappe.utils.jinja import validate_template
|
|||
|
||||
|
||||
class EmailTemplate(Document):
|
||||
@property
|
||||
def response_(self):
|
||||
return self.response_html if self.use_html else self.response
|
||||
|
||||
def validate(self):
|
||||
if self.use_html:
|
||||
validate_template(self.response_html)
|
||||
else:
|
||||
validate_template(self.response)
|
||||
validate_template(self.subject)
|
||||
validate_template(self.response_)
|
||||
|
||||
def get_formatted_subject(self, doc):
|
||||
return frappe.render_template(self.subject, doc)
|
||||
|
||||
def get_formatted_response(self, doc):
|
||||
if self.use_html:
|
||||
return frappe.render_template(self.response_html, doc)
|
||||
|
||||
return frappe.render_template(self.response, doc)
|
||||
return frappe.render_template(self.response_, doc)
|
||||
|
||||
def get_formatted_email(self, doc):
|
||||
if isinstance(doc, str):
|
||||
doc = json.loads(doc)
|
||||
|
||||
return {"subject": self.get_formatted_subject(doc), "message": self.get_formatted_response(doc)}
|
||||
return {
|
||||
"subject": self.get_formatted_subject(doc),
|
||||
"message": self.get_formatted_response(doc),
|
||||
}
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_email_template(template_name, doc):
|
||||
"""Returns the processed HTML of a email template with the given doc"""
|
||||
if isinstance(doc, str):
|
||||
doc = json.loads(doc)
|
||||
|
||||
email_template = frappe.get_doc("Email Template", template_name)
|
||||
return email_template.get_formatted_email(doc)
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control
|
|||
"title",
|
||||
__(
|
||||
"This value is fetched from {0}'s {1} field",
|
||||
me.df.fetch_from.split(".")
|
||||
me.df.fetch_from.split(".").map((value) => __(frappe.unscrub(value)))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,9 +104,8 @@ def patch_query_execute():
|
|||
# frame1: execute_query()
|
||||
# frame2: frame that called `query.run()`
|
||||
#
|
||||
# if frame2 is server script it wont have a filename and hence
|
||||
# if frame2 is server script <serverscript> is set as the filename
|
||||
# it shouldn't be allowed.
|
||||
# p.s. stack() returns `"<unknown>"` as filename if not a file.
|
||||
pass
|
||||
else:
|
||||
raise frappe.PermissionError("Only SELECT SQL allowed in scripting")
|
||||
|
|
|
|||
|
|
@ -75,3 +75,10 @@ class TestSafeExec(FrappeTestCase):
|
|||
def test_unsafe_objects(self):
|
||||
unsafe_global = {"frappe": frappe}
|
||||
self.assertRaises(SyntaxError, safe_exec, """frappe.msgprint("Hello")""", unsafe_global)
|
||||
|
||||
def test_attrdict(self):
|
||||
# jinja
|
||||
frappe.render_template("{% set my_dict = _dict() %} {{- my_dict.works -}}")
|
||||
|
||||
# RestrictedPython
|
||||
safe_exec("my_dict = _dict()")
|
||||
|
|
|
|||
|
|
@ -4828,3 +4828,4 @@ CSV Quoting,Anführungszeichen,
|
|||
CSV Preview,Vorschau,
|
||||
Non-numeric,Nicht-numerische,
|
||||
Minimal,Minimal,
|
||||
This value is fetched from {0}'s {1} field,Dieser Wert ergibt sich aus dem Feld {1} von {0},
|
||||
|
|
|
|||
|
|
|
@ -60,7 +60,7 @@ def validate_template(html):
|
|||
frappe.throw(frappe._("Syntax error in template"))
|
||||
|
||||
|
||||
def render_template(template, context, is_path=None, safe_render=True):
|
||||
def render_template(template, context=None, is_path=None, safe_render=True):
|
||||
"""Render a template using Jinja
|
||||
|
||||
:param template: path or HTML containing the jinja template
|
||||
|
|
@ -76,6 +76,9 @@ def render_template(template, context, is_path=None, safe_render=True):
|
|||
if not template:
|
||||
return ""
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
if is_path or guess_is_path(template):
|
||||
return get_jenv().get_template(template).render(context)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from functools import lru_cache
|
|||
|
||||
import RestrictedPython.Guards
|
||||
from RestrictedPython import compile_restricted, safe_globals
|
||||
from RestrictedPython.transformer import RestrictingNodeTransformer
|
||||
|
||||
import frappe
|
||||
import frappe.exceptions
|
||||
|
|
@ -45,6 +46,14 @@ class NamespaceDict(frappe._dict):
|
|||
return ret
|
||||
|
||||
|
||||
class FrappeTransformer(RestrictingNodeTransformer):
|
||||
def check_name(self, node, name, *args, **kwargs):
|
||||
if name == "_dict":
|
||||
return
|
||||
|
||||
return super().check_name(node, name, *args, **kwargs)
|
||||
|
||||
|
||||
def safe_exec(script, _globals=None, _locals=None, restrict_commit_rollback=False):
|
||||
# server scripts can be disabled via site_config.json
|
||||
# they are enabled by default
|
||||
|
|
@ -69,7 +78,11 @@ def safe_exec(script, _globals=None, _locals=None, restrict_commit_rollback=Fals
|
|||
|
||||
with safe_exec_flags(), patched_qb():
|
||||
# execute script compiled by RestrictedPython
|
||||
exec(compile_restricted(script), exec_globals, _locals) # pylint: disable=exec-used
|
||||
exec(
|
||||
compile_restricted(script, filename="<serverscript>", policy=FrappeTransformer),
|
||||
exec_globals,
|
||||
_locals,
|
||||
)
|
||||
|
||||
return exec_globals, _locals
|
||||
|
||||
|
|
@ -106,6 +119,7 @@ def get_safe_globals():
|
|||
as_json=frappe.as_json,
|
||||
dict=dict,
|
||||
log=frappe.log,
|
||||
_dict=frappe._dict,
|
||||
args=form_dict,
|
||||
frappe=NamespaceDict(
|
||||
call=call_whitelisted_function,
|
||||
|
|
@ -116,7 +130,6 @@ def get_safe_globals():
|
|||
time_format=time_format,
|
||||
format_date=frappe.utils.data.global_date_format,
|
||||
form_dict=form_dict,
|
||||
as_dict=frappe._dict,
|
||||
bold=frappe.bold,
|
||||
copy_doc=frappe.copy_doc,
|
||||
errprint=frappe.errprint,
|
||||
|
|
|
|||
|
|
@ -62,10 +62,6 @@ class WebsiteTheme(Document):
|
|||
def generate_bootstrap_theme(self):
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
self.theme_scss = frappe.render_template(
|
||||
"frappe/website/doctype/website_theme/website_theme_template.scss", self.as_dict()
|
||||
)
|
||||
|
||||
# create theme file in site public files folder
|
||||
folder_path = abspath(frappe.utils.get_files_path("website_theme", is_private=False))
|
||||
# create folder if not exist
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue