|
|
@@ -14,11 +14,12 @@ import frappe.integrations.utils |
|
|
|
import frappe.utils |
|
|
|
import frappe.utils.data |
|
|
|
from frappe import _ |
|
|
|
from frappe.handler import execute_cmd |
|
|
|
from frappe.frappeclient import FrappeClient |
|
|
|
from frappe.modules import scrub |
|
|
|
from frappe.website.utils import get_next_link, get_shade, get_toc |
|
|
|
from frappe.www.printview import get_visible_columns |
|
|
|
|
|
|
|
from frappe.utils.background_jobs import enqueue, get_jobs |
|
|
|
|
|
|
|
class ServerScriptNotEnabled(frappe.PermissionError): |
|
|
|
pass |
|
|
@@ -74,7 +75,9 @@ def get_safe_globals(): |
|
|
|
|
|
|
|
add_data_utils(datautils) |
|
|
|
|
|
|
|
if "_" in getattr(frappe.local, 'form_dict', {}): |
|
|
|
form_dict = getattr(frappe.local, 'form_dict', frappe._dict()) |
|
|
|
|
|
|
|
if "_" in form_dict: |
|
|
|
del frappe.local.form_dict["_"] |
|
|
|
|
|
|
|
user = getattr(frappe.local, "session", None) and frappe.local.session.user or "Guest" |
|
|
@@ -89,14 +92,16 @@ def get_safe_globals(): |
|
|
|
dict=dict, |
|
|
|
log=frappe.log, |
|
|
|
_dict=frappe._dict, |
|
|
|
args=form_dict, |
|
|
|
frappe=NamespaceDict( |
|
|
|
call=call_whitelisted_function, |
|
|
|
flags=frappe._dict(), |
|
|
|
format=frappe.format_value, |
|
|
|
format_value=frappe.format_value, |
|
|
|
date_format=date_format, |
|
|
|
time_format=time_format, |
|
|
|
format_date=frappe.utils.data.global_date_format, |
|
|
|
form_dict=getattr(frappe.local, 'form_dict', {}), |
|
|
|
form_dict=form_dict, |
|
|
|
bold=frappe.bold, |
|
|
|
copy_doc=frappe.copy_doc, |
|
|
|
errprint=frappe.errprint, |
|
|
@@ -132,6 +137,7 @@ def get_safe_globals(): |
|
|
|
make_post_request=frappe.integrations.utils.make_post_request, |
|
|
|
socketio_port=frappe.conf.socketio_port, |
|
|
|
get_hooks=get_hooks, |
|
|
|
enqueue=safe_enqueue, |
|
|
|
sanitize_html=frappe.utils.sanitize_html, |
|
|
|
log_error=frappe.log_error |
|
|
|
), |
|
|
@@ -147,7 +153,8 @@ def get_safe_globals(): |
|
|
|
guess_mimetype=mimetypes.guess_type, |
|
|
|
html2text=html2text, |
|
|
|
dev_server=1 if frappe._dev_server else 0, |
|
|
|
run_script=run_script |
|
|
|
run_script=run_script, |
|
|
|
is_job_queued=is_job_queued, |
|
|
|
) |
|
|
|
|
|
|
|
add_module_properties(frappe.exceptions, out.frappe, lambda obj: inspect.isclass(obj) and issubclass(obj, Exception)) |
|
|
@@ -190,6 +197,55 @@ def get_safe_globals(): |
|
|
|
|
|
|
|
return out |
|
|
|
|
|
|
|
def is_job_queued(job_name, queue="default"): |
|
|
|
''' |
|
|
|
:param job_name: used to identify a queued job, usually dotted path to function |
|
|
|
:param queue: should be either long, default or short |
|
|
|
''' |
|
|
|
|
|
|
|
site = frappe.local.site |
|
|
|
queued_jobs = get_jobs(site=site, queue=queue, key='job_name').get(site) |
|
|
|
return queued_jobs and job_name in queued_jobs |
|
|
|
|
|
|
|
def safe_enqueue(function, **kwargs): |
|
|
|
''' |
|
|
|
Enqueue function to be executed using a background worker |
|
|
|
Accepts frappe.enqueue params like job_name, queue, timeout, etc. |
|
|
|
in addition to params to be passed to function |
|
|
|
|
|
|
|
:param function: whitelised function or API Method set in Server Script |
|
|
|
''' |
|
|
|
|
|
|
|
return enqueue( |
|
|
|
'frappe.utils.safe_exec.call_whitelisted_function', |
|
|
|
function=function, |
|
|
|
**kwargs |
|
|
|
) |
|
|
|
|
|
|
|
def call_whitelisted_function(function, **kwargs): |
|
|
|
'''Executes a whitelisted function or Server Script of type API''' |
|
|
|
|
|
|
|
return call_with_form_dict(lambda: execute_cmd(function), kwargs) |
|
|
|
|
|
|
|
def run_script(script, **kwargs): |
|
|
|
'''run another server script''' |
|
|
|
|
|
|
|
return call_with_form_dict( |
|
|
|
lambda: frappe.get_doc('Server Script', script).execute_method(), |
|
|
|
kwargs |
|
|
|
) |
|
|
|
|
|
|
|
def call_with_form_dict(function, kwargs): |
|
|
|
# temporarily update form_dict, to use inside below call |
|
|
|
form_dict = getattr(frappe.local, 'form_dict', frappe._dict()) |
|
|
|
if kwargs: |
|
|
|
frappe.local.form_dict = form_dict.copy().update(kwargs) |
|
|
|
|
|
|
|
try: |
|
|
|
return function() |
|
|
|
finally: |
|
|
|
frappe.local.form_dict = form_dict |
|
|
|
|
|
|
|
def get_python_builtins(): |
|
|
|
return { |
|
|
|
'abs': abs, |
|
|
@@ -221,9 +277,6 @@ def read_sql(query, *args, **kwargs): |
|
|
|
raise frappe.PermissionError('Only SELECT SQL allowed in scripting') |
|
|
|
return frappe.db.sql(query, *args, **kwargs) |
|
|
|
|
|
|
|
def run_script(script): |
|
|
|
'''run another server script''' |
|
|
|
return frappe.get_doc('Server Script', script).execute_method() |
|
|
|
|
|
|
|
def _getitem(obj, key): |
|
|
|
# guard function for RestrictedPython |
|
|
|