From 1f2c9b6ea4d371a8017675426bdd66f8816164fd Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 14 Mar 2018 07:06:14 +0530 Subject: [PATCH 01/14] Letterhead cleanup --- frappe/core/doctype/communication/email.py | 2 +- frappe/public/js/frappe/views/communication.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index 00b9918933..8acececa03 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -88,7 +88,7 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received = frappe.db.commit() if cint(send_email): - frappe.flags.print_letterhead = print_letterhead + frappe.flags.print_letterhead = cint(print_letterhead) comm.send(print_html, print_format, attachments, send_me_a_copy=send_me_a_copy) return { diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 3ca9715556..5799aec97d 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -555,10 +555,10 @@ frappe.views.CommunicationComposer = Class.extend({ is_print_letterhead_checked: function() { if (this.frm && $(this.frm.wrapper).find('.form-print-wrapper').is(':visible')){ - return $(this.frm.wrapper).find('.print-letterhead').prop('checked'); + return $(this.frm.wrapper).find('.print-letterhead').prop('checked') ? 1 : 0; } else { return (frappe.model.get_doc(":Print Settings", "Print Settings") || - { with_letterhead: 1 }).with_letterhead ? true : false; + { with_letterhead: 1 }).with_letterhead ? 1 : 0; } }, From fa46d65754a888dbcabbe96335f92d1960b5e2e2 Mon Sep 17 00:00:00 2001 From: Sunny Date: Wed, 14 Mar 2018 08:52:20 +0530 Subject: [PATCH 02/14] set fieldname for Section Break and Column Break, only if fieldname is not set, else it breaks existing custom fields. Also Use label for creating fieldname if user has entered label --- .../custom/doctype/custom_field/custom_field.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/frappe/custom/doctype/custom_field/custom_field.py b/frappe/custom/doctype/custom_field/custom_field.py index 1f2445eb13..dbab4eadcb 100644 --- a/frappe/custom/doctype/custom_field/custom_field.py +++ b/frappe/custom/doctype/custom_field/custom_field.py @@ -14,14 +14,17 @@ class CustomField(Document): self.name = self.dt + "-" + self.fieldname def set_fieldname(self): - if self.fieldtype in ["Section Break", "Column Break"]: - self.fieldname = self.fieldtype.lower().replace(" ","_") + "_" + str(self.idx) if not self.fieldname: - if not self.label: - frappe.throw(_("Label is mandatory")) + label = self.label + if not label: + if self.fieldtype in ["Section Break", "Column Break"]: + label = self.fieldtype + "_" + str(self.idx) + else: + frappe.throw(_("Label is mandatory")) + # remove special characters from fieldname self.fieldname = "".join(filter(lambda x: x.isdigit() or x.isalpha() or '_', - cstr(self.label).lower().replace(' ','_'))) + cstr(label).replace(' ','_'))) # fieldnames should be lowercase self.fieldname = self.fieldname.lower() @@ -130,4 +133,4 @@ def create_custom_fields(custom_fields): @frappe.whitelist() def add_custom_field(doctype, df): df = json.loads(df) - return create_custom_field(doctype, df) \ No newline at end of file + return create_custom_field(doctype, df) From b5454a353a1cadc0d80baf70590b080ece2888c5 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 16 Mar 2018 10:25:44 +0530 Subject: [PATCH 03/14] [gitignore] --- .gitignore | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 171 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bbd843c61b..3b00b7b374 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,177 @@ build/ frappe/docs/current .vscode node_modules - +.kdev4/ +*.kdev4 +*debug.log # Not Recommended, but will remove once webpack ready package-lock.json + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +.static_storage/ +.media/ +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# next.js build output +.next \ No newline at end of file From dc124d685a69be7186e7726ac31abe14c354f421 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 19 Mar 2018 11:51:21 +0530 Subject: [PATCH 04/14] [fix] [xss] web search (#5205) --- frappe/www/search.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frappe/www/search.py b/frappe/www/search.py index baf2be4e63..c55970c1fc 100644 --- a/frappe/www/search.py +++ b/frappe/www/search.py @@ -4,13 +4,14 @@ from frappe.utils.global_search import web_search from html2text import html2text from frappe import _ from jinja2 import utils +from frappe.utils import sanitize_html def get_context(context): context.no_cache = 1 if frappe.form_dict.q: - frappe.form_dict.q = str(utils.escape(frappe.form_dict.q)) - context.title = _('Search Results for "{0}"').format(frappe.form_dict.q) - context.update(get_search_results(frappe.form_dict.q)) + query = str(utils.escape(sanitize_html(frappe.form_dict.q))) + context.title = _('Search Results for "{0}"').format(query) + context.update(get_search_results(query)) else: context.title = _('Search') From e2a6a954a5bd7ceb184419eab955428fe5e5e06a Mon Sep 17 00:00:00 2001 From: Saurabh Date: Mon, 19 Mar 2018 18:28:53 +0530 Subject: [PATCH 05/14] [fix] validate minimum transaction amount while creating a charge on stripe (#5223) --- .../doctype/stripe_settings/stripe_settings.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/frappe/integrations/doctype/stripe_settings/stripe_settings.py b/frappe/integrations/doctype/stripe_settings/stripe_settings.py index c96b508743..62d90cbe53 100644 --- a/frappe/integrations/doctype/stripe_settings/stripe_settings.py +++ b/frappe/integrations/doctype/stripe_settings/stripe_settings.py @@ -23,12 +23,18 @@ class StripeSettings(Document): "XAF", "XOF", "XPF", "YER", "ZAR" ] + currency_wise_minimum_charge_amount = { + 'JPY': 50, 'MXN': 10, 'DKK': 2.50, 'HKD': 4.00, 'NOK': 3.00, 'SEK': 3.00, + 'USD': 0.50, 'AUD': 0.50, 'BRL': 0.50, 'CAD': 0.50, 'CHF': 0.50, 'EUR': 0.50, + 'GBP': 0.30, 'NZD': 0.50, 'SGD': 0.50 + } + def validate(self): create_payment_gateway('Stripe') call_hook_method('payment_gateway_enabled', gateway='Stripe') if not self.flags.ignore_mandatory: self.validate_stripe_credentails() - + def validate_stripe_credentails(self): if self.publishable_key and self.secret_key: header = {"Authorization": "Bearer {0}".format(self.get_password(fieldname="secret_key", raise_exception=False))} @@ -36,11 +42,17 @@ class StripeSettings(Document): make_get_request(url="https://api.stripe.com/v1/charges", headers=header) except Exception: frappe.throw(_("Seems Publishable Key or Secret Key is wrong !!!")) - + def validate_transaction_currency(self, currency): if currency not in self.supported_currencies: frappe.throw(_("Please select another payment method. Stripe does not support transactions in currency '{0}'").format(currency)) + def validate_minimum_transaction_amount(self, currency, amount): + if currency in self.currency_wise_minimum_charge_amount: + if flt(amount) < self.currency_wise_minimum_charge_amount.get(currency, 0.0): + frappe.throw(_("For currency {0}, the minimum transaction amount should be {1}").format(currency, + self.currency_wise_minimum_charge_amount.get(currency, 0.0))) + def get_payment_url(self, **kwargs): return get_url("./integrations/stripe_checkout?{0}".format(urlencode(kwargs))) From ba5ec5bcc86ee802f0f923f2e41a0deb64768f8c Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 20 Mar 2018 11:40:32 +0530 Subject: [PATCH 06/14] [fix] fix ajax call to update doc not replace (#5204) --- frappe/public/js/frappe/model/sync.js | 36 ++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/model/sync.js b/frappe/public/js/frappe/model/sync.js index 645585b082..ddcd587695 100644 --- a/frappe/public/js/frappe/model/sync.js +++ b/frappe/public/js/frappe/model/sync.js @@ -20,7 +20,12 @@ $.extend(frappe.model, { for(var i=0, l=r.docs.length; i d[fieldname].length) { + local_doc[fieldname].length = d[fieldname].length; + } + } else { + // literal + local_doc[fieldname] = d[fieldname]; + } + } } }); From d00b20a610b9d04ddefb9ab5eb8c406c7fa0e6d3 Mon Sep 17 00:00:00 2001 From: Achilles Rasquinha Date: Wed, 21 Mar 2018 12:37:04 +0530 Subject: [PATCH 07/14] user image fix --- frappe/core/doctype/user/user.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index edf4c285b4..69d6cb1628 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -68,6 +68,7 @@ class User(Document): self.validate_user_email_inbox() ask_pass_update() self.validate_roles() + self.validate_user_image() if self.language == "Loading...": self.language = None @@ -81,6 +82,10 @@ class User(Document): self.set('roles', []) self.append_roles(*[role.role for role in role_profile.roles]) + def validate_user_image(self): + if len(self.user_image) > 2000: + frappe.throw(_("Not a valid User Image.")) + def on_update(self): # clear new password self.validate_user_limit() From 73aeb5ea96252507721018ae22c47d3c2d2555d9 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 21 Mar 2018 15:27:24 +0530 Subject: [PATCH 08/14] fix test --- frappe/core/doctype/user/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 69d6cb1628..ab5609a5da 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -83,7 +83,7 @@ class User(Document): self.append_roles(*[role.role for role in role_profile.roles]) def validate_user_image(self): - if len(self.user_image) > 2000: + if self.user_image and len(self.user_image) > 2000: frappe.throw(_("Not a valid User Image.")) def on_update(self): From 13f0f19f75f56e0c87845a6b499da9d515a1a4b6 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Thu, 22 Mar 2018 11:15:01 +0530 Subject: [PATCH 09/14] [Fix] RTL for document print (#5244) --- frappe/www/printview.html | 3 +++ frappe/www/printview.py | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/frappe/www/printview.html b/frappe/www/printview.html index 6136426593..ecefab57ad 100644 --- a/frappe/www/printview.html +++ b/frappe/www/printview.html @@ -9,6 +9,9 @@ href="/assets/frappe/css/bootstrap.css"> + {%- if has_rtl -%} + + {%- endif -%} diff --git a/frappe/www/printview.py b/frappe/www/printview.py index 82af3e1f3c..b4e085242d 100644 --- a/frappe/www/printview.py +++ b/frappe/www/printview.py @@ -41,7 +41,8 @@ def get_context(context): no_letterhead=frappe.form_dict.no_letterhead), "css": get_print_style(frappe.form_dict.style, print_format), "comment": frappe.session.user, - "title": doc.get(meta.title_field) if meta.title_field else doc.name + "title": doc.get(meta.title_field) if meta.title_field else doc.name, + "has_rtl": True if frappe.local.lang in ["ar", "he", "fa"] else False } def get_print_format_doc(print_format_name, meta): From 3dab3478db0c4c4c206e1b98c70d7fa59ac862c7 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 22 Mar 2018 12:14:21 +0530 Subject: [PATCH 10/14] Minor fix in autonaming --- frappe/model/naming.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/model/naming.py b/frappe/model/naming.py index 88fba659c9..e769ac06ac 100644 --- a/frappe/model/naming.py +++ b/frappe/model/naming.py @@ -47,7 +47,7 @@ def set_new_name(doc): if autoname.startswith("naming_series:"): set_name_by_naming_series(doc) elif "#" in autoname: - doc.name = make_autoname(autoname) + doc.name = make_autoname(autoname, doc=doc) elif autoname.lower()=='prompt': # set from __newname in save.py if not doc.name: From 763360c68fb16d19f124aabe6b62f4351f42ec2d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 22 Mar 2018 12:55:42 +0530 Subject: [PATCH 11/14] minor fix in syncing after ajax --- frappe/public/js/frappe/model/sync.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frappe/public/js/frappe/model/sync.js b/frappe/public/js/frappe/model/sync.js index ddcd587695..284e9b2cb4 100644 --- a/frappe/public/js/frappe/model/sync.js +++ b/frappe/public/js/frappe/model/sync.js @@ -33,10 +33,6 @@ $.extend(frappe.model, { frappe.meta.sync(d); } - if(cur_frm && cur_frm.doctype==d.doctype && cur_frm.docname==d.name) { - cur_frm.doc = d; - } - if(d.localname) { frappe.model.new_names[d.localname] = d.name; $(document).trigger('rename', [d.doctype, d.localname, d.name]); From d0f3b9b6e6c47dcd0d1f641cf22b2ac7c76631b0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 23 Mar 2018 15:09:28 +0530 Subject: [PATCH 12/14] Dropbox settings UX fix (#5253) * Fixed dropbox UX issue * Fixed typo --- .../dropbox_settings/dropbox_settings.js | 5 ++- .../dropbox_settings/dropbox_settings.json | 40 +++---------------- .../dropbox_settings/dropbox_settings.py | 11 ++--- 3 files changed, 14 insertions(+), 42 deletions(-) diff --git a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.js b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.js index 2e3c707a5e..c264d12dec 100644 --- a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.js +++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.js @@ -3,6 +3,7 @@ frappe.ui.form.on('Dropbox Settings', { refresh: function(frm) { + frm.toggle_display(["app_access_key", "app_secret_key"], !(frm.doc.__onload && frm.doc.__onload.dropbox_setup_via_site_config)); frm.clear_custom_buttons(); frm.events.take_backup(frm); }, @@ -19,7 +20,7 @@ frappe.ui.form.on('Dropbox Settings', { } }) } - else if (frm.doc.dropbox_setup_via_site_config) { + else if (frm.doc.__onload && frm.doc.__onload.dropbox_setup_via_site_config) { frappe.call({ method: "frappe.integrations.doctype.dropbox_settings.dropbox_settings.get_redirect_url", freeze: true, @@ -36,7 +37,7 @@ frappe.ui.form.on('Dropbox Settings', { }, take_backup: function(frm) { - if ((frm.doc.app_access_key && frm.doc.app_secret_key) || frm.doc.dropbox_setup_via_site_config){ + if ((frm.doc.app_access_key && frm.doc.app_secret_key) || (frm.doc.__onload && frm.doc.__onload.dropbox_setup_via_site_config)){ frm.add_custom_button(__("Take Backup Now"), function(frm){ frappe.call({ method: "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backup", diff --git a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json index cbe1fe8b1a..a8ab581bf7 100644 --- a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json +++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json @@ -54,7 +54,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Send Notifications To", "length": 0, @@ -84,7 +84,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Backup Frequency", "length": 0, @@ -108,7 +108,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:!doc.dropbox_setup_via_site_config", + "depends_on": "", "fieldname": "app_access_key", "fieldtype": "Data", "hidden": 0, @@ -139,7 +139,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:!doc.dropbox_setup_via_site_config", + "depends_on": "", "fieldname": "app_secret_key", "fieldtype": "Password", "hidden": 0, @@ -283,36 +283,6 @@ "search_index": 0, "set_only_once": 0, "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "dropbox_setup_via_site_config", - "fieldtype": "Check", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Dropbox Setup via Site Config", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 } ], "has_web_view": 0, @@ -325,7 +295,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2017-06-20 15:45:33.683827", + "modified": "2018-03-22 16:02:00.597029", "modified_by": "Administrator", "module": "Integrations", "name": "Dropbox Settings", diff --git a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py index 35027b90c9..283546320f 100644 --- a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py +++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py @@ -20,7 +20,8 @@ ignore_list = [".DS_Store"] class DropboxSettings(Document): def onload(self): if not self.app_access_key and frappe.conf.dropbox_access_key: - self.dropbox_setup_via_site_config = 1 + self.set_onload("dropbox_setup_via_site_config", 1) + @frappe.whitelist() def take_backup(): @@ -171,7 +172,7 @@ def upload_file_to_dropbox(filename, folder, dropbox_client): cursor.offset = f.tell() except dropbox.exceptions.ApiError as e: if isinstance(e.error, dropbox.files.UploadError): - error = "File Path: {path}\n".foramt(path=path) + error = "File Path: {path}\n".format(path=path) error += frappe.get_traceback() frappe.log_error(error) else: @@ -201,7 +202,7 @@ def get_dropbox_settings(redirect_uri=False): if redirect_uri: app_details.update({ - 'rediret_uri': get_request_site_address(True) \ + 'redirect_uri': get_request_site_address(True) \ + '/api/method/frappe.integrations.doctype.dropbox_settings.dropbox_settings.dropbox_auth_finish' \ if settings.app_secret_key else frappe.conf.dropbox_broker_site\ + '/api/method/dropbox_erpnext_broker.www.setup_dropbox.generate_dropbox_access_token', @@ -233,7 +234,7 @@ def get_dropbox_authorize_url(): dropbox_oauth_flow = dropbox.DropboxOAuth2Flow( app_details["app_key"], app_details["app_secret"], - app_details["rediret_uri"], + app_details["redirect_uri"], {}, "dropbox-auth-csrf-token" ) @@ -254,7 +255,7 @@ def dropbox_auth_finish(return_access_token=False): dropbox_oauth_flow = dropbox.DropboxOAuth2Flow( app_details["app_key"], app_details["app_secret"], - app_details["rediret_uri"], + app_details["redirect_uri"], { 'dropbox-auth-csrf-token': callback.state }, From 577ce03fd8e8d8058097a59da3372cee9c31ef7d Mon Sep 17 00:00:00 2001 From: Zarrar Date: Fri, 23 Mar 2018 15:13:58 +0530 Subject: [PATCH 13/14] [Hotfix] File upload fix (#5254) * append hash if same filename found while uploading through socketio * pass file size * upload after filename change --- frappe/public/js/frappe/upload.js | 48 +++++++++++++++++++------------ frappe/utils/file_manager.py | 7 +++++ 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/frappe/public/js/frappe/upload.js b/frappe/public/js/frappe/upload.js index c5ed49f29c..c913825b67 100644 --- a/frappe/public/js/frappe/upload.js +++ b/frappe/public/js/frappe/upload.js @@ -296,26 +296,38 @@ frappe.upload = { if (opts.no_socketio || frappe.flags.no_socketio || file_not_big_enough) { upload_with_filedata(); return; + } else { + args.file_size = fileobj.size; + frappe.call({ + method: 'frappe.utils.file_manager.validate_filename', + args: {"filename": args.filename}, + callback: function(r) { + args.filename = r.message; + upload_through_socketio(); + } + }); } - frappe.socketio.uploader.start({ - file: fileobj, - filename: args.filename, - is_private: args.is_private, - fallback: () => { - // if fails, use old filereader - upload_with_filedata(); - }, - callback: (data) => { - args.file_url = data.file_url; - frappe.upload._upload_file(fileobj, args, opts); - }, - on_progress: (percent_complete) => { - let increment = (flt(percent_complete) / frappe.upload.total_files); - frappe.show_progress(__('Uploading'), - start_complete + increment); - } - }); + var upload_through_socketio = function() { + frappe.socketio.uploader.start({ + file: fileobj, + filename: args.filename, + is_private: args.is_private, + fallback: () => { + // if fails, use old filereader + upload_with_filedata(); + }, + callback: (data) => { + args.file_url = data.file_url; + frappe.upload._upload_file(fileobj, args, opts); + }, + on_progress: (percent_complete) => { + let increment = (flt(percent_complete) / frappe.upload.total_files); + frappe.show_progress(__('Uploading'), + start_complete + increment); + } + }); + } }, upload_to_server: function(file, args, opts) { diff --git a/frappe/utils/file_manager.py b/frappe/utils/file_manager.py index a62f04eb10..638637b9ee 100644 --- a/frappe/utils/file_manager.py +++ b/frappe/utils/file_manager.py @@ -84,6 +84,7 @@ def save_url(file_url, filename, dt, dn, folder, is_private, df=None): # return None, None file_url = unquote(file_url) + file_size = frappe.form_dict.file_size f = frappe.get_doc({ "doctype": "File", @@ -93,6 +94,7 @@ def save_url(file_url, filename, dt, dn, folder, is_private, df=None): "attached_to_name": dn, "attached_to_field": df, "folder": folder, + "file_size": file_size, "is_private": is_private }) f.flags.ignore_permissions = True @@ -392,3 +394,8 @@ def get_random_filename(extn=None, content_type=None): extn = mimetypes.guess_extension(content_type) return random_string(7) + (extn or "") + +@frappe.whitelist() +def validate_filename(filename): + fname = get_file_name(filename, hashlib.md5(filename).hexdigest()[-6:]) + return fname From fa20790ac9c15af418a943d87ad839aa5d18bdc1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 23 Mar 2018 15:45:35 +0600 Subject: [PATCH 14/14] bumped to version 10.1.7 --- frappe/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 196d6da92d..9ce53286ab 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -14,7 +14,7 @@ import os, sys, importlib, inspect, json from .exceptions import * from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template -__version__ = '10.1.6' +__version__ = '10.1.7' __title__ = "Frappe Framework" local = Local()