You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

385 lines
14 KiB

# -*- coding: utf-8 -*-
import datetime
from django.views.generic import CreateView, ListView, UpdateView, DeleteView, FormView, DetailView, RedirectView, TemplateView
from django.conf import settings
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from django.forms.formsets import formset_factory
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import get_object_or_404
from django.core.urlresolvers import reverse_lazy
from django.forms.models import modelformset_factory
from HTMLParser import HTMLParseError
from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter, Attachment, ContactMailingStatus
from emencia.django.newsletter.admin_forms import ContactSettingsForm, MailingListForm, NewsletterForm, AttachmentForm
from emencia.django.newsletter.mailer import Mailer
from emencia.django.newsletter.forms import PopupCountFilter, MailingStatusFilter
from ..forms import ContactFilterForm, ContactImportForm
from ..utils.excel import ExcelResponse
from functions.admin_views import paginate_results
from ..models import PopupCount
from theme.models import Theme
class ContactList(FormView):
paginate_by = settings.ADMIN_PAGINATION
model = Contact
template_name = 'admin/newsletters/contact_list.html'
form_class = ContactFilterForm
queryset = Contact.objects.all()
def get_form(self, form_class):
if self.request.GET:
return form_class(self.request.GET)
else:
return form_class(**self.get_form_kwargs())
def get(self, request, *args, **kwargs):
if request.GET:
form_class = self.get_form_class()
form = self.get_form(form_class)
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
else:
return super(ContactList, self).get(request, *args, **kwargs)
def form_valid(self, form):
qs, _ = form.filter()
result = paginate_results(qs, page=self.request.GET.get('page'))
context = self.get_context_data(form=form)
context.update({'object_list': result})
return self.render_to_response(context)
def get_context_data(self, **kwargs):
context = super(ContactList, self).get_context_data(**kwargs)
qs = self.model.objects.all()
result = paginate_results(qs, page=self.request.GET.get('page'))
context['object_list'] = result
return context
class ContactQueryDelete(RedirectView):
url = reverse_lazy('newsletters_contact_list')
filter_form = ContactFilterForm
def get(self, request, *args, **kwargs):
form = self.filter_form(request.GET)
if form.is_valid():
qs,_ = form.filter()
qs.delete()
return HttpResponseRedirect(self.url)
else:
return HttpResponse('400')
class DeleteContact(DeleteView):
model = Contact
success_url = reverse_lazy('newsletters_contact_list')
template_name = 'admin/newsletters/confirm_delete.html'
class UpdateContact(UpdateView):
model = ContactSettings
form_class = ContactSettingsForm
template_name = 'admin/newsletters/contact.html'
success_url = '/admin/newsletters/contact/all/'
def form_valid(self, form):
self.object = form.save()
self.object.theme = form.cleaned_data['theme']
self.object.country = form.cleaned_data['country']
self.object.area = form.cleaned_data['area']
self.object.city = form.cleaned_data['city']
self.object.save()
return HttpResponseRedirect(self.get_success_url())
def get_initial(self):
lang = translation.get_language()
obj = self.object.contact
data = self.initial.copy()
city = ','.join(['%s:%s'%(item.id, item.name) for item in self.object.city.filter(translations__language_code=lang)])
data.update({'first_name': obj.first_name, 'subscriber': obj.subscriber,
'valid': obj.valid, 'tester': obj.tester, 'city':city})
return data
class ExportContacts(FormView):
form_class = ContactFilterForm
def get(self, request=None, *args, **kwargs):
form = self.form_class(request.GET)
if form.is_valid():
qs, title = form.filter()
if qs.count():
columns = ('email', 'first_name')
return ExcelResponse(qs, title, columns,'contacts')
return HttpResponseRedirect(self.request.META['HTTP_REFERER'])
class ImportContacts(FormView):
form_class = ContactImportForm
success_url = reverse_lazy("newsletters_contact_list")
template_name = 'admin/import templates/import_contacts.html'
def form_valid(self, form):
form.save()
return HttpResponseRedirect(self.get_success_url())
class MailingListView(ListView):
paginate_by = settings.ADMIN_PAGINATION
model = MailingList
template_name = 'admin/newsletters/mailing_list.html'
class DeleteMailingList(DeleteView):
model = MailingList
template_name = 'admin/newsletters/confirm_delete.html'
success_url = reverse_lazy('newsletters_mailinglist')
class UpdateMailingList(UpdateView):
model = MailingList
form_class = MailingListForm
template_name = 'admin/newsletters/mailing_list_object.html'
success_url = '/admin/newsletters/mailinglist/all/'
def get_success_url(self):
return self.success_url
def form_valid(self, form):
obj = form.save()
themes = form.cleaned_data.get('theme_for_filter')
if themes:
obj.subscribers.add(*list(Contact.objects.filter(contactsettings__theme__in=themes).distinct()))
return HttpResponseRedirect(self.success_url)
class CreateMailingList(CreateView):
model = MailingList
form_class = MailingListForm
template_name = 'admin/newsletters/mailing_list_object.html'
success_url = '/admin/newsletters/mailinglist/all/'
def form_valid(self, form):
obj = form.save()
filter_form = ContactFilterForm(self.request.GET)
if filter_form.is_valid():
contacts, _ = filter_form.filter()
obj.subscribers = contacts
obj.save()
return HttpResponseRedirect(self.success_url)
class NewsletterCreate(CreateView):
model = Newsletter
form_class = NewsletterForm
template_name = 'admin/newsletters/newsletter_object.html'
success_url = '/admin/newsletters/newsletters/all/'
def get_formset(self):
AttachmentFormSet = formset_factory(AttachmentForm)
if self.request.POST:
return AttachmentFormSet(self.request.POST, self.request.FILES)
else:
return AttachmentFormSet()
def get_context_data(self, **kwargs):
context = super(NewsletterCreate, self).get_context_data(**kwargs)
context['attachment_formset'] = self.get_formset()
return context
def form_valid(self, form):
self.object = form.save()
self.object.test_contacts = form.cleaned_data['test_contacts']
formset = self.get_formset()
if formset.is_valid():
for item in formset.forms:
if item.is_valid() and item.has_changed():
instance = item.save(commit=False)
instance.newsletter = self.object
instance.save()
return HttpResponseRedirect(self.success_url)
class NewsletterUpdate(UpdateView):
model = Newsletter
form_class = NewsletterForm
template_name = 'admin/newsletters/newsletter_object.html'
success_url = '/admin/newsletters/newsletters/all/'
def get_formset(self):
if self.request.POST:
AttachmentFormSet = modelformset_factory(Attachment, form=AttachmentForm, exclude=('newsletter',))
else:
AttachmentFormSet = modelformset_factory(Attachment, form=AttachmentForm, exclude=('newsletter',))
if self.request.POST:
return AttachmentFormSet(self.request.POST, self.request.FILES, queryset=self.object.attachment_set.all())
else:
return AttachmentFormSet(queryset=self.object.attachment_set.all())
def get_context_data(self, **kwargs):
context = super(NewsletterUpdate, self).get_context_data(**kwargs)
context['attachment_formset'] = self.get_formset()
return context
def form_valid(self, form):
self.object = form.save()
self.object.test_contacts = form.cleaned_data['test_contacts']
formset = self.get_formset()
if formset.is_valid():
for item in formset.forms:
if item.is_valid() and item.has_changed():
instance = item.save(commit=False)
instance.newsletter = self.object
instance.save()
return HttpResponseRedirect(self.success_url)
class NewsletterListView(ListView):
paginate_by = settings.ADMIN_PAGINATION
model = Newsletter
template_name = 'admin/newsletters/newsletter_list.html'
success_url = '/admin/newsletters/newsletters/all/'
def send_test_newsletter(request, pk):
newsletter = get_object_or_404(Newsletter, pk=pk)
if newsletter.test_contacts.count():
mailer = Mailer(newsletter, test=True)
try:
mailer.run()
except HTMLParseError:
return HttpResponse(_('Unable send newsletter, due to errors within HTML.'))
else:
return HttpResponse(_(u'Нет тестовых контактов'))
redirect = request.META.get('HTTP_REFERER', '/admin/newsletter/newsletter/all/')
return HttpResponseRedirect(redirect)
class NewsletterStatistics(DetailView):
model = Newsletter
template_name = 'admin/newsletters/newsletter_stat.html'
def get_context_data(self, **kwargs):
context = super(NewsletterStatistics, self).get_context_data(**kwargs)
sent = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.SENT).count()
errors = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.ERROR).count()
opened = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.OPENED).\
values_list('contact', flat=True).distinct().count()
unsubscribed = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.UNSUBSCRIPTION).\
values_list('contact', flat=True).distinct().count()
no_data = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.ANNOUNCE_NO_DATA).count()
links = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.LINK_OPENED).count()
links_unique = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.LINK_OPENED).\
values_list('contact', flat=True).distinct().count()
CMS = ContactMailingStatus
opened_percent = 0 if opened or sent == 0 else (float(opened)/sent)*100
unsub_percent = 0 if unsubscribed or sent == 0 else (float(unsubscribed)/sent)*100
stat = {
'sent': {'data': sent, 'filter': ""},
'errors': {'data': errors, 'filter': CMS.ERROR},
'opened': {'data': opened, 'filter': CMS.OPENED, 'percent': opened_percent},
'unsub': {'data': unsubscribed, 'filter': CMS.UNSUBSCRIPTION, 'percent': unsub_percent},
'no_data': {'data': no_data, 'filter': CMS.ANNOUNCE_NO_DATA},
'links': {'data': links, 'filter': CMS.LINK_OPENED},
'links_unique': {'data': links_unique, 'filter': CMS.LINK_OPENED}}
context.update({'stat': stat})
return context
class NewsletterCloneView(RedirectView):
url = reverse_lazy("newsletters_newsletters_list")
def get(self, request, *args, **kwargs):
newsletter = get_object_or_404(Newsletter, id=kwargs['pk'])
newsletter.clone()
return HttpResponseRedirect(self.url)
def post(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
class NewsletterHistory(ListView):
model = ContactMailingStatus
template_name = 'admin/newsletters/newsletter_history.html'
paginate_by = 50
def get_queryset(self):
self.newsletter = get_object_or_404(Newsletter, pk=self.kwargs['pk'])
if self.request.GET:
form = MailingStatusFilter(self.request.GET)
if form.is_valid():
qs = form.filter(self.newsletter)
else:
qs = ContactMailingStatus.objects.select_related().filter(newsletter=self.newsletter)
else:
qs = ContactMailingStatus.objects.select_related().filter(newsletter=self.newsletter)
return qs
def get_context_data(self, **kwargs):
context = super(NewsletterHistory, self).get_context_data(**kwargs)
context['newsletter'] = self.newsletter
context['choices'] = ContactMailingStatus.STATUS_CHOICES
form = MailingStatusFilter(self.request.GET)
context['filter_form'] = form
return context
class NewsletterDelete(DeleteView):
model = Newsletter
template_name = 'admin/newsletters/confirm_delete.html'
success_url = reverse_lazy('newsletters_newsletters_list')
def count_popups(request):
if not request.is_ajax():
return HttpResponse("request is not ajax")
else:
themes = request.GET.getlist('theme')
if themes:
for theme_id in themes:
obj,_ = PopupCount.objects.get_or_create(theme=Theme.objects.get(id=theme_id), date=datetime.date.today())
obj.cnt += 1
obj.save()
else:
obj,_ = PopupCount.objects.get_or_create(theme=None, date=datetime.date.today())
obj.cnt+=1
obj.save()
return HttpResponse(obj.cnt, content_type='application/json')
class PopupStatisticsView(FormView):
form_class = PopupCountFilter
template_name = 'admin/newsletters/popup_count.html'
def get(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = form_class(request.GET)
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
data = form.filter()
data['form'] = form
return self.render_to_response(data)