diff --git a/.travis.yml b/.travis.yml index e9e5c0e183..77e3c6662f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,7 @@ before_script: - echo "USE mysql;\nGRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost';\n" | mysql -u root -ptravis - cd ~/frappe-bench + - npm install babel-core less chokidar babel-preset-es2015 babel-preset-es2016 babel-preset-es2017 babel-preset-babili - bench use test_site - bench reinstall --yes - bench start & diff --git a/frappe/__init__.py b/frappe/__init__.py index 11bb9bc60f..666290f93f 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -13,7 +13,7 @@ import os, sys, importlib, inspect, json from .exceptions import * from .utils.jinja import get_jenv, get_template, render_template -__version__ = '8.0.55' +__version__ = '8.0.56' __title__ = "Frappe Framework" local = Local() diff --git a/frappe/app.py b/frappe/app.py index f6d89d15b2..0813e82635 100644 --- a/frappe/app.py +++ b/frappe/app.py @@ -65,7 +65,7 @@ def application(request): elif frappe.request.path.startswith('/private/files/'): response = frappe.utils.response.download_private_file(request.path) - elif frappe.local.request.method in ('GET', 'HEAD'): + elif frappe.local.request.method in ('GET', 'HEAD', 'POST'): response = frappe.website.render.render() else: @@ -122,6 +122,7 @@ def make_form_dict(request): frappe.local.form_dict.pop("_") def handle_exception(e): + response = None http_status_code = getattr(e, "http_status_code", 500) return_as_message = False diff --git a/frappe/auth.py b/frappe/auth.py index e2f2e2c1f0..3612b98f04 100644 --- a/frappe/auth.py +++ b/frappe/auth.py @@ -185,6 +185,9 @@ class LoginManager: if not (user and pwd): self.fail('Incomplete login details', user=user) + if cint(frappe.db.get_value("System Settings", "System Settings", "allow_login_using_mobile_number")): + user = frappe.db.get_value("User", filters={"mobile_no": user}, fieldname="name") or user + self.check_if_enabled(user) self.user = self.check_password(user, pwd) diff --git a/frappe/build.js b/frappe/build.js index e0b0a5f8db..4d14b933c5 100644 --- a/frappe/build.js +++ b/frappe/build.js @@ -24,7 +24,7 @@ const build_map = make_build_map(); // command line args const action = process.argv[2] || '--build'; -if (!['--build', '--watch'].includes(action)) { +if (['--build', '--watch'].indexOf(action) === -1) { console.log('Invalid argument: ', action); return; } diff --git a/frappe/build.py b/frappe/build.py index 56339f7c76..9e7f928d03 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -31,7 +31,7 @@ def bundle(no_compress, make_copy=False, verbose=False): make_asset_dirs(make_copy=make_copy) # new nodejs build system - command = 'node ../apps/frappe/frappe/build.js --build' + command = 'node --use_strict ../apps/frappe/frappe/build.js --build' if not no_compress: command += ' --minify' subprocess.call(command.split(' ')) @@ -42,7 +42,7 @@ def watch(no_compress): """watch and rebuild if necessary""" # new nodejs file watcher - command = 'node ../apps/frappe/frappe/build.js --watch' + command = 'node --use_strict ../apps/frappe/frappe/build.js --watch' subprocess.call(command.split(' ')) # setup() diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py index 855681be5d..aa9a7c3a4e 100644 --- a/frappe/core/doctype/communication/communication.py +++ b/frappe/core/doctype/communication/communication.py @@ -11,7 +11,8 @@ from frappe.core.doctype.communication.comment import (notify_mentions, from frappe.core.doctype.communication.email import (validate_email, notify, _notify, update_parent_status) from frappe.utils.bot import BotReply -from email.utils import parseaddr +from frappe.utils import parse_addr + from collections import Counter exclude_from_linked_with = True @@ -140,14 +141,9 @@ class Communication(Document): else: if self.sent_or_received=='Sent': validate_email_add(self.sender, throw=True) - - sender_name, sender_email = parseaddr(self.sender) - - if not sender_name: - sender_name = get_fullname(sender_email) - if sender_name == sender_email: - sender_name = None - + sender_name, sender_email = parse_addr(self.sender) + if sender_name == sender_email: + sender_name = None self.sender = sender_email self.sender_full_name = sender_name or get_fullname(frappe.session.user) if frappe.session.user!='Administrator' else None diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index 4f1c7ccabc..3af3def992 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -5,9 +5,9 @@ from __future__ import unicode_literals, absolute_import from six.moves import range import frappe import json -from email.utils import formataddr, parseaddr +from email.utils import formataddr from frappe.utils import (get_url, get_formatted_email, cint, - validate_email_add, split_emails, time_diff_in_seconds) + validate_email_add, split_emails, time_diff_in_seconds, parse_addr) from frappe.utils.file_manager import get_file from frappe.email.queue import check_email_limit from frappe.utils.scheduler import log @@ -321,11 +321,11 @@ def get_cc(doc, recipients=None, fetched_from_email_account=False): # exclude unfollows, recipients and unsubscribes exclude = [] #added to remove account check exclude += [d[0] for d in frappe.db.get_all("User", ["name"], {"thread_notify": 0}, as_list=True)] - exclude += [(parseaddr(email)[1] or "").lower() for email in recipients] + exclude += [(parse_addr(email)[1] or "").lower() for email in recipients] if fetched_from_email_account: # exclude sender when pulling email - exclude += [parseaddr(doc.sender)[1]] + exclude += [parse_addr(doc.sender)[1]] if doc.reference_doctype and doc.reference_name: exclude += [d[0] for d in frappe.db.get_all("Email Unsubscribe", ["email"], @@ -356,7 +356,7 @@ def filter_email_list(doc, email_list, exclude, is_cc=False): email_address_list = [] for email in list(set(email_list)): - email_address = (parseaddr(email)[1] or "").lower() + email_address = (parse_addr(email)[1] or "").lower() if not email_address: continue diff --git a/frappe/core/doctype/communication/test_communication.py b/frappe/core/doctype/communication/test_communication.py index 8b09cf6bee..653904a07b 100644 --- a/frappe/core/doctype/communication/test_communication.py +++ b/frappe/core/doctype/communication/test_communication.py @@ -4,8 +4,27 @@ from __future__ import unicode_literals import frappe import unittest - test_records = frappe.get_test_records('Communication') + class TestCommunication(unittest.TestCase): - pass + + def test_parse_addr(self): + valid_email_list = ["me@example.com", "a.nonymous@example.com", "name@tag@example.com", + "foo@example.com", 'Full Name ', + '"Full Name with quotes and " ', + 'foo@bar@google.com', 'Surname, Name ', + 'Purchase@ABC ', 'xyz@abc2.com ', + 'Name [something else] ', + '.com@test@yahoo.com'] + + invalid_email_list = ['[invalid!email]', 'invalid-email', + 'tes2', 'e', 'rrrrrrrr', 'manas','[[[sample]]]', + '[invalid!email].com'] + + for x in valid_email_list: + self.assertTrue(frappe.utils.parse_addr(x)) + + for x in invalid_email_list: + self.assertFalse(frappe.utils.parse_addr(x)[0]) + diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index 0a84b1a791..5db186d340 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -770,6 +770,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "User can login using Email id or Mobile number", + "fieldname": "allow_login_using_mobile_number", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Allow Login using Mobile Number", + "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 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -902,7 +933,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2017-05-11 15:27:11.079447", + "modified": "2017-05-19 09:12:50.353887", "modified_by": "Administrator", "module": "Core", "name": "System Settings", diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json index c32339421c..3eda403272 100644 --- a/frappe/core/doctype/user/user.json +++ b/frappe/core/doctype/user/user.json @@ -14,6 +14,7 @@ "engine": "InnoDB", "fields": [ { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -42,6 +43,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -73,6 +75,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -102,6 +105,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -133,6 +137,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -163,6 +168,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -193,6 +199,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 1, "collapsible": 0, @@ -223,6 +230,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -252,6 +260,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 1, "collapsible": 0, @@ -283,6 +292,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -311,6 +321,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -341,6 +352,7 @@ "width": "50%" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -370,6 +382,7 @@ "unique": 1 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -400,6 +413,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -429,6 +443,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -458,6 +473,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -488,6 +504,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -516,6 +533,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -546,6 +564,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -575,6 +594,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -606,6 +626,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -635,6 +656,37 @@ "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "mobile_no", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Mobile No", + "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": 1 + }, + { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -665,6 +717,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -693,6 +746,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -720,6 +774,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -748,6 +803,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -777,6 +833,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -806,6 +863,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -834,6 +892,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -864,6 +923,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -892,6 +952,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -921,6 +982,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -951,6 +1013,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -981,6 +1044,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1009,6 +1073,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -1038,6 +1103,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1069,6 +1135,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -1099,6 +1166,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1128,6 +1196,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1158,6 +1227,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -1189,6 +1259,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1218,6 +1289,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1248,6 +1320,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1280,6 +1353,7 @@ "width": "50%" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1310,6 +1384,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -1340,6 +1415,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1370,6 +1446,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1403,6 +1480,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1432,6 +1510,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1461,6 +1540,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1490,6 +1570,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1520,6 +1601,7 @@ "width": "50%" }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1550,6 +1632,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1580,6 +1663,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1609,6 +1693,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1639,6 +1724,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -1668,6 +1754,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1696,6 +1783,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1724,6 +1812,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1752,6 +1841,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1780,6 +1870,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1808,6 +1899,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1836,6 +1928,7 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1878,7 +1971,7 @@ "istable": 0, "max_attachments": 5, "menu_index": 0, - "modified": "2017-04-01 14:38:25.869060", + "modified": "2017-05-19 09:12:35.697915", "modified_by": "Administrator", "module": "Core", "name": "User", diff --git a/frappe/custom/doctype/customize_form/customize_form.js b/frappe/custom/doctype/customize_form/customize_form.js index d9b1496877..8308d5a85a 100644 --- a/frappe/custom/doctype/customize_form/customize_form.js +++ b/frappe/custom/doctype/customize_form/customize_form.js @@ -149,6 +149,7 @@ frappe.customize_form.set_primary_action = function(frm) { callback: function(r) { if(!r.exc) { frappe.customize_form.clear_locals_and_refresh(frm); + frm.script_manager.trigger("doc_type"); } } }); diff --git a/frappe/email/doctype/email_group/email_group.py b/frappe/email/doctype/email_group/email_group.py index 8551c2e33d..0aad49c1e6 100755 --- a/frappe/email/doctype/email_group/email_group.py +++ b/frappe/email/doctype/email_group/email_group.py @@ -7,7 +7,7 @@ import frappe from frappe import _ from frappe.utils import validate_email_add from frappe.model.document import Document -from email.utils import parseaddr +from frappe.utils import parse_addr class EmailGroup(Document): def onload(self): @@ -26,7 +26,7 @@ class EmailGroup(Document): for user in frappe.db.get_all(doctype, [email_field, unsubscribed_field or "name"]): try: - email = parseaddr(user.get(email_field))[1] + email = parse_addr(user.get(email_field))[1] if email: frappe.get_doc({ "doctype": "Email Group Member", diff --git a/frappe/email/doctype/newsletter/newsletter.py b/frappe/email/doctype/newsletter/newsletter.py index 29ec6e376d..a54ab28c8d 100755 --- a/frappe/email/doctype/newsletter/newsletter.py +++ b/frappe/email/doctype/newsletter/newsletter.py @@ -14,6 +14,7 @@ from frappe.utils.scheduler import log from frappe.email.queue import send from frappe.email.doctype.email_group.email_group import add_subscribers from frappe.utils.file_manager import get_file +from frappe.utils import parse_addr class Newsletter(Document): @@ -135,17 +136,15 @@ def return_unsubscribed_page(email, name): def create_lead(email_id): """create a lead if it does not exist""" - from email.utils import parseaddr from frappe.model.naming import get_default_naming_series - real_name, email_id = parseaddr(email_id) - + full_name, email_id = parse_addr(email_id) if frappe.db.get_value("Lead", {"email_id": email_id}): return lead = frappe.get_doc({ "doctype": "Lead", "email_id": email_id, - "lead_name": real_name or email_id, + "lead_name": full_name or email_id, "status": "Lead", "naming_series": get_default_naming_series("Lead"), "company": frappe.db.get_default("Company"), diff --git a/frappe/email/email_body.py b/frappe/email/email_body.py index a20484b8ab..43f79a3027 100755 --- a/frappe/email/email_body.py +++ b/frappe/email/email_body.py @@ -8,6 +8,7 @@ from frappe.email.smtp import get_outgoing_email_account from frappe.utils import (get_url, scrub_urls, strip, expand_relative_urls, cint, split_emails, to_markdown, markdown, encode, random_string) import email.utils +from frappe.utils import parse_addr def get_email(recipients, sender='', msg='', subject='[No Subject]', text_content = None, footer=None, print_html=None, formatted=None, attachments=None, @@ -179,8 +180,7 @@ class EMail: def replace_sender(self): if cint(self.email_account.always_use_account_email_id_as_sender): self.set_header('X-Original-From', self.sender) - - sender_name, sender_email = email.utils.parseaddr(self.sender) + sender_name, sender_email = parse_addr(self.sender) self.sender = email.utils.formataddr((sender_name or self.email_account.name, self.email_account.email_id)) def set_message_id(self, message_id, is_notification=False): diff --git a/frappe/email/receive.py b/frappe/email/receive.py index 039dd52723..33aa9c2d0b 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -9,7 +9,7 @@ from email.header import decode_header import frappe from frappe import _ from frappe.utils import (extract_email_id, convert_utc_to_user_timezone, now, - cint, cstr, strip, markdown) + cint, cstr, strip, markdown, parse_addr) from frappe.utils.scheduler import log from frappe.utils.file_manager import get_random_filename, save_file, MaxFileSizeReachedError import re @@ -411,7 +411,7 @@ class Email: if self.from_email: self.from_email = self.from_email.lower() - self.from_real_name = email.utils.parseaddr(_from_email)[0] if "@" in _from_email else _from_email + self.from_real_name = parse_addr(_from_email)[0] if "@" in _from_email else _from_email def decode_email(self, email): if not email: return diff --git a/frappe/frappeclient.py b/frappe/frappeclient.py index a090a0aa41..3ad77000e5 100644 --- a/frappe/frappeclient.py +++ b/frappe/frappeclient.py @@ -5,9 +5,6 @@ import frappe ''' FrappeClient is a library that helps you connect with other frappe systems - - - ''' class AuthError(Exception): diff --git a/frappe/public/html/print_template.html b/frappe/public/html/print_template.html index 0cf8a343a3..78df4aca94 100644 --- a/frappe/public/html/print_template.html +++ b/frappe/public/html/print_template.html @@ -29,7 +29,11 @@ {% endif %} -