diff --git a/frappe/__init__.py b/frappe/__init__.py index ce88d65257..abfa10305e 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -149,6 +149,7 @@ def init(site, sites_path=None, new_site=False): local.jenv = None local.jloader =None local.cache = {} + local.meta_cache = {} local.form_dict = _dict() local.session = _dict() diff --git a/frappe/commands/__init__.py b/frappe/commands/__init__.py index e944aeb9cf..51cb08fbae 100644 --- a/frappe/commands/__init__.py +++ b/frappe/commands/__init__.py @@ -29,7 +29,10 @@ def pass_context(f): ps = pstats.Stats(pr, stream=s)\ .sort_stats('cumtime', 'tottime', 'ncalls') ps.print_stats() - print(s.getvalue()) + + # print the top-100 + for line in s.getvalue().splitlines()[:100]: + print(line) return ret diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index 37298b07f1..549b1d351f 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -35,6 +35,7 @@ class DocType(Document): - Check fieldnames (duplication etc) - Clear permission table for child tables - Add `amended_from` and `amended_by` if Amendable""" + self.check_developer_mode() self.validate_name() @@ -215,6 +216,10 @@ class DocType(Document): if not frappe.flags.in_install and hasattr(self, 'before_update'): self.sync_global_search() + # clear from local cache + if self.name in frappe.local.meta_cache: + del frappe.local.meta_cache[self.name] + def sync_global_search(self): '''If global search settings are changed, rebuild search properties for this table''' global_search_fields_before_update = [d.fieldname for d in @@ -419,7 +424,7 @@ def validate_fields(meta): def check_in_list_view(d): if d.in_list_view and (d.fieldtype in not_allowed_in_list_view): frappe.throw(_("'In List View' not allowed for type {0} in row {1}").format(d.fieldtype, d.idx)) - + def check_in_global_search(d): if d.in_global_search and d.fieldtype in no_value_fields: frappe.throw(_("'In Global Search' not allowed for type {0} in row {1}") diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 73ea87d0a7..298b798c99 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -59,7 +59,6 @@ class User(Document): self.set_system_user() self.set_full_name() self.check_enable_disable() - self.update_gravatar() self.ensure_unique_roles() self.remove_all_roles_for_guest() self.validate_username() @@ -80,6 +79,8 @@ class User(Document): clear_notifications(user=self.name) frappe.clear_cache(user=self.name) self.send_password_notification(self.__new_password) + if self.name not in ('Administrator', 'Guest') and not self.user_image: + frappe.enqueue('frappe.core.doctype.user.user.update_gravatar', name=self.name) def has_website_permission(self, ptype, verbose=False): """Returns true if current user is the session user""" @@ -193,11 +194,6 @@ class User(Document): print frappe.get_traceback() pass # email server not set, don't send email - - def update_gravatar(self): - if not self.user_image: - self.user_image = has_gravatar(self.name) - @Document.hook def validate_reset_password(self): pass @@ -554,7 +550,6 @@ def test_password_strength(new_password, key=None, old_password=None, user_data= if new_password: result = _test_password_strength(new_password, user_inputs=user_data) - enable_password_policy = cint(frappe.db.get_single_value("System Settings", "enable_password_policy")) and True or False minimum_password_score = cint(frappe.db.get_single_value("System Settings", "minimum_password_score")) or 0 password_policy_validation_passed = False @@ -620,16 +615,16 @@ def setup_user_email_inbox(email_account, awaiting_password, email_id, enable_ou return for user in user_names: - user = user.get("name") + user_name = user.get("name") # check if inbox is alreay configured user_inbox = frappe.db.get_value("User Email", { "email_account": email_account, - "parent": user + "parent": user_name }, ["name"]) or None if not user_inbox: - add_user_email(user) + add_user_email(user_name) else: # update awaiting password for email account udpate_user_email_settings = True @@ -882,3 +877,8 @@ def handle_password_test_fail(result): warning = result['feedback']['warning'] if 'warning' in result['feedback'] else '' suggestions += "
" + _("Hint: Include symbols, numbers and capital letters in the password") + '
' frappe.throw(_('Invalid Password: ' + ' '.join([warning, suggestions]))) + +def update_gravatar(name): + gravatar = has_gravatar(name) + if gravatar: + frappe.db.set_value('User', name, 'user_image', gravatar) \ No newline at end of file diff --git a/frappe/model/meta.py b/frappe/model/meta.py index a453b614f2..244f30c79e 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -28,7 +28,9 @@ from frappe import _ def get_meta(doctype, cached=True): if cached: - return frappe.cache().hget("meta", doctype, lambda: Meta(doctype)) + if not frappe.local.meta_cache.get(doctype): + frappe.local.meta_cache[doctype] = frappe.cache().hget("meta", doctype, lambda: Meta(doctype)) + return frappe.local.meta_cache[doctype] else: return Meta(doctype) @@ -469,7 +471,7 @@ def get_default_df(fieldname): def trim_tables(doctype=None): """Use this to remove columns that don't exist in meta""" ignore_fields = default_fields + optional_fields - + filters={ "issingle": 0 } if doctype: filters["name"] = doctype @@ -490,6 +492,9 @@ def trim_tables(doctype=None): def clear_cache(doctype=None): cache = frappe.cache() + if doctype in frappe.local.meta_cache: + del frappe.local.meta_cache[doctype] + for key in ('is_table', 'doctype_modules'): cache.delete_value(key) diff --git a/frappe/model/utils/link_count.py b/frappe/model/utils/link_count.py index 34f2375a1d..01f5214f1b 100644 --- a/frappe/model/utils/link_count.py +++ b/frappe/model/utils/link_count.py @@ -30,7 +30,7 @@ def update_link_count(): if key[0] not in ignore_doctypes: try: frappe.db.sql('update `tab{0}` set idx = idx + {1} where name=%s'.format(key[0], count), - key[1]) + key[1], auto_commit=1) except Exception, e: if e.args[0]!=1146: # table not found, single raise e diff --git a/frappe/utils/data.py b/frappe/utils/data.py index e5cf25edeb..1f41f82de1 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -55,7 +55,10 @@ def get_datetime(datetime_str=None): if not datetime_str or (datetime_str or "").startswith("0000-00-00"): return None - return parser.parse(datetime_str) + try: + return datetime.datetime.strptime(datetime_str, DATETIME_FORMAT) + except ValueError: + return parser.parse(datetime_str) def to_timedelta(time_str): if isinstance(time_str, basestring): @@ -438,7 +441,7 @@ def money_in_words(number, main_currency = None, fraction_currency=None): number_format = frappe.db.get_value("Currency", main_currency, "number_format", cache=True) or \ frappe.db.get_default("number_format") or "#,###.##" - + fraction_length = get_number_format_info(number_format)[2] n = "%.{0}f".format(fraction_length) % number