diff --git a/py/core/doctype/bulk_email/__init__.py b/py/core/doctype/bulk_email/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/py/core/doctype/bulk_email/bulk_email.txt b/py/core/doctype/bulk_email/bulk_email.txt
new file mode 100644
index 0000000000..09ff565cc6
--- /dev/null
+++ b/py/core/doctype/bulk_email/bulk_email.txt
@@ -0,0 +1,103 @@
+# DocType, Bulk Email
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2012-08-02 15:17:28',
+ 'docstatus': 0,
+ 'modified': '2012-08-02 15:17:29',
+ 'modified_by': u'Administrator',
+ 'owner': u'Administrator'
+ },
+
+ # These values are common for all DocType
+ {
+ 'description': u'Bulk Email records.',
+ 'doctype': 'DocType',
+ 'document_type': u'System',
+ 'in_create': 1,
+ 'module': u'Core',
+ 'name': '__common__',
+ 'read_only': 1,
+ 'version': 1
+ },
+
+ # These values are common for all DocField
+ {
+ 'doctype': u'DocField',
+ 'name': '__common__',
+ 'parent': u'Bulk Email',
+ 'parentfield': u'fields',
+ 'parenttype': u'DocType',
+ 'permlevel': 0
+ },
+
+ # These values are common for all DocPerm
+ {
+ 'doctype': u'DocPerm',
+ 'name': '__common__',
+ 'parent': u'Bulk Email',
+ 'parentfield': u'permissions',
+ 'parenttype': u'DocType',
+ 'permlevel': 0,
+ 'read': 1
+ },
+
+ # DocType, Bulk Email
+ {
+ 'doctype': 'DocType',
+ 'name': u'Bulk Email'
+ },
+
+ # DocPerm
+ {
+ 'doctype': u'DocPerm',
+ 'role': u'Administrator'
+ },
+
+ # DocPerm
+ {
+ 'doctype': u'DocPerm',
+ 'role': u'System Manager'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'sender',
+ 'fieldtype': u'Data',
+ 'label': u'Sender'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'recipient',
+ 'fieldtype': u'Data',
+ 'label': u'Recipient'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'message',
+ 'fieldtype': u'Text',
+ 'label': u'Message'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'status',
+ 'fieldtype': u'Data',
+ 'label': u'Status'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'error',
+ 'fieldtype': u'Text',
+ 'label': u'Error'
+ }
+]
\ No newline at end of file
diff --git a/py/webnotes/tests/test_email.py b/py/webnotes/tests/test_email.py
new file mode 100644
index 0000000000..a76d6a3354
--- /dev/null
+++ b/py/webnotes/tests/test_email.py
@@ -0,0 +1,65 @@
+import os, sys
+
+sys.path.append('.')
+sys.path.append('lib/py')
+sys.path.append('erpnext')
+
+import unittest, webnotes
+
+class TestEmail(unittest.TestCase):
+ def setUp(self):
+ webnotes.conn.begin()
+
+ def tearDown(self):
+ webnotes.conn.rollback()
+
+ def test_send(self):
+ from webnotes.utils.email_lib import sendmail
+ #sendmail('rmehta@gmail.com', subject='Test Mail', msg="Test Content")
+
+ def test_bulk(self):
+ from webnotes.utils.email_lib.bulk import send
+ send(recipients = ['rmehta@gmail.com', 'rushabh@erpnext.com'],
+ doctype='Lead', email_field='email_id', first_name_field='lead_name',
+ last_name_field=None, subject='Testing Bulk', message='This is a bulk mail!')
+
+ bulk = webnotes.conn.sql("""select * from `tabBulk Email` where status='Not Sent'""", as_dict=1)
+ self.assertEquals(len(bulk), 2)
+ self.assertTrue('rmehta@gmail.com' in [d['recipient'] for d in bulk])
+ self.assertTrue('rushabh@erpnext.com' in [d['recipient'] for d in bulk])
+ self.assertTrue('Unsubscribe' in bulk[0]['message'])
+
+ def test_flush(self):
+ self.test_bulk()
+ from webnotes.utils.email_lib.bulk import flush
+ flush()
+ bulk = webnotes.conn.sql("""select * from `tabBulk Email` where status='Sent'""", as_dict=1)
+ self.assertEquals(len(bulk), 2)
+ self.assertTrue('rmehta@gmail.com' in [d['recipient'] for d in bulk])
+ self.assertTrue('rushabh@erpnext.com' in [d['recipient'] for d in bulk])
+ webnotes.conn.sql("""delete from `tabBulk Email`""", auto_commit=True)
+
+ def test_unsubscribe(self):
+ from webnotes.utils.email_lib.bulk import unsubscribe, send
+ webnotes.form_dict = {
+ 'email':'rmehta@gmail.com',
+ 'type':'Lead',
+ 'email_field':'email_id'
+ }
+ unsubscribe()
+
+ send(recipients = ['rmehta@gmail.com', 'rushabh@erpnext.com'],
+ doctype='Lead', email_field='email_id', first_name_field='lead_name',
+ last_name_field=None, subject='Testing Bulk', message='This is a bulk mail!')
+
+ bulk = webnotes.conn.sql("""select * from `tabBulk Email` where status='Not Sent'""",
+ as_dict=1)
+ self.assertEquals(len(bulk), 1)
+ self.assertFalse('rmehta@gmail.com' in [d['recipient'] for d in bulk])
+ self.assertTrue('rushabh@erpnext.com' in [d['recipient'] for d in bulk])
+ self.assertTrue('Unsubscribe' in bulk[0]['message'])
+
+
+if __name__=='__main__':
+ webnotes.connect()
+ unittest.main()
\ No newline at end of file
diff --git a/py/webnotes/utils/__init__.py b/py/webnotes/utils/__init__.py
index eccc8da8fb..812a116bd9 100644
--- a/py/webnotes/utils/__init__.py
+++ b/py/webnotes/utils/__init__.py
@@ -66,21 +66,26 @@ def extract_email_id(s):
return s
def validate_email_add(email_str):
- """
- Validates the email string
- """
+ """Validates the email string"""
s = extract_email_id(email_str)
import re
#return re.match("^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", 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])?", s)
def sendmail(recipients, sender='', msg='', subject='[No Subject]', parts=[], cc=[], attach=[]):
- """
- Send an email. For more details see :func:`email_lib.sendmail`
- """
+ """Send an email. For more details see :func:`email_lib.sendmail`"""
import webnotes.utils.email_lib
return email_lib.sendmail(recipients, sender, msg, subject, parts, cc, attach)
-
+
+def get_request_site_address():
+ """get app url from request"""
+ import os
+ try:
+ return 'HTTPS' in os.environ.get('SERVER_PROTOCOL') and 'https://' or 'http://' \
+ + os.environ.get('HTTP_HOST')
+ except TypeError, e:
+ return 'http://localhost'
+
def generate_hash():
"""
Generates random hash for session id
diff --git a/py/webnotes/utils/email_lib/__init__.py b/py/webnotes/utils/email_lib/__init__.py
index 58ea04bcf7..c1b6b6af95 100644
--- a/py/webnotes/utils/email_lib/__init__.py
+++ b/py/webnotes/utils/email_lib/__init__.py
@@ -22,101 +22,25 @@
import webnotes
-def sendmail_html(sender, recipients, subject, html, text=None, template=None, send_now=1, reply_to=None):
- """
- Send an html mail with alternative text and using Page Templates
- """
- sendmail(recipients, sender, html, subject,
- send_now = send_now, reply_to = reply_to, template = template)
-
-def make_html_body(content, template = None):
- """
- Generate html content from a Page Template object
- """
- template_html = '
%(content)s
'
-
- if template:
- from webnotes.model.code import get_code
- template_html = get_code(webnotes.conn.get_value('Page Template', template, 'module'), 'Page Template', template, 'html', fieldname='template')
-
- return template_html % {'content': content}
-
-def sendmail_md(recipients, sender=None, msg=None, subject=None, from_defs=0):
+def sendmail_md(recipients, sender=None, msg=None, subject=None):
"""send markdown email"""
import markdown2
- sendmail(recipients, sender, markdown2.markdown(msg), subject, txt=msg, from_defs=from_defs)
-
-def sendmail(recipients, sender='', msg='', subject='[No Subject]', txt=None, \
- parts=[], cc=[], attach=[], send_now=1, reply_to=None, template=None, from_defs=0):
- """
- send an html email as multipart with attachments and all
- """
-
- from webnotes.utils.email_lib.html2text import html2text
- from webnotes.utils.email_lib.send import EMail
- import HTMLParser
-
- email = EMail(sender, recipients, subject, reply_to=reply_to, from_defs=from_defs)
- email.cc = cc
-
- if msg:
- if template:
- msg = make_html_body(msg, template)
- else:
- # if not html, then lets put some whitespace
- if (not '
' in msg) and (not '' in msg):
- msg = msg.replace('\n','
')
-
- footer = get_footer()
-
- # encode using utf-8
- footer = footer.encode('utf-8', 'ignore')
-
- msg = msg + (footer or '')
- if txt:
- email.set_text(txt)
- else:
- try:
- msg_unicode = msg
- if isinstance(msg, str):
- msg_unicode = unicode(msg, 'utf-8', 'ignore')
- email.set_text(html2text(msg_unicode))
- except HTMLParser.HTMLParseError:
- pass
- email.set_html(msg)
- for p in parts:
- email.set_message(p[1])
- for a in attach:
- email.attach(a)
-
- email.send(send_now)
-
-
-def get_footer():
- """
- Returns combination of footer from globals and Control Panel
- """
-
- footer = webnotes.conn.get_value('Control Panel',None,'mail_footer') or ''
- footer += (webnotes.conn.get_global('global_mail_footer') or '')
- return footer
+ sendmail(recipients, sender, markdown2.markdown(msg), subject)
+
+def sendmail(recipients, sender='', msg='', subject='[No Subject]'):
+ """send an html email as multipart with attachments and all"""
+ from webnotes.utils.email_lib.smtp import get_email
+ get_email(recipients, sender, msg, subject).send()
@webnotes.whitelist()
def send_form():
- """
- Emails a print format (form)
- Called from form UI
- """
-
+ """Emails a print format (form). Called from form UI"""
from webnotes.utils.email_lib.form_email import FormEmail
FormEmail().send()
@webnotes.whitelist()
def get_contact_list():
- """
- Returns contacts (from autosuggest)
- """
-
+ """Returns contacts (from autosuggest)"""
cond = ['`%s` like "%s%%"' % (f,
webnotes.form.getvalue('txt')) for f in webnotes.form.getvalue('where').split(',')]
cl = webnotes.conn.sql("select `%s` from `tab%s` where %s" % (
@@ -126,5 +50,3 @@ def get_contact_list():
)
)
webnotes.response['cl'] = filter(None, [c[0] for c in cl])
-
-
diff --git a/py/webnotes/utils/email_lib/bulk.py b/py/webnotes/utils/email_lib/bulk.py
new file mode 100644
index 0000000000..31a1cee4ee
--- /dev/null
+++ b/py/webnotes/utils/email_lib/bulk.py
@@ -0,0 +1,118 @@
+# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
+#
+# MIT License (MIT)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+import webnotes
+
+def send(recipients=[], doctype='Profile', email_field='email', first_name_field="first_name",
+ last_name_field="last_name", subject='[No Subject]', message='[No Content]'):
+ """send bulk mail if not unsubscribed and within conf.bulk_mail_limit"""
+ import webnotes
+ def is_unsubscribed(rdata):
+ if not rdata: return 1
+ return rdata[0]['unsubscribed']
+
+ def check_bulk_limit(new_mails):
+ import conf
+ from webnotes.utils import nowdate
+ todays_bulk = webnotes.conn.sql("""select count(*) from `tabBulk Email` where
+ datediff(%s, creation)<1""" % nowdate())[0][0]
+
+ bulk_mail_limit = getattr(conf, 'bulk_mail_limit', 200)
+ if todays_bulk + len(recipients) > bulk_mail_limit:
+ webnotes.msgprint("""Buik Mail Limit Crossed""", raise_exception=1)
+
+ def add_unsubscribe_link(email):
+ from webnotes.utils import get_request_site_address
+ return message + """
""" % (get_request_site_address(),
+ 'webnotes.utils.email_lib.bulk.unsubscribe', email, doctype, email_field)
+
+ def full_name(rdata):
+ fname = rdata[0].get(first_name_field, '')
+ lname = rdata[0].get(last_name_field, '')
+ if fname and not lname:
+ return fname
+ elif lname and not fname:
+ return lname
+ elif fname and lname:
+ return fname + ' ' + lname
+ else:
+ return rdata[0][email_field].split('@')[0].title()
+
+ check_bulk_limit(len(recipients))
+ sender = webnotes.conn.get_value('Email Settings', None, 'auto_mail_id')
+
+ for r in recipients:
+ rdata = webnotes.conn.sql("""select * from `tab%s` where %s=%s""" % (doctype,
+ email_field, '%s'), r, as_dict=1)
+ if not is_unsubscribed(rdata):
+ # add to queue
+ add(r, sender, subject, add_unsubscribe_link(r) % {"full_name":full_name(rdata)})
+
+def add(email, sender, subject, message):
+ """add to bulk mail queue"""
+ from webnotes.model.doc import Document
+ from webnotes.utils.email_lib.smtp import get_email
+
+ e = Document('Bulk Email')
+ e.sender = sender
+ e.recipient = email
+ e.message = get_email(email, sender=e.sender, msg=message, subject=subject).as_string()
+ e.status = 'Not Sent'
+ e.save()
+
+@webnotes.whitelist(allow_guest=True)
+def unsubscribe():
+ doctype = webnotes.form_dict.get('type')
+ field = webnotes.form_dict.get('email_field')
+ email = webnotes.form_dict.get('email')
+ webnotes.conn.sql("""update `tab%s` set unsubscribed=1
+ where email_id=%s""" % (doctype, '%s'), email)
+
+ webnotes.unsubscribed_email = email
+ webnotes.response['type'] = 'page'
+ webnotes.response['page_name'] = 'unsubscribed.html'
+
+def flush():
+ """flush email queue, every time: called from scheduler"""
+ import webnotes
+ from webnotes.utils.email_lib.smtp import SMTPServer
+
+ smptserver = SMTPServer()
+
+ for email in webnotes.conn.sql("""select * from `tabBulk Email` where status='Not Sent'""",
+ as_dict=1):
+ webnotes.conn.sql("""update `tabBulk Email` set status='Sending' where name=%s""",
+ email["name"], auto_commit=True)
+ try:
+ smptserver.sess.sendmail(email["sender"], email["recipient"], email["message"])
+ webnotes.conn.sql("""update `tabBulk Email` set status='Sent' where name=%s""",
+ email["name"], auto_commit=True)
+ except Exception, e:
+ webnotes.conn.sql("""update `tabBulk Email` set status='Error', error=%s
+ where name=%s""", (str(e), email["name"]), auto_commit=True)
+
+def clear_outbox():
+ """remove mails older than 7 days in Outbox"""
+ webnotes.conn.sql("""delete from `tabBulk Email` where
+ datediff(now(), creation) > 7""", (str(e), email["name"]), auto_commit=True)
\ No newline at end of file
diff --git a/py/webnotes/utils/email_lib/form_email.py b/py/webnotes/utils/email_lib/form_email.py
index dc9bfabb6e..7bc63cbcb8 100644
--- a/py/webnotes/utils/email_lib/form_email.py
+++ b/py/webnotes/utils/email_lib/form_email.py
@@ -26,7 +26,7 @@ from webnotes.utils import cint
form = webnotes.form
from webnotes.utils.email_lib import get_footer
-from webnotes.utils.email_lib.send import EMail
+from webnotes.utils.email_lib.smtp import EMail
class FormEmail:
"""
@@ -204,7 +204,7 @@ class FormEmail:
if self.cc:
self.email.cc = [self.cc]
- self.email.send(send_now=1)
+ self.email.send()
self.make_communication()
webnotes.msgprint('Sent')
diff --git a/py/webnotes/utils/email_lib/send.py b/py/webnotes/utils/email_lib/smtp.py
similarity index 67%
rename from py/webnotes/utils/email_lib/send.py
rename to py/webnotes/utils/email_lib/smtp.py
index 7b02683182..e5ac54dede 100644
--- a/py/webnotes/utils/email_lib/send.py
+++ b/py/webnotes/utils/email_lib/smtp.py
@@ -30,13 +30,22 @@ import conf
from webnotes import msgprint
import email
+def get_email(recipients, sender='', msg='', subject='[No Subject]'):
+ """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)
+
+ return email
+
class EMail:
"""
Wrapper on the email module. Email object represents emails to be sent to the client.
Also provides a clean way to add binary `FileData` attachments
Also sets all messages as multipart/alternative for cleaner reading in text-only clients
"""
- def __init__(self, sender='', recipients=[], subject='', from_defs=0, alternative=0, reply_to=None):
+ def __init__(self, sender='', recipients=[], subject='', alternative=0, reply_to=None):
from email.mime.multipart import MIMEMultipart
from email import Charset
Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')
@@ -48,7 +57,6 @@ class EMail:
# remove null
recipients = filter(None, recipients)
- self.from_defs = from_defs
self.sender = sender
self.reply_to = reply_to or sender
self.recipients = recipients
@@ -58,6 +66,7 @@ class EMail:
self.msg_multipart = MIMEMultipart('alternative')
self.msg_root.attach(self.msg_multipart)
self.cc = []
+ self.html_set = False
def set_text(self, message):
"""
@@ -68,21 +77,32 @@ class EMail:
message = message.encode('utf-8')
part = MIMEText(message, 'plain', 'utf-8')
self.msg_multipart.attach(part)
-
+
def set_html(self, message):
- """
- Attach message in the html portion of multipart/alternative
- """
- from email.mime.text import MIMEText
- if isinstance(message, unicode):
- message = message.encode('utf-8')
- part = MIMEText(message, 'html', 'utf-8')
+ """Attach message in the html portion of multipart/alternative"""
+ from email.mime.text import MIMEText
+ message = unicode(message) + self.get_footer()
+
+ # this is the first html part of a multi-part message,
+ # convert to text well
+ if not self.html_set:
+ self.set_html_text(message)
+
+ part = MIMEText(message.encode('utf-8'), 'html', 'utf-8')
self.msg_multipart.attach(part)
+ self.html_set = True
+
+ def set_html_text(self, html):
+ """return html2text"""
+ import HTMLParser
+ from webnotes.utils.email_lib.html2text import html2text
+ try:
+ self.set_text(html2text(html))
+ except HTMLParser.HTMLParseError:
+ pass
def set_message(self, message, mime_type='text/html', as_attachment=0, filename='attachment.html'):
- """
- Append the message with MIME content to the root node (as attachment)
- """
+ """Append the message with MIME content to the root node (as attachment)"""
from email.mime.text import MIMEText
maintype, subtype = mime_type.split('/')
@@ -92,11 +112,15 @@ class EMail:
part.add_header('Content-Disposition', 'attachment', filename=filename)
self.msg_root.attach(part)
+
+ def get_footer(self):
+ """append a footer"""
+ footer = webnotes.conn.get_value('Control Panel',None,'mail_footer') or ''
+ footer += (webnotes.conn.get_global('global_mail_footer') or '')
+ return unicode(footer)
def attach_file(self, n):
- """
- attach a file from the `FileData` table
- """
+ """attach a file from the `FileData` table"""
from webnotes.utils.file_manager import get_file
res = get_file(n)
if not res:
@@ -105,7 +129,7 @@ class EMail:
self.add_attachment(res[0], res[1])
def add_attachment(self, fname, fcontent, content_type=None):
-
+ """add attachment"""
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
@@ -143,12 +167,10 @@ class EMail:
self.msg_root.attach(part)
def validate(self):
- """
- validate the email ids
- """
+ """validate the email ids"""
if not self.sender:
- self.sender = hasattr(conf, 'auto_email_id') \
- and conf.auto_email_id or '"ERPNext Notification"
'
+ self.sender = webnotes.conn.get_value('Email Settings', None, 'auto_email_id') \
+ or getattr(conf, 'auto_email_id', '"ERPNext Notification" ')
from webnotes.utils import validate_email_add
# validate ids
@@ -162,31 +184,8 @@ class EMail:
if not validate_email_add(e):
webnotes.msgprint("%s is not a valid email id" % e, raise_exception = 1)
- def setup(self):
- """
- setup the SMTP (outgoing) server from `Control Panel` or defs.py
- """
- if self.from_defs:
- import webnotes
- self.server = getattr(conf,'mail_server','')
- self.login = getattr(conf,'mail_login','')
- self.port = getattr(conf,'mail_port',None)
- self.password = getattr(conf,'mail_password','')
- self.use_ssl = getattr(conf,'use_ssl',0)
-
- else:
- import webnotes.model.doc
- from webnotes.utils import cint
-
- # get defaults from control panel
- es = webnotes.model.doc.Document('Email Settings','Email Settings')
- self.server = es.outgoing_mail_server.encode('utf-8') or getattr(conf,'mail_server','')
- self.login = es.mail_login.encode('utf-8') or getattr(conf,'mail_login','')
- self.port = cint(es.mail_port) or getattr(conf,'mail_port',None)
- self.password = es.mail_password.encode('utf-8') or getattr(conf,'mail_password','')
- self.use_ssl = cint(es.use_ssl) or cint(getattr(conf, 'use_ssl', ''))
-
- def make_msg(self):
+ def make(self):
+ """build into msg_root"""
self.msg_root['Subject'] = self.subject
self.msg_root['From'] = self.sender
self.msg_root['To'] = ', '.join([r.strip() for r in self.recipients])
@@ -194,46 +193,43 @@ class EMail:
self.msg_root['Reply-To'] = self.reply_to
if self.cc:
self.msg_root['CC'] = ', '.join([r.strip() for r in self.cc])
-
- def add_to_queue(self):
- # write to a file called "email_queue" or as specified in email
- q = EmailQueue()
- q.push({
- 'server': self.server,
- 'port': self.port,
- 'use_ssl': self.use_ssl,
- 'login': self.login,
- 'password': self.password,
- 'sender': self.sender,
- 'recipients': self.recipients,
- 'msg': self.msg_root.as_string()
- })
- q.close()
- def send(self, send_now = 0):
- """
- send the message
- """
- from webnotes.utils import cint
-
- self.setup()
+ def as_string(self):
+ """validate, build message and convert to string"""
self.validate()
- self.make_msg()
+ self.make()
+ return self.msg_root.as_string()
- sess = self.smtp_connect()
+ def send(self, as_bulk=False):
+ """send the message or add it to Outbox Email"""
+ SMTPServer().sess.sendmail(self.sender, self.recipients, self.as_string())
- sess.sendmail(self.sender, self.recipients, self.msg_root.as_string())
+
+class SMTPServer:
+ def __init__(self, login=None, password=None, server=None, port=None, use_ssl=None):
+ import webnotes.model.doc
+ from webnotes.utils import cint
+
+ # get defaults from control panel
+ es = webnotes.model.doc.Document('Email Settings','Email Settings')
+ self.server = server or es.outgoing_mail_server.encode('utf-8') \
+ or getattr(conf,'mail_server','')
+ self.login = login or es.mail_login.encode('utf-8') \
+ or getattr(conf,'mail_login','')
+ self.port = port or cint(es.mail_port) \
+ or getattr(conf,'mail_port',None)
+ self.password = password or es.mail_password.encode('utf-8') \
+ or getattr(conf,'mail_password','')
+ self.use_ssl = use_ssl or cint(es.use_ssl) \
+ or cint(getattr(conf, 'use_ssl', ''))
+ self._sess = None
+
+ @property
+ def sess(self):
+ """get session"""
+ if self._sess:
+ return self._sess
- try:
- sess.quit()
- except:
- pass
-
-
- def smtp_connect(self):
- """
- Gets a smtp connection and handles errors
- """
from webnotes.utils import cint
import smtplib
import _socket
@@ -245,26 +241,26 @@ class EMail:
raise webnotes.OutgoingEmailError, err_msg
try:
- sess = smtplib.SMTP(self.server, cint(self.port) or None)
+ self._sess = smtplib.SMTP(self.server, cint(self.port) or None)
- if not sess:
+ if not self._sess:
err_msg = 'Could not connect to outgoing email server'
webnotes.msgprint(err_msg)
raise webnotes.OutgoingEmailError, err_msg
if self.use_ssl:
- sess.ehlo()
- sess.starttls()
- sess.ehlo()
+ self._sess.ehlo()
+ self._sess.starttls()
+ self._sess.ehlo()
- ret = sess.login(self.login, self.password)
+ ret = self._sess.login(self.login, self.password)
# check if logged correctly
if ret[0]!=235:
msgprint(ret[1])
raise webnotes.OutgoingEmailError, ret[1]
- return sess
+ return self._sess
except _socket.error, e:
# Invalid mail server -- due to refusing connection
@@ -276,4 +272,6 @@ class EMail:
except smtplib.SMTPException, e:
webnotes.msgprint('There is something wrong with your Outgoing Mail Settings. \
Please contact us at support@erpnext.com')
- raise webnotes.OutgoingEmailError, e
\ No newline at end of file
+ raise webnotes.OutgoingEmailError, e
+
+
\ No newline at end of file