Merge branch 'develop' into banners

remotes/origin/1203
Kotiuk Nazarii 11 years ago
commit 5a221c1538
  1. 2
      .gitignore
  2. 2
      banners/models.py
  3. 7
      city/models.py
  4. 34
      city/search_indexes.py
  5. 13
      conference/admin.py
  6. 1
      conference/admin_urls.py
  7. 7
      conference/forms.py
  8. 10
      conference/search_indexes.py
  9. 2
      conference/urls.py
  10. 8
      conference/views.py
  11. 7
      country/manager.py
  12. 12
      country/models.py
  13. 62
      country/search_indexes.py
  14. 11
      exposition/admin.py
  15. 1
      exposition/admin_urls.py
  16. 15
      exposition/forms.py
  17. 4
      exposition/models.py
  18. 10
      exposition/search_indexes.py
  19. 1
      exposition/urls.py
  20. 15
      exposition/views.py
  21. 50
      functions/model_mixin.py
  22. 2
      functions/search_forms.py
  23. 53
      import_xls/admin.py
  24. 10
      import_xls/admin_urls.py
  25. 39
      import_xls/import_forms.py
  26. 77
      import_xls/models.py
  27. 32
      import_xls/utils.py
  28. 2
      proj/admin_urls.py
  29. 1
      proj/settings.py
  30. 1
      proj/urls.py
  31. 8
      service/forms.py
  32. 59
      service/models.py
  33. 8
      settings/templatetags/template_filters.py
  34. 81
      settings/views.py
  35. 4
      static/custom_js/main.js
  36. BIN
      static/img/expob/cemat15.gif
  37. BIN
      static/img/expob/cemat15_v2.gif
  38. BIN
      static/img/expob/mims15.gif
  39. 9
      templates/admin/base.html
  40. 8
      templates/admin/conference/conference.html
  41. 71
      templates/admin/conference/conference_list.html
  42. 46
      templates/admin/exposition/exposition.html
  43. 41
      templates/admin/exposition/exposition_list.html
  44. 46
      templates/admin/import templates/log.html
  45. 15
      templates/admin/import templates/log_delete.html
  46. 1
      templates/admin/includes/admin_nav.html
  47. 8
      templates/admin/service/control.html
  48. 91
      templates/client/blank.html
  49. 86
      templates/client/exposition/exposition_detail.html
  50. 33
      templates/client/includes/banners/under_search.html
  51. 29
      templates/client/includes/conference/conference_object.html
  52. 31
      templates/client/includes/exposition/exposition_object.html
  53. 6
      templates/client/includes/exposition/exposition_services.html
  54. 1
      templates/client/includes/services.html
  55. 8
      templates/client/popups/auto_banner.html
  56. 23
      templates/client/popups/auto_modal.html
  57. 8
      templates/client/popups/cemat_banner1.html
  58. 8
      templates/client/popups/cemat_banner2.html
  59. 24
      templates/client/popups/cemat_modal.html
  60. 2
      templates/client/search/indexes/city/city_text.txt
  61. 1
      templates/client/search/indexes/country/area_text.txt
  62. 1
      templates/client/search/indexes/country/country_text.txt
  63. 132
      templates/client/static_client/css/main.css
  64. 2
      templates/client/static_client/css_min/main.min.css
  65. 1214
      templates/client/static_client/html-cut/subscribe.html
  66. BIN
      templates/client/static_client/img/arrow.png
  67. BIN
      templates/client/static_client/img/expo_b/cemat15.gif
  68. BIN
      templates/client/static_client/img/expo_b/cemat15_v2.gif
  69. BIN
      templates/client/static_client/img/expo_b/cemat_modal1.png
  70. BIN
      templates/client/static_client/img/expo_b/cemat_modal2.png
  71. BIN
      templates/client/static_client/img/expo_b/mims.png
  72. BIN
      templates/client/static_client/img/expo_b/mims15.gif
  73. BIN
      templates/client/static_client/img/expob/cemat15.gif
  74. BIN
      templates/client/static_client/img/expob/cemat15_v2.gif
  75. BIN
      templates/client/static_client/img/expob/mims15.gif
  76. BIN
      templates/client/static_client/img/partners/IPSA_2015_web_900x130.gif
  77. BIN
      templates/client/static_client/img/partners/beach.png
  78. BIN
      templates/client/static_client/img/partners/cemat15_900x130_bilet.gif
  79. BIN
      templates/client/static_client/img/partners/mims15_900x130_bilet.gif
  80. BIN
      templates/client/static_client/img/soc-medias/email/gmail.png
  81. BIN
      templates/client/static_client/img/soc-medias/email/mailru.png
  82. BIN
      templates/client/static_client/img/soc-medias/email/rambler.png
  83. BIN
      templates/client/static_client/img/soc-medias/email/yahoo.png
  84. BIN
      templates/client/static_client/img/soc-medias/email/yandex.png
  85. 11
      theme/models.py
  86. 2
      theme/search_indexes.py

2
.gitignore vendored

@ -13,3 +13,5 @@ npm-debug.log
node_modules

@ -5,6 +5,8 @@ from django.db import models
class Redirect(models.Model): class Redirect(models.Model):
redirect = models.URLField() redirect = models.URLField()
count = models.PositiveIntegerField(default=0) count = models.PositiveIntegerField(default=0)
views = models.PositiveIntegerField(default=0)
def __unicode__(self): def __unicode__(self):
return self.redirect return self.redirect

@ -2,6 +2,7 @@
from datetime import date from datetime import date
from django.db import models from django.db import models
from django.db.models.signals import post_save, pre_save from django.db.models.signals import post_save, pre_save
from django.utils import translation
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from bitfield import BitField from bitfield import BitField
from sorl.thumbnail import ImageField from sorl.thumbnail import ImageField
@ -116,6 +117,12 @@ class City(TranslatableModel):
def get_sub_categories(self): def get_sub_categories(self):
return [] return []
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
return names

@ -1,18 +1,36 @@
# -*- coding: utf-8 -*-
from django.utils import translation
from haystack import indexes from haystack import indexes
from models import City from models import City
from functions.search_mixin import ExpoSearchMixin
"""
class CityIndex(indexes.SearchIndex, indexes.Indexable): class CountryIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
text = indexes.CharField(document=True, use_template=True) text = indexes.CharField(document=True, use_template=True)
translations = indexes.MultiValueField() url = indexes.CharField()
#name = indexes.CharField(model_attr='translations__name') content_auto = indexes.EdgeNgramField()
form_name = indexes.CharField()
# translated fields
name_en = indexes.CharField()
name_ru = indexes.CharField()
catalog_name_en = indexes.CharField()
catalog_name_ru = indexes.CharField()
def prepare_form_name(self, obj):
return 'ci'
def prepare_catalog_name_en(self, obj):
return u'Cities'
def prepare_translations(self, obj): def prepare_catalog_name_ru(self, obj):
return [tr.name for tr in obj.translations.all()] return u'Города'
def get_model(self): def get_model(self):
return City return City
def index_queryset(self, using=None): def index_queryset(self, using=None):
return self.get_model().objects.filter()
""" return self.get_model().used.all()
def get_updated_field(self):
return 'modified'

@ -239,7 +239,7 @@ class ConferenceView(AdminView):
'link':obj.link, 'conference_id':obj.id, 'expohit': obj.expohit, 'periodic':obj.periodic, 'link':obj.link, 'conference_id':obj.id, 'expohit': obj.expohit, 'periodic':obj.periodic,
'discount': obj.discount,'canceled': obj.canceled, 'moved': obj.moved, 'discount': obj.discount,'canceled': obj.canceled, 'moved': obj.moved,
'visitors': obj.visitors, 'members': obj.members, 'logo': obj.logo, 'visitors': obj.visitors, 'members': obj.members, 'logo': obj.logo,
'audience':[item for item, bool in obj.audience if bool==True], 'audience':[item for item, bool in obj.audience if bool==True], 'org': obj.org,
'quality_label': [item for item, bool in obj.quality_label if bool==True]} 'quality_label': [item for item, bool in obj.quality_label if bool==True]}
if obj.place: if obj.place:
@ -313,3 +313,14 @@ def search_conf(request):
result = [{'id': item.pk, 'label': get_by_lang(item, 'name', lang)} for item in qs] result = [{'id': item.pk, 'label': get_by_lang(item, 'name', lang)} for item in qs]
return HttpResponse(json.dumps(result), content_type='application/json') return HttpResponse(json.dumps(result), content_type='application/json')
def conf_copy(request):
response = {'redirect': ''}
conf = Conference.objects.get(id=request.GET['id'])
duplicate = conf.copy(request.GET['url'])
if isinstance(duplicate, Conference):
response['redirect'] = '/admin/conference/%s/'%duplicate.url
else:
response['msg'] = duplicate
return HttpResponse(json.dumps(response), content_type='application/json')

@ -5,6 +5,7 @@ from admin import ConferenceListView, ConferenceView
urlpatterns = patterns('conference.admin', urlpatterns = patterns('conference.admin',
url(r'^upload-photo/(?P<conf_id>.*)/$', 'upload_conference_photo'), url(r'^upload-photo/(?P<conf_id>.*)/$', 'upload_conference_photo'),
url(r'^delete/(?P<url>.*)$', 'conference_delete'), url(r'^delete/(?P<url>.*)$', 'conference_delete'),
url(r'^copy/$', 'conf_copy'),
url(r'^all/$', ConferenceListView.as_view()), url(r'^all/$', ConferenceListView.as_view()),
#url(r'^change/(?P<url>.*)/$', 'conference_change'), #url(r'^change/(?P<url>.*)/$', 'conference_change'),

@ -47,9 +47,9 @@ class ConferenceCreateForm(forms.Form):
data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y']) data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y'])
logo = forms.ImageField(label='Logo', required=False) logo = forms.ImageField(label='Logo', required=False)
organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False, #organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
choices=[(item.id, item.name) for item in Organiser.objects.language().all()]) # choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
org = forms.CharField(required=False, label=u'Организатор')
country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()]) country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()])
theme = forms.MultipleChoiceField(label='Тематики', theme = forms.MultipleChoiceField(label='Тематики',
choices=[(item.id, item.name) for item in Theme.objects.language().all()]) choices=[(item.id, item.name) for item in Theme.objects.language().all()])
@ -140,6 +140,7 @@ class ConferenceCreateForm(forms.Form):
if data.get('logo'): if data.get('logo'):
conference.logo = data['logo'] conference.logo = data['logo']
conference.org = data['org']
conference.data_begin = data['data_begin'] conference.data_begin = data['data_begin']
conference.data_end = data['data_end'] conference.data_end = data['data_end']
conference.link = data['link'] conference.link = data['link']

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from haystack import indexes from haystack import indexes
from models import Conference from models import Conference
from functions.search_mixin import ExpoSearchMixin
class ConferenceIndex(indexes.SearchIndex, indexes.Indexable): class ConferenceIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
text = indexes.CharField(document=True, use_template=True) text = indexes.CharField(document=True, use_template=True)
where = indexes.MultiValueField() where = indexes.MultiValueField()
url = indexes.CharField() url = indexes.CharField()
@ -31,13 +32,6 @@ class ConferenceIndex(indexes.SearchIndex, indexes.Indexable):
def prepare_catalog_name_ru(self, obj): def prepare_catalog_name_ru(self, obj):
return u'Конференции' return u'Конференции'
def prepare_where(self, obj):
country = [tr.name for tr in obj.country.translations.all()]
city = [tr.name for tr in obj.city.translations.all()]
return country + city
def get_model(self): def get_model(self):
return Conference return Conference

@ -66,6 +66,8 @@ urlpatterns = patterns('',
url(r'conference/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ConferenceMembers.as_view()), url(r'conference/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ConferenceMembers.as_view()),
url(r'conference/(?P<slug>.*)/members/$', ConferenceMembers.as_view()), url(r'conference/(?P<slug>.*)/members/$', ConferenceMembers.as_view()),
url(r'^conference/(?P<slug>.*)/service/thanks/', ConferenceThankView.as_view()), url(r'^conference/(?P<slug>.*)/service/thanks/', ConferenceThankView.as_view()),
url(r'^conference/(?P<slug>.*)/service/visit/', 'conference.views.visit_redirect'),
url(r'conference/(?P<slug>.*)/service/(?P<service_url>.*)/', ConferenceServiceView.as_view()), url(r'conference/(?P<slug>.*)/service/(?P<service_url>.*)/', ConferenceServiceView.as_view()),

@ -2,7 +2,7 @@
import json import json
import datetime import datetime
from django.conf import settings from django.conf import settings
from django.http import HttpResponse, Http404, HttpResponseRedirect from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpResponsePermanentRedirect
from django.contrib import messages from django.contrib import messages
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -287,6 +287,12 @@ class ConferenceThankView(MetadataMixin, DetailView):
slug_field = 'url' slug_field = 'url'
template_name = 'client/service/thank_u_page.html' template_name = 'client/service/thank_u_page.html'
def visit_redirect(request, slug):
obj = get_object_or_404(Conference, url=slug)
redirect = obj.get_permanent_url()
return HttpResponsePermanentRedirect(redirect)
class ConferenceServiceView(FormMixin, DetailView): class ConferenceServiceView(FormMixin, DetailView):
model = Conference model = Conference
slug_field = 'url' slug_field = 'url'

@ -93,6 +93,13 @@ class CountryManager(TranslationManager):
cache.set(key, countries, self.cache_time) cache.set(key, countries, self.cache_time)
return countries return countries
def countries_for_search(self):
lang = translation.get_language()
qs = super(CountryManager, self).select_related('exposition_country').\
filter(exposition_country__country__isnull=False, translations__language_code=lang, )\
.order_by('translations__name').distinct()
return qs
class AreaManager(TranslationManager): class AreaManager(TranslationManager):
def all_sorted(self): def all_sorted(self):

@ -55,6 +55,12 @@ class Area(TranslatableModel):
parent = {} parent = {}
return parent return parent
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
return names
class Country(TranslatableModel): class Country(TranslatableModel):
""" """
@ -161,6 +167,12 @@ class Country(TranslatableModel):
parent = {'text' : self.area.name, 'id': self.area.id, 'name': 'area'} parent = {'text' : self.area.name, 'id': self.area.id, 'name': 'area'}
return parent return parent
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
return names
pre_save.connect(pre_save_handler, sender=Country) pre_save.connect(pre_save_handler, sender=Country)

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
from django.utils import translation
from haystack import indexes
from models import Country, Area
from functions.search_mixin import ExpoSearchMixin
class CountryIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
text = indexes.CharField(document=True, use_template=True)
url = indexes.CharField()
content_auto = indexes.EdgeNgramField()
form_name = indexes.CharField()
# translated fields
name_en = indexes.CharField()
name_ru = indexes.CharField()
catalog_name_en = indexes.CharField()
catalog_name_ru = indexes.CharField()
def prepare_form_name(self, obj):
return 'co'
def prepare_catalog_name_en(self, obj):
return u'Countries'
def prepare_catalog_name_ru(self, obj):
return u'Страны'
def get_model(self):
return Country
def index_queryset(self, using=None):
return self.get_model().objects.countries_for_search()
def get_updated_field(self):
return 'modified'
class AreaIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
text = indexes.CharField(document=True, use_template=True)
content_auto = indexes.EdgeNgramField()
form_name = indexes.CharField()
# translated fields
name_en = indexes.CharField()
name_ru = indexes.CharField()
catalog_name_en = indexes.CharField()
catalog_name_ru = indexes.CharField()
def prepare_form_name(self, obj):
return 'area'
def prepare_catalog_name_en(self, obj):
return u'Areas'
def prepare_catalog_name_ru(self, obj):
return u'Регионы'
def get_model(self):
return Area
def index_queryset(self, using=None):
return self.get_model().objects.filter()

@ -277,7 +277,7 @@ class ExpositionView(AdminView):
'min_stand_size':obj.min_stand_size, 'application_deadline':obj.application_deadline, 'min_stand_size':obj.min_stand_size, 'application_deadline':obj.application_deadline,
'min_open_area':obj.min_open_area, 'max_open_area':obj.max_open_area, 'min_open_area':obj.min_open_area, 'max_open_area':obj.max_open_area,
'registration_payment':obj.registration_payment, 'exposition_id':obj.id, 'registration_payment':obj.registration_payment, 'exposition_id':obj.id,
'registration_link': obj.registration_link, 'registration_link': obj.registration_link, 'org': obj.org,
'expohit': obj.expohit, 'discount': obj.discount, 'expohit': obj.expohit, 'discount': obj.discount,
'canceled': obj.canceled, 'moved': obj.moved, 'logo': obj.logo, 'canceled': obj.canceled, 'moved': obj.moved, 'logo': obj.logo,
'visitors': obj.visitors, 'members': obj.members, 'visitors': obj.visitors, 'members': obj.members,
@ -404,3 +404,12 @@ class PaidView(FormView):
def expo_copy(request):
response = {'redirect': ''}
expo = Exposition.objects.get(id=request.GET['id'])
duplicate = expo.copy(request.GET['url'])
if isinstance(duplicate, Exposition):
response['redirect'] = '/admin/exposition/%s/'%duplicate.url
else:
response['msg'] = duplicate
return HttpResponse(json.dumps(response), content_type='application/json')

@ -4,6 +4,7 @@ from admin import ExpositionListView, ExpositionView, PaidView
urlpatterns = patterns('exposition.admin', urlpatterns = patterns('exposition.admin',
url(r'^upload-photo/(?P<expo_id>.*)/$', 'upload_exposition_photo'), url(r'^upload-photo/(?P<expo_id>.*)/$', 'upload_exposition_photo'),
url(r'^copy/$', 'expo_copy'),
url(r'^(?P<url>.*)/paid/$', PaidView.as_view()), url(r'^(?P<url>.*)/paid/$', PaidView.as_view()),
#url(r'^add.*/$', 'exposition_add'), #url(r'^add.*/$', 'exposition_add'),

@ -49,11 +49,12 @@ class ExpositionCreateForm(forms.Form):
data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y']) data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y'])
logo = forms.ImageField(label='Logo', required=False) logo = forms.ImageField(label='Logo', required=False)
organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False, #organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
choices=[(item.id, item.name) for item in Organiser.objects.language().all()]) # choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
org = forms.CharField(required=False, label=u'Организатор')
company = forms.MultipleChoiceField(label=u'Компании', required=False, #company = forms.MultipleChoiceField(label=u'Компании', required=False,
choices=[(item.id, item.name) for item in Company.objects.language().all()] ) # choices=[(item.id, item.name) for item in Company.objects.language().all()] )
country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()]) country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()])
theme = forms.MultipleChoiceField(label='Тематики', theme = forms.MultipleChoiceField(label='Тематики',
choices=[(item.id, item.name) for item in Theme.objects.language().all()]) choices=[(item.id, item.name) for item in Theme.objects.language().all()])
@ -62,7 +63,6 @@ class ExpositionCreateForm(forms.Form):
#creates select input with empty choices cause it will be filled with ajax #creates select input with empty choices cause it will be filled with ajax
city = forms.CharField(label=u'Город', widget=forms.HiddenInput()) city = forms.CharField(label=u'Город', widget=forms.HiddenInput())
tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False) tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False)
#tag = forms.MultipleChoiceField(label=u'Теги', required=False)
periodic = forms.ChoiceField(label=u'Периодичность', choices=PERIODIC, required=False) periodic = forms.ChoiceField(label=u'Периодичность', choices=PERIODIC, required=False)
audience = forms.MultipleChoiceField(label=u'Аудитория', choices=public, initial='', required=False) audience = forms.MultipleChoiceField(label=u'Аудитория', choices=public, initial='', required=False)
@ -169,7 +169,7 @@ class ExpositionCreateForm(forms.Form):
exposition.theme.clear() exposition.theme.clear()
exposition.tag.clear() exposition.tag.clear()
exposition.organiser.clear() exposition.organiser.clear()
exposition.company.clear() #exposition.company.clear()
#simple fields #simple fields
if not getattr(exposition, 'url'): if not getattr(exposition, 'url'):
@ -177,6 +177,7 @@ class ExpositionCreateForm(forms.Form):
if data.get('logo'): if data.get('logo'):
exposition.logo = data['logo'] exposition.logo = data['logo']
exposition.org = data['org']
exposition.data_begin = data['data_begin'] exposition.data_begin = data['data_begin']
exposition.data_end = data['data_end'] exposition.data_end = data['data_end']
exposition.periodic = data['periodic'] exposition.periodic = data['periodic']
@ -236,7 +237,7 @@ class ExpositionCreateForm(forms.Form):
exposition.theme.add(*data['theme']) exposition.theme.add(*data['theme'])
exposition.tag.add(*Tag.objects.filter(id__in=data['tag'])) exposition.tag.add(*Tag.objects.filter(id__in=data['tag']))
exposition.organiser.add(*Organiser.objects.filter(id__in=data.get('organiser', []))) exposition.organiser.add(*Organiser.objects.filter(id__in=data.get('organiser', [])))
exposition.company.add(*Company.objects.filter(id__in=data.get('company', []))) #exposition.company.add(*Company.objects.filter(id__in=data.get('company', [])))
exposition.save() exposition.save()

@ -72,6 +72,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
organiser = models.ManyToManyField('organiser.Organiser', verbose_name='Организатор', organiser = models.ManyToManyField('organiser.Organiser', verbose_name='Организатор',
blank=True, null=True, related_name='exposition_organisers') blank=True, null=True, related_name='exposition_organisers')
org = models.CharField(max_length=255, blank=True, null=True) org = models.CharField(max_length=255, blank=True, null=True)
place_alt = models.CharField(max_length=255, blank=True, null=True)
company = models.ManyToManyField('company.Company', verbose_name='Компании', company = models.ManyToManyField('company.Company', verbose_name='Компании',
blank=True, null=True, related_name='exposition_companies') blank=True, null=True, related_name='exposition_companies')
users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки', users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки',
@ -299,6 +300,9 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
return code return code
return cur return cur
def theme_ids(self):
return [item['id'] for item in self.theme.all().values('id')]
class Statistic(TranslatableModel): class Statistic(TranslatableModel):
exposition = models.ForeignKey(Exposition, related_name='statistic') exposition = models.ForeignKey(Exposition, related_name='statistic')

@ -40,15 +40,5 @@ class ExpositionIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
return self.get_model().objects.filter(is_published=True) return self.get_model().objects.filter(is_published=True)
def get_name(self):
return 123
lang = translation.get_language()
if lang == 'ru':
return self.name_ru
elif lang=='en':
return self.name_en
else:
return self.name_ru
def get_updated_field(self): def get_updated_field(self):
return 'modified' return 'modified'

@ -72,6 +72,7 @@ urlpatterns = patterns('',
url(r'^expo/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ExpoMembers.as_view(), {'meta_id':63}), url(r'^expo/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ExpoMembers.as_view(), {'meta_id':63}),
url(r'^expo/(?P<slug>.*)/members/$', ExpoMembers.as_view(), {'meta_id':63}), url(r'^expo/(?P<slug>.*)/members/$', ExpoMembers.as_view(), {'meta_id':63}),
url(r'^expo/(?P<slug>.*)/service/thanks/', ExpositionThankView.as_view()), url(r'^expo/(?P<slug>.*)/service/thanks/', ExpositionThankView.as_view()),
url(r'^expo/(?P<slug>.*)/service/visit/', 'exposition.views.visit_redirect'),
url(r'^expo/(?P<slug>.*)/service/(?P<service_url>.*)/', ExpositionServiceView.as_view()), url(r'^expo/(?P<slug>.*)/service/(?P<service_url>.*)/', ExpositionServiceView.as_view()),
# expo list # expo list
url(r'^expo/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':4}), url(r'^expo/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':4}),

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
import datetime import datetime
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse, HttpResponsePermanentRedirect
from django.contrib import messages from django.contrib import messages
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.conf import settings from django.conf import settings
@ -182,6 +182,11 @@ class ExpositionThankView(MetadataMixin, DetailView):
slug_field = 'url' slug_field = 'url'
template_name = 'client/service/thank_u_page.html' template_name = 'client/service/thank_u_page.html'
def visit_redirect(request, slug):
obj = get_object_or_404(Exposition, url=slug)
redirect = obj.get_permanent_url() + 'price/'
return HttpResponsePermanentRedirect(redirect)
class ExpositionServiceView(MetadataMixin, FormMixin, DetailView): class ExpositionServiceView(MetadataMixin, FormMixin, DetailView):
model = Exposition model = Exposition
slug_field = 'url' slug_field = 'url'
@ -289,7 +294,7 @@ MONTHES = settings.MONTHES
class ExpoCatalog(MetadataMixin, ListView): class ExpoCatalog(MetadataMixin, ListView):
model = Exposition model = Exposition
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
template_name = 'exposition/catalog.html' template_name = 'client/exposition/catalog.html'
search_form = ExpositionSearchForm search_form = ExpositionSearchForm
filter_object = None filter_object = None
year = None year = None
@ -440,6 +445,12 @@ class ExpoTagCatalog(ExpoCatalog):
self.filter_object = tag self.filter_object = tag
return qs return qs
def get_context_data(self, **kwargs):
context = super(ExpoTagCatalog, self).get_context_data(**kwargs)
tag = self.kwargs['tag']
context['theme_for_filter'] = tag.theme
return context
class ExpoVisitors(MetadataMixin, ListView): class ExpoVisitors(MetadataMixin, ListView):
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
import copy
import calendar as python_calendar import calendar as python_calendar
from service.models import Service from service.models import Service
@ -32,8 +34,11 @@ class EventMixin(object):
url = '%s%s/'%(self.get_catalog_url(), self.url) url = '%s%s/'%(self.get_catalog_url(), self.url)
return url return url
def org_split(self):
if self.org:
return self.org.split(';')
else:
return []
def get_logo(self): def get_logo(self):
return self.logo return self.logo
@ -98,4 +103,43 @@ class EventMixin(object):
if self.data_end.month == month: if self.data_end.month == month:
return self.data_end.day return self.data_end.day
return 0 return 0
def copy(self, url):
"""
Copy event with new url
:param url: new url for event
:return: event object
"""
# check url
Model = type(self)
try:
Model.objects.get(url=url)
return u'Событие с таким урлом уже существует'
except Model.DoesNotExist:
pass
duplicate = copy.copy(self)
duplicate.url = url
# Setting pk to None. for Django its a new object.
duplicate.pk = None
# copy translations
ignore_fields = ['id', 'master', 'language_code']
duplicate.translate('ru')
tr = self._meta.translations_model.objects.get(language_code='ru', master__id=self.pk)
for field in duplicate._translated_field_names:
if field in ignore_fields:
continue
setattr(duplicate, field, getattr(tr, field))
duplicate.is_published = False
duplicate.save() # save but lost all ManyToMany relations
# copy relations
for field in self._meta.many_to_many:
source = getattr(self, field.attname)
destination = getattr(duplicate, field.attname)
for item in source.all():
destination.add(item)
return duplicate

@ -279,7 +279,7 @@ class ExpositionSearchForm(AbstactSearchForm):
area = self.cleaned_data.get('area') area = self.cleaned_data.get('area')
sqs = SearchQuerySet().models(Exposition).all() sqs = SearchQuerySet().models(Exposition, Conference).all()
if fr: if fr:
sqs = sqs.filter(data_begin__gte=fr) sqs = sqs.filter(data_begin__gte=fr)

@ -13,8 +13,10 @@ from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, Import
from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\ from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\
ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\ ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\
ExportCityForm ExportCityForm
from django.views.generic import FormView from django.views.generic import FormView, ListView, DeleteView
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.shortcuts import get_object_or_404
def xls_to_response(xls, fname): def xls_to_response(xls, fname):
response = HttpResponse(mimetype="application/ms-excel") response = HttpResponse(mimetype="application/ms-excel")
@ -97,20 +99,23 @@ class ExportCity(ExportView):
from exposition.models import Exposition from import_xls.models import Log
class ImportEvent(FormView): class ImportEvent(FormView):
form_class = ImportEventForm form_class = ImportEventForm
success_url = '/admin/import-event/' success_url = '/admin/import-event/'
template_name = 'admin/import templates/import_event.html' template_name = 'admin/import templates/import_event.html'
def form_valid(self, form): def form_valid(self, form):
errors = form.save_file_debug() errors = form.save_file_debug()
messages.success(self.request, 'Success') return HttpResponseRedirect('/admin/import/log/')
context = self.get_context_data()
context['import_errors'] = errors #messages.success(self.request, 'Success')
context['form'] = form
return render_to_response(self.template_name, context) #context = self.get_context_data()
#context['import_errors'] = errors
#context['form'] = form
#return render_to_response(self.template_name, context)
#return super(ImportEvent, self).form_valid(form)
class ImportTheme(ImportView): class ImportTheme(ImportView):
form_class = ImportThemeForm form_class = ImportThemeForm
@ -135,4 +140,34 @@ class ImportPlaceConference(ImportView):
class ExportEvent(ExportView): class ExportEvent(ExportView):
form_class = ExportEventForm form_class = ExportEventForm
template_name = 'export_event.html' template_name = 'export_event.html'
success_url = '/admin/export-event' success_url = '/admin/export-event'
class LogList(ListView):
model = Log
paginate_by = settings.ADMIN_PAGINATION
template_name = 'admin/import templates/log.html'
class LogDelete(DeleteView):
model = Log
success_url = '/admin/import/log/'
template_name = 'admin/import templates/log_delete.html'
def log_file(request, log_id):
log = get_object_or_404(Log, id=log_id)
response = HttpResponse()
response['content-type'] = 'application/x-executable'
filename = 'import_%s_log.txt'%str(log.id)
response['content-disposition'] = 'attachment;filename=%s'%filename
response['X-Accel-Redirect'] = log.log.url
return response
def work_file(request, log_id):
log = get_object_or_404(Log, id=log_id)
response = HttpResponse()
response['content-type'] = 'application/x-executable'
filename = 'import_%s_file.xls'%str(log.id)
response['content-disposition'] = 'attachment;filename=%s'%filename
response['X-Accel-Redirect'] = log.work_file.url
return response

@ -2,8 +2,11 @@
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference
from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\ from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\
ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity, LogList
from import_xls.admin import LogDelete
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^import-event/$', ImportEvent.as_view()), url(r'^import-event/$', ImportEvent.as_view()),
@ -23,5 +26,8 @@ urlpatterns = patterns('',
url(r'^export-company/$', ExportCompany.as_view()), url(r'^export-company/$', ExportCompany.as_view()),
url(r'^export-blog/$', ExportBlog.as_view()), url(r'^export-blog/$', ExportBlog.as_view()),
url(r'^export-city/$', ExportCity.as_view()), url(r'^export-city/$', ExportCity.as_view()),
url(r'^import/log/$', LogList.as_view()),
url(r'^import/log/delete/(?P<pk>.*)/$', LogDelete.as_view()),
url(r'^log/log/(?P<log_id>.*)/$', 'import_xls.admin.log_file'),
url(r'^log/work_file/(?P<log_id>.*)/$', 'import_xls.admin.work_file'),
) )

@ -246,6 +246,15 @@ typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправи
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'} '(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'}
# event # event
import time
def logcall(f, msg):
with open(f.file.name, 'a') as logfile:
logfile.write(msg.encode('utf8'))
from import_xls.models import Log
class ImportEventForm(ImportForm): class ImportEventForm(ImportForm):
""" """
extended form for importing one type of event extended form for importing one type of event
@ -270,20 +279,22 @@ class ImportEventForm(ImportForm):
labels = [label for label in row_list[0]] labels = [label for label in row_list[0]]
errors = [] errors = []
log = Log.custom.create_log_name(f)
for row_number, row in enumerate(row_list): for row_number, row in enumerate(row_list):
if row_number == 0: if row_number == 0:
continue continue
log_msg = u'[%s] %s: '%(str(row_number), row[2])
if row[0] != '': if row[0] != '':
# in first column id # in first column id
try: try:
obj = self.model.objects.language(lang).get(id=int(row[0])) obj = model.objects.language(lang).get(id=int(row[0]))
except ValueError: except ValueError:
obj = self.model() obj = model()
obj.translate(lang) obj.translate(lang)
except self.model.DoesNotExist: except model.DoesNotExist:
obj = self.model(id= int(row[0])) obj = model(id= int(row[0]))
obj.translate(lang) obj.translate(lang)
else: else:
# if id blank - its a new event # if id blank - its a new event
@ -305,7 +316,8 @@ class ImportEventForm(ImportForm):
if setting.get('method'): if setting.get('method'):
# this cell contains data that must be written after creating object # this cell contains data that must be written after creating object
if cell != "": if cell != "":
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')}) methods.append({'func': setting['func'], 'value': cell,
'purpose': setting.get('purpose'), 'field': label})
continue continue
field_name = setting['field'] field_name = setting['field']
@ -316,7 +328,7 @@ class ImportEventForm(ImportForm):
extra_value = setting.get('extra_values') extra_value = setting.get('extra_values')
if extra_value is not None: if extra_value is not None:
# if setting has extra value then # if setting has extra value then
# it is some field like city, theme, tag # it is some field like city, tag
# that has relation and can be created # that has relation and can be created
# in function we add language(need for relation fields) # in function we add language(need for relation fields)
@ -332,8 +344,8 @@ class ImportEventForm(ImportForm):
else: else:
value = func(cell) value = func(cell)
if field_name != 'place':
if field_name != 'place':
try: try:
setattr(obj, field_name, value) setattr(obj, field_name, value)
except ValueError: except ValueError:
@ -347,19 +359,22 @@ class ImportEventForm(ImportForm):
except Exception: except Exception:
setattr(obj, 'place_alt', cell) setattr(obj, 'place_alt', cell)
if not obj.url: if not obj.url:
a = obj.name
obj.url = translit_with_separator(obj.name) obj.url = translit_with_separator(obj.name)
obj.is_published = True obj.is_published = True
try: try:
obj.save() obj.save()
except IntegrityError, e: except IntegrityError, e:
error = str(e) error = str(e)
if typical_errors.get(error): if typical_errors.get(error):
error = typical_errors[error] error = typical_errors[error]
if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'): if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'):
error = u'Событие с таким названием или урлом уже существует' error = u'Событие с таким названием или урлом уже существует'
errors.append([obj.name, error]) errors.append([obj.name, error])
log_msg += error
logcall(log.log, log_msg + '\n')
continue continue
for method in methods: for method in methods:
@ -368,12 +383,14 @@ class ImportEventForm(ImportForm):
try: try:
func(obj, method['value'], method['purpose']) func(obj, method['value'], method['purpose'])
except: except:
log_msg += '(%s: Ошибка);'%method['field']
continue continue
else: else:
func(obj, method['value']) msg = func(obj, method['value'])
if msg:
#------------- log_msg += '(%s: %s);'%(method['field'], msg)
logcall(log.log, log_msg + '\n')
return errors return errors
def save_file(self): def save_file(self):

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.conf import settings
from django.db.models.fields.files import FieldFile
from django.db.models.signals import pre_delete
def get_doc_dir(instance, filename):
from pytils import translit
return u'import_xls/import/%s' %translit.translify(filename)
def file_cleanup(sender, instance, *args, **kwargs):
'''
Deletes the file(s) associated with a model instance. The model
is not saved after deletion of the file(s) since this is meant
to be used with the pre_delete signal.
'''
for field_name, _ in instance.__dict__.iteritems():
field = getattr(instance, field_name)
if issubclass(field.__class__, FieldFile) and field.name:
field.delete(save=False)
class LogManager(models.Manager):
def create_log(self, work_file, errors):
"""
:param work_file: executing file
:param errors: list of errors ([{'event name':['err1', 'err2']}])
:return: object log
"""
LOG_DIRECTORY = settings.MEDIA_ROOT+'import_xls/logs/'
name= '111.txt'
filename = LOG_DIRECTORY + name
log_file = open(filename, "w")
for error in errors:
event_name = ';'.join(error.keys())
errs = ''
for err in error.values():
errs += '; '.join(err)
errs += ';'
log_file.write('%s: %s\n'%(event_name, errs))
log_file.close()
#update.log_file.name = 'updates/'+name
log = Log(work_file=work_file)
log.log.name = 'import_xls/logs/' + name
#log = Log.objects.create(work_file=work_file, log=log_file)
log.save()
return log
def create_log_name(self, work_file):
log = Log.objects.create(work_file=work_file)
LOG_DIRECTORY = settings.MEDIA_ROOT+'import_xls/logs/'
name= 'log_%d.log'%log.id
filename = LOG_DIRECTORY + name
log_file = open(filename, "w").close()
log.log.name = 'import_xls/logs/' + name
log.save()
return log
class Log(models.Model):
work_file = models.FileField(upload_to=get_doc_dir)
log = models.FileField(upload_to='import_xls/logs/', blank=True)
type = models.CharField(max_length=10, default='IMPORT')
created = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
custom = LogManager()
class Meta:
ordering = ['-created']
pre_delete.connect(file_cleanup, sender=Log)

@ -1,6 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import urllib2 import urllib2
import time, xlrd import time, xlrd
import os
from PIL import Image
from django.conf import settings from django.conf import settings
from django.utils import translation from django.utils import translation
from hvad.utils import get_translation_aware_manager from hvad.utils import get_translation_aware_manager
@ -89,9 +91,13 @@ def to_theme(obj, value):
theme_ids = value.split(',') theme_ids = value.split(',')
if theme_ids == ['']: if theme_ids == ['']:
return return u'Неправильное значение'
obj.theme.clear() obj.theme.clear()
obj.theme.add(*Theme.objects.filter(id__in=theme_ids)) obj.theme.add(*Theme.objects.filter(id__in=theme_ids))
if not Theme.objects.filter(id__in=theme_ids).exists():
return u'Нет совпадений'
return None
def to_tag(obj,value): def to_tag(obj,value):
if value == [""]: if value == [""]:
@ -101,8 +107,7 @@ def to_tag(obj,value):
if names: if names:
obj.tag.clear() obj.tag.clear()
obj.tag.add(*Tag.objects.filter(translations__name__in=names, theme__in=obj.theme.all())) obj.tag.add(*Tag.objects.filter(translations__name__in=names, theme__in=obj.theme.all()))
else: return None
return
@ -131,6 +136,7 @@ def to_periodic(value):
def to_audience(value, model=Exposition): def to_audience(value, model=Exposition):
if value: if value:
translation.activate('ru')
l = value.split(', ') l = value.split(', ')
if l: if l:
new_list = [] new_list = []
@ -171,7 +177,7 @@ def save_logo(obj, path):
try: try:
alt_name = get_alternative_filename(full_path, file_name) alt_name = get_alternative_filename(full_path, file_name)
except UnicodeEncodeError: except UnicodeEncodeError:
return None return u'Некоректное название файла'
download_to = full_path+alt_name download_to = full_path+alt_name
@ -187,9 +193,9 @@ def save_logo(obj, path):
return None return None
try: try:
response = urllib2.urlopen(url, timeout=15) response = urllib2.urlopen(url, timeout=5)
except: except:
return None return u'Превышено время ожидания'
with open(download_to,'wb') as f: with open(download_to,'wb') as f:
try: try:
@ -197,14 +203,20 @@ def save_logo(obj, path):
f.close() f.close()
except: except:
# can be timeout # can be timeout
return None return u'Превышено время ожидания'
try:
# check if image
im=Image.open(download_to)
except IOError:
os.remove(download_to)
return u'Неправильный формат логотипа'
obj.logo = logo_path + alt_name obj.logo = logo_path + alt_name
try: try:
obj.save() obj.save()
except: except:
print('logo exception. logo: %s'%obj.logo) print('logo exception. logo: %s'%obj.logo)
return None return u'Неизвестная ошибка'
@ -213,10 +225,10 @@ def check_quality_label(obj, value, label):
try: try:
value = int(value) value = int(value)
except: except:
return bit return None
if value: if value:
setattr(bit, label, True) setattr(bit, label, True)
return bit return None
def to_user(value): def to_user(value):
try: try:

@ -31,6 +31,8 @@ urlpatterns = required(
url(r'^webinar/', include('webinar.admin_urls')), url(r'^webinar/', include('webinar.admin_urls')),
url(r'^settings/', include('settings.admin_urls')), url(r'^settings/', include('settings.admin_urls')),
url(r'^meta/', include('meta.admin_urls')), url(r'^meta/', include('meta.admin_urls')),
url(r'^import_xls/', include('import_xls.admin_urls')),
url(r'^language/add/', 'directories.admin.language_add'), url(r'^language/add/', 'directories.admin.language_add'),
url(r'^currency/add/', 'directories.admin.currency_add'), url(r'^currency/add/', 'directories.admin.currency_add'),
# ajax requests # ajax requests

@ -285,6 +285,7 @@ INSTALLED_APPS = (
'expobanner', 'expobanner',
'exposition', 'exposition',
'file', 'file',
'import_xls',
'news', 'news',
'note', 'note',
'organiser', 'organiser',

@ -79,6 +79,7 @@ urlpatterns = patterns('',
# ajax urls # ajax urls
urlpatterns += patterns('', urlpatterns += patterns('',
url(r'^ajax/get_popover/$', 'settings.views.get_popover_info'),
url(r'^registration/reply/$', 'registration.backends.default.views.RegisterReply'), url(r'^registration/reply/$', 'registration.backends.default.views.RegisterReply'),
url(r'^register/', 'registration.backends.default.views.RegisterAjaxView'), url(r'^register/', 'registration.backends.default.views.RegisterAjaxView'),
url(r'^register-complete/', 'registration.backends.default.views.complete_registration'), url(r'^register-complete/', 'registration.backends.default.views.complete_registration'),

@ -129,15 +129,15 @@ from exposition.models import Exposition
from conference.models import Conference from conference.models import Conference
class ServiceControlForm(forms.Form): class ServiceControlForm(forms.Form):
event = [{'verbose': 'Выставки', 'model': Exposition, 'id': 1}, event = [{'verbose': 'Выставки', 'model': Exposition, 'id': 1, 'service_bit': 'expo'},
{'verbose': 'Конференции', 'model': Conference, 'id': 2}] {'verbose': 'Конференции', 'model': Conference, 'id': 2, 'service_bit': 'conference'}]
region = forms.ChoiceField(required=False, label='Регион', region = forms.ChoiceField(required=False, label='Регион',
choices=[('', '')]+[(item.id, item.name) choices=[('', '')]+[(item.id, item.name)
for item in list(Area.objects.all())]) for item in list(Area.objects.all())])
country = forms.MultipleChoiceField(required=False, label='Страны', country = forms.MultipleChoiceField(required=False, label='Страны',
choices=[('', '')]+[(item.id, item.name) choices=[('', '')]+[(item.id, item.name)
for item in list(Country.objects.all())]) for item in list(Country.objects.all())])
country_all = forms.BooleanField() country_all = forms.BooleanField(required=False)
expositions = forms.CharField(label=u'Выставки', widget=forms.HiddenInput(), required=False) expositions = forms.CharField(label=u'Выставки', widget=forms.HiddenInput(), required=False)
conferences = forms.CharField(label=u'Конференции', widget=forms.HiddenInput(), required=False) conferences = forms.CharField(label=u'Конференции', widget=forms.HiddenInput(), required=False)
@ -145,5 +145,5 @@ class ServiceControlForm(forms.Form):
super(ServiceControlForm, self).__init__(*args, **kwargs) super(ServiceControlForm, self).__init__(*args, **kwargs)
self.fields['event_type'] = forms.MultipleChoiceField(required=False, label = 'Тип события', self.fields['event_type'] = forms.MultipleChoiceField(required=False, label = 'Тип события',
widget=forms.CheckboxSelectMultiple(), widget=forms.CheckboxSelectMultiple(),
choices=[(item['id'], item['verbose']) choices=[(item['service_bit'], item['verbose'])
for item in self.event]) for item in self.event])

@ -52,18 +52,56 @@ class Service(TranslatableModel):
uses for control form uses for control form
:return: :return:
""" """
state = {'event_type':[1, 2], from country.models import Country
'region': [], country_all = False
'country':[], country = []
'country_all': True, region = []
'expositions': [], expositions = []
'conferences': []} conferences = []
service = self.url
event_type = [key for key, value in self.type.iteritems() if value]
if not event_type:
return {'event_type': event_type,
'region': region,
'country': country,
'country_all': country_all,
'expositions': expositions,
'conferences': conferences}
count1 = Country.objects.filter().count()
count2 = Country.objects.filter(services=getattr(Country.services, service)).count()
country_all = count1 == count2
if not country_all:
from exposition.models import Exposition
from conference.models import Conference
from country.models import Area
from django.utils.translation import get_language
lang = get_language()
countries = list(Country.objects.language(lang).filter(services=getattr(Country.services, service)))
expositions = [(item.id, item.name) for item in Exposition.enable.upcoming().exclude(country__in=countries, services=getattr(Exposition.services, service))]
conferences = [(item.id, item.name) for item in Conference.enable.upcoming().exclude(country__in=countries, services=getattr(Conference.services, service))]
region = []
countries = set(countries)
for item in list(Area.objects.language(lang).all()):
print(item)
area_countries = item.countries()
if set(area_countries).issubset(countries):
region.append((item.id, item.name))
countries = countries - set(area_countries)
country = [(item.id, item.name) for item in list(countries)]
state = {'event_type': event_type,
'region': region,
'country': country,
'country_all': country_all,
'expositions': expositions,
'conferences': conferences}
return state return state
from django.db.models.signals import post_save from django.db.models.signals import post_save
from functions.signal_handlers import post_save_handler from functions.signal_handlers import post_save_handler
@ -118,6 +156,7 @@ class Translation(AbstractOrder):
languages = models.TextField(blank=True) languages = models.TextField(blank=True)
themes = models.TextField(blank=True) themes = models.TextField(blank=True)
class Visit(AbstractOrder): class Visit(AbstractOrder):
fr = models.DateField() fr = models.DateField()
to = models.DateField() to = models.DateField()

@ -160,6 +160,14 @@ def random_social(value):
def random3(value): def random3(value):
return random.randrange(0,3) return random.randrange(0,3)
@register.filter
def random4(value):
return random.randrange(0,4)
@register.filter
def random5(value):
return random.randrange(0,5)
@register.filter @register.filter
def fourth(value): def fourth(value):
# return almost in 75% cases True in 25% False # return almost in 75% cases True in 25% False

@ -10,6 +10,7 @@ from theme.models import Tag, Theme
from place_exposition.models import PlaceExposition from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference from place_conference.models import PlaceConference
from company.models import Company from company.models import Company
from conference.models import Conference
# every this model must have method get_subcategories # every this model must have method get_subcategories
categories = {'area':{'sub':True, 'model':Area, 'sub_categorie_name':'co'}, categories = {'area':{'sub':True, 'model':Area, 'sub_categorie_name':'co'},
@ -43,17 +44,20 @@ def search_autocomplete(request):
term = request.GET['term'] term = request.GET['term']
form = request.GET['form'] form = request.GET['form']
if form == 'place': if form == 'place':
areas = [{'text':item.name, 'id':item.id, 'name':'area'} for item in Area.objects.filter(translations__name__contains=term)] qs = list(SearchQuerySet().models(Country, City, Area).autocomplete(content_auto=term)[:6])
countries = [{'text':item.name, 'id':item.id, 'name':'co'} for item in Country.objects.select_related('exposition_country')\ objects = [{'text':get_by_lang(item, 'name', lang), 'id': item.pk, 'name': item.form_name} for item in qs]
.filter(exposition_country__country__isnull=False, translations__language_code=lang, translations__name__contains=term).distinct()] #areas = [{'text':item.name, 'id':item.id, 'name':'area'} for item in Area.objects.filter(translations__name__contains=term)]
cities = [{'text':item.name, 'id':item.id, 'name':'ci'} for item in City.objects.select_related('exposition_city')\
.filter(exposition_city__city__isnull=False, translations__language_code=lang, translations__name__contains=term).distinct()] #countries = [{'text':item.name, 'id':item.id, 'name':'co'} for item in Country.objects.select_related('exposition_country')\
# .filter(exposition_country__country__isnull=False, translations__language_code=lang, translations__name__contains=term).distinct()]
objects = areas + countries + cities #cities = [{'text':item.name, 'id':item.id, 'name':'ci'} for item in City.objects.select_related('exposition_city')\
return HttpResponse(json.dumps(objects), content_type='application/json') # .filter(exposition_city__city__isnull=False, translations__language_code=lang, translations__name__contains=term).distinct()]
#objects = areas + countries + cities
return HttpResponse(json.dumps(objects, indent=4), content_type='application/json')
if form == 'subj': if form == 'subj':
objects = [{'text': get_by_lang(item, 'name', lang), 'id':item.pk, 'name': item.form_name, 'cat': get_by_lang(item, 'parent', lang)} for item in SearchQuerySet().models(Theme, Tag).autocomplete(content_auto=term)] objects = [{'text': get_by_lang(item, 'name', lang), 'id':item.pk, 'name': item.form_name, 'cat': get_by_lang(item, 'parent', lang)} for item in SearchQuerySet().models(Theme, Tag).autocomplete(content_auto=term)]
return HttpResponse(json.dumps(objects), content_type='application/json') return HttpResponse(json.dumps(objects, indent=4), content_type='application/json')
else: else:
return HttpResponse("Don't implemented yet") return HttpResponse("Don't implemented yet")
@ -91,17 +95,20 @@ def expo_autosearch(request):
if request.GET: if request.GET:
lang = translation.get_language() lang = translation.get_language()
term = request.GET['term'] term = request.GET['term']
term = term.strip()
d = datetime.date.today() d = datetime.date.today()
expos = list(SearchQuerySet().models(Exposition).filter(data_end__gte=d).autocomplete(content_auto=term).order_by('data_begin','text')[:6]) expos = list(SearchQuerySet().models(Exposition).filter(data_end__gte=d).autocomplete(content_auto=term).order_by('data_begin','text')[:6])
themes = list(SearchQuerySet().models(Tag).autocomplete(content_auto=term).order_by('text')[:15]) confs = list(SearchQuerySet().models(Conference).filter(data_end__gte=d).autocomplete(content_auto=term).order_by('data_begin','text')[:6])
res = expos + themes tags = list(SearchQuerySet().models(Tag).autocomplete(content_auto=term).order_by('text')[:6])
themes = list(SearchQuerySet().models(Theme).autocomplete(content_auto=term).order_by('text')[:6])
res = expos + themes + tags + confs
result = [{'cat': get_by_lang(item, 'catalog_name', lang), result = [{'cat': get_by_lang(item, 'catalog_name', lang),
'text': '%s (%s)'%(get_by_lang(item, 'name', lang),get_by_lang(item, 'parent', lang)) if get_by_lang(item, 'parent', lang) else get_by_lang(item, 'name', lang), 'text': '%s (%s)'%(get_by_lang(item, 'name', lang),get_by_lang(item, 'parent', lang)) if get_by_lang(item, 'parent', lang) else get_by_lang(item, 'name', lang),
'url':item.url, 'url':item.url,
'id':item.pk, 'id':item.pk,
'name': item.form_name} for item in res] 'name': item.form_name} for item in res]
result = sorted(result, key=lambda x:x['cat'], reverse=True) result = sorted(result, key=lambda x:x['cat'], reverse=True)
return HttpResponse(json.dumps(result), content_type='application/json') return HttpResponse(json.dumps(result, indent=4), content_type='application/json')
else: else:
raise Http404 raise Http404
@ -124,4 +131,52 @@ def company_autosearch(request):
result = sorted(result, key=lambda x:x['cat']) result = sorted(result, key=lambda x:x['cat'])
return HttpResponse(json.dumps(result), content_type='application/json') return HttpResponse(json.dumps(result), content_type='application/json')
else: else:
raise Http404 raise Http404
#------------------------------------------------------
# POPOVERS
#------------------------------------------------------
import random
from django.shortcuts import render
from django.template.loader import render_to_string
def get_popover(request):
response = {'success': True}
theme_id = request.GET.get('theme_id')
themes = {'2': ['client/popups/auto_modal.html', 'client/popups/auto_banner.html'],
'32': ['client/popups/auto_modal.html', 'client/popups/auto_banner.html', 'client/popups/cemat_modal.html', 'client/popups/cemat_banner1.html', 'client/popups/cemat_banner2.html'],
'54': ['client/popups/cemat_modal.html', 'client/popups/cemat_banner1.html', 'client/popups/cemat_banner2.html'],
'26': ['client/popups/cemat_modal.html', 'client/popups/cemat_banner1.html', 'client/popups/cemat_banner2.html'],
'22': ['client/popups/cemat_modal.html', 'client/popups/cemat_banner1.html', 'client/popups/cemat_banner2.html'],
'15': ['client/popups/cemat_modal.html', 'client/popups/cemat_banner1.html', 'client/popups/cemat_banner2.html'],
'44': ['client/popups/cemat_modal.html', 'client/popups/cemat_banner1.html', 'client/popups/cemat_banner2.html'],
'30': ['client/popups/cemat_modal.html', 'client/popups/cemat_banner1.html', 'client/popups/cemat_banner2.html']}
popovers = themes.get(theme_id)
if not popovers:
popovers = ['fail']
response['success'] = False
popover = random.choice(popovers)
html = render_to_string(popover)
response['html'] = html
return HttpResponse(json.dumps(response), content_type='application/json')
from banners.models import Redirect
from django.db.models import F
import datetime
def set_cookie(response, key, value, days_expire = 7):
if days_expire is None:
max_age = 365 * 24 * 60 * 60 #one year
else:
max_age = days_expire * 24 * 60 * 60
expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age), "%a, %d-%b-%Y %H:%M:%S GMT")
response.set_cookie(key, value, max_age=max_age, expires=expires)
def get_popover_info(request):
id = request.GET.get('rdr')
if id:
Redirect.objects.filter(id=id).update(views = F('views') + 1)
response = HttpResponse('success')
set_cookie(response, 'popover_test1', '1')
return response

@ -112,13 +112,13 @@ function postStat(data, textStatus){
$(document).ready(function(){ $(document).ready(function(){
/*
$('#id_created').datetimepicker({ $('#id_created').datetimepicker({
todayHighlight: true, todayHighlight: true,
format : 'yyyy-mm-dd', format : 'yyyy-mm-dd',
minView:2 minView:2
}); });
*/
$('#photo_form').on('submit', function(e){ $('#photo_form').on('submit', function(e){
e.preventDefault(); e.preventDefault();
var url = $(this).attr('action'); var url = $(this).attr('action');

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

@ -31,6 +31,10 @@
<link href="{% static 'css/uploadify.css' %}" rel='stylesheet'> <link href="{% static 'css/uploadify.css' %}" rel='stylesheet'>
{# The fav icon #} {# The fav icon #}
<link rel="shortcut icon" href="img/favicon.ico"> <link rel="shortcut icon" href="img/favicon.ico">
{# datetimepicker #}
<link href="{% static 'js/datetimepicker/css/datetimepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datetimepicker/js/bootstrap-datetimepicker.js' %}"></script>
<script src="{% static 'custom_js/main.js' %}"></script>
{% block scripts %} {% block scripts %}
{% endblock %} {% endblock %}
@ -72,10 +76,7 @@
</div> </div>
</body> </body>
{# datetimepicker #}
<link href="{% static 'js/datetimepicker/css/datetimepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datetimepicker/js/bootstrap-datetimepicker.js' %}"></script>
<script src="{% static 'custom_js/main.js' %}"></script>
{% block bot_scripts %} {% block bot_scripts %}
{% endblock %} {% endblock %}
</html> </html>

@ -181,6 +181,14 @@
<span class="help-inline">{{ form.web_page.errors }}</span> <span class="help-inline">{{ form.web_page.errors }}</span>
</div> </div>
</div> </div>
{# organiser #}
<div class="control-group {% if form.org.errors %}error{% endif %}">
<label class="control-label">{{ form.org.label }}:</label>
<div class="controls">{{ form.org }}
<span class="help-inline">{{ form.org.errors }}</span>
</div>
</div>
{# link #} {# link #}
<div class="control-group {% if form.link.errors %}error{% endif %}"> <div class="control-group {% if form.link.errors %}error{% endif %}">
<label class="control-label">{{ form.link.label }}:</label> <label class="control-label">{{ form.link.label }}:</label>

@ -1,12 +1,19 @@
{% extends 'admin_list.html' %} {% extends 'admin_list.html' %}
{% load static %} {% load static %}
{% block scripts %}
<script src="{% static 'custom_js/event_switcher.js' %}"></script>
{% block styles %}
td a{
float:left;
margin: 0 10px 10px 0
}
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div class="box span8"> <div class="box span8">
@ -30,11 +37,16 @@
<div class="box-content"> <div class="box-content">
<table class="table table-hover"> <table class="table table-hover">
<col width="25%">
<col width="15%">
<col width="35%">
<col width="25%">
<thead> <thead>
<tr> <tr>
<th>Название</th> <th>Название</th>
<th>Дата начала</th> <th>Дата начала</th>
<th>&nbsp;</th> <th>&nbsp;</th>
<th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -42,30 +54,28 @@
<tr> <tr>
<td>{{ item.name }}</td> <td>{{ item.name }}</td>
<td>{{ item.data_begin }}</td> <td>{{ item.data_begin|date:"Y-m-d" }}</td>
<td><a class="btn-small btn-inverse copy" data-id="{{ item.id }}" href="#">Копировать</a><input id="copy_url_{{ item.id }}" type="text" placeholder="новый урл"></td>
<td> <td style="width: 200px; height:100px;">
<a class="btn-small btn-warning off" style="{% if item.is_published %}{% else %}display: none;{% endif %}" <a class="btn-small btn-warning off" style="{% if item.is_published %}{% else %}display: none;{% endif %}"
href="/admin/conference/switch/{{ item.url }}/off"> href="/admin/conference/switch/{{ item.url }}/off">
Отключить Отключить
</a> </a>
<a class="btn-small btn-success on" style="{% if item.is_published %}display: none;{% else %}{% endif %}" <a class="btn-small btn-success on" style="{% if item.is_published %}display: none;{% else %}{% endif %}"
href="/admin/conference/switch/{{ item.url }}/on"> href="/admin/conference/switch/{{ item.url }}/on">
Включить Включить
</a>
<a class="btn-small btn-info" href="/admin/conference/{{ item.url|lower }}">
Изменить
</a>
<a class="btn-small btn-inverse" target="_blank" href="{{ item.get_permanent_url }}">
на сайте
</a> </a>
</td> <a class="btn-small btn-danger" href="/admin/conference/delete/{{ item.url|lower }}">
Удалить
<td class="center sorting_1">
<a class="btn-small btn-info" href="/admin/conference/{{ item.url|lower }}">
Изменить
</a> </a>
</td> </td>
<td>
<a class="btn-small btn-danger" href="/admin/conference/delete/{{ item.url|lower }}">
Удалить
</a>
</td>
</tr> </tr>
@ -77,4 +87,33 @@
{# pagination #} {# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} {% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</div> </div>
<script>
$(function(){
$('.copy').on('click', function(e){
e.preventDefault();
var id = $(this).attr('data-id');
var copy_url = '#copy_url_'+id
var input_url = $(copy_url).val();
if(input_url == ''){
alert('Урл не должен быть пустым')
}
else{
url = '/admin/conference/copy/';
formData = {'id': id, url: input_url};
$.get(url, formData, function(data){
if(data['redirect']==''){
alert(data['msg'])
}
else{
window.location = data['redirect'];
}
})
}
});
})
</script>
{% endblock %} {% endblock %}

@ -22,23 +22,10 @@
{# selects #} {# selects #}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/> <link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<script src="{% static 'js/select/select2.js' %}"></script> <script src="{% static 'js/select/select2.js' %}"></script>
{# datepicker #}
<link href="{% static 'js/datepicker/css/datepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datepicker/js/bootstrap-datepicker.js' %}"></script>
<script src="{% static 'custom_js/formset_add.js' %}"></script> <script src="{% static 'custom_js/formset_add.js' %}"></script>
<!--
{# ajax #}
<script src="{% static 'custom_js/timetable_post.js' %}"></script>
<script src="{% static 'custom_js/place_city_ajax.js' %}"></script>
<script src="{% static 'custom_js/select_tag.js' %}"></script>
-->
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function(){ $(document).ready(function(){
$('#id_data_begin').datetimepicker({ $('#id_data_begin').datetimepicker({
@ -223,6 +210,13 @@
<span class="help-inline">{{ form.web_page.errors }}</span> <span class="help-inline">{{ form.web_page.errors }}</span>
</div> </div>
</div> </div>
{# organiser #}
<div class="control-group {% if form.org.errors %}error{% endif %}">
<label class="control-label">{{ form.org.label }}:</label>
<div class="controls">{{ form.org }}
<span class="help-inline">{{ form.org.errors }}</span>
</div>
</div>
{# products #} {# products #}
{% with field='products' form=form languages=languages %} {% with field='products' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %} {% include 'admin/forms/multilang.html' %}
@ -371,32 +365,6 @@
</div> </div>
</div> </div>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i>Участники</h2>
</div>
<div class="box-content">
{# organiser #}
<div class="control-group {% if form.organiser.errors %}error{% endif %}">
<label class="control-label">{{ form.organiser.label }}:</label>
<div class="controls">{{ form.organiser }}
<span class="help-inline">{{ form.organiser.errors }}</span>
</div>
</div>
{# company #}
<div class="control-group {% if form.company.errors %}error{% endif %}">
<label class="control-label">{{ form.company.label }}:</label>
<div class="controls">{{ form.company }}
<span class="help-inline">{{ form.company.errors }}</span>
</div>
</div>
</div>
</div>
<div class="box span8"> <div class="box span8">
<div class="box-header well"> <div class="box-header well">
<h2><i class="icon-pencil"></i>Деловая программа</h2> <h2><i class="icon-pencil"></i>Деловая программа</h2>

@ -34,21 +34,25 @@ td a{
<div class="box-content"> <div class="box-content">
<table class="table table-hover"> <table class="table table-hover">
<col width="25%">
<col width="15%">
<col width="35%">
<col width="25%">
<thead> <thead>
<tr> <tr>
<th>id</th>
<th>Название</th> <th>Название</th>
<th>Дата начала</th> <th>Дата начала</th>
<th>&nbsp;</th> <th>&nbsp;</th>
<th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for item in object_list %} {% for item in object_list %}
<tr> <tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td> <td>{{ item.name }}</td>
<td>{{ item.data_begin }}</td> <td>{{ item.data_begin|date:"Y-m-d" }}</td>
<td><a class="btn-small btn-inverse copy" data-id="{{ item.id }}" href="#">Копировать</a><input id="copy_url_{{ item.id }}" type="text" placeholder="новый урл"></td>
<td style="width: 200px; height:100px;"> <td style="width: 200px; height:100px;">
<a class="btn-small btn-warning off" style="{% if item.is_published %}{% else %}display: none;{% endif %}" <a class="btn-small btn-warning off" style="{% if item.is_published %}{% else %}display: none;{% endif %}"
href="/admin/exposition/switch/{{ item.url }}/off"> href="/admin/exposition/switch/{{ item.url }}/off">
@ -80,4 +84,33 @@ td a{
{# pagination #} {# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} {% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</div> </div>
{% endblock %}
<script>
$(function(){
$('.copy').on('click', function(e){
e.preventDefault();
var id = $(this).attr('data-id');
var copy_url = '#copy_url_'+id
var input_url = $(copy_url).val();
if(input_url == ''){
alert('Урл не должен быть пустым')
}
else{
url = '/admin/exposition/copy/';
formData = {'id': id, url: input_url};
$.get(url, formData, function(data){
if(data['redirect']==''){
alert(data['msg'])
}
else{
window.location = data['redirect'];
}
})
}
});
})
</script>
{% endblock %}

@ -0,0 +1,46 @@
{% extends 'base.html' %}
{% load static %}
{% block body %}
{% comment %}
Displays lists of all cities in the table
and creating buttons which can change each city
{% endcomment %}
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Логи импорта</h2>
</div>
<div class="box-content">
<table class="table table-hover">
<thead>
<tr>
<th>Время импорта</th>
<th>Робочий файл</th>
<th>Лог</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for item in object_list %}
<tr>
<td>{{ item.created|date:"Y-m-d H:m:s" }}</td>
<td><a href="/admin/log/work_file/{{ item.id }}/">скачать</a></td>
<td><a href="/admin/log/log/{{ item.id }}/">скачать</a></td>
<td class="center sorting_1">
<a class="btn btn-danger delete" href="/admin/import/log/delete/{{ item.id }}/">
<i class="icon-trash icon-white"></i> Удалить
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include 'admin/includes/admin_pagination.html' with page_obj=objects %}
</div>
{% endblock %}

@ -0,0 +1,15 @@
{% extends 'base.html' %}
{% block body %}
<form action="" method="post"> {% csrf_token %}
<div class="alert alert-danger">
<p>Вы действительно хотите удалить <b>{{ object }}</b>?</p>
</div>
<input type="submit" class="btn-primary" value="Да">
<a class="btn" href="/admin/import/log/">Нет</a>
</form>
{% endblock %}

@ -12,6 +12,7 @@
<li class="divider"></li> <li class="divider"></li>
<li><a href="/admin/import-event">Импорт</a></li> <li><a href="/admin/import-event">Импорт</a></li>
<li><a href="/admin/export-event">Экспорт</a></li> <li><a href="/admin/export-event">Экспорт</a></li>
<li><a href="/admin/import/log/">Архив логов</a></li>
</ul> </ul>
</li> </li>

@ -29,6 +29,14 @@
</div> </div>
</div> </div>
{# country_all #}
<div class="control-group {% if form.country_all.errors %}error{% endif %}">
<label class="control-label">{{ form.country_all.label }}:</label>
<div class="controls">{{ form.country_all }}
<span class="help-inline">{{ form.country_all.errors }}</span>
</div>
</div>
{# region #} {# region #}
<div class="control-group {% if form.region.errors %}error{% endif %}"> <div class="control-group {% if form.region.errors %}error{% endif %}">
<label class="control-label">{{ form.region.label }}:</label> <label class="control-label">{{ form.region.label }}:</label>

@ -1,6 +1,8 @@
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
{% load template_filters %}
{% get_current_language as LANGUAGE_CODE %} {% get_current_language as LANGUAGE_CODE %}
{% comment %} {% comment %}
This template include basic anf main styles and js files, This template include basic anf main styles and js files,
block with header and footer, which same in all pages, block with header and footer, which same in all pages,
@ -20,6 +22,8 @@ This template include basic anf main styles and js files,
<!--if IE 8><script src="js/selectivizr-min.js"></script><![endif]--> <!--if IE 8><script src="js/selectivizr-min.js"></script><![endif]-->
<head> <head>
{% include 'includes/meta.html' %} {% include 'includes/meta.html' %}
<meta name="cmsmagazine" content="ca270688603566278c9006a1511705b1" />
<meta name="ktoprodvinul" content="7bf9e596b7b6707a" />
<link rel="icon" href="{% static 'client/img/favicon.ico' %}" type="image/x-icon" /> <link rel="icon" href="{% static 'client/img/favicon.ico' %}" type="image/x-icon" />
<link rel="shortcut icon" href="{% static 'client/img/favicon.ico' %}" type="image/x-icon" /> <link rel="shortcut icon" href="{% static 'client/img/favicon.ico' %}" type="image/x-icon" />
@ -161,7 +165,7 @@ This template include basic anf main styles and js files,
{% include 'client/includes/footer.html' %} {% include 'client/includes/footer.html' %}
{% endblock %} {% endblock %}
</div> </div>
<div class="popups-wrap"> <div class="popups-wrap" id="main-popup-wrap">
{% if not user.is_authenticated %} {% if not user.is_authenticated %}
{% include 'client/popups/login.html' %} {% include 'client/popups/login.html' %}
{% include 'client/popups/register.html' %} {% include 'client/popups/register.html' %}
@ -170,7 +174,92 @@ This template include basic anf main styles and js files,
{% endif %} {% endif %}
{% include 'client/popups/callback.html' %} {% include 'client/popups/callback.html' %}
{% block popup_banner %}
{% if not request.COOKIES.popover_test1 %}
{% if theme_for_filter %}
{% if theme_for_filter.id == 2 %}
{% if False|random_social %}
{% include 'client/popups/auto_modal.html' %}
{% else %}
{% include 'client/popups/auto_banner.html' %}
{% endif %}
{% endif %}
{% if theme_for_filter.id == 54 or theme_for_filter.id == 26 or theme_for_filter.id == 22 or theme_for_filter.id == 15 or theme_for_filter.id == 44 or theme_for_filter.id == 30 %}
{% with r=False|random3 %}
{% if r == 1 %}
{% include 'client/popups/cemat_modal.html' %}
{% else %}
{% if r == 2 %}
{% include 'client/popups/cemat_banner1.html' %}
{% else %}
{% include 'client/popups/cemat_banner2.html' %}
{% endif %}
{% endif %}
{% endwith %}
{% endif %}
{% if theme_for_filter.id == 32 %}
{% with r=False|random5 %}
{% if r == 1 %}
{% include 'client/popups/auto_modal.html' %}
{% endif %}
{% if r == 2 %}
{% include 'client/popups/auto_banner.html' %}
{% endif %}
{% if r == 3 %}
{% include 'client/popups/cemat_modal.html' %}
{% endif %}
{% if r == 4 %}
{% include 'client/popups/cemat_banner1.html' %}
{% endif %}
{% if r == 0 %}
{% include 'client/popups/cemat_banner2.html' %}
{% endif %}
{% endwith %}
{% endif %}
<script>
$(function() {
if ($('#expo-ad-popup').length > 0){
$('#expo-form-popup').on('submit', function(e){
e.preventDefault();
var link = $('#expo-form-popup').attr('action');
window.location = link;
});
setTimeout(function(){
$.fancybox.open(
[{href: '#expo-ad-popup'}],
{}
);
var rdr = $('#expo-ad-popup').attr('data-rdr');
sendData = {'rdr': rdr};
console.log(rdr);
$.ajax({
url: '/ajax/get_popover/',
data: sendData,
type: 'GET',
async: true,
success: function(data){
console.log(data);
}
});
}, 5000);
}
});
</script>
{% endif %}
{% endif %}
{% endblock %}
{# if user doesnt have url- show form #} {# if user doesnt have url- show form #}
{% if not request.user.is_anonymous %} {% if not request.user.is_anonymous %}

@ -1,5 +1,6 @@
{% extends 'base_catalog.html' %} {% extends 'base_catalog.html' %}
{% load i18n %} {% load i18n %}
{% load template_filters %}
{% block bread_scrumbs %} {% block bread_scrumbs %}
<div class="bread-crumbs"> <div class="bread-crumbs">
@ -25,4 +26,87 @@
{% block paginator %} {% block paginator %}
{% endblock %} {% endblock %}
{% block popup%}
{% if not request.COOKIES.popover_test1 %}
{% with theme_ids=object.theme_ids %}
{% if 32 in theme_ids %}
{% with r=False|random5 %}
{% if r == 1 %}
{% include 'client/popups/auto_modal.html' %}
{% endif %}
{% if r == 2 %}
{% include 'client/popups/auto_banner.html' %}
{% endif %}
{% if r == 3 %}
{% include 'client/popups/cemat_modal.html' %}
{% endif %}
{% if r == 4 %}
{% include 'client/popups/cemat_banner1.html' %}
{% endif %}
{% if r == 5 %}
{% include 'client/popups/cemat_banner2.html' %}
{% endif %}
{% endwith %}
{% else %}
{% if 54 in theme_ids or 26 in theme_ids or 22 in theme_ids or 15 in theme_ids or 44 in theme_ids or 30 in theme_ids %}
{% with r=False|random3 %}
{% if r == 1 %}
{% include 'client/popups/cemat_modal.html' %}
{% else %}
{% if r == 2 %}
{% include 'client/popups/cemat_banner1.html' %}
{% else %}
{% include 'client/popups/cemat_banner2.html' %}
{% endif %}
{% endif %}
{% endwith %}
{% else %}
{% if 2 in theme_ids %}
{% if False|random_social %}
{% include 'client/popups/auto_modal.html' %}
{% else %}
{% include 'client/popups/auto_banner.html' %}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endwith %}
<script>
$(function() {
if ($('#expo-ad-popup').length > 0){
$('#expo-form-popup').on('submit', function(e){
e.preventDefault();
var link = $('#expo-form-popup').attr('action');
window.location = link;
});
setTimeout(function(){
$.fancybox.open(
[{href: '#expo-ad-popup'}],
{}
);
var rdr = $('#expo-ad-popup').attr('data-rdr');
sendData = {'rdr': rdr};
$.ajax({
url: '/ajax/get_popover/',
data: sendData,
type: 'GET',
async: true,
success: function(data){
console.log(data);
}
});
}, 5000);
}
});
</script>
{% endif %}
{% endblock %}

@ -2,23 +2,18 @@
{% load template_filters %} {% load template_filters %}
<div class="abn"> <div class="abn">
{% comment %} {% with r=False|random4 %}
{% if False|random3 == 1 %} {% ifequal r 0 %}
<a target="_blank" href="/redirect/redirect/31/"><img src="{% static 'client/img/partners/expomap-seminars-01.jpg' %}" alt="" /></a> <a target="_blank" href="/redirect/redirect/57/"><img src="{% static 'client/img/partners/cemat15_900x130_bilet.gif' %}" alt="" /></a>
{% else %} {% endifequal %}
{% if False|random3 == 2 %} {% ifequal r 1 %}
<a target="_blank" href="/redirect/redirect/32/"><img src="{% static 'client/img/partners/expomap-seminars-02.gif' %}" alt="" /></a> <a target="_blank" href="/redirect/redirect/58/"><img src="{% static 'client/img/partners/beach.png' %}" alt="" /></a>
{% else %} {% endifequal %}
<a target="_blank" href="/redirect/redirect/33/"><img src="{% static 'client/img/partners/expomap-seminars-03.gif' %}" alt="" /></a> {% ifequal r 2 %}
{% endif %} <a target="_blank" href="/redirect/redirect/59/"><img src="{% static 'client/img/partners/mims15_900x130_bilet.gif' %}" alt="" /></a>
{% endif %} {% endifequal %}
{% endcomment %} {% ifequal r 3 %}
<a target="_blank" href="/redirect/redirect/61/"><img src="{% static 'client/img/partners/IPSA_2015_web_900x130.gif' %}" alt="" /></a>
{% comment %} {% endifequal %}
{% if False|fourth %} {% endwith %}
<a target="_blank" href="/redirect/redirect/21/"><img src="{% static 'client/img/partners/unnamed.gif' %}" alt="" /></a>
{% else %}
<a target="_blank" href="/redirect/redirect/23/"><img src="{% static 'client/img/partners/unnamed_1.gif' %}" alt="" /></a>
{% endif %}
{% endcomment %}
</div> </div>

@ -58,6 +58,14 @@
<div class="map-canvas" id="map-canvas" data-coords="{{ event.place.address.lat|stringformat:'f' }},{{ event.place.address.lng|stringformat:'f' }}" ></div> <div class="map-canvas" id="map-canvas" data-coords="{{ event.place.address.lat|stringformat:'f' }},{{ event.place.address.lng|stringformat:'f' }}" ></div>
</div> </div>
</div> </div>
{% else %}
<div class="i-address">
<header>
<div class="address">
{{ event.country.name }}, {{ event.city.name }}{% if event.place_alt %} , {{ event.place_alt }}{% endif %}
</div>
</header>
</div>
{% endif %} {% endif %}
<hr /> <hr />
<div class="i-buttons clearfix"> <div class="i-buttons clearfix">
@ -154,21 +162,18 @@
</dd> </dd>
{% else %} {% else %}
{% if event.org %} {% if event.org %}
<dt>{% trans 'Организатор' %}:</dt>
<dd> {% for item in event.org_split %}
{{ event.org }} <dt>{% if forloop.counter == 1 %}{% trans 'Организатор' %}:{% endif %}</dt>
</dd>
<dd>
{{ item }}
</dd>
{% endfor %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if event.place_alt %}
{% if not event.place %}
<dt>{% trans 'Место проведения' %}:</dt>
<dd>
{{ event.place_alt }}
</dd>
{% endif %}
{% endif %}
{% if event.web_page %} {% if event.web_page %}
<dt>{% trans 'Веб-сайт' %}:</dt> <dt>{% trans 'Веб-сайт' %}:</dt>
<dd> <dd>

@ -19,7 +19,7 @@
<span class="visitors" title="Посетители">{{ exposition.visitors }}</span> <span class="visitors" title="Посетители">{{ exposition.visitors }}</span>
{% endif %} {% endif %}
{% if exposition.members %} {% if exposition.members %}
<span class="participants" title="Участники">{{ exposition.members }}</span> <span classlinkebreaksbr="participants" title="Участники">{{ exposition.members }}</span>
{% endif %} {% endif %}
</div> </div>
<div class="i-discount"> <div class="i-discount">
@ -59,6 +59,15 @@
<div class="map-canvas" id="map-canvas" data-coords="{{ exposition.place.address.lat|stringformat:'f' }},{{ exposition.place.address.lng|stringformat:'f' }}" ></div> <div class="map-canvas" id="map-canvas" data-coords="{{ exposition.place.address.lat|stringformat:'f' }},{{ exposition.place.address.lng|stringformat:'f' }}" ></div>
</div> </div>
</div> </div>
{% else %}
<div class="i-address">
<header>
<div class="address">
{{ exposition.country.name }}, {{ exposition.city.name }}{% if exposition.place_alt %} , {{ exposition.place_alt }}{% endif %}
</div>
</header>
</div>
{% endif %} {% endif %}
<hr /> <hr />
<div class="i-buttons clearfix"> <div class="i-buttons clearfix">
@ -159,21 +168,17 @@
</dd> </dd>
{% else %} {% else %}
{% if exposition.org %} {% if exposition.org %}
<dt>{% trans 'Организатор' %}:</dt> {% for item in exposition.org_split %}
<dd> <dt>{% if forloop.counter == 1 %}{% trans 'Организатор' %}:{% endif %}</dt>
{{ exposition.org }}
</dd> <dd>
{{ item }}
</dd>
{% endfor %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if exposition.place_alt %}
{% if not exposition.place %}
<dt>{% trans 'Место проведения' %}:</dt>
<dd>
{{ exposition.place_alt }}
</dd>
{% endif %}
{% endif %}
{% if exposition.web_page %} {% if exposition.web_page %}
<dt>{% trans 'Веб-сайт' %}:</dt> <dt>{% trans 'Веб-сайт' %}:</dt>
<dd> <dd>

@ -8,11 +8,7 @@
<li> <li>
<a href="{{ exposition.get_permanent_url }}service/translator/">{% trans 'Устный переводчик' %}</a> <a href="{{ exposition.get_permanent_url }}service/translator/">{% trans 'Устный переводчик' %}</a>
</li> </li>
{% if exposition.country_id not in sng_countries %}
<li>
<a href="{{ exposition.get_permanent_url }}service/visit/">{% trans 'Бизнес-тур "под ключ"' %}</a>
</li>
{% endif %}
<li> <li>
<a href="{{ exposition.get_permanent_url }}service/remote/">{% trans 'Заочное посещение' %}</a> <a href="{{ exposition.get_permanent_url }}service/remote/">{% trans 'Заочное посещение' %}</a>
</li> </li>

@ -7,7 +7,6 @@
{% comment %}<li><a href="/service/tickets/">{% trans 'Билеты на выставки' %}</a></li>{% endcomment %} {% comment %}<li><a href="/service/tickets/">{% trans 'Билеты на выставки' %}</a></li>{% endcomment %}
<li><a href="/service/remote/">{% trans 'Заочное посещение' %}</a></li> <li><a href="/service/remote/">{% trans 'Заочное посещение' %}</a></li>
<li><a href="/service/participation/">{% trans 'Участие в выставках' %}</a></li> <li><a href="/service/participation/">{% trans 'Участие в выставках' %}</a></li>
<li><a href="/service/visit/">{% trans 'Посещение выставки' %}</a></li>
</ul> </ul>
</nav> </nav>
</div> </div>

@ -0,0 +1,8 @@
<div id="expo-ad-popup" data-rdr="51" class="popup-window" style="width:800px;">
<header class="clearfix">
<div class="pw-title"></div>
</header>
<div class="pw-body clearfix">
<a href="/redirect/redirect/51/"><img src="/static/client/img/expo_b/mims15.gif"/></a>
</div>
</div>

@ -0,0 +1,23 @@
<div id="expo-ad-popup" data-rdr="52" class="popup-window" style="width:500px;">
<header class="clearfix">
<div class="pw-title">Вы планируете посещение MIMS Automechanika Moscow в Экспоцентре?</div>
</header>
<div class="pw-body clearfix">
<form id="expo-form-popup" class="pw-form simple-validate" action="/redirect/redirect/52/">
<div class="pwf-line">
С 24 по 27 августа 2015 г. в Экспоцентре будут представлены лучшие предложения производителей и поставщиков автозапчастей, оборудования и товаров для технического обслуживания автомобилей.
</div>
<div class="pwf-line">
<a href="/redirect/redirect/52/">
<img src="/static/client/img/expo_b/mims.png">
</a>
</div>
<button>Узнать подробнее</button>
</form>
</div>
</div>

@ -0,0 +1,8 @@
<div id="expo-ad-popup" data-rdr="49" class="popup-window" style="width:800px;">
<header class="clearfix">
<div class="pw-title"></div>
</header>
<div class="pw-body clearfix">
<a href="/redirect/redirect/49/"><img src="/static/client/img/expo_b/cemat15.gif"/></a>
</div>
</div>

@ -0,0 +1,8 @@
<div id="expo-ad-popup" data-rdr="50" class="popup-window" style="width:800px;">
<header class="clearfix">
<div class="pw-title"></div>
</header>
<div class="pw-body clearfix">
<a href="/redirect/redirect/50/"><img src="/static/client/img/expo_b/cemat15_v2.gif"/></a>
</div>
</div>

@ -0,0 +1,24 @@
<div id="expo-ad-popup" data-rdr="53" class="popup-window">
<header class="clearfix">
<div class="pw-title">Ваш логист пойдет на выставку CEMAT?</div>
</header>
<div class="pw-body clearfix">
<form id="expo-form-popup" class="pw-form simple-validate" action="/redirect/redirect/53/">
<div class="pwf-line">
С 22 по 25 сентября 2015 г. в Крокус Экспо производители складского оборудования и техники представят свои выгодные предложения.
</div>
<div class="pwf-line">
<a href="/redirect/redirect/53/">
<img src="/static/client/img/expo_b/cemat_modal1.png">
</a>
<a href="/redirect/redirect/53. /" style="margin-left: 10px;">
<img src="/static/client/img/expo_b/cemat_modal2.png">
</a>
</div>
<button >Узнать подробнее</button>
</form>
</div>
</div>

@ -1 +1 @@
{{ object.name }} {{ object.get_index_text }}

@ -13433,11 +13433,140 @@ hr + .rq-note {
.сallback-modal .required.err:before{ .сallback-modal .required.err:before{
margin-top: 2px; margin-top: 2px;
} }
/************************\
# subscribe modal window
\***********************/
.subscribe-modal{
width: 560px;
color: #000000;
}
.subscribe-modal .pw-form .pwf-field{
width: 340px;
}
.subscribe-modal .required.err:before{
margin-top: 2px;
}
.subscribe-modal .submit{
cursor: pointer;
}
.subscribe-modal .pw-title {
font-size: 26px;
font-weight: 300;
}
.subscribe-modal .sub-header{
margin-top: 0;
}
.subscribe-modal .submit-arrow{
display: inline-block;
margin-left: 20px;
}
.subscribe-modal header{
padding-bottom: 0;
}
.subscribe-modal .gray{
color: #8d807f;
}
.subscribe-modal .small{
font-size: .9em;
}
/************************\
# subscribe lessons modal window
\***********************/
.subscribe-modal.lessons .form-side{
float: left;
width: 60%;
position: relative;
z-index: 1;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding-left: 14px;
}
.subscribe-modal.lessons .image-side{
float: left;
width: 40%;
}
.subscribe-modal.lessons .image-side{
}
.subscribe-modal.lessons .image-side img{
position: absolute;
width: 233px;
margin-left: -42px;
margin-bottom: -19px;
z-index: 0;
}
.subscribe-modal.lessons .label-header{
font-size: 18px;
}
.subscribe-modal.lessons .label-header .small{
font-size: .8em;
}
.subscribe-modal.lessons .pw-form .pwf-field{
width: 214px;
}
.subscribe-modal.lessons .pw-form .submit{
height: 42px;
line-height: 42px;
width: 214px;
}
.subscribe-modal.lessons .submit-arrow {
position: absolute;
right: 0;
margin-right: -20px;
}
/************************\ /************************\
# add event page /organiser/add-event/ # invite logist modal window
\***********************/ \***********************/
.invite-modal{
width: 560px;
color: #000000;
}
.invite-modal .logos{
display: table;
margin-left: auto;
margin-right: auto;
margin-bottom: 26px;
}
.invite-modal .logos .item{
display: inline-block;
margin-left: 16px;
}
.invite-modal .logos .item:first-child{
margin-left: 0;
}
.invite-modal .label p{
margin: 0;
}
.invite-modal .pw-title{
font-size: 24px;
font-weight: 400;
line-height: 25px;
}
.invite-modal .button{
height: 42px;
line-height: 42px;
padding-top: 0;
padding-bottom: 0;
font-size: 15px;
width: 214px;
text-align: center;
}
.invite-modal .submit-arrow{
display: inline-block;
margin-left: 20px;
}
/************************\
# add event page /organiser/add-event/
\***********************/
.add-event-page .set-sect.not-active .form-wrap{ .add-event-page .set-sect.not-active .form-wrap{
display: none; display: none;
} }
@ -13457,7 +13586,6 @@ hr + .rq-note {
color: #d80000; color: #d80000;
} }
/************************\ /************************\
# completion of registration modal # completion of registration modal
# after registration form # after registration form

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -133,7 +133,7 @@ class Theme(TranslatableModel):
parent = {} parent = {}
return parent return parent
from django.db import IntegrityError
class Tag(TranslatableModel): class Tag(TranslatableModel):
""" """
Create Tag model Create Tag model
@ -167,6 +167,15 @@ class Tag(TranslatableModel):
#created = models.DateTimeField(auto_now_add=True) #created = models.DateTimeField(auto_now_add=True)
#modified = models.DateTimeField(auto_now=True) #modified = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
try:
super(Tag, self).save(*args, **kwargs)
except IntegrityError:
theme = self.theme
self.url = '%s_%s'%(theme.url, self.url)
super(Tag, self).save(*args, **kwargs)
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk)) return self.lazy_translation_getter('name', unicode(self.pk))

@ -170,4 +170,4 @@ class TagIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
def index_queryset(self, using=None): def index_queryset(self, using=None):
#return self.get_model().active.all() #return self.get_model().active.all()
return self.get_model().objects.filter() return self.get_model().active.all()
Loading…
Cancel
Save