浏览代码

[bulk] [feature] added send_after

version-14
Rushabh Mehta 10 年前
父节点
当前提交
b64b79c4f1
共有 6 个文件被更改,包括 36 次插入16 次删除
  1. +3
    -2
      frappe/__init__.py
  2. +2
    -1
      frappe/core/doctype/user/user.py
  3. +16
    -9
      frappe/email/bulk.py
  4. +10
    -2
      frappe/email/doctype/bulk_email/bulk_email.json
  5. +1
    -1
      frappe/public/js/frappe/router.js
  6. +4
    -1
      frappe/utils/__init__.py

+ 3
- 2
frappe/__init__.py 查看文件

@@ -274,7 +274,7 @@ def sendmail(recipients=(), sender="", subject="No Subject", message="No Message
as_markdown=False, bulk=False, reference_doctype=None, reference_name=None, as_markdown=False, bulk=False, reference_doctype=None, reference_name=None,
unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None,
attachments=None, content=None, doctype=None, name=None, reply_to=None, attachments=None, content=None, doctype=None, name=None, reply_to=None,
cc=(), message_id=None, as_bulk=False):
cc=(), message_id=None, as_bulk=False, send_after=None):
"""Send email using user's default **Email Account** or global default **Email Account**. """Send email using user's default **Email Account** or global default **Email Account**.




@@ -291,6 +291,7 @@ def sendmail(recipients=(), sender="", subject="No Subject", message="No Message
:param attachments: List of attachments. :param attachments: List of attachments.
:param reply_to: Reply-To email id. :param reply_to: Reply-To email id.
:param message_id: Used for threading. If a reply is received to this email, Message-Id is sent back as In-Reply-To in received email. :param message_id: Used for threading. If a reply is received to this email, Message-Id is sent back as In-Reply-To in received email.
:param send_after: Send after the given datetime.
""" """


if bulk or as_bulk: if bulk or as_bulk:
@@ -299,7 +300,7 @@ def sendmail(recipients=(), sender="", subject="No Subject", message="No Message
subject=subject, message=content or message, subject=subject, message=content or message,
reference_doctype = doctype or reference_doctype, reference_name = name or reference_name, reference_doctype = doctype or reference_doctype, reference_name = name or reference_name,
unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message, unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message,
attachments=attachments, reply_to=reply_to, cc=cc, message_id=message_id)
attachments=attachments, reply_to=reply_to, cc=cc, message_id=message_id, send_after=send_after)
else: else:
import frappe.email import frappe.email
if as_markdown: if as_markdown:


+ 2
- 1
frappe/core/doctype/user/user.py 查看文件

@@ -161,7 +161,8 @@ class User(Document):
self.db_set("reset_password_key", key) self.db_set("reset_password_key", key)
link = get_url("/update-password?key=" + key) link = get_url("/update-password?key=" + key)


self.send_login_mail(_("Verify Your Account"), "templates/emails/new_user.html", {"link": link})
self.send_login_mail(_("Verify Your Account"), "templates/emails/new_user.html",
{"link": link})


def send_login_mail(self, subject, template, add_args): def send_login_mail(self, subject, template, add_args):
"""send mail with login details""" """send mail with login details"""


+ 16
- 9
frappe/email/bulk.py 查看文件

@@ -9,13 +9,13 @@ from frappe.email.smtp import SMTPServer, get_outgoing_email_account
from frappe.email.email_body import get_email, get_formatted_html from frappe.email.email_body import get_email, get_formatted_html
from frappe.utils.verified_command import get_signed_params, verify_request from frappe.utils.verified_command import get_signed_params, verify_request
from html2text import html2text from html2text import html2text
from frappe.utils import get_url, nowdate, encode
from frappe.utils import get_url, nowdate, encode, now_datetime


class BulkLimitCrossedError(frappe.ValidationError): pass class BulkLimitCrossedError(frappe.ValidationError): pass


def send(recipients=None, sender=None, subject=None, message=None, reference_doctype=None, def send(recipients=None, sender=None, subject=None, message=None, reference_doctype=None,
reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None, reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None,
attachments=None, reply_to=None, cc=(), message_id=None):
attachments=None, reply_to=None, cc=(), message_id=None, send_after=None):
"""Add email to sending queue (Bulk Email) """Add email to sending queue (Bulk Email)


:param recipients: List of recipients. :param recipients: List of recipients.
@@ -29,15 +29,17 @@ def send(recipients=None, sender=None, subject=None, message=None, reference_doc
:param attachments: Attachments to be sent. :param attachments: Attachments to be sent.
:param reply_to: Reply to be captured here (default inbox) :param reply_to: Reply to be captured here (default inbox)
:param message_id: Used for threading. If a reply is received to this email, Message-Id is sent back as In-Reply-To in received email. :param message_id: Used for threading. If a reply is received to this email, Message-Id is sent back as In-Reply-To in received email.
:param send_after: Send this email after the given datetime.
""" """


if not unsubscribe_method: if not unsubscribe_method:
unsubscribe_method = "/api/method/frappe.email.bulk.unsubscribe" unsubscribe_method = "/api/method/frappe.email.bulk.unsubscribe"


if not recipients: if not recipients:
return return


if isinstance(recipients, basestring):
recipients = recipients.split(",")

if not sender or sender == "Administrator": if not sender or sender == "Administrator":
email_account = get_outgoing_email_account() email_account = get_outgoing_email_account()
sender = email_account.get("sender") or email_account.email_id sender = email_account.get("sender") or email_account.email_id
@@ -51,8 +53,11 @@ def send(recipients=None, sender=None, subject=None, message=None, reference_doc
except HTMLParser.HTMLParseError: except HTMLParser.HTMLParseError:
text_content = "See html attachment" text_content = "See html attachment"


unsubscribed = [d.email for d in frappe.db.get_all("Email Unsubscribe", "email",
{"reference_doctype": reference_doctype, "reference_name": reference_name})]
if reference_doctype and reference_name:
unsubscribed = [d.email for d in frappe.db.get_all("Email Unsubscribe", "email",
{"reference_doctype": reference_doctype, "reference_name": reference_name})]
else:
unsubscribed = []


for email in filter(None, list(set(recipients))): for email in filter(None, list(set(recipients))):
if email not in unsubscribed: if email not in unsubscribed:
@@ -70,11 +75,11 @@ def send(recipients=None, sender=None, subject=None, message=None, reference_doc
email_text_context += "\n" + _("Unsubscribe link: {0}").format(unsubscribe_url) email_text_context += "\n" + _("Unsubscribe link: {0}").format(unsubscribe_url)


add(email, sender, subject, email_content, email_text_context, reference_doctype, reference_name, attachments, reply_to, add(email, sender, subject, email_content, email_text_context, reference_doctype, reference_name, attachments, reply_to,
cc, message_id)
cc, message_id, send_after)


def add(email, sender, subject, formatted, text_content=None, def add(email, sender, subject, formatted, text_content=None,
reference_doctype=None, reference_name=None, attachments=None, reply_to=None, reference_doctype=None, reference_name=None, attachments=None, reply_to=None,
cc=(), message_id=None):
cc=(), message_id=None, send_after=None):
"""add to bulk mail queue""" """add to bulk mail queue"""
e = frappe.new_doc('Bulk Email') e = frappe.new_doc('Bulk Email')
e.sender = sender e.sender = sender
@@ -95,6 +100,7 @@ def add(email, sender, subject, formatted, text_content=None,


e.reference_doctype = reference_doctype e.reference_doctype = reference_doctype
e.reference_name = reference_name e.reference_name = reference_name
e.send_after = send_after
e.insert(ignore_permissions=True) e.insert(ignore_permissions=True)


def check_bulk_limit(recipients): def check_bulk_limit(recipients):
@@ -169,7 +175,8 @@ def flush(from_test=False):


for i in xrange(500): for i in xrange(500):
email = frappe.db.sql("""select * from `tabBulk Email` where email = frappe.db.sql("""select * from `tabBulk Email` where
status='Not Sent' order by creation asc limit 1 for update""", as_dict=1)
status='Not Sent' and ifnull(send_after, "2000-01-01") > %s
order by creation asc limit 1 for update""", now_datetime(), as_dict=1)
if email: if email:
email = email[0] email = email[0]
else: else:


+ 10
- 2
frappe/email/doctype/bulk_email/bulk_email.json 查看文件

@@ -59,19 +59,27 @@
"permlevel": 0, "permlevel": 0,
"read_only": 1, "read_only": 1,
"reqd": 0 "reqd": 0
},
{
"fieldname": "send_after",
"fieldtype": "Datetime",
"label": "Send After",
"no_copy": 1,
"permlevel": 0,
"precision": "",
"read_only": 1
} }
], ],
"icon": "icon-envelope", "icon": "icon-envelope",
"idx": 1, "idx": 1,
"in_create": 1, "in_create": 1,
"modified": "2015-03-31 15:10:57.553836",
"modified": "2015-04-01 10:00:20.892939",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Email", "module": "Email",
"name": "Bulk Email", "name": "Bulk Email",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"delete": 1,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,


+ 1
- 1
frappe/public/js/frappe/router.js 查看文件

@@ -103,7 +103,7 @@ frappe.set_route = function() {
window.location.hash = route; window.location.hash = route;


// Set favicon (app.js) // Set favicon (app.js)
frappe.app.set_favicon();
frappe.app.set_favicon && frappe.app.set_favicon();
} }


frappe.set_re_route = function() { frappe.set_re_route = function() {


+ 4
- 1
frappe/utils/__init__.py 查看文件

@@ -30,8 +30,11 @@ def getCSVelement(v):
return '"'+v+'"' return '"'+v+'"'
else: return v or '' else: return v or ''


def get_fullname(user):
def get_fullname(user=None):
"""get the full name (first name + last name) of the user from User""" """get the full name (first name + last name) of the user from User"""
if not user:
user = frappe.session.user

if not hasattr(frappe.local, "fullnames"): if not hasattr(frappe.local, "fullnames"):
frappe.local.fullnames = {} frappe.local.fullnames = {}




正在加载...
取消
保存