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.
 
 
 
 
 
 

214 lines
9.9 KiB

# -*- coding: utf-8 -*-
import xlrd
from collections import namedtuple
import re
from city.models import City
from ckeditor.widgets import CKEditorWidget
from country.models import Area, Country
from django import forms
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from emencia.django.newsletter.models import (
Attachment,
Contact,
ContactSettings,
MailingList,
Newsletter
)
from theme.models import Theme
class ContactSettingsForm(forms.ModelForm):
city = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput() ,required=False)
periodic = forms.ChoiceField(choices=ContactSettings.PERIODIC_CHOICES,
label=_(u'Периодичность отправки'))
first_name = forms.CharField(label=_('first name'))
subscriber = forms.BooleanField(label=_('subscriber'), required=False)
valid = forms.BooleanField(label=_('valid email'), required=False)
tester = forms.BooleanField(label=_('contact tester'), required=False)
country = forms.MultipleChoiceField(choices=[(c.id,c.name) for c in list(set(Country.objects.language().all()))], required=False)
area = forms.MultipleChoiceField(choices=[(a.id, a.name) for a in list(set(Area.objects.language().all()))], required=False)
def __init__(self, *args, **kwargs):
super(ContactSettingsForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance:
lang = translation.get_language()
self.fields['city'].widget.attrs['data-init-text'] = [(item.id, item.name) for item in list(instance.city.filter(translations__language_code=lang))]
class Meta:
model = ContactSettings
fields = ('periodic', 'exponent_practicum', 'organiser_practicum', 'theme', 'area', 'country', 'city', )
def save(self, commit=True):
contactsettings = super(ContactSettingsForm, self).save(commit=False)
old_save_m2m = self.save_m2m
if commit:
contactsettings.save()
contact = contactsettings.contact
contact.first_name = self.cleaned_data['first_name']
contact.subscriber = self.cleaned_data['subscriber']
contact.valid = self.cleaned_data['valid']
contact.tester = self.cleaned_data['tester']
contact.save()
return contactsettings
def clean_periodic(self):
return int(self.cleaned_data['periodic'])
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()
class MailingListForm(forms.ModelForm):
theme_choices = [(item.id, item.name) for item in Theme.objects.language().all()]
excel_file = forms.FileField(label=_(u'Импортировать подписчиков'), required=False)
add_from_themes = forms.MultipleChoiceField(label=_(u'Добавить подписчиков по тематикам'), required=False,
choices=theme_choices)
theme_for_filter = forms.MultipleChoiceField(label=_(u'Тематики'), required=False,
choices=theme_choices)
class Meta:
model = MailingList
fields = ('name', 'description', 'theme_for_filter')
def save(self, commit=True):
ml = super(MailingListForm, self).save(commit=True)
# data = self.cleaned_data
# f = data['excel_file']
# if f:
# # contact_list = list(Contact.objects.all())
# book = xlrd.open_workbook(file_contents=f.read())
# sheet = book.sheet_by_index(0)
# excel_emails = {sheet.row_values(row_number)[0]: sheet.row_values(row_number)[1] for row_number in range(1, sheet.nrows)}
# valid_contacts = []
# # for contact in contact_list:
# # if contact.email in excel_emails:
# # valid_contacts.append(contact)
# for email, first_name in excel_emails.iteritems():
# valid_contacts.append(Contact.objects.create(
# email=email, first_name=first_name,
# valid=True, activated=True))
# ml.subscribers = valid_contacts
# ml.save()
return ml
def get_contact_list(self, qs):
headers_map = namedtuple("Headers", ['email', 'first_name', 'exponent_practicum', 'organiser_practicum', 'geo', 'country', 'city', 'theme', 'time1', 'time2'])
excel_file = self.cleaned_data['excel_file']
contact_items = dict(qs.values_list('email', 'pk'))
ids = set(contact_items.values())
if excel_file:
book = xlrd.open_workbook(file_contents=excel_file.read())
sheet = book.sheet_by_index(0)
countries = {}
cities = {}
themes = {}
field_models = {
'country': {'model': Country, 'cached': {}},
'city': {'model': City, 'cached': {}},
'theme': {'model': Theme, 'cached': {}}
}
for i in range(1, sheet.nrows):
item = headers_map(*sheet.row(i))
# email = sheet.row_values(i)[0]
# first_name = sheet.row_values(i)[1]
# exponent_practicum = sheet.row_values(i)[2]
# organiser_practicum = sheet.row_values(i)[3]
# if email not in contact_items:
c, created = Contact.objects.get_or_create(email=item.email.value.strip())
c.first_name = item.first_name.value.strip() or c.first_name
c.activated = True
c.save()
ids.add(c.pk)
contactsettings, _created = ContactSettings.objects.get_or_create(contact_id=c.pk)
contactsettings.exponent_practicum = item.exponent_practicum.value
contactsettings.organiser_practicum = item.organiser_practicum.value
for field, data in field_models.iteritems():
# model = data['model']
# cached = data['cached']
cell = getattr(item, field)
values = cell.value.split(';')
names_to_fetch = []
pks = set()
for val in values:
val = val.strip()
_pk = data['cached'].get(val, None)
if _pk is None:
names_to_fetch.append(val)
else:
pks.add(_pk)
if names_to_fetch:
_pks = dict(data['model'].objects.language().filter(name__in=values).values_list('name', 'pk'))
data['cached'].update(_pks)
pks.update(_pks.values())
if pks:
_field = getattr(contactsettings, field)
_field.add(*pks)
contactsettings.save()
# p = re.compile(r'([^\(pk=\d+\)]*\(pk=(?P<pk>\d+)\))')
# p.finditer():
# ...
if self.cleaned_data['add_from_themes']:
ct_from_themes = Contact.objects\
.filter(
contactsettings__theme__in=self.cleaned_data['add_from_themes']
).distinct().values_list('pk', flat=True)
ids.update(ct_from_themes)
return ids
class NewsletterForm(forms.ModelForm):
test_contacts = forms.ModelMultipleChoiceField(label=_(u'Тестовые контакты'), required=False,
queryset=Contact.objects.filter(tester=True))
content = forms.CharField(label=_('content'), widget=CKEditorWidget(config_name='newsletters'))
content2 = forms.CharField(label=_('Content B'), widget=CKEditorWidget(config_name='newsletters'), required=False)
class Meta:
model = Newsletter
fields = ('preheader', 'title', 'content', 'ab_testing', 'ab_first_stage', 'preheader2', 'title2', 'content2', 'mailing_list', 'theme_for_filter', 'test_contacts', 'header_sender',
'header_reply', 'status', 'sending_date', 'slug')
widgets = {
'ab_first_stage': forms.widgets.TextInput(attrs={'type':'number', 'min': 5, 'max': 100}),
}
def __init__(self, *args, **kwargs):
super(NewsletterForm, self).__init__(*args, **kwargs)
# добавляем поле для возможности указания варианта финальной рассылки (А-В тестирование)
if self.instance.pk and self.instance.ab_testing and self.instance.ab_final_stage:
self._meta.fields = (
'preheader', 'title', 'content', 'ab_testing',
'ab_first_stage', 'preheader2', 'title2', 'content2', 'mailing_list',
'theme_for_filter', 'test_contacts', 'header_sender',
'header_reply', 'ab_final_choice', 'status', 'sending_date',
'slug')
field = forms.ChoiceField(
label=_(u'Вариант в финальную рассылку'),
choices=Newsletter.AB_FINAL_CHOICE,
initial=self.instance.ab_final_choice or Newsletter.A)
self.fields.insert(self.fields.keyOrder.index('status'), 'ab_final_choice', field)
if self.instance and self.instance.mailing_list_id:
self.fields['theme_for_filter'].queryset = self.instance.mailing_list.theme_for_filter.all()
self.initial['ab_first_stage'] = self.initial.get('ab_first_stage') or 10
class AttachmentForm(forms.ModelForm):
class Meta:
model = Attachment
fields = ('title', 'file_attachment')