Merge branch 'develop' into flaky-ui-test-3

This commit is contained in:
Shariq Ansari 2022-04-22 17:14:33 +05:30 committed by GitHub
commit ff6f4c93c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 115 additions and 68 deletions

View file

@ -354,11 +354,11 @@ def cache() -> "RedisWrapper":
return redis_server
def get_traceback():
def get_traceback(with_context=False):
"""Returns error traceback."""
from frappe.utils import get_traceback
return get_traceback()
return get_traceback(with_context=with_context)
def errprint(msg):
@ -1210,18 +1210,35 @@ def reload_doc(module, dt=None, dn=None, force=False, reset_permissions=False):
@whitelist()
def rename_doc(*args, **kwargs):
def rename_doc(
doctype: str,
old: str,
new: str,
force: bool = False,
merge: bool = False,
*,
ignore_if_exists: bool = False,
show_alert: bool = True,
rebuild_search: bool = True,
) -> str:
"""
Renames a doc(dt, old) to doc(dt, new) and updates all linked fields of type "Link"
Calls `frappe.model.rename_doc.rename_doc`
"""
kwargs.pop("ignore_permissions", None)
kwargs.pop("cmd", None)
from frappe.model.rename_doc import rename_doc
return rename_doc(*args, **kwargs)
return rename_doc(
doctype=doctype,
old=old,
new=new,
force=force,
merge=merge,
ignore_if_exists=ignore_if_exists,
show_alert=show_alert,
rebuild_search=rebuild_search,
)
def get_module(modulename):
@ -2069,7 +2086,6 @@ def logger(
def log_error(title=None, message=None, reference_doctype=None, reference_name=None):
"""Log error to Error Log"""
# Parameter ALERT:
# the title and message may be swapped
# the better API for this is log_error(title, message), and used in many cases this way
@ -2082,20 +2098,15 @@ def log_error(title=None, message=None, reference_doctype=None, reference_name=N
else:
traceback = message
if not traceback:
traceback = get_traceback()
if not title:
title = "Error"
title = title or "Error"
traceback = as_unicode(traceback or get_traceback(with_context=True))
return get_doc(
dict(
doctype="Error Log",
error=as_unicode(traceback),
method=title,
reference_doctype=reference_doctype,
reference_name=reference_name,
)
doctype="Error Log",
error=traceback,
method=title,
reference_doctype=reference_doctype,
reference_name=reference_name,
).insert(ignore_permissions=True)

View file

@ -68,6 +68,8 @@
"prepared_report_section",
"enable_prepared_report_auto_deletion",
"prepared_report_expiry_period",
"column_break_64",
"max_auto_email_report_per_user",
"system_updates_section",
"disable_system_update_notification"
],
@ -445,7 +447,7 @@
"collapsible": 1,
"fieldname": "prepared_report_section",
"fieldtype": "Section Break",
"label": "Prepared Report"
"label": "Reports"
},
{
"default": "Frappe",
@ -485,12 +487,22 @@
"fieldtype": "Select",
"label": "First Day of the Week",
"options": "Sunday\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday"
},
{
"fieldname": "column_break_64",
"fieldtype": "Column Break"
},
{
"default": "20",
"fieldname": "max_auto_email_report_per_user",
"fieldtype": "Int",
"label": "Max auto email report per user"
}
],
"icon": "fa fa-cog",
"issingle": 1,
"links": [],
"modified": "2022-01-04 11:28:34.881192",
"modified": "2022-04-21 09:11:35.218721",
"modified_by": "Administrator",
"module": "Core",
"name": "System Settings",

View file

@ -1066,7 +1066,7 @@ class Database(object):
now_datetime() - relativedelta(minutes=minutes),
)[0][0]
def get_db_table_columns(self, table):
def get_db_table_columns(self, table) -> List[str]:
"""Returns list of column names from given table."""
columns = frappe.cache().hget("table_columns", table)
if columns is None:
@ -1146,18 +1146,13 @@ class Database(object):
return frappe.db.is_missing_column(e)
def get_descendants(self, doctype, name):
"""Return descendants of the current record"""
node_location_indexes = self.get_value(doctype, name, ("lft", "rgt"))
if node_location_indexes:
lft, rgt = node_location_indexes
return self.sql_list(
"""select name from `tab{doctype}`
where lft > {lft} and rgt < {rgt}""".format(
doctype=doctype, lft=lft, rgt=rgt
)
)
else:
# when document does not exist
"""Return descendants of the group node in tree"""
from frappe.utils.nestedset import get_descendants_of
try:
return get_descendants_of(doctype, name, ignore_permissions=True)
except Exception:
# Can only happen if document doesn't exists - kept for backward compatibility
return []
def is_missing_table_or_column(self, e):

View file

@ -12,6 +12,7 @@ from frappe.model.document import Document
from frappe.model.naming import append_number_if_name_exists
from frappe.utils import (
add_to_date,
cint,
format_time,
get_link_to_form,
get_url_to_report,
@ -51,14 +52,18 @@ class AutoEmailReport(Document):
self.email_to = "\n".join(valid)
def validate_report_count(self):
"""check that there are only 3 enabled reports per user"""
count = frappe.db.sql(
"select count(*) from `tabAuto Email Report` where user=%s and enabled=1", self.user
)[0][0]
max_reports_per_user = frappe.local.conf.max_reports_per_user or 3
count = frappe.db.count("Auto Email Report", {"user": self.user, "enabled": 1})
max_reports_per_user = (
cint(frappe.local.conf.max_reports_per_user) # kept for backward compatibilty
or cint(frappe.db.get_single_value("System Settings", "max_auto_email_report_per_user"))
or 20
)
if count > max_reports_per_user + (-1 if self.flags.in_insert else 0):
frappe.throw(_("Only {0} emailed reports are allowed per user").format(max_reports_per_user))
msg = _("Only {0} emailed reports are allowed per user.").format(max_reports_per_user)
msg += " " + _("To allow more reports update limit in System Settings.")
frappe.throw(msg, title=_("Report limit reached"))
def validate_report_format(self):
"""check if user has select correct report format"""

View file

@ -226,7 +226,6 @@ scheduler_events = {
"frappe.sessions.clear_expired_sessions",
"frappe.email.doctype.notification.notification.trigger_daily_alerts",
"frappe.utils.scheduler.restrict_scheduler_events_if_dormant",
"frappe.email.doctype.auto_email_report.auto_email_report.send_daily",
"frappe.website.doctype.personal_data_deletion_request.personal_data_deletion_request.remove_unverified_record",
"frappe.desk.form.document_follow.send_daily_updates",
"frappe.social.doctype.energy_point_settings.energy_point_settings.allocate_review_points",
@ -241,6 +240,7 @@ scheduler_events = {
"frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_daily",
"frappe.utils.change_log.check_for_update",
"frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_daily",
"frappe.email.doctype.auto_email_report.auto_email_report.send_daily",
"frappe.integrations.doctype.google_drive.google_drive.daily_backup",
],
"weekly_long": [

View file

@ -2,6 +2,7 @@
# License: MIT. See LICENSE
import datetime
import json
from typing import Dict, List
import frappe
from frappe import _
@ -252,7 +253,7 @@ class BaseDocument(object):
def get_valid_dict(
self, sanitize=True, convert_dates_to_str=False, ignore_nulls=False, ignore_virtual=False
):
) -> Dict:
d = frappe._dict()
for fieldname in self.meta.get_valid_columns():
d[fieldname] = self.get(fieldname)
@ -329,7 +330,7 @@ class BaseDocument(object):
if key not in self.__dict__:
self.__dict__[key] = None
def get_valid_columns(self):
def get_valid_columns(self) -> List[str]:
if self.doctype not in frappe.local.valid_columns:
if self.doctype in DOCTYPES_FOR_DOCTYPE:
from frappe.model.meta import get_table_columns
@ -342,7 +343,7 @@ class BaseDocument(object):
return frappe.local.valid_columns[self.doctype]
def is_new(self):
def is_new(self) -> bool:
return self.get("__islocal")
@property
@ -359,7 +360,7 @@ class BaseDocument(object):
no_default_fields=False,
convert_dates_to_str=False,
no_child_table_fields=False,
):
) -> Dict:
doc = self.get_valid_dict(convert_dates_to_str=convert_dates_to_str)
doc["doctype"] = self.doctype

View file

@ -289,19 +289,23 @@ export default class GridRow {
var me = this;
if(this.doc && !this.grid.df.in_place_edit) {
// remove row
if(!this.open_form_button) {
this.open_form_button = $(`
<div class="btn-open-row">
<a>${frappe.utils.icon('edit', 'xs')}</a>
<div class="hidden-xs edit-grid-row">${ __("Edit") }</div>
</div>
`)
.appendTo($('<div class="col col-xs-1"></div>').appendTo(this.row))
.on('click', function() {
me.toggle_view(); return false;
});
if (!this.open_form_button) {
this.open_form_button = $('<div class="col col-xs-1"></div>').appendTo(this.row);
if(this.is_too_small()) {
if (!this.configure_columns) {
this.open_form_button = $(`
<div class="btn-open-row">
<a>${frappe.utils.icon('edit', 'xs')}</a>
<div class="hidden-xs edit-grid-row">${ __("Edit") }</div>
</div>
`)
.appendTo(this.open_form_button)
.on('click', function() {
me.toggle_view(); return false;
});
}
if (this.is_too_small()) {
// narrow
this.open_form_button.css({'margin-right': '-2px'});
}
@ -310,7 +314,9 @@ export default class GridRow {
}
add_column_configure_button() {
if (this.configure_columns) {
if (this.grid.df.in_place_edit && !this.frm) return;
if (this.configure_columns && this.frm) {
this.configure_columns_button = $(`
<div class="col grid-static-col col-xs-1 d-flex justify-content-center" style="cursor: pointer;">
<a>${frappe.utils.icon('setting-gear', 'sm', '', 'filter: opacity(0.5)')}</a>
@ -320,6 +326,10 @@ export default class GridRow {
.on('click', () => {
this.configure_dialog_for_columns_selector();
});
} else if (this.configure_columns && !this.frm) {
this.configure_columns_button = $(`
<div class="col grid-static-col col-xs-1"></div>
`).appendTo(this.row);
}
}

View file

@ -343,11 +343,10 @@ textarea.form-control {
.duration-picker {
position: absolute;
z-index: 999;
border-radius: var(--border-radius);
box-shadow: var(--shadow-sm);
background: var(--popover-bg);
width: max-content;
&:after,
&:before {
border: solid transparent;
@ -466,4 +465,4 @@ button.data-pill {
top: 0;
right: 0;
cursor: pointer;
}
}

View file

@ -18,6 +18,7 @@ from typing import Generator, Iterable
from urllib.parse import quote, urlparse
from redis.exceptions import ConnectionError
from traceback_with_variables import iter_exc_lines
from werkzeug.test import Client
import frappe
@ -255,7 +256,7 @@ def get_gravatar(email):
return gravatar_url
def get_traceback() -> str:
def get_traceback(with_context=False) -> str:
"""
Returns the traceback of the Exception
"""
@ -264,14 +265,19 @@ def get_traceback() -> str:
if not any([exc_type, exc_value, exc_tb]):
return ""
trace_list = traceback.format_exception(exc_type, exc_value, exc_tb)
bench_path = get_bench_path() + "/"
if with_context:
trace_list = iter_exc_lines()
tb = "\n".join(trace_list)
else:
trace_list = traceback.format_exception(exc_type, exc_value, exc_tb)
tb = "".join(cstr(t) for t in trace_list)
return "".join(cstr(t) for t in trace_list).replace(bench_path, "")
bench_path = get_bench_path() + "/"
return tb.replace(bench_path, "")
def log(event, details):
frappe.logger().info(details)
frappe.logger(event).info(details)
def dict_to_str(args, sep="&"):

View file

@ -15,6 +15,9 @@ import frappe.utils.data
from frappe import _
from frappe.frappeclient import FrappeClient
from frappe.handler import execute_cmd
from frappe.model.delete_doc import delete_doc
from frappe.model.mapper import get_mapped_doc
from frappe.model.rename_doc import rename_doc
from frappe.modules import scrub
from frappe.utils.background_jobs import enqueue, get_jobs
from frappe.website.utils import get_next_link, get_shade, get_toc
@ -110,12 +113,16 @@ def get_safe_globals():
errprint=frappe.errprint,
qb=frappe.qb,
get_meta=frappe.get_meta,
new_doc=frappe.new_doc,
get_doc=frappe.get_doc,
get_mapped_doc=get_mapped_doc,
get_last_doc=frappe.get_last_doc,
get_cached_doc=frappe.get_cached_doc,
get_list=frappe.get_list,
get_all=frappe.get_all,
get_system_settings=frappe.get_system_settings,
rename_doc=frappe.rename_doc,
rename_doc=rename_doc,
delete_doc=delete_doc,
utils=datautils,
get_url=frappe.utils.get_url,
render_template=frappe.render_template,

View file

@ -63,10 +63,11 @@ semantic-version~=2.8.5
sqlparse~=0.4.1
stripe~=2.56.0
terminaltables~=3.1.0
traceback-with-variables~=2.0.4
urllib3~=1.26.4
Werkzeug~=2.0.3
Whoosh~=2.7.4
wrapt~=1.12.1
wrapt~=1.14.0
xlrd~=2.0.1
zxcvbn-python~=4.4.24
tenacity~=8.0.1