Commit 65526cee authored by Patrick's avatar Patrick

Create a mail object and a 'unsubscre' to mails

parent 1b59026c
# -*- coding: utf-8
from __future__ import unicode_literals
from smtplib import SMTPRecipientsRefused, SMTPAuthenticationError
import time
import datetime
from django.conf import settings
from django.core import mail
from django.core.mail import EmailMultiAlternatives, mail_admins
from django.utils.html import strip_tags
from django.utils.text import slugify
from django.utils import timezone
from repanier.const import DEMO_EMAIL, EMPTY_STRING
class RepanierEmail(EmailMultiAlternatives):
def __init__(self, *args, **kwargs):
self.html_content = kwargs.pop('html_content', None)
self.unsubscribe = kwargs.pop('unsubscribe', True)
self.test_connection = kwargs.pop('test_connection', None)
super(RepanierEmail, self).__init__(*args, **kwargs)
self._set_connection_param()
def _set_connection_param(self):
from repanier.apps import REPANIER_SETTINGS_CONFIG
config = REPANIER_SETTINGS_CONFIG
if config.email_is_custom and not settings.DJANGO_SETTINGS_DEMO:
self.host = config.email_host
self.port = config.email_port
self.from_email = self.host_user = config.email_host_user
self.host_password = config.email_host_password
self.use_tls = config.email_use_tls
else:
self.host = settings.EMAIL_HOST
self.port = settings.EMAIL_PORT
self.host_user = settings.EMAIL_HOST_USER
if not hasattr(self, 'from_email') or settings.DJANGO_SETTINGS_DEMO:
self.from_email = settings.DEFAULT_FROM_EMAIL
self.host_password = settings.EMAIL_HOST_PASSWORD
self.use_tls = settings.EMAIL_USE_TLS
def send_email(self, from_name=EMPTY_STRING):
email_send = False
if settings.DJANGO_SETTINGS_DEMO:
self.to = [DEMO_EMAIL]
self.cc = []
self.bcc = []
email_send = self._send_email_with_error_log(from_name=from_name)
else:
from repanier.apps import REPANIER_SETTINGS_TEST_MODE
if REPANIER_SETTINGS_TEST_MODE:
from repanier.tools import emails_of_testers
self.to = emails_of_testers()
if len(self.to) > 0:
# Send the mail only if there is at least one tester
self.cc = []
self.bcc = []
email_send = self._send_email_with_error_log(from_name=from_name)
else:
print('############################ test mode, without tester...')
else:
if settings.DEBUG:
print("to : %s" % self.to)
print("cc : %s" % self.cc)
print("bcc : %s" % self.bcc)
print("subject : %s" % slugify(self.subject))
email_send = True
else:
# chunks = [email.to[x:x+100] for x in xrange(0, len(email.to), 100)]
# for chunk in chunks:
# Remove duplicates
send_email_to = list(set(self.to + self.cc + self.bcc))
self.cc = []
self.bcc = []
email_send = True
if len(send_email_to) >= 1:
for email_to in send_email_to:
self.to = [email_to]
email_send &= self._send_email_with_error_log(from_name=from_name)
time.sleep(1)
return email_send
def _send_email_with_error_log(self, from_name=EMPTY_STRING):
email_to = self.to[0]
if not self.test_connection:
# customer = self._get_customer("ask.it@test.it")
customer = self._get_customer(email_to)
if customer is not None:
if customer.user.last_login is None:
# Do not spam someone who has never logged in
return False
else:
max_2_years_in_the_past = timezone.now() - datetime.timedelta(days=730)
if customer.user.last_login < max_2_years_in_the_past:
# Do not spam someone who has never logged in since more than 2 years
return False
else:
customer = None
self.body = strip_tags(self.html_content)
if self.unsubscribe and customer is not None:
self.attach_alternative(
"%s%s" % (self.html_content, customer.get_unsubscribe_mail_footer()),
"text/html"
)
else:
self.attach_alternative(
self.html_content,
"text/html"
)
email_send = False
try:
from repanier.apps import REPANIER_SETTINGS_GROUP_NAME
with mail.get_connection(
host=self.host,
port=self.port,
username=self.host_user,
password=self.host_password,
use_tls=self.use_tls,
use_ssl=not self.use_tls) as connection:
self.connection = connection
message = EMPTY_STRING
if not self.from_email.endswith(settings.DJANGO_SETTINGS_ALLOWED_MAIL_EXTENSION):
self.reply_to = [self.from_email]
self.from_email = "%s <%s>" % (from_name or REPANIER_SETTINGS_GROUP_NAME, self.from_email)
else:
self.from_email = "%s <%s>" % (from_name or REPANIER_SETTINGS_GROUP_NAME, self.from_email)
try:
print("################################## send_email")
from_email = "from_email : %s" % self.from_email
reply_to = "reply_to : %s" % self.reply_to
to = "to : %s" % self.to
cc = "cc : %s" % self.cc
bcc = "bcc : %s" % self.bcc
subject = "subject : %s" % slugify(self.subject)
print(from_email)
print(reply_to)
print(to)
print(cc)
print(bcc)
print(subject)
message = "%s\n%s\n%s\n%s" % (to, cc, bcc, subject)
self.send()
email_send = True
except SMTPRecipientsRefused as error_str:
print("################################## send_email SMTPRecipientsRefused")
print(error_str)
time.sleep(1)
connection = mail.get_connection()
connection.open()
mail_admins("ERROR", "%s\n%s" % (message, error_str), connection=connection)
connection.close()
except Exception as error_str:
print("################################## send_email error")
print(error_str)
time.sleep(1)
connection = mail.get_connection()
connection.open()
mail_admins("ERROR", "%s\n%s" % (message, error_str), connection=connection)
connection.close()
print("##################################")
if email_send and customer is not None:
from repanier.models.customer import Customer
# customer.valid_email = valid_email
# customer.save(update_fields=['valid_email'])
# use vvvv because ^^^^^ will call "pre_save" function which reset valid_email to None
Customer.objects.filter(id=customer.id).order_by('?').update(valid_email=email_send)
except SMTPAuthenticationError as error_str:
print("################################## send_email SMTPAuthenticationError")
# https://support.google.com/accounts/answer/185833
# https://support.google.com/accounts/answer/6010255
# https://security.google.com/settings/security/apppasswords
print(error_str)
return email_send
def _get_customer(self, email_address):
from repanier.models.customer import Customer
# try to find a customer based on user__email or customer__email2
customer = Customer.objects.filter(
user__email=email_address,
subscribe_to_email=True,
).exclude(
valid_email=False,
).only('id').order_by('?').first()
if customer is None:
customer = Customer.objects.filter(
email2=email_address,
subscribe_to_email=True,
).exclude(
valid_email=False
).only('id').order_by('?').first()
return customer
# -*- coding: utf-8
from __future__ import unicode_literals
from django.core.mail import EmailMultiAlternatives
from django.core.urlresolvers import reverse
from django.template import Template, Context as TemplateContext
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from repanier.models import Purchase
from repanier.models import Configuration
from repanier.models import Customer
from repanier.models import Permanence
from repanier.models import Producer
from repanier.models.configuration import Configuration
from repanier.models.customer import Customer
from repanier.models.permanence import Permanence
from repanier.models.producer import Producer
from repanier.models.purchase import Purchase
from repanier.tools import *
......@@ -46,7 +45,7 @@ def send_invoice(permanence_id):
'name' : long_profile_name,
'long_profile_name': long_profile_name,
'permanence_link' : mark_safe(
'<a href="http://%s%s">%s</a>' % (settings.ALLOWED_HOSTS[0],
'<a href="https://%s%s">%s</a>' % (settings.ALLOWED_HOSTS[0],
reverse('producer_invoice_uuid_view',
args=(0, producer.uuid)),
permanence)),
......@@ -62,14 +61,13 @@ def send_invoice(permanence_id):
to_email_producer.append(producer.email2)
if producer.email3:
to_email_producer.append(producer.email3)
email = EmailMultiAlternatives(
invoice_producer_mail_subject,
strip_tags(html_content),
email = RepanierEmail(
subject=invoice_producer_mail_subject,
html_content=html_content,
from_email=sender_email,
to=to_email_producer
)
email.attach_alternative(html_content, "text/html")
send_email(email=email)
email.send_email()
if REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER:
# To the customer we speak of "invoice".
......@@ -105,10 +103,10 @@ def send_invoice(permanence_id):
'basket_name' : customer.short_basket_name,
'short_basket_name' : customer.short_basket_name,
'permanence_link' : mark_safe(
'<a href="http://%s%s">%s</a>' % (settings.ALLOWED_HOSTS[0],
'<a href="https://%s%s">%s</a>' % (settings.ALLOWED_HOSTS[0],
reverse('order_view', args=(permanence.id,)),
permanence)),
'last_balance_link' : mark_safe('<a href="http://%s%s">%s</a>' % (
'last_balance_link' : mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0,)),
customer_last_balance)),
'last_balance' : mark_safe(customer_last_balance),
......@@ -120,12 +118,11 @@ def send_invoice(permanence_id):
signature, sender_function, REPANIER_SETTINGS_GROUP_NAME))
})
html_content = template.render(context)
email = EmailMultiAlternatives(
invoice_customer_mail_subject,
strip_tags(html_content),
email = RepanierEmail(
subject=invoice_customer_mail_subject,
html_content=html_content,
from_email=sender_email,
to=to_email_customer
)
email.attach_alternative(html_content, "text/html")
send_email(email=email)
email.send_email()
translation.activate(cur_language)
......@@ -3,16 +3,18 @@ from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.template import Template, Context as TemplateContext
# AttributeError: 'Context' object has no attribute 'render_context'
# OK, i got the solution:
# from decimal import *
# is the "bad One" this lib has a Context object too. Thanks for anyone reading!
from django.core.mail import EmailMultiAlternatives
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from repanier.models import Permanence, Producer, OfferItem
from repanier.models import Customer, Configuration
from repanier.models.configuration import Configuration
from repanier.models.customer import Customer
from repanier.models.offeritem import OfferItem
from repanier.models.permanence import Permanence
from repanier.models.producer import Producer
from repanier.tools import *
......@@ -46,13 +48,13 @@ def send_pre_open_order(permanence_id):
context = TemplateContext({
'name' : long_profile_name,
'long_profile_name': long_profile_name,
'permanence_link' : mark_safe('<a href="http://%s%s">%s</a>' % (
'permanence_link' : mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0],
reverse('pre_order_uuid_view', args=(producer.offer_uuid,)), _("offer"))
),
'offer_description': mark_safe(offer_description),
'offer_link' : mark_safe(
'<a href="http://%s%s">%s</a>' % (
'<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0],
reverse('pre_order_uuid_view', args=(producer.offer_uuid,)), _("offer"))
),
......@@ -68,15 +70,14 @@ def send_pre_open_order(permanence_id):
to_email_producer.append(producer.email2)
if producer.email3:
to_email_producer.append(producer.email3)
email = EmailMultiAlternatives(
offer_producer_mail_subject,
strip_tags(html_content),
email = RepanierEmail(
subject=offer_producer_mail_subject,
html_content=html_content,
from_email=sender_email,
to=to_email_producer,
cc=cc_email_staff
)
email.attach_alternative(html_content, "text/html")
send_email(email=email)
email.send_email()
send_sms(
sms_nr=producer.phone1,
sms_msg="%s : %s - %s" % (REPANIER_SETTINGS_GROUP_NAME,
......@@ -129,7 +130,7 @@ def send_open_order(permanence_id):
),)
template = Template(offer_customer_mail)
context = TemplateContext({
'permanence_link' : mark_safe('<a href="http://%s%s">%s</a>' % (
'permanence_link' : mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)),
'offer_description': mark_safe(offer_description),
'offer_detail' : mark_safe(offer_detail),
......@@ -139,12 +140,11 @@ def send_open_order(permanence_id):
'%s<br/>%s<br/>%s' % (signature, sender_function, REPANIER_SETTINGS_GROUP_NAME))
})
html_content = template.render(context)
email = EmailMultiAlternatives(
offer_customer_mail_subject,
strip_tags(html_content),
email = RepanierEmail(
subject=offer_customer_mail_subject,
html_content=html_content,
from_email=sender_email,
bcc=list(set(to_email_staff) | set(to_email_customer))
)
email.attach_alternative(html_content, "text/html")
send_email(email=email, track_customer_on_error=True)
email.send_email()
translation.activate(cur_language)
# -*- coding: utf-8
from __future__ import unicode_literals
from django.core.mail import EmailMultiAlternatives
from django.core.urlresolvers import reverse
from django.template import Template, Context as TemplateContext
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from openpyxl.writer.excel import save_virtual_workbook
from repanier.models import Customer
from repanier.models import DeliveryBoard
from repanier.models import Permanence, Configuration, CustomerInvoice
from repanier.models import PermanenceBoard
from repanier.models import Producer, ProducerInvoice
from repanier.models.configuration import Configuration
from repanier.models.customer import Customer
from repanier.models.deliveryboard import DeliveryBoard
from repanier.models.invoice import CustomerInvoice, ProducerInvoice
from repanier.models.permanence import Permanence
from repanier.models.permanenceboard import PermanenceBoard
from repanier.models.producer import Producer
from repanier.tools import *
from repanier.xlsx.xlsx_order import generate_customer_xlsx, generate_producer_xlsx
......@@ -79,7 +81,7 @@ def email_order(permanence_id, all_producers=True, producers_id=None, closed_del
template = Template(order_staff_mail)
context = TemplateContext({
'permanence_link' : mark_safe('<a href="http://%s%s">%s</a>' % (
'permanence_link' : mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)),
'board_composition' : mark_safe(board_composition),
'board_composition_and_description': mark_safe(board_composition_and_description),
......@@ -87,9 +89,9 @@ def email_order(permanence_id, all_producers=True, producers_id=None, closed_del
'%s<br/>%s<br/>%s' % (signature, sender_function, REPANIER_SETTINGS_GROUP_NAME))
})
html_content = template.render(context)
email = EmailMultiAlternatives(
order_staff_mail_subject,
strip_tags(html_content),
email = RepanierEmail(
subject=order_staff_mail_subject,
html_content=html_content,
from_email=sender_email,
to=to_email_board,
cc=cc_email_staff
......@@ -97,13 +99,12 @@ def email_order(permanence_id, all_producers=True, producers_id=None, closed_del
email.attach(group_filename,
save_virtual_workbook(wb),
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
email.attach_alternative(html_content, "text/html")
if not REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_BOARD:
email.to = cc_email_staff
email.cc = []
email.bcc = []
send_email(email=email)
email.send_email()
# Orders send to our producers
if REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_PRODUCER:
......@@ -128,14 +129,14 @@ def email_order(permanence_id, all_producers=True, producers_id=None, closed_del
'long_profile_name': long_profile_name,
'order_empty' : wb is None,
'duplicate' : not (wb is None or producer.manage_replenishment),
'permanence_link' : mark_safe('<a href="http://%s%s">%s</a>' % (
'permanence_link' : mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)),
'signature' : mark_safe(
'%s<br/>%s<br/>%s' % (signature, sender_function, REPANIER_SETTINGS_GROUP_NAME))
})
html_content = template.render(context)
producer_invoice = models.ProducerInvoice.objects.filter(
producer_invoice = ProducerInvoice.objects.filter(
producer_id=producer.id, permanence_id=permanence.id
).only("total_price_with_tax").order_by('?').first()
if producer_invoice is not None \
......@@ -154,9 +155,9 @@ def email_order(permanence_id, all_producers=True, producers_id=None, closed_del
to_email_producer.append(producer.email2)
if producer.email3:
to_email_producer.append(producer.email3)
email = EmailMultiAlternatives(
order_producer_mail_subject,
strip_tags(html_content),
email = RepanierEmail(
subject=order_producer_mail_subject,
html_content=html_content,
from_email=sender_email,
to=to_email_producer,
cc=cc_email_staff
......@@ -171,8 +172,7 @@ def email_order(permanence_id, all_producers=True, producers_id=None, closed_del
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
email.attach_alternative(html_content, "text/html")
send_email(email=email)
email.send_email()
if all_producers:
# Orders send to our customers only if they don't have already received it
......@@ -233,9 +233,9 @@ def export_order_2_1_group(config, customer, delivery_point, closed_delivery_id,
'long_basket_name' : long_basket_name,
'basket_name' : customer.short_basket_name,
'short_basket_name': customer.short_basket_name,
'permanence_link' : mark_safe('<a href="http://%s%s">%s</a>' % (
'permanence_link' : mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)),
'last_balance_link': mark_safe('<a href="http://%s%s">%s</a>' % (
'last_balance_link': mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0,)), _("Group invoices"))),
'last_balance' : EMPTY_STRING,
'order_amount' : EMPTY_STRING,
......@@ -246,9 +246,9 @@ def export_order_2_1_group(config, customer, delivery_point, closed_delivery_id,
'%s<br/>%s<br/>%s' % (signature, sender_function, REPANIER_SETTINGS_GROUP_NAME))
})
html_content = template.render(context)
email = EmailMultiAlternatives(
order_customer_mail_subject,
strip_tags(html_content),
email = RepanierEmail(
subject=order_customer_mail_subject,
html_content=html_content,
from_email=sender_email,
to=to_email_customer
)
......@@ -256,8 +256,7 @@ def export_order_2_1_group(config, customer, delivery_point, closed_delivery_id,
save_virtual_workbook(wb),
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
email.attach_alternative(html_content, "text/html")
send_email(email=email)
email.send_email()
def export_order_2_1_customer(customer, filename, permanence, sender_email, sender_function, signature,
......@@ -311,9 +310,9 @@ def export_order_2_1_customer(customer, filename, permanence, sender_email, send
'long_basket_name' : long_basket_name,
'basket_name' : customer.short_basket_name,
'short_basket_name': customer.short_basket_name,
'permanence_link' : mark_safe('<a href="http://%s%s">%s</a>' % (
'permanence_link' : mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)),
'last_balance_link': mark_safe('<a href="http://%s%s">%s</a>' % (
'last_balance_link': mark_safe('<a href="https://%s%s">%s</a>' % (
settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0,)), customer_last_balance)),
'last_balance' : mark_safe(customer_last_balance),
'order_amount' : mark_safe(customer_order_amount),
......@@ -324,9 +323,9 @@ def export_order_2_1_customer(customer, filename, permanence, sender_email, send
'%s<br/>%s<br/>%s' % (signature, sender_function, REPANIER_SETTINGS_GROUP_NAME))
})
html_content = template.render(context)
email = EmailMultiAlternatives(
order_customer_mail_subject,
strip_tags(html_content),
email = RepanierEmail(
subject=order_customer_mail_subject,
html_content=html_content,
from_email=sender_email,
to=to_email_customer
)
......@@ -337,5 +336,4 @@ def export_order_2_1_customer(customer, filename, permanence, sender_email, send
save_virtual_workbook(wb),
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
email.attach_alternative(html_content, "text/html")
send_email(email=email)
email.send_email()
This diff is collapsed.
{% extends "base.html" %}{% load i18n admin_static %}
{% block base_content %}
<div id="content-main" class="container-repanier">
<div class="container">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="unsubscribeModalLabel">{% trans "Unsubscribe" %}</h4>
</div>
<div class="modal-body">
{% blocktrans %}Your unsubscription is registered. You can go right now on the
<a href="/repanier/go_repanier/" class="btn btn-default">login page</a> or on the
<a href="/" class="btn btn-default">home page</a>.{% endblocktrans %}
</div><!-- /form -->
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
</div>
{% endblock %}
This diff is collapsed.
# -*- coding: utf-8
from __future__ import unicode_literals
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
from repanier.models.customer import Customer
@csrf_protect
@never_cache
def unsubscribe_view(request, short_name, token):
"""
User is immediately unsubscribed
if they came from an unexpired unsubscribe link.
"""
customer = Customer.objects.filter(
short_basket_name=short_name
).order_by('?').first()
if customer is not None and (not customer.subscribe_to_email or customer.check_token(token)):
# unsubscribe them
# customer.save(update_fields=['subscribe_to_email'])
# use vvvv because ^^^^^ will call "pre_save" function which reset valid_email to None
if customer.subscribe_to_email:
Customer.objects.filter(id=customer.id).order_by('?').update(subscribe_to_email=False)
return render(request, 'repanier/registration/unsubscribe.html')
else:
return HttpResponseRedirect("/")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment