@@ -490,10 +490,11 @@ def setup_module_map(): | |||||
_cache.set_value("module_app", local.module_app) | _cache.set_value("module_app", local.module_app) | ||||
def get_file_items(path, raise_not_found=False, ignore_empty_lines=True): | def get_file_items(path, raise_not_found=False, ignore_empty_lines=True): | ||||
import frappe.utils | |||||
content = read_file(path, raise_not_found=raise_not_found) | content = read_file(path, raise_not_found=raise_not_found) | ||||
if content: | if content: | ||||
# \ufeff is no-width-break, \u200b is no-width-space | |||||
content = content.replace("\ufeff", "").replace("\u200b", "").strip() | |||||
content = frappe.utils.strip(content) | |||||
return [p.strip() for p in content.splitlines() if (not ignore_empty_lines) or (p.strip() and not p.startswith("#"))] | return [p.strip() for p in content.splitlines() if (not ignore_empty_lines) or (p.strip() and not p.startswith("#"))] | ||||
else: | else: | ||||
@@ -64,7 +64,11 @@ def extract_email_id(email): | |||||
def validate_email_add(email_str): | def validate_email_add(email_str): | ||||
"""Validates the email string""" | """Validates the email string""" | ||||
email = extract_email_id(email_str) | email = extract_email_id(email_str) | ||||
return re.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", email.lower()) | |||||
match = re.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", email.lower()) | |||||
if not match: | |||||
return False | |||||
return match.group(0)==email.lower() | |||||
def random_string(length): | def random_string(length): | ||||
"""generate a random string""" | """generate a random string""" | ||||
@@ -598,3 +598,7 @@ def unique(seq): | |||||
seen = set() | seen = set() | ||||
seen_add = seen.add | seen_add = seen.add | ||||
return [ x for x in seq if not (x in seen or seen_add(x)) ] | return [ x for x in seq if not (x in seen or seen_add(x)) ] | ||||
def strip(val, chars=None): | |||||
# \ufeff is no-width-break, \u200b is no-width-space | |||||
return (val or "").replace("\ufeff", "").replace("\u200b", "").strip(chars) |
@@ -4,7 +4,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
from frappe import msgprint, throw, _ | from frappe import msgprint, throw, _ | ||||
from frappe.utils import scrub_urls, get_url | |||||
from frappe.utils import scrub_urls, get_url, strip | |||||
from frappe.utils.pdf import get_pdf | from frappe.utils.pdf import get_pdf | ||||
import email.utils | import email.utils | ||||
from markdown2 import markdown | from markdown2 import markdown | ||||
@@ -41,7 +41,7 @@ class EMail: | |||||
recipients = recipients.split(',') | recipients = recipients.split(',') | ||||
# remove null | # remove null | ||||
recipients = filter(None, (r.strip() for r in recipients)) | |||||
recipients = filter(None, (strip(r) for r in recipients)) | |||||
self.sender = sender | self.sender = sender | ||||
self.reply_to = reply_to or sender | self.reply_to = reply_to or sender | ||||
@@ -175,23 +175,24 @@ class EMail: | |||||
msgprint(_("Alternatively, you can also specify 'auto_email_id' in site_config.json")) | msgprint(_("Alternatively, you can also specify 'auto_email_id' in site_config.json")) | ||||
raise frappe.ValidationError, msg | raise frappe.ValidationError, msg | ||||
self.sender = _validate(self.sender) | |||||
self.reply_to = _validate(self.reply_to) | |||||
self.sender = _validate(strip(self.sender)) | |||||
self.reply_to = _validate(strip(self.reply_to) or self.sender) | |||||
self.recipients = [strip(r) for r in self.recipients] | |||||
self.cc = [strip(r) for r in self.cc] | |||||
for e in self.recipients + (self.cc or []): | for e in self.recipients + (self.cc or []): | ||||
_validate(e.strip()) | |||||
_validate(e) | |||||
def make(self): | def make(self): | ||||
"""build into msg_root""" | """build into msg_root""" | ||||
self.msg_root['Subject'] = self.subject.encode("utf-8") | |||||
self.msg_root['Subject'] = strip(self.subject).encode("utf-8") | |||||
self.msg_root['From'] = self.sender.encode("utf-8") | self.msg_root['From'] = self.sender.encode("utf-8") | ||||
self.msg_root['To'] = ', '.join([r.strip() for r in self.recipients]).encode("utf-8") | |||||
self.msg_root['To'] = ', '.join(self.recipients).encode("utf-8") | |||||
self.msg_root['Date'] = email.utils.formatdate() | self.msg_root['Date'] = email.utils.formatdate() | ||||
if not self.reply_to: | |||||
self.reply_to = self.sender | |||||
self.msg_root['Reply-To'] = self.reply_to.encode("utf-8") | self.msg_root['Reply-To'] = self.reply_to.encode("utf-8") | ||||
if self.cc: | if self.cc: | ||||
self.msg_root['CC'] = ', '.join([r.strip() for r in self.cc]).encode("utf-8") | |||||
self.msg_root['CC'] = ', '.join(self.cc).encode("utf-8") | |||||
# add frappe site header | # add frappe site header | ||||
self.msg_root.add_header(b'X-Frappe-Site', get_url().encode('utf-8')) | self.msg_root.add_header(b'X-Frappe-Site', get_url().encode('utf-8')) | ||||
@@ -23,7 +23,8 @@ def send(email, as_bulk=False): | |||||
email.reply_to = email.sender | email.reply_to = email.sender | ||||
email.sender = smtpserver.login | email.sender = smtpserver.login | ||||
smtpserver.sess.sendmail(email.sender, email.recipients + (email.cc or []), | |||||
smtpserver.sess.sendmail(email.sender.encode("utf-8"), | |||||
[e.encode("utf-8") for e in (email.recipients + (email.cc or []))], | |||||
email.as_string()) | email.as_string()) | ||||
except smtplib.SMTPSenderRefused: | except smtplib.SMTPSenderRefused: | ||||