Сделал страницу "Переслать другу"

remotes/origin/stage6
Alexander Burdeinyi 9 years ago
parent 371d3a8594
commit b99a14d516
  1. 1
      accounts/views.py
  2. 10
      emencia/django/newsletter/forms.py
  3. 49
      emencia/django/newsletter/mailer.py
  4. 19
      emencia/django/newsletter/templates/newsletter/AutomaticEmail_v2.html
  5. 2
      emencia/django/newsletter/templates/newsletter/AutomaticEmail_web.html
  6. 5
      emencia/django/newsletter/urls/mailing_list.py
  7. 59
      emencia/django/newsletter/views/mailing_list.py
  8. 2
      templates/client/accounts/mailing_settings.html
  9. 2
      templates/client/article/article.html
  10. 65
      templates/client/newsletters/sendmail_to_friend.html
  11. 19
      templates/client/newsletters/sendmail_to_friend_message.html

@ -131,6 +131,7 @@ class MailingSettings(GetUserMixin, ContextMixin, AjaxableResponseMixin, CreateU
'checked_r_cities': list(instance.r_cities.values_list('pk', flat=True)), 'checked_r_cities': list(instance.r_cities.values_list('pk', flat=True)),
'checked_tg': list(instance.tags.values_list('pk', flat=True)), 'checked_tg': list(instance.tags.values_list('pk', flat=True)),
'checked_th': list(instance.themes.values_list('pk', flat=True)), 'checked_th': list(instance.themes.values_list('pk', flat=True)),
'contact': instance,
}) })
elif not self.request.user.is_authenticated(): elif not self.request.user.is_authenticated():
raise HttpResponseForbidden() raise HttpResponseForbidden()

@ -584,3 +584,13 @@ class MailingStatusFilter(forms.Form):
if ab: if ab:
qs = qs.filter(ab=ab) qs = qs.filter(ab=ab)
return qs return qs
class SendtoFriendForm(forms.Form):
email = forms.EmailField(label=_(u"E-mail Вашего друга"), required=False)
first_name = forms.CharField(label=_(u"Имя Вашего друга"), required=False)
def clean_first_name(self):
if self.cleaned_data.get('email') and not self.cleaned_data.get('first_name'):
raise forms.ValidationError(_(u'Введите имя вашего друга'))
return self.cleaned_data.get('first_name')

@ -129,7 +129,7 @@ dailymail_attahcments = {
'twitter': 'newsletter/images/twitter.png', 'twitter': 'newsletter/images/twitter.png',
} }
context_attachments_size = { context_attachments_size = {
'recommended': '281x225', 'recommended': '17',
'news': '272x195', 'news': '272x195',
'blog': '272x195', 'blog': '272x195',
'moscow': '109x114', 'moscow': '109x114',
@ -144,6 +144,7 @@ class NewsLetterSender(object):
self.test = test self.test = test
self.verbose = verbose self.verbose = verbose
self.newsletter = newsletter self.newsletter = newsletter
self.settings_links = True
self.newsletter_template = Template(self.newsletter.content) self.newsletter_template = Template(self.newsletter.content)
self.themes = dict(Theme.objects.language('ru').all().values_list('pk', 'name')) self.themes = dict(Theme.objects.language('ru').all().values_list('pk', 'name'))
@ -159,14 +160,14 @@ class NewsLetterSender(object):
self.announce = self.newsletter.dailymail self.announce = self.newsletter.dailymail
self.local_dev = getattr(settings, 'LOCAL_DEV', False) self.local_dev = getattr(settings, 'LOCAL_DEV', False)
def build_message(self, contact, announce_context=None): def build_message(self, contact, announce_context=None, name=None):
""" """
Build the email as a multipart message containing Build the email as a multipart message containing
a multipart alternative for text (plain, HTML) plus a multipart alternative for text (plain, HTML) plus
all the attached files. all the attached files.
""" """
content_html = self.build_email_content(contact, announce_context) content_html = self.build_email_content(contact, announce_context, name)
h = HTMLParser.HTMLParser() h = HTMLParser.HTMLParser()
content_html = h.unescape(content_html) content_html = h.unescape(content_html)
@ -384,7 +385,7 @@ class NewsLetterSender(object):
title = self.newsletter.title2.format(**self.preheader_ctx) title = self.newsletter.title2.format(**self.preheader_ctx)
return title return title
def build_email_content(self, contact, announce_context=None): def build_email_content(self, contact, announce_context=None, name=None):
"""Generate the mail for a contact""" """Generate the mail for a contact"""
uidb36, token = tokenize(contact) uidb36, token = tokenize(contact)
context = Context({'contact': contact, context = Context({'contact': contact,
@ -392,7 +393,8 @@ class NewsLetterSender(object):
'newsletter': self.newsletter, 'newsletter': self.newsletter,
'tracking_image_format': TRACKING_IMAGE_FORMAT, 'tracking_image_format': TRACKING_IMAGE_FORMAT,
'uidb36': uidb36, 'token': token, 'uidb36': uidb36, 'token': token,
'name': contact.first_name or contact.last_name or _(u'Подписчик'), 'name': name or contact.first_name or contact.last_name or _(u'Подписчик'),
'settings_links': self.settings_links,
}) })
if self.announce: if self.announce:
# render template by default announce template # render template by default announce template
@ -441,7 +443,7 @@ class NewsLetterSender(object):
return smart_unicode(content) return smart_unicode(content)
def build_preheader_ctx(self, contact): def build_preheader_ctx(self, contact, name=None):
t_add = u'' t_add = u''
count = contact.themes.count() count = contact.themes.count()
if count > 3: if count > 3:
@ -452,7 +454,7 @@ class NewsLetterSender(object):
theme_word=theme_word.make_agree_with_number(count).word, theme_word=theme_word.make_agree_with_number(count).word,
) )
self.preheader_ctx = { self.preheader_ctx = {
'name': contact.first_name or contact.last_name or _(u'Подписчик'), 'name': name or contact.first_name or contact.last_name or _(u'Подписчик'),
'themes': u', '.join([self.themes.get(x) for x in contact.themes.all().values_list('pk', flat=True)[:3]]) + t_add, 'themes': u', '.join([self.themes.get(x) for x in contact.themes.all().values_list('pk', flat=True)[:3]]) + t_add,
} }
@ -571,6 +573,39 @@ class Mailer(NewsLetterSender):
In test mode the mailer always send mails but do not log it""" In test mode the mailer always send mails but do not log it"""
smtp = None smtp = None
def send_to_friends(self, contact, contacts):
if not self.can_send:
return
if not self.smtp and not self.local_dev:
self.smtp_connect()
self.attachments = self.build_daily_attachments()
for _contact in contacts:
send = True
self.build_preheader_ctx(contact, name=_contact.get('name'))
announce_context = contact.get_announce_context_v2(self.newsletter.sending_date)
if not announce_context:
send = False
try:
log.info(u'Trying send to {email}'.format(email=contact.email))
# pass
if send:
message = self.build_message(contact, announce_context, _contact.get('name'))
if not self.local_dev:
self.smtp.sendmail(self.newsletter.header_sender,
_contact.get('email'),
message.as_string())
except (Exception,) as e:
exception = e
log.info(u'Exception was raised while sending to {email}: {exception}'.format(
email=contact.email, exception=exception))
else:
exception = None
if not self.local_dev:
self.smtp.quit()
def run(self): def run(self):
"""Send the mails""" """Send the mails"""
if not self.can_send: if not self.can_send:

@ -115,7 +115,6 @@
<table cellspacing="0" cellpadding="0" border="0" style="width: 600px; margin: 0 auto;"> <table cellspacing="0" cellpadding="0" border="0" style="width: 600px; margin: 0 auto;">
<tr> <tr>
<td valign="top" style="width: 170px;"> <td valign="top" style="width: 170px;">
{# TODO: Сменить размер картинки на 170x170 #}
<a href="http://{{ domain }}{{ obj.get_permanent_url }}"><img src="cid:recommended{{ obj.pk }}" style="margin-top: -2px;"/></a>{# {% endthumbnail %}#} <a href="http://{{ domain }}{{ obj.get_permanent_url }}"><img src="cid:recommended{{ obj.pk }}" style="margin-top: -2px;"/></a>{# {% endthumbnail %}#}
</td> </td>
@ -653,12 +652,18 @@
<!-- footer --> <!-- footer -->
<table cellspacing="0" cellpadding="0" border="0" style="width: 100%; background-color: #ffffff; border-top: 1px solid #f3f3f3;"> <table cellspacing="0" cellpadding="0" border="0" style="width: 100%; background-color: #ffffff; border-top: 1px solid #f3f3f3;">
<tr> {% if settings_links %}
<td style="padding-top: 35px; padding-left: 20px; padding-right: 20px; font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;" align="center">{% trans "Вы получили это письмо, так как подписаны на рассылку" %} <a href="#" style="color: #ff6600;">https://www.expomap.ru</a></td> <tr>
</tr> <td style="padding-top: 35px; padding-left: 20px; padding-right: 20px; font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;" align="center">{% trans "Вы получили это письмо, так как подписаны на рассылку" %} <a href="http://www.expomap.ru" style="color: #ff6600;">https://www.expomap.ru</a></td>
<tr> </tr>
<td align="center" style="font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;"><a href="#" style="color: #ff6600;">{% trans "Переслать другу" %}</a> {% trans "или" %} <a href="#" style="color: #ff6600;">{% trans "Отписаться" %}</a></td> <tr>
</tr> <td align="center" style="font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;"><a href="{% url 'newsletter-sendtofriend' slug=newsletter.slug uidb36=uidb36 token=token %}" style="color: #ff6600;">{% trans "Переслать другу" %}</a> {% trans "или" %} <a href="{% if uidb36 and token %}http://{{ domain }}{% url 'newsletter-authmailingsettings' uidb36=uidb36 token=token %}{% endif %}" style="color: #ff6600;">{% trans "Отписаться" %}</a></td>
</tr>
{% else %}
<tr>
<td style="padding-top: 35px; padding-left: 20px; padding-right: 20px; font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;" align="center">{% trans "Вы получили это письмо, так как его переслал ваш друг" %} {{ contact.email }}. <a href="#" style="color: #ff6600;">https://www.expomap.ru</a></td>
</tr>
{% endif %}
<tr> <tr>
<td align="center" style="padding-bottom: 30px; font-family: Arial, sans-serif; font-size: 13px; color: #999999;">&copy; 2008 — 2016 Expomap.ru</td> <td align="center" style="padding-bottom: 30px; font-family: Arial, sans-serif; font-size: 13px; color: #999999;">&copy; 2008 — 2016 Expomap.ru</td>
</tr> </tr>

@ -668,7 +668,7 @@
<td style="padding-top: 35px; padding-left: 20px; padding-right: 20px; font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;" align="center">{% trans "Вы получили это письмо, так как подписаны на рассылку" %} <a href="#" style="color: #ff6600;">https://www.expomap.ru</a></td> <td style="padding-top: 35px; padding-left: 20px; padding-right: 20px; font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;" align="center">{% trans "Вы получили это письмо, так как подписаны на рассылку" %} <a href="#" style="color: #ff6600;">https://www.expomap.ru</a></td>
</tr> </tr>
<tr> <tr>
<td align="center" style="font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;"><a href="#" style="color: #ff6600;">{% trans "Переслать другу" %}</a> {% trans "или" %} <a href="#" style="color: #ff6600;">{% trans "Отписаться" %}</a></td> <td align="center" style="font-family: Arial, sans-serif; font-size: 13px; color: #999999; padding-bottom: 7px;"><a href="{% url 'newsletter-sendtofriend' slug=newsletter.slug uidb36=uidb36 token=token %}" style="color: #ff6600;">{% trans "Переслать другу" %}</a> {% trans "или" %} <a href="#" style="color: #ff6600;">{% trans "Отписаться" %}</a></td>
</tr> </tr>
<tr> <tr>
<td align="center" style="padding-bottom: 30px; font-family: Arial, sans-serif; font-size: 13px; color: #999999;">&copy; 2008 — 2016 Expomap.ru</td> <td align="center" style="padding-bottom: 30px; font-family: Arial, sans-serif; font-size: 13px; color: #999999;">&copy; 2008 — 2016 Expomap.ru</td>

@ -4,6 +4,7 @@ from django.conf.urls import patterns
from emencia.django.newsletter.views.mailing_list import UnsubscribeView from emencia.django.newsletter.views.mailing_list import UnsubscribeView
from emencia.django.newsletter.views.mailing_list import UnsubscriptionSuccess from emencia.django.newsletter.views.mailing_list import UnsubscriptionSuccess
from emencia.django.newsletter.views.mailing_list import AuthMailingSettings from emencia.django.newsletter.views.mailing_list import AuthMailingSettings
from emencia.django.newsletter.views.mailing_list import SendtoFriendView
from emencia.django.newsletter.forms import MailingListSubscriptionForm from emencia.django.newsletter.forms import MailingListSubscriptionForm
from emencia.django.newsletter.forms import AllMailingListSubscriptionForm from emencia.django.newsletter.forms import AllMailingListSubscriptionForm
@ -39,4 +40,8 @@ urlpatterns = patterns('emencia.django.newsletter.views.mailing_list',
AuthMailingSettings.as_view(), AuthMailingSettings.as_view(),
name='newsletter-authmailingsettings'), name='newsletter-authmailingsettings'),
url(r'^tofriend/(?P<slug>[-\w]+)/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
SendtoFriendView.as_view(),
name='newsletter-sendtofriend'),
) )

@ -1,17 +1,21 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Views for emencia.django.newsletter Mailing List""" """Views for emencia.django.newsletter Mailing List"""
from datetime import datetime, timedelta
from django.template import RequestContext from django.template import RequestContext
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.contrib import messages from django.contrib import messages
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.views.generic import DetailView, TemplateView, RedirectView from django.views.generic import DetailView, TemplateView, RedirectView, FormView
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
from django.contrib import messages
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.forms.formsets import formset_factory
from emencia.django.newsletter.mailer import Mailer
from emencia.django.newsletter.utils.tokens import untokenize from emencia.django.newsletter.utils.tokens import untokenize
from emencia.django.newsletter.models import Newsletter, MailingList, ContactMailingStatus, Contact, ContactSettings from emencia.django.newsletter.models import Newsletter, MailingList, ContactMailingStatus, Contact, ContactSettings
from emencia.django.newsletter.forms import SubscribeSettingsForm from emencia.django.newsletter.forms import SubscribeSettingsForm, SendtoFriendForm
def view_mailinglist_unsubscribe(request, slug, uidb36, token): def view_mailinglist_unsubscribe(request, slug, uidb36, token):
@ -150,3 +154,54 @@ class AuthMailingSettings(RedirectView):
self.contact = untokenize(self.kwargs.get('uidb36'), self.kwargs.get('token')) self.contact = untokenize(self.kwargs.get('uidb36'), self.kwargs.get('token'))
request.session['ml_contact_pk'] = self.contact.pk request.session['ml_contact_pk'] = self.contact.pk
return super(AuthMailingSettings, self).get(request, *args, **kwargs) return super(AuthMailingSettings, self).get(request, *args, **kwargs)
class SendtoFriendView(TemplateView):
# form_class = SendtoFriendForm
formset_class = formset_factory(SendtoFriendForm, extra=5, max_num=5)
template_name = 'client/newsletters/sendmail_to_friend.html'
message_template_name = 'client/newsletters/sendmail_to_friend_message.html'
def dispatch(self, request, *args, **kwargs):
self.message_template = False
self.formset = self.formset_class(request.POST or None)
self.newsletter = get_object_or_404(Newsletter, slug=kwargs.get('slug'))
self.contact = untokenize(self.kwargs.get('uidb36'), self.kwargs.get('token'))
last_send = request.session.get('last_friend_send')
if last_send and datetime.now() - last_send < timedelta(hours=1):
self.add_msg(_(u'В целях направленных на борьбу со спамом, пересылать письма можно не чаще чем раз в час.'))
return super(SendtoFriendView, self).dispatch(request, *args, **kwargs)
def add_msg(self, msg):
self.message_template = True
messages.add_message(self.request, messages.INFO, msg)
def post(self, request, *args, **kwargs):
if self.formset.is_valid():
contacts = []
for form in self.formset:
contacts.append({
'name': form.cleaned_data.get('first_name'),
'email': form.cleaned_data.get('email')
})
self.send_mail(contacts)
request.session['last_friend_send'] = datetime.now()
self.add_msg(_(u'Мы успешно переслали письмо вашим друзьям. Спасибо что Вы с нами!'))
return self.get(request, *args, **kwargs)
def get_template_names(self):
if self.message_template:
return [self.message_template_name]
return super(SendtoFriendView, self).get_template_names()
def send_mail(self, contacts):
mailer = Mailer(self.newsletter)
mailer.settings_links = False
mailer.send_to_friends(self.contact, contacts)
def get_context_data(self, **kwargs):
ctx = super(SendtoFriendView, self).get_context_data(**kwargs)
ctx['formset'] = self.formset
ctx['newsletter'] = self.newsletter
ctx['contact'] = self.contact
return ctx

@ -21,7 +21,7 @@
<a href="/" class="back_to_site">expomap.ru <span>&#8250;</span></a> <a href="/" class="back_to_site">expomap.ru <span>&#8250;</span></a>
</div> </div>
<h1>{% trans 'Настройте рассылку от Expomap' %}</h1> <h1>{% trans 'Настройте рассылку от Expomap' %}</h1>
<p>{% trans 'для' %} <span>{{ request.user }}</span></p> <p>{% trans 'для' %} <span>{{ contact.email }}</span></p>
</div> </div>
</header> </header>

@ -31,10 +31,8 @@
{# {% include 'client/includes/article/article_logo.html' with obj=object %} #} {# {% include 'client/includes/article/article_logo.html' with obj=object %} #}
<h1><a href="#" class="preview_toggle" data-short="{% trans 'Краткое содержание' %}" data-full="{% trans 'Полное содержание' %}">{% trans 'Краткое содержание' %}</a>{{ object.main_title }}</h1> <h1><a href="#" class="preview_toggle" data-short="{% trans 'Краткое содержание' %}" data-full="{% trans 'Полное содержание' %}">{% trans 'Краткое содержание' %}</a>{{ object.main_title }}</h1>
<ul class="article_info"> <ul class="article_info">
{# TODO: подставить переменную #}
<li><i class="fa fa-user"></i> {{ object.author_s.fullname }}</li> <li><i class="fa fa-user"></i> {{ object.author_s.fullname }}</li>
<li><i class="fa fa-calendar"></i> {{ object.publish_date|date:"d E Y" }}</li> <li><i class="fa fa-calendar"></i> {{ object.publish_date|date:"d E Y" }}</li>
{# TODO: подставить переменную #}
<li>Раздел: <a href="/blogs/theme/{{ object.theme.all.0.url }}"> {{ object.theme.all.0 }} </a></li> <li>Раздел: <a href="/blogs/theme/{{ object.theme.all.0.url }}"> {{ object.theme.all.0 }} </a></li>
</ul> </ul>
{# <strong><span>{{ object.publish_date|date:"d E Y" }}</span></strong> #} {# <strong><span>{{ object.publish_date|date:"d E Y" }}</span></strong> #}

@ -0,0 +1,65 @@
{% load i18n %}
{% load static %}
{% load widget_tweaks %}
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{% trans 'Перешлите письмо другу' %}</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.4/jquery.fancybox.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.5/jquery.mCustomScrollbar.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<link rel="stylesheet" href="{% static 'mailing_settings/css/main.css' %}">
{# <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">#}
{# <script scr="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>#}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js" defer></script>
</head>
<body>
<header class="page_header">
<div class="container">
<div class="logo_block">
<a href="/"><img src="{% static 'mailing_settings/images/logo.png' %}" alt="Expomap"></a>
<a href="/" class="back_to_site">expomap.ru <span>&#8250;</span></a>
</div>
<h1>{% trans 'Перешлите письмо другу' %}</h1>
<p>{% trans 'от' %} <span>{{ contact.email }}</span></p>
</div>
</header>
{% block content %}
<form method="post" action="." style="padding: 0 50px">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<br>
{{ form.as_p }}
<br>
<hr>
{# {% for field in form %}#}
{# <div class="form-group">#}
{# <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ field.label }}</label>#}
{# <div class="col-sm-10">#}
{# {{ field|add_class:"form-control" }}#}
{# <span class="help-inline">{{ field.errors }}</span>#}
{# </div>#}
{# </div>#}
{# {% endfor %}#}
{% endfor %}
<div class="button_block">
<div class="container">
<button type="submit">{% trans "Отправить" %}</button>
</div>
</div>
</form>
{% endblock %}
<footer class="page_footer">&copy; Expomap {% now "Y" %}</footer>
</body>
</html>

@ -0,0 +1,19 @@
{% extends 'client/newsletters/sendmail_to_friend.html' %}
{% load i18n %}
{% load static %}
{% load widget_tweaks %}
{% block content %}
<div style="padding: 10px 50px;text-align: center;vertical-align: middle;min-height: 200px">
{% if messages %}
{# <ul class="messages">#}
{% for message in messages %}
<span{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</span>
{% endfor %}
{# </ul>#}
{% endif %}
</div>
{% endblock %}
Loading…
Cancel
Save