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 %} + + + + +
+ {% trans "посмотреть все" %} +
+
+ {% 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 %} + + + + + +
+ {% trans "все события" %} +
+
+ {% endif %} + + + + {% if foreign %} + + + + + + + + + + + + + +
{% trans "За рубежом" %}
+ + + {% for sqs_obj in foreign %} + {% with sqs_obj.object as obj %} + + {% endwith %} + {% endfor %} + +
+ + + + + + + + + + + + + + + + +
+ {% 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 %} +
+
+
+ {% 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 %} + + + + + + + + + + + + + +
{{ blog.main_title|safe }}
{{ blog.preview|safe }}
+ {% trans "посмотреть Подробнее" %} +
+
+
+ {% endif %} + + + + + + + + + +
+ {% trans "Следуйте за нами" %}: + + + + + + + +
+ + + + + + + + + + + + + + + +
{% trans "Управление подпиской:" %}
{% trans "Вы можете настроить включение различных блоков информации в свое письмо, выбратьфильтры по темам, странам и городам, а также выбрать комфортную периодичность получения писем." %}
+ {% trans "Настроить" %} +
+ + + + + + + +
+ + + + + + +
+ + + + + + + + +
{% trans "Хорошего Вам дня!" %}
+
+ + + + + + + + +
+ {% trans "Поисковик деловых событий" %}
+ expomap.ru
+ mail@expomap.ru +
+ {% trans "По вопросам участия в выставках звоните" %}:
+ +7 (499) 999 -12-07 +
+
+
+ + + + + + + + + + + +
{% trans "Выставки" %}{% trans "Конференции" %}{% trans "Участие в выставках" %}{% trans "Новости" %}{% trans "Статьи" %}
+ + + + + + + + + + + + + +
{% trans "Вы получили это письмо, так как подписаны на рассылку" %} https://www.expomap.ru
{% trans "Переслать другу" %} {% trans "или" %} {% trans "Отписаться" %}
© 2008 — 2016 Expomap.ru
+ + +
+ +
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 %} -
- {% csrf_token %} - {{ form.as_p }} - -
-{% endblock test_form %} + + + + + + + + {% trans "Emencia Django Newsletter" %} - {% block title %}{% endblock %} + + +

{% trans "Emencia Django Newsletter" %}

+ +
+ {% csrf_token %} + {{ form.as_p }} + +
+ {% 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