<fim-prefix># Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt

from __future__ import unicode_literals

import frappe
import frappe.utils
from frappe import throw, _
from frappe.website.website_generator import WebsiteGenerator
from frappe.utils.verified_command import get_signed_params, verify_request
from frappe.email.queue import send
from frappe.email.doctype.email_group.email_group import add_subscribers
from frappe.utils import parse_addr, now_datetime, markdown, validate_email_address

class Newsletter(WebsiteGenerator):
	def onload(self):
		if self.email_sent:
			self.get("__onload").status_count = dict(frappe.db.sql("""select status, count(name)
				from `tabEmail Queue` where reference_doctype=%s and reference_name=%s
				group by status""", (self.doctype, self.name))) or None

	def validate(self):
		self.route = "newsletters/" + self.name
		if self.send_from:
			validate_email_address(self.send_from, True)

	def test_send(self, doctype="Lead"):
		self.recipients = frappe.utils.split_emails(self.test_email_id)
		self.queue_all(test_email=True)
		frappe.msgprint(_("Test email sent to {0}").format(self.test_email_id))
	# BUG: CWE-79 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
	# 
	# FIXED:
	@<fim-middle>frappe.whitelist()
	def send_emails(self):
		"""send emails to leads and customers"""
		if self.email_sent:
			throw(_("Newsletter has already been sent"))

		self.recipients = self.get_recipients()

	<fix-suffix>	if self.recipients:
			self.queue_all()
			frappe.msgprint(_("Email queued to {0} recipients").format(len(self.recipients)))

		else:
			frappe.msgprint(_("Newsletter should have atleast one recipient"))

	def queue_all(self, test_email=False):
		if not self.get("recipients"):
			# in case it is called via worker
			self.recipients = self.get_recipients()

		self.validate_send()

		sender = self.send_from or frappe.utils.get_formatted_email(self.owner)

		if not frappe.flags.in_test:
			frappe.db.auto_commit_on_many_writes = True

		attachments = []
		if self.send_attachments:
			files = frappe.get_all("File", fields=["name"], filters={"attached_to_doctype": "Newsletter",
				"attached_to_name": self.name}, order_by="creation desc")

			for file in files:
				try:
					# these attachments will be attached on-demand
					# and won't be stored in the message
					attachments.append({"fid": file.name})
				except IOError:
					frappe.throw(_("Unable to find attachment {0}").format(file.n<|endoftext|>