From c48daa9e025583d9ddfa15f39cea2cb2cd13961f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 31 Jan 2014 16:08:27 +0530 Subject: [PATCH] more fixes to email --- .../doctype/communication/communication.py | 45 +++----------- .../core/doctype/print_format/print_format.py | 16 +++-- webnotes/templates/emails/new_user.html | 6 +- .../templates/print_formats/standard.html | 0 webnotes/test_runner.py | 2 +- webnotes/tests/test_email.py | 4 -- webnotes/utils/email_lib/bulk.py | 20 ++++--- webnotes/utils/email_lib/email_body.py | 58 +++++++++++-------- 8 files changed, 70 insertions(+), 81 deletions(-) create mode 100644 webnotes/templates/print_formats/standard.html diff --git a/webnotes/core/doctype/communication/communication.py b/webnotes/core/doctype/communication/communication.py index fe9cac3e4f..64199c4537 100644 --- a/webnotes/core/doctype/communication/communication.py +++ b/webnotes/core/doctype/communication/communication.py @@ -3,6 +3,13 @@ from __future__ import unicode_literals import webnotes +import json +import urllib +from email.utils import formataddr +from webnotes.webutils import is_signup_enabled +from webnotes.utils import get_url, cstr +from webnotes.utils.email_lib.email_body import get_email +from webnotes.utils.email_lib.smtp import send class DocType(): def __init__(self, doc, doclist=[]): @@ -36,13 +43,11 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received = # since we are using fullname and email, # if the fullname has any incompatible characters,formataddr can deal with it try: - import json sender = json.loads(sender) except ValueError: pass if isinstance(sender, (tuple, list)) and len(sender)==2: - from email.utils import formataddr sender = formataddr(sender) comm = webnotes.new_bean('Communication') @@ -76,7 +81,6 @@ def get_customer_supplier(args=None): """ Get Customer/Supplier, given a contact, if a unique match exists """ - import webnotes if not args: args = webnotes.local.form_dict if not args.get('contact'): raise Exception, "Please specify a contact to fetch Customer/Supplier" @@ -92,7 +96,6 @@ def get_customer_supplier(args=None): return {} def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', send_me_a_copy=False): - from json import loads footer = None if sent_via: @@ -105,7 +108,6 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s footer = set_portal_link(sent_via, d) - from webnotes.utils.email_lib.smtp import get_email mail = get_email(d.recipients, sender=d.sender, subject=d.subject, msg=d.content, footer=footer) @@ -115,20 +117,17 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s if print_html: mail.add_attachment(name.replace(' ','').replace('/','-') + '.html', print_html) - for a in loads(attachments): + for a in json.loads(attachments): try: mail.attach_file(a) except IOError, e: webnotes.msgprint("""Unable to find attachment %s. Please resend without attaching this file.""" % a, raise_exception=True) - mail.send() + send(mail) def set_portal_link(sent_via, comm): """set portal link in footer""" - from webnotes.webutils import is_signup_enabled - from webnotes.utils import get_url, cstr - import urllib footer = None @@ -143,29 +142,3 @@ def set_portal_link(sent_via, comm): View this on our website""" % url return footer - -def get_user(doctype, txt, searchfield, start, page_len, filters): - from erpnext.controllers.queries import get_match_cond - return webnotes.conn.sql("""select name, concat_ws(' ', first_name, middle_name, last_name) - from `tabProfile` - where ifnull(enabled, 0)=1 - and docstatus < 2 - and (%(key)s like "%(txt)s" - or concat_ws(' ', first_name, middle_name, last_name) like "%(txt)s") - %(mcond)s - limit %(start)s, %(page_len)s """ % {'key': searchfield, - 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype, searchfield), - 'start': start, 'page_len': page_len}) - -def get_lead(doctype, txt, searchfield, start, page_len, filters): - from erpnext.controllers.queries import get_match_cond - return webnotes.conn.sql(""" select name, lead_name from `tabLead` - where docstatus < 2 - and (%(key)s like "%(txt)s" - or lead_name like "%(txt)s" - or company_name like "%(txt)s") - %(mcond)s - order by lead_name asc - limit %(start)s, %(page_len)s """ % {'key': searchfield,'txt': "%%%s%%" % txt, - 'mcond':get_match_cond(doctype, searchfield), 'start': start, - 'page_len': page_len}) \ No newline at end of file diff --git a/webnotes/core/doctype/print_format/print_format.py b/webnotes/core/doctype/print_format/print_format.py index 7821f18b53..c7f15f2b31 100644 --- a/webnotes/core/doctype/print_format/print_format.py +++ b/webnotes/core/doctype/print_format/print_format.py @@ -7,6 +7,8 @@ from webnotes import conf import webnotes.utils from webnotes.modules import get_doc_path +standard_format = "templates/print_formats/standard.html" + class DocType: def __init__(self, d, dl): self.doc, self.doclist = d,dl @@ -39,8 +41,9 @@ class DocType: webnotes.clear_cache(doctype=self.doc.doc_type) def get_args(): - if not webnotes.form_dict.doctype or not webnotes.form_dict.name \ - or not webnotes.form_dict.format: + if not webnotes.form_dict.format: + webnotes.form_dict.format = standard_format + if not webnotes.form_dict.doctype or not webnotes.form_dict.name: return { "body": """

Error

Parameters doctype, name and format required

@@ -79,15 +82,18 @@ def get_html(doc, doclist, print_format=None): html = template.render(args) return html -def get_print_format(doctype, format): +def get_print_format(doctype, format_name): + if format_name==standard_format: + return format_name + # server, find template path = os.path.join(get_doc_path(webnotes.conn.get_value("DocType", doctype, "module"), - "Print Format", format), format + ".html") + "Print Format", format_name), format_name + ".html") if os.path.exists(path): with open(path, "r") as pffile: return pffile.read() else: - html = webnotes.conn.get_value("Print Format", format, "html") + html = webnotes.conn.get_value("Print Format", format_name, "html") if html: return html else: diff --git a/webnotes/templates/emails/new_user.html b/webnotes/templates/emails/new_user.html index b6e5150dc2..8c6b099c29 100644 --- a/webnotes/templates/emails/new_user.html +++ b/webnotes/templates/emails/new_user.html @@ -2,7 +2,9 @@

Dear {{ first_name }}{% if last_name %} {{ last_name}}{% endif %},

A new account has been created for you.

Your login id is: {{ user }} -

To complete your registration, please click on the link below:

-

{{ link }}

+

Click on the button below to complete your registration and set a new password.

+

Complete Registration

+
+

You can also copy-paste this link in your browser {{ link }}

Thank you,
{{ user_fullname }}

\ No newline at end of file diff --git a/webnotes/templates/print_formats/standard.html b/webnotes/templates/print_formats/standard.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/webnotes/test_runner.py b/webnotes/test_runner.py index fd453c2084..dfb1d4a801 100644 --- a/webnotes/test_runner.py +++ b/webnotes/test_runner.py @@ -30,7 +30,7 @@ def main(app=None, module=None, doctype=None, verbose=False): for doctype in module.test_dependencies: make_test_records(doctype, verbose=verbose) - test_suite.addTest(unittest.TestLoader().loadTestsFromModule(sys.modules[module])) + test_suite.addTest(unittest.TestLoader().loadTestsFromModule(module)) ret = unittest.TextTestRunner(verbosity=1+(verbose and 1 or 0)).run(test_suite) else: ret = run_all_tests(app, verbose) diff --git a/webnotes/tests/test_email.py b/webnotes/tests/test_email.py index 7ad906054b..1e2a39be79 100644 --- a/webnotes/tests/test_email.py +++ b/webnotes/tests/test_email.py @@ -4,10 +4,6 @@ from __future__ import unicode_literals import os, sys -sys.path.append('.') -sys.path.append('lib/py') -sys.path.append('erpnext') - import unittest, webnotes from webnotes.test_runner import make_test_records diff --git a/webnotes/utils/email_lib/bulk.py b/webnotes/utils/email_lib/bulk.py index a4ec103b0a..cc89866543 100644 --- a/webnotes/utils/email_lib/bulk.py +++ b/webnotes/utils/email_lib/bulk.py @@ -6,7 +6,7 @@ import webnotes import HTMLParser import urllib from webnotes.utils.email_lib.smtp import SMTPServer, send -from webnotes.utils.email_lib.email_body import get_email +from webnotes.utils.email_lib.email_body import get_email, get_formatted_html from webnotes.utils.email_lib.html2text import html2text from webnotes.utils import cint, get_url, expand_partial_links, nowdate @@ -30,8 +30,8 @@ def send(recipients=None, sender=None, doctype='Profile', email_field='email', webnotes.msgprint("""Monthly Bulk Mail Limit (%s) Crossed""" % monthly_bulk_mail_limit, raise_exception=BulkLimitCrossedError) - def update_message(doc): - updated = message + def update_message(formatted, doc, add_unsubscribe_link): + updated = formatted if add_unsubscribe_link: unsubscribe_link = """
@@ -43,7 +43,8 @@ def send(recipients=None, sender=None, doctype='Profile', email_field='email', "type": doctype, "email_field": email_field })) - updated.replace("", unsubscribe_link) + + updated = updated.replace("", unsubscribe_link) return updated @@ -53,11 +54,12 @@ def send(recipients=None, sender=None, doctype='Profile', email_field='email', check_bulk_limit(len(recipients)) try: - message = expand_partial_links(message) text_content = html2text(message) except HTMLParser.HTMLParseError: text_content = "[See html attachment]" + formatted = get_formatted_html(subject, message) + for r in filter(None, list(set(recipients))): rdata = webnotes.conn.sql("""select * from `tab%s` where %s=%s""" % (doctype, email_field, '%s'), (r,), as_dict=1) @@ -66,15 +68,17 @@ def send(recipients=None, sender=None, doctype='Profile', email_field='email', if not is_unsubscribed(doc): # add to queue - add(r, sender, subject, update_message(doc), text_content, ref_doctype, ref_docname) + add(r, sender, subject, update_message(formatted, doc, add_unsubscribe_link), + text_content, ref_doctype, ref_docname) -def add(email, sender, subject, message, text_content=None, ref_doctype=None, ref_docname=None): +def add(email, sender, subject, formatted, text_content=None, + ref_doctype=None, ref_docname=None): """add to bulk mail queue""" e = webnotes.doc('Bulk Email') e.sender = sender e.recipient = email try: - e.message = get_email(email, sender=e.sender, msg=message, subject=subject, + e.message = get_email(email, sender=e.sender, formatted=formatted, subject=subject, text_content = text_content).as_string() except webnotes.ValidationError: # bad email id - don't add to queue diff --git a/webnotes/utils/email_lib/email_body.py b/webnotes/utils/email_lib/email_body.py index ee7d8d805e..a9b309e46e 100644 --- a/webnotes/utils/email_lib/email_body.py +++ b/webnotes/utils/email_lib/email_body.py @@ -9,12 +9,13 @@ from webnotes.utils import expand_partial_links import email.utils from inlinestyler.utils import inline_css -def get_email(recipients, sender='', msg='', subject='[No Subject]', text_content = None, footer=None): +def get_email(recipients, sender='', msg='', subject='[No Subject]', + text_content = None, footer=None, formatted=None): """send an html email as multipart with attachments and all""" email = EMail(sender, recipients, subject) if (not '
' in msg) and (not '

' in msg) and (not '') - email.set_html(msg, text_content, footer=footer) + email.set_html(msg, text_content, footer=footer, formatted=formatted) return email @@ -47,15 +48,10 @@ class EMail: self.cc = [] self.html_set = False - def set_html(self, message, text_content = None, footer=None): + def set_html(self, message, text_content = None, footer=None, formatted=None): """Attach message in the html portion of multipart/alternative""" - message = expand_partial_links(message) - - content_html = inline_css(webnotes.get_template("templates/emails/standard.html").render({ - "content": message, - "footer": self.get_footer(footer), - "title": self.subject - })) + if not formatted: + formatted = get_formatted_html(self.subject, message, footer) # this is the first html part of a multi-part message, # convert to text well @@ -65,7 +61,7 @@ class EMail: else: self.set_html_as_text(message) - self.set_part_html(content_html) + self.set_part_html(formatted) self.html_set = True def set_text(self, message): @@ -101,19 +97,7 @@ class EMail: part.add_header('Content-Disposition', 'attachment', filename=filename) self.msg_root.attach(part) - - def get_footer(self, footer=None): - """append a footer (signature)""" - footer = footer or "" - footer += webnotes.conn.get_value('Control Panel',None,'mail_footer') or '' - - for f in webnotes.get_hooks("mail_footer"): - footer += webnotes.get_attr(f) - - footer += "" - - return footer - + def attach_file(self, n): """attach a file from the `FileData` table""" from webnotes.utils.file_manager import get_file @@ -206,4 +190,28 @@ class EMail: """validate, build message and convert to string""" self.validate() self.make() - return self.msg_root.as_string() \ No newline at end of file + return self.msg_root.as_string() + +def get_formatted_html(subject, message, footer=None): + message = expand_partial_links(message) + + return inline_css(webnotes.get_template("templates/emails/standard.html").render({ + "content": message, + "footer": get_footer(footer), + "title": subject + })) + +def get_footer(footer=None): + """append a footer (signature)""" + footer = footer or "" + + # control panel + footer += webnotes.conn.get_value('Control Panel',None,'mail_footer') or '' + + # hooks + for f in webnotes.get_hooks("mail_footer"): + footer += webnotes.get_attr(f) + + footer += "" + + return footer