diff --git a/frappe/__init__.py b/frappe/__init__.py index 282f36f186..dc3a02afb9 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -24,7 +24,7 @@ if sys.version[0] == '2': reload(sys) sys.setdefaultencoding("utf-8") -__version__ = '11.1.6' +__version__ = '11.1.7' __title__ = "Frappe Framework" local = Local() @@ -919,11 +919,15 @@ def get_hooks(hook=None, default=None, app_name=None): append_hook(hooks, key, getattr(app_hooks, key)) return hooks + no_cache = conf.developer_mode or False if app_name: hooks = _dict(load_app_hooks(app_name)) else: - hooks = _dict(cache().get_value("app_hooks", load_app_hooks)) + if no_cache: + hooks = _dict(load_app_hooks()) + else: + hooks = _dict(cache().get_value("app_hooks", load_app_hooks)) if hook: return hooks.get(hook) or (default if default is not None else []) diff --git a/frappe/chat/doctype/chat_profile/chat_profile.py b/frappe/chat/doctype/chat_profile/chat_profile.py index 22ce94858d..ca33751519 100644 --- a/frappe/chat/doctype/chat_profile/chat_profile.py +++ b/frappe/chat/doctype/chat_profile/chat_profile.py @@ -9,99 +9,93 @@ import frappe from frappe.core.doctype.version.version import get_diff from frappe.chat.doctype.chat_room import chat_room from frappe.chat.util import ( - safe_json_loads, - filter_dict, - dictify + safe_json_loads, + filter_dict, + dictify ) session = frappe.session class ChatProfile(Document): - def before_save(self): - if not self.is_new(): - self.get_doc_before_save() + def before_save(self): + if not self.is_new(): + self.get_doc_before_save() - def on_update(self): - if not self.is_new(): - b, a = self.get_doc_before_save(), self - diff = dictify(get_diff(a, b)) - if diff: - user = session.user + def on_update(self): + if not self.is_new(): + b, a = self.get_doc_before_save(), self + diff = dictify(get_diff(a, b)) + if diff: + user = session.user - fields = [changed[0] for changed in diff.changed] + fields = [changed[0] for changed in diff.changed] - if 'status' in fields: - rooms = chat_room.get(user, filters = ['Chat Room', 'type', '=', 'Direct']) - update = dict(user = user, data = dict(status = self.status)) + if 'status' in fields: + rooms = chat_room.get(user, filters = ['Chat Room', 'type', '=', 'Direct']) + update = dict(user = user, data = dict(status = self.status)) - for room in rooms: - frappe.publish_realtime('frappe.chat.profile:update', update, room = room.name, after_commit = True) + for room in rooms: + frappe.publish_realtime('frappe.chat.profile:update', update, room = room.name, after_commit = True) - if 'enable_chat' in fields: - update = dict(user = user, data = dict(enable_chat = bool(self.enable_chat))) - frappe.publish_realtime('frappe.chat.profile:update', update, user = user, after_commit = True) + if 'enable_chat' in fields: + update = dict(user = user, data = dict(enable_chat = bool(self.enable_chat))) + frappe.publish_realtime('frappe.chat.profile:update', update, user = user, after_commit = True) def authenticate(user): - if user != session.user: - frappe.throw(_("Sorry, you're not authorized.")) + if user != session.user: + frappe.throw(_("Sorry, you're not authorized.")) @frappe.whitelist() def get(user, fields = None): - duser = frappe.get_doc('User', user) - dprof = frappe.get_doc('Chat Profile', user) + duser = frappe.get_doc('User', user) + dprof = frappe.get_doc('Chat Profile', user) - # If you're adding something here, make sure the client recieves it. - profile = dict( - # User - name = duser.name, - email = duser.email, - first_name = duser.first_name, - last_name = duser.last_name, - username = duser.username, - avatar = duser.user_image, - bio = duser.bio, - # Chat Profile - status = dprof.status, - chat_background = dprof.chat_background, - message_preview = bool(dprof.message_preview), - notification_tones = bool(dprof.notification_tones), - conversation_tones = bool(dprof.conversation_tones), - enable_chat = bool(dprof.enable_chat) - ) - profile = filter_dict(profile, fields) + # If you're adding something here, make sure the client recieves it. + profile = dict( + # User + name = duser.name, + email = duser.email, + first_name = duser.first_name, + last_name = duser.last_name, + username = duser.username, + avatar = duser.user_image, + bio = duser.bio, + # Chat Profile + status = dprof.status, + chat_background = dprof.chat_background, + message_preview = bool(dprof.message_preview), + notification_tones = bool(dprof.notification_tones), + conversation_tones = bool(dprof.conversation_tones), + enable_chat = bool(dprof.enable_chat) + ) + profile = filter_dict(profile, fields) - return dictify(profile) + return dictify(profile) @frappe.whitelist() def create(user, exists_ok = False, fields = None): - authenticate(user) + authenticate(user) - exists_ok, fields = safe_json_loads(exists_ok, fields) + exists_ok, fields = safe_json_loads(exists_ok, fields) - result = frappe.db.sql(""" - SELECT * - FROM `tabChat Profile` - WHERE `user` = '{user}' - """.format(user = user)) + try: + dprof = frappe.new_doc('Chat Profile') + dprof.user = user + dprof.save(ignore_permissions = True) + except frappe.DuplicateEntryError: + if not exists_ok: + frappe.throw(_('Chat Profile for User {0} exists.').format(user)) - if result: - if not exists_ok: - frappe.throw(_('Chat Profile for User {0} exists.').format(user)) - else: - dprof = frappe.new_doc('Chat Profile') - dprof.user = user - dprof.save(ignore_permissions = True) + profile = get(user, fields = fields) - profile = get(user, fields = fields) - - return profile + return profile @frappe.whitelist() def update(user, data): - authenticate(user) + authenticate(user) - data = safe_json_loads(data) + data = safe_json_loads(data) - dprof = frappe.get_doc('Chat Profile', user) - dprof.update(data) - dprof.save(ignore_permissions = True) \ No newline at end of file + dprof = frappe.get_doc('Chat Profile', user) + dprof.update(data) + dprof.save(ignore_permissions = True) \ No newline at end of file diff --git a/frappe/email/receive.py b/frappe/email/receive.py index 9bdf3a9ba3..09aa4ff57a 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -190,12 +190,10 @@ class EmailServer: # compare the UIDVALIDITY of email account and imap server uid_validity = self.settings.uid_validity - responce, message = self.imap.status("Inbox", "(UIDVALIDITY UIDNEXT)") - current_uid_validity = self.parse_imap_responce("UIDVALIDITY", message[0]) - if not current_uid_validity: - frappe.throw(_("Can not find UIDVALIDITY in imap status response")) + response, message = self.imap.status("Inbox", "(UIDVALIDITY UIDNEXT)") + current_uid_validity = self.parse_imap_response("UIDVALIDITY", message[0]) or 0 - uidnext = int(self.parse_imap_responce("UIDNEXT", message[0]) or "1") + uidnext = int(self.parse_imap_response("UIDNEXT", message[0]) or "1") frappe.db.set_value("Email Account", self.settings.email_account, "uidnext", uidnext) if not uid_validity or uid_validity != current_uid_validity: @@ -223,9 +221,9 @@ class EmailServer: elif uid_validity == current_uid_validity: return - def parse_imap_responce(self, cmd, responce): + def parse_imap_response(self, cmd, response): pattern = r"(?<={cmd} )[0-9]*".format(cmd=cmd) - match = re.search(pattern, responce.decode('utf-8'), re.U | re.I) + match = re.search(pattern, response.decode('utf-8'), re.U | re.I) if match: return match.group(0) else: diff --git a/frappe/public/js/frappe/form/controls/link.js b/frappe/public/js/frappe/form/controls/link.js index 1d413b83f8..86a99c970f 100644 --- a/frappe/public/js/frappe/form/controls/link.js +++ b/frappe/public/js/frappe/form/controls/link.js @@ -157,7 +157,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ me.set_custom_query(args); frappe.call({ - type: "GET", + type: "POST", method:'frappe.desk.search.search_link', no_spinner: true, args: args, diff --git a/frappe/public/js/frappe/form/controls/multiselect.js b/frappe/public/js/frappe/form/controls/multiselect.js index ae6a7a124e..fc5cb05010 100644 --- a/frappe/public/js/frappe/form/controls/multiselect.js +++ b/frappe/public/js/frappe/form/controls/multiselect.js @@ -32,6 +32,31 @@ frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({ }); }, + get_value() { + let data = this._super(); + // find value of label from option list and return actual value string + if (this.df.options[0].label) { + data = data.split(',').map(op => op.trim()); + data = data.map(val => { + let option = this.df.options.find(op => op.label === val); + return option ? option.value : null; + }).filter(n => n != null).join(', '); + } + return data; + }, + + set_formatted_input(value) { + if (!value) return; + // find label of value from option list and set from it as input + if (this.df.options[0].label) { + value = value.split(',').map(d => d.trim()).map(val => { + let option = this.df.options.find(op => op.value === val); + return option ? option.label : val; + }).filter(n => n != null).join(', '); + } + this._super(value); + }, + get_values() { const value = this.get_value() || ''; const values = value.split(/\s*,\s*/).filter(d => d); diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 946e7c221d..89133df515 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -877,7 +877,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { } return return_value; }); - + this.toggle_result_area(); this.render(); }); }); diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index fb15f6b561..4a4c42852a 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -84,8 +84,15 @@ frappe.get_route = function(route) { // for app route = frappe.get_raw_route_str(route).split('/'); route = $.map(route, frappe._decode_str); - var parts = route[route.length - 1].split("?"); - route[route.length - 1] = parts[0]; + var parts = null; + var doc_name = route[route.length - 1]; + // if the last part contains ? then check if it is valid query string + if(doc_name.indexOf("?") < doc_name.indexOf("=")){ + parts = doc_name.split("?"); + route[route.length - 1] = parts[0]; + } else { + parts = doc_name; + } if (parts.length > 1) { var query_params = frappe.utils.get_query_params(parts[1]); frappe.route_options = $.extend(frappe.route_options || {}, query_params);