From 1b73602a1731f718f3a1cac86116292e18df40a4 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 19 Aug 2020 14:31:38 +0530 Subject: [PATCH 01/10] feat(system console): Added a System Console to help in debugging and Console Log --- .../doctype_action/doctype_action.json | 10 +-- frappe/database/mariadb/framework_mariadb.sql | 2 +- .../database/postgres/framework_postgres.sql | 2 +- frappe/desk/doctype/console_log/__init__.py | 0 .../desk/doctype/console_log/console_log.js | 8 +++ .../desk/doctype/console_log/console_log.json | 52 +++++++++++++++ .../desk/doctype/console_log/console_log.py | 10 +++ .../doctype/console_log/test_console_log.py | 10 +++ .../desk/doctype/system_console/__init__.py | 0 .../doctype/system_console/system_console.js | 8 +++ .../system_console/system_console.json | 66 +++++++++++++++++++ .../doctype/system_console/system_console.py | 36 ++++++++++ .../system_console/test_system_console.py | 10 +++ frappe/model/__init__.py | 3 +- frappe/model/naming.py | 2 + frappe/public/js/frappe/form/form.js | 12 +++- frappe/utils/safe_exec.py | 1 + 17 files changed, 224 insertions(+), 8 deletions(-) create mode 100644 frappe/desk/doctype/console_log/__init__.py create mode 100644 frappe/desk/doctype/console_log/console_log.js create mode 100644 frappe/desk/doctype/console_log/console_log.json create mode 100644 frappe/desk/doctype/console_log/console_log.py create mode 100644 frappe/desk/doctype/console_log/test_console_log.py create mode 100644 frappe/desk/doctype/system_console/__init__.py create mode 100644 frappe/desk/doctype/system_console/system_console.js create mode 100644 frappe/desk/doctype/system_console/system_console.json create mode 100644 frappe/desk/doctype/system_console/system_console.py create mode 100644 frappe/desk/doctype/system_console/test_system_console.py diff --git a/frappe/core/doctype/doctype_action/doctype_action.json b/frappe/core/doctype/doctype_action/doctype_action.json index 7a1b845af3..87ee6fc12f 100644 --- a/frappe/core/doctype/doctype_action/doctype_action.json +++ b/frappe/core/doctype/doctype_action/doctype_action.json @@ -31,20 +31,22 @@ "fieldtype": "Select", "in_list_view": 1, "label": "Action Type", - "options": "Server Action", + "options": "Server Action\nRoute", "reqd": 1 }, { "columns": 4, "fieldname": "action", - "fieldtype": "Data", + "fieldtype": "Small Text", "in_list_view": 1, - "label": "Action", + "label": "Action / Route", "reqd": 1 } ], + "index_web_pages_for_search": 1, "istable": 1, - "modified": "2019-09-24 09:11:39.860100", + "links": [], + "modified": "2020-08-18 20:03:42.479436", "modified_by": "Administrator", "module": "Core", "name": "DocType Action", diff --git a/frappe/database/mariadb/framework_mariadb.sql b/frappe/database/mariadb/framework_mariadb.sql index 1e3749e030..15b0bed699 100644 --- a/frappe/database/mariadb/framework_mariadb.sql +++ b/frappe/database/mariadb/framework_mariadb.sql @@ -128,7 +128,7 @@ CREATE TABLE `tabDocType Action` ( `label` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `group` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `action_type` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `action` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `action` text COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`name`), KEY `parent` (`parent`), KEY `modified` (`modified`) diff --git a/frappe/database/postgres/framework_postgres.sql b/frappe/database/postgres/framework_postgres.sql index a946a7ee5c..eeb0eecd3f 100644 --- a/frappe/database/postgres/framework_postgres.sql +++ b/frappe/database/postgres/framework_postgres.sql @@ -128,7 +128,7 @@ CREATE TABLE "tabDocType Action" ( "parenttype" varchar(255) DEFAULT NULL, "idx" bigint NOT NULL DEFAULT 0, "label" varchar(140) NOT NULL, - "group" varchar(140) DEFAULT NULL, + "group" text DEFAULT NULL, "action_type" varchar(140) NOT NULL, "action" varchar(140) NOT NULL, PRIMARY KEY ("name") diff --git a/frappe/desk/doctype/console_log/__init__.py b/frappe/desk/doctype/console_log/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/desk/doctype/console_log/console_log.js b/frappe/desk/doctype/console_log/console_log.js new file mode 100644 index 0000000000..1ef4fdce59 --- /dev/null +++ b/frappe/desk/doctype/console_log/console_log.js @@ -0,0 +1,8 @@ +// Copyright (c) 2020, Frappe Technologies and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Console Log', { + // refresh: function(frm) { + + // } +}); diff --git a/frappe/desk/doctype/console_log/console_log.json b/frappe/desk/doctype/console_log/console_log.json new file mode 100644 index 0000000000..a9ae9717fd --- /dev/null +++ b/frappe/desk/doctype/console_log/console_log.json @@ -0,0 +1,52 @@ +{ + "actions": [], + "autoname": "format:Log on {timestamp}", + "creation": "2020-08-18 19:56:12.336427", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "script", + "output" + ], + "fields": [ + { + "fieldname": "script", + "fieldtype": "Code", + "in_list_view": 1, + "label": "Script", + "read_only": 1 + }, + { + "fieldname": "output", + "fieldtype": "Code", + "label": "Output", + "read_only": 1 + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2020-08-18 20:07:57.587344", + "modified_by": "Administrator", + "module": "Desk", + "name": "Console Log", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/frappe/desk/doctype/console_log/console_log.py b/frappe/desk/doctype/console_log/console_log.py new file mode 100644 index 0000000000..635c4c1ba7 --- /dev/null +++ b/frappe/desk/doctype/console_log/console_log.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class ConsoleLog(Document): + pass diff --git a/frappe/desk/doctype/console_log/test_console_log.py b/frappe/desk/doctype/console_log/test_console_log.py new file mode 100644 index 0000000000..04dc4f241f --- /dev/null +++ b/frappe/desk/doctype/console_log/test_console_log.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestConsoleLog(unittest.TestCase): + pass diff --git a/frappe/desk/doctype/system_console/__init__.py b/frappe/desk/doctype/system_console/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/desk/doctype/system_console/system_console.js b/frappe/desk/doctype/system_console/system_console.js new file mode 100644 index 0000000000..20c1257c10 --- /dev/null +++ b/frappe/desk/doctype/system_console/system_console.js @@ -0,0 +1,8 @@ +// Copyright (c) 2020, Frappe Technologies and contributors +// For license information, please see license.txt + +frappe.ui.form.on('System Console', { + // refresh: function(frm) { + + // } +}); diff --git a/frappe/desk/doctype/system_console/system_console.json b/frappe/desk/doctype/system_console/system_console.json new file mode 100644 index 0000000000..8c56792abb --- /dev/null +++ b/frappe/desk/doctype/system_console/system_console.json @@ -0,0 +1,66 @@ +{ + "actions": [ + { + "action": "#List/Console Log/List", + "action_type": "Route", + "label": "Logs" + }, + { + "action": "frappe.desk.doctype.system_console.system_console.execute_code", + "action_type": "Server Action", + "label": "Execute" + } + ], + "creation": "2020-08-18 17:44:35.647815", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "console", + "commit", + "output" + ], + "fields": [ + { + "description": "To print output use log(text)", + "fieldname": "console", + "fieldtype": "Code", + "label": "Console" + }, + { + "fieldname": "output", + "fieldtype": "Code", + "label": "Output", + "read_only": 1 + }, + { + "default": "0", + "fieldname": "commit", + "fieldtype": "Check", + "label": "Commit" + } + ], + "hide_toolbar": 1, + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2020-08-18 20:05:36.936664", + "modified_by": "Administrator", + "module": "Desk", + "name": "System Console", + "owner": "Administrator", + "permissions": [ + { + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/frappe/desk/doctype/system_console/system_console.py b/frappe/desk/doctype/system_console/system_console.py new file mode 100644 index 0000000000..3d7b3db2c2 --- /dev/null +++ b/frappe/desk/doctype/system_console/system_console.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals + +import json + +import frappe +from frappe.utils.safe_exec import safe_exec +from frappe.model.document import Document + +class SystemConsole(Document): + pass + +@frappe.whitelist() +def execute_code(doc): + doc = json.loads(doc) + frappe.only_for('System Manager') + try: + frappe.debug_log = [] + safe_exec(doc['console']) + doc['output'] = '\n'.join(frappe.debug_log) + except: + doc['output'] = frappe.get_traceback() + + if doc.get('commit'): + frappe.db.commit() + else: + frappe.db.rollback() + + frappe.get_doc(dict(doctype='Console Log', script=doc['console'], output=doc['output'])).insert() + frappe.db.commit() + + + return doc \ No newline at end of file diff --git a/frappe/desk/doctype/system_console/test_system_console.py b/frappe/desk/doctype/system_console/test_system_console.py new file mode 100644 index 0000000000..2635b5a210 --- /dev/null +++ b/frappe/desk/doctype/system_console/test_system_console.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestSystemConsole(unittest.TestCase): + pass diff --git a/frappe/model/__init__.py b/frappe/model/__init__.py index e59d325c9a..c39a73ccd7 100644 --- a/frappe/model/__init__.py +++ b/frappe/model/__init__.py @@ -134,7 +134,8 @@ log_types = ( 'Notification Log', 'Email Queue', 'DocShare', - 'Document Follow' + 'Document Follow', + 'Console Log' ) def delete_fields(args_dict, delete=0): diff --git a/frappe/model/naming.py b/frappe/model/naming.py index ffaf84e2b3..f2c918113b 100644 --- a/frappe/model/naming.py +++ b/frappe/model/naming.py @@ -142,6 +142,8 @@ def parse_naming_series(parts, doctype='', doc=''): part = today.strftime("%d") elif e == 'YYYY': part = today.strftime('%Y') + elif e == 'timestamp': + part = str(today) elif e == 'FY': part = frappe.defaults.get_user_default("fiscal_year") elif e.startswith('{') and doc: diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index ff48ad2f60..d417d37c08 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -323,12 +323,22 @@ frappe.ui.form.Form = class FrappeForm { if (!this.is_new()) { this.add_custom_button(action.label, () => { if (action.action_type==='Server Action') { - frappe.xcall(action.action, {doc: this.doc}).then(() => { + frappe.xcall(action.action, {doc: this.doc}).then((doc) => { + if (doc.doctype) { + // document is returned by the method, + // apply the changes locally and refresh + frappe.model.sync(doc); + this.refresh(); + } + + // feedback frappe.msgprint({ message: __('{} Complete', [action.label]), alert: true }); }); + } else if (action.action_type==='Route') { + frappe.set_route(action.action); } }, action.group); } diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index c95b7e4699..548bd0baf7 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -48,6 +48,7 @@ def get_safe_globals(): # make available limited methods of frappe json=json, dict=dict, + log=frappe.log, _dict=frappe._dict, frappe=frappe._dict( flags=frappe.flags, From 12be3d26ff26fa798000504547325251e474820a Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 21 Aug 2020 15:03:57 +0530 Subject: [PATCH 02/10] fix(minor): primary button --- .../doctype_action/doctype_action.json | 11 +++- .../doctype/system_console/system_console.js | 9 ++- .../system_console/system_console.json | 3 +- frappe/public/js/frappe/form/form.js | 60 ++++++++++++------- 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/frappe/core/doctype/doctype_action/doctype_action.json b/frappe/core/doctype/doctype_action/doctype_action.json index 87ee6fc12f..0f9da802eb 100644 --- a/frappe/core/doctype/doctype_action/doctype_action.json +++ b/frappe/core/doctype/doctype_action/doctype_action.json @@ -8,7 +8,8 @@ "label", "action_type", "action", - "group" + "group", + "hidden" ], "fields": [ { @@ -41,12 +42,18 @@ "in_list_view": 1, "label": "Action / Route", "reqd": 1 + }, + { + "default": "0", + "fieldname": "hidden", + "fieldtype": "Check", + "label": "Hidden" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-08-18 20:03:42.479436", + "modified": "2020-08-21 14:44:03.845315", "modified_by": "Administrator", "module": "Core", "name": "DocType Action", diff --git a/frappe/desk/doctype/system_console/system_console.js b/frappe/desk/doctype/system_console/system_console.js index 20c1257c10..0aae8bd519 100644 --- a/frappe/desk/doctype/system_console/system_console.js +++ b/frappe/desk/doctype/system_console/system_console.js @@ -2,7 +2,10 @@ // For license information, please see license.txt frappe.ui.form.on('System Console', { - // refresh: function(frm) { - - // } + refresh: function(frm) { + frm.disable_save(); + frm.page.set_primary_action(__("Execute"), () => { + frm.execute_action('Execute'); + }); + } }); diff --git a/frappe/desk/doctype/system_console/system_console.json b/frappe/desk/doctype/system_console/system_console.json index 8c56792abb..296647a17a 100644 --- a/frappe/desk/doctype/system_console/system_console.json +++ b/frappe/desk/doctype/system_console/system_console.json @@ -8,6 +8,7 @@ { "action": "frappe.desk.doctype.system_console.system_console.execute_code", "action_type": "Server Action", + "hidden": 1, "label": "Execute" } ], @@ -44,7 +45,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2020-08-18 20:05:36.936664", + "modified": "2020-08-21 14:44:35.296877", "modified_by": "Administrator", "module": "Desk", "name": "System Console", diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index d417d37c08..9e221f7131 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -321,32 +321,52 @@ frappe.ui.form.Form = class FrappeForm { for (let action of this.meta.actions) { frappe.ui.form.on(this.doctype, 'refresh', () => { if (!this.is_new()) { - this.add_custom_button(action.label, () => { - if (action.action_type==='Server Action') { - frappe.xcall(action.action, {doc: this.doc}).then((doc) => { - if (doc.doctype) { - // document is returned by the method, - // apply the changes locally and refresh - frappe.model.sync(doc); - this.refresh(); - } - - // feedback - frappe.msgprint({ - message: __('{} Complete', [action.label]), - alert: true - }); - }); - } else if (action.action_type==='Route') { - frappe.set_route(action.action); - } - }, action.group); + if (!action.hidden) { + this.add_custom_button(action.label, () => { + this.execute_action(action); + }, action.group); + } } }); } } } + execute_action(action) { + if (typeof action === 'string') { + // called by label - maybe via custom script + // frm.execute_action('Action') + for (let _action of this.meta.actions) { + if (_action.label === action) { + action = _action; + break; + } + } + + if (typeof action === 'string') { + frappe.throw(`Action ${action} not found`); + } + } + if (action.action_type==='Server Action') { + frappe.xcall(action.action, {doc: this.doc}).then((doc) => { + if (doc.doctype) { + // document is returned by the method, + // apply the changes locally and refresh + frappe.model.sync(doc); + this.refresh(); + } + + // feedback + frappe.msgprint({ + message: __('{} Complete', [action.label]), + alert: true + }); + }); + } else if (action.action_type==='Route') { + frappe.set_route(action.action); + } + } + switch_doc(docname) { // record switch if(this.docname != docname && (!this.meta.in_dialog || this.in_form) && !this.meta.istable) { From 5a61558820d1c05892c27320a6b455b112aefbd5 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 24 Aug 2020 17:45:20 +0530 Subject: [PATCH 03/10] fix(minor): return value in frappe.flags --- frappe/core/doctype/server_script/server_script.json | 7 ++++--- frappe/core/doctype/server_script/server_script.py | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/server_script/server_script.json b/frappe/core/doctype/server_script/server_script.json index 3ed4076430..cc3995ad1d 100644 --- a/frappe/core/doctype/server_script/server_script.json +++ b/frappe/core/doctype/server_script/server_script.json @@ -7,12 +7,12 @@ "engine": "InnoDB", "field_order": [ "script_type", - "disabled", - "column_break_3", "reference_doctype", "doctype_event", "api_method", "allow_guest", + "column_break_3", + "disabled", "section_break_8", "script", "help_section", @@ -85,8 +85,9 @@ "fieldtype": "HTML" } ], + "index_web_pages_for_search": 1, "links": [], - "modified": "2020-08-07 13:13:02.483963", + "modified": "2020-08-24 16:44:41.060350", "modified_by": "Administrator", "module": "Core", "name": "Server Script", diff --git a/frappe/core/doctype/server_script/server_script.py b/frappe/core/doctype/server_script/server_script.py index 539ae8eb01..55d7a33b8c 100644 --- a/frappe/core/doctype/server_script/server_script.py +++ b/frappe/core/doctype/server_script/server_script.py @@ -25,6 +25,7 @@ class ServerScript(Document): if frappe.session.user == 'Guest' and not self.allow_guest: raise frappe.PermissionError safe_exec(self.script) + return frappe.flags # output can be stored in flags else: # wrong report type! raise frappe.DoesNotExistError From 079a0e4af0fb38d8773b4f0d6669cbd090cba26e Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 25 Aug 2020 11:14:03 +0530 Subject: [PATCH 04/10] wip: refactor System Console --- .../doctype/system_console/system_console.py | 42 ++++++++++--------- frappe/utils/safe_exec.py | 8 +++- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/frappe/desk/doctype/system_console/system_console.py b/frappe/desk/doctype/system_console/system_console.py index 3d7b3db2c2..2715cd1425 100644 --- a/frappe/desk/doctype/system_console/system_console.py +++ b/frappe/desk/doctype/system_console/system_console.py @@ -11,26 +11,28 @@ from frappe.utils.safe_exec import safe_exec from frappe.model.document import Document class SystemConsole(Document): - pass + def run(self): + frappe.only_for('System Manager') + try: + frappe.debug_log = [] + safe_exec(self.console) + self.output = '\n'.join(frappe.debug_log) + except: + self.output = frappe.get_traceback() + + if self.commit: + frappe.db.commit() + else: + frappe.db.rollback() + + frappe.get_doc(dict( + doctype='Console Log', + script=self.console, + output=self.output)).insert() + frappe.db.commit() @frappe.whitelist() def execute_code(doc): - doc = json.loads(doc) - frappe.only_for('System Manager') - try: - frappe.debug_log = [] - safe_exec(doc['console']) - doc['output'] = '\n'.join(frappe.debug_log) - except: - doc['output'] = frappe.get_traceback() - - if doc.get('commit'): - frappe.db.commit() - else: - frappe.db.rollback() - - frappe.get_doc(dict(doctype='Console Log', script=doc['console'], output=doc['output'])).insert() - frappe.db.commit() - - - return doc \ No newline at end of file + console = frappe.get_doc(json.loads(doc)) + console.run() + return console.as_dict() \ No newline at end of file diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 548bd0baf7..a070d287da 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -100,7 +100,8 @@ def get_safe_globals(): scrub=scrub, guess_mimetype=mimetypes.guess_type, html2text=html2text, - dev_server=1 if os.environ.get('DEV_SERVER', False) else 0 + dev_server=1 if os.environ.get('DEV_SERVER', False) else 0, + run_script=run_script ) add_module_properties(frappe.exceptions, out.frappe, lambda obj: inspect.isclass(obj) and issubclass(obj, Exception)) @@ -143,6 +144,11 @@ def read_sql(query, *args, **kwargs): else: raise frappe.PermissionError('Only SELECT SQL allowed in scripting') +def run_script(script): + '''run another server script''' + frappe.get_doc('Server Script', script).execute_method() + return frappe.flags + def _getitem(obj, key): # guard function for RestrictedPython # allow any key to be accessed as long as it does not start with underscore From 39e36e01cde80e37ba0e758f60b4492700dbd177 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 25 Aug 2020 15:09:33 +0530 Subject: [PATCH 05/10] fix(test): test for system console; --- .../doctype/system_console/test_system_console.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frappe/desk/doctype/system_console/test_system_console.py b/frappe/desk/doctype/system_console/test_system_console.py index 2635b5a210..55ef199122 100644 --- a/frappe/desk/doctype/system_console/test_system_console.py +++ b/frappe/desk/doctype/system_console/test_system_console.py @@ -3,8 +3,18 @@ # See license.txt from __future__ import unicode_literals -# import frappe +import frappe import unittest class TestSystemConsole(unittest.TestCase): - pass + def test_system_console(self): + system_console = frappe.get_doc('System Console') + system_console.console = 'log("hello")' + system_console.run() + + self.assertEqual(system_console.output, 'hello') + + system_console.console = 'log(frappe.db.get_value("DocType", "DocType", "module"))' + system_console.run() + + self.assertEqual(system_console.output, 'Core') From 5e4ee1a6bcfd77d10ace5b810d43244c25394fc7 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 31 Aug 2020 11:29:06 +0530 Subject: [PATCH 06/10] fix(minor): quote the column names in alter table --- frappe/database/postgres/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/database/postgres/schema.py b/frappe/database/postgres/schema.py index b5129b60bb..58153ca6ce 100644 --- a/frappe/database/postgres/schema.py +++ b/frappe/database/postgres/schema.py @@ -49,7 +49,7 @@ class PostgresTable(DBTable): elif col.fieldtype in ("Check"): using_clause = "USING {}::smallint".format(col.fieldname) - query.append("ALTER COLUMN {0} TYPE {1} {2}".format( + query.append("ALTER COLUMN `{0}` TYPE {1} {2}".format( col.fieldname, get_definition(col.fieldtype, precision=col.precision, length=col.length), using_clause) From a032e9fc3d0d87835f22d4a2990a57ad247244b5 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 31 Aug 2020 11:31:44 +0530 Subject: [PATCH 07/10] fix(flake8): ignore bare except --- frappe/desk/doctype/system_console/system_console.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/desk/doctype/system_console/system_console.py b/frappe/desk/doctype/system_console/system_console.py index 2715cd1425..6c87ca8c36 100644 --- a/frappe/desk/doctype/system_console/system_console.py +++ b/frappe/desk/doctype/system_console/system_console.py @@ -17,7 +17,7 @@ class SystemConsole(Document): frappe.debug_log = [] safe_exec(self.console) self.output = '\n'.join(frappe.debug_log) - except: + except: # noqa: E722 self.output = frappe.get_traceback() if self.commit: From c53813950fde81bd884f601690a9c5c15c070c1c Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 1 Sep 2020 12:59:22 +0530 Subject: [PATCH 08/10] fix(minor): Server Script can return values in frappe.flags --- frappe/core/doctype/server_script/server_script.py | 4 ++-- .../core/doctype/server_script/test_server_script.py | 12 ++++++++++++ frappe/utils/safe_exec.py | 5 +++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/frappe/core/doctype/server_script/server_script.py b/frappe/core/doctype/server_script/server_script.py index 55d7a33b8c..839b784651 100644 --- a/frappe/core/doctype/server_script/server_script.py +++ b/frappe/core/doctype/server_script/server_script.py @@ -24,8 +24,8 @@ class ServerScript(Document): # validate if guest is allowed if frappe.session.user == 'Guest' and not self.allow_guest: raise frappe.PermissionError - safe_exec(self.script) - return frappe.flags # output can be stored in flags + _globals, _locals = safe_exec(self.script) + return _globals.frappe.flags # output can be stored in flags else: # wrong report type! raise frappe.DoesNotExistError diff --git a/frappe/core/doctype/server_script/test_server_script.py b/frappe/core/doctype/server_script/test_server_script.py index 5c12858e8a..3356e584af 100644 --- a/frappe/core/doctype/server_script/test_server_script.py +++ b/frappe/core/doctype/server_script/test_server_script.py @@ -36,6 +36,15 @@ if "validate" in doc.description: allow_guest = 1, script = ''' frappe.response['message'] = 'hello' +''' + ), + dict( + name='test_return_value', + script_type = 'API', + api_method = 'test_return_value', + allow_guest = 1, + script = ''' +frappe.flags = 'hello' ''' ) ] @@ -73,3 +82,6 @@ class TestServerScript(unittest.TestCase): response = requests.post(get_site_url(frappe.local.site) + "/api/method/test_server_script") self.assertEqual(response.status_code, 200) self.assertEqual("hello", response.json()["message"]) + + def test_api_return(self): + self.assertEqual(frappe.get_doc('Server Script', 'test_return_value').execute_method(), 'hello') diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index a070d287da..56c5fe90c8 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -28,6 +28,8 @@ def safe_exec(script, _globals=None, _locals=None): # execute script compiled by RestrictedPython exec(compile_restricted(script), exec_globals, _locals) # pylint: disable=exec-used + return exec_globals, _locals + def get_safe_globals(): datautils = frappe._dict() if frappe.db: @@ -146,8 +148,7 @@ def read_sql(query, *args, **kwargs): def run_script(script): '''run another server script''' - frappe.get_doc('Server Script', script).execute_method() - return frappe.flags + return frappe.get_doc('Server Script', script).execute_method() def _getitem(obj, key): # guard function for RestrictedPython From 3eb0e5ce8a88f39bc79f61415f2af6bc0a7c45e2 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 2 Sep 2020 09:21:24 +0530 Subject: [PATCH 09/10] Update frappe/desk/doctype/system_console/system_console.js Co-authored-by: Aditya Hase --- frappe/desk/doctype/system_console/system_console.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/frappe/desk/doctype/system_console/system_console.js b/frappe/desk/doctype/system_console/system_console.js index 0aae8bd519..c7eac39490 100644 --- a/frappe/desk/doctype/system_console/system_console.js +++ b/frappe/desk/doctype/system_console/system_console.js @@ -2,6 +2,16 @@ // For license information, please see license.txt frappe.ui.form.on('System Console', { + onload: function(frm) { + frappe.ui.keys.add_shortcut({ + shortcut: 'shift+enter', + action: () => frm.execute_action('Execute'), + page: frm.page, + description: __('Execute Console script'), + ignore_inputs: true, + }); + }, + refresh: function(frm) { frm.disable_save(); frm.page.set_primary_action(__("Execute"), () => { From ac76c551600408f2020c192ceb4dfa1016746ccf Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 2 Sep 2020 09:22:28 +0530 Subject: [PATCH 10/10] Update frappe/desk/doctype/system_console/system_console.json Co-authored-by: Aditya Hase --- frappe/desk/doctype/system_console/system_console.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frappe/desk/doctype/system_console/system_console.json b/frappe/desk/doctype/system_console/system_console.json index 296647a17a..14e36e6fd3 100644 --- a/frappe/desk/doctype/system_console/system_console.json +++ b/frappe/desk/doctype/system_console/system_console.json @@ -26,7 +26,8 @@ "description": "To print output use log(text)", "fieldname": "console", "fieldtype": "Code", - "label": "Console" + "label": "Console", + "options": "Python" }, { "fieldname": "output", @@ -64,4 +65,4 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 1 -} \ No newline at end of file +}