From bf8d930d8e19f39433aa27c3827a20b1b6893ffb Mon Sep 17 00:00:00 2001 From: "Chinmay D. Pai" Date: Mon, 27 Apr 2020 18:21:53 +0530 Subject: [PATCH 01/14] fix: sanitize input before displaying search results Signed-off-by: Chinmay D. Pai --- frappe/templates/includes/search_template.html | 2 +- frappe/utils/safe_exec.py | 1 + frappe/www/search.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frappe/templates/includes/search_template.html b/frappe/templates/includes/search_template.html index 8ad73f836a..91a9a1dc47 100644 --- a/frappe/templates/includes/search_template.html +++ b/frappe/templates/includes/search_template.html @@ -28,7 +28,7 @@ {% if frappe.form_dict.scope %} - + {% endif %} diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index f80d819907..daae75228e 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -83,6 +83,7 @@ def get_safe_globals(): 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 ), style=frappe._dict( border_color='#d1d8dd' diff --git a/frappe/www/search.py b/frappe/www/search.py index 19df1e48e0..a8bb1a5294 100644 --- a/frappe/www/search.py +++ b/frappe/www/search.py @@ -13,7 +13,7 @@ def get_context(context): context.title = _('Search Results for ') context.query = query context.route = '/search' - context.update(get_search_results(query, frappe.form_dict.scope)) + context.update(get_search_results(query, frappe.utils.sanitize_html(frappe.form_dict.scope))) else: context.title = _('Search') From 0ff51a257d723ebd19bb89ca44f8b0644b4abcb8 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 6 May 2020 13:17:41 +0530 Subject: [PATCH 02/14] refactor: move dashboard utilities to frappe.utils --- frappe/desk/doctype/dashboard_chart/dashboard_chart.py | 2 +- frappe/{core/page/dashboard => utils}/dashboard.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename frappe/{core/page/dashboard => utils}/dashboard.py (100%) diff --git a/frappe/desk/doctype/dashboard_chart/dashboard_chart.py b/frappe/desk/doctype/dashboard_chart/dashboard_chart.py index 7ddb3d98f0..417ef2ba82 100644 --- a/frappe/desk/doctype/dashboard_chart/dashboard_chart.py +++ b/frappe/desk/doctype/dashboard_chart/dashboard_chart.py @@ -7,7 +7,7 @@ import frappe from frappe import _ import datetime import json -from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan +from frappe.utils.dashboard import cache_source, get_from_date_from_timespan from frappe.utils import nowdate, add_to_date, getdate, get_last_day, formatdate, get_datetime from frappe.model.naming import append_number_if_name_exists from frappe.boot import get_allowed_reports diff --git a/frappe/core/page/dashboard/dashboard.py b/frappe/utils/dashboard.py similarity index 100% rename from frappe/core/page/dashboard/dashboard.py rename to frappe/utils/dashboard.py From 52eee67217b4238886661d5664046d3a6d89958d Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 6 May 2020 14:44:41 +0530 Subject: [PATCH 03/14] feat: added sync dashboard utility --- frappe/utils/dashboard.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/frappe/utils/dashboard.py b/frappe/utils/dashboard.py index 17f46a24d2..43057be79a 100644 --- a/frappe/utils/dashboard.py +++ b/frappe/utils/dashboard.py @@ -4,8 +4,10 @@ from __future__ import unicode_literals import json import frappe from frappe import _ +import os from functools import wraps from frappe.utils import add_to_date, get_link_to_form +from frappe.modules.import_file import import_doc def cache_source(function): @@ -72,3 +74,38 @@ def get_from_date_from_timespan(to_date, timespan): years = -50 return add_to_date(to_date, years=years, months=months, days=days, as_datetime=True) + +def sync_dashboards(app=None): + """Import, overwrite fixtures from `[app]/fixtures`""" + if app: + apps = [app] + else: + apps = frappe.get_installed_apps() + + for app_name in apps: + print("Updating Dashboard for {app}".format(app=app_name)) + for module_name in frappe.local.app_modules.get(app_name) or []: + config = get_config(app_name, module_name) + if config: + frappe.flags.in_import = True + make_records(config.charts, "Dashboard Chart") + make_records(config.dashboards, "Dashboard") + frappe.flags.in_import = False + +def make_records(config, doctype): + if not config: + return + + for item in config: + item["doctype"] = doctype + import_doc(item) + frappe.db.commit() + +def get_config(app, module): + try: + module_dashboards = frappe.get_module('{app}.{module}.dashboard_fixtures'.format(app=app, module=module)) + if hasattr(module_dashboards, 'get_data'): + return frappe._dict(module_dashboards.get_data()) + return None + except ImportError: + return None From db152b28de1c7dee0cf11cbe353022ce9fb3c75e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 6 May 2020 14:45:07 +0530 Subject: [PATCH 04/14] feat: sync dashboards after setup and migrate --- frappe/desk/page/setup_wizard/install_fixtures.py | 3 ++- frappe/migrate.py | 3 +++ frappe/model/sync.py | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/frappe/desk/page/setup_wizard/install_fixtures.py b/frappe/desk/page/setup_wizard/install_fixtures.py index c857bd077f..6917ef0426 100644 --- a/frappe/desk/page/setup_wizard/install_fixtures.py +++ b/frappe/desk/page/setup_wizard/install_fixtures.py @@ -6,12 +6,14 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.desk.doctype.global_search_settings.global_search_settings import update_global_search_doctypes +from frappe.utils.dashboard import sync_dashboards def install(): update_genders() update_salutations() update_global_search_doctypes() setup_email_linking() + sync_dashboards() @frappe.whitelist() def update_genders(): @@ -35,4 +37,3 @@ def setup_email_linking(): "email_id": "email_linking@example.com", }) doc.insert(ignore_permissions=True, ignore_if_duplicate=True) - \ No newline at end of file diff --git a/frappe/migrate.py b/frappe/migrate.py index 043b6817d7..094abbe099 100644 --- a/frappe/migrate.py +++ b/frappe/migrate.py @@ -10,6 +10,7 @@ import frappe.translate import frappe.modules.patch_handler import frappe.model.sync from frappe.utils.fixtures import sync_fixtures +from frappe.utils.dashboard import sync_dashboards from frappe.cache_manager import clear_global_cache from frappe.desk.notifications import clear_notifications from frappe.website import render @@ -23,6 +24,7 @@ def migrate(verbose=True, rebuild_website=False, skip_failing=False): - run before migrate hooks - run patches - sync doctypes (schema) + - sync dashboards - sync fixtures - sync desktop icons - sync web pages (from /www) @@ -53,6 +55,7 @@ def migrate(verbose=True, rebuild_website=False, skip_failing=False): frappe.translate.clear_cache() sync_jobs() sync_fixtures() + sync_dashboards() sync_customizations() sync_languages() diff --git a/frappe/model/sync.py b/frappe/model/sync.py index c2acb59f63..c753f64e89 100644 --- a/frappe/model/sync.py +++ b/frappe/model/sync.py @@ -45,6 +45,8 @@ def sync_for(app_name, force=0, sync_everything = False, verbose=False, reset_pe ("data_migration", "data_migration_mapping"), ("data_migration", "data_migration_plan_mapping"), ("data_migration", "data_migration_plan"), + ("desk", "dashboard_chart"), + ("desk", "dashboard"), ("desk", "onboarding_permission"), ("desk", "onboarding_step"), ("desk", "onboarding_step_map"), From 61d07941b8d269ac243823c5d808a22f79d91d23 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 6 May 2020 16:46:49 +0530 Subject: [PATCH 05/14] feat: allow number cards in sync --- frappe/utils/dashboard.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/utils/dashboard.py b/frappe/utils/dashboard.py index 43057be79a..9d31c8aa2d 100644 --- a/frappe/utils/dashboard.py +++ b/frappe/utils/dashboard.py @@ -90,6 +90,7 @@ def sync_dashboards(app=None): frappe.flags.in_import = True make_records(config.charts, "Dashboard Chart") make_records(config.dashboards, "Dashboard") + make_records(config.number_cards, "Number Cards") frappe.flags.in_import = False def make_records(config, doctype): From 7df3d2e585fbcbd1ea5fd5a1def18a9635a224da Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 6 May 2020 16:47:27 +0530 Subject: [PATCH 06/14] fix: sync number cards before dashbaords --- frappe/utils/dashboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/utils/dashboard.py b/frappe/utils/dashboard.py index 9d31c8aa2d..ceb5ea758a 100644 --- a/frappe/utils/dashboard.py +++ b/frappe/utils/dashboard.py @@ -89,8 +89,8 @@ def sync_dashboards(app=None): if config: frappe.flags.in_import = True make_records(config.charts, "Dashboard Chart") - make_records(config.dashboards, "Dashboard") make_records(config.number_cards, "Number Cards") + make_records(config.dashboards, "Dashboard") frappe.flags.in_import = False def make_records(config, doctype): From 213b0a228847b32c6eaad35a1eac40a3e4d8ae66 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 6 May 2020 16:50:44 +0530 Subject: [PATCH 07/14] style: remove unused import --- frappe/utils/dashboard.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/frappe/utils/dashboard.py b/frappe/utils/dashboard.py index ceb5ea758a..cf64d9da61 100644 --- a/frappe/utils/dashboard.py +++ b/frappe/utils/dashboard.py @@ -1,10 +1,8 @@ # Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt from __future__ import unicode_literals -import json import frappe from frappe import _ -import os from functools import wraps from frappe.utils import add_to_date, get_link_to_form from frappe.modules.import_file import import_doc From 961fbf6594c3f97af482f5f673c3f960e29315d3 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 6 May 2020 17:26:28 +0530 Subject: [PATCH 08/14] feat: sync number cards --- frappe/model/sync.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/model/sync.py b/frappe/model/sync.py index c753f64e89..320cc24677 100644 --- a/frappe/model/sync.py +++ b/frappe/model/sync.py @@ -45,6 +45,7 @@ def sync_for(app_name, force=0, sync_everything = False, verbose=False, reset_pe ("data_migration", "data_migration_mapping"), ("data_migration", "data_migration_plan_mapping"), ("data_migration", "data_migration_plan"), + ("desk", "number_card"), ("desk", "dashboard_chart"), ("desk", "dashboard"), ("desk", "onboarding_permission"), From ea0b10d1a76406433fdd8c8c16f257a8d3cb51e6 Mon Sep 17 00:00:00 2001 From: Marica Date: Wed, 6 May 2020 17:30:34 +0530 Subject: [PATCH 09/14] fix: navigation issue for quick entry in onboarding (#10250) * fix: Sucess Dialog shows up multiple times * fix: Remove console statements --- .../js/frappe/widgets/onboarding_widget.js | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/frappe/public/js/frappe/widgets/onboarding_widget.js b/frappe/public/js/frappe/widgets/onboarding_widget.js index a6c15134df..78305edd5d 100644 --- a/frappe/public/js/frappe/widgets/onboarding_widget.js +++ b/frappe/public/js/frappe/widgets/onboarding_widget.js @@ -173,21 +173,26 @@ export default class OnboardingWidget extends Widget { frappe.ui.form.make_quick_entry( step.reference_document, () => { - if (frappe.get_route_str != current_route) { - let args = {}; - args.message = __("Let's take you back to onboarding"); - args.title = __("Looks Great"); - args.primary_action = { - action: () => { - frappe.set_route(current_route).then(() => { - this.mark_complete(step); - }); - }, - label: __("Continue"), - }; + if (frappe.get_route_str() != current_route) { + let success_dialog = frappe.msgprint({ + message: __("Let's take you back to onboarding"), + title: __("Looks Great"), + primary_action: { + action: () => { + success_dialog.hide(); + frappe.set_route(current_route).then(() => { + this.mark_complete(step); + }); + }, + label: __("Continue"), + } + }); - frappe.msgprint(args); - frappe.msg_dialog.custom_onhide = () => args.primary_action.action(); + frappe.msg_dialog.custom_onhide = () => { + frappe.set_route(current_route).then(() => { + this.mark_complete(step); + }); + }; } else { this.mark_complete(step); } @@ -277,25 +282,27 @@ export default class OnboardingWidget extends Widget { `); - let success_dialog = new frappe.ui.Dialog({ - primary_action: () => { - success_dialog.hide(); - // Wait for modal to close before removing widget - setTimeout(() => { - this.delete(); - }, 300); - }, - primary_action_label: __("Continue"), - }); + if (!this.success_dialog) { + this.success_dialog = new frappe.ui.Dialog({ + primary_action: () => { + this.success_dialog.hide(); + // Wait for modal to close before removing widget + setTimeout(() => { + this.delete(); + }, 300); + }, + primary_action_label: __("Continue"), + }); - success_dialog.set_title(__("Onboarding Complete")); - success_dialog.header - .find(".indicator") - .removeClass("hidden") - .addClass("green"); + this.success_dialog.set_title(__("Onboarding Complete")); + this.success_dialog.header + .find(".indicator") + .removeClass("hidden") + .addClass("green"); - success.appendTo(success_dialog.$body); - success_dialog.show(); + success.appendTo(this.success_dialog.$body); + this.success_dialog.show(); + } } set_body() { From 8f9cfcb55db447a105d72efd7559ada7fe9dc8da Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 6 May 2020 21:42:05 +0530 Subject: [PATCH 10/14] chore: Use xenial distribution --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e9c2ee5262..488c3074f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: python -dist: trusty +dist: xenial addons: hosts: @@ -9,6 +9,10 @@ addons: postgresql: 9.5 chrome: stable +services: + - xvfb + - mysql + git: depth: 1 From a7ba5c9eb01df23d6fdd342538ae67e57d184907 Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Thu, 7 May 2020 22:26:07 +0530 Subject: [PATCH 11/14] chore: Try Bionic --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 488c3074f1..866b5889bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: python -dist: xenial +dist: bionic addons: hosts: From 198041a5ef57b45dabd2125126f06e39c3bf08a9 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 8 May 2020 02:58:23 +0530 Subject: [PATCH 12/14] fix: dashboard sync issue --- frappe/utils/dashboard.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/frappe/utils/dashboard.py b/frappe/utils/dashboard.py index cf64d9da61..7cc97ed3f9 100644 --- a/frappe/utils/dashboard.py +++ b/frappe/utils/dashboard.py @@ -87,7 +87,7 @@ def sync_dashboards(app=None): if config: frappe.flags.in_import = True make_records(config.charts, "Dashboard Chart") - make_records(config.number_cards, "Number Cards") + make_records(config.number_cards, "Number Card") make_records(config.dashboards, "Dashboard") frappe.flags.in_import = False @@ -95,10 +95,13 @@ def make_records(config, doctype): if not config: return - for item in config: - item["doctype"] = doctype - import_doc(item) - frappe.db.commit() + try: + for item in config: + item["doctype"] = doctype + import_doc(item) + frappe.db.commit() + except frappe.DuplicateEntryError: + pass def get_config(app, module): try: From 3296687178a1849b133e68eed4d14c30c436e9e6 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 8 May 2020 11:00:03 +0530 Subject: [PATCH 13/14] chore: Use python 3.7 --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 866b5889bc..174f92ea11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,18 +27,18 @@ cache: matrix: include: - - name: "Python 3.6 MariaDB" - python: 3.6 + - name: "Python 3.7 MariaDB" + python: 3.7 env: DB=mariadb TYPE=server script: bench --site test_site run-tests --coverage - - name: "Python 3.6 PostgreSQL" - python: 3.6 + - name: "Python 3.7 PostgreSQL" + python: 3.7 env: DB=postgres TYPE=server script: bench --site test_site run-tests --coverage - name: "Cypress" - python: 3.6 + python: 3.7 env: DB=mariadb TYPE=ui before_script: - bench --site test_site execute frappe.utils.install.complete_setup_wizard From 3ae2c1294d1d30586a5a5b164a84f1eac7b32274 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 8 May 2020 13:55:56 +0530 Subject: [PATCH 14/14] test: Remove unwanted test and fix permission test --- frappe/email/test_email_body.py | 16 ---------------- frappe/tests/test_form_load.py | 2 ++ 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/frappe/email/test_email_body.py b/frappe/email/test_email_body.py index f44c6e775a..43c4bb8333 100644 --- a/frappe/email/test_email_body.py +++ b/frappe/email/test_email_body.py @@ -75,22 +75,6 @@ This is the text version of this email else: self.assertTrue(True) - def test_rfc_5322_header_is_wrapped_at_998_chars(self): - # unfortunately the db can only hold 140 chars so this can't be tested properly. test at max chars anyway. - email = get_email_queue( - recipients=['test@example.com'], - sender='me@example.com', - subject='Test Subject', - content='

Whatever

', - text_content='whatever', - message_id="a.really.long.message.id.that.should.not.wrap.until.998.if.it.does.then.exchange.will.break" + - ".really.long.message.id.that.should.not.wrap.unti") - result = safe_decode(prepare_message(email=email, recipient='test@test.com', - recipients_list=[])) - self.assertTrue( - "a.really.long.message.id.that.should.not.wrap.until.998.if.it.does.then.exchange.will.break" + - ".really.long.message.id.that.should.not.wrap.unti" in result) - def test_image(self): img_signature = ''' Content-Type: image/png diff --git a/frappe/tests/test_form_load.py b/frappe/tests/test_form_load.py index 5e8ad26b5e..34fc58465e 100644 --- a/frappe/tests/test_form_load.py +++ b/frappe/tests/test_form_load.py @@ -79,6 +79,8 @@ class TestFormLoad(unittest.TestCase): user.remove_roles('Blogger', 'Website Manager') user.add_roles(*user_roles) + blog_doc.delete() + def test_fieldlevel_permissions_in_load_for_child_table(self): contact = frappe.new_doc('Contact') contact.first_name = '_Test Contact 1'