diff --git a/emencia/django/newsletter/forms.py b/emencia/django/newsletter/forms.py
index 07bfe564..73c753dc 100644
--- a/emencia/django/newsletter/forms.py
+++ b/emencia/django/newsletter/forms.py
@@ -77,46 +77,12 @@ class CustomModelChoiceIterator(ModelChoiceIterator):
class ML_ModelMultipleChoiceField(forms.ModelMultipleChoiceField):
- ''' use it with field.queryset = Model.objects.none()
- '''
-
def _get_choices(self):
- # If self._choices is set, then somebody must have manually set
- # the property self.choices. In this case, just return self._choices.
if hasattr(self, '_choices'):
return self._choices
-
- # Otherwise, execute the QuerySet in self.queryset to determine the
- # choices dynamically. Return a fresh ModelChoiceIterator that has not been
- # consumed. Note that we're instantiating a new ModelChoiceIterator *each*
- # time _get_choices() is called (and, thus, each time self.choices is
- # accessed) so that we can ensure the QuerySet has not been consumed. This
- # construct might look complicated but it allows for lazy evaluation of
- # the queryset.
return CustomModelChoiceIterator(self)
-
choices = property(_get_choices, forms.ChoiceField._set_choices)
- # def clean(self, value):
- # if self.required and not value:
- # raise ValidationError(self.error_messages['required'])
- # elif not self.required and not value:
- # return self.queryset.none()
- # if not isinstance(value, (list, tuple)):
- # raise ValidationError(self.error_messages['list'])
- # key = self.to_field_name or 'pk'
-
- # qs = self.queryset.filter(**{'%s__in' % key: value})
- # pks = set([force_text(getattr(o, key)) for o in qs])
- # for val in value:
- # if force_text(val) not in pks:
- # raise ValidationError(self.error_messages['invalid_choice'] % val)
- # # Since this overrides the inherited ModelChoiceField.clean
- # # we run custom validators here
- # self.run_validators(value)
- # return qs
-
-
class MailingSettingsForm(forms.ModelForm):
r_cities = ML_ModelMultipleChoiceField(
label=_(u'Города России'), required=False,
@@ -138,7 +104,6 @@ class MailingSettingsForm(forms.ModelForm):
model = Contact
fields = [
'moscow', 'russia', 'r_cities', 'foreign',
- # 'tags', 'themes',
'periodic', 'periodic_day', 'content_news', 'content_overview',
'content_articles',
]
diff --git a/emencia/django/newsletter/models.py b/emencia/django/newsletter/models.py
index 3cf2d8bc..66678173 100644
--- a/emencia/django/newsletter/models.py
+++ b/emencia/django/newsletter/models.py
@@ -7,7 +7,7 @@ from datetime import timedelta
from dateutil import relativedelta
from email.MIMEImage import MIMEImage
from random import choice
-from itertools import chain
+from itertools import chain, groupby
import copy
import operator
@@ -234,8 +234,8 @@ class Contact(models.Model):
paid_recommend = NewsletterRecommend.objects.filter(
fr__gte=date,
to__lte=date)
- recommended = RelatedSearchQuerySet().models(Exposition, Conference)\
- .filter(expohit=True)
+ recommended = SearchQuerySet().models(Exposition, Conference)\
+ .filter(expohit=True, data_begin__gte=date)
if th_tg_filter:
paid_recommend = list(paid_recommend.filter(theme__in=th_tg_structure.keys()))
recommended = recommended.filter(th_tg_filter)
@@ -249,7 +249,7 @@ class Contact(models.Model):
# moscow
if self.moscow:
- moscow_sqs = RelatedSearchQuerySet().models(Exposition, Conference)\
+ moscow_sqs = SearchQuerySet().models(Exposition, Conference)\
.filter(city_id=Exact(settings.MOSCOW_PK), data_begin__gte=date)
if th_tg_filter is not None:
moscow_sqs = moscow_sqs.filter(th_tg_filter)
@@ -258,14 +258,14 @@ class Contact(models.Model):
moscow_filter_url.setlist('theme', th_tg_structure.keys())
moscow_filter_url.setlist('tag', list(chain(th_tg_structure.values())))
moscow_filter_url['city'] = settings.MOSCOW_PK
- # moscow_filter_url['date_from'] = date.strftime('%d.%m.%Y')
+ moscow_filter_url['date_from'] = date.strftime('%d.%m.%Y')
ctx['moscow_filter_url'] = mark_safe(moscow_filter_url.urlencode())
# russia
if self.russia:
r_cities = set(self.r_cities.values_list('pk', flat=True))
r_date = date + relativedelta.relativedelta(months=1)
- russia_sqs = RelatedSearchQuerySet().models(Exposition, Conference)\
+ russia_sqs = SearchQuerySet().models(Exposition, Conference)\
.filter(country_id=Exact(settings.RUSSIA_PK), data_begin__gte=r_date)\
.exclude(city_id=Exact(settings.MOSCOW_PK))
if r_cities:
@@ -277,14 +277,25 @@ class Contact(models.Model):
russia_filter_url.setlist('theme', th_tg_structure.keys())
russia_filter_url.setlist('tag', list(chain(th_tg_structure.values())))
russia_filter_url['country'] = settings.RUSSIA_PK
- # russia_filter_url['date_from'] = r_date.strftime('%d.%m.%Y')
+ russia_filter_url['date_from'] = r_date.strftime('%d.%m.%Y')
ctx['russia_filter_url'] = mark_safe(russia_filter_url.urlencode())
# foreign
if self.foreign:
- f_countries = set(self.f_countries.values_list('pk', flat=True))
- foreign_sqs = RelatedSearchQuerySet().models(Exposition, Conference)\
- .filter(country_id__in=f_countries, data_begin__gte=date)
+ f_countries_cleaned = list(self.f_countries.order_by('pk').values_list('pk', 'area_id'))
+ areas = set(self.area.order_by('pk').values_list('pk', flat=True))
+ areas_with_country = set()
+ f_countries = set()
+ for area, group in groupby(f_countries_cleaned, lambda x: x[1]):
+ areas_with_country.add(area)
+ f_countries.update(map(lambda x: x[0], group))
+ full_areas = areas.difference(areas_with_country)
+
+ foreign_sqs = SearchQuerySet().models(Exposition, Conference)\
+ .filter(
+ SQ(country_id__in=f_countries) |\
+ SQ(area_id__in=full_areas),
+ data_begin__gte=date)
if th_tg_filter is not None:
foreign_sqs = foreign_sqs.filter(th_tg_filter)
ctx['foreign'] = foreign_sqs.order_by('data_begin')[:4]
@@ -292,7 +303,7 @@ class Contact(models.Model):
foreign_filter_url.setlist('theme', th_tg_structure.keys())
foreign_filter_url.setlist('tag', list(chain(th_tg_structure.values())))
foreign_filter_url.setlist('country', f_countries)
- # foreign_filter_url['date_from'] = date.strftime('%d.%m.%Y')
+ foreign_filter_url['date_from'] = date.strftime('%d.%m.%Y')
ctx['foreign_filter_url'] = mark_safe(foreign_filter_url.urlencode())
# news
@@ -315,6 +326,7 @@ class Contact(models.Model):
except:
pass
+ # import pdb; pdb.set_trace()
return ctx
def get_announce_context(self):
diff --git a/emencia/django/newsletter/templates/newsletter/AutomaticEmail.html b/emencia/django/newsletter/templates/newsletter/AutomaticEmail.html
index c52d231c..2d5ee6ad 100644
--- a/emencia/django/newsletter/templates/newsletter/AutomaticEmail.html
+++ b/emencia/django/newsletter/templates/newsletter/AutomaticEmail.html
@@ -1,25 +1,582 @@
{% load i18n %}
+{% load static %}
+{% load thumbnail %}
-
-
-
-
-
-
-
- {% trans "Emencia Django Newsletter" %} - {% block title %}{% endblock %}
-
-
- {% trans "Emencia Django Newsletter" %}
- {% block test_form %}
- {% endblock test_form %}
-
- {% block content %}
- {% trans "ПОСМОТРЕТЬ ВСЕ" %} >
- {% trans "ПОСМОТРЕТЬ ВСЕ" %} >
- {% trans "ПОСМОТРЕТЬ ВСЕ" %} >
- {% trans "НАСТРОИТЬ" %} >
-
- {% endblock %}
-
-
+{# {% trans "ПОСМОТРЕТЬ ВСЕ" %} > #}
+{# {% trans "ПОСМОТРЕТЬ ВСЕ" %} > #}
+{# {% trans "ПОСМОТРЕТЬ ВСЕ" %} > #}
+{# {% trans "НАСТРОИТЬ" %} > #}
+
+
+
+
+
+
+
+ | |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+ |
+
+
+
+ {% if recommended %}
+ {% with recommended.object as obj %}
+
+
+
+
+
+
+ | {% trans "Самые важные события для вас" %} |
+
+
+
+
+
+
+ {% thumbnail obj.get_logo '281x225' as im %}
+
+ {% endthumbnail %}
+ |
+
+
+
+
+
+
+ {{ obj.get_event_place_name }}
+ |
+
+
+
+ | {{ obj.name|safe }} |
+
+
+
+
+
+ {{ obj.get_dates }}, {{ obj.get_event_place_name }}
+ |
+
+
+
+ |
+ {{ obj.main_title|safe }}
+ |
+
+
+
+ |
+ {% for tag in obj.tags %}
+ {{ tag.name }}{% if not forloop.last %},{% endif %}
+ {% endfor %}
+ |
+
+
+
+ |
+ {% trans "посмотреть Подробнее" %}
+ |
+
+
+ |
+
+
+ |
+
+
+ {% endwith %}
+ {% endif %}
+
+ {% if moscow %}
+
+
+
+
+
+
+ | {% trans "в москве" %} |
+
+
+ {% for sqs_obj in moscow %}
+ {% with sqs_obj.object as obj %}
+
+
+
+ {% thumbnail obj.get_logo '109x114' as im %}
+
+ {% endthumbnail %}
+ |
+
+
+
+ | {{ obj.name|safe }} |
+
+
+
+ | {{ obj.main_title|safe }} |
+
+
+
+
+
+ {{ obj.get_dates }}
+ |
+
+
+
+
+ {% if obj.get_event_place_name %}
+
+ {{ obj.get_event_place_name }}
+ {% endif %}
+ |
+
+
+
+ |
+ {% trans "подробнее" %}
+ |
+
+
+ |
+
+
+ {% endwith %}
+ {% endfor %}
+
+ |
+
+
+ {% endif %}
+
+
+
+ {% if russia %}
+
+
+
+
+
+
+ | {% trans "В России" %} |
+
+
+ {% for sqs_obj in russia %}
+ {% with sqs_obj.object as obj %}
+
+
+
+ {% thumbnail obj.get_logo '109x114' as im %}
+
+ {% endthumbnail %}
+ |
+
+
+
+
+ {% if obj.get_event_place_name %}
+
+ {{ obj.get_event_place_name }}
+ {% endif %}
+ |
+
+
+
+ | {{ obj.name|safe }} |
+
+
+
+ | {{ obj.main_title|safe }} |
+
+
+
+
+
+ {{ obj.get_dates }}
+ |
+
+
+
+ |
+ {% trans "подробнее" %}
+ |
+
+
+ |
+
+
+ {% endwith %}
+ {% endfor %}
+
+
+ |
+
+
+ {% endif %}
+
+
+
+ {% if foreign %}
+
+
+
+ | {% trans "За рубежом" %} |
+
+
+
+
+
+
+ {% for sqs_obj in foreign %}
+ {% with sqs_obj.object as obj %}
+
+
+
+
+ {% thumbnail obj.get_logo '109x114' as im %}
+
+ {% endthumbnail %}
+ |
+
+
+
+ {% if obj.get_event_place_name %}
+
+ {{ obj.get_event_place_name }}
+ {% endif %}
+ |
+
+
+ | {{ obj.name|safe }} |
+
+
+
+
+ {{ obj.get_dates }}
+ |
+
+
+ |
+ {% for tag in obj.tags %}
+ {{ tag.name }}{% if not forloop.last %},{% endif %}
+ {% endfor %}
+ |
+
+
+ |
+ {% endwith %}
+ {% endfor %}
+
+
+ |
+
+
+
+ |
+ {% trans "Посмотреть все" %}
+ |
+
+
+ {% endif %}
+
+
+
+
+
+
+
+ | {% trans "Снимаем всю гололвную боль" %}
+ |
+
+
+
+ {% blocktrans %}По организации участия в зарубежной выставке{% endblocktrans %} |
+
+
+
+ | {% trans "Отдыхайте, пока мы работаем!" %} |
+
+
+ |
+
+
+
+
+
+ {% trans "Команда" %}
+
+ |
+
+
+ |
+
+
+
+ {% if news %}
+
+
+
+ | {% trans "Новости событий" %} |
+
+
+
+
+
+
+
+ {% thumbnail news.logo "272x195" as im %}
+
+ {% endthumbnail %}
+
+ |
+
+
+
+
+ | {{ news.main_title|safe }} |
+
+
+
+
+ {# С 1 по 4 сентября #}
+ |
+
+
+ | {{ news.preview|safe }} |
+
+
+ |
+ {% trans "Все новости" %}
+ |
+
+
+ |
+
+
+ |
+
+
+ {% endif %}
+
+
+
+ {% if blog %}
+
+
+
+ | {% trans "Новенькое из блога" %} |
+
+
+
+
+
+
+
+ {% thumbnail blog.logo "272x195" as im %}
+
+ {% endthumbnail %}
+ |
+
+
+
+ |
+
+
+ |
+
+
+ {% endif %}
+
+
+
+
+
+ |
+ {% trans "Следуйте за нами" %}:
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+ | {% trans "Управление подпиской:" %} |
+
+
+
+ | {% trans "Вы можете настроить включение различных блоков информации в свое письмо, выбратьфильтры по темам, странам и городам, а также выбрать комфортную периодичность получения писем." %} |
+
+
+
+ |
+ {% trans "Настроить" %}
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+  |
+
+
+
+ | {% trans "Хорошего Вам дня!" %} |
+
+
+ |
+
+
+
+
+
+ {% trans "Поисковик деловых событий" %}
+ expomap.ru
+ mail@expomap.ru
+ |
+
+
+
+
+ {% trans "По вопросам участия в выставках звоните" %}:
+ +7 (499) 999 -12-07
+ |
+
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
diff --git a/emencia/django/newsletter/templates/newsletter/AutomaticEmail_test.html b/emencia/django/newsletter/templates/newsletter/AutomaticEmail_test.html
index 44f96963..0824f732 100644
--- a/emencia/django/newsletter/templates/newsletter/AutomaticEmail_test.html
+++ b/emencia/django/newsletter/templates/newsletter/AutomaticEmail_test.html
@@ -1,10 +1,25 @@
-{% extends "newsletter/AutomaticEmail.html" %}
{% load i18n %}
-{% block test_form %}
-
-{% endblock test_form %}
+
+
+
+
+
+
+
+ {% trans "Emencia Django Newsletter" %} - {% block title %}{% endblock %}
+
+
+ {% trans "Emencia Django Newsletter" %}
+
+
+ {% if contact %}
+ {% include "newsletter/AutomaticEmail.html" %}
+ {% endif %}
+
+
+
diff --git a/events/forms.py b/events/forms.py
index b41aa692..bf75b7d3 100644
--- a/events/forms.py
+++ b/events/forms.py
@@ -212,6 +212,7 @@ def check_year(value):
class FilterForm(forms.Form):
_month_choices = None
_month = None
+ _date_begin_sqs_params = None
event_type = FilterTypedMultipleChoiceField(
label=_(u'Тип события'), coerce=int,
@@ -1017,42 +1018,43 @@ class FilterForm(forms.Form):
return year, month
def make_date_begin_sqs_params(self):
- periods = []
- self.checked_monthes = {}
- cleaned_periods = self.get_date_begin_periods()
- # print(cleaned_periods)
- date_range = self.get_date_from_to_range()
- if date_range is not None:
- periods.append(date_range)
- else:
- for year, monthes in cleaned_periods.iteritems():
- for month in monthes:
- if month in self.checked_monthes.get(year, []):
- continue
- start_year, start_month = self.get_start_of_period(year, cleaned_periods, month)
- end_year, end_month = self.get_end_of_period(year, cleaned_periods, month)
- _first_day, _last_day = calendar.monthrange(end_year, end_month)
- periods.append((
- date.today().replace(day=1, month=start_month, year=start_year),
- date.today().replace(day=_last_day, month=end_month, year=end_year)
- ))
- if not monthes:
- start_year, start_month = self.get_start_of_period(year, cleaned_periods)
- end_year, end_month = self.get_end_of_period(year, cleaned_periods)
- _first_day, _last_day = calendar.monthrange(end_year, end_month)
- periods.append((
- date.today().replace(day=1, month=start_month, year=start_year),
- date.today().replace(day=_last_day, month=end_month, year=end_year)
- ))
-
- params = None
- for start, end in periods:
- lookup = {'data_begin__range': (start, end)} if end else {'data_begin': start}
- if params is None:
- params = SQ(**lookup)
+ if self._date_begin_sqs_params is None:
+ periods = []
+ self.checked_monthes = {}
+ cleaned_periods = self.get_date_begin_periods()
+ # print(cleaned_periods)
+ date_range = self.get_date_from_to_range()
+ if date_range is not None:
+ periods.append(date_range)
else:
- params |= SQ(**lookup)
- return params
+ for year, monthes in cleaned_periods.iteritems():
+ for month in monthes:
+ if month in self.checked_monthes.get(year, []):
+ continue
+ start_year, start_month = self.get_start_of_period(year, cleaned_periods, month)
+ end_year, end_month = self.get_end_of_period(year, cleaned_periods, month)
+ _first_day, _last_day = calendar.monthrange(end_year, end_month)
+ periods.append((
+ date.today().replace(day=1, month=start_month, year=start_year),
+ date.today().replace(day=_last_day, month=end_month, year=end_year)
+ ))
+ if not monthes:
+ start_year, start_month = self.get_start_of_period(year, cleaned_periods)
+ end_year, end_month = self.get_end_of_period(year, cleaned_periods)
+ _first_day, _last_day = calendar.monthrange(end_year, end_month)
+ periods.append((
+ date.today().replace(day=1, month=start_month, year=start_year),
+ date.today().replace(day=_last_day, month=end_month, year=end_year)
+ ))
+ params = None
+ for start, end in periods:
+ lookup = {'data_begin__range': (start, end)} if end else {'data_begin__gte': start}
+ if params is None:
+ params = SQ(**lookup)
+ else:
+ params |= SQ(**lookup)
+ self._date_begin_sqs_params = params
+ return self._date_begin_sqs_params
def make_rating_sqs_params(self):
params = None
diff --git a/functions/model_mixin.py b/functions/model_mixin.py
index 04b0fcbb..7cf31639 100644
--- a/functions/model_mixin.py
+++ b/functions/model_mixin.py
@@ -20,7 +20,7 @@ class ExpoMixin(object):
logo = self.files.filter(purpose='logo')
if logo:
return logo[0]
- return logo
+ return self.logo
def get_preview(self):
@@ -80,6 +80,11 @@ class EventMixin(object):
set_cached_translation(self.place, tr)
return self.place.name
+ def get_event_place_name(self):
+ if self.place:
+ return self.get_place_name
+ return getattr(self, 'place_alt', None)
+
def get_permanent_url(self):
url = '%s%s/'%(self.get_catalog_url(), self.url)
return url
diff --git a/static/newsletter/images/b.png b/static/newsletter/images/b.png
new file mode 100755
index 00000000..580949b1
Binary files /dev/null and b/static/newsletter/images/b.png differ
diff --git a/static/newsletter/images/calendar.png b/static/newsletter/images/calendar.png
new file mode 100755
index 00000000..a6ab9a77
Binary files /dev/null and b/static/newsletter/images/calendar.png differ
diff --git a/static/newsletter/images/expo.png b/static/newsletter/images/expo.png
new file mode 100755
index 00000000..a370c2a7
Binary files /dev/null and b/static/newsletter/images/expo.png differ
diff --git a/static/newsletter/images/img.jpg b/static/newsletter/images/img.jpg
new file mode 100755
index 00000000..aadb46b7
Binary files /dev/null and b/static/newsletter/images/img.jpg differ
diff --git a/static/newsletter/images/img2.png b/static/newsletter/images/img2.png
new file mode 100755
index 00000000..98dae4c7
Binary files /dev/null and b/static/newsletter/images/img2.png differ
diff --git a/static/newsletter/images/logo1.png b/static/newsletter/images/logo1.png
new file mode 100755
index 00000000..ab1032af
Binary files /dev/null and b/static/newsletter/images/logo1.png differ
diff --git a/static/newsletter/images/logo2.png b/static/newsletter/images/logo2.png
new file mode 100755
index 00000000..5b23269e
Binary files /dev/null and b/static/newsletter/images/logo2.png differ
diff --git a/static/newsletter/images/m1.png b/static/newsletter/images/m1.png
new file mode 100755
index 00000000..d5d69b12
Binary files /dev/null and b/static/newsletter/images/m1.png differ
diff --git a/static/newsletter/images/m2.png b/static/newsletter/images/m2.png
new file mode 100755
index 00000000..9fa42e6d
Binary files /dev/null and b/static/newsletter/images/m2.png differ
diff --git a/static/newsletter/images/m3.png b/static/newsletter/images/m3.png
new file mode 100755
index 00000000..40180916
Binary files /dev/null and b/static/newsletter/images/m3.png differ
diff --git a/static/newsletter/images/m4.png b/static/newsletter/images/m4.png
new file mode 100755
index 00000000..560d46a3
Binary files /dev/null and b/static/newsletter/images/m4.png differ
diff --git a/static/newsletter/images/marker.png b/static/newsletter/images/marker.png
new file mode 100755
index 00000000..5d6896a2
Binary files /dev/null and b/static/newsletter/images/marker.png differ
diff --git a/static/newsletter/images/marker2.png b/static/newsletter/images/marker2.png
new file mode 100755
index 00000000..be97b524
Binary files /dev/null and b/static/newsletter/images/marker2.png differ
diff --git a/static/newsletter/images/news.jpg b/static/newsletter/images/news.jpg
new file mode 100755
index 00000000..1d2dff6a
Binary files /dev/null and b/static/newsletter/images/news.jpg differ
diff --git a/static/newsletter/images/news2.jpg b/static/newsletter/images/news2.jpg
new file mode 100755
index 00000000..017f69cb
Binary files /dev/null and b/static/newsletter/images/news2.jpg differ
diff --git a/static/newsletter/images/s1.png b/static/newsletter/images/s1.png
new file mode 100755
index 00000000..6233037d
Binary files /dev/null and b/static/newsletter/images/s1.png differ
diff --git a/static/newsletter/images/s2.png b/static/newsletter/images/s2.png
new file mode 100755
index 00000000..9c1a98f0
Binary files /dev/null and b/static/newsletter/images/s2.png differ
diff --git a/static/newsletter/images/s3.png b/static/newsletter/images/s3.png
new file mode 100755
index 00000000..1bcde81f
Binary files /dev/null and b/static/newsletter/images/s3.png differ
diff --git a/static/newsletter/images/s4.png b/static/newsletter/images/s4.png
new file mode 100755
index 00000000..46805375
Binary files /dev/null and b/static/newsletter/images/s4.png differ
diff --git a/static/newsletter/images/s5.png b/static/newsletter/images/s5.png
new file mode 100755
index 00000000..f8799b41
Binary files /dev/null and b/static/newsletter/images/s5.png differ
diff --git a/static/newsletter/images/s6.png b/static/newsletter/images/s6.png
new file mode 100755
index 00000000..e83c4e1e
Binary files /dev/null and b/static/newsletter/images/s6.png differ
diff --git a/static/newsletter/images/site_logo.png b/static/newsletter/images/site_logo.png
new file mode 100755
index 00000000..106a225e
Binary files /dev/null and b/static/newsletter/images/site_logo.png differ