Example #1
0
def send_email(success, service_name, error_status=None):
	if success:
		if dataent.db.get_value("Dropbox Settings", None, "send_email_for_successful_backup") == '0':
			return

		subject = "Backup Upload Successful"
		message ="""<h3>Backup Uploaded Successfully</h3><p>Hi there, this is just to inform you
		that your backup was successfully uploaded to your %s account. So relax!</p>
		""" % service_name

	else:
		subject = "[Warning] Backup Upload Failed"
		message ="""<h3>Backup Upload Failed</h3><p>Oops, your automated backup to %s
		failed.</p>
		<p>Error message: <br>
		<pre><code>%s</code></pre>
		</p>
		<p>Please contact your system manager for more information.</p>
		""" % (service_name, error_status)

	if not dataent.db:
		dataent.connect()

	recipients = split_emails(dataent.db.get_value("Dropbox Settings", None, "send_notifications_to"))
	dataent.sendmail(recipients=recipients, subject=subject, message=message)
Example #2
0
	def __init__(self, sender='', recipients=(), subject='', alternative=0, reply_to=None, cc=(), bcc=(), email_account=None, expose_recipients=None):
		from email import charset as Charset
		Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')

		if isinstance(recipients, string_types):
			recipients = recipients.replace(';', ',').replace('\n', '')
			recipients = split_emails(recipients)

		# remove null
		recipients = filter(None, (strip(r) for r in recipients))

		self.sender = sender
		self.reply_to = reply_to or sender
		self.recipients = recipients
		self.subject = subject
		self.expose_recipients = expose_recipients

		self.msg_root = MIMEMultipart('mixed')
		self.msg_alternative = MIMEMultipart('alternative')
		self.msg_root.attach(self.msg_alternative)
		self.cc = cc or []
		self.bcc = bcc or []
		self.html_set = False

		self.email_account = email_account or get_outgoing_email_account(sender=sender)
Example #3
0
def get_bcc(doc, recipients=None, fetched_from_email_account=False):
    """Build a list of email addresses for BCC"""
    bcc = split_emails(doc.bcc)

    if bcc:
        exclude = []
        exclude += [
            d[0] for d in dataent.db.get_all(
                "User", ["email"], {"thread_notify": 0}, as_list=True)
        ]
        exclude += [(parse_addr(email)[1] or "").lower()
                    for email in recipients]

        if fetched_from_email_account:
            # exclude sender when pulling email
            exclude += [parse_addr(doc.sender)[1]]

        if doc.reference_doctype and doc.reference_name:
            exclude += [
                d[0] for d in dataent.db.get_all(
                    "Email Unsubscribe", ["email"], {
                        "reference_doctype": doc.reference_doctype,
                        "reference_name": doc.reference_name
                    },
                    as_list=True)
            ]

        bcc = filter_email_list(doc, bcc, exclude, is_bcc=True)

    return bcc
Example #4
0
def validate_email(doc):
    """Validate Email Addresses of Recipients and CC"""
    if not (doc.communication_type == "Communication"
            and doc.communication_medium == "Email") or doc.flags.in_receive:
        return

    # validate recipients
    for email in split_emails(doc.recipients):
        validate_email_add(email, throw=True)

    # validate CC
    for email in split_emails(doc.cc):
        validate_email_add(email, throw=True)

    for email in split_emails(doc.bcc):
        validate_email_add(email, throw=True)
Example #5
0
def get_recipients_cc_and_bcc(doc,
                              recipients,
                              cc,
                              bcc,
                              fetched_from_email_account=False):
    doc.all_email_addresses = []
    doc.sent_email_addresses = []
    doc.previous_email_sender = None

    if not recipients:
        recipients = get_recipients(
            doc, fetched_from_email_account=fetched_from_email_account)

    if not cc:
        cc = get_cc(doc,
                    recipients,
                    fetched_from_email_account=fetched_from_email_account)

    if not bcc:
        bcc = get_bcc(doc,
                      recipients,
                      fetched_from_email_account=fetched_from_email_account)

    if fetched_from_email_account:
        # email was already sent to the original recipient by the sender's email service
        original_recipients, recipients = recipients, []

        # send email to the sender of the previous email in the thread which this email is a reply to
        #provides erratic results and can send external
        #if doc.previous_email_sender:
        #	recipients.append(doc.previous_email_sender)

        # cc that was received in the email
        original_cc = split_emails(doc.cc)

        # don't cc to people who already received the mail from sender's email service
        cc = list(set(cc) - set(original_cc) - set(original_recipients))
        remove_administrator_from_email_list(cc)

        original_bcc = split_emails(doc.bcc)
        bcc = list(set(bcc) - set(original_bcc) - set(original_recipients))
        remove_administrator_from_email_list(bcc)

    remove_administrator_from_email_list(recipients)

    return recipients, cc, bcc
Example #6
0
    def validate_email_id(self):
        if self.notify_by_email:
            if self.recipients:
                email_list = split_emails(self.recipients.replace("\n", ""))

                from dataent.utils import validate_email_add
                for email in email_list:
                    if not validate_email_add(email):
                        dataent.throw(
                            _("{0} is an invalid email address in 'Recipients'"
                              ).format(email))
            else:
                dataent.throw(_("'Recipients' not specified"))
Example #7
0
def get_recipients(doc, fetched_from_email_account=False):
    """Build a list of email addresses for To"""
    # [EDGE CASE] doc.recipients can be None when an email is sent as BCC
    recipients = split_emails(doc.recipients)

    #if fetched_from_email_account and doc.in_reply_to:
    # add sender of previous reply
    #doc.previous_email_sender = dataent.db.get_value("Communication", doc.in_reply_to, "sender")
    #recipients.append(doc.previous_email_sender)

    if recipients:
        recipients = filter_email_list(doc, recipients, [])

    return recipients
Example #8
0
def get_cc(doc, recipients=None, fetched_from_email_account=False):
    """Build a list of email addresses for CC"""
    # get a copy of CC list
    cc = split_emails(doc.cc)

    if doc.reference_doctype and doc.reference_name:
        if fetched_from_email_account:
            # if it is a fetched email, add follows to CC
            cc.append(get_owner_email(doc))
            cc += get_assignees(doc)

    if getattr(doc, "send_me_a_copy", False) and doc.sender not in cc:
        cc.append(doc.sender)

    if cc:
        # exclude unfollows, recipients and unsubscribes
        exclude = []  #added to remove account check
        exclude += [
            d[0] for d in dataent.db.get_all(
                "User", ["email"], {"thread_notify": 0}, as_list=True)
        ]
        exclude += [(parse_addr(email)[1] or "").lower()
                    for email in recipients]

        if fetched_from_email_account:
            # exclude sender when pulling email
            exclude += [parse_addr(doc.sender)[1]]

        if doc.reference_doctype and doc.reference_name:
            exclude += [
                d[0] for d in dataent.db.get_all(
                    "Email Unsubscribe", ["email"], {
                        "reference_doctype": doc.reference_doctype,
                        "reference_name": doc.reference_name
                    },
                    as_list=True)
            ]

        cc = filter_email_list(doc, cc, exclude, is_cc=True)

    return cc
Example #9
0
def send_email(success, service_name, error_status=None):
	if success:
		if dataent.db.get_value("S3 Backup Settings", None, "send_email_for_successful_backup") == '0':
			return

		subject = "Backup Upload Successful"
		message = """<h3>Backup Uploaded Successfully! </h3><p>Hi there, this is just to inform you
		that your backup was successfully uploaded to your Amazon S3 bucket. So relax!</p> """

	else:
		subject = "[Warning] Backup Upload Failed"
		message = """<h3>Backup Upload Failed! </h3><p>Oops, your automated backup to Amazon S3 failed.
		</p> <p>Error message: %s</p> <p>Please contact your system manager
		for more information.</p>""" % error_status

	if not dataent.db:
		dataent.connect()

	if dataent.db.get_value("S3 Backup Settings", None, "notification_email"):
		recipients = split_emails(dataent.db.get_value("S3 Backup Settings", None, "notification_email"))
		dataent.sendmail(recipients=recipients, subject=subject, message=message)
Example #10
0
def send(recipients=None, sender=None, subject=None, message=None, text_content=None, reference_doctype=None,
		reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None,
		attachments=None, reply_to=None, cc=[], bcc=[], message_id=None, in_reply_to=None, send_after=None,
		expose_recipients=None, send_priority=1, communication=None, now=False, read_receipt=None,
		queue_separately=False, is_notification=False, add_unsubscribe_link=1, inline_images=None,
		header=None, print_letterhead=False):
	"""Add email to sending queue (Email Queue)

	:param recipients: List of recipients.
	:param sender: Email sender.
	:param subject: Email subject.
	:param message: Email message.
	:param text_content: Text version of email message.
	:param reference_doctype: Reference DocType of caller document.
	:param reference_name: Reference name of caller document.
	:param send_priority: Priority for Email Queue, default 1.
	:param unsubscribe_method: URL method for unsubscribe. Default is `/api/method/dataent.email.queue.unsubscribe`.
	:param unsubscribe_params: additional params for unsubscribed links. default are name, doctype, email
	:param attachments: Attachments to be sent.
	:param reply_to: Reply to be captured here (default inbox)
	:param in_reply_to: Used to send the Message-Id of a received email back as In-Reply-To.
	:param send_after: Send this email after the given datetime. If value is in integer, then `send_after` will be the automatically set to no of days from current date.
	:param communication: Communication link to be set in Email Queue record
	:param now: Send immediately (don't send in the background)
	:param queue_separately: Queue each email separately
	:param is_notification: Marks email as notification so will not trigger notifications from system
	:param add_unsubscribe_link: Send unsubscribe link in the footer of the Email, default 1.
	:param inline_images: List of inline images as {"filename", "filecontent"}. All src properties will be replaced with random Content-Id
	:param header: Append header in email (boolean)
	"""
	if not unsubscribe_method:
		unsubscribe_method = "/api/method/dataent.email.queue.unsubscribe"

	if not recipients and not cc:
		return

	if isinstance(recipients, string_types):
		recipients = split_emails(recipients)

	if isinstance(cc, string_types):
		cc = split_emails(cc)

	if isinstance(bcc, string_types):
		bcc = split_emails(bcc)

	if isinstance(send_after, int):
		send_after = add_days(nowdate(), send_after)

	email_account = get_outgoing_email_account(True, append_to=reference_doctype, sender=sender)
	if not sender or sender == "Administrator":
		sender = email_account.default_sender

	check_email_limit(recipients)

	if not text_content:
		try:
			text_content = html2text(message)
		except HTMLParser.HTMLParseError:
			text_content = "See html attachment"

	recipients = list(set(recipients))
	cc = list(set(cc))

	all_ids = recipients + cc

	unsubscribed = dataent.db.sql_list('''
		SELECT
			distinct email
		from
			`tabEmail Unsubscribe`
		where
			email in %(all_ids)s
			and (
				(
					reference_doctype = %(reference_doctype)s
					and reference_name = %(reference_name)s
				)
				or global_unsubscribe = 1
			)
	''', {
		'all_ids': all_ids,
		'reference_doctype': reference_doctype,
		'reference_name': reference_name,
	})

	recipients = [r for r in recipients if r and r not in unsubscribed]

	if cc:
		cc = [r for r in cc if r and r not in unsubscribed]

	if not recipients and not cc:
		# Recipients may have been unsubscribed, exit quietly
		return

	email_text_context = text_content

	should_append_unsubscribe = (add_unsubscribe_link
		and reference_doctype
		and (unsubscribe_message or reference_doctype=="Newsletter")
		and add_unsubscribe_link==1)

	unsubscribe_link = None
	if should_append_unsubscribe:
		unsubscribe_link = get_unsubscribe_message(unsubscribe_message, expose_recipients)
		email_text_context += unsubscribe_link.text

	email_content = get_formatted_html(subject, message,
		email_account=email_account, header=header,
		unsubscribe_link=unsubscribe_link)

	# add to queue
	add(recipients, sender, subject,
		formatted=email_content,
		text_content=email_text_context,
		reference_doctype=reference_doctype,
		reference_name=reference_name,
		attachments=attachments,
		reply_to=reply_to,
		cc=cc,
		bcc=bcc,
		message_id=message_id,
		in_reply_to=in_reply_to,
		send_after=send_after,
		send_priority=send_priority,
		email_account=email_account,
		communication=communication,
		add_unsubscribe_link=add_unsubscribe_link,
		unsubscribe_method=unsubscribe_method,
		unsubscribe_params=unsubscribe_params,
		expose_recipients=expose_recipients,
		read_receipt=read_receipt,
		queue_separately=queue_separately,
		is_notification = is_notification,
		inline_images = inline_images,
		header=header,
		now=now,
		print_letterhead=print_letterhead)