Merge branch 'user_permission_cleanup' of https://github.com/anurag810/frappe into user_permission_cleanup
This commit is contained in:
commit
44db8b4825
24 changed files with 91 additions and 34 deletions
|
|
@ -23,7 +23,7 @@ if sys.version[0] == '2':
|
|||
reload(sys)
|
||||
sys.setdefaultencoding("utf-8")
|
||||
|
||||
__version__ = '11.1.1'
|
||||
__version__ = '11.1.4'
|
||||
__title__ = "Frappe Framework"
|
||||
|
||||
local = Local()
|
||||
|
|
|
|||
|
|
@ -34,8 +34,10 @@ def import_data(data_import):
|
|||
frappe.db.set_value("Data Import", data_import, "import_status", "In Progress", update_modified=False)
|
||||
frappe.publish_realtime("data_import_progress", {"progress": "0",
|
||||
"data_import": data_import, "reload": True}, user=frappe.session.user)
|
||||
|
||||
from frappe.core.page.background_jobs.background_jobs import get_info
|
||||
enqueued_jobs = [d.get("job_name") for d in get_info()]
|
||||
|
||||
if data_import not in enqueued_jobs:
|
||||
enqueue(upload, queue='default', timeout=6000, event='data_import', job_name=data_import,
|
||||
data_import_doc=data_import, from_data_import="Yes", user=frappe.session.user)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from frappe.utils.csvutils import getlink
|
|||
from frappe.utils.dateutils import parse_date
|
||||
from frappe.utils.file_manager import save_url
|
||||
|
||||
from frappe.utils import cint, cstr, flt, getdate, get_datetime, get_url, get_url_to_form
|
||||
from frappe.utils import cint, cstr, flt, getdate, get_datetime, get_url, get_absolute_url
|
||||
from six import text_type, string_types
|
||||
|
||||
|
||||
|
|
@ -411,31 +411,44 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False,
|
|||
# log errors
|
||||
if parentfield:
|
||||
log(**{"row": doc.idx, "title": 'Inserted row for "%s"' % (as_link(parenttype, doc.parent)),
|
||||
"link": get_url_to_form(parenttype, doc.parent), "message": 'Document successfully saved', "indicator": "green"})
|
||||
"link": get_absolute_url(parenttype, doc.parent), "message": 'Document successfully saved', "indicator": "green"})
|
||||
elif submit_after_import:
|
||||
log(**{"row": row_idx + 1, "title":'Submitted row for "%s"' % (as_link(doc.doctype, doc.name)),
|
||||
"message": "Document successfully submitted", "link": get_url_to_form(doc.doctype, doc.name), "indicator": "blue"})
|
||||
"message": "Document successfully submitted", "link": get_absolute_url(doc.doctype, doc.name), "indicator": "blue"})
|
||||
elif original:
|
||||
log(**{"row": row_idx + 1,"title":'Updated row for "%s"' % (as_link(doc.doctype, doc.name)),
|
||||
"message": "Document successfully updated", "link": get_url_to_form(doc.doctype, doc.name), "indicator": "green"})
|
||||
"message": "Document successfully updated", "link": get_absolute_url(doc.doctype, doc.name), "indicator": "green"})
|
||||
elif not update_only:
|
||||
log(**{"row": row_idx + 1, "title":'Inserted row for "%s"' % (as_link(doc.doctype, doc.name)),
|
||||
"message": "Document successfully saved", "link": get_url_to_form(doc.doctype, doc.name), "indicator": "green"})
|
||||
"message": "Document successfully saved", "link": get_absolute_url(doc.doctype, doc.name), "indicator": "green"})
|
||||
else:
|
||||
log(**{"row": row_idx + 1, "title":'Ignored row for %s' % (row[1]), "link": None,
|
||||
"message": "Document updation ignored", "indicator": "orange"})
|
||||
|
||||
except Exception as e:
|
||||
error_flag = True
|
||||
err_msg = frappe.local.message_log and "\n".join([json.loads(msg).get('message') for msg in frappe.local.message_log]) or cstr(e)
|
||||
|
||||
# build error message
|
||||
if frappe.local.message_log:
|
||||
err_msg = "\n".join(['<p class="border-bottom small">{}</p>'.format(json.loads(msg).get('message')) for msg in frappe.local.message_log])
|
||||
else:
|
||||
err_msg = '<p class="border-bottom small">{}</p>'.format(cstr(e))
|
||||
|
||||
error_trace = frappe.get_traceback()
|
||||
if error_trace:
|
||||
error_log_doc = frappe.log_error(error_trace)
|
||||
error_link = get_url_to_form("Error Log", error_log_doc.name)
|
||||
error_link = get_absolute_url("Error Log", error_log_doc.name)
|
||||
else:
|
||||
error_link = None
|
||||
log(**{"row": row_idx + 1, "title":'Error for row %s' % (len(row)>1 and frappe.safe_decode(row[1]) or ""), "message": err_msg,
|
||||
"indicator": "red", "link":error_link})
|
||||
|
||||
log(**{
|
||||
"row": row_idx + 1,
|
||||
"title": 'Error for row %s' % (len(row)>1 and frappe.safe_decode(row[1]) or ""),
|
||||
"message": err_msg,
|
||||
"indicator": "red",
|
||||
"link":error_link
|
||||
})
|
||||
|
||||
# data with error to create a new file
|
||||
# include the errored data in the last row as last_error_row_idx will not be updated for the last row
|
||||
if skip_errors:
|
||||
|
|
|
|||
|
|
@ -6,19 +6,19 @@
|
|||
<th style="width:40%"> {{ __("Row Status") }} </th>
|
||||
<th style="width:50%"> {{ __("Message") }} </th>
|
||||
</tr>
|
||||
|
||||
|
||||
{% for row in data %}
|
||||
{% if (!show_only_errors) || (show_only_errors && row.indicator == "red") %}
|
||||
<tr>
|
||||
<td>
|
||||
<span>{{ row.row }} </span>
|
||||
<span>{{ row.row }} </span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="indicator {{ row.indicator }}"> {{ row.title }} </span>
|
||||
</td>
|
||||
<td>
|
||||
{% if (import_status != "Failed" || (row.indicator == "red")) { %}
|
||||
<span> {{ row.message }} </span>
|
||||
<div>{{ row.message }}</div>
|
||||
{% if row.link %}
|
||||
<span style="width: 10%; float:right;">
|
||||
<a class="btn-open no-decoration" title="Open Link" href="{{ row.link }}">
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ class Report(Document):
|
|||
|
||||
if params.get('sort_by'):
|
||||
order_by = _format(params.get('sort_by').split('.')) + ' ' + params.get('sort_order')
|
||||
elif params.get('order_by'):
|
||||
order_by = params.get('order_by')
|
||||
else:
|
||||
order_by = _format([self.ref_doctype, 'modified']) + ' desc'
|
||||
|
||||
|
|
|
|||
|
|
@ -358,6 +358,9 @@ class User(Document):
|
|||
where `%s`=%s""" % \
|
||||
(tab[0], field, '%s', field, '%s'), (new_name, old_name))
|
||||
|
||||
if frappe.db.exists("Chat Profile", old_name):
|
||||
frappe.rename_doc("Chat Profile", old_name, new_name, force=True)
|
||||
|
||||
# set email
|
||||
frappe.db.sql("""\
|
||||
update `tabUser` set email=%s
|
||||
|
|
@ -930,7 +933,7 @@ def handle_password_test_fail(result):
|
|||
suggestions = result['feedback']['suggestions'][0] if result['feedback']['suggestions'] else ''
|
||||
warning = result['feedback']['warning'] if 'warning' in result['feedback'] else ''
|
||||
suggestions += "<br>" + _("Hint: Include symbols, numbers and capital letters in the password") + '<br>'
|
||||
frappe.throw(_('Invalid Password: ' + ' '.join([warning, suggestions])))
|
||||
frappe.throw(' '.join([_('Invalid Password:'), warning, suggestions]))
|
||||
|
||||
def update_gravatar(name):
|
||||
gravatar = has_gravatar(name)
|
||||
|
|
|
|||
|
|
@ -192,7 +192,9 @@ def run(report_name, filters=None, user=None):
|
|||
def get_prepared_report_result(report, filters, dn="", user=None):
|
||||
latest_report_data = {}
|
||||
# Only look for completed prepared reports with given filters.
|
||||
doc_list = frappe.get_all("Prepared Report", filters={"status": "Completed", "report_name": report.name, "filters": json.dumps(filters), "owner": user})
|
||||
doc_list = frappe.get_all("Prepared Report",
|
||||
filters={"status": "Completed", "report_name": report.name, "filters": filters, "owner": user})
|
||||
|
||||
doc = None
|
||||
if len(doc_list):
|
||||
if dn:
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ def delete_items():
|
|||
"""delete selected items"""
|
||||
import json
|
||||
|
||||
il = sorted(json.loads(frappe.form_dict.get('items')), reverse=True, key=frappe.safe_decode)
|
||||
il = sorted(json.loads(frappe.form_dict.get('items')), reverse=True)
|
||||
doctype = frappe.form_dict.get('doctype')
|
||||
|
||||
failed = []
|
||||
|
|
|
|||
|
|
@ -547,10 +547,20 @@ class BaseDocument(object):
|
|||
# single doctype value type is mediumtext
|
||||
return
|
||||
|
||||
column_types_to_check_length = ('varchar', 'int', 'bigint')
|
||||
|
||||
for fieldname, value in iteritems(self.get_valid_dict()):
|
||||
df = self.meta.get_field(fieldname)
|
||||
if df and df.fieldtype in type_map and type_map[df.fieldtype][0]=="varchar":
|
||||
max_length = cint(df.get("length")) or cint(varchar_len)
|
||||
|
||||
if not df or df.fieldtype == 'Check':
|
||||
# skip standard fields and Check fields
|
||||
continue
|
||||
|
||||
column_type = type_map[df.fieldtype][0] or None
|
||||
default_column_max_length = type_map[df.fieldtype][1] or None
|
||||
|
||||
if df and df.fieldtype in type_map and column_type in column_types_to_check_length:
|
||||
max_length = cint(df.get("length")) or cint(default_column_max_length)
|
||||
|
||||
if len(cstr(value)) > max_length:
|
||||
if self.parentfield and self.idx:
|
||||
|
|
|
|||
|
|
@ -234,3 +234,4 @@ frappe.patches.v11_0.migrate_report_settings_for_new_listview
|
|||
frappe.patches.v11_0.delete_all_prepared_reports
|
||||
frappe.patches.v11_0.fix_order_by_in_reports_json
|
||||
execute:frappe.delete_doc('Page', 'applications', ignore_missing=True)
|
||||
frappe.patches.v11_0.set_missing_creation_and_modified_value_for_user_permissions
|
||||
|
|
@ -43,9 +43,9 @@ def execute():
|
|||
# only specific doctypes are selected
|
||||
# split this into multiple records and delete
|
||||
linked_doctypes = get_linked_doctypes(user_permission.allow, True).keys()
|
||||
|
||||
|
||||
linked_doctypes = list(linked_doctypes)
|
||||
|
||||
|
||||
# append the doctype for which we have build the user permission
|
||||
linked_doctypes += [user_permission.allow]
|
||||
|
||||
|
|
@ -56,14 +56,16 @@ def execute():
|
|||
user_permission.skip_for_doctype = None
|
||||
for doctype in applicable_for_doctypes:
|
||||
if doctype:
|
||||
# Maintain sequence (name, user, allow, for_value, applicable_for, apply_to_all_doctypes)
|
||||
# Maintain sequence (name, user, allow, for_value, applicable_for, apply_to_all_doctypes, creation, modified)
|
||||
new_user_permissions_list.append((
|
||||
frappe.generate_hash("", 10),
|
||||
user_permission.user,
|
||||
user_permission.allow,
|
||||
user_permission.for_value,
|
||||
doctype,
|
||||
0
|
||||
0,
|
||||
user_permission.creation,
|
||||
user_permission.modified
|
||||
))
|
||||
else:
|
||||
# No skip_for_doctype found! Just update apply_to_all_doctypes.
|
||||
|
|
@ -72,7 +74,7 @@ def execute():
|
|||
if new_user_permissions_list:
|
||||
frappe.db.sql('''
|
||||
INSERT INTO `tabUser Permission`
|
||||
(`name`, `user`, `allow`, `for_value`, `applicable_for`, `apply_to_all_doctypes`)
|
||||
(`name`, `user`, `allow`, `for_value`, `applicable_for`, `apply_to_all_doctypes`, `creation`, `modified`)
|
||||
VALUES {}
|
||||
'''.format( # nosec
|
||||
', '.join(['%s'] * len(new_user_permissions_list))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.db.sql('''UPDATE `tabUser Permission`
|
||||
SET `modified`=NOW(), `creation`=NOW()
|
||||
WHERE `creation` IS NULL''')
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="print-format-builder-section row light-bg" data-label="{{ section.label || '' }}">
|
||||
<div class="print-format-builder-section row light-bg" data-label="{{ section.label }}">
|
||||
<div class="print-format-builder-section-head">
|
||||
<a class="section-settings pull-right
|
||||
btn-default btn-xs" style="padding-top: 3px">
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ export default class Grid {
|
|||
data.push(["------"]);
|
||||
$.each(frappe.get_meta(me.df.options).fields, function(i, df) {
|
||||
// don't include the read-only field in the template
|
||||
if(frappe.model.is_value_type(df.fieldtype) && !df.read_only) {
|
||||
if(frappe.model.is_value_type(df.fieldtype)) {
|
||||
data[1].push(df.label);
|
||||
data[2].push(df.fieldname);
|
||||
let description = (df.description || "") + ' ';
|
||||
|
|
|
|||
|
|
@ -801,7 +801,9 @@ frappe.views.ReportView = frappe.ui.BaseList.extend({
|
|||
});
|
||||
|
||||
this.page.add_menu_item(__("Delete"), function() {
|
||||
var delete_list = $.map(me.get_checked_items(), function(d) { return d.name; });
|
||||
var delete_list = $.map(me.get_checked_items(), function(d) {
|
||||
return d.name.toString();
|
||||
});
|
||||
if(!delete_list.length)
|
||||
return;
|
||||
if(frappe.confirm(__("This is PERMANENT action and you cannot undo. Continue?"),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
frappe.ready_events.push(fn);
|
||||
}
|
||||
window.dev_server = {{ dev_server }};
|
||||
window.socketio_port = {{ frappe.socketio_port }};
|
||||
</script>
|
||||
</head>
|
||||
{% block body %}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{% if blog_title and not (frappe.local.form_dict.txt or frappe.local.form_dict.by) %}
|
||||
{% if blog_title and not (form_dict.txt or form_dict.by) %}
|
||||
<div class="page-hero border-bottom">
|
||||
<div class="container">
|
||||
<h1 class="page-title">
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<script>
|
||||
frappe.ready(function() {
|
||||
if(frappe.utils.get_url_arg("search")) {
|
||||
$(".item-search-results").html('{{ _("Search results for") + ": " + html2text(frappe.form_dict.search or "")|trim }}');
|
||||
$(".item-search-results").html('{{ _("Search results for") + ": " + html2text(frappe.form_dict.search or "") | e | trim }}');
|
||||
$(".item-search").toggle(false);
|
||||
$(".clear").toggle(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -745,6 +745,9 @@ def get_link_to_form(doctype, name, label=None):
|
|||
|
||||
return """<a href="{0}">{1}</a>""".format(get_url_to_form(doctype, name), label)
|
||||
|
||||
def get_absolute_url(doctype, name):
|
||||
return "desk#Form/{0}/{1}".format(quoted(doctype), quoted(name))
|
||||
|
||||
def get_url_to_form(doctype, name):
|
||||
return get_url(uri = "desk#Form/{0}/{1}".format(quoted(doctype), quoted(name)))
|
||||
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ def sync_global_search():
|
|||
:return:
|
||||
"""
|
||||
while frappe.cache().llen('global_search_queue') > 0:
|
||||
value = json.loads(frappe.cache().lpop('global_search_queue'))
|
||||
value = json.loads(frappe.cache().lpop('global_search_queue').decode('utf-8'))
|
||||
sync_value(value)
|
||||
|
||||
def sync_value(value):
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ def render_template(template, context, is_path=None, safe_render=True):
|
|||
:param template: path or HTML containing the jinja template
|
||||
:param context: dict of properties to pass to the template
|
||||
:param is_path: (optional) assert that the `template` parameter is a path
|
||||
:param safe_render: (optional) prevent server side scripting via jinja templating
|
||||
:param safe_render: (optional) prevent server side scripting via jinja templating
|
||||
'''
|
||||
|
||||
from frappe import throw
|
||||
|
|
@ -117,7 +117,6 @@ def get_allowed_functions_for_jenv():
|
|||
'date_format': date_format,
|
||||
"format_date": frappe.utils.data.global_date_format,
|
||||
"form_dict": getattr(frappe.local, 'form_dict', {}),
|
||||
"local": frappe.local,
|
||||
"get_hooks": frappe.get_hooks,
|
||||
"get_meta": frappe.get_meta,
|
||||
"get_doc": frappe.get_doc,
|
||||
|
|
@ -130,10 +129,12 @@ def get_allowed_functions_for_jenv():
|
|||
"get_gravatar": frappe.utils.get_gravatar_url,
|
||||
"full_name": frappe.local.session.data.full_name if getattr(frappe.local, "session", None) else "Guest",
|
||||
"render_template": frappe.render_template,
|
||||
"request": getattr(frappe.local, 'request', {}),
|
||||
'session': {
|
||||
'user': user,
|
||||
'csrf_token': frappe.local.session.data.csrf_token if getattr(frappe.local, "session", None) else ''
|
||||
},
|
||||
"socketio_port": frappe.conf.socketio_port,
|
||||
},
|
||||
'style': {
|
||||
'border_color': '#d1d8dd'
|
||||
|
|
|
|||
|
|
@ -90,13 +90,13 @@ def download_pdf(doctype, name, format=None, doc=None, no_letterhead=0):
|
|||
html = frappe.get_print(doctype, name, format, doc=doc, no_letterhead=no_letterhead)
|
||||
frappe.local.response.filename = "{name}.pdf".format(name=name.replace(" ", "-").replace("/", "-"))
|
||||
frappe.local.response.filecontent = get_pdf(html)
|
||||
frappe.local.response.type = "download"
|
||||
frappe.local.response.type = "pdf"
|
||||
|
||||
@frappe.whitelist()
|
||||
def report_to_pdf(html, orientation="Landscape"):
|
||||
frappe.local.response.filename = "report.pdf"
|
||||
frappe.local.response.filecontent = get_pdf(html, {"orientation": orientation})
|
||||
frappe.local.response.type = "download"
|
||||
frappe.local.response.type = "pdf"
|
||||
|
||||
@frappe.whitelist()
|
||||
def print_by_server(doctype, name, print_format=None, doc=None, no_letterhead=0):
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ def build_response(response_type=None):
|
|||
'txt': as_txt,
|
||||
'download': as_raw,
|
||||
'json': as_json,
|
||||
'pdf': as_pdf,
|
||||
'page': as_page,
|
||||
'redirect': redirect,
|
||||
'binary': as_binary
|
||||
|
|
@ -84,6 +85,13 @@ def as_json():
|
|||
response.data = json.dumps(frappe.local.response, default=json_handler, separators=(',',':'))
|
||||
return response
|
||||
|
||||
def as_pdf():
|
||||
response = Response()
|
||||
response.mimetype = "application/pdf"
|
||||
response.headers["Content-Disposition"] = ("filename=\"%s\"" % frappe.response['filename'].replace(' ', '_')).encode("utf-8")
|
||||
response.data = frappe.response['filecontent']
|
||||
return response
|
||||
|
||||
def as_binary():
|
||||
response = Response()
|
||||
response.mimetype = 'application/octet-stream'
|
||||
|
|
|
|||
|
|
@ -427,5 +427,6 @@ frappe.ready(function() {
|
|||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
frappe.socketio.init(window.socketio_port);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue