diff --git a/frappe/__init__.py b/frappe/__init__.py index 2c84fe4759..cc2f0fd8df 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -51,6 +51,13 @@ def _(msg, lang=None): return get_full_dict(local.lang).get(msg) or msg +def as_unicode(text, encoding='utf-8'): + '''Convert to unicode if required''' + if text and not isinstance(text, unicode): + return unicode(text, encoding) + else: + return text or '' + def get_lang_dict(fortype, name=None): """Returns the translated language dict for the given type and name. diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index 575f86f5ba..7e04c8f609 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -347,10 +347,10 @@ class EmailAccount(Document): parent = frappe.new_doc(self.append_to) if self.subject_field: - parent.set(self.subject_field, email.subject) + parent.set(self.subject_field, frappe.as_unicode(email.subject)) if self.sender_field: - parent.set(self.sender_field, email.from_email) + parent.set(self.sender_field, frappe.as_unicode(email.from_email)) parent.flags.ignore_mandatory = True diff --git a/frappe/public/css/form.css b/frappe/public/css/form.css index c595c6c726..33bf2ae74a 100644 --- a/frappe/public/css/form.css +++ b/frappe/public/css/form.css @@ -415,9 +415,6 @@ h6.uppercase, .frappe-control pre { white-space: pre-wrap; } -.frappe-control:last-child { - margin-bottom: 0px; -} .hide-control { display: none !important; } @@ -510,17 +507,20 @@ select.form-control { .form-page .form-section { padding: 0px 15px; } - .form-page .frappe-control { + .frappe-control.form-page { padding: 7px 15px; border-bottom: 1px solid #EBEFF2; margin: 0px -15px; } - .form-page .frappe-control .link-btn { + .frappe-control.form-page .link-btn { top: -2px; } - .form-page .frappe-control .like-disabled-input { + .frappe-control.form-page .like-disabled-input { min-height: 0px !important; } + .frappe-control.form-page:last-child { + margin-bottom: 0px; + } .form-page .frappe-control:last-child { border-bottom: 0px; } diff --git a/frappe/public/less/form.less b/frappe/public/less/form.less index 0af79d0ebd..7d69079835 100644 --- a/frappe/public/less/form.less +++ b/frappe/public/less/form.less @@ -522,10 +522,6 @@ h6.uppercase, .h6.uppercase { pre { white-space: pre-wrap; } - - &:last-child { - margin-bottom: 0px; - } } .hide-control { @@ -651,7 +647,7 @@ select.form-control { padding: 0px 15px; } - .frappe-control { + .frappe-control& { padding: 7px 15px; border-bottom: 1px solid @light-border-color; margin: 0px -15px; @@ -663,6 +659,10 @@ select.form-control { .like-disabled-input { min-height: 0px !important; } + + &:last-child { + margin-bottom: 0px; + } } .frappe-control:last-child { diff --git a/frappe/utils/__init__.py b/frappe/utils/__init__.py index 3a7884066e..a8e1abef45 100644 --- a/frappe/utils/__init__.py +++ b/frappe/utils/__init__.py @@ -118,6 +118,7 @@ def random_string(length): from random import choice return ''.join([choice(string.letters + string.digits) for i in range(length)]) + def has_gravatar(email): '''Returns gravatar url if user has set an avatar at gravatar.com''' if (frappe.flags.in_import @@ -127,10 +128,7 @@ def has_gravatar(email): # since querying gravatar for every item will be slow return '' - if not isinstance(email, unicode): - email = unicode(email, 'utf-8') - - hexdigest = md5.md5(email).hexdigest() + hexdigest = md5.md5(frappe.as_unicode(email)).hexdigest() gravatar_url = "https://secure.gravatar.com/avatar/{hash}?d=404&s=200".format(hash=hexdigest) try: diff --git a/frappe/utils/password_strength.py b/frappe/utils/password_strength.py index bc0b6ad8c3..215ba1cba0 100644 --- a/frappe/utils/password_strength.py +++ b/frappe/utils/password_strength.py @@ -23,7 +23,7 @@ import re from zxcvbn import scoring # Default feedback value -feedback = { +default_feedback = { "warning": "", "suggestions":[ _("Use a few words, avoid common phrases."), @@ -35,9 +35,10 @@ def get_feedback (score, sequence): """ Returns the feedback dictionary consisting of ("warning","suggestions") for the given sequences. """ + global default_feedback # Starting feedback if len(sequence) == 0: - return feedback + return default_feedback # No feedback if score is good or great if score > 2: return dict({"warning": "","suggestions": []}) @@ -119,6 +120,7 @@ def get_match_feedback(match, is_sole_match): _("Avoid dates and years that are associated with you.") ], } + # Dictionary that maps pattern names to funtions that return feedback patterns = { "bruteforce": fun_bruteforce, @@ -128,6 +130,7 @@ def get_match_feedback(match, is_sole_match): "sequence": fun_sequence, "regex": fun_regex, "date": fun_date, + "year": fun_date } return(patterns[match['pattern']]())