From 55e2af20c66b7bf490ae3c4cfb5d3f4d58e885ca Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 7 Sep 2021 17:51:46 +0530 Subject: [PATCH 01/80] feat: Enhancements in Server Script --- frappe/utils/safe_exec.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 2e27859faa..3fb55af926 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -111,6 +111,7 @@ def get_safe_globals(): get_hooks=frappe.get_hooks, sanitize_html=frappe.utils.sanitize_html, log_error=frappe.log_error + cache=frappe.cache ), FrappeClient=FrappeClient, style=frappe._dict( @@ -141,7 +142,8 @@ def get_safe_globals(): get_single_value = frappe.db.get_single_value, get_default = frappe.db.get_default, escape = frappe.db.escape, - sql = read_sql + sql = read_sql, + commit = frappe.db.commit ) if frappe.response: From a1251aace99bef5166925e79926a146f79bd7cb6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 7 Sep 2021 18:29:04 +0530 Subject: [PATCH 02/80] fix: Syntax Error --- frappe/utils/safe_exec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 3fb55af926..983e4aabf8 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -110,7 +110,7 @@ def get_safe_globals(): socketio_port=frappe.conf.socketio_port, get_hooks=frappe.get_hooks, sanitize_html=frappe.utils.sanitize_html, - log_error=frappe.log_error + log_error=frappe.log_error, cache=frappe.cache ), FrappeClient=FrappeClient, From dd563001096f957722f708e829cfe5c28a802d21 Mon Sep 17 00:00:00 2001 From: leela Date: Wed, 22 Sep 2021 18:20:57 +0530 Subject: [PATCH 03/80] fix: date mismatches while displaying in short form --- frappe/public/js/frappe/utils/pretty_date.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frappe/public/js/frappe/utils/pretty_date.js b/frappe/public/js/frappe/utils/pretty_date.js index 84fd276068..3ebe2c1ae2 100644 --- a/frappe/public/js/frappe/utils/pretty_date.js +++ b/frappe/public/js/frappe/utils/pretty_date.js @@ -25,11 +25,11 @@ function prettyDate(date, mini) { if (day_diff < 7) { return __("{0} d", [day_diff]); } else if (day_diff < 31) { - return __("{0} w", [Math.ceil(day_diff / 7)]); + return __("{0} w", [Math.floor(day_diff / 7)]); } else if (day_diff < 365) { - return __("{0} M", [Math.ceil(day_diff / 30)]); + return __("{0} M", [Math.floor(day_diff / 30)]); } else { - return __("{0} y", [Math.ceil(day_diff / 365)]); + return __("{0} y", [Math.floor(day_diff / 365)]); } } } else { @@ -54,15 +54,15 @@ function prettyDate(date, mini) { } else if (day_diff < 14) { return __("1 week ago"); } else if (day_diff < 31) { - return __("{0} weeks ago", [Math.ceil(day_diff / 7)]); + return __("{0} weeks ago", [Math.floor(day_diff / 7)]); } else if (day_diff < 62) { return __("1 month ago"); } else if (day_diff < 365) { - return __("{0} months ago", [Math.ceil(day_diff / 30)]); + return __("{0} months ago", [Math.floor(day_diff / 30)]); } else if (day_diff < 730) { return __("1 year ago"); } else { - return __("{0} years ago", [Math.ceil(day_diff / 365)]); + return __("{0} years ago", [Math.floor(day_diff / 365)]); } } } From dffd78d3fca385dc4e5ee536beae93099746cdff Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 27 Sep 2021 12:02:31 +0530 Subject: [PATCH 04/80] fix: Validate server script for doc events --- frappe/core/doctype/server_script/server_script.py | 9 +++++++++ frappe/utils/safe_exec.py | 10 ++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/server_script/server_script.py b/frappe/core/doctype/server_script/server_script.py index 79fe7a9140..8aa2dd0bae 100644 --- a/frappe/core/doctype/server_script/server_script.py +++ b/frappe/core/doctype/server_script/server_script.py @@ -11,6 +11,8 @@ from frappe.model.document import Document from frappe.utils.safe_exec import get_safe_globals, safe_exec, NamespaceDict from frappe import _ +import re + class ServerScript(Document): def validate(self): @@ -94,8 +96,15 @@ class ServerScript(Document): Args: doc (Document): Executes script with for a certain document's events """ + self.validate_script_for_doc_events() safe_exec(self.script, _locals={"doc": doc}) + def validate_script_for_doc_events(self): + for line in self.script.splitlines(): + line = line.strip() + if not line.startswith('#') and "frappe.db.commit()" in line: + frappe.throw(_("Commit cannot be used in DocType Event server script")) + def execute_scheduled_method(self): """Specific to Scheduled Jobs via Server Scripts diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 1c09a17a66..6f9398745e 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -116,8 +116,7 @@ def get_safe_globals(): socketio_port=frappe.conf.socketio_port, get_hooks=frappe.get_hooks, sanitize_html=frappe.utils.sanitize_html, - log_error=frappe.log_error, - cache=frappe.cache + log_error=frappe.log_error ), FrappeClient=FrappeClient, style=frappe._dict( @@ -157,6 +156,13 @@ def get_safe_globals(): commit = frappe.db.commit ) + out.frappe.cache = NamespaceDict( + get_value = frappe.cache().get_value, + set_value = frappe.cache().set_value, + hset = frappe.cache().hset, + hget = frappe.cache().hget + ) + if frappe.response: out.frappe.response = frappe.response From 6ab38e5d65406f927bfee1eeb708ae553a0f962d Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 27 Sep 2021 12:09:32 +0530 Subject: [PATCH 05/80] fix: Linting Issues --- frappe/core/doctype/server_script/server_script.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/frappe/core/doctype/server_script/server_script.py b/frappe/core/doctype/server_script/server_script.py index 8aa2dd0bae..03b33443eb 100644 --- a/frappe/core/doctype/server_script/server_script.py +++ b/frappe/core/doctype/server_script/server_script.py @@ -11,8 +11,6 @@ from frappe.model.document import Document from frappe.utils.safe_exec import get_safe_globals, safe_exec, NamespaceDict from frappe import _ -import re - class ServerScript(Document): def validate(self): From e13f99dcb1577a7bfaa26f206be4eb0389c7786f Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 27 Sep 2021 12:56:08 +0530 Subject: [PATCH 06/80] test: Check for doc event validations and cache methods --- .../doctype/server_script/server_script.py | 4 +- .../server_script/test_server_script.py | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/frappe/core/doctype/server_script/server_script.py b/frappe/core/doctype/server_script/server_script.py index 03b33443eb..14f173f906 100644 --- a/frappe/core/doctype/server_script/server_script.py +++ b/frappe/core/doctype/server_script/server_script.py @@ -11,6 +11,8 @@ from frappe.model.document import Document from frappe.utils.safe_exec import get_safe_globals, safe_exec, NamespaceDict from frappe import _ +class CommitNotAllowed(frappe.ValidationError): + pass class ServerScript(Document): def validate(self): @@ -101,7 +103,7 @@ class ServerScript(Document): for line in self.script.splitlines(): line = line.strip() if not line.startswith('#') and "frappe.db.commit()" in line: - frappe.throw(_("Commit cannot be used in DocType Event server script")) + frappe.throw(_("Commit cannot be used in DocType Event server script"), CommitNotAllowed) def execute_scheduled_method(self): """Specific to Scheduled Jobs via Server Scripts diff --git a/frappe/core/doctype/server_script/test_server_script.py b/frappe/core/doctype/server_script/test_server_script.py index 6c028ff136..cf49430ff4 100644 --- a/frappe/core/doctype/server_script/test_server_script.py +++ b/frappe/core/doctype/server_script/test_server_script.py @@ -5,6 +5,7 @@ import frappe import unittest import requests from frappe.utils import get_site_url +from frappe.core.doctype.server_script.server_script import CommitNotAllowed scripts = [ dict( @@ -59,6 +60,26 @@ conditions = '1 = 1' reference_doctype = 'Note', script = ''' frappe.method_that_doesnt_exist("do some magic") +''' + ), + dict( + name='test_todo_commit', + script_type = 'DocType Event', + doctype_event = 'Before Save', + reference_doctype = 'ToDo', + disabled = 1, + script = ''' +frappe.db.commit() +''' + ), + dict( + name='test_cache_methods', + script_type = 'DocType Event', + doctype_event = 'Before Save', + reference_doctype = 'ToDo', + disabled = 1, + script = ''' +frappe.cache.set_value('test_key', doc.name) ''' ) ] @@ -119,3 +140,24 @@ class TestServerScript(unittest.TestCase): self.assertTrue("invalid python code" in str(se.exception).lower(), msg="Python code validation not working") + + def test_commit_in_doctype_event(self): + server_script = frappe.get_doc('Server Script', 'test_todo_commit') + server_script.disabled = 0 + server_script.save() + + self.assertRaises(CommitNotAllowed, frappe.get_doc(dict(doctype='ToDo', description='test me')).insert) + + server_script.disabled = 1 + server_script.save() + + def test_cache_methods_in_server_script(self): + server_script = frappe.get_doc('Server Script', 'test_cache_methods') + server_script.disabled = 0 + server_script.save() + + todo = frappe.get_doc(dict(doctype='ToDo', description='test me')).insert() + self.assertEqual(todo.name, frappe.cache().get_value('test_key')) + + server_script.disabled = 1 + server_script.save() From bfc68bdd956e33e9bc2839d3d37fa83bcf0b6392 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Tue, 28 Sep 2021 16:35:13 +0530 Subject: [PATCH 07/80] fix: Hide Show Filter if there is no saved filters --- frappe/public/js/frappe/list/list_filter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frappe/public/js/frappe/list/list_filter.js b/frappe/public/js/frappe/list/list_filter.js index 4c5a1da319..a3eadea8b3 100644 --- a/frappe/public/js/frappe/list/list_filter.js +++ b/frappe/public/js/frappe/list/list_filter.js @@ -26,6 +26,7 @@ export default class ListFilter { this.$input_area = this.wrapper.find('.input-area'); this.$list_filters = this.wrapper.find('.list-filters'); this.$saved_filters = this.wrapper.find('.saved-filters').hide(); + this.$saved_filters_preview = this.wrapper.find('.saved-filters-preview'); this.saved_filters_hidden = true; this.filter_input = frappe.ui.form.make_control({ @@ -57,6 +58,7 @@ export default class ListFilter { refresh() { this.get_list_filters().then(() => { + this.filters.length ? this.$saved_filters_preview.show() : this.$saved_filters_preview.hide(); const html = this.filters.map((filter) => this.filter_template(filter)); this.wrapper.find('.filter-pill').remove(); this.$saved_filters.append(html); From 624cd3a04cac9c69ed2ff95b65e5cc39c0e9cdd5 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Thu, 30 Sep 2021 16:21:20 +0530 Subject: [PATCH 08/80] fix: Scrollbar is hidden when search modal is minimized --- frappe/public/js/frappe/ui/dialog.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/ui/dialog.js b/frappe/public/js/frappe/ui/dialog.js index 58175381cf..b1a22c8929 100644 --- a/frappe/public/js/frappe/ui/dialog.js +++ b/frappe/public/js/frappe/ui/dialog.js @@ -78,6 +78,8 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { this.$wrapper .on("hide.bs.modal", function() { me.display = false; + me.is_minimized = false; + me.hide_scrollbar(false); if(frappe.ui.open_dialogs[frappe.ui.open_dialogs.length-1]===me) { frappe.ui.open_dialogs.pop(); @@ -96,6 +98,7 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { window.cur_dialog = me; frappe.ui.open_dialogs.push(me); me.focus_on_first_input(); + me.hide_scrollbar(true); me.on_page_show && me.on_page_show(); $(document).trigger('frappe.ui.Dialog:shown'); $(document).off('focusin.modal'); @@ -233,7 +236,11 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { this.get_minimize_btn().html(frappe.utils.icon(icon)); this.on_minimize_toggle && this.on_minimize_toggle(this.is_minimized); this.header.find('.modal-title').toggleClass('cursor-pointer'); - $("body").css("overflow", this.is_minimized ? "auto" : "hidden"); + this.hide_scrollbar(!this.is_minimized); + } + + hide_scrollbar(bool) { + $("body").css("overflow", bool ? "hidden" : "auto"); } add_custom_action(label, action, css_class=null) { From 4ebdabda485e19777bb64613d9eb0fefa3c76b27 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 4 Oct 2021 10:59:47 +0530 Subject: [PATCH 09/80] fix: Encapsulate cache methods --- .../doctype/server_script/test_server_script.py | 2 +- frappe/utils/safe_exec.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/frappe/core/doctype/server_script/test_server_script.py b/frappe/core/doctype/server_script/test_server_script.py index cf49430ff4..a3de577ef2 100644 --- a/frappe/core/doctype/server_script/test_server_script.py +++ b/frappe/core/doctype/server_script/test_server_script.py @@ -79,7 +79,7 @@ frappe.db.commit() reference_doctype = 'ToDo', disabled = 1, script = ''' -frappe.cache.set_value('test_key', doc.name) +frappe.cache().set_value('test_key', doc.name) ''' ) ] diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 6f9398745e..79a103c9b3 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -156,12 +156,7 @@ def get_safe_globals(): commit = frappe.db.commit ) - out.frappe.cache = NamespaceDict( - get_value = frappe.cache().get_value, - set_value = frappe.cache().set_value, - hset = frappe.cache().hset, - hget = frappe.cache().hget - ) + out.frappe.cache = cache if frappe.response: out.frappe.response = frappe.response @@ -180,6 +175,14 @@ def get_safe_globals(): return out +def cache(): + return NamespaceDict( + get_value = frappe.cache().get_value, + set_value = frappe.cache().set_value, + hset = frappe.cache().hset, + hget = frappe.cache().hget + ) + def read_sql(query, *args, **kwargs): '''a wrapper for frappe.db.sql to allow reads''' if query.strip().split(None, 1)[0].lower() == 'select': From 5f83045baf70936fd3291784d70819fd442b6249 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 4 Oct 2021 12:26:12 +0530 Subject: [PATCH 10/80] feat: single thread discussions --- frappe/templates/discussions/comment_box.html | 3 +-- frappe/templates/discussions/discussions.js | 25 ++++++++++++------- .../discussions/discussions_section.html | 17 +++++++------ .../web_template/discussions/discussions.json | 11 ++++++-- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/frappe/templates/discussions/comment_box.html b/frappe/templates/discussions/comment_box.html index cbdc3ad3e5..ebaa37f772 100644 --- a/frappe/templates/discussions/comment_box.html +++ b/frappe/templates/discussions/comment_box.html @@ -25,8 +25,7 @@ {{ _("Cancel") }} -
+
{{ _("Post") }}
diff --git a/frappe/templates/discussions/discussions.js b/frappe/templates/discussions/discussions.js index becc50410d..8b36d0846c 100644 --- a/frappe/templates/discussions/discussions.js +++ b/frappe/templates/discussions/discussions.js @@ -87,12 +87,17 @@ const setup_socket_io = () => { }; const publish_message = (data) => { + const doctype = decodeURIComponent($(".discussions-parent .thread-card").attr("data-doctype")); + const docname = decodeURIComponent($(".discussions-parent .thread-card").attr("data-docname")); + const topic = data.topic_info; + + if ($(`.discussion-on-page[data-topic=${topic.name}]`).length) { - if ($(`.discussion-on-page[data-topic=${data.topic_info.name}]`).length) { post_message_cleanup(); - $('
' + data.template).insertBefore(`.discussion-on-page[data-topic=${data.topic_info.name}] .discussion-form`); - } else if ((decodeURIComponent($(".discussions-parent .discussions-card").attr("data-doctype")) == data.topic_info.reference_doctype - && decodeURIComponent($(".discussions-parent .discussions-card").attr("data-docname")) == data.topic_info.reference_docname)) { + $('
' + data.template) + .insertBefore(`.discussion-on-page[data-topic=${topic.name}] .discussion-form`); + + } else if (doctype == topic.reference_doctype && docname == topic.reference_docname) { post_message_cleanup(); data.new_topic_template = style_avatar_frame(data.new_topic_template); @@ -100,16 +105,18 @@ const publish_message = (data) => { $(data.sidebar).insertAfter(`.discussions-sidebar .form-group`); $(`#discussion-group`).prepend(data.new_topic_template); - if (data.topic_info.owner == frappe.session.user) { + if (topic.owner == frappe.session.user) { $(".discussion-on-page").collapse(); $(".sidebar-topic").first().click(); } - } else if (data.topic_info.owner == frappe.session.user) { + + } else if (topic.owner == frappe.session.user + && doctype == topic.reference_docname && docname == topic.reference_docname) { post_message_cleanup(); window.location.reload(); } - update_reply_count(data.topic_info.name); + update_reply_count(topic.name); }; const post_message_cleanup = () => { @@ -191,10 +198,10 @@ const submit_discussion = (e) => { const reply = $(".comment-field:visible").val().trim(); if (reply) { - let doctype = $(e.currentTarget).attr("data-doctype"); + let doctype = $(e.currentTarget).closest(".thread-card").attr("data-doctype"); doctype = doctype ? decodeURIComponent(doctype) : doctype; - let docname = $(e.currentTarget).attr("data-docname"); + let docname = $(e.currentTarget).closest(".thread-card").attr("data-docname"); docname = docname ? decodeURIComponent(docname) : docname; frappe.call({ diff --git a/frappe/templates/discussions/discussions_section.html b/frappe/templates/discussions/discussions_section.html index 65e1730bc7..b9fa80fe4f 100644 --- a/frappe/templates/discussions/discussions_section.html +++ b/frappe/templates/discussions/discussions_section.html @@ -11,10 +11,10 @@ {% endif %} - {% if topics %} -
+
+ {% if topics %}
{% include "frappe/templates/discussions/search.html" %} {% for topic in topics %} @@ -26,11 +26,14 @@
{% include "frappe/templates/discussions/reply_section.html" %}
-
- {% else %} -
-
+ {% elif not topics and single_thread %} +
+ {% include "frappe/templates/discussions/comment_box.html" %} +
+ + {% else %} +
No {{ title }}
There are no {{ title | lower }} for this {{ doctype | lower }}, why don't you start one!
diff --git a/frappe/website/web_template/discussions/discussions.json b/frappe/website/web_template/discussions/discussions.json index 8856787828..c8c90e08aa 100644 --- a/frappe/website/web_template/discussions/discussions.json +++ b/frappe/website/web_template/discussions/discussions.json @@ -22,10 +22,17 @@ "label": "Web Page", "options": "Web Page", "reqd": 1 + }, + { + "__unsaved": 1, + "fieldname": "single_thread", + "fieldtype": "Check", + "label": "Single Thread", + "reqd": 0 } ], "idx": 0, - "modified": "2021-10-01 12:15:28.876920", + "modified": "2021-10-01 15:15:57.366552", "modified_by": "Administrator", "module": "Website", "name": "Discussions", @@ -33,4 +40,4 @@ "standard": 1, "template": "", "type": "Section" -} +} \ No newline at end of file From 214e5b89d8e8b6dae140180addf2b79739d13c57 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 4 Oct 2021 20:56:44 +0530 Subject: [PATCH 11/80] fix: Filter pop-up overlaps the Notification Window --- frappe/public/scss/desk/filters.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/public/scss/desk/filters.scss b/frappe/public/scss/desk/filters.scss index 3680adcf5c..d7a7ffbee7 100644 --- a/frappe/public/scss/desk/filters.scss +++ b/frappe/public/scss/desk/filters.scss @@ -8,6 +8,7 @@ min-width: 500px; min-height: 50px; font-size: var(--text-md); + z-index: 1019; } .filter-area { From 9c00a288690d703c7f1478b4ec0b88055f4bf924 Mon Sep 17 00:00:00 2001 From: Aradhya-Tripathi Date: Tue, 5 Oct 2021 12:39:22 +0530 Subject: [PATCH 12/80] feat: Added safe_qb for server scripts --- frappe/utils/safe_exec.py | 52 ++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 0d1574b49a..a494df0e74 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -14,6 +14,8 @@ from frappe.www.printview import get_visible_columns import frappe.exceptions import frappe.integrations.utils from frappe.frappeclient import FrappeClient +from frappe.query_builder.utils import get_attr +from typing import get_type_hints class ServerScriptNotEnabled(frappe.PermissionError): pass @@ -29,6 +31,13 @@ class NamespaceDict(frappe._dict): return ret +query_class = get_attr(str(frappe.qb).split("'")[1]) +class SafeQb(query_class): + def __init__(self, *args, **kwargs): + _builder = get_type_hints(super()._builder).get('return') + _builder.run = read_sql + + def safe_exec(script, _globals=None, _locals=None): # server scripts can be disabled via site_config.json # they are enabled by default @@ -52,6 +61,7 @@ def safe_exec(script, _globals=None, _locals=None): def get_safe_globals(): datautils = frappe._dict() + safe_qb = SafeQb() if frappe.db: date_format = frappe.db.get_default("date_format") or "yyyy-mm-dd" time_format = frappe.db.get_default("time_format") or "HH:mm:ss" @@ -69,8 +79,8 @@ def get_safe_globals(): out = NamespaceDict( # make available limited methods of frappe json=NamespaceDict( - loads = json.loads, - dumps = json.dumps), + loads=json.loads, + dumps=json.dumps), dict=dict, log=frappe.log, _dict=frappe._dict, @@ -85,6 +95,7 @@ def get_safe_globals(): bold=frappe.bold, copy_doc=frappe.copy_doc, errprint=frappe.errprint, + qb=safe_qb, get_meta=frappe.get_meta, get_doc=frappe.get_doc, @@ -99,9 +110,9 @@ def get_safe_globals(): render_template=frappe.render_template, msgprint=frappe.msgprint, throw=frappe.throw, - sendmail = frappe.sendmail, - get_print = frappe.get_print, - attach_print = frappe.attach_print, + sendmail=frappe.sendmail, + get_print=frappe.get_print, + attach_print=frappe.attach_print, user=user, get_fullname=frappe.utils.get_fullname, @@ -112,8 +123,8 @@ def get_safe_globals(): user=user, csrf_token=frappe.local.session.data.csrf_token if getattr(frappe.local, "session", None) else '' ), - make_get_request = frappe.integrations.utils.make_get_request, - make_post_request = frappe.integrations.utils.make_post_request, + make_get_request=frappe.integrations.utils.make_get_request, + make_post_request=frappe.integrations.utils.make_post_request, socketio_port=frappe.conf.socketio_port, get_hooks=frappe.get_hooks, sanitize_html=frappe.utils.sanitize_html, @@ -141,19 +152,19 @@ def get_safe_globals(): out.frappe.date_format = date_format out.frappe.time_format = time_format out.frappe.db = NamespaceDict( - get_list = frappe.get_list, - get_all = frappe.get_all, - get_value = frappe.db.get_value, - set_value = frappe.db.set_value, - get_single_value = frappe.db.get_single_value, - get_default = frappe.db.get_default, - count = frappe.db.count, - min = frappe.db.min, - max = frappe.db.max, - avg = frappe.db.avg, - sum = frappe.db.sum, - escape = frappe.db.escape, - sql = read_sql + get_list=frappe.get_list, + get_all=frappe.get_all, + get_value=frappe.db.get_value, + set_value=frappe.db.set_value, + get_single_value=frappe.db.get_single_value, + get_default=frappe.db.get_default, + count=frappe.db.count, + min=frappe.db.min, + max=frappe.db.max, + avg=frappe.db.avg, + sum=frappe.db.sum, + escape=frappe.db.escape, + sql=read_sql ) if frappe.response: @@ -175,6 +186,7 @@ def get_safe_globals(): def read_sql(query, *args, **kwargs): '''a wrapper for frappe.db.sql to allow reads''' + query = str(query) if query.strip().split(None, 1)[0].lower() == 'select': return frappe.db.sql(query, *args, **kwargs) else: From 4e8f42288fd83f1fefb5e859f08307d832884ab3 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 5 Oct 2021 12:49:56 +0530 Subject: [PATCH 13/80] feat: single thread discussions --- frappe/templates/discussions/comment_box.html | 48 ++++++++++--------- frappe/templates/discussions/discussions.js | 25 ++++++---- .../discussions/discussions_section.html | 16 +++++-- .../templates/discussions/reply_section.html | 4 -- frappe/templates/styles/discussion_style.css | 2 +- .../discussion_reply/discussion_reply.py | 2 +- 6 files changed, 54 insertions(+), 43 deletions(-) diff --git a/frappe/templates/discussions/comment_box.html b/frappe/templates/discussions/comment_box.html index ebaa37f772..ab4714185a 100644 --- a/frappe/templates/discussions/comment_box.html +++ b/frappe/templates/discussions/comment_box.html @@ -1,31 +1,35 @@
-
-
-
- -
+ {% if not single_thread %} +
+
+
+
+
+ {% endif %} -
-
-
- -
+
+
+
+
+
-