169 lines
4.3 KiB
Python
169 lines
4.3 KiB
Python
import functools
|
|
import sys
|
|
from typing import Literal
|
|
|
|
import frappe
|
|
from frappe import _
|
|
from frappe.utils import strip_html_tags
|
|
from frappe.utils.data import safe_decode
|
|
|
|
_strip_html_tags = functools.lru_cache(maxsize=1024)(strip_html_tags)
|
|
|
|
|
|
def msgprint(
|
|
msg: str,
|
|
title: str | None = None,
|
|
raise_exception: bool | type[Exception] | Exception = False,
|
|
as_table: bool = False,
|
|
as_list: bool = False,
|
|
indicator: Literal["blue", "green", "orange", "red", "yellow"] | None = None,
|
|
alert: bool = False,
|
|
primary_action: dict | None = None,
|
|
is_minimizable: bool = False,
|
|
wide: bool = False,
|
|
*,
|
|
realtime=False,
|
|
) -> None:
|
|
"""Print a message to the user (via HTTP response).
|
|
Messages are sent in the `__server_messages` property in the
|
|
response JSON and shown in a pop-up / modal.
|
|
|
|
:param msg: Message.
|
|
:param title: [optional] Message title. Default: "Message".
|
|
:param raise_exception: [optional] Raise given exception and show message.
|
|
:param as_table: [optional] If `msg` is a list of lists, render as HTML table.
|
|
:param as_list: [optional] If `msg` is a list, render as un-ordered list.
|
|
:param primary_action: [optional] Bind a primary server/client side action.
|
|
:param is_minimizable: [optional] Allow users to minimize the modal
|
|
:param wide: [optional] Show wide modal
|
|
:param realtime: Publish message immediately using websocket.
|
|
"""
|
|
import inspect
|
|
|
|
msg = safe_decode(msg)
|
|
out = frappe._dict(message=msg)
|
|
|
|
def _raise_exception():
|
|
if raise_exception:
|
|
if inspect.isclass(raise_exception) and issubclass(raise_exception, Exception):
|
|
exc = raise_exception(msg)
|
|
elif isinstance(raise_exception, Exception):
|
|
exc = raise_exception
|
|
exc.args = (msg,)
|
|
else:
|
|
exc = frappe.ValidationError(msg)
|
|
if out.__frappe_exc_id:
|
|
exc.__frappe_exc_id = out.__frappe_exc_id
|
|
raise exc
|
|
|
|
if frappe.flags.mute_messages:
|
|
_raise_exception()
|
|
return
|
|
|
|
if as_table and type(msg) in (list, tuple):
|
|
out.as_table = 1
|
|
|
|
if as_list and type(msg) in (list, tuple):
|
|
out.as_list = 1
|
|
|
|
if sys.stdin and sys.stdin.isatty():
|
|
if out.as_list:
|
|
msg = [_strip_html_tags(msg) for msg in out.message]
|
|
else:
|
|
msg = _strip_html_tags(out.message)
|
|
|
|
if frappe.flags.print_messages and out.message:
|
|
print(f"Message: {_strip_html_tags(out.message)}")
|
|
|
|
out.title = title or _("Message", context="Default title of the message dialog")
|
|
|
|
if not indicator and raise_exception:
|
|
indicator = "red"
|
|
|
|
if indicator:
|
|
out.indicator = indicator
|
|
|
|
if is_minimizable:
|
|
out.is_minimizable = is_minimizable
|
|
|
|
if alert:
|
|
out.alert = 1
|
|
|
|
if raise_exception:
|
|
out.raise_exception = 1
|
|
out.__frappe_exc_id = frappe.generate_hash()
|
|
|
|
if primary_action:
|
|
out.primary_action = primary_action
|
|
|
|
if wide:
|
|
out.wide = wide
|
|
|
|
if realtime:
|
|
frappe.publish_realtime(event="msgprint", message=out)
|
|
else:
|
|
frappe.message_log.append(out)
|
|
_raise_exception()
|
|
|
|
|
|
def toast(message: str, indicator: Literal["blue", "green", "orange", "red", "yellow"] | None = None):
|
|
msgprint(message, indicator=indicator, alert=True)
|
|
|
|
|
|
def clear_messages():
|
|
frappe.local.message_log = []
|
|
|
|
|
|
def get_message_log() -> list[dict]:
|
|
return [msg_out for msg_out in frappe.local.message_log]
|
|
|
|
|
|
def clear_last_message():
|
|
if len(frappe.local.message_log) > 0:
|
|
frappe.local.message_log = frappe.local.message_log[:-1]
|
|
|
|
|
|
def throw(
|
|
msg: str,
|
|
exc: type[Exception] | Exception = frappe.ValidationError,
|
|
title: str | None = None,
|
|
is_minimizable: bool = False,
|
|
wide: bool = False,
|
|
as_list: bool = False,
|
|
primary_action=None,
|
|
) -> None:
|
|
"""Throw execption and show message (`msgprint`).
|
|
|
|
:param msg: Message.
|
|
:param exc: Exception class. Default `frappe.ValidationError`
|
|
:param title: [optional] Message title. Default: "Message".
|
|
:param is_minimizable: [optional] Allow users to minimize the modal
|
|
:param wide: [optional] Show wide modal
|
|
:param as_list: [optional] If `msg` is a list, render as un-ordered list.
|
|
:param primary_action: [optional] Bind a primary server/client side action.
|
|
"""
|
|
msgprint(
|
|
msg,
|
|
raise_exception=exc,
|
|
title=title,
|
|
indicator="red",
|
|
is_minimizable=is_minimizable,
|
|
wide=wide,
|
|
as_list=as_list,
|
|
primary_action=primary_action,
|
|
)
|
|
|
|
|
|
def throw_permission_error():
|
|
throw(_("Not permitted"), frappe.PermissionError)
|
|
|
|
|
|
__all__ = [
|
|
"clear_last_message",
|
|
"clear_messages",
|
|
"get_message_log",
|
|
"msgprint",
|
|
"throw",
|
|
"throw_permission_error",
|
|
"toast",
|
|
]
|