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.
 
 
 
 
 
 

418 lines
17 KiB

# -*- coding: utf-8 -*-
"""Forms for emencia.django.newsletter"""
from datetime import date, datetime, timedelta
import xlrd
from city.models import City
from country.models import Area, Country
from django import forms
from django.core.exceptions import ValidationError
from django.db.models import Sum
from django.http import Http404
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from emencia.django.newsletter.models import (
Contact,
ContactMailingStatus,
ContactSettings,
MailingList,
Newsletter,
PopupCount
)
from functions.form_check import translit_with_separator as tr
from functions.search_forms import get_by_lang
from haystack.query import SearchQuerySet
from theme.models import Theme
class MailingListSubscriptionForm(forms.ModelForm):
"""Form for subscribing to a mailing list"""
# Notes : This form will not check the uniquess of
# the 'email' field, by defining it explictly and setting6
# it the Meta.exclude list, for allowing registration
# to a mailing list even if the contact already exists.
# Then the contact is always added to the subscribers field
# of the mailing list because it will be cleaned with no
# double.
email = forms.EmailField(label=_('Email'), max_length=75)
def save(self, mailing_list):
data = self.cleaned_data
contact, created = Contact.objects.get_or_create(
email=data['email'],
defaults={'first_name': data['first_name'],
'last_name': data['last_name']})
mailing_list.subscribers.add(contact)
mailing_list.unsubscribers.remove(contact)
class Meta:
model = Contact
fields = ('first_name', 'last_name')
exclude = ('email',)
class AllMailingListSubscriptionForm(MailingListSubscriptionForm):
"""Form for subscribing to all mailing list"""
mailing_lists = forms.ModelMultipleChoiceField(
queryset=MailingList.objects.all(),
initial=[obj.id for obj in MailingList.objects.all()],
label=_('Mailing lists'),
widget=forms.CheckboxSelectMultiple())
def save(self, mailing_list):
data = self.cleaned_data
contact, created = Contact.objects.get_or_create(
email=data['email'],
defaults={'first_name': data['first_name'],
'last_name': data['last_name']})
for mailing_list in data['mailing_lists']:
mailing_list.subscribers.add(contact)
mailing_list.unsubscribers.remove(contact)
class ContactForm(forms.ModelForm):
email = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': _(u'Ваш e-mail')}))
first_name = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': _(u'Ваше имя')}))
class Meta:
model = Contact
fields = ('email', 'first_name', )
def clean_first_name(self):
name = self.cleaned_data['first_name']
return name.capitalize()
class ContactSettingsForm(forms.ModelForm):
theme = forms.MultipleChoiceField(choices=[(str(item.id), item.name) for item in list(Theme.objects.language().all())],
widget=forms.CheckboxSelectMultiple(attrs={'class': 'pr-checkbox'}), required=False)
class Meta:
model = ContactSettings
fields = ('exponent_practicum', 'organiser_practicum', 'theme')
def clean_theme(self):
theme = self.cleaned_data.get('theme')
if theme:
return Theme.objects.filter(id__in=theme)
else:
return Theme.objects.none()
class ContactFilterForm(forms.Form):
email = forms.EmailField(
label="Email",
max_length=255,
required=False,
widget=forms.TextInput(attrs={'class':'input-xlarge search-query','placeholder': 'Email'})
)
theme = forms.MultipleChoiceField(
label="Тематика",
choices=[(t.id, t.name) for t in Theme.objects.language()],
required=False
)
country = forms.MultipleChoiceField(
label="Страна",
choices=[(c.id, c.name) for c in list(set(Country.objects.language('ru').all()))],
required=False
)
city = forms.MultipleChoiceField(
label="Город",
choices=[(c.id, c.name) for c in list(set(City.objects.language('ru').filter(contactsettings__isnull=False)))],
required=False,
widget= forms.SelectMultiple(attrs={'id':'cities'})
)
area = forms.MultipleChoiceField(
label="Area", choices=[(c.id, c.name) for c in list(set(Area.objects.language()))],
required=False
)
mailinglist = forms.ModelChoiceField(
queryset=MailingList.objects.all(),
label="Список рассылки",
required=False
)
created_from = forms.CharField(max_length=255, label=_(u"Создан с"), required=False)
created_to = forms.CharField(max_length=255, label=_(u"Создан по"), required=False)
not_active = forms.BooleanField(label=_(u"Не подтверждена подписка"), required=False)
not_valid = forms.BooleanField(label=_(u"Неалидный Email"), required=False)
not_subscriber = forms.BooleanField(label=_(u"Отписался"), required=False)
def filter(self):
title = u'contact list '
qs = Contact.objects.all().select_related('contactsettings')
if self.cleaned_data.get('mailinglist'):
qs = qs.filter(mailinglist_subscriber__id=self.cleaned_data['mailinglist'].pk)
title += u" mailinglist: %s" % self.cleaned_data['mailinglist'].name
if self.cleaned_data.get('country'):
qs = qs.filter(contactsettings__country__id__in=self.cleaned_data['country'])
title += u" countries: %s" % ','.join([obj.url for obj in Country.objects.language().filter(id__in=self.cleaned_data['country'])])
if self.cleaned_data.get('email'):
qs = qs.filter(email__icontains=self.cleaned_data['email'])
if self.cleaned_data.get('theme'):
qs = qs.filter(contactsettings__theme__id__in=self.cleaned_data['theme'])
title += u" themes: %s" % ','.join([obj.url for obj in Theme.objects.language().filter(id__in=self.cleaned_data['theme'])])
if self.cleaned_data.get('city'):
qs = qs.filter(contactsettings__city__id__in=self.cleaned_data['city'])
title += u" cities: %s" % ','.join([obj.url for obj in Country.objects.language().filter(id__in=self.cleaned_data['country'])])
if self.cleaned_data.get('area'):
qs = qs.filter(contactsettings__area__id__in=self.cleaned_data['area'])
title += u" geo area: %s" % ','.join([tr(obj.name) for obj in Area.objects.language('en').filter(id__in=self.cleaned_data['area'])])
if self.cleaned_data.get('not_active'):
title = u' not active ' + title
qs = qs.filter(activated=False)
else:
qs = qs.filter(activated=True)
if self.cleaned_data.get('not_valid'):
title = u'not valid e-mail ' + title
qs = qs.filter(valid=False)
else:
qs = qs.filter(valid=True)
if self.cleaned_data.get("created_from"):
qs = qs.filter(creation_date__gte=datetime.strptime(self.cleaned_data['created_from'], "%d.%m.%Y"))
if self.cleaned_data.get("created_to"):
qs = qs.filter(creation_date__lt=datetime.strptime(self.cleaned_data['created_to'], "%d.%m.%Y"))
if self.cleaned_data.get('not_subscriber'):
qs = qs.filter(subscriber=False)
else:
qs = qs.filter(subscriber=True)
qs = qs.distinct()
return qs, title.replace('"', '\"').replace('\n', '')
COUNTRY_CHOICES = [(c.id, c.name) for c in list(set(Country.objects.language('ru').all()))]
COUNTRY_CHOICES.insert(0, ('', _(u'Страна')))
class ContactImportForm(forms.Form):
excel_file = forms.FileField(label=_(u'Выберите файл'))
activated = forms.BooleanField(label=_(u"Активные"), required=False)
is_tester = forms.BooleanField(label=_(u"Тестовые"), required=False)
country = forms.ChoiceField(label=_(u"Страна"), choices=COUNTRY_CHOICES, required=False)
def save(self):
data = self.cleaned_data
country_id = self.cleaned_data.get('country')
country = None
if country_id:
country = Country.objects.get(id=country_id)
activated = data['activated']
is_tester = data['is_tester']
f = data['excel_file']
book = xlrd.open_workbook(file_contents=f.read())
sheet = book.sheet_by_index(0)
row_list = [sheet.row_values(row_number) for row_number in range(1, sheet.nrows)]
for row in row_list:
c = Contact(email = row[0], first_name=row[1], last_name="", tester=is_tester,
activated=activated, valid=True, subscriber=True)
try:
c.save()
except:
continue
cs = ContactSettings()
cs.contact = c
cs.save()
if country:
cs.country.add(country)
cs.save()
class AbstractSubscribeForm(forms.ModelForm):
email = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': 'Email'}))
class Meta:
model = ContactSettings
fields = ('periodic', 'exponent_practicum', 'organiser_practicum', 'theme', 'country', 'city')
def clean_email(self):
email = self.cleaned_data['email']
try:
Contact.objects.get(email=email)
except Contact.DoesNotExist:
return email
raise ValidationError(_(u'Такой email уже есть в базе даных'))
def clean_city(self):
cities = self.cleaned_data.get('city')
if cities:
res = []
for id in cities.split(','):
try:
res.append(int(id))
except ValueError:
continue
return City.objects.filter(id__in=res)
else:
return City.objects.none()
def clean_country(self):
countries = self.cleaned_data['country']
return Country.objects.filter(id__in=countries)
def clean_theme(self):
themes = self.cleaned_data['theme']
return Theme.objects.filter(id__in=themes)
class SubscribeAssideForm(AbstractSubscribeForm):
city = forms.CharField(
widget=forms.HiddenInput(attrs={'id': 'id_subscription_city', 'placeholder': _(u'Город')}),
required=False)
periodic = forms.ChoiceField(
choices=ContactSettings.PERIODIC_CHOICES, required=False,
widget=forms.Select(attrs={'placeholder': _(u'Периодичность'), 'id': 'id_subscription_periodic'}))
def __init__(self, *args, **kwargs):
super(SubscribeAssideForm, self).__init__(*args, **kwargs)
lang = translation.get_language()
self.fields['theme'] = forms.MultipleChoiceField(
choices=[(item.pk, get_by_lang(item, 'name', lang)) for item in SearchQuerySet().models(Theme).all()],
widget=forms.SelectMultiple(attrs={'placeholder': _(u'Тематики'), 'id': 'id_subscription_theme'}))
self.fields['country'] = forms.MultipleChoiceField(
choices=[(item.pk, get_by_lang(item, 'name', lang)) for item in SearchQuerySet().models(Country).all()],
required=False,
widget=forms.SelectMultiple(attrs={'placeholder': _(u'Страны'), 'id': 'id_subscription_country'}))
class SubscribeSettingsForm(AbstractSubscribeForm):
NA_ID = 12
ASIA_ID = 9
EUROPE_ID = 4
city = forms.CharField(
widget=forms.HiddenInput(attrs={'id': 'id_sub_set_city', 'placeholder': _(u'Город')}),
required=False)
get_announce = forms.BooleanField(required=False, label=_(u'Получать анонсы'))
na_expo = forms.BooleanField(required=False, label=_(u'Выставки Северной Америки'))
asia_expo = forms.BooleanField(required=False, label=_(u'Выставки Азии'))
europe_expo = forms.BooleanField(required=False, label=_(u'Выставки Европы'))
def __init__(self, *args, **kwargs):
self.contact = kwargs.pop('contact')
self.activation_send = False
lang = translation.get_language()
self.cities_choices = dict(City.objects.language(lang).all().values_list('pk', 'name'))
super(SubscribeSettingsForm, self).__init__(*args, **kwargs)
self.fields['theme'] = forms.MultipleChoiceField(
choices=[(item.pk, get_by_lang(item, 'name', lang)) for item in SearchQuerySet().models(Theme).all()],
required=False,
widget=forms.SelectMultiple(attrs={'placeholder': _(u'Тематики'), 'id': 'id_sub_set_theme'}))
self.fields['country'] = forms.MultipleChoiceField(
choices=[(item.pk, get_by_lang(item, 'name', lang)) for item in SearchQuerySet().models(Country).all()],
required=False,
widget=forms.SelectMultiple(attrs={'placeholder': _(u'Страны'), 'id': 'id_sub_set_country'}))
if self.instance.pk:
self.initial['get_announce'] = self.instance.exponent_practicum or self.instance.organiser_practicum or self.instance.theme.exists()
self.initial['city'] = ','.join(['%s:%s'%(pk, self.cities_choices.get(pk)) for pk in set(self.instance.city.all().values_list('pk', flat=True))])
def make_pretty_city_val(self):
self.data = self.data.copy()
self.data['city'] = ','.join(['%s:%s'%(pk, self.cities_choices.get(pk)) for pk in set(self.instance.city.all().values_list('pk', flat=True))])
def save_additional_fields(self, settings):
get_announce = self.cleaned_data.get('get_announce')
na_expo = self.cleaned_data.get('na_expo')
asia_expo = self.cleaned_data.get('asia_expo')
europe_expo = self.cleaned_data.get('europe_expo')
if not get_announce:
settings.organiser_practicum = False
settings.exponent_practicum = False
settings.save()
settings.theme.clear()
if na_expo:
settings.area.add(Area.objects.get(id=self.NA_ID))
else:
settings.area.remove(Area.objects.get(id=self.NA_ID))
if asia_expo:
settings.area.add(Area.objects.get(id=self.ASIA_ID))
else:
settings.area.remove(Area.objects.get(id=self.ASIA_ID))
if europe_expo:
settings.area.add(Area.objects.get(id=self.EUROPE_ID))
else:
settings.area.remove(Area.objects.get(id=self.EUROPE_ID))
return settings
def save(self, commit=True):
contactsettings = super(SubscribeSettingsForm, self).save(commit=False)
# Prepare a 'save_m2m' method for the form,
old_save_m2m = self.save_m2m
def save_m2m():
old_save_m2m()
contactsettings.theme.clear()
for theme in self.cleaned_data['theme']:
contactsettings.theme.add(theme)
contactsettings.country.clear()
for country in self.cleaned_data['country']:
contactsettings.country.add(country)
contactsettings.city.clear()
for city in self.cleaned_data['city']:
contactsettings.city.add(city)
self.save_m2m = save_m2m
if commit:
contactsettings.save()
self.save_m2m()
return contactsettings
def clean_email(self):
if not self.contact:
return super(SubscribeSettingsForm, self).clean_email()
email = self.cleaned_data['email']
if self.contact.email != email:
self.contact.activated = False
self.contact.send_activation()
self.save()
self.activation_send = True
return self.cleaned_data['email']
class PopupCountFilter(forms.Form):
fr = forms.DateField(required=False)
to = forms.DateField(required=False)
def filter(self):
fr = self.cleaned_data.get('fr')
to = self.cleaned_data.get('to')
if not fr and not to:
fr = date.today()
qs = PopupCount.objects.filter(date__gte=fr)
contacts = Contact.objects.filter(creation_date__gte=fr)
if to:
contacts = contacts.filter(creation_date__lte=to+timedelta(days=1))
qs = qs.filter(date__lte=to)
subscribed = contacts.count()
activated = contacts.filter(activated=True).count()
popups = qs.aggregate(count=Sum('cnt'))['count']
return {'subscribed': subscribed, 'activated': activated, 'popups': popups}
class MailingStatusFilter(forms.Form):
status = forms.ChoiceField(choices=[('', _(u'Не выбрано'))] + [(item[0], item[1]) for item in ContactMailingStatus.STATUS_CHOICES],
required=False)
email = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': 'Email'}))
ab = forms.TypedChoiceField(required=False, choices=((0, _(u'Любое')), ) + Newsletter.AB_FINAL_CHOICE, coerce=int, empty_value=0)
def filter(self, newsletter):
status = self.cleaned_data.get('status')
email = self.cleaned_data.get('email')
ab = self.cleaned_data.get('ab')
qs = ContactMailingStatus.objects.select_related().filter(newsletter=newsletter)
if status:
qs = qs.filter(status=status)
if email:
qs = qs.filter(contact__email=email)
if ab:
qs = qs.filter(ab=ab)
return qs