resolved some conflicts while merging

remotes/origin/1203
Ivan 11 years ago
commit da15bf65a4
  1. 2
      .gitignore
  2. 5
      accounts/models.py
  3. 2
      banners/models.py
  4. 4
      city/admin.py
  5. 19
      city/forms.py
  6. 8
      city/models.py
  7. 34
      city/search_indexes.py
  8. 30
      conference/admin.py
  9. 2
      conference/admin_urls.py
  10. 19
      conference/forms.py
  11. 11
      conference/models.py
  12. 10
      conference/search_indexes.py
  13. 2
      conference/urls.py
  14. 8
      conference/views.py
  15. 14
      core/simple_views.py
  16. 7
      country/admin.py
  17. 8
      country/forms.py
  18. 7
      country/manager.py
  19. 18
      country/models.py
  20. 62
      country/search_indexes.py
  21. 0
      expobanner/__init__.py
  22. 74
      expobanner/admin.py
  23. 21
      expobanner/admin_urls.py
  24. 76
      expobanner/forms.py
  25. 32
      expobanner/managers.py
  26. 236
      expobanner/models.py
  27. 159
      expobanner/static/banners/css/slider.css
  28. 10
      expobanner/static/banners/js/log.js
  29. 71
      expobanner/static/banners/js/slider.js
  30. 55
      expobanner/templates/banner.html
  31. 32
      expobanner/templates/grid.html
  32. 30
      expobanner/templates/group.html
  33. 74
      expobanner/templates/slider.html
  34. 0
      expobanner/templatetags/__init__.py
  35. 74
      expobanner/templatetags/banner.py
  36. 16
      expobanner/tests.py
  37. 11
      expobanner/urls.py
  38. 46
      expobanner/views.py
  39. 11
      exposition/admin.py
  40. 1
      exposition/admin_urls.py
  41. 15
      exposition/forms.py
  42. 137
      exposition/management/commands/test.py
  43. 4
      exposition/models.py
  44. 10
      exposition/search_indexes.py
  45. 1
      exposition/urls.py
  46. 15
      exposition/views.py
  47. 9
      functions/form_check.py
  48. 48
      functions/model_mixin.py
  49. 2
      functions/search_forms.py
  50. 51
      import_xls/admin.py
  51. 10
      import_xls/admin_urls.py
  52. 19
      import_xls/excel_settings.py
  53. 164
      import_xls/import_forms.py
  54. 77
      import_xls/models.py
  55. 33
      import_xls/utils.py
  56. 3
      proj/admin_urls.py
  57. 2
      proj/settings.py
  58. 9
      proj/urls.py
  59. 6
      proj/views.py
  60. 28
      service/admin.py
  61. 5
      service/admin_urls.py
  62. 25
      service/forms.py
  63. 58
      service/models.py
  64. 2
      settings/management/commands/do_inflect.py
  65. 26
      settings/templatetags/template_filters.py
  66. 88
      settings/views.py
  67. 47
      static/custom_js/find_events.js
  68. 18
      static/custom_js/main.js
  69. BIN
      static/img/expob/cemat15.gif
  70. BIN
      static/img/expob/cemat15_v2.gif
  71. BIN
      static/img/expob/mims15.gif
  72. 6
      templates/admin/base.html
  73. 9
      templates/admin/city/city_add.html
  74. 8
      templates/admin/conference/conference.html
  75. 71
      templates/admin/conference/conference_list.html
  76. 7
      templates/admin/country/country_add.html
  77. 33
      templates/admin/expobanner/banners_control.html
  78. 59
      templates/admin/expobanner/default_form.html
  79. 34
      templates/admin/expobanner/default_list.html
  80. 49
      templates/admin/exposition/exposition.html
  81. 39
      templates/admin/exposition/exposition_list.html
  82. 46
      templates/admin/import templates/log.html
  83. 15
      templates/admin/import templates/log_delete.html
  84. 8
      templates/admin/includes/admin_nav.html
  85. 78
      templates/admin/service/control.html
  86. 39
      templates/admin/service/control_list.html
  87. 45
      templates/admin/settings/main_page.html
  88. 133
      templates/admin/translator/translator.html
  89. 7
      templates/admin/translator/translator_all.html
  90. 7
      templates/admin/translator/translator_list.html
  91. 108
      templates/client/accounts/translators/translator_city.html
  92. 137
      templates/client/accounts/translators/translator_country.html
  93. 59
      templates/client/accounts/translators/translator_profile.html
  94. 33
      templates/client/accounts/translators/translators_by.html
  95. 105
      templates/client/blank.html
  96. 84
      templates/client/exposition/exposition_detail.html
  97. 20
      templates/client/includes/banners/under_search.html
  98. 21
      templates/client/includes/conference/conference_object.html
  99. 24
      templates/client/includes/exposition/exposition_object.html
  100. 6
      templates/client/includes/exposition/exposition_services.html
  101. Some files were not shown because too many files have changed in this diff Show More

2
.gitignore vendored

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

@ -205,6 +205,11 @@ class User(AbstractBaseUser, PermissionsMixin):
return '/%d/'%self.id return '/%d/'%self.id
#return self.catalog+str(self.id)+'/' #return self.catalog+str(self.id)+'/'
def get_translator_url(self):
if self.url:
return '/translators/%s/'%self.url
return '/translators/%d/'%self.id
def get_expos(self): def get_expos(self):
""" """
return information about expos and them related data by 1 query return information about expos and them related data by 1 query

@ -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

@ -49,14 +49,14 @@ def city_change(request, url):
return HttpResponseRedirect('/admin/city/all') return HttpResponseRedirect('/admin/city/all')
if request.POST: if request.POST:
form = CityForm(request.POST) form = CityForm(request.POST, request.FILES)
if form.is_valid(): if form.is_valid():
form.save(city_id) form.save(city_id)
return HttpResponseRedirect('/admin/city/all') return HttpResponseRedirect('/admin/city/all')
else: else:
#fill form with data from database #fill form with data from database
data = {'population' : c.population, 'phone_code' : c.phone_code, data = {'population' : c.population, 'phone_code' : c.phone_code,
'city_id' : city_id, 'inflect':c.inflect} 'city_id' : city_id, 'inflect':c.inflect, 'logo': c.logo}
if c.country: if c.country:
data['country'] = c.country.id data['country'] = c.country.id

@ -34,6 +34,7 @@ class CityForm(forms.Form):
widget=forms.TextInput(attrs={'placeholder':'Код города'})) widget=forms.TextInput(attrs={'placeholder':'Код города'}))
code_IATA = forms.ModelChoiceField(label='Код IATA', queryset=Iata.objects.all(), empty_label=None, required=False) code_IATA = forms.ModelChoiceField(label='Код IATA', queryset=Iata.objects.all(), empty_label=None, required=False)
inflect = forms.CharField(label='Inflect', required=False) inflect = forms.CharField(label='Inflect', required=False)
logo = forms.ImageField(label='Logo', required=False)
#field for comparing tmp files #field for comparing tmp files
key = forms.CharField(required=False, widget=forms.HiddenInput()) key = forms.CharField(required=False, widget=forms.HiddenInput())
# #
@ -91,6 +92,11 @@ class CityForm(forms.Form):
city.population = data.get('population') city.population = data.get('population')
city.inflect = data['inflect'] city.inflect = data['inflect']
if data.get('logo'):
city.logo = data['logo']
else:
city.logo = ''
if data.get('code_IATA'): if data.get('code_IATA'):
city.code_IATA = Iata.objects.get(id=data['code_IATA'].id)# .id cause select uses queryset city.code_IATA = Iata.objects.get(id=data['code_IATA'].id)# .id cause select uses queryset
@ -161,4 +167,17 @@ class CityDeleteForm(forms.ModelForm):
class CityFilterForm(AdminFilterForm): class CityFilterForm(AdminFilterForm):
country = forms.ChoiceField(choices=[('', '')]+[(item.id, item.name) for item in Country.objects.all()], required=False,
label='Страна')
model = City model = City
def filter(self):
qs = super(CityFilterForm, self).filter()
data = self.cleaned_data
country_id = data['country']
if country_id:
qs = qs.filter(country__id=country_id)
return qs

@ -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
@ -62,6 +63,7 @@ class City(TranslatableModel):
# fields saves information about creating and changing model # fields saves information about creating and changing model
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)
logo = models.ImageField(verbose_name='Logo', upload_to='city/logo/', blank=True, max_length=255)
class Meta: class Meta:
ordering = ['translations__name'] ordering = ['translations__name']
@ -115,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:
@ -296,3 +296,31 @@ class ConferenceListView(AdminListView):
def upload_conference_photo(request, conf_id): def upload_conference_photo(request, conf_id):
return upload_photo(request, conf_id, Conference) return upload_photo(request, conf_id, Conference)
from django.utils import translation
from haystack.query import SearchQuerySet
import json
from exposition.admin import get_by_lang
def search_conf(request):
term = request.GET['term'].capitalize()
lang = translation.get_language()
if not term:
qs = SearchQuerySet().models(Conference).order_by('text')[:30]
else:
qs = SearchQuerySet().models(Conference).autocomplete(content_auto=term).order_by('text')[:30]
result = [{'id': item.pk, 'label': get_by_lang(item, 'name', lang)} for item in qs]
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,10 +5,12 @@ 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'),
url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'conference_switch'), url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'conference_switch'),
url(r'^search/$', 'search_conf'),
url(r'^(?P<url>.*)/$', ConferenceView.as_view()), url(r'^(?P<url>.*)/$', ConferenceView.as_view()),
url(r'^$', ConferenceView.as_view()), url(r'^$', ConferenceView.as_view()),

@ -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']
@ -375,4 +376,16 @@ class TimeTableForm(forms.Form):
class ConferenceFilterForm(AdminFilterForm): class ConferenceFilterForm(AdminFilterForm):
created = forms.DateField(required=False, label='Дата создания')
model = Conference model = Conference
def filter(self):
qs = super(ConferenceFilterForm, self).filter()
data = self.cleaned_data
created = data['created']
if created:
qs = qs.filter(created__startswith=created)
return qs

@ -5,6 +5,7 @@ from django.db import models
from django.db.models import Q from django.db.models import Q
from django.db.models.signals import post_save, pre_save from django.db.models.signals import post_save, pre_save
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from django.utils import translation
from exposition.manager import ClientManager from exposition.manager import ClientManager
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from functions.translate import fill_with_signal from functions.translate import fill_with_signal
@ -53,6 +54,7 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
related_name='conference_city') related_name='conference_city')
place = models.ForeignKey('place_conference.PlaceConference', verbose_name='Место проведения', place = models.ForeignKey('place_conference.PlaceConference', verbose_name='Место проведения',
blank=True, null=True, on_delete=models.PROTECT, related_name='conference_place') blank=True, null=True, on_delete=models.PROTECT, related_name='conference_place')
place_alt = models.CharField(blank=True, null=True, max_length=255) # alternative for object place
theme = models.ManyToManyField('theme.Theme', verbose_name='Тематики', theme = models.ManyToManyField('theme.Theme', verbose_name='Тематики',
related_name='conference_themes') related_name='conference_themes')
tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', tag = models.ManyToManyField('theme.Tag', verbose_name='Теги',
@ -171,6 +173,15 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
def tags(self): def tags(self):
return self.tag.language().all() return self.tag.language().all()
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
titles = ' '.join([tr.main_title for tr in translations])
themes = ' '.join([' '.join(theme.get_all_names()) for theme in self.theme.all()])
tags = ' '.join([' '.join(tag.get_all_names()) for tag in self.tag.all()])
return names + ' ' + titles + ' ' + themes + ' ' + tags
def get_gallery(self): def get_gallery(self):
if self.photogallery: if self.photogallery:
return self.photogallery return self.photogallery

@ -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'

@ -13,26 +13,32 @@ class SeminarLendingView(TemplateView):
def send_to_organiser(request): def send_to_organiser(request):
mail_send = 'kotzilla@ukr.net' mail_send = 'expomap@mail.ru'
fname = request.POST.get('name') fname = request.POST.get('name')
lname = request.POST.get('surname') lname = request.POST.get('surname')
email = request.POST.get('email', '') email = request.POST.get('email', '')
company = request.POST.get('company', '') company = request.POST.get('company', '')
office = request.POST.get('office', '') office = request.POST.get('office', '')
phone = request.POST.get('phone', '')
title = request.POST.get('type', '') title = request.POST.get('type', '')
text = u"""Имя: %s; text = u"""Имя: %s;
Фамилия:%s; Фамилия:%s;
Email: %s; Email: %s;
Телефон: %s;
компния:%s; компния:%s;
должность: %s"""%(fname, lname, email, company, office) должность: %s"""%(fname, lname, email, phone, company, office)
msg = EmailMessage(title, text, settings.DEFAULT_FROM_EMAIL, [mail_send]) msg = EmailMessage(title, text, settings.DEFAULT_FROM_EMAIL, [mail_send])
msg.content_subtype = "html" msg.content_subtype = "html"
msg.send() msg.send()
redirect_to = '/service/thanks/' redirect_to = '/service/thanks/'
message = u"""Мы получили Ваш запрос и очень рады, что Вам интересно участие в семинаре Expomap. Если места еще есть, мы пришлем Вам приглашение на указанную Вами электронную почту. if title.endswith(u'семинар'):
Увидимся на welcome-coffee """ message = u"""Мы получили Ваш запрос и очень рады, что Вам интересно участие в семинаре Expomap. Если места еще есть, мы пришлем Вам приглашение на указанную Вами электронную почту.
Увидимся на welcome-coffee """
else:
message = u"""Благодарим за интерес к нашему семинару! За несколько дней до мероприятия мы пришлем Вам ссылку для подключения к онлайн-трансляции!"""
return HttpResponse(json.dumps({'success':True, 'redirect_to': redirect_to, 'message': message}), content_type='application/json') return HttpResponse(json.dumps({'success':True, 'redirect_to': redirect_to, 'message': message}), content_type='application/json')

@ -63,7 +63,7 @@ def country_change(request, url):
if request.POST: if request.POST:
#country_id sending for saving capital field in __init__ #country_id sending for saving capital field in __init__
form = CountryForm(request.POST, country_id=country_id) form = CountryForm(request.POST, request.FILES, country_id=country_id)
if form.is_valid(): if form.is_valid():
form.save(country_id) form.save(country_id)
@ -71,8 +71,9 @@ def country_change(request, url):
else: else:
#fill form with data from database #fill form with data from database
data = {'population' : c.population, 'teritory' : c.teritory, #data from NOT translated fields data = {'population' : c.population, 'teritory' : c.teritory, #data from NOT translated fields
'timezone' : c.timezone, 'country_id' : country_id, 'timezone' : c.timezone, 'country_id' : country_id,
'phone_code' : c.phone_code, 'time_delivery' : c.time_delivery} 'phone_code' : c.phone_code, 'time_delivery' : c.time_delivery,
'logo': c.logo}
if c.capital: if c.capital:
data['capital'] = c.capital.id data['capital'] = c.capital.id

@ -55,6 +55,8 @@ class CountryForm(forms.Form):
time_delivery = forms.CharField(label='Срок выдачи', required=False, time_delivery = forms.CharField(label='Срок выдачи', required=False,
widget=forms.TextInput(attrs={'placeholder':'Срок выдачи'})) widget=forms.TextInput(attrs={'placeholder':'Срок выдачи'}))
logo = forms.ImageField(label='Logo', required=False)
#services = forms.MultipleChoiceField(label='Сервисы', required=False, choices=); #services = forms.MultipleChoiceField(label='Сервисы', required=False, choices=);
#field for comparing tmp files #field for comparing tmp files
key = forms.CharField(required=False, widget=forms.HiddenInput()) key = forms.CharField(required=False, widget=forms.HiddenInput())
@ -136,6 +138,12 @@ class CountryForm(forms.Form):
country.phone_code = data['phone_code'] country.phone_code = data['phone_code']
country.time_delivery = data['time_delivery'] country.time_delivery = data['time_delivery']
if data.get('logo'):
country.logo = data['logo']
else:
country.logo = ''
if data.get('capital'): if data.get('capital'):
country.capital = City.objects.get(id=data['capital']) country.capital = City.objects.get(id=data['capital'])

@ -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):
""" """
@ -102,6 +108,7 @@ class Country(TranslatableModel):
descriptions = models.CharField(max_length=255), descriptions = models.CharField(max_length=255),
keywords = models.CharField(max_length=255), keywords = models.CharField(max_length=255),
) )
logo = models.ImageField(verbose_name='Logo', upload_to='country/logo/', blank=True, max_length=255)
class Meta: class Meta:
ordering = ['translations__name'] ordering = ['translations__name']
@ -145,8 +152,9 @@ class Country(TranslatableModel):
return Webinar.objects.filter(country=self.id).count() return Webinar.objects.filter(country=self.id).count()
def active_cities(self): def active_cities(self):
result = list(set(City.used.active_qs().filter(country=self)))
return City.used.active_qs().filter(country=self) result.sort(key=lambda x:x.name)
return result
lang = translation.get_language() lang = translation.get_language()
#return City.objects.select_related('exposition_city')\ #return City.objects.select_related('exposition_city')\
# .filter(exposition_city__city__isnull=False, translations__language_code=lang, country=self).distinct().order_by('translations__name') # .filter(exposition_city__city__isnull=False, translations__language_code=lang, country=self).distinct().order_by('translations__name')
@ -159,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()

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
from django.views.generic import TemplateView, CreateView, ListView, UpdateView
from django.conf import settings
from expobanner.models import URL, BannerGroup, Banner
from expobanner.forms import UrlCreateForm, BannerCreateGroupForm, BannerCreateForm, BannerGroupUpdateForm
class BannersControl(TemplateView):
template_name = 'admin/expobanner/banners_control.html'
# CREATE VIEWS
class AbstractCreate(CreateView):
template_name = 'admin/expobanner/default_form.html'
success_url = '/admin/expobanners/banners/control/'
class CreateUrl(AbstractCreate):
model = URL
form_class = UrlCreateForm
class CreateBannerGroup(AbstractCreate):
model = BannerGroup
form_class = BannerCreateGroupForm
class CreateBanner(AbstractCreate):
model = Banner
form_class = BannerCreateForm
# LISTS VIEWS
class AbstractList(ListView):
paginate_by = settings.ADMIN_PAGINATION
template_name = 'admin/expobanner/default_list.html'
def get_context_data(self, **kwargs):
context = super(AbstractList, self).get_context_data(**kwargs)
context['verbose'] = self.verbose
return context
class UrlList(AbstractList):
model = URL
verbose = u'Список урлов'
class BannerGroupList(AbstractList):
model = BannerGroup
verbose = u'Список груп'
class BannerList(AbstractList):
model = Banner
verbose = u'Список банеров'
# UPDATE VIEWS
class AbstractUpdate(UpdateView):
template_name = 'admin/expobanner/default_form.html'
success_url = '/admin/expobanners/banners/control/'
class UrlUpdate(AbstractUpdate):
model = URL
form_class = UrlCreateForm
class BannerGroupUpdate(AbstractUpdate):
model = BannerGroup
form_class = BannerGroupUpdateForm
class BannerUpdate(AbstractUpdate):
model = Banner
form_class = BannerCreateForm

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from expobanner.admin import *
urlpatterns = patterns('expobanner.admin',
url(r'^banners/control/$', BannersControl.as_view(), name='expobanner-baneers_control'),
url(r'^banners/url/$', CreateUrl.as_view(), name='expobanner-create_url'),
url(r'^banners/group/$', CreateBannerGroup.as_view(), name='expobanner-create_group'),
url(r'^banners/banner/$', CreateBanner.as_view(), name='expobanner-create_banner'),
url(r'^banners/url/list/$', UrlList.as_view(), name='expobanner-list_url'),
url(r'^banners/group/list/$', BannerGroupList.as_view(), name='expobanner-list_group'),
url(r'^banners/banner/list/$', BannerList.as_view(), name='expobanner-list_banner'),
url(r'^banners/url/(?P<pk>\d+)/edit/$', UrlUpdate.as_view(), name='expobanner-update_url'),
url(r'^banners/group/(?P<pk>\d+)/edit/$', BannerGroupUpdate.as_view(), name='expobanner-update_group'),
url(r'^banners/banner/(?P<pk>\d+)/edit/$', BannerUpdate.as_view(), name='expobanner-update_banner'),
)

@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
from django import forms
from expobanner.models import URL, BannerGroup, Banner
from country.models import Country
from city.models import City
from theme.models import Theme, Tag
class UrlCreateForm(forms.ModelForm):
verbose = u'Создать урл'
class Meta:
model = URL
exclude = ['created_at', 'updated_at', 'sites']
class BannerCreateGroupForm(forms.ModelForm):
verbose = u'Создать групу'
class Meta:
model = BannerGroup
exclude = ['created_at', 'updated_at', 'speed']
class BannerGroupUpdateForm(BannerCreateGroupForm):
verbose = u'Изменить групу'
class Meta:
model = BannerGroup
exclude = ['created_at', 'updated_at', 'slug', 'speed']
class BannerCreateForm(forms.ModelForm):
verbose = u'Создать банер'
country = forms.ChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False)
theme = forms.ChoiceField(label=u'Тематика', required=False,
choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()])
city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False)
tag = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False)
class Meta:
model = Banner
exclude = ['created_at', 'updated_at', 'often', 'paid']
def clean_theme(self):
theme = self.cleaned_data['theme']
if not theme:
return None
try:
return Theme.objects.filter(id=theme)
except Theme.DoesNotExist:
return None
def clean_country(self):
country = self.cleaned_data['country']
if not country:
return None
try:
return Country.objects.get(id=country)
except Country.DoesNotExist:
return None
def clean_tag(self):
tag = self.cleaned_data['tag']
if not tag:
return None
try:
return Tag.objects.get(id=tag)
except Tag.DoesNotExist:
return None
def clean_city(self):
city = self.cleaned_data['city']
if not city:
return None
try:
return City.objects.get(id=city)
except City.DoesNotExist:
return None

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*
from random import choice, shuffle
from django.db import models
from django.core.cache import cache
class BiasedManager(models.Manager):
def by_time(self, **kwargs):
all = super(BiasedManager, self).get_query_set().filter(**kwargs)
result = []
for i in all:
for j in range(i.often):
result.append(i)
return result
def one(self, **kwargs):
return choice(self.by_time(**kwargs))
def by_often(self, **kwargs):
result = self.by_time(**kwargs)
shuffle(result)
return result
class BannerGroupCached(models.Manager):
def all(self):
key = 'banner_group_all'
result = cache.get(key)
if not result:
result = list(self.filter())
cache.set(key, result, 90)
return result

@ -0,0 +1,236 @@
# -*- coding: utf-8 -*-
import hashlib
from datetime import datetime, date
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.contrib.sites.models import Site
from .managers import BiasedManager, BannerGroupCached
class URL(models.Model):
title = models.CharField(verbose_name=u'Заголовок', max_length=256)
url = models.CharField(verbose_name=u'URL or URL RegEx', max_length=2048)
regex = models.BooleanField(verbose_name=u'RegEx', default=False)
sites = models.ManyToManyField(Site, related_name='site_urls', verbose_name=_('Sites'), null=True, blank=True)
public = models.BooleanField(verbose_name=u'Активный', default=True)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['-created_at']
verbose_name = _('URL')
verbose_name_plural = _('URLs')
def get_admin_url(self):
return '/admin/expobanners/banners/url/%d/edit/'%self.id
class BannerGroup (models.Model):
name = models.CharField(verbose_name=u'Имя', max_length=255)
slug = models.SlugField(verbose_name=u'URL', unique=True)
width = models.PositiveSmallIntegerField(verbose_name=u'Ширина', default=0)
height = models.PositiveSmallIntegerField(verbose_name=u'Высота', default=0)
speed = models.PositiveSmallIntegerField(verbose_name=u'Скорость отображения', default=2000)
public = models.BooleanField(verbose_name=u'Активная', default=True)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
cached = BannerGroupCached()
def size(self):
return '%sx%s' % (self.width, self.height)
def __unicode__(self):
return '%s - [%s x %s]' % (self.name, self.width, self.height)
class Meta:
ordering = ['name']
verbose_name = _('Banner Group')
verbose_name_plural = _('Banner Groups')
def get_admin_url(self):
return '/admin/expobanners/banners/group/%d/edit/'%self.id
class Banner(models.Model):
objects = BiasedManager()
title = models.CharField(verbose_name=u'Заголовок', max_length=255, blank=True)
alt = models.CharField(verbose_name=_('Alt'), max_length=255)
text = models.TextField(verbose_name=u'Текст', blank=True, null=True)
img = models.FileField(verbose_name=u'Картинка', upload_to='expo_upload', blank=True, null=True)
url = models.CharField(verbose_name=u'URL', max_length=1024)
sort = models.PositiveSmallIntegerField(verbose_name=u'Сорт', default=500)
group = models.ForeignKey(BannerGroup, related_name='banners', verbose_name=u'Место', null=True, blank=True)
often = models.PositiveSmallIntegerField(
verbose_name=_('Often'),
help_text=_('A ten will display 10 times more often that a one.'),
choices=[[i, i] for i in range(11)]
)
urls = models.ManyToManyField(URL, related_name='url_banners', verbose_name=_('URLs'), null=True, blank=True)
html = models.BooleanField(verbose_name=_('HTML?'), default=False)
flash = models.BooleanField(verbose_name=_('Flash?'), default=False)
paid = models.BooleanField(verbose_name=_('Is Paid event link?'), default=False)
public = models.BooleanField(verbose_name=u'Активный', default=True)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
theme = models.ForeignKey('theme.Theme', blank=True, null=True, verbose_name=u'Тематика')
tag = models.ForeignKey('theme.Tag', blank=True, null=True, verbose_name=u'Тег')
country = models.ForeignKey('country.Country', blank=True, null=True, verbose_name=u'Страна')
city = models.ForeignKey('city.City', blank=True, null=True, verbose_name=u'Город')
def get_admin_url(self):
return '/admin/expobanners/banners/banner/%d/edit/'%self.id
def key(slef):
if hasattr(settings, 'SECRET_KEY'):
key = str(datetime.now()) + settings.SECRET_KEY
else:
key = str(datetime.now())
return hashlib.md5(key).hexdigest()
def log(self, request, type, key):
log = {
'type': type,
'key': key,
'banner': self,
'group': self.group,
'ip': request.META.get('REMOTE_ADDR'),
'user_agent': request.META.get('HTTP_USER_AGENT'),
'page': request.META.get('HTTP_REFERER'),
}
if request.user.is_authenticated():
log['user'] = request.user
return Log.objects.create(**log)
@models.permalink
def image(self):
return ('banner_view', (), {'banner_id': self.pk, 'key': self.key()})
def impressions(self):
return Log.objects.filter(banner=self.pk, type=0).count()
def views(self):
return Log.objects.filter(banner=self.pk, type=1).count()
def clicks(self):
return Log.objects.filter(banner=self.pk, type=2).count()
def __unicode__(self):
return self.title or self.alt
def get_absolute_url(self):
if self.url == '#':
return self.url
else:
@models.permalink
def get_absolute_url(self):
return ('banner_click', (), {'banner_id': self.pk, 'key': self.key()})
return get_absolute_url(self)
class Meta:
ordering = ['sort']
verbose_name = _('Banner')
verbose_name_plural = _('Banners')
class Log(models.Model):
banner = models.ForeignKey(Banner, related_name='banner_logs')
group = models.ForeignKey(BannerGroup, related_name='group_logs', verbose_name=_('Group'), blank=True)
urls = models.ManyToManyField(URL, related_name='url_logs', verbose_name=_('URLs'), blank=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='users', verbose_name=_('User'))
datetime = models.DateTimeField(verbose_name=_('Clicked At'), auto_now_add=True)
ip = models.IPAddressField(verbose_name=_('IP'), null=True, blank=True)
user_agent = models.CharField(verbose_name=_('User Agent'), max_length=1024, null=True, blank=True)
page = models.URLField(verbose_name=_('Page'), null=True, blank=True)
key = models.CharField(verbose_name=_('User Agent'), max_length=32, null=True, blank=True)
TYPE_CHOICES = (
(0, 'impressions'),
(1, 'view'),
(2, 'click')
)
type = models.PositiveSmallIntegerField(verbose_name=_('Type'), max_length=1, default=0, choices=TYPE_CHOICES)
def __unicode__(self):
return '%s - (%s)' % (self.banner, self.datetime)
class LogStat(models.Model):
banner = models.ForeignKey(Banner, related_name='banner_stat', verbose_name=_('Banner'), blank=True)
group = models.ForeignKey(BannerGroup, related_name='group_stat', verbose_name=_('Group'), blank=True)
urls = models.ManyToManyField(URL, related_name='url_bloks', verbose_name=_('URLs'), null=True, blank=True)
date = models.DateField(verbose_name=_('Data'))
view = models.PositiveIntegerField(verbose_name=_('Views'))
click = models.PositiveIntegerField(verbose_name=_('Clicks'))
unique_click = models.PositiveIntegerField(verbose_name=_('Unique Views'), blank=True, null=True)
unique_view = models.PositiveIntegerField(verbose_name=_('Unique Clicks'))
def __unicode__(self):
return '%s - (%s)' % (self.banner, self.date)
# ------------------
class Paid(models.Model):
tickets = models.ForeignKey(Banner, related_name='paid_tickets')
participation = models.ForeignKey(Banner, related_name='paid_participation')
official = models.ForeignKey(Banner, related_name='paid_official')
logo = models.ImageField(upload_to='/')# !!!!!
organiser = models.CharField(max_length=100)
active = models.BooleanField(default=True)
stat_pswd = models.CharField(max_length=16)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class PaidStat(models.Model):
paid = models.ForeignKey(Paid)
date = models.DateField(verbose_name=_('Date'))
page_views = models.PositiveIntegerField(default=0)
price_views = models.PositiveIntegerField(default=0)
catalog_views = models.PositiveIntegerField(default=0)
catalog_clicks = models.PositiveIntegerField(default=0)
class Top(models.Model):
catalog = models.CharField(max_length=16)
position = models.PositiveIntegerField(blank=True, null=True)
theme = models.ManyToManyField('theme.Theme', blank=True, null=True)
excluded_tags = models.ManyToManyField('theme.Tag', blank=True, null=True)
country = models.ManyToManyField('country.Country', blank=True, null=True)
excluded_cities = models.ManyToManyField('city.City', blank=True, null=True)
fr = models.DateField(default=date.today())
to = models.DateField(blank=True, null=True)
stat_pswd = models.CharField(max_length=16)
class Meta:
ordering = ['position']
class TopStat(models.Model):
date = models.DateField()
theme = models.ForeignKey('theme.Theme', blank=True, null=True)
tag = models.ForeignKey('theme.Tag', blank=True, null=True)
country = models.ForeignKey('country.Country', blank=True, null=True)
city = models.ForeignKey('city.City', blank=True, null=True)
views = models.PositiveIntegerField(default=0)
clicks = models.PositiveIntegerField(default=0)

@ -0,0 +1,159 @@
/*
**************************
* =COMMON
**************************
*/
.b-slider {
position: relative;
display: block;
overflow: hidden;
margin: 0;
padding: 0;
width: 725px;
height: 360px;
}
.b-slider-list {
position: absolute;
display: block;
overflow: hidden;
margin: 0;
padding: 0;
width: 725px;
height: 360px;
list-style: none;
}
.b-slider-item {
position: absolute;
z-index: 50;
float: left;
overflow: hidden;
margin: 0;
padding: 0;
width: 725px;
height: 360px;
}
.m-slider-current {
z-index: 100;
}
.b-slider-item__img,
.b-slider-item__title,
.b-slider-item__text {
position: absolute;
}
.b-slider-item__img {
top: 0;
left: 0;
text-decoration: none;
}
.b-slider-item__link {
}
.b-slider-item__title {
bottom: 10px;
left: 10px;
width: 500px;
color: #333;
text-transform: uppercase;
text-shadow: 0 0 3px #fff, 0 0 2px #fff, 0 0 1px #fff;
letter-spacing: -5px;
font-size: 65px;
font-family: Calibri;
line-height: 0.8em;
}
.b-slider-item__text {
position: absolute;
top: 150px;
left: 300px;
display: inline-block;
display: none;
margin: -10px;
padding: 10px;
max-width: 300px;
border-radius: 10px;
background: rgba(255, 255, 255, 0.5);
box-shadow: 0 0 5px #fff;
color: #555;
line-height: 1.5em;
}
/*
**************************
* =NAV
**************************
*/
.b-slider-nav {
position: absolute;
width: 100%;
top: 10px;
height: 30px;
left: 0;
z-index: 500;
display: block;
margin: 0;
padding: 0;
list-style-type: none;
text-align: center;
}
.b-slider-nav-button {
display: inline-block;
margin: 5px;
width: 16px;
height: 16px;
border-radius: 8px;
background: #ddd;
color: transparent;
text-align: center;
font-weight: bold;
font-size: 8px;
line-height: 16px;
cursor: pointer;
}
.b-slider-nav-button:hover {
background: #eee;
}
.m-slider-nav-current_button {
background: #fff;
}
.b-slider-nav-prev,
.b-slider-nav-next {
position: absolute;
top: 0;
z-index: 500;
padding-right: 20px;
padding-left: 20px;
color: #000;
text-shadow: 0 0 3px #fff, 0 0 2px #fff, 0 0 1px #fff;
font-size: 50px;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
line-height: 360px;
opacity: 0.5;
cursor: pointer;
}
.b-slider-nav-prev:hover,
.b-slider-nav-next:hover {
opacity: 0.8;
}
.b-slider-nav-prev {
left: 0;
padding-left: 0;
}
.b-slider-nav-next {
right: 0;
padding-right: 0;
}

@ -0,0 +1,10 @@
$(document).ready(function() {
$('.b-banner-click').on('click', function(){
$.get($(this).data('url'));
});
$(".b-banner").on('load', function() {
$.get($(this).data('view'));
});
});

@ -0,0 +1,71 @@
$.fn.bannersSlider = function(options) {
$this = this;
var settings = $.extend( {
'auto_play': false,
'effect': 'fade',
'speed' : 3000
}, options);
$this.current = 1;
$this.old = 1;
$this.len = $this.find('.b-slider-list li').length;
$this.find('.b-slider-item').hide();
$this.find('.m-slider-item-1').show();
$this.fadeTo = function(new_num) {
old_num = $this.old;
if (new_num != old_num) {
$this.find('.m-slider-item-' + new_num).hide();
$this.find('.m-slider-item-' + new_num).fadeIn(1000);
$this.find('.m-slider-current').fadeOut(1000);
$this.find('.m-slider-current').removeClass('m-slider-current');
$this.find('.m-slider-item-' + new_num).addClass('m-slider-current');
$this.find('.b-slider-nav-button').removeClass('m-slider-nav-current_button');
$this.find('.b-slider-nav-button[data-slide=' + new_num + ']').addClass('m-slider-nav-current_button');
}
};
$this.prev = function() {
prev = ($this.current != 1) ? $this.current - 1 : $this.len;
$this.old = $this.current;
$this.current = prev;
$this.fadeTo(prev);
};
$this.next = function() {
next = ($this.current != $this.len) ? $this.current + 1 : 1;
$this.old = $this.current;
$this.current = next;
$this.fadeTo(next);
};
$this.children('.b-slider-nav-prev').on('click', function(){
$this.prev();
});
$this.children('.b-slider-nav-next').on('click', function(){
$this.next();
});
$this.find('.b-slider-nav-button').on('click', function(){
to_slide = $(this).data('slide');
$this.old = $this.current;
$this.current = to_slide;
$this.fadeTo(to_slide);
});
if (settings.auto_play) {
setInterval(function() {
$this.next();
}, settings.speed);
}
return $this;
};

@ -0,0 +1,55 @@
{% if banner.html %}
{% load banner %}
<div id='banner_{{ banner.id }}' class='b-banner b-banner-{{ group.slug }} m-banner__html'>
{% render banner.text %}
</div>
{% elif banner.flash %}
<div id='banner_{{ banner.id }}' class='b-banner b-banner-{{ group.slug }} m-banner__flash'>
<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
codebase='http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0'
width='{{ banner.group.width }}' height='{{ banner.group.height }}'>
<param name='movie' value='{{ banner.img.url }}' />
<param name='quality' value='high'>
<param name='play' value='true'>
<param name='loop' value='true'>
<param name='wmode' value='transparent'>
<embed src='{{ banner.img.url }}'
quality='high'
bgcolor='#d0f'
width='{{ banner.group.width }}'
height='{{ banner.group.height }}'
name='banner_{{ banner.id }}'
type='application/x-shockwave-flash'
play='true'
loop='true'
wmode='transparent'
pluginspage='http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'
>
</embed>
</object>
</div>
<script>
$('#banner_{{ banner.id }}').mousedown(function() {
// alert('mouse down');
});
</script>
{% else %}
<a href='{{ banner.url }}' id='banner_{{ banner.id }}' class='b-banner b-banner-{{ group.slug }}'>
<img src='{{ banner.img.url }}' alt='{{ banner.alt }}' title='{{ banner.title }}'>
</a>
{% endif %}
<style>
.b-banner {
display: block;
padding: 0;
margin: 0;
/*border: 1px solid silver;*/
}
.b-banner-{{ group.slug }} {
width: {{ banner.group.width }}px;
height: {{ banner.group.height }}px;
}
</style>

@ -0,0 +1,32 @@
{% load banner %}
<div class="b-banner-group">
{% for banner in banners %}
{% banner_one banner.id %}
{% endfor %}
</div>
<style type="text/css">
.b-banner-group {
display: block;
overflow: hidden;
}
.b-banner {
display: block;
padding: 0;
margin: 0;
/*border: 1px solid silver;*/
}
.b-banner-{{ group.slug }} {
width: {{ banner.group.width }}px;
height: {{ banner.group.height }}px;
float: left;
}
.b-banner-{{ group.slug }} img {
width: 100%;
height: 100%;
}
</style>

@ -0,0 +1,30 @@
{% load banner %}
<div class="b-banner-group">
{% for banner in banners %}
{% banner_one banner.id %}
{% endfor %}
<script>
var arr = [];
{% for banner in banners %}
arr[{{ forloop.counter }}] = {'id': {{ banner.id }}, 'often': {{ banner.often }}};
{% endfor %}
var length = arr.length - 1;
var i = 1;
var speed = {{ group.speed }};
$('.b-banner-{{ group.slug }}').hide();
$('#banner_' + arr[i]['id']).show();
total_speed = speed * arr[i]['often'];
setInterval(function () {
if (i < length) i++; else i = 1;
total_speed = speed * arr[i]['often'];
console.log (total_speed, arr[i]);
$('.b-banner-{{ group.slug }}').hide();
$('#banner_' + arr[i]['id']).show();
}, speed);
</script>
</div>

@ -0,0 +1,74 @@
{% load thumbnail %}
{% if banners %}
<div class="b-slider m-{{ group.slug }}" id="slider-{{ group.slug }}">
<ul class='b-slider-list'>
{% for banner in banners %}
<li data-url='{{ banner.get_absolute_url }}'
class='
b-slider-item
m-slider-item-{{ forloop.counter }}
{% if forloop.counter == 1 %}
m-slider-current
{% endif %}
'
data-slide='{{ forloop.counter }}'
>
<a href='{{ banner.get_absolute_url }}' class='b-slider-item__link'>
{% thumbnail banner.img group.size crop="top" as im %}
<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" alt="{{ banner.alt }}" title="{{ banner.title }}" class='b-slider-item__img' data-view='{{ banner.image }}'>
{% endthumbnail %}
<div class="b-slider-item__info_cover">
<span class='b-slider-item__title'>{{ banner.title|safe }}</span>
<span class='b-slider-item__text'>{{ banner.text|safe }}</span>
</div>
</a>
</li>
{% endfor %}
</ul>
<ul class="b-slider-nav">
{% for banner in banners %}
<li class="b-slider-nav-button
{% if forloop.counter == 1 %}
m-slider-nav-current_button
{% endif %}
" data-slide='{{ forloop.counter }}'>
{{ forloop.counter }}
</li>
{% endfor %}
</ul>
<span data-direction="prev" class='b-slider-nav-prev'>&#9001;&nbsp;&nbsp;</span>
<span data-direction="next" class='b-slider-nav-next'>&nbsp;&nbsp;&#9002;</span>
</div>
<script>
(function() {
$('.m-{{ group.slug }}').bannersSlider({'auto_play': {{ group.speed }}, 'speed': {{ group.speed }}});
})();
</script>
<style>
.m-{{ group.slug }} {
width: {{ group.width }}px;
height: {{ group.height }}px;
}
.m-{{ group.slug }} .b-slider-nav-prev,
.m-{{ group.slug }} .b-slider-nav-next {
line-height: {{ group.height }}px;
}
.m-{{ group.slug }} .b-slider-item,
.m-{{ group.slug }} .b-slider-list {
width: {{ group.width }}px;
height: {{ group.height }}px;
}
</style>
{% endif %}

@ -0,0 +1,74 @@
from ..models import Banner
from ..models import BannerGroup
from ..models import URL
from django import template
# For render tag
from django.template import Context
from django.template import Template
import re
register = template.Library()
@register.simple_tag(takes_context=True)
def banner_group(context, group, tpl='group.html'):
try:
page_url = context['request'].path_info
site = context['request'].site
group = BannerGroup.objects.get(slug=group)
good_urls = []
for url in URL.objects.filter(public=True, sites__in=[site]):
if url.regex:
url_re = re.compile(url.url)
if url_re.findall(page_url):
good_urls.append(url)
elif page_url == url.url:
good_urls.append(url)
banners = Banner.objects.filter(public=True, group=group, urls__in=good_urls)
except:
banners = False
group = False
if(banners and group):
context['banners'] = banners
context['group'] = group
t = template.loader.get_template(tpl)
return t.render(template.Context(context))
@register.simple_tag(takes_context=True)
def banner_one(context, banner_id, tpl='banner.html'):
try:
page_url = context['request'].path_info
site = context['request'].site
good_urls = []
for url in URL.objects.filter(public=True, sites__in=[site]):
if url.regex:
url_re = re.compile(url.url)
if url_re.findall(page_url):
good_urls.append(url)
elif page_url == url.url:
good_urls.append(url)
banner = Banner.objects.get(id=banner_id, public=True, urls__in=good_urls)
except:
banner = False
context['banner'] = banner
t = template.loader.get_template(tpl)
return t.render(template.Context(context))
# block render
@register.simple_tag(takes_context=True)
def render(context, content):
try:
tpl = Template(content)
content = Context(context)
return tpl.render(content)
except:
return 'Render Error'

@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

@ -0,0 +1,11 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^click/(?P<banner_id>\d{1,4})/(?P<key>[-\w]+)/$', views.click, name='banner_click'),
url(r'^view/(?P<banner_id>\d+)/(?P<key>[-\w]+)/$', views.view, name='banner_view'),
#
url(r'^get-banners/$', views.get_banners),
]

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
import json
from django.http import HttpResponse
from django.shortcuts import redirect, get_object_or_404
from .models import Banner, BannerGroup
def click(request, banner_id, key):
banner = get_object_or_404(Banner, pk=banner_id)
banner.log(request, 2, key)
return redirect(banner.url)
def view(request, banner_id, key):
banner = get_object_or_404(Banner, pk=banner_id)
banner.log(request, 1, key)
return redirect(banner.img.url)
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def get_banners(request):
url = request.GET.get('url', '/')
theme = request.GET.get('theme')
country = request.GET.get('country')
city = request.GET.get('city')
tag = request.GET.get('tag')
ip = get_client_ip(request)
params = {'url': url,
'theme': theme,
'tag': tag,
'country': country,
'city': city,
'ip': ip}
b = Banner.objects.get(id=1)
result = [{'url': b.url, 'id': 'expo_b_%d'%b.id, 'is_html': b.html,
'is_flash': b.flash, 'is_img': True, 'html': b.text, 'img': b.img.url}]
return HttpResponse(json.dumps(result, indent=4), content_type='application/json')

@ -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()

@ -1,20 +1,141 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import MySQLdb
import os.path
from MySQLdb.cursors import DictCursor
from django.utils.translation import activate
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from meta.models import MetaSetting from django.conf import settings
from exposition.models import Exposition
from theme.models import Theme
from theme.models import Theme, Tag
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
a = MetaSetting.objects.filter(translations__h1__contains='«').count() #expos = Exposition.objects.filter(theme__isnull=True, old_url__isnull=False)
qs = MetaSetting.objects.language('ru').all() db = MySQLdb.connect(host="localhost",
for item in qs: user="expomap",
item.title = item.title.replace(u'«', u'').replace(u'»', u'') passwd="7FbLtAGjse",
item.description = item.title.replace(u'«', u'').replace(u'»', u'') db="old_db",
item.h1 = item.h1.replace(u'«', u'').replace(u'»', u'') charset='utf8',
#item.save() cursorclass=DictCursor)
cursor = db.cursor()
activate('ru')
#expos = Exposition.enable.upcoming().filter(logo='')
expos = Exposition.objects.filter(tag__isnull=True).order_by('-data_end')
#expo = Exposition.objects.get(old_url='salon-du-livre-2015')
#handle_expo_tag(expo, cursor)
for expo in expos:
handle_expo_tag(expo, cursor)
'''
find_old_id = """
SELECT products.products_id
from products
LEFT JOIN `products_description` ON products.products_id=products_description.products_id
WHERE url='%s'
"""
find_themes = "SELECT categories_id FROM `products_to_categories` WHERE `products_id` =%d"
'''
"""
for expo in expos:
cursor.execute(find_old_id%expo.old_url)
old_ids = [item['products_id'] for item in cursor.fetchall()]
print expo.old_url
for id in old_ids:
cursor.execute(find_themes%id)
themes_ids = [item['categories_id'] for item in cursor.fetchall()]
print themes_ids
#if not themes_ids:
# continue
theme_qs = Theme.objects.filter(id__in=themes_ids)
#expo.theme.add(*theme_qs)
break
print('----------------------')
"""
def handle_expo_tag(expo, cursor):
old_url = expo.old_url
if not old_url:
return None
print(old_url)
find_old = """
SELECT products.products_id, url
from products
LEFT JOIN `products_description` ON products.products_id=products_description.products_id
WHERE url='%s'
"""
cursor.execute(find_old%old_url)
result = cursor.fetchone()
expo_id = result.get('products_id')
if not expo_id:
return
find_tag_id = """
SELECT tag_id
FROM `products_tags`
WHERE `product_id` =%d
"""
cursor.execute(find_tag_id%expo_id)
tags_ids = [str(item['tag_id']) for item in cursor.fetchall()]
if not tags_ids:
return None
find_tag = """
SELECT title
FROM `tags`
WHERE id in(%s)
"""
cursor.execute(find_tag%', '.join(tags_ids))
tag_names = [item['title'] for item in cursor.fetchall()]
if not tag_names:
return None
themes = [item['id'] for item in expo.theme.all().values('id')]
qs = Tag.objects.filter(translations__name__in=tag_names, theme__in=themes)
expo.tag.add(*qs)
def handle_expo(expo, cursor):
"""
fixing logos
"""
if expo.logo:
return
find_old = """
SELECT products.products_id, url, products_img1 as logo
from products
LEFT JOIN `products_description` ON products.products_id=products_description.products_id
WHERE url='%s'
"""
cursor.execute(find_old%expo.old_url)
result = cursor.fetchall()
if not result:
return
logo = result[0]['logo']
if logo:
logo = logo.replace('..', '')
print(logo)
print(os.path.isfile(settings.MEDIA_ROOT[:-1]+logo))
if (os.path.isfile(settings.MEDIA_ROOT[:-1]+logo)):
expo.logo = logo
expo.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

@ -31,10 +31,15 @@ def translit_with_separator(string, separator='-'):
#make string unicode #make string unicode
string = string.strip() string = string.strip()
string = u'%s'%string string = u'%s'%string
string = string.replace(u'\u200e', '')
#make string translit #make string translit
st = pytils.translit.translify(string) try:
st = pytils.translit.translify(string)
except ValueError:
# remove exception symbs(hack)
string = string.replace(u'\u200e', '')
string = string.replace(u'\u200b', '')
st = pytils.translit.translify(string)
#replace "bad" symbols for '-'symbol #replace "bad" symbols for '-'symbol
st = st.replace('.', '') st = st.replace('.', '')

@ -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
@ -99,3 +104,42 @@ class EventMixin(object):
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

@ -278,7 +278,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")
@ -93,20 +95,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
@ -132,3 +137,33 @@ 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'),
) )

@ -45,11 +45,6 @@ def get_periodic(value):
return periodic.get(value, '') return periodic.get(value, '')
return '' return ''
def get_date(value):
if value:
return str(value)
return ''
def get_quality(value, field): def get_quality(value, field):
flags = {u'UFI': 'ufi', u'РСВЯ': 'rsva', u'EXPORATING': 'exporating'} flags = {u'UFI': 'ufi', u'РСВЯ': 'rsva', u'EXPORATING': 'exporating'}
v = flags.get(field) v = flags.get(field)
@ -326,19 +321,27 @@ article_sett = {
u'Создана':{u'field': u'created', u'func': to_datetime} u'Создана':{u'field': u'created', u'func': to_datetime}
} }
def get_date(value):
try:
return value.strftime('%d.%m.%Y')
except AttributeError:
return ''
event_export_sett = [ event_export_sett = [
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500}, {'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode}, {'name': 'url', 'verbose_name': u'Url', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode}, {'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode}, {'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'data_begin', 'verbose_name': u'Дата начала:(YYYY-MM-DD)', 'type': unicode}, {'name': 'data_begin', 'verbose_name': u'Дата начала:(YYYY-MM-DD)', 'type': get_date},
{'name': 'data_end', 'verbose_name': u'Дата окончания:(YYYY-MM-DD)', 'type': unicode}, {'name': 'data_end', 'verbose_name': u'Дата окончания:(YYYY-MM-DD)', 'type': get_date},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode}, {'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode}, {'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place}, {'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place},
{'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000}, {'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000},
{'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000}, {'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000},
{'name': 'description', 'verbose_name': u'Описание события', 'type': unicode}, {'name': 'description', 'verbose_name': u'Описание события', 'type': unicode},
{'name': 'org', 'verbose_name': u'Организатор №1', 'type': get_int},
{'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic}, {'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic},
{'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience}, {'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience},
{'name': 'web_page', 'verbose_name': u'Официальный веб-сайт', 'type': unicode}, {'name': 'web_page', 'verbose_name': u'Официальный веб-сайт', 'type': unicode},
@ -500,6 +503,8 @@ event_sett = {
u'Участники':{u'field': u'members', u'func': to_int}, u'Участники':{u'field': u'members', u'func': to_int},
u'Страны':{u'field': u'stat_countries', u'func': unicode}, u'Страны':{u'field': u'stat_countries', u'func': unicode},
u'Площадь':{u'field': u'area', u'func': to_int}, u'Площадь':{u'field': u'area', u'func': to_int},
u'Мин стоимость':{u'field': u'min_price', u'func': to_int},
u'Макс стоимость':{u'field': u'max_price', u'func': to_int},
u'Min_Raw кв.м.':{u'field': u'min_closed_area', u'func': to_int}, u'Min_Raw кв.м.':{u'field': u'min_closed_area', u'func': to_int},
u'Max_Raw кв.м.':{u'field': u'max_closed_area', u'func': to_int}, u'Max_Raw кв.м.':{u'field': u'max_closed_area', u'func': to_int},
u'Min_Pack кв.м.':{u'field': u'min_closed_equipped_area', u'func': to_int}, u'Min_Pack кв.м.':{u'field': u'min_closed_equipped_area', u'func': to_int},

@ -106,6 +106,7 @@ def google_address(address):
response = {'address' : results[0].get('formatted_address'), response = {'address' : results[0].get('formatted_address'),
'lat' : results[0]['geometry']['location']['lat'], 'lat' : results[0]['geometry']['location']['lat'],
'lng' : results[0]['geometry']['location']['lng']} 'lng' : results[0]['geometry']['location']['lng']}
#return response
return json.dumps(response) return json.dumps(response)
else: else:
return '' return ''
@ -113,11 +114,11 @@ def google_address(address):
from djutils.decorators import async from djutils.decorators import async
from djutils.queue.decorators import queue_command from djutils.queue.decorators import queue_command
# place
class ImportPlaceExpositionForm(ImportForm): class ImportPlaceExpositionForm(ImportForm):
model = PlaceExposition model = PlaceExposition
settings = place_exp_sett settings = place_exp_sett
#@async
def save_file(self): def save_file(self):
data = self.cleaned_data data = self.cleaned_data
lang = data['language'] lang = data['language']
@ -125,86 +126,113 @@ class ImportPlaceExpositionForm(ImportForm):
book = xlrd.open_workbook(file_contents=f.read()) book = xlrd.open_workbook(file_contents=f.read())
sheet = book.sheet_by_index(0) sheet = book.sheet_by_index(0)
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
model = self.model
labels = [label for label in row_list[0]] labels = [label for label in row_list[0]]
errors = []
for row_number, row in enumerate(row_list): for row_number, row in enumerate(row_list):
if row_number == 0:
continue
if row[0] != '':
# in first column id
try:
obj = self.model.objects.language(lang).get(id=int(row[0]))
except ValueError:
obj = self.model()
obj.translate(lang)
except self.model.DoesNotExist:
obj = self.model(id= int(row[0]))
obj.translate(lang)
else:
# if id blank - its a new event
obj = model()
obj.translate(lang)
# ----------------
# go through all rows in file # go through all rows in file
if row_number > 0:
# first field is label
if row[0] != '':
# in first column ids
methods = []
for col_number, cell in enumerate(row):
# go through row cells
# field name current cell
label = labels[col_number]
setting = place_exp_sett.get(label)
if setting is None:
continue
if setting.get('method'):
if cell != "":
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')})
continue
field_name = setting['field']
func = setting.get('func')
if func is None:
continue
extra_value = setting.get('extra_values')
if extra_value is not None:
# if setting has extra value then
# it is some field like city, theme, tag
# that has relation and can be created
# in function we add language(need for relation fields)
# and extra value from object (like for city need country)
try: try:
object = self.model.objects.language(lang).get(id=int(row[0])) extra = getattr(obj, extra_value)
except ValueError: except Exception:
object = self.model() continue
object.translate(lang) value = func(cell, 'ru', extra)
except self.model.DoesNotExist:
object = self.model(id= int(row[0]))
object.translate(lang)
else: else:
# if id blank - its a new event value = func(cell)
object = self.model()
object.translate(lang)
methods = []
for col_number, cell in enumerate(row):
# go through row cells
# field name current cell
label = labels[col_number]
setting = place_exp_sett.get(label)
if setting is None: try:
continue setattr(obj, field_name, value)
except ValueError, e:
continue
if setting.get('method'): if field_name !='adress':
if cell != "": try:
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')}) setattr(obj, field_name, value)
except ValueError:
continue continue
field_name = setting['field'] else:
#gaddress = google_address(value)
setattr(obj, 'address', google_address(value))
if not obj.url:
obj.url = translit_with_separator(obj.name)
try:
obj.save()
except IntegrityError, e:
func = setting.get('func') error = str(e)
if func is not None: if typical_errors.get(error):
extra_value = setting.get('extra_values') error = typical_errors[error]
if extra_value is not None: if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'):
# if setting has extra value then error = u'Место с таким названием или урлом уже существует'
# it is some field like city, theme, tag
# that has relation and can be created
# in function we add language(need for relation fields) errors.append([obj.name, error])
# and extra value from object (like for city need country) continue
value = func(cell, lang, getattr(object, extra_value))
else:
value = func(cell)
if field_name =='adress':
setattr(object, 'address', google_address(value))
setattr(object, field_name, value)
for method in methods:
func = method['func']
if method.get('purpose'):
try:
func(obj, method['value'], method['purpose'])
except Exception, e:
continue
else:
func(obj, method['value'])
try: return errors
object.save()
except IntegrityError:
continue
#url = object.url + translit_with_separator(object.city.name)
#object.url = url
#object.save()
for method in methods:
func = method['func']
if method.get('purpose'):
try:
func(object, method['value'], method['purpose'])
except:
continue
else:
try:
func(object, method['value'])
except:
continue
class ImportPlaceConferenceForm(ImportForm): class ImportPlaceConferenceForm(ImportForm):
@ -217,6 +245,16 @@ 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'НЕправильный формат или не заполнена дата окончания',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'} '(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'}
# 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

@ -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
@ -30,6 +32,7 @@ def to_date(value):
return None return None
if isinstance(value, unicode) or isinstance(value, str): if isinstance(value, unicode) or isinstance(value, str):
try: try:
t = time.strptime(value, "%d.%m.%Y") t = time.strptime(value, "%d.%m.%Y")
except ValueError: except ValueError:
@ -88,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 == [""]:
@ -100,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
@ -130,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 = []
@ -165,7 +172,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
@ -181,9 +188,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:
@ -191,14 +198,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'Неизвестная ошибка'
@ -207,10 +220,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:

@ -19,6 +19,7 @@ urlpatterns = required(
url(r'^company/', include('company.admin_urls')), url(r'^company/', include('company.admin_urls')),
url(r'^conference/', include('conference.admin_urls')), url(r'^conference/', include('conference.admin_urls')),
url(r'^country/', include('country.admin_urls')), url(r'^country/', include('country.admin_urls')),
url(r'^expobanners/', include('expobanner.admin_urls')),
url(r'^exposition/', include('exposition.admin_urls')), url(r'^exposition/', include('exposition.admin_urls')),
url(r'^news/', include('news.admin_urls')), url(r'^news/', include('news.admin_urls')),
url(r'^organiser/', include('organiser.admin_urls')), url(r'^organiser/', include('organiser.admin_urls')),
@ -32,6 +33,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

@ -319,8 +319,10 @@ INSTALLED_APPS = (
'core', 'core',
'country', 'country',
'directories', 'directories',
'expobanner',
'exposition', 'exposition',
'file', 'file',
'import_xls',
'news', 'news',
'note', 'note',
'organiser', 'organiser',

@ -11,6 +11,9 @@ class Robot(TemplateView):
template_name = 'robots.txt' template_name = 'robots.txt'
content_type = 'text/plain' content_type = 'text/plain'
class YandexCheck(TemplateView):
template_name = 'client/simple_pages/yandex_check.html'
from sitemaps import ExpoCard, ExpoCity, ExpoCountry, ExpoTheme, ExpoTag, ConfCard, ConfCity, ConfCountry, ConfTheme,\ from sitemaps import ExpoCard, ExpoCity, ExpoCountry, ExpoTheme, ExpoTag, ConfCard, ConfCity, ConfCountry, ConfTheme,\
ConfTag, NewsSiteMap, BlogsSiteMap, Additional, Important ConfTag, NewsSiteMap, BlogsSiteMap, Additional, Important
@ -26,8 +29,6 @@ sitemaps = {
handler404 = 'proj.views.error404' handler404 = 'proj.views.error404'
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^wizard/', include('wizard.urls')),
url(r'^acquire_email/$', 'registration.backends.default.views.acquire_email', name = 'acquire_email'),
url(r'^rss/', include('core.urls')), url(r'^rss/', include('core.urls')),
#url(r'^__debug__/', include(debug_toolbar.urls)), #url(r'^__debug__/', include(debug_toolbar.urls)),
url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}), url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}),
@ -36,10 +37,13 @@ urlpatterns = patterns('',
url(r'^sitemap\.xml$', views.index, {'sitemaps': sitemaps}), url(r'^sitemap\.xml$', views.index, {'sitemaps': sitemaps}),
url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}), url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}),
url(r'^robots.txt$', Robot.as_view()), url(r'^robots.txt$', Robot.as_view()),
url(r'^yandex_4c326c16c916403e.html$', YandexCheck.as_view()),
url(r'^$', MainPageView.as_view()), url(r'^$', MainPageView.as_view()),
url(r'^page/', include('core.simple_urls')), url(r'^page/', include('core.simple_urls')),
url(r'^theme/', include('theme.urls')), url(r'^theme/', include('theme.urls')),
url(r'^places/', include('place_exposition.urls')), url(r'^places/', include('place_exposition.urls')),
url(r'^translators/', include('translator.urls')),
url(r'^expo-b/', include('expobanner.urls')),
url(r'^', include('accounts.urls')), url(r'^', include('accounts.urls')),
url(r'^', include('exposition.urls')), url(r'^', include('exposition.urls')),
url(r'^', include('settings.conference_old_urls')), # conference redirects from old version url(r'^', include('settings.conference_old_urls')), # conference redirects from old version
@ -76,6 +80,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'),

@ -66,7 +66,9 @@ def error404(request):
expo_themes = Theme.active.expo_themes_with_count() expo_themes = Theme.active.expo_themes_with_count()
conf_themes = Theme.active.conference_themes_with_count() conf_themes = Theme.active.conference_themes_with_count()
context.update({'expo_themes': expo_themes, 'conf_themes': conf_themes}) context.update({'expo_themes': expo_themes, 'conf_themes': conf_themes})
return render_to_response('client/404.html', context, context_instance=RequestContext(request)) response = render_to_response('client/404.html', context, context_instance=RequestContext(request))
response.status_code = 404
return response
class MainPageView(JitterCacheMixin, TemplateView): class MainPageView(JitterCacheMixin, TemplateView):
@ -76,7 +78,7 @@ class MainPageView(JitterCacheMixin, TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(MainPageView, self).get_context_data(**kwargs) context = super(MainPageView, self).get_context_data(**kwargs)
events = Exposition.objects.language().select_related('country', 'city', 'place').filter(main_page=1) events = Exposition.objects.language().select_related('country', 'city', 'place').filter(main_page__gte=1).order_by('-main_page')
exposition_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.exposition)[:6] exposition_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.exposition)[:6]
conference_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.conference)[:6] conference_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.conference)[:6]

@ -4,6 +4,7 @@ from django.http import HttpResponseRedirect, HttpResponse
from django.core.context_processors import csrf from django.core.context_processors import csrf
from django.conf import settings from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.views.generic import ListView, FormView
#models and forms #models and forms
from models import Service from models import Service
from forms import ServiceForm, ServiceDeleteForm from forms import ServiceForm, ServiceDeleteForm
@ -114,3 +115,30 @@ def get_city(request):
return render_to_response('checkbox_option.html', {'options': cities}) return render_to_response('checkbox_option.html', {'options': cities})
else: else:
return HttpResponse('error') return HttpResponse('error')
class ServiceControlList(ListView):
model = Service
template_name = 'admin/service/control_list.html'
paginate_by = 20
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import FormMixin
from django.views.generic import DetailView
from service.forms import ServiceControlForm
class ServiceControl(FormMixin, DetailView):
form_class = ServiceControlForm
template_name = 'admin/service/control.html'
model = Service
def get_form(self, form_class):
obj = self.object
data = obj.get_current_state()
return form_class(data)
def get_context_data(self, **kwargs):
context = super(ServiceControl, self).get_context_data(**kwargs)
context['form'] = self.get_form(self.form_class)
return context

@ -2,8 +2,11 @@
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from views import CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \ from views import CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \
ParticipationListView, RemoteListView,TicketsListView ParticipationListView, RemoteListView,TicketsListView
from service.admin import ServiceControlList, ServiceControl
urlpatterns = patterns('service.admin', urlpatterns = patterns('service.admin',
url(r'^control/list/$', ServiceControlList.as_view()),
url(r'^control/(?P<pk>.*)/$', ServiceControl.as_view()),
url(r'^add.*/$', 'service_add'), url(r'^add.*/$', 'service_add'),
url(r'^delete/(?P<url>.*)/$', 'service_delete'), url(r'^delete/(?P<url>.*)/$', 'service_delete'),
url(r'^change/(?P<url>.*)/$', 'service_change'), url(r'^change/(?P<url>.*)/$', 'service_change'),
@ -17,6 +20,6 @@ urlpatterns = patterns('service.admin',
url(r'order/tickets/$', TicketsListView.as_view()), url(r'order/tickets/$', TicketsListView.as_view()),
#ajax #ajax
url(r'^get_city/$', 'get_city'), url(r'^get_city/$', 'get_city'),
#url(r'^get_country/$', 'get_country'), #url(r'^get_country/$', 'get_country'),
) )

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

@ -47,9 +47,60 @@ class Service(TranslatableModel):
def get_price(self): def get_price(self):
pr = self.price pr = self.price
def get_current_state(self):
"""
uses for control form
:return:
"""
from country.models import Country
country_all = False
country = []
region = []
expositions = []
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
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
@ -105,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()

@ -8,7 +8,7 @@ from city.models import City
CITIES = settings.MEDIA_ROOT+'/import/cities_inflect.xls' CITIES = settings.MEDIA_ROOT+'/import/cities_inflect.xls'
TAGS = settings.MEDIA_ROOT+'/import/tags_inflect.xls' TAGS = settings.MEDIA_ROOT+'/import/tags_inflect.xls'
import inspect, os
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):

@ -156,6 +156,18 @@ def timetable_by_day(qs, day):
def random_social(value): def random_social(value):
return bool(random.getrandbits(1)) return bool(random.getrandbits(1))
@register.filter
def random3(value):
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
@ -224,7 +236,10 @@ def without_page(value):
@register.filter @register.filter
def note_by_user(obj, user): def note_by_user(obj, user):
return obj.get_note_by_user(user.id) if obj:
return obj.get_note_by_user(user.id)
return ''
@register.filter @register.filter
def isdigit(value): def isdigit(value):
@ -283,3 +298,12 @@ def generate_countries_list(value):
return ul1+ul2+ul3 return ul1+ul2+ul3
@register.filter
def how_many_years(value):
if not isinstance(value, datetime.date):
return ''
now = datetime.date.today()
delta = now - value
return delta.days/365

@ -10,7 +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
import datetime 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'},
@ -44,19 +44,22 @@ 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("Doesn't implemented yet") return HttpResponse("Don't implemented yet")
else: else:
@ -87,29 +90,28 @@ def get_by_lang(item, field, lang='en'):
:return: :return:
""" """
return getattr(item, field+'_'+lang) return getattr(item, field+'_'+lang)
import datetime
def expo_autosearch(request): 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
def place_autosearch(request): def place_autosearch(request):
if request.GET: if request.GET:
lang = translation.get_language() lang = translation.get_language()
@ -130,3 +132,51 @@ def company_autosearch(request):
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

@ -0,0 +1,47 @@
function make_event_select(id, url, placeholder){
$(id).select2({
placeholder: placeholder,
multiple: true,
ajax: {
url: url,
width: '550px',
dataType: "json",
quietMillis: 200,
multiple: true,
data: function(term, page, theme){
return {term: term,
page: page};
},
results: function (data) {
var results = [];
$.each(data, function(index, item){
results.push({
id: item.id,
text: item.label
});
});
return {results: results};
}
},
initSelection : function(element, callback) {
var data = [];
$(element.val().split(",")).each(function(i) {
var item = this.split(':');
data.push({
id: item[0],
text: item[1]
});
});
callback(data);
}
});
}
$(document).ready(function(){
make_event_select('#id_expositions', '/admin/exposition/search/', 'Выставки');
make_event_select('#id_conferences', '/admin/conference/search/', 'Конференции');
});

@ -112,7 +112,13 @@ function postStat(data, textStatus){
$(document).ready(function(){ $(document).ready(function(){
/*
$('#id_created').datetimepicker({
todayHighlight: true,
format : 'yyyy-mm-dd',
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');
@ -230,11 +236,7 @@ $(document).ready(function(){
}); });
// end on-of events // end on-of events
$('select').select2({
width: 'element',
allowClear: true
});//end select
@ -485,5 +487,11 @@ $(document).ready(function(){
}); });
}); });
$('select').select2({
width: 'element',
allowClear: true
});//end select
}); });

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,7 +76,7 @@
</div> </div>
</body> </body>
<script src="{% static 'custom_js/main.js' %}"></script>
{% block bot_scripts %} {% block bot_scripts %}
{% endblock %} {% endblock %}
</html> </html>

@ -17,7 +17,7 @@
{% block body %} {% block body %}
{# Uses multilang.html template for translated fields #} {# Uses multilang.html template for translated fields #}
<form method="post" class="form-horizontal" name="form2" id="form2"> {% csrf_token %} <form method="post" class="form-horizontal" name="form2" id="form2" enctype="multipart/form-data"> {% csrf_token %}
<fieldset> <fieldset>
<legend><i class="icon-edit"></i>{% if obj_id %} Изменить {% else %} Добавить {% endif %}город</legend> <legend><i class="icon-edit"></i>{% if obj_id %} Изменить {% else %} Добавить {% endif %}город</legend>
@ -47,6 +47,13 @@
<label class="control-label"><b>{{ form.country.label }}:</b></label> <label class="control-label"><b>{{ form.country.label }}:</b></label>
<div class="controls">{{ form.country}}</div> <div class="controls">{{ form.country}}</div>
</div> </div>
<div class="control-group {% if form.logo.errors %}error{% endif %}">
<label class="control-label">{{ form.logo.label }}:</label>
<div class="controls">{{ form.logo }}
<span class="help-inline">{{ form.logo.errors }}</span>
</div>
</div>
{# region #} {# region #}
{% with field='region' form=form languages=languages %} {% with field='region' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %} {% include 'admin/forms/multilang.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 %}

@ -41,6 +41,13 @@
{% with field='description' form=form languages=languages %} {% with field='description' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %} {% include 'admin/forms/multilang.html' %}
{% endwith %} {% endwith %}
<div class="control-group {% if form.logo.errors %}error{% endif %}">
<label class="control-label">{{ form.logo.label }}:</label>
<div class="controls">{{ form.logo }}
<span class="help-inline">{{ form.logo.errors }}</span>
</div>
</div>
{# capital #} {# capital #}
<div class="control-group {% if form.capital.errors %}error{% endif %}"> <div class="control-group {% if form.capital.errors %}error{% endif %}">
<label class="control-label">{{ form.capital.label }}:</label> <label class="control-label">{{ form.capital.label }}:</label>

@ -0,0 +1,33 @@
{% extends 'base.html' %}
{% block body %}
<div class="row-fluid sortable ui-sortable">
<div class="box span6">
<div class="box-header well" data-original-title="">
<h2><i class="icon-th"></i> Создание</h2>
</div>
<div class="box-content">
<div class="row-fluid">
<div class="span4"><h6><a href="{% url 'expobanner-create_url' %}">Урла</a></h6></div>
<div class="span4"><h6><a href="{% url 'expobanner-create_group' %}">Групы</a></h6></div>
<div class="span4"><h6><a href="{% url 'expobanner-create_banner' %}">Банера</a></h6></div>
</div>
</div>
</div><!--/span-->
<div class="box span6">
<div class="box-header well" data-original-title="">
<h2><i class="icon-th"></i> Список</h2>
</div>
<div class="box-content">
<div class="row-fluid">
<div class="span4"><h6><a href="{% url 'expobanner-list_url' %}">Урлов</a></h6></div>
<div class="span4"><h6><a href="{% url 'expobanner-list_group' %}">Груп</a></h6></div>
<div class="span4"><h6><a href="{% url 'expobanner-list_banner' %}">Банеров</a></h6></div>
</div>
</div>
</div><!--/span-->
</div>
{% endblock %}

@ -0,0 +1,59 @@
{% extends 'base.html' %}
{% load static %}
{% block scripts %}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<script src="{% static 'js/select/select2.js' %}"></script>
<script>
$(function(){
$('#id_tag').select2({
placeholder: "Тег",
width: '200px',
ajax: {
url: "/admin/theme/tag/search-without-theme/",
dataType: "json",
quietMillis: 200,
multiple: true,
data: function(term, page){
return {term: term,
page: page};
},
results: function (data) {
return {results: data};
}
}
});
})
</script>
{% endblock %}
{% block body %}
<form method="post" class="form-horizontal" name="form2" id="form2" enctype="multipart/form-data"> {% csrf_token %}
<fieldset>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i>{{ form.verbose }}</h2>
</div>
<div class="box-content">
{% for field in form %}
<div class="control-group {% if field.errors %}error{% endif %}">
<label class="control-label">{% if field.field.required %}<b>{{ field.label }}:</b>{% else %}{{ field.label }}{% endif %}</label>
<div class="controls">{{ field }}
<span class="help-inline">{{ field.errors }}</span>
</div>
</div>
{% endfor %}
</div>
</div>
</fieldset>
<div class="controls">
<input class="btn btn-large btn-primary" type="submit" value="Готово">
<input class="btn btn-large" type="reset" value="Отмена">
</div>
</form>
{% endblock %}

@ -0,0 +1,34 @@
{% extends 'base.html' %}
{% block body %}
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>{{ verbose }}</h2>
</div>
<div class="box-content">
{% block list_table %}
<table class="table table-hover">
<thead>
<tr>
<th>Объект</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for item in object_list %}
<tr>
<td>{{ item }}</td>
<td><a href="{{ item.get_admin_url }}">Изменить</a> </td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
</div>
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</div>
{% endblock %}

@ -22,26 +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>
-->
{# datetimepicker #}
<link href="{% static 'js/datetimepicker/css/datetimepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datetimepicker/js/bootstrap-datetimepicker.js' %}"></script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function(){ $(document).ready(function(){
$('#id_data_begin').datetimepicker({ $('#id_data_begin').datetimepicker({
@ -226,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' %}
@ -374,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>
<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 %} {% 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>
@ -104,6 +105,13 @@
</ul> </ul>
</li> </li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class=" icon-circle-arrow-up"></i> Реклама<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/admin/expobanners/banners/control/">Управление банерами</a></li>
</ul>
</li>
</ul> </ul>
</div> </div>

@ -0,0 +1,78 @@
{% extends 'base.html' %}
{% load static %}
{% block scripts %}
{# selects #}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<script src="{% static 'js/select/select2.js' %}"></script>
{% endblock %}
{% block body %}
<form method="post" class="form-horizontal" name="form" id="main_form"> {% csrf_token %}
<fieldset>
<legend><i class="icon-edit"></i>Управление услугой {{ object.name }}</legend>
<div class="box span8" >
<div class="box-header well">
<h2><i class="icon-pencil"></i></h2>
</div>
<div class="box-content">
{# event_type #}
<div class="control-group {% if form.event_type.errors %}error{% endif %}">
<label class="control-label">{{ form.event_type.label }}:</label>
<div class="controls">
{{ form.event_type }}
</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 #}
<div class="control-group {% if form.region.errors %}error{% endif %}">
<label class="control-label">{{ form.region.label }}:</label>
<div class="controls">{{ form.region }}
<span class="help-inline">{{ form.region.errors }}</span>
</div>
</div>
{# country #}
<div class="control-group {% if form.country.errors %}error{% endif %}">
<label class="control-label">{{ form.country.label }}:</label>
<div class="controls">{{ form.country }}
<span class="help-inline">{{ form.country.errors }}</span>
</div>
</div>
{# expositions #}
<div class="control-group {% if form.expositions.errors %}error{% endif %}">
<label class="control-label">{{ form.expositions.label }}:</label>
<div class="controls">{{ form.expositions }}
<span class="help-inline">{{ form.expositions.errors }}</span>
</div>
</div>
{# conferences #}
<div class="control-group {% if form.conferences.errors %}error{% endif %}">
<label class="control-label">{{ form.conferences.label }}:</label>
<div class="controls">{{ form.conferences }}
<span class="help-inline">{{ form.conferences.errors }}</span>
</div>
</div>
</div>
</div>
</fieldset>
</form>
{% endblock %}
{% block bot_scripts %}
<script src="{% static 'custom_js/find_events.js' %}"></script>
{% endblock %}

@ -0,0 +1,39 @@
{% extends 'admin_list.html' %}
{% block body %}
<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>id</th>
<th>Название</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for item in object_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>
<a class="btn-small btn-info" href="/admin/service/control/{{ item.id }}/">
Управлять
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</div>
{% endblock %}

@ -89,48 +89,5 @@
{% endblock %} {% endblock %}
{% block bot_scripts %} {% block bot_scripts %}
<script> <script src="{% static 'custom_js/find_events.js' %}"></script>
$(document).ready(function(){
$('#id_expositions').select2({
placeholder: "Выставки",
multiple: true,
ajax: {
url: "/admin/exposition/search/",
width: '550px',
dataType: "json",
quietMillis: 200,
multiple: true,
data: function(term, page, theme){
return {term: term,
page: page};
},
results: function (data) {
var results = [];
$.each(data, function(index, item){
results.push({
id: item.id,
text: item.label
});
});
return {results: results};
}
},
initSelection : function(element, callback) {
var data = [];
$(element.val().split(",")).each(function(i) {
var item = this.split(':');
data.push({
id: item[0],
text: item[1]
});
});
callback(data);
}
});
});
</script>
{% endblock %} {% endblock %}

@ -0,0 +1,133 @@
{% extends 'base.html' %}
{% load static %}
{# Displays translator form and file form in modal window #}
{% block scripts %}
<script src="{% static 'ckeditor/ckeditor/ckeditor.js' %}"></script>
{# selects #}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<script src="{% static 'js/select/select2.js' %}"></script>
<script src="{% static 'custom_js/make_select.js' %}"></script>
{# ajax #}
<script src="{% static 'custom_js/file_post_ajax.js' %}"></script>
{# datetimepicker #}
<link href="{% static 'js/datetimepicker/css/datetimepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datetimepicker/js/bootstrap-datetimepicker.js' %}"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#id_birth').datetimepicker({
todayHighlight: true,
format : 'dd.mm.yyyy',
minView:2
});
});
</script>
{% endblock %}
{% block body %}
<form method="post" class="form-horizontal" enctype="multipart/form-data" name="form1" id="form1"> {% csrf_token %}
<fieldset>
<legend><i class="icon-edit"></i>Изменить переводчика(<a target="_blank" href="{{ object.get_translator_url }}">на сайте</a>)</legend>
<div class="box span8" >
<div class="box-header well">
<h2><i class="icon-pencil"></i> Основная информация</h2>
</div>
<div class="box-content">
{# name #}
<div class="control-group {% if form_user.first_name.errors %}error{% endif %}">
<label class="control-label"><b>{{ form_user.first_name.label }}:</b></label>
<div class="controls">{{ form_user.first_name }}
<span class="help-inline">{{ form_user.first_name.errors }}</span>
</div>
</div>
{# surname #}
<div class="control-group {% if form_user.last_name.errors %}error{% endif %}">
<label class="control-label"><b>{{ form_user.last_name.label }}:</b></label>
<div class="controls">{{ form_user.last_name }}
<span class="help-inline">{{ form_user.last_name.errors }}</span>
</div>
</div>
{# country #}
<div class="control-group {% if form_profile.country.errors %}error{% endif %}">
<label class="control-label"><b>{{ form_profile.country.label }}:</b></label>
<div class="controls">{{ form_profile.country }}
<span class="help-inline">{{ form_profile.country.errors }}</span>
</div>
</div>
{# city #}
<div class="control-group {% if form_profile.city.errors %}error{% endif %}">
<label class="control-label"><b>{{ form_profile.city.label }}:</b></label>
<div class="controls">{{ form_profile.city }}
<span class="help-inline">{{ form_profile.city.errors }}</span>
</div>
</div>
{# logo #}
<div class="control-group {% if form_profile.avatar.errors %}error{% endif %}">
<label class="control-label"><b>{{ form_profile.avatar.label }}:</b></label>
<div class="controls">{{ form_profile.avatar }}
<span class="help-inline">{{ form_profile.avatar.errors }}</span>
</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">
{# car #}
<div class="control-group {% if form.car.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.car.label }}:</b></label>
<div class="controls">{{ form.car }}
<span class="help-inline">{{ form.car.errors }}</span>
</div>
</div>
{# birth #}
<div class="control-group {% if form.birth.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.birth.label }}:</b></label>
<div class="controls">{{ form.birth }}
<span class="help-inline">{{ form.birth.errors }}</span>
</div>
</div>
{# gender #}
<div class="control-group {% if form.gender.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.gender.label }}:</b></label>
<div class="controls">{{ form.gender }}
<span class="help-inline">{{ form.gender.errors }}</span>
</div>
</div>
{# time #}
{% include 'admin/forms/multilang.html' with field='education' form=form languages=languages%}
{% include 'admin/forms/multilang.html' with field='specialization' form=form languages=languages%}
{% include 'admin/forms/multilang.html' with field='languages' form=form languages=languages%}
{% include 'admin/forms/multilang.html' with field='native_language' form=form languages=languages%}
{% include 'admin/forms/multilang.html' with field='prices' form=form languages=languages%}
{% include 'admin/forms/multilang.html' with field='discounts' form=form languages=languages%}
</div>
</div>
<div class="controls">
<input class="btn btn-large btn-primary" type="submit" value="Изменить">
<input class="btn btn-large" type="reset" value="Отмена">
</div>
</fieldset>
</form>
{% endblock %}

@ -21,10 +21,9 @@
<tr> <tr>
<td>{{ item.id }}</td> <td>{{ item.id }}</td>
{% for u in item.user.all %} <td>{{ item.get_full_name }}</td>
<td>{{ u }}</td> <td>{{ item.profile.country.name }}</td>
<td>{{ u.country }}</td>
{% endfor %}
<td class="center sorting_1"> <td class="center sorting_1">
<a class="btn btn-info" href="/admin/translator/change/{{ item.id }}"> <a class="btn btn-info" href="/admin/translator/change/{{ item.id }}">

@ -28,6 +28,7 @@
<th>id</th> <th>id</th>
<th>Пользователь</th> <th>Пользователь</th>
<th>Страна</th> <th>Страна</th>
<th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -35,10 +36,8 @@
<tr> <tr>
<td>{{ item.id }}</td> <td>{{ item.id }}</td>
{% for u in item.user.all %} <td>{{ item.get_full_name }}</td>
<td>{{ u.get_full_name }}</td> <td>{{ item.profile.country.name }}</td>
<td>{{ u.profile.country.name }}</td>
{% endfor %}
<td class="center sorting_1"> <td class="center sorting_1">
<a class="btn btn-info" href="/admin/translator/change/{{ item.id }}"> <a class="btn btn-info" href="/admin/translator/change/{{ item.id }}">

@ -0,0 +1,108 @@
{% extends 'base_catalog.html' %}
{% load i18n %}
{% block bread_scrumbs %}
{% endblock %}
{% block page_title %}
<div class="bread-crumbs">
<a href="/">Главная страница</a>
<a href="/translators/city/{{ object.url }}/">Города</a>
<strong>Переводчики {{ object.inflect }}</strong>
</div>
{% endblock %}
{% block content_list %}
<div class="m-article">
<div class="item-wrap place clearfix">
<aside>
<div class="i-pict">
{% include 'client/includes/show_logo.html' with obj=object %}
</div>
{# <a class="button about" href="#">о городе</a> #}
</aside>
<div class="i-info">
<header>
<div class="i-title">{{ object.name }}</div>
</header>
<div class="i-descr">
<p>Компания Serve Businesses Worldwide предлагает Вам возможность заказать услуги русскоговорящих переводчиков со знанием английского языка практически непосредственно в Великобритании.</p>
</div>
</div>
</div>
<hr />
<div class="i-services country_content">
<div class="i-descr">
<h4>Коротко о наших преимуществах:</h4>
<ul class="content_list">
<li>Эффективная цена</li>
<li>Опыт и профессионализм специалистов</li>
<li>Знание разных менталитетов и психологических аспектов проведения переговоров с зарубежными бизнесменами</li>
<li>Ориентированность в мировых выставочных комплексах </li>
<li>Гарантии, отчетность по договору, прозрачные безналичные расчеты в России</li>
</ul>
</div>
</div>
<div class="rq-btn-wrap rq-btn-to-hide">
<div class="rqb-cols">
<div class="rqb-button">
<div class="rq-order-button">
<div class="rqob-wrap">
<div class="rqob-price">от 80 € / день</div>
<div class="rqob-button">
<a class="ob-text" href="#">заказать услугу</a>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<div class="i-staff">
<div class="sect-title"><a href="/translators/city/{{ object.url }}/all/">Наши специалисты</a></div>
<div class="i-staff-list">
<ul>
{% with object_list=object_list %}
{% for user in object_list %}
<li>
<a href="{{ user.get_translator_url }}">
<div class="sl-item clearfix">
<div class="sl-pict">
{% include 'includes/show_logo.html' with obj=user %}
</div>
<div class="sl-info">
<div class="sl-info-wrap">
<div class="sl-name">{{ user.get_full_name }}</div>
<div class="sl-position">{{ user.translator.languages }}</div>
</div>
</div>
</div>
</a>
</li>
{% endfor %}
{% endwith %}
</ul>
</div>
<a class="button more" href="/translators/city/{{ object.url }}/all/">Все переводчики</a>
</div>
</div>
{% endblock %}

@ -0,0 +1,137 @@
{% extends 'base_catalog.html' %}
{% load i18n %}
{% block bread_scrumbs %}
<div class="bread-crumbs">
<a href="/">Главная страница</a>
<a href="/translators/country/">Страны</a>
<strong>Переводчики {{ object.inflect }}</strong>
</div>
{% endblock %}
{% block page_title %}
{% endblock %}
{% block content_list %}
<div class="m-article">
<div class="item-wrap place clearfix">
<aside>
<div class="i-pict">{% include 'client/includes/show_logo.html' with obj=object %}</div>
{# <a class="button about" href="#">о стране</a> #}
</aside>
<div class="i-info">
<header>
<div class="i-title">Переводчики {{ object.inflect }}</div>
</header>
<div class="i-descr">
<p>Компания Serve Businesses Worldwide предлагает Вам возможность заказать услуги русскоговорящих переводчиков со знанием английского языка практически непосредственно в Великобритании.</p>
<p>Ниже приведен список наиболее часто востребованных территориальных направлений для оказания услуг перевода в Великобритании. Приведенный перечень не является исчерпывающим, поэтому, если Вы не нашли нужный Вам город, обратитесь к нашим консультантам. </p>
</div>
<br>
{% if object.latitude and object.longitude %}
<div class="i-address map-opened country_map">
<div class="i-map">
<!-- позиция для карты задается в атрибуте data-coords -->
<div class="map-canvas" id="map-canvas" data-coords="{{ object.latitude }},{{ object.longitude }}" ></div>
<div class="close-map"><a class="toggle-map" href="#">Скрыть карту</a></div>
</div>
<header>
<div class="show-map show-map_1"><a class="toggle-map" href="#">Раскрыть карту</a></div>
</header>
</div>
{% endif %}
</div>
</div>
<hr />
{% if object.big_cities.exists %}
{% with cities=object.big_cities.all %}
<div class="country_towns">
<h4>Крупные города:</h4>
<table>
<tr>
<td>
<ul>
{% for city in cities %}
<li><a href="/translators/city/{{ city.url }}/" title="">{{ city.name }}</a></li>
{% endfor %}
</ul>
</td>
<th>&nbsp;</th>
</tr>
</table>
</div>
<hr/>
{% endwith %}
{% endif %}
<div class="i-services country_content">
<div class="i-descr">
<h4>Коротко о наших преимуществах:</h4>
<ul class="content_list">
<li>Эффективная цена</li>
<li>Опыт и профессионализм специалистов</li>
<li>Знание разных менталитетов и психологических аспектов проведения переговоров с зарубежными бизнесменами</li>
<li>Ориентированность в мировых выставочных комплексах </li>
<li>Гарантии, отчетность по договору, прозрачные безналичные расчеты в России</li>
</ul>
</div>
</div>
<div class="rq-btn-wrap rq-btn-to-hide">
<div class="rqb-cols">
<div class="rqb-button">
<div class="rq-order-button">
<div class="rqob-wrap">
<div class="rqob-price">от 80 € / день</div>
<div class="rqob-button">
<a class="ob-text" href="#">заказать услугу</a>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<div class="i-staff">
<div class="sect-title"><a href="/translators/country/{{ object.url }}/all/">Наши специалисты</a></div>
<div class="i-staff-list">
<ul>
{% for user in object_list %}
<li>
<a href="{{ user.get_translator_url }}">
<div class="sl-item clearfix">
<div class="sl-pict">{% include 'client/includes/show_logo.html' with obj=user %}</div>
<div class="sl-info">
<div class="sl-info-wrap">
<div class="sl-name">{{ user.get_full_name }}</div>
<div class="sl-position">{{ user.translator.languages }}</div>
</div>
</div>
</div>
</a>
</li>
{% endfor %}
</ul>
</div>
<a class="button more" href="/translators/country/{{ object.url }}/all/">Все переводчики</a>
</div>
</div>
{% endblock %}

@ -0,0 +1,59 @@
{% extends 'base_catalog.html' %}
{% load static %}
{% load i18n %}
{% load thumbnail %}
{% load template_filters %}
{% block bread_scrumbs %}
<div class="bread-crumbs">
<a href="/">{% trans 'Главная страница' %}</a>
{% if object.profile.country %}
<a href="/translators/country/{{ object.profile.country.url }}/">{{ object.profile.country.name }}</a>
{% if object.profile.city %}
<a href="/translators/city/{{ object.profile.city.url }}/">{{ object.profile.city.name }}</a>
{% endif %}
{% endif %}
<strong>{{ obect.get_full_name }}</strong>
</div>
{% endblock %}
{% block content_list %}
<div class="m-article cl-news blog_block">
<div class="profile_top">
<div class="profile_top_pic">
{% if object.profile.avatar %}
{% thumbnail object.profile.avatar "100x100" format="PNG" as im %}
<img class="user-avatar" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"/>
{% endthumbnail %}
{% else %}
<img class="user-avatar" src="{% static 'client/img/no-userpic-big.gif' %}" width="100" height="100"/>
{% endif %}
</div>
<div class="profile_top_left_1">
<h1>{{ object.get_full_name }}</h1>
<p><span class="icon1"></span><b>{{ object.translator.languages }}</b></p>
<p>{% ifequal object.translator.gender 'female' %}<span class="icon2"></span>{% endifequal %}{{ object.translator.birth|how_many_years }} лет{% if object.translator.car %}<span class="icon3"></span>Есть личный автомобиль</p>{% endif %}
</div>
<div class="profile_top_right_1">
{% if object.profile.country %}
<p><span class="icon4"></span><a href="/translators/country/{{ object.profile.country.url }}/" title="">{{ object.profile.country.name }}</a>
{% if object.profile.city %}, <a href="/translators/city/{{ object.profile.city.url }}/" title="">{{ object.profile.city.name }}</a>{% endif %}</p>
{% endif %}
{% if object.translator.native_language %}
<p><span class="icon5"></span>{% trans 'Родной язык' %} — {{ object.translator.native_language }}</p>
{% endif %}
</div>
<div class="clear"></div>
<hr>
{% if object.translator.education %}
<h3>{% trans 'Образование' %}:</h3>
{{ object.translator.education }}
<hr>
{% endif %}
</div>
</div>
{% endblock %}

@ -0,0 +1,33 @@
{% extends 'base_catalog.html' %}
{% load i18n %}
{% load template_filters %}
{% block bread_scrumbs %}
<div class="bread-crumbs">
<a href="/">Главная страница</a>
<strong>{{ catalog_name }}</strong>
</div>
{% endblock %}
{% block page_title %}
{% endblock %}
{% block content_list %}
{% with objects=object_list %}
{% for obj in objects %}
{% set cur_word = obj.name %}
{% if cur_word|slice:":1"|lower != prev_word|slice:":1"|lower and forloop.counter != 1 %}
</ul>
{% endif %}
{% if cur_word|slice:":1"|lower != prev_word|slice:":1"|lower %}
<ul class="leter-list">
<div class="leter"><font size="5">{{ cur_word|slice:":1"|upper }}</font></div>
{% endif %}
<li>
<a href="/translators{{ obj.catalog }}{{ obj.url }}/">{{ obj.name }}&nbsp;({{ obj.translators_count }})</a>
</li>
{% set prev_word = obj.name %}
{% endfor %}
{% endwith %}
{% endblock %}

@ -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" />
@ -108,6 +112,20 @@ This template include basic anf main styles and js files,
ga('create', 'UA-3151423-1', 'auto'); ga('create', 'UA-3151423-1', 'auto');
ga('send', 'pageview'); ga('send', 'pageview');
</script> </script>
<!--test expo_b -->
<script>
$(function () {
var sendData = {
"url": "{{ request.path }}",
"theme": "{{ theme.id }}",
"country": "{{ country.id }}",
"city": "{{ city.id }}",
"tag": "{{ tag.id }}"
}
console.log(sendData);
});
</script>
</head> </head>
<body {% block body_class %}{% endblock %}> <body {% block body_class %}{% endblock %}>
@ -147,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' %}
@ -156,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 'partial_pipeline' not in request.session %} {% if 'partial_pipeline' not in request.session %}
{% include 'client/popups/acquire_email.html' %} {% include 'client/popups/acquire_email.html' %}

@ -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">
@ -26,3 +27,86 @@
{% 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 %}

@ -1,9 +1,19 @@
{% load static %} {% load static %}
{% load template_filters %} {% load template_filters %}
<div class="abn"> <div class="abn">
{% if False|fourth %} {% with r=False|random4 %}
<a target="_blank" href="/redirect/redirect/21/"><img src="{% static 'client/img/partners/unnamed.gif' %}" alt="" /></a> {% ifequal r 0 %}
{% else %} <a target="_blank" href="/redirect/redirect/57/"><img src="{% static 'client/img/partners/cemat15_900x130_bilet.gif' %}" alt="" /></a>
<a target="_blank" href="/redirect/redirect/23/"><img src="{% static 'client/img/partners/unnamed_1.gif' %}" alt="" /></a> {% endifequal %}
{% endif %} {% ifequal r 1 %}
<a target="_blank" href="/redirect/redirect/58/"><img src="{% static 'client/img/partners/beach.png' %}" alt="" /></a>
{% endifequal %}
{% ifequal r 2 %}
<a target="_blank" href="/redirect/redirect/59/"><img src="{% static 'client/img/partners/mims15_900x130_bilet.gif' %}" alt="" /></a>
{% endifequal %}
{% ifequal r 3 %}
<a target="_blank" href="/redirect/redirect/61/"><img src="{% static 'client/img/partners/IPSA_2015_web_900x130.gif' %}" alt="" /></a>
{% endifequal %}
{% endwith %}
</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">
@ -152,7 +160,20 @@
{% endfor %} {% endfor %}
{% endwith %} {% endwith %}
</dd> </dd>
{% else %}
{% if event.org %}
{% for item in event.org_split %}
<dt>{% if forloop.counter == 1 %}{% trans 'Организатор' %}:{% endif %}</dt>
<dd>
{{ item }}
</dd>
{% endfor %}
{% endif %}
{% 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,12 +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.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>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save