diff --git a/frappe/app.py b/frappe/app.py index 5a0bf0b0d2..9860a924cc 100644 --- a/frappe/app.py +++ b/frappe/app.py @@ -68,7 +68,8 @@ def application(request): frappe.DoesNotExistError, frappe.DuplicateEntryError, frappe.OutgoingEmailError, - frappe.ValidationError), e: + frappe.ValidationError, + frappe.UnsupportedMediaType), e: if frappe.local.is_ajax: response = frappe.utils.response.report_error(e.http_status_code) diff --git a/frappe/core/doctype/customize_form/customize_form.js b/frappe/core/doctype/customize_form/customize_form.js index 7c762bea25..2a9bc3842b 100644 --- a/frappe/core/doctype/customize_form/customize_form.js +++ b/frappe/core/doctype/customize_form/customize_form.js @@ -1,102 +1,84 @@ // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors // MIT License. See license.txt -$(cur_frm.wrapper).on("grid-row-render", function(e, grid_row) { - if(grid_row.doc && grid_row.doc.fieldtype=="Section Break") { - $(grid_row.row).css({"font-weight": "bold"}); - } -}) +frappe.provide("frappe.customize_form"); -cur_frm.cscript.doc_type = function() { - return cur_frm.call({ - method: "get", - doc: cur_frm.doc, - callback: function(r) { - cur_frm.refresh(); +frappe.ui.form.on("Customize Form", "onload", function(frm) { + frm.fields_dict.fields.grid.cannot_add_rows = true; + frappe.customize_form.add_fields_help(frm); + + frm.set_query("doc_type", function() { + return { + filters: [ + ['DocType', 'issingle', '=', 0], + ['DocType', 'in_create', '=', 0], + ['DocType', 'name', 'not in', 'DocType, DocField, DocPerm, User, Role, UserRole, \ + Page, Page Role, Module Def, Print Format, Report, Customize Form, \ + Customize Form Field'] + ] + }; + }); + + $(frm.wrapper).on("grid-row-render", function(e, grid_row) { + if(grid_row.doc && grid_row.doc.fieldtype=="Section Break") { + $(grid_row.row).css({"font-weight": "bold"}); } }); -} +}); -cur_frm.cscript.onload = function(doc, dt, dn) { - cur_frm.fields_dict.fields.grid.cannot_add_rows = true; - cur_frm.add_fields_help(); -} - -cur_frm.fields_dict.doc_type.get_query = function(doc, dt, dn) { - return{ - filters:[ - ['DocType', 'issingle', '=', 0], - ['DocType', 'in_create', '=', 0], - ['DocType', 'name', 'not in', 'DocType, DocField, DocPerm, User, Role, UserRole,\ - Page, Page Role, Module Def, Print Format, Report, Customize Form, Customize Form Field'] - ] +frappe.ui.form.on("Customize Form", "doc_type", function(frm) { + if(frm.doc.doc_type) { + return frm.call({ + method: "fetch_to_customize", + doc: frm.doc, + callback: function(r) { + frm.refresh(); + } + }); } -} +}); -cur_frm.cscript.refresh = function() { - cur_frm.disable_save(); - cur_frm.frm_head.appframe.iconbar.clear("1"); - - cur_frm.appframe.set_title_right("Update", function() { - if(cur_frm.doc.doc_type) { - return cur_frm.call({ - doc: cur_frm.doc, - method: "post", +frappe.ui.form.on("Customize Form", "refresh", function(frm) { + frm.disable_save(); + frm.frm_head.appframe.iconbar.clear("1"); + frm.appframe.set_title_right("Update", function() { + if(frm.doc.doc_type) { + return frm.call({ + doc: frm.doc, + method: "save_customization", callback: function(r) { if(!r.exc && r.server_messages) { - cur_frm.script_manager.trigger("doc_type"); - cur_frm.frm_head.set_label(['Updated', 'label-success']); + frm.script_manager.trigger("doc_type"); + frm.frm_head.set_label(['Updated', 'label-success']); } } }); } }); - cur_frm.add_custom_button('Refresh Form', function() { - cur_frm.script_manager.trigger("doc_type"); + frm.add_custom_button('Refresh Form', function() { + frm.script_manager.trigger("doc_type"); }, "icon-refresh"); - cur_frm.add_custom_button('Reset to defaults', function() { - cur_frm.confirm('This will remove the customizations defined for this form.

' - + 'Are you sure you want to reset to defaults?', cur_frm.doc, cur_frm.doctype, cur_frm.docname); + frm.add_custom_button('Reset to defaults', function() { + frappe.customize_form.confirm('This will remove the customizations defined for this form.

' + + 'Are you sure you want to reset to defaults?', frm); }, "icon-eraser"); - if(!cur_frm.doc.doc_type) { - var frm_head = cur_frm.frm_head.appframe; + if(!frm.doc.doc_type) { + var frm_head = frm.frm_head.appframe; $(frm_head.buttons['Update']).prop('disabled', true); $(frm_head.buttons['Refresh Form']).prop('disabled', true); $(frm_head.buttons['Reset to defaults']).prop('disabled', true); } - cur_frm.cscript.hide_allow_attach(cur_frm.doc); - if(frappe.route_options) { frappe.model.set_value("Customize Form", null, "doc_type", frappe.route_options.doctype) frappe.route_options = null; } -} +}); -cur_frm.cscript.hide_allow_attach = function(doc) { - var allow_attach_list = ['Website Settings', 'Web Page', 'Timesheet', 'Ticket', - 'Support Ticket', 'Supplier', 'Style Settings', 'Stock Reconciliation', - 'Stock Entry', 'Serial No', 'Sales Order', 'Sales Invoice', - 'Quotation', 'Question', 'Purchase Receipt', 'Purchase Order', - 'Project', 'User', 'Production Order', 'Product', 'Print Format', - 'Price List', 'Purchase Invoice', 'Page', 'Module Def', - 'Maintenance Visit', 'Maintenance Schedule', 'Letter Head', - 'Leave Application', 'Lead', 'Journal Voucher', 'Item', 'Material Request', - 'Expense Claim', 'Opportunity', 'Employee', 'Delivery Note', - 'Customer Issue', 'Customer', 'Contact Us Settings', 'Company', - 'Blog Post', 'BOM', 'About Us Settings', 'Batch']; - - if(inList(allow_attach_list, doc.doc_type)) { - unhide_field('allow_attach'); - } else { - hide_field('allow_attach'); - } -} - -cur_frm.confirm = function(msg, doc, dt, dn) { +frappe.customize_form.confirm = function(msg, frm) { var d = new frappe.ui.Dialog({ title: 'Reset To Defaults', width: 500 @@ -110,16 +92,16 @@ cur_frm.confirm = function(msg, doc, dt, dn) { $y(button_wrapper, {paddingTop: '15px'}); var proceed_btn = $btn(button_wrapper, 'Proceed', function() { - return cur_frm.call({ - doc: cur_frm.doc, + return frm.call({ + doc: frm.doc, method: "delete", callback: function(r) { if(r.exc) { msgprint(r.exc); } else { - cur_frm.confirm.dialog.hide(); - cur_frm.refresh(); - cur_frm.frm_head.set_label(['Saved', 'label-success']); + frm.confirm.dialog.hide(); + frm.refresh(); + frm.frm_head.set_label(['Saved', 'label-success']); } } }); @@ -128,19 +110,19 @@ cur_frm.confirm = function(msg, doc, dt, dn) { $y(proceed_btn, {marginRight: '20px', fontWeight: 'bold'}); var cancel_btn = $btn(button_wrapper, 'Cancel', function() { - cur_frm.confirm.dialog.hide(); + frm.confirm.dialog.hide(); }); $(cancel_btn).addClass('btn-small btn-info'); $y(cancel_btn, {fontWeight: 'bold'}); - cur_frm.confirm.dialog = d; + frm.confirm.dialog = d; d.show(); } -cur_frm.add_fields_help = function() { - $(cur_frm.grids[0].parent).before( +frappe.customize_form.add_fields_help = function(frm) { + $(frm.grids[0].parent).before( '
\ Help\
'); @@ -223,7 +205,7 @@ cur_frm.add_fields_help = function() { \ \ Press Esc to close\ \ \ @@ -235,7 +217,7 @@ cur_frm.add_fields_help = function() { d.show(); - cur_frm.fields_help_dialog = d; + frm.fields_help_dialog = d; }); } diff --git a/frappe/core/doctype/customize_form/customize_form.json b/frappe/core/doctype/customize_form/customize_form.json index 89a1790135..568d2e9074 100644 --- a/frappe/core/doctype/customize_form/customize_form.json +++ b/frappe/core/doctype/customize_form/customize_form.json @@ -111,7 +111,7 @@ "icon": "icon-glass", "idx": 1, "issingle": 1, - "modified": "2014-01-15 16:16:23.000000", + "modified": "2014-01-15 16:16:24.000000", "modified_by": "Administrator", "module": "Core", "name": "Customize Form", diff --git a/frappe/core/doctype/customize_form/customize_form.py b/frappe/core/doctype/customize_form/customize_form.py index 6e393472a0..a48ec4be2d 100644 --- a/frappe/core/doctype/customize_form/customize_form.py +++ b/frappe/core/doctype/customize_form/customize_form.py @@ -49,6 +49,16 @@ class CustomizeForm(Document): property_restrictions = { 'fieldtype': [['Currency', 'Float'], ['Small Text', 'Data'], ['Text', 'Text Editor', 'Code']], } + + def on_update(self): + frappe.db.sql("delete from tabSingles where doctype='Customize Form'") + frappe.db.sql("delete from `tabCustomize Form Field`") + + def fetch_to_customize(self): + pass + + def save_customization(self): + pass def _get(self): """ diff --git a/frappe/data/Framework.sql b/frappe/data/Framework.sql index f6b04d5d26..b7c78719cc 100644 --- a/frappe/data/Framework.sql +++ b/frappe/data/Framework.sql @@ -9,8 +9,8 @@ DROP TABLE IF EXISTS `tabDocField`; CREATE TABLE `tabDocField` ( `name` varchar(120) NOT NULL, - `creation` datetime DEFAULT NULL, - `modified` datetime DEFAULT NULL, + `creation` datetime(6) DEFAULT NULL, + `modified` datetime(6) DEFAULT NULL, `modified_by` varchar(40) DEFAULT NULL, `owner` varchar(40) DEFAULT NULL, `docstatus` int(1) DEFAULT '0', @@ -61,8 +61,8 @@ DROP TABLE IF EXISTS `tabDocPerm`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `tabDocPerm` ( `name` varchar(120) NOT NULL, - `creation` datetime DEFAULT NULL, - `modified` datetime DEFAULT NULL, + `creation` datetime(6) DEFAULT NULL, + `modified` datetime(6) DEFAULT NULL, `modified_by` varchar(40) DEFAULT NULL, `owner` varchar(40) DEFAULT NULL, `docstatus` int(1) DEFAULT '0', @@ -100,8 +100,8 @@ DROP TABLE IF EXISTS `tabDocType`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `tabDocType` ( `name` varchar(180) NOT NULL DEFAULT '', - `creation` datetime DEFAULT NULL, - `modified` datetime DEFAULT NULL, + `creation` datetime(6) DEFAULT NULL, + `modified` datetime(6) DEFAULT NULL, `modified_by` varchar(40) DEFAULT NULL, `owner` varchar(180) DEFAULT NULL, `docstatus` int(1) DEFAULT '0', @@ -191,7 +191,7 @@ CREATE TABLE `tabSessions` ( `sid` varchar(120) DEFAULT NULL, `sessiondata` longtext, `ipaddress` varchar(16) DEFAULT NULL, - `lastupdate` datetime DEFAULT NULL, + `lastupdate` datetime(6) DEFAULT NULL, `status` varchar(20) DEFAULT NULL, KEY `sid` (`sid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -232,8 +232,8 @@ CREATE TABLE `__Auth` ( DROP TABLE IF EXISTS `tabFile Data`; CREATE TABLE `tabFile Data` ( `name` varchar(120) NOT NULL, - `creation` datetime DEFAULT NULL, - `modified` datetime DEFAULT NULL, + `creation` datetime(6) DEFAULT NULL, + `modified` datetime(6) DEFAULT NULL, `modified_by` varchar(40) DEFAULT NULL, `owner` varchar(40) DEFAULT NULL, `docstatus` int(1) DEFAULT '0', @@ -260,8 +260,8 @@ CREATE TABLE `tabFile Data` ( DROP TABLE IF EXISTS `tabDefaultValue`; CREATE TABLE `tabDefaultValue` ( `name` varchar(120) NOT NULL, - `creation` datetime DEFAULT NULL, - `modified` datetime DEFAULT NULL, + `creation` datetime(6) DEFAULT NULL, + `modified` datetime(6) DEFAULT NULL, `modified_by` varchar(40) DEFAULT NULL, `owner` varchar(40) DEFAULT NULL, `docstatus` int(1) DEFAULT '0', diff --git a/frappe/exceptions.py b/frappe/exceptions.py index 3a15f913d4..e0954b4080 100644 --- a/frappe/exceptions.py +++ b/frappe/exceptions.py @@ -26,7 +26,10 @@ class OutgoingEmailError(Exception): class SessionStopped(Exception): http_status_code = 503 -class DataError(Exception): pass +class UnsupportedMediaType(Exception): + http_status_code = 415 + +class DataError(ValidationError): pass class UnknownDomainError(Exception): pass class MappingMismatchError(ValidationError): pass class InvalidStatusError(ValidationError): pass diff --git a/frappe/modules/import_file.py b/frappe/modules/import_file.py index 94df3cc13a..716a592266 100644 --- a/frappe/modules/import_file.py +++ b/frappe/modules/import_file.py @@ -37,7 +37,8 @@ def import_file_by_path(path, force=False): if doc: if not force: # check if timestamps match - if doc['modified']==get_datetime_str(frappe.db.get_value(doc['doctype'], doc['name'], 'modified')): + db_modified = frappe.db.get_value(doc['doctype'], doc['name'], 'modified') + if db_modified and doc['modified']==get_datetime_str(db_modified): return False original_modified = doc["modified"] diff --git a/frappe/website/render.py b/frappe/website/render.py index 8f2aa75648..9329edd131 100644 --- a/frappe/website/render.py +++ b/frappe/website/render.py @@ -111,8 +111,10 @@ def set_content_type(response, data, path): response.headers["Content-Type"] = "text/html; charset: utf-8" - if "." in path and not path.endswith(".html"): + if "." in path: content_type, encoding = mimetypes.guess_type(path) + if not content_type: + raise frappe.UnsupportedMediaType("Cannot determine content type of {}".format(path)) response.headers["Content-Type"] = content_type.encode("utf-8") return data diff --git a/frappe/widgets/form/run_method.py b/frappe/widgets/form/run_method.py index dd2e80e891..79ffaaf9c2 100644 --- a/frappe/widgets/form/run_method.py +++ b/frappe/widgets/form/run_method.py @@ -2,6 +2,7 @@ # MIT License. See license.txt from __future__ import unicode_literals +import json import frappe from frappe import _ @@ -14,7 +15,6 @@ def runserverobj(): wrapper = None method = frappe.form_dict.get('method') - arg = frappe.form_dict.get('args', frappe.form_dict.get("arg")) dt = frappe.form_dict.get('doctype') dn = frappe.form_dict.get('docname') @@ -30,7 +30,14 @@ def runserverobj(): frappe.msgprint(_("No Permission"), raise_exception = True) if doc: - r = doc.run_method(method, arg) + try: + args = frappe.form_dict.get('args', frappe.form_dict.get("arg")) + args = json.loads(args) + except ValueError: + r = doc.run_method(method, args) + else: + r = doc.run_method(method, **args) + if r: #build output as csv if cint(frappe.form_dict.get('as_csv')): diff --git a/frappe/widgets/search.py b/frappe/widgets/search.py index d166f3cd03..53c794c13d 100644 --- a/frappe/widgets/search.py +++ b/frappe/widgets/search.py @@ -57,9 +57,9 @@ def search_widget(doctype, txt, query=None, searchfield="name", start=0, # build from doctype if txt: filters.append([doctype, searchfield or "name", "like", txt + "%"]) - if meta.get({"parent":doctype, "fieldname":"enabled", "fieldtype":"Check"}): + if meta.get("fields", {"fieldname":"enabled", "fieldtype":"Check"}): filters.append([doctype, "enabled", "=", 1]) - if meta.get({"parent":doctype, "fieldname":"disabled", "fieldtype":"Check"}): + if meta.get("fields", {"fieldname":"disabled", "fieldtype":"Check"}): filters.append([doctype, "disabled", "!=", 1]) frappe.response["values"] = frappe.widgets.reportview.execute(doctype,