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. 21
      city/forms.py
  6. 8
      city/models.py
  7. 34
      city/search_indexes.py
  8. 32
      conference/admin.py
  9. 2
      conference/admin_urls.py
  10. 21
      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. 50
      functions/model_mixin.py
  49. 2
      functions/search_forms.py
  50. 53
      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. 27
      service/forms.py
  63. 58
      service/models.py
  64. 2
      settings/management/commands/do_inflect.py
  65. 28
      settings/templatetags/template_filters.py
  66. 90
      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. 41
      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. 86
      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 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):
"""
return information about expos and them related data by 1 query

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

@ -49,14 +49,14 @@ def city_change(request, url):
return HttpResponseRedirect('/admin/city/all')
if request.POST:
form = CityForm(request.POST)
form = CityForm(request.POST, request.FILES)
if form.is_valid():
form.save(city_id)
return HttpResponseRedirect('/admin/city/all')
else:
#fill form with data from database
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:
data['country'] = c.country.id

@ -34,6 +34,7 @@ class CityForm(forms.Form):
widget=forms.TextInput(attrs={'placeholder':'Код города'}))
code_IATA = forms.ModelChoiceField(label='Код IATA', queryset=Iata.objects.all(), empty_label=None, required=False)
inflect = forms.CharField(label='Inflect', required=False)
logo = forms.ImageField(label='Logo', required=False)
#field for comparing tmp files
key = forms.CharField(required=False, widget=forms.HiddenInput())
#
@ -91,6 +92,11 @@ class CityForm(forms.Form):
city.population = data.get('population')
city.inflect = data['inflect']
if data.get('logo'):
city.logo = data['logo']
else:
city.logo = ''
if data.get('code_IATA'):
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):
model = City
country = forms.ChoiceField(choices=[('', '')]+[(item.id, item.name) for item in Country.objects.all()], required=False,
label='Страна')
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 django.db import models
from django.db.models.signals import post_save, pre_save
from django.utils import translation
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from bitfield import BitField
from sorl.thumbnail import ImageField
@ -62,6 +63,7 @@ class City(TranslatableModel):
# fields saves information about creating and changing model
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
logo = models.ImageField(verbose_name='Logo', upload_to='city/logo/', blank=True, max_length=255)
class Meta:
ordering = ['translations__name']
@ -115,6 +117,12 @@ class City(TranslatableModel):
def get_sub_categories(self):
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 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)
translations = indexes.MultiValueField()
#name = indexes.CharField(model_attr='translations__name')
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 'ci'
def prepare_catalog_name_en(self, obj):
return u'Cities'
def prepare_translations(self, obj):
return [tr.name for tr in obj.translations.all()]
def prepare_catalog_name_ru(self, obj):
return u'Города'
def get_model(self):
return City
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,
'discount': obj.discount,'canceled': obj.canceled, 'moved': obj.moved,
'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]}
if obj.place:
@ -295,4 +295,32 @@ class ConferenceListView(AdminListView):
model = Conference
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',
url(r'^upload-photo/(?P<conf_id>.*)/$', 'upload_conference_photo'),
url(r'^delete/(?P<url>.*)$', 'conference_delete'),
url(r'^copy/$', 'conf_copy'),
url(r'^all/$', ConferenceListView.as_view()),
#url(r'^change/(?P<url>.*)/$', 'conference_change'),
url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'conference_switch'),
url(r'^search/$', 'search_conf'),
url(r'^(?P<url>.*)/$', 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'])
logo = forms.ImageField(label='Logo', required=False)
organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
#organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
# 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()])
theme = forms.MultipleChoiceField(label='Тематики',
choices=[(item.id, item.name) for item in Theme.objects.language().all()])
@ -140,6 +140,7 @@ class ConferenceCreateForm(forms.Form):
if data.get('logo'):
conference.logo = data['logo']
conference.org = data['org']
conference.data_begin = data['data_begin']
conference.data_end = data['data_end']
conference.link = data['link']
@ -375,4 +376,16 @@ class TimeTableForm(forms.Form):
class ConferenceFilterForm(AdminFilterForm):
model = Conference
created = forms.DateField(required=False, label='Дата создания')
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.signals import post_save, pre_save
from django.contrib.contenttypes import generic
from django.utils import translation
from exposition.manager import ClientManager
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from functions.translate import fill_with_signal
@ -53,6 +54,7 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
related_name='conference_city')
place = models.ForeignKey('place_conference.PlaceConference', verbose_name='Место проведения',
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='Тематики',
related_name='conference_themes')
tag = models.ManyToManyField('theme.Tag', verbose_name='Теги',
@ -171,6 +173,15 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
def tags(self):
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):
if self.photogallery:
return self.photogallery

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from haystack import indexes
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)
where = indexes.MultiValueField()
url = indexes.CharField()
@ -31,13 +32,6 @@ class ConferenceIndex(indexes.SearchIndex, indexes.Indexable):
def prepare_catalog_name_ru(self, obj):
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):
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/$', ConferenceMembers.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()),

@ -2,7 +2,7 @@
import json
import datetime
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.shortcuts import get_object_or_404
from django.contrib.contenttypes.models import ContentType
@ -287,6 +287,12 @@ class ConferenceThankView(MetadataMixin, DetailView):
slug_field = 'url'
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):
model = Conference
slug_field = 'url'

@ -13,26 +13,32 @@ class SeminarLendingView(TemplateView):
def send_to_organiser(request):
mail_send = 'kotzilla@ukr.net'
mail_send = 'expomap@mail.ru'
fname = request.POST.get('name')
lname = request.POST.get('surname')
email = request.POST.get('email', '')
company = request.POST.get('company', '')
office = request.POST.get('office', '')
phone = request.POST.get('phone', '')
title = request.POST.get('type', '')
text = u"""Имя: %s;
Фамилия:%s;
Email: %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.content_subtype = "html"
msg.send()
redirect_to = '/service/thanks/'
message = u"""Мы получили Ваш запрос и очень рады, что Вам интересно участие в семинаре Expomap. Если места еще есть, мы пришлем Вам приглашение на указанную Вами электронную почту.
Увидимся на welcome-coffee """
if title.endswith(u'семинар'):
message = u"""Мы получили Ваш запрос и очень рады, что Вам интересно участие в семинаре Expomap. Если места еще есть, мы пришлем Вам приглашение на указанную Вами электронную почту.
Увидимся на welcome-coffee """
else:
message = u"""Благодарим за интерес к нашему семинару! За несколько дней до мероприятия мы пришлем Вам ссылку для подключения к онлайн-трансляции!"""
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:
#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():
form.save(country_id)
@ -71,8 +71,9 @@ def country_change(request, url):
else:
#fill form with data from database
data = {'population' : c.population, 'teritory' : c.teritory, #data from NOT translated fields
'timezone' : c.timezone, 'country_id' : country_id,
'phone_code' : c.phone_code, 'time_delivery' : c.time_delivery}
'timezone' : c.timezone, 'country_id' : country_id,
'phone_code' : c.phone_code, 'time_delivery' : c.time_delivery,
'logo': c.logo}
if c.capital:
data['capital'] = c.capital.id

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

@ -93,6 +93,13 @@ class CountryManager(TranslationManager):
cache.set(key, countries, self.cache_time)
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):
def all_sorted(self):

@ -55,6 +55,12 @@ class Area(TranslatableModel):
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):
"""
@ -102,6 +108,7 @@ class Country(TranslatableModel):
descriptions = 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:
ordering = ['translations__name']
@ -145,8 +152,9 @@ class Country(TranslatableModel):
return Webinar.objects.filter(country=self.id).count()
def active_cities(self):
return City.used.active_qs().filter(country=self)
result = list(set(City.used.active_qs().filter(country=self)))
result.sort(key=lambda x:x.name)
return result
lang = translation.get_language()
#return City.objects.select_related('exposition_city')\
# .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'}
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)

@ -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_open_area':obj.min_open_area, 'max_open_area':obj.max_open_area,
'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,
'canceled': obj.canceled, 'moved': obj.moved, 'logo': obj.logo,
'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',
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'^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'])
logo = forms.ImageField(label='Logo', required=False)
organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
#organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
# 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,
choices=[(item.id, item.name) for item in Company.objects.language().all()] )
#company = forms.MultipleChoiceField(label=u'Компании', required=False,
# 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()])
theme = forms.MultipleChoiceField(label='Тематики',
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
city = forms.CharField(label=u'Город', widget=forms.HiddenInput())
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)
audience = forms.MultipleChoiceField(label=u'Аудитория', choices=public, initial='', required=False)
@ -169,7 +169,7 @@ class ExpositionCreateForm(forms.Form):
exposition.theme.clear()
exposition.tag.clear()
exposition.organiser.clear()
exposition.company.clear()
#exposition.company.clear()
#simple fields
if not getattr(exposition, 'url'):
@ -177,6 +177,7 @@ class ExpositionCreateForm(forms.Form):
if data.get('logo'):
exposition.logo = data['logo']
exposition.org = data['org']
exposition.data_begin = data['data_begin']
exposition.data_end = data['data_end']
exposition.periodic = data['periodic']
@ -236,7 +237,7 @@ class ExpositionCreateForm(forms.Form):
exposition.theme.add(*data['theme'])
exposition.tag.add(*Tag.objects.filter(id__in=data['tag']))
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()

@ -1,20 +1,141 @@
# -*- 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 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):
def handle(self, *args, **options):
a = MetaSetting.objects.filter(translations__h1__contains='«').count()
qs = MetaSetting.objects.language('ru').all()
for item in qs:
item.title = item.title.replace(u'«', u'').replace(u'»', u'')
item.description = item.title.replace(u'«', u'').replace(u'»', u'')
item.h1 = item.h1.replace(u'«', u'').replace(u'»', u'')
#item.save()
#expos = Exposition.objects.filter(theme__isnull=True, old_url__isnull=False)
db = MySQLdb.connect(host="localhost",
user="expomap",
passwd="7FbLtAGjse",
db="old_db",
charset='utf8',
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='Организатор',
blank=True, null=True, related_name='exposition_organisers')
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='Компании',
blank=True, null=True, related_name='exposition_companies')
users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки',
@ -299,6 +300,9 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
return code
return cur
def theme_ids(self):
return [item['id'] for item in self.theme.all().values('id')]
class Statistic(TranslatableModel):
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)
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):
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/$', ExpoMembers.as_view(), {'meta_id':63}),
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()),
# expo list
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 -*-
import json
import datetime
from django.http import HttpResponseRedirect, HttpResponse
from django.http import HttpResponseRedirect, HttpResponse, HttpResponsePermanentRedirect
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
@ -182,6 +182,11 @@ class ExpositionThankView(MetadataMixin, DetailView):
slug_field = 'url'
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):
model = Exposition
slug_field = 'url'
@ -289,7 +294,7 @@ MONTHES = settings.MONTHES
class ExpoCatalog(MetadataMixin, ListView):
model = Exposition
paginate_by = settings.CLIENT_PAGINATION
template_name = 'exposition/catalog.html'
template_name = 'client/exposition/catalog.html'
search_form = ExpositionSearchForm
filter_object = None
year = None
@ -440,6 +445,12 @@ class ExpoTagCatalog(ExpoCatalog):
self.filter_object = tag
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):
paginate_by = settings.CLIENT_PAGINATION

@ -31,10 +31,15 @@ def translit_with_separator(string, separator='-'):
#make string unicode
string = string.strip()
string = u'%s'%string
string = string.replace(u'\u200e', '')
#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
st = st.replace('.', '')

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
import copy
import calendar as python_calendar
from service.models import Service
@ -32,8 +34,11 @@ class EventMixin(object):
url = '%s%s/'%(self.get_catalog_url(), self.url)
return url
def org_split(self):
if self.org:
return self.org.split(';')
else:
return []
def get_logo(self):
return self.logo
@ -98,4 +103,43 @@ class EventMixin(object):
if self.data_end.month == month:
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')
sqs = SearchQuerySet().models(Exposition).all()
sqs = SearchQuerySet().models(Exposition, Conference).all()
if 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,\
ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\
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.shortcuts import get_object_or_404
def xls_to_response(xls, fname):
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):
form_class = ImportEventForm
success_url = '/admin/import-event/'
template_name = 'admin/import templates/import_event.html'
def form_valid(self, form):
errors = form.save_file_debug()
messages.success(self.request, 'Success')
context = self.get_context_data()
context['import_errors'] = errors
context['form'] = form
return render_to_response(self.template_name, context)
return HttpResponseRedirect('/admin/import/log/')
#messages.success(self.request, 'Success')
#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):
form_class = ImportThemeForm
@ -131,4 +136,34 @@ class ImportPlaceConference(ImportView):
class ExportEvent(ExportView):
form_class = ExportEventForm
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 admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference
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('',
url(r'^import-event/$', ImportEvent.as_view()),
@ -23,5 +26,8 @@ urlpatterns = patterns('',
url(r'^export-company/$', ExportCompany.as_view()),
url(r'^export-blog/$', ExportBlog.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 ''
def get_date(value):
if value:
return str(value)
return ''
def get_quality(value, field):
flags = {u'UFI': 'ufi', u'РСВЯ': 'rsva', u'EXPORATING': 'exporating'}
v = flags.get(field)
@ -326,19 +321,27 @@ article_sett = {
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 = [
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
{'name': 'name', '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_end', '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': get_date},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place},
{'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000},
{'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000},
{'name': 'description', 'verbose_name': u'Описание события', 'type': unicode},
{'name': 'org', 'verbose_name': u'Организатор №1', 'type': get_int},
{'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic},
{'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience},
{'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'stat_countries', u'func': unicode},
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'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},

@ -106,6 +106,7 @@ def google_address(address):
response = {'address' : results[0].get('formatted_address'),
'lat' : results[0]['geometry']['location']['lat'],
'lng' : results[0]['geometry']['location']['lng']}
#return response
return json.dumps(response)
else:
return ''
@ -113,11 +114,11 @@ def google_address(address):
from djutils.decorators import async
from djutils.queue.decorators import queue_command
# place
class ImportPlaceExpositionForm(ImportForm):
model = PlaceExposition
settings = place_exp_sett
#@async
def save_file(self):
data = self.cleaned_data
lang = data['language']
@ -125,86 +126,113 @@ class ImportPlaceExpositionForm(ImportForm):
book = xlrd.open_workbook(file_contents=f.read())
sheet = book.sheet_by_index(0)
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]]
errors = []
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
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:
object = self.model.objects.language(lang).get(id=int(row[0]))
except ValueError:
object = self.model()
object.translate(lang)
extra = getattr(obj, extra_value)
except Exception:
continue
value = func(cell, 'ru', extra)
except self.model.DoesNotExist:
object = self.model(id= int(row[0]))
object.translate(lang)
else:
# if id blank - its a new event
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)
value = func(cell)
if setting is None:
continue
try:
setattr(obj, field_name, value)
except ValueError, e:
continue
if setting.get('method'):
if cell != "":
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')})
if field_name !='adress':
try:
setattr(obj, field_name, value)
except ValueError:
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')
if func is not None:
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
error = str(e)
if typical_errors.get(error):
error = typical_errors[error]
if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'):
error = u'Место с таким названием или урлом уже существует'
# in function we add language(need for relation fields)
# and extra value from object (like for city need country)
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)
errors.append([obj.name, error])
continue
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:
object.save()
return errors
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):
@ -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'НЕправильный формат или не заполнена дата начала'}
# 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):
"""
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 -*-
import urllib2
import time, xlrd
import os
from PIL import Image
from django.conf import settings
from django.utils import translation
from hvad.utils import get_translation_aware_manager
@ -30,6 +32,7 @@ def to_date(value):
return None
if isinstance(value, unicode) or isinstance(value, str):
try:
t = time.strptime(value, "%d.%m.%Y")
except ValueError:
@ -88,9 +91,13 @@ def to_theme(obj, value):
theme_ids = value.split(',')
if theme_ids == ['']:
return
return u'Неправильное значение'
obj.theme.clear()
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):
if value == [""]:
@ -100,8 +107,7 @@ def to_tag(obj,value):
if names:
obj.tag.clear()
obj.tag.add(*Tag.objects.filter(translations__name__in=names, theme__in=obj.theme.all()))
else:
return
return None
@ -130,6 +136,7 @@ def to_periodic(value):
def to_audience(value, model=Exposition):
if value:
translation.activate('ru')
l = value.split(', ')
if l:
new_list = []
@ -165,7 +172,7 @@ def save_logo(obj, path):
try:
alt_name = get_alternative_filename(full_path, file_name)
except UnicodeEncodeError:
return None
return u'Некоректное название файла'
download_to = full_path+alt_name
@ -181,9 +188,9 @@ def save_logo(obj, path):
return None
try:
response = urllib2.urlopen(url, timeout=15)
response = urllib2.urlopen(url, timeout=5)
except:
return None
return u'Превышено время ожидания'
with open(download_to,'wb') as f:
try:
@ -191,14 +198,20 @@ def save_logo(obj, path):
f.close()
except:
# 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
try:
obj.save()
except:
print('logo exception. logo: %s'%obj.logo)
return None
return u'Неизвестная ошибка'
@ -207,10 +220,10 @@ def check_quality_label(obj, value, label):
try:
value = int(value)
except:
return bit
return None
if value:
setattr(bit, label, True)
return bit
return None
def to_user(value):
try:

@ -19,6 +19,7 @@ urlpatterns = required(
url(r'^company/', include('company.admin_urls')),
url(r'^conference/', include('conference.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'^news/', include('news.admin_urls')),
url(r'^organiser/', include('organiser.admin_urls')),
@ -32,6 +33,8 @@ urlpatterns = required(
url(r'^webinar/', include('webinar.admin_urls')),
url(r'^settings/', include('settings.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'^currency/add/', 'directories.admin.currency_add'),
# ajax requests

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

@ -11,6 +11,9 @@ class Robot(TemplateView):
template_name = 'robots.txt'
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,\
ConfTag, NewsSiteMap, BlogsSiteMap, Additional, Important
@ -26,8 +29,6 @@ sitemaps = {
handler404 = 'proj.views.error404'
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'^__debug__/', include(debug_toolbar.urls)),
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-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}),
url(r'^robots.txt$', Robot.as_view()),
url(r'^yandex_4c326c16c916403e.html$', YandexCheck.as_view()),
url(r'^$', MainPageView.as_view()),
url(r'^page/', include('core.simple_urls')),
url(r'^theme/', include('theme.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('exposition.urls')),
url(r'^', include('settings.conference_old_urls')), # conference redirects from old version
@ -76,6 +80,7 @@ urlpatterns = patterns('',
# ajax urls
urlpatterns += patterns('',
url(r'^ajax/get_popover/$', 'settings.views.get_popover_info'),
url(r'^registration/reply/$', 'registration.backends.default.views.RegisterReply'),
url(r'^register/', 'registration.backends.default.views.RegisterAjaxView'),
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()
conf_themes = Theme.active.conference_themes_with_count()
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):
@ -76,7 +78,7 @@ class MainPageView(JitterCacheMixin, TemplateView):
def get_context_data(self, **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]
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.conf import settings
from django.contrib.auth.decorators import login_required
from django.views.generic import ListView, FormView
#models and forms
from models import Service
from forms import ServiceForm, ServiceDeleteForm
@ -114,3 +115,30 @@ def get_city(request):
return render_to_response('checkbox_option.html', {'options': cities})
else:
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 views import CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \
ParticipationListView, RemoteListView,TicketsListView
from service.admin import ServiceControlList, ServiceControl
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'^delete/(?P<url>.*)/$', 'service_delete'),
url(r'^change/(?P<url>.*)/$', 'service_change'),
@ -17,6 +20,6 @@ urlpatterns = patterns('service.admin',
url(r'order/tickets/$', TicketsListView.as_view()),
#ajax
url(r'^get_city/$', 'get_city'),
#url(r'^get_country/$', 'get_country'),
#url(r'^get_country/$', 'get_country'),
)

@ -121,4 +121,29 @@ class ServiceDeleteForm(forms.ModelForm):
class Meta:
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):
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 functions.signal_handlers import post_save_handler
@ -105,6 +156,7 @@ class Translation(AbstractOrder):
languages = models.TextField(blank=True)
themes = models.TextField(blank=True)
class Visit(AbstractOrder):
fr = models.DateField()
to = models.DateField()

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

@ -156,6 +156,18 @@ def timetable_by_day(qs, day):
def random_social(value):
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
def fourth(value):
# return almost in 75% cases True in 25% False
@ -224,7 +236,10 @@ def without_page(value):
@register.filter
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
def isdigit(value):
@ -282,4 +297,13 @@ 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_conference.models import PlaceConference
from company.models import Company
import datetime
from conference.models import Conference
# every this model must have method get_subcategories
categories = {'area':{'sub':True, 'model':Area, 'sub_categorie_name':'co'},
@ -44,19 +44,22 @@ def search_autocomplete(request):
term = request.GET['term']
form = request.GET['form']
if form == 'place':
areas = [{'text':item.name, 'id':item.id, 'name':'area'} for item in Area.objects.filter(translations__name__contains=term)]
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()]
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()]
objects = areas + countries + cities
return HttpResponse(json.dumps(objects), content_type='application/json')
qs = list(SearchQuerySet().models(Country, City, Area).autocomplete(content_auto=term)[:6])
objects = [{'text':get_by_lang(item, 'name', lang), 'id': item.pk, 'name': item.form_name} for item in qs]
#areas = [{'text':item.name, 'id':item.id, 'name':'area'} for item in Area.objects.filter(translations__name__contains=term)]
#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()]
#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()]
#objects = areas + countries + cities
return HttpResponse(json.dumps(objects, indent=4), content_type='application/json')
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)]
return HttpResponse(json.dumps(objects), content_type='application/json')
return HttpResponse(json.dumps(objects, indent=4), content_type='application/json')
else:
return HttpResponse("Doesn't implemented yet")
return HttpResponse("Don't implemented yet")
else:
@ -87,29 +90,28 @@ def get_by_lang(item, field, lang='en'):
:return:
"""
return getattr(item, field+'_'+lang)
import datetime
def expo_autosearch(request):
if request.GET:
lang = translation.get_language()
term = request.GET['term']
term = term.strip()
d = datetime.date.today()
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])
res = expos + themes
confs = list(SearchQuerySet().models(Conference).filter(data_end__gte=d).autocomplete(content_auto=term).order_by('data_begin','text')[:6])
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),
'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,
'id':item.pk,
'name': item.form_name} for item in res]
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:
raise Http404
def place_autosearch(request):
if request.GET:
lang = translation.get_language()
@ -129,4 +131,52 @@ def company_autosearch(request):
result = sorted(result, key=lambda x:x['cat'])
return HttpResponse(json.dumps(result), content_type='application/json')
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(){
/*
$('#id_created').datetimepicker({
todayHighlight: true,
format : 'yyyy-mm-dd',
minView:2
});
*/
$('#photo_form').on('submit', function(e){
e.preventDefault();
var url = $(this).attr('action');
@ -230,11 +236,7 @@ $(document).ready(function(){
});
// 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'>
{# The fav icon #}
<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 %}
{% endblock %}
@ -72,7 +76,7 @@
</div>
</body>
<script src="{% static 'custom_js/main.js' %}"></script>
{% block bot_scripts %}
{% endblock %}
</html>

@ -17,7 +17,7 @@
{% block body %}
{# 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>
<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>
<div class="controls">{{ form.country}}</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 #}
{% with field='region' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}

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

@ -1,12 +1,19 @@
{% extends 'admin_list.html' %}
{% 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 %}
{% block body %}
<div class="box span8">
@ -30,11 +37,16 @@
<div class="box-content">
<table class="table table-hover">
<col width="25%">
<col width="15%">
<col width="35%">
<col width="25%">
<thead>
<tr>
<th>Название</th>
<th>Дата начала</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
@ -42,30 +54,28 @@
<tr>
<td>{{ item.name }}</td>
<td>{{ item.data_begin }}</td>
<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;">
<a class="btn-small btn-warning off" style="{% if item.is_published %}{% else %}display: none;{% endif %}"
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 %}"
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>
</td>
<td class="center sorting_1">
<a class="btn-small btn-info" href="/admin/conference/{{ item.url|lower }}">
Изменить
<a class="btn-small btn-danger" href="/admin/conference/delete/{{ item.url|lower }}">
Удалить
</a>
</td>
<td>
<a class="btn-small btn-danger" href="/admin/conference/delete/{{ item.url|lower }}">
Удалить
</a>
</td>
</tr>
@ -77,4 +87,33 @@
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</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 %}

@ -41,6 +41,13 @@
{% with field='description' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
{% 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 #}
<div class="control-group {% if form.capital.errors %}error{% endif %}">
<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 #}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<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>
<!--
{# 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">
$(document).ready(function(){
$('#id_data_begin').datetimepicker({
@ -226,6 +210,13 @@
<span class="help-inline">{{ form.web_page.errors }}</span>
</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 #}
{% with field='products' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %}
@ -374,32 +365,6 @@
</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-header well">
<h2><i class="icon-pencil"></i>Деловая программа</h2>

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

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

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

@ -12,6 +12,7 @@
<li class="divider"></li>
<li><a href="/admin/import-event">Импорт</a></li>
<li><a href="/admin/export-event">Экспорт</a></li>
<li><a href="/admin/import/log/">Архив логов</a></li>
</ul>
</li>
@ -104,6 +105,13 @@
</ul>
</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>
</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 %}
{% block bot_scripts %}
<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>
<script src="{% static 'custom_js/find_events.js' %}"></script>
{% 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>
<td>{{ item.id }}</td>
{% for u in item.user.all %}
<td>{{ u }}</td>
<td>{{ u.country }}</td>
{% endfor %}
<td>{{ item.get_full_name }}</td>
<td>{{ item.profile.country.name }}</td>
<td class="center sorting_1">
<a class="btn btn-info" href="/admin/translator/change/{{ item.id }}">

@ -28,6 +28,7 @@
<th>id</th>
<th>Пользователь</th>
<th>Страна</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
@ -35,10 +36,8 @@
<tr>
<td>{{ item.id }}</td>
{% for u in item.user.all %}
<td>{{ u.get_full_name }}</td>
<td>{{ u.profile.country.name }}</td>
{% endfor %}
<td>{{ item.get_full_name }}</td>
<td>{{ item.profile.country.name }}</td>
<td class="center sorting_1">
<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 i18n %}
{% load template_filters %}
{% get_current_language as LANGUAGE_CODE %}
{% comment %}
This template include basic anf main styles and js files,
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]-->
<head>
{% 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="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('send', 'pageview');
</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>
<body {% block body_class %}{% endblock %}>
@ -147,7 +165,7 @@ This template include basic anf main styles and js files,
{% include 'client/includes/footer.html' %}
{% endblock %}
</div>
<div class="popups-wrap">
<div class="popups-wrap" id="main-popup-wrap">
{% if not user.is_authenticated %}
{% include 'client/popups/login.html' %}
{% include 'client/popups/register.html' %}
@ -156,7 +174,92 @@ This template include basic anf main styles and js files,
{% endif %}
{% 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 'partial_pipeline' not in request.session %}
{% include 'client/popups/acquire_email.html' %}

@ -1,5 +1,6 @@
{% extends 'base_catalog.html' %}
{% load i18n %}
{% load template_filters %}
{% block bread_scrumbs %}
<div class="bread-crumbs">
@ -25,4 +26,87 @@
{% 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 template_filters %}
<div class="abn">
{% if False|fourth %}
<a target="_blank" href="/redirect/redirect/21/"><img src="{% static 'client/img/partners/unnamed.gif' %}" alt="" /></a>
{% else %}
<a target="_blank" href="/redirect/redirect/23/"><img src="{% static 'client/img/partners/unnamed_1.gif' %}" alt="" /></a>
{% endif %}
{% with r=False|random4 %}
{% ifequal r 0 %}
<a target="_blank" href="/redirect/redirect/57/"><img src="{% static 'client/img/partners/cemat15_900x130_bilet.gif' %}" alt="" /></a>
{% endifequal %}
{% 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>

@ -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>
</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 %}
<hr />
<div class="i-buttons clearfix">
@ -152,7 +160,20 @@
{% endfor %}
{% endwith %}
</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 %}
{% if event.web_page %}
<dt>{% trans 'Веб-сайт' %}:</dt>
<dd>

@ -19,7 +19,7 @@
<span class="visitors" title="Посетители">{{ exposition.visitors }}</span>
{% endif %}
{% if exposition.members %}
<span class="participants" title="Участники">{{ exposition.members }}</span>
<span classlinkebreaksbr="participants" title="Участники">{{ exposition.members }}</span>
{% endif %}
</div>
<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>
</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 %}
<hr />
<div class="i-buttons clearfix">
@ -159,12 +168,17 @@
</dd>
{% else %}
{% if exposition.org %}
<dt>{% trans 'Организатор' %}:</dt>
<dd>
{{ exposition.org }}
</dd>
{% for item in exposition.org_split %}
<dt>{% if forloop.counter == 1 %}{% trans 'Организатор' %}:{% endif %}</dt>
<dd>
{{ item }}
</dd>
{% endfor %}
{% endif %}
{% endif %}
{% if exposition.web_page %}
<dt>{% trans 'Веб-сайт' %}:</dt>
<dd>

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

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

Loading…
Cancel
Save