Merged branches

remotes/origin/1203
Назар Котюк 11 years ago
commit 0a97d52be9
  1. 2
      .gitignore
  2. 26
      accounts/edit_forms.py
  3. 20
      accounts/forms.py
  4. 117
      accounts/models.py
  5. 1
      accounts/urls.py
  6. 10
      accounts/user_catalog_urls.py
  7. 101
      accounts/views.py
  8. 9
      article/admin.py
  9. 46
      article/forms.py
  10. 139
      article/models.py
  11. 22
      article/urls.py
  12. 165
      article/views.py
  13. 2
      city/admin.py
  14. 2
      city/forms.py
  15. 22
      city/management/commands/city_slug.py
  16. 30
      city/management/commands/city_update_from_old.py
  17. 26
      city/models.py
  18. 40
      company/edit_forms.py
  19. 82
      company/edit_views.py
  20. 2
      company/forms.py
  21. 15
      company/models.py
  22. 5
      company/search_indexes.py
  23. 50
      company/urls.py
  24. 53
      company/views.py
  25. 84
      conference/admin.py
  26. 14
      conference/admin_urls.py
  27. 100
      conference/forms.py
  28. 170
      conference/models.py
  29. 29
      conference/search_indexes.py
  30. 75
      conference/urls.py
  31. 451
      conference/views.py
  32. 12
      core/simple_index_view.py
  33. 39
      country/management/commands/country_update_from_old.py
  34. 105
      country/manager.py
  35. 78
      country/models.py
  36. 48
      exposition/admin.py
  37. 5
      exposition/admin_urls.py
  38. 69
      exposition/forms.py
  39. 201
      exposition/management/commands/expo_old.py
  40. 60
      exposition/management/commands/expo_organiser.py
  41. 77
      exposition/management/commands/expo_test.py
  42. 40
      exposition/management/commands/exposition_load.py
  43. 89
      exposition/management/commands/fix_logo.py
  44. 68
      exposition/management/commands/imp_stat.py
  45. 20
      exposition/management/commands/test.py
  46. 5
      exposition/manager.py
  47. 114
      exposition/models.py
  48. 5
      exposition/search_indexes.py
  49. 124
      exposition/urls.py
  50. 176
      exposition/views.py
  51. 4
      file/forms.py
  52. 3
      file/models.py
  53. 2
      functions/admin_forms.py
  54. 5
      functions/admin_views.py
  55. 50
      functions/cache_mixin.py
  56. 13
      functions/custom_views.py
  57. 2
      functions/form_check.py
  58. 5
      functions/model_mixin.py
  59. 114
      functions/models_methods.py
  60. 53
      functions/search_forms.py
  61. 2
      functions/signal_handlers.py
  62. 13
      functions/translate.py
  63. 15
      import_xls/admin.py
  64. 4
      import_xls/admin_urls.py
  65. 32
      import_xls/excel_settings.py
  66. 22
      import_xls/export_forms.py
  67. 48
      import_xls/utils.py
  68. 57
      meta/admin.py
  69. 11
      meta/admin_urls.py
  70. 23
      meta/decorators.py
  71. 48
      meta/forms.py
  72. 88
      meta/models.py
  73. 51
      meta/views.py
  74. 31
      organiser/management/commands/organiser_from_old_db.py
  75. 1
      organiser/models.py
  76. 114
      password_reset/templates/password_reset/recovery_email_expo.html
  77. 38
      password_reset/views.py
  78. 27
      place_exposition/admin.py
  79. 3
      place_exposition/admin_urls.py
  80. 22
      place_exposition/forms.py
  81. 8
      place_exposition/management/commands/convert_logo.py
  82. 165
      place_exposition/management/commands/place_exposition_load.py
  83. 44
      place_exposition/models.py
  84. 15
      place_exposition/urls.py
  85. 32
      place_exposition/views.py
  86. 52
      proj/admin.py
  87. 4
      proj/admin_urls.py
  88. 4
      proj/production.py
  89. 194
      proj/settings.py
  90. 141
      proj/sitemaps.py
  91. 78
      proj/urls.py
  92. 52
      proj/views.py
  93. 39
      registration/backends/default/views.py
  94. 31
      registration/forms.py
  95. 36
      registration/models.py
  96. 7
      service/forms.py
  97. 37
      service/models.py
  98. 32
      service/order_forms.py
  99. 12
      service/urls.py
  100. 55
      service/views.py
  101. Some files were not shown because too many files have changed in this diff Show More

2
.gitignore vendored

@ -11,3 +11,5 @@ Thumbs.db
npm-debug.log npm-debug.log
/proj/local.py /proj/local.py

@ -60,17 +60,22 @@ class HomeForm(forms.ModelForm):
class WorkForm(forms.ModelForm): class WorkForm(forms.ModelForm):
position = forms.CharField(label=_(u'Укажите вашу должность'), position = forms.CharField(label=_(u'Укажите вашу должность'),
required=False, widget=forms.TextInput()) required=False, widget=forms.TextInput())
company = forms.CharField(label=_(u'Укажите вашу компанию'), required=False,
widget=forms.HiddenInput(attrs={'class': 'select2'}))
company = forms.CharField(label=_(u'Место работы'), widget=forms.HiddenInput(attrs={'class': 'select2'}))
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(WorkForm, self).__init__(*args, **kwargs) super(WorkForm, self).__init__(*args, **kwargs)
if self.instance.company: if self.instance.company:
self.fields['company'].widget = forms.HiddenInput(attrs={'class': 'select2', 'data-init-text': self.instance.company.name}) self.fields['company'].widget = forms.HiddenInput(attrs={'class': 'select2', 'data-init-text': self.instance.company.name})
class Meta: class Meta:
model = User model = User
fields = ('position', 'company') fields = ('position', 'company')
def clean_company(self): def clean_company(self):
if not self.cleaned_data.get('company'):
return None
try: try:
return Company.objects.get(id=self.cleaned_data['company']) return Company.objects.get(id=self.cleaned_data['company'])
except Company.DoesNotExist: except Company.DoesNotExist:
@ -87,9 +92,26 @@ class AboutCompanyForm(forms.ModelForm):
class PhoneForm(forms.ModelForm): class PhoneForm(forms.ModelForm):
phone = forms.CharField(label=_(u'Контактный телефон'), required=False) phone = forms.CharField(label=_(u'Контактный телефон'), required=False)
show_phone = forms.BooleanField(label=_(u'Контактный телефон'), required=False)
class Meta: class Meta:
model = Profile model = Profile
fields = ('phone',) fields = ('phone', 'show_phone')
def clean_phone(self):
phone = self.cleaned_data['phone']
if not phone:
return
deduct = ('-','(',')','.',' ', '+')
for elem in deduct:
phone = phone.replace(elem, '')
if phone.isdigit():
return phone
else:
raise forms.ValidationError(_(u'Введите правильный телефон'))
class EmailForm(forms.ModelForm): class EmailForm(forms.ModelForm):
email = forms.EmailField(label=_(u'Ваш e-mail'), required=False) email = forms.EmailField(label=_(u'Ваш e-mail'), required=False)

@ -218,10 +218,10 @@ class EmailAnnouncementForm(forms.Form):
class RegistrationCompleteForm(forms.ModelForm): class RegistrationCompleteForm(forms.ModelForm):
country = forms.ChoiceField(label='Страна', choices=[(c.id, c.name) for c in Country.objects.all()], country = forms.ModelChoiceField(label='Страна', queryset= Country.objects.all(),
widget=forms.Select(attrs={'class': 'select2'})) widget=forms.Select(attrs={'class': 'select2'}))
city = forms.CharField(label='Город', widget=forms.HiddenInput()) city = forms.CharField(label='Город', widget=forms.HiddenInput())
url = forms.CharField(widget=forms.TextInput(attrs={'placeholder': _(u'адрес страны(обязательно)')})) url = forms.CharField(widget=forms.TextInput(attrs={'placeholder': _(u'url(обязательно)')}))
code_country = forms.ChoiceField(label=_(u'код страны'), initial='70', code_country = forms.ChoiceField(label=_(u'код страны'), initial='70',
choices=[(str(c.phone_code), '+'+str(c.phone_code)) for c in Country.objects.all() if c.phone_code is not None], choices=[(str(c.phone_code), '+'+str(c.phone_code)) for c in Country.objects.all() if c.phone_code is not None],
@ -254,12 +254,6 @@ class RegistrationCompleteForm(forms.ModelForm):
return None return None
def clean_country(self):
try:
return Country.objects.get(id=self.cleaned_data['country'])
except City.DoesNotExist:
return None
def clean_url(self): def clean_url(self):
url = self.cleaned_data['url'] url = self.cleaned_data['url']
if not is_latin(url): if not is_latin(url):
@ -317,18 +311,14 @@ class FeedFilterForm(forms.Form):
th = forms.MultipleChoiceField(label=_(u'Тематика'), choices=[(item.id, item.name) for item in Theme.active.all()], th = forms.MultipleChoiceField(label=_(u'Тематика'), choices=[(item.id, item.name) for item in Theme.active.all()],
required=False, widget=forms.CheckboxSelectMultiple()) required=False, widget=forms.CheckboxSelectMultiple())
tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple()) tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple())
area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.all_sorted()], area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.language().all()],
required=False, widget=forms.CheckboxSelectMultiple()) required=False, widget=forms.CheckboxSelectMultiple())
co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(), co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\ choices=[(item.id, item.name) for item in Country.objects.expo_countries()]
.filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
) )
ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(), ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in City.objects.select_related('exposition_city')\ choices=[(item.id, item.name) for item in City.used.expo_cities()]
.filter(exposition_city__city__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
) )
fr = forms.DateField(required=False, fr = forms.DateField(required=False,

@ -132,8 +132,7 @@ class User(AbstractBaseUser, PermissionsMixin):
translator = models.ForeignKey('translator.Translator', verbose_name='Переводчик', blank=True, null=True, translator = models.ForeignKey('translator.Translator', verbose_name='Переводчик', blank=True, null=True,
unique=True, unique=True,
on_delete=models.PROTECT, related_name='user') on_delete=models.PROTECT, related_name='user')
company = models.ForeignKey('company.Company', blank=True, null=True, company = models.ForeignKey('company.Company', blank=True, null=True, related_name='users')
on_delete=models.PROTECT, related_name='users')
position = models.CharField(verbose_name='Должность', max_length=255, blank=True) position = models.CharField(verbose_name='Должность', max_length=255, blank=True)
objects = UserManager() objects = UserManager()
@ -223,6 +222,23 @@ class User(AbstractBaseUser, PermissionsMixin):
""" """
return self.seminar_users.language().select_related('country', 'city').all() return self.seminar_users.language().select_related('country', 'city').all()
def remove_from_calendar(self, data):
expo = data['expo']
conf = data['conf']
seminar = data['seminar']
webinar = data['webinar']
calendar = self.calendar
if expo:
calendar.expositions.remove(*expo)
if conf:
calendar.conferences.remove(*conf)
if seminar:
calendar.seminars.remove(*seminar)
if webinar:
calendar.webinars.remove(*webinar)
class Profile(models.Model): class Profile(models.Model):
@ -237,15 +253,16 @@ class Profile(models.Model):
on_delete=models.PROTECT) on_delete=models.PROTECT)
about_company = models.TextField(verbose_name=_(u'Описание компании'), blank=True) about_company = models.TextField(verbose_name=_(u'Описание компании'), blank=True)
phone = models.BigIntegerField(verbose_name='Телефон', blank=True, null=True) phone = models.BigIntegerField(verbose_name=_(u'Телефон'), blank=True, null=True)
show_phone = models.NullBooleanField(verbose_name=_(u'Показывать телефон'), blank=True, null=True, default=1)
web_page = models.URLField(verbose_name='Вебсайт',blank=True) web_page = models.URLField(verbose_name='Вебсайт',blank=True)
about = models.TextField(verbose_name='О себе', blank=True) about = models.TextField(verbose_name='О себе', blank=True)
avatar = models.ImageField(verbose_name='Фото', upload_to='accounts/avatar/', blank=True) avatar = models.ImageField(verbose_name='Фото', upload_to='accounts/avatar/', blank=True)
skype = models.CharField(blank=True, max_length=255) skype = models.CharField(blank=True, max_length=255)
facebook = models.URLField(verbose_name=_(u'Facebook'), blank=True) facebook = models.URLField(verbose_name=_(u'Facebook'), blank=True, max_length=255)
twitter = models.URLField(verbose_name=_(u'Twitter'), blank=True) twitter = models.URLField(verbose_name=_(u'Twitter'), blank=True,max_length=255)
linkedin = models.URLField(verbose_name=_(u'LinkedIn'), blank=True) linkedin = models.URLField(verbose_name=_(u'LinkedIn'), blank=True, max_length=255)
vk = models.URLField(verbose_name=_(u'В контакте'), blank=True) vk = models.URLField(verbose_name=_(u'В контакте'), blank=True, max_length=255)
# meta # meta
title = models.CharField(max_length=255, blank=True) title = models.CharField(max_length=255, blank=True)
@ -385,86 +402,10 @@ def create_user_inf(sender, instance, created, **kwargs):
calculate_rating(instance) calculate_rating(instance)
post_save.connect(create_user_inf, sender=User) def post_profile(sender, instance, created, **kwargs):
user = instance.user
#need import after User Model, because User imported in "organiser.models" calculate_rating(user)
#from organiser.models import Organiser
'''
def create_profiles(sender, **kw):
"""
create Translator profile if "is_translator" field in User model true
if it's false delete Translator profile connected to User
create Organiser profile if "is_organiser" field in User model true
if it's false delete Organiser profile connected to User
"""
user = kw["instance"]
if user.is_translator and not user.translator.all():
#check flag is_translator and if translator profile already exist
translator = TranslatorProfile(user=user)
translator.save()
if not user.is_translator:
TranslatorProfile.objects.filter(user = user).delete()
if user.is_organiser and not user.organiser.all():
#check flag is_organiser and if organiser profile already exist
organiser = Organiser(user=user)
if user.country:
organiser.country = user.country
if user.city:
organiser.city = user.city
organiser.save()
data = {'name_ru':user.get_full_name()}
zero_fields = {}
fill_trans_fields_all(Organiser, organiser, data, None, zero_fields)
#populate empty fields and fields which was already populated
organiser_id = getattr(organiser, 'id')
populate_all(Organiser, data, organiser_id, zero_fields)
if not user.is_organiser:
Organiser.objects.filter(user = user).delete()
post_save.connect(create_profiles, sender=User)
'''
"""
class MyUserAuthBackend(object):
def check_md5_password(self, db_password, supplied_password):
return md5(supplied_password).hex_digest(), db_password
def authenticate(self, username=None, password=None, **kwargs):
# Authenticate a user based on email address as the user name.
UserModel = get_user_model()
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
try:
user = UserModel._default_manager.get_by_natural_key(username)
if check_password(password, user.password):
# user.set_password(password)
# user.save()
return user
#if user.check_password(password):
# return user
except UserModel.DoesNotExist:
return None
post_save.connect(create_user_inf, sender=User)
post_save.connect(post_profile, sender=Profile)
def get_user(self, user_id):
try:
UserModel = get_user_model()
return UserModel._default_manager.get(pk=user_id)
except UserModel.DoesNotExist:
return None
"""

@ -15,6 +15,7 @@ urlpatterns = patterns('',
url(r'^profile/$', login_required(ProfileView.as_view())), url(r'^profile/$', login_required(ProfileView.as_view())),
url(r'^profile/company/$', login_required(ProfileCompanyView.as_view())), url(r'^profile/company/$', login_required(ProfileCompanyView.as_view())),
url(r'^profile/settings/$', login_required(SettingsView.as_view())), url(r'^profile/settings/$', login_required(SettingsView.as_view())),
url(r'^profile/calendar/remove/$', 'accounts.views.remove_from_calendar'),
url(r'^profile/calendar/$', login_required(CalendarView.as_view())), url(r'^profile/calendar/$', login_required(CalendarView.as_view())),
url(r'^profile/feed/page/(?P<page>\d+)/$', Feed.as_view()), url(r'^profile/feed/page/(?P<page>\d+)/$', Feed.as_view()),
url(r'^profile/feed/$', login_required(Feed.as_view())), url(r'^profile/feed/$', login_required(Feed.as_view())),

@ -3,14 +3,14 @@ from django.contrib.auth.decorators import login_required
from views import SettingsView, ProfileView, CalendarView, UserView, UserExpositionsView, UserConferenceView, UserSeminarView from views import SettingsView, ProfileView, CalendarView, UserView, UserExpositionsView, UserConferenceView, UserSeminarView
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^(?P<url>.*)/expositions/(?P<page>\d+)/$', UserExpositionsView.as_view()), url(r'^(?P<url>.*)/expositions/(?P<page>\d+)/$', UserExpositionsView.as_view(), {'meta_id': 72}),
url(r'^(?P<url>.*)/expositions/$', UserExpositionsView.as_view()), url(r'^(?P<url>.*)/expositions/$', UserExpositionsView.as_view(), {'meta_id': 72}),
url(r'^(?P<url>.*)/seminars/(?P<page>\d+)/$', UserSeminarView.as_view()), url(r'^(?P<url>.*)/seminars/(?P<page>\d+)/$', UserSeminarView.as_view()),
url(r'^(?P<url>.*)/seminars/$', UserSeminarView.as_view()), url(r'^(?P<url>.*)/seminars/$', UserSeminarView.as_view()),
url(r'^(?P<url>.*)/conferences/(?P<page>\d+)/$', UserConferenceView.as_view()), url(r'^(?P<url>.*)/conferences/(?P<page>\d+)/$', UserConferenceView.as_view(), {'meta_id': 73}),
url(r'^(?P<url>.*)/conferences/$', UserConferenceView.as_view()), url(r'^(?P<url>.*)/conferences/$', UserConferenceView.as_view(), {'meta_id': 73}),
url(r'^(?P<url>.*)/events/(?P<page>\d+)/$', UserView.as_view()), url(r'^(?P<url>.*)/events/(?P<page>\d+)/$', UserView.as_view()),
url(r'^(?P<url>.*)/events/$', UserView.as_view()), url(r'^(?P<url>.*)/events/$', UserView.as_view()),
url(r'^(?P<url>.*)/$', UserView.as_view()), url(r'^(?P<url>.*)/$', UserView.as_view(), {'meta_id': 71}),
) )

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import dateutil.relativedelta as rdelta
import json, datetime import json, datetime
import calendar as python_calendar import calendar as python_calendar
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
@ -55,7 +56,7 @@ class CalendarView(TemplateView):
""" """
context = super(CalendarView, self).get_context_data(**kwargs) context = super(CalendarView, self).get_context_data(**kwargs)
now = timezone.now().replace(microsecond=0, second=0, minute=0, hour=0) now = datetime.datetime.now().replace(microsecond=0, second=0, minute=0, hour=0)
context['current_day'] = now context['current_day'] = now
year = self.request.GET.get('year') year = self.request.GET.get('year')
@ -69,8 +70,8 @@ class CalendarView(TemplateView):
# events in current months # events in current months
number_of_days = python_calendar.monthrange(now.year, now.month)[1] number_of_days = python_calendar.monthrange(now.year, now.month)[1]
# number of days in current month # number of days in current month
days = [timezone.make_aware(datetime.datetime(now.year, now.month, i+1), timezone.get_default_timezone()) for i in range(number_of_days)] days = [datetime.datetime(now.year, now.month, i+1) for i in range(number_of_days)]
context['days'] = days #context['days'] = days
calendar = self.request.user.calendar calendar = self.request.user.calendar
# events in current month # events in current month
@ -78,17 +79,33 @@ class CalendarView(TemplateView):
else: else:
number_of_days = python_calendar.monthrange(year, month)[1] number_of_days = python_calendar.monthrange(year, month)[1]
days = [timezone.make_aware(datetime.datetime(year, month, i+1), timezone.get_default_timezone()) for i in range(number_of_days)] days = [datetime.datetime(year, month, i+1) for i in range(number_of_days)]
# number of days in current month # number of days in current month
context['days'] = days #context['days'] = days
calendar = self.request.user.calendar calendar = self.request.user.calendar
now = now.replace(year=year, month=month, day=1) now = now.replace(year=year, month=month, day=1)
# events in current month # events in current month
context['events'] = calendar.events_by_month(now) context['events'] = calendar.events_by_month(now)
# add days from previous mondey to next sunday
first_day = days[0]
if first_day.weekday() != 0:
past_monday = first_day + rdelta.relativedelta(days=-1, weekday=rdelta.MO(-1))
a = [past_monday + datetime.timedelta(days=x) for x in range((first_day - past_monday).days)]
days = a + days
last_day = days[-1]
if last_day != 6:
next_sunday = last_day + rdelta.relativedelta(days=1, weekday=rdelta.SU(+1))
b = [last_day + datetime.timedelta(days=x+1) for x in range((next_sunday - last_day).days)]
days += b
events = context['events'] events = context['events']
days = context['days'] context['days'] = days
#days = context['days']
event_in_day = False event_in_day = False
counter = 0 counter = 0
dates_with_events = [] dates_with_events = []
@ -190,21 +207,27 @@ class ProfileCompanyView(TemplateView):
from meta.views import MetadataMixin
class UserView(TemplateView): class UserView(MetadataMixin, TemplateView):
""" """
display user information for another users display user information for another users
""" """
template_name = 'accounts/user.html' template_name = 'client/accounts/user.html'
def get_context_data(self, **kwargs): def get_user(self):
context = super(UserView, self).get_context_data(**kwargs)
url = self.kwargs.get('url') url = self.kwargs.get('url')
try: try:
url = int(url) url = int(url)
user = get_object_or_404(User, id=url) user = get_object_or_404(User, id=url)
except ValueError: except ValueError:
user = get_object_or_404(User, url=url) user = get_object_or_404(User, url=url)
self.kwargs['user_full_name'] = user.get_full_name()
return user
def get_context_data(self, **kwargs):
user = self.get_user()
context = super(UserView, self).get_context_data(**kwargs)
if user == self.request.user: if user == self.request.user:
profile = user.profile profile = user.profile
@ -213,11 +236,9 @@ class UserView(TemplateView):
'home_form': HomeForm(instance=profile), 'work_form': WorkForm(instance=user), 'home_form': HomeForm(instance=profile), 'work_form': WorkForm(instance=user),
'about_company_form': AboutCompanyForm(instance=profile), 'phone_form': PhoneForm(instance=profile), 'about_company_form': AboutCompanyForm(instance=profile), 'phone_form': PhoneForm(instance=profile),
'email_form': EmailForm(instance=user), 'web_page_form': WebPageForm(instance=profile), 'email_form': EmailForm(instance=user), 'web_page_form': WebPageForm(instance=profile),
'social_form': SocialForm(instance=profile), 'about_form': AboutForm(instance=profile) 'social_form': SocialForm(instance=profile), 'about_form': AboutForm(instance=profile),
'company_form': CreateCompanyForm()
} }
if not user.company:
company_form = {'company_form': CreateCompanyForm()}
context.update(company_form)
context.update(profile_forms) context.update(profile_forms)
@ -246,8 +267,8 @@ class BaseProfileView(ProfileInvalidView):
def form_valid(self, form): def form_valid(self, form):
profile = self.request.user.profile profile = self.request.user.profile
form = self.form_class(self.request.POST, instance=profile) form = self.form_class(self.request.POST, instance=profile)
form.save() profile = form.save()
response = {'success': True} response = {'success': True, 'rating': profile.user.rating}
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
class WorkView(ProfileInvalidView): class WorkView(ProfileInvalidView):
@ -260,10 +281,10 @@ class WorkView(ProfileInvalidView):
user = self.request.user user = self.request.user
form = self.form_class(self.request.POST, instance=user) form = self.form_class(self.request.POST, instance=user)
user = form.save() user = form.save()
company = user.company #company = user.company
response = {'success': True, 'url':company.get_permanent_url()} #response = {'success': True, 'url':company.get_permanent_url()}
response = {'success': True, 'rating': user.rating}
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
@ -278,10 +299,10 @@ class AvatarView(BaseProfileView):
def form_valid(self, form): def form_valid(self, form):
profile = self.request.user.profile profile = self.request.user.profile
form = self.form_class(self.request.POST, self.request.FILES, instance=profile) form = self.form_class(self.request.POST, self.request.FILES, instance=profile)
form.save() profile = form.save()
if self.request.is_ajax(): if self.request.is_ajax():
im = get_thumbnail(profile.avatar, '100x100', crop='center') im = get_thumbnail(profile.avatar, '100x100', format="PNG")
response = {'success': True, 'url': im.url} response = {'success': True, 'url': im.url, 'rating': profile.user.rating}
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
else: else:
return HttpResponseRedirect('/profile/') return HttpResponseRedirect('/profile/')
@ -337,8 +358,8 @@ class NameView(ProfileInvalidView):
def form_valid(self, form): def form_valid(self, form):
user = self.request.user user = self.request.user
form = self.form_class(self.request.POST, instance=user) form = self.form_class(self.request.POST, instance=user)
form.save() user = form.save()
response = {'success': True} response = {'success': True, 'rating': user.rating}
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
@ -373,7 +394,7 @@ class UserEventView(ListView):
context['event_type'] = self.event_type context['event_type'] = self.event_type
return context return context
class UserExpositionsView(UserEventView): class UserExpositionsView(MetadataMixin, UserEventView):
""" """
return template with list of expos that user joined return template with list of expos that user joined
""" """
@ -383,10 +404,11 @@ class UserExpositionsView(UserEventView):
url = self.kwargs.get('url') url = self.kwargs.get('url')
user = get_user(url) user = get_user(url)
self.obj = user self.obj = user
self.kwargs['user_full_name'] = user.get_full_name()
return user.get_expos() return user.get_expos()
class UserConferenceView(UserEventView): class UserConferenceView(MetadataMixin, UserEventView):
""" """
return template with list of confs that user joined return template with list of confs that user joined
""" """
@ -396,6 +418,7 @@ class UserConferenceView(UserEventView):
url = self.kwargs.get('url') url = self.kwargs.get('url')
user = get_user(url) user = get_user(url)
self.obj = user self.obj = user
self.kwargs['user_full_name'] = user.get_full_name()
return user.get_confs() return user.get_confs()
class UserSeminarView(UserEventView): class UserSeminarView(UserEventView):
@ -441,7 +464,7 @@ def change_password(request):
from django.views.generic.edit import FormMixin from django.views.generic.edit import FormMixin
class Feed(ListView): class Feed(ListView):
template_name = 'client/accounts/feed.html' template_name = 'client/accounts/feed.html'
paginate_by = 5 paginate_by = 10
model = Exposition model = Exposition
filter_form = FeedFilterForm filter_form = FeedFilterForm
success_url = '/profile/feed/' success_url = '/profile/feed/'
@ -465,4 +488,24 @@ class Feed(ListView):
user = self.request.user user = self.request.user
filter_form = self.filter_form(user=user) filter_form = self.filter_form(user=user)
context['filter_form'] = filter_form context['filter_form'] = filter_form
return context return context
@login_required
def remove_from_calendar(request):
if request.GET:
expo = request.GET.get('expo')
conf = request.GET.get('conf')
seminar = request.GET.get('seminar')
webinar = request.GET.get('webinar')
data = {'expo': expo if expo is None else json.loads(expo),
'conf': conf if conf is None else json.loads(conf),
'seminar': seminar if seminar is None else json.loads(seminar),
'webinar': webinar if webinar is None else json.loads(webinar)}
user = request.user
user.remove_from_calendar(data)
return HttpResponse(json.dumps({'success': True}), content_type='application/json')
else:
return Http404

@ -9,7 +9,7 @@ from django.contrib.contenttypes.models import ContentType
from forms import ArticleForm, ArticleDeleteForm, Article, NewsForm from forms import ArticleForm, ArticleDeleteForm, Article, NewsForm
from theme.models import Tag from theme.models import Tag
from file.models import FileModel, TmpFile from file.models import FileModel, TmpFile
from file.forms import FileModelForm from file.forms import FileModelForm, FileForm
#custom views #custom views
from functions.custom_views import objects_list, add_object_with_file, delete_object from functions.custom_views import objects_list, add_object_with_file, delete_object
@ -180,7 +180,13 @@ class BlogView(FormView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(BlogView, self).get_context_data(**kwargs) context = super(BlogView, self).get_context_data(**kwargs)
self.set_obj() self.set_obj()
context['article'] = self.obj context['article'] = self.obj
if context['article']:
context['file_form'] = FileForm(initial={'model': 'article.Article'})
context['files'] = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(context['article']),
object_id=getattr(context['article'], 'id'))
context['languages'] = settings.LANGUAGES context['languages'] = settings.LANGUAGES
return context return context
@ -188,6 +194,7 @@ class BlogView(FormView):
class NewsList(ListView): class NewsList(ListView):
model = Article model = Article
template_name = 'article/article_admin_list.html' template_name = 'article/article_admin_list.html'
paginate_by = 20
def get_queryset(self): def get_queryset(self):
return self.model.objects.news() return self.model.objects.news()

@ -4,6 +4,7 @@ from django.conf import settings
from ckeditor.widgets import CKEditorWidget from ckeditor.widgets import CKEditorWidget
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms.util import ErrorList from django.forms.util import ErrorList
from django.utils.translation import ugettext as _
#functions #functions
from functions.translate import fill_with_signal from functions.translate import fill_with_signal
from functions.files import check_tmp_files from functions.files import check_tmp_files
@ -226,4 +227,47 @@ class BlogForm(forms.ModelForm):
widget=forms.TextInput(attrs={'style':'width: 550px'})) widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255,
widget=forms.TextInput(attrs={'style':'width: 550px'})) widget=forms.TextInput(attrs={'style':'width: 550px'}))
""" """
class ArticleFilterForm(forms.Form):
theme = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in Theme.objects.language().all()])
tag = forms.CharField(label=_(u'Теги:'), widget=forms.HiddenInput(), required=False)
'''
def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
"""
super(ArticleFilterForm, self).__init__(*args, **kwargs)
ids = [item['theme_id'] for item in list(Article.objects.blogs().values('theme_id').distinct())]
self.fields['theme'] = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in Theme.objects.language().filter(id__in=ids)])
'''
class BlogFilterForm(forms.Form):
tag = forms.CharField(label=_(u'Теги:'), widget=forms.HiddenInput(), required=False)
def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
"""
super(BlogFilterForm, self).__init__(*args, **kwargs)
ids = [item['theme'] for item in list(Article.objects.blogs().values('theme').distinct())]
self.fields['theme'] = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in Theme.objects.language().filter(id__in=ids)])
class NewsFilterForm(forms.Form):
tag = forms.CharField(label=_(u'Теги:'), widget=forms.HiddenInput(), required=False)
def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
"""
super(NewsFilterForm, self).__init__(*args, **kwargs)
ids = [item['theme'] for item in list(Article.objects.news().values('theme').distinct())]
self.fields['theme'] = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in Theme.objects.language().filter(id__in=ids)])

@ -1,16 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import copy import copy
from django.db import models from django.db import models
from django.contrib.contenttypes import generic
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import translation
from django.utils.timezone import now from django.utils.timezone import now
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from django.utils.html import strip_tags from django.utils.html import strip_tags
from sorl.thumbnail import ImageField from sorl.thumbnail import ImageField
from functions.url_utils import slugify, unique_slug from functions.url_utils import slugify, unique_slug
from functions.model_utils import base_concrete_model from functions.model_utils import base_concrete_model
from functions.form_check import translit_with_separator
from django.core.cache import cache
class ArticleManager(TranslationManager): class ArticleManager(TranslationManager):
cache_time = 60
def safe_get(self, **kwargs): def safe_get(self, **kwargs):
model = self.model model = self.model
try: try:
@ -23,14 +29,38 @@ class ArticleManager(TranslationManager):
return queryset of news return queryset of news
""" """
model = self.model model = self.model
return model.objects.filter(type=model.news) return self.language().filter(type=model.news)
def blogs(self): def blogs(self):
""" """
return queryset of blogs return queryset of blogs
""" """
model = self.model model = self.model
return model.objects.filter(type=model.blog) return self.language().filter(type=model.blog)
def main_page_news(self):
lang = translation.get_language()
key = 'main_page_news_%s'%lang
cached_news = cache.get(key)
if cached_news:
return cached_news
else:
news = list(self.news().filter(publish_date__isnull=False).order_by('-main_page', '-publish_date')[:3])
cache.set(key, news, self.cache_time)
return news
def main_page_blogs(self):
lang = translation.get_language()
key = 'main_page_blogs_%s'%lang
cached_blogs = cache.get(key)
if cached_blogs:
return cached_blogs
else:
blogs = list(self.blogs().filter(publish_date__isnull=False).order_by('-main_page', '-publish_date')[:3])
cache.set(key, blogs, self.cache_time)
return blogs
return list(self.blogs().filter(publish_date__isnull=False).order_by('-main_page', '-publish_date')[:3])
class Article(TranslatableModel): class Article(TranslatableModel):
""" """
@ -73,23 +103,27 @@ class Article(TranslatableModel):
gen_description = models.BooleanField(_("Generate description"), gen_description = models.BooleanField(_("Generate description"),
help_text=_("If checked, the description will be automatically " help_text=_("If checked, the description will be automatically "
"generated from content. Uncheck if you want to manually " "generated from content. Uncheck if you want to manually "
"set a custom description."), default=True) "set a custom description."), default=False)
# published = models. # published = models.
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField()
modified = models.DateTimeField(auto_now=True) modified = models.DateTimeField(auto_now=True)
#translated fields #translated fields
translations = TranslatedFields( translations = TranslatedFields(
main_title = models.CharField(max_length=100), main_title = models.CharField(max_length=255),
preview = models.TextField(), preview = models.TextField(),
description = models.TextField(), description = models.TextField(blank=False),
#-----meta #-----meta
title = models.CharField(max_length=255, blank=True), title = models.CharField(max_length=255, blank=True),
descriptions = models.CharField(max_length=255, blank=True), descriptions = models.CharField(max_length=255, blank=True),
keywords = models.CharField(max_length=255, blank=True), keywords = models.CharField(max_length=255, blank=True),
) )
files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id')
class Meta:
ordering = ['-created']
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('main_title', self.pk) return self.lazy_translation_getter('main_title', self.pk)
@ -121,8 +155,8 @@ class Article(TranslatableModel):
self.slug = self.generate_unique_slug() self.slug = self.generate_unique_slug()
#Set the description field on save. #Set the description field on save.
if self.gen_description: #if self.gen_description:
self.description = strip_tags(self.description_from_content()) # self.description = strip_tags(self.description_from_content())
super(Article, self).save(*args, **kwargs) super(Article, self).save(*args, **kwargs)
def description_from_content(self): def description_from_content(self):
@ -140,7 +174,9 @@ class Article(TranslatableModel):
# slug lookup. # slug lookup.
concrete_model = base_concrete_model(Article, self) concrete_model = base_concrete_model(Article, self)
slug_qs = concrete_model.objects.exclude(id=self.id) slug_qs = concrete_model.objects.exclude(id=self.id)
return unique_slug(slug_qs, "slug", self.get_slug()) slug = unique_slug(slug_qs, "slug", self.get_slug())
slug = translit_with_separator(slug)
return slug
def get_slug(self): def get_slug(self):
""" """
@ -184,60 +220,6 @@ class Article(TranslatableModel):
""" """
return self._get_next_or_previous_by_publish_date(False, **kwargs) return self._get_next_or_previous_by_publish_date(False, **kwargs)
def clone(self):
"""
Return an identical copy of the instance with a new ID.
"""
if not self.pk:
raise ValueError('Instance must be saved before it can be cloned.')
duplicate = copy.copy(self)
# Setting pk to None. Django thinking this is a new object.
duplicate.pk = None
# url must be unique
duplicate.url += '_copy'
if Article.objects.safe_get(url=duplicate.url):
#already has copy this instance
return
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.save()
# but lost all ManyToMany relations and Translations.
'''
# 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)
# copy translations
languages = self.get_available_languages()
ignore_fields = ['id', 'master', 'language_code']
for code in languages:
duplicate.translate(code)
tr = self._meta.translations_model.objects.get(language_code = code,master__id=self.pk)
for field in duplicate._translated_field_names:
if field in ignore_fields:
continue
setattr(duplicate, field, getattr(tr, field))
duplicate.save()
'''
return duplicate
def admin_url(self): def admin_url(self):
if self.type == 1: if self.type == 1:
@ -247,9 +229,36 @@ class Article(TranslatableModel):
def get_permanent_url(self): def get_permanent_url(self):
if self.type == 1: if self.type == 1:
return '/blogs/%s'%self.slug return '/blogs/%s/'%self.slug
elif self.type == 2: elif self.type == 2:
return '/news/%s'%self.slug return '/news/%s/'%self.slug
def get_blog_preview(self):
preview = self.files.filter(purpose='preview')
if preview:
return preview[0]
else:
return None
def get_blog_preview2(self):
preview = self.files.filter(purpose='preview2')
if preview:
return preview[0]
else:
return None
def get_catalog(self):
if self.type == 1:
return '/blogs/'
elif self.type == 2:
return '/news/'
def similar(self):
themes = [item ['id'] for item in self.theme.all().values('id')]
return list(Article.objects.language().exclude(id=self.id).filter(type=self.type, publish_date__isnull=False, theme__in=themes).distinct().order_by('-publish_date')[:3])
from django.db.models.signals import post_save from django.db.models.signals import post_save
from functions.signal_handlers import post_save_handler from functions.signal_handlers import post_save_handler

@ -1,10 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from views import BlogList, NewsList, BlogDetail, NewsDetail from views import BlogList, NewsList, BlogDetail, NewsDetail, NewsTagCatalog, BlogsTagCatalog
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'blogs/$', BlogList.as_view()), url(r'^blogs/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', BlogsTagCatalog.as_view(), {'meta_id':75}),
url(r'news/$', NewsList.as_view()), url(r'^blogs/page/(?P<page>\d+)/$', BlogList.as_view(), {'meta_id':79}),
url(r'blogs/(?P<slug>.*)$', BlogDetail.as_view()), url(r'^blogs/tag/(?P<slug>.*)/$', BlogsTagCatalog.as_view(), {'meta_id':75}),
url(r'news/(?P<slug>.*)$', NewsDetail.as_view()), url(r'^blogs/$', BlogList.as_view(), {'meta_id':79}),
url(r'^news/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', NewsTagCatalog.as_view(), {'meta_id':77}),
url(r'^news/tag/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', NewsTagCatalog.as_view(), {'meta_id':76}),
url(r'^news/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', NewsTagCatalog.as_view(), {'meta_id':74}),
url(r'^news/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', NewsTagCatalog.as_view(), {'meta_id':77}),
url(r'^news/tag/(?P<slug>.*)/(?P<year>\d+)/$', NewsTagCatalog.as_view(), {'meta_id':76}),
url(r'^news/tag/(?P<slug>.*)/$', NewsTagCatalog.as_view(), {'meta_id':74}),
url(r'^news/page/(?P<page>\d+)/$', NewsList.as_view(), {'meta_id':78}),
url(r'^news/$', NewsList.as_view(), {'meta_id':78}),
url(r'^blogs/(?P<slug>.*)/$', BlogDetail.as_view(), {'meta_id':19}),
url(r'^news/(?P<slug>.*)/$', NewsDetail.as_view(), {'meta_id':19}),
) )

@ -1,10 +1,18 @@
# -*- coding: utf-8 -*-
import json
from django.views.generic import DetailView, ListView from django.views.generic import DetailView, ListView
from django.http import HttpResponse from django.http import HttpResponse
from models import Article from models import Article
from forms import ArticleFilterForm
from theme.models import Tag
from meta.views import MetadataMixin
class NewsList(ListView):
class NewsList(MetadataMixin, ListView):
model = Article model = Article
template_name = 'article/news_list.html' template_name = 'article/news_list.html'
paginate_by = 10
def get_queryset(self): def get_queryset(self):
if self.request.GET: if self.request.GET:
@ -14,22 +22,47 @@ class NewsList(ListView):
qs = qs.filter(theme__id__in=themes) qs = qs.filter(theme__id__in=themes)
tags = self.request.GET.getlist('tag') tags = self.request.GET.getlist('tag')
if u'' in tags:
tags.remove(u'')
if tags: if tags:
tags = tags[0].split(',')
qs = qs.filter(tag__id__in=tags) qs = qs.filter(tag__id__in=tags)
return qs return qs
else: else:
return self.model.objects.news() return self.model.objects.news().filter(publish_date__isnull=False).order_by('-publish_date')
class NewsDetail(DetailView): def get_context_data(self, **kwargs):
context = super(NewsList, self).get_context_data(object_list=self.object_list)
if self.request.GET:
filter_form = ArticleFilterForm(self.request.GET)
tags = self.request.GET.getlist('tag')
if u'' in tags:
tags.remove(u'')
if tags:
tags = tags[0].split(',')
tag_qs = Tag.objects.filter(id__in=tags)
tags = [{'id': str(tag.id), 'text': tag.name} for tag in tag_qs]
filter_form.fields['tag'].widget.attrs['data-predifined'] = json.dumps(tags)
filter_form.fields['tag'].widget.attrs['value'] = ''
else:
filter_form = ArticleFilterForm()
context['article_filter_form'] = filter_form
return context
class NewsDetail(MetadataMixin, DetailView):
model = Article model = Article
slug_field = 'slug' slug_field = 'slug'
template_name = 'article/news.html' template_name = 'article/news.html'
class BlogList(ListView): class BlogList(MetadataMixin, ListView):
model = Article model = Article
template_name = 'article/blog_list.html' template_name = 'article/blog_list.html'
paginate_by = 10
def get_queryset(self): def get_queryset(self):
if self.request.GET: if self.request.GET:
@ -40,16 +73,136 @@ class BlogList(ListView):
qs = qs.filter(theme__id__in=themes) qs = qs.filter(theme__id__in=themes)
tags = self.request.GET.getlist('tag') tags = self.request.GET.getlist('tag')
if u'' in tags:
tags.remove(u'')
if tags: if tags:
tags = tags[0].split(',')
qs = qs.filter(tag__id__in=tags) qs = qs.filter(tag__id__in=tags)
return qs return qs
else: else:
return self.model.objects.blogs() return self.model.objects.blogs()
def get_context_data(self, **kwargs):
context = super(BlogList, self).get_context_data(object_list=self.object_list)
if self.request.GET:
filter_form = ArticleFilterForm(self.request.GET)
tags = self.request.GET.getlist('tag')
if u'' in tags:
tags.remove(u'')
if tags:
tags = tags[0].split(',')
tag_qs = Tag.objects.filter(id__in=tags)
tags = [{'id': str(tag.id), 'text': tag.name} for tag in tag_qs]
filter_form.fields['tag'].widget.attrs['data-predifined'] = json.dumps(tags)
filter_form.fields['tag'].widget.attrs['value'] = ''
else:
filter_form = ArticleFilterForm()
context['article_filter_form'] = filter_form
return context
class BlogDetail(DetailView): class BlogDetail(MetadataMixin, DetailView):
model = Article model = Article
slug_field = 'slug' slug_field = 'slug'
template_name = 'article/article.html' template_name = 'article/article.html'
from exposition.views import ExpoCatalog
from django.conf import settings
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext as _
class NewsTagCatalog(MetadataMixin, ListView):
model = Article
template_name = 'client/article/catalog.html'
catalog_url = '/news/tag/'
filter_object = None
year = None
month = None
def get_queryset(self):
slug = self.kwargs.get('slug')
tag = get_object_or_404(Tag, url=slug)
self.kwargs['tag'] = tag
self.filter_object = tag
qs = Article.objects.news().filter(tag=tag)
year = self.kwargs.get('year')
if year:
qs = qs.filter(publish_date__year=year)
# info for breadscrumbs
self.year = {'text': year, 'link': '%s%s/%s/'%(self.catalog_url, self.filter_object.url, year)}
month = self.kwargs.get('month')
monthes = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')},
'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')},
'may': {'value': 5, 'name': _(u'Май')}, 'jun': {'value': 6, 'name': _(u'Июнь')},
'jul': {'value': 7, 'name': _(u'Июль')}, 'aug': {'value': 8, 'name': _(u'Август')},
'sep': {'value': 9, 'name': _(u'Сентябрь')}, 'oct': {'value': 10, 'name': _(u'Октябрь')},
'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}}
if month and monthes.get(month):
qs = qs.filter(publish_date__month=monthes[month]['value'])
self.month = {'text': monthes[month]['name'], 'link': '%s%s/%s/%s/'%(self.catalog_url, self.filter_object.url, year, month)}
return qs
def get_context_data(self, **kwargs):
context = super(NewsTagCatalog, self).get_context_data(**kwargs)
context['filter_object'] = self.filter_object
context['year'] = self.year
context['month'] = self.month
context['catalog_url'] = self.catalog_url
return context
class BlogsTagCatalog(MetadataMixin, ListView):
model = Article
template_name = 'client/article/catalog.html'
catalog_url = '/blogs/tag/'
filter_object = None
year = None
month = None
def get_queryset(self):
slug = self.kwargs.get('slug')
tag = get_object_or_404(Tag, url=slug)
self.kwargs['tag'] = tag
self.filter_object = tag
qs = Article.objects.blogs().filter(tag=tag)
year = self.kwargs.get('year')
if year:
qs = qs.filter(publish_date__year=year)
# info for breadscrumbs
self.year = {'text': year, 'link': '%s%s/%s/'%(self.catalog_url, self.filter_object.url, year)}
month = self.kwargs.get('month')
monthes = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')},
'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')},
'may': {'value': 5, 'name': _(u'Май')}, 'jun': {'value': 6, 'name': _(u'Июнь')},
'jul': {'value': 7, 'name': _(u'Июль')}, 'aug': {'value': 8, 'name': _(u'Август')},
'sep': {'value': 9, 'name': _(u'Сентябрь')}, 'oct': {'value': 10, 'name': _(u'Октябрь')},
'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}}
if month and monthes.get(month):
qs = qs.filter(publish_date__month=monthes[month]['value'])
self.month = {'text': monthes[month]['name'], 'link': '%s%s/%s/%s/'%(self.catalog_url, self.filter_object.url, year, month)}
return qs
def get_context_data(self, **kwargs):
context = super(BlogsTagCatalog, self).get_context_data(**kwargs)
context['filter_object'] = self.filter_object
context['year'] = self.year
context['month'] = self.month
context['catalog_url'] = self.catalog_url
return context

@ -56,7 +56,7 @@ def city_change(request, url):
else: else:
#fill form with data from database #fill form with data from database
data = {'population' : c.population, 'phone_code' : c.phone_code, data = {'population' : c.population, 'phone_code' : c.phone_code,
'city_id' : city_id} 'city_id' : city_id, 'inflect':c.inflect}
if c.country: if c.country:
data['country'] = c.country.id data['country'] = c.country.id

@ -33,6 +33,7 @@ class CityForm(forms.Form):
phone_code = forms.CharField(label='Код города', required=False, phone_code = forms.CharField(label='Код города', required=False,
widget=forms.TextInput(attrs={'placeholder':'Код города'})) widget=forms.TextInput(attrs={'placeholder':'Код города'}))
code_IATA = forms.ModelChoiceField(label='Код IATA', queryset=Iata.objects.all(), empty_label=None, required=False) code_IATA = forms.ModelChoiceField(label='Код IATA', queryset=Iata.objects.all(), empty_label=None, required=False)
inflect = forms.CharField(label='Inflect', required=False)
#field for comparing tmp files #field for comparing tmp files
key = forms.CharField(required=False, widget=forms.HiddenInput()) key = forms.CharField(required=False, widget=forms.HiddenInput())
# #
@ -85,6 +86,7 @@ class CityForm(forms.Form):
city.phone_code = data['phone_code'] city.phone_code = data['phone_code']
city.population = data.get('population') city.population = data.get('population')
city.inflect = data['inflect']
if data.get('code_IATA'): if data.get('code_IATA'):
city.code_IATA = Iata.objects.get(id=data['code_IATA'].id)# .id cause select uses queryset city.code_IATA = Iata.objects.get(id=data['code_IATA'].id)# .id cause select uses queryset

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand, CommandError
from city.models import City
from country.models import Country
from functions.form_check import translit_with_separator
from django.db import IntegrityError
class Command(BaseCommand):
def handle(self, *args, **options):
qs = City.objects.language('en').filter()
for c in qs:
url = translit_with_separator(c.name.encode('utf8'))
c.url = url
try:
c.save()
except IntegrityError:
continue
print(c.url)
#print(qs.count())

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from django.utils import translation
from country.models import City
class Command(BaseCommand):
def handle(self, *args, **options):
db = MySQLdb.connect(host="localhost",
user="kotzilla",
passwd="qazedc",
db="test2",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
sql = """SELECT title, url, inflect
FROM old_expomap.products_places
WHERE parent_id > 0 """
cursor.execute(sql)
result = cursor.fetchall()
for res in result:
name = res['title']
url = res['url']
inflect = res['inflect']
City.objects.filter(translations__name=name).update(inflect=inflect, old_url=url)
print(name.encode('utf-8'))

@ -11,10 +11,13 @@ from service.models import Service
from exposition.models import Exposition from exposition.models import Exposition
from place_exposition.models import PlaceExposition from place_exposition.models import PlaceExposition
from organiser.models import Organiser from organiser.models import Organiser
from conference.models import Conference
from seminar.models import Seminar
from webinar.models import Webinar
# custom functions # custom functions
from functions.db import db_table_exists from functions.db import db_table_exists
from functions.signal_handlers import post_save_handler from functions.signal_handlers import post_save_handler
from functions.models_methods import ExpoManager from functions.models_methods import ExpoManager, CityManager
#check if table exist and create flags if true #check if table exist and create flags if true
flags = [str(item.url) for item in Service.objects.all()] if db_table_exists('service_service') else [] flags = [str(item.url) for item in Service.objects.all()] if db_table_exists('service_service') else []
@ -28,11 +31,15 @@ class City(TranslatableModel):
""" """
objects = ExpoManager() objects = ExpoManager()
used = CityManager()
catalog = '/city/' catalog = '/city/'
services = BitField(flags=flags) services = BitField(flags=flags)
url = models.SlugField(unique=True) url = models.SlugField(unique=True)
#
old_url = models.CharField(max_length=55)
inflect = models.CharField(max_length=255, blank=True)
#relations #relations
country = models.ForeignKey('country.Country', null=True, on_delete=models.PROTECT, related_name='cities') country = models.ForeignKey('country.Country', null=True, on_delete=models.PROTECT, related_name='cities')
code_IATA = models.ForeignKey(Iata, blank=True, null=True) code_IATA = models.ForeignKey(Iata, blank=True, null=True)
@ -56,6 +63,9 @@ class City(TranslatableModel):
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True) modified = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['translations__name']
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', self.pk) return self.lazy_translation_getter('name', self.pk)
@ -83,7 +93,19 @@ class City(TranslatableModel):
def expositions_number(self): def expositions_number(self):
return len(Exposition.objects.filter(city=self.id)) return Exposition.objects.filter(city=self.id).count()
def conferences_number(self):
return Conference.objects.filter(city=self.id).count()
def seminars_number(self):
return Seminar.objects.filter(city=self.id).count()
def webinars_number(self):
return Webinar.objects.filter(city=self.id).count()
def get_parent(self): def get_parent(self):
parent = {'text' : self.country.name, 'id': self.country.id, 'name': 'co', parent = {'text' : self.country.name, 'id': self.country.id, 'name': 'co',

@ -4,6 +4,7 @@ from django.utils.translation import ugettext as _, get_language
from country.models import Country from country.models import Country
from city.models import City from city.models import City
from company.models import Company from company.models import Company
from theme.models import Theme
class BaseForm(forms.ModelForm): class BaseForm(forms.ModelForm):
@ -27,7 +28,7 @@ class NameForm(BaseForm):
class SpecializationForm(BaseForm): class SpecializationForm(BaseForm):
translation = True translation = True
specialization = forms.CharField(label=_(u'Описание компании'), widget=forms.TextInput()) specialization = forms.CharField(label=_(u'Описание компании'), widget=forms.TextInput(), required=False)
class Meta: class Meta:
model = Company._meta.translations_model model = Company._meta.translations_model
fields = ('specialization',) fields = ('specialization',)
@ -36,7 +37,7 @@ class SpecializationForm(BaseForm):
class HomeForm(BaseForm): class HomeForm(BaseForm):
city = forms.CharField(label='Город', required=False, city = forms.CharField(label='Город', required=False,
widget=forms.HiddenInput(attrs={'class': 'select2'})) widget=forms.HiddenInput(attrs={'class': 'select2'}))
country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.all()], required=False, country = forms.ChoiceField(label=_(u'Страна'), choices=[('', '')]+[(c.id, c.name) for c in list(Country.objects.all())], required=False,
widget=forms.Select(attrs={'class': 'select2'})) widget=forms.Select(attrs={'class': 'select2'}))
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(HomeForm, self).__init__(*args, **kwargs) super(HomeForm, self).__init__(*args, **kwargs)
@ -68,6 +69,19 @@ class PhoneForm(BaseForm):
model = Company model = Company
fields = ('phone',) fields = ('phone',)
def clean_phone(self):
phone = self.cleaned_data['phone']
if not phone:
return
deduct = ('-','(',')','.',' ', '+')
for elem in deduct:
phone = phone.replace(elem, '')
if phone.isdigit():
return phone
else:
raise forms.ValidationError(_(u'Введите правильный телефон'))
class EmailForm(BaseForm): class EmailForm(BaseForm):
email = forms.EmailField(label=_(u'Ваш e-mail'), required=False) email = forms.EmailField(label=_(u'Ваш e-mail'), required=False)
@ -94,12 +108,32 @@ class SocialForm(BaseForm):
fields = ('facebook', 'twitter', 'vk', 'linkedin') fields = ('facebook', 'twitter', 'vk', 'linkedin')
class ThemeForm(BaseForm):
theme = forms.ModelMultipleChoiceField(queryset=Theme.objects.all())
class Meta:
model = Company
fields = ('theme',)
class TagForm(BaseForm): class TagForm(BaseForm):
tag = forms.CharField(required=False, widget=forms.HiddenInput(attrs={'class': 'select2'})) tag = forms.CharField(required=False, widget=forms.HiddenInput(attrs={'class': 'select2'}))
class Meta: class Meta:
model = Company model = Company
fields = ('tag',) fields = ('tag',)
def clean_tag(self):
tags = self.cleaned_data.get('tag')
if tags:
res = []
for id in tags.split(','):
try:
res.append(int(id))
except:
continue
return res
else:
return []
class FoundationForm(BaseForm): class FoundationForm(BaseForm):
class Meta: class Meta:
@ -122,7 +156,7 @@ class DescriptionForm(BaseForm):
class AddressForm(BaseForm): class AddressForm(BaseForm):
translation = True translation = True
address_inf = forms.CharField(label=_(u'Адрес компании'), widget=forms.TextInput()) address_inf = forms.CharField(label=_(u'Адрес компании'), widget=forms.TextInput(), required=False)
class Meta: class Meta:
model = Company._meta.translations_model model = Company._meta.translations_model
fields = ('address_inf',) fields = ('address_inf',)

@ -1,13 +1,21 @@
import json import json
from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseForbidden
from django.utils.translation import get_language from django.utils.translation import get_language
from sorl.thumbnail import get_thumbnail from sorl.thumbnail import get_thumbnail
from edit_forms import * from edit_forms import *
from accounts.views import ProfileInvalidView from accounts.views import ProfileInvalidView
from .models import Company
class BaseView(ProfileInvalidView): class BaseView(ProfileInvalidView):
def form_valid(self, form): def form_valid(self, form):
company = self.request.user.company slug = self.kwargs.get('slug')
if not slug:
raise Http404
company = Company.objects.get(url=slug)
if company.creator_id != self.request.user.id:
return HttpResponseForbidden()
if self.form_class.translation: if self.form_class.translation:
lang = get_language() lang = get_language()
comp_transl = company.translations.get(language_code=lang) comp_transl = company.translations.get(language_code=lang)
@ -16,8 +24,12 @@ class BaseView(ProfileInvalidView):
else: else:
form = self.form_class(self.request.POST, instance=company) form = self.form_class(self.request.POST, instance=company)
form.save() company = form.save()
response = {'success': True} try:
rating = company.rating
except AttributeError:
rating = company.master.rating
response = {'success': True, 'rating': rating}
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
@ -30,12 +42,19 @@ class LogoView(BaseView):
form_class = LogoForm form_class = LogoForm
def form_valid(self, form): def form_valid(self, form):
company = self.request.user.company #company = self.request.user.company#!!!
slug = self.kwargs.get('slug')
if not slug:
raise Http404
company = Company.objects.get(url=slug)
if company.creator_id != self.request.user.id:
return HttpResponseForbidden()
form = self.form_class(self.request.POST, self.request.FILES, instance=company) form = self.form_class(self.request.POST, self.request.FILES, instance=company)
form.save() company = form.save()
if self.request.is_ajax(): if self.request.is_ajax():
im = get_thumbnail(company.logo, '100x100', crop='center') im = get_thumbnail(company.logo, '100x100', format="PNG")
response = {'success': True, 'url': im.url} response = {'success': True, 'url': im.url, 'rating': company.rating}
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
else: else:
return HttpResponseRedirect(company.get_permanent_url()) return HttpResponseRedirect(company.get_permanent_url())
@ -68,9 +87,56 @@ class SocialView(BaseView):
form_class = SocialForm form_class = SocialForm
class ThemeView(BaseView):
form_class = ThemeForm
def form_valid(self, form):
slug = self.kwargs.get('slug')
if not slug:
raise Http404
company = Company.objects.get(url=slug)
if company.creator_id != self.request.user.id:
return HttpResponseForbidden()
form = self.form_class(self.request.POST, instance=company)
company = form.save()
try:
rating = company.rating
except AttributeError:
rating = company.master.rating
themes = [{'text': item.name,'id': str(item.id),'url': '/members/theme/%s/'%item.url} for item in company.theme.all()]
response = {'success': True, 'rating': rating, 'tags': themes}
return HttpResponse(json.dumps(response), content_type='application/json')
class TagView(BaseView): class TagView(BaseView):
form_class = TagForm form_class = TagForm
def form_valid(self, form):
slug = self.kwargs.get('slug')
if not slug:
raise Http404
company = Company.objects.get(url=slug)
if company.creator_id != self.request.user.id:
return HttpResponseForbidden()
form = self.form_class(self.request.POST, instance=company)
company = form.save()
try:
rating = company.rating
except AttributeError:
rating = company.master.rating
tags = [{'text': item.name,'id': str(item.id),'url': '/members/tag/%s/'%item.url} for item in company.tag.all()]
response = {'success': True, 'rating': rating, 'tags': tags}
return HttpResponse(json.dumps(response), content_type='application/json')
class FoundationView(BaseView): class FoundationView(BaseView):
form_class = FoundationForm form_class = FoundationForm

@ -282,6 +282,8 @@ class CreateCompanyForm(forms.Form):
def clean_url(self): def clean_url(self):
url = self.cleaned_data['url'] url = self.cleaned_data['url']
url = url.replace('http://expomap.ru/members/', '')
if not is_latin(url): if not is_latin(url):
raise forms.ValidationError(_(u'url должен состоять только из латинских букв')) raise forms.ValidationError(_(u'url должен состоять только из латинских букв'))

@ -119,7 +119,7 @@ class Company(TranslatableModel, ExpoMixin):
def calculate_rating(company): def calculate_rating(company):
rating_simple = {'country': 5, 'city': 5, 'address_inf': 10, 'phone': 10, 'fax': 5, 'email': 10, rating_simple = {'country': 5, 'city': 5, 'address_inf': 10, 'phone': 10, 'fax': 5, 'email': 10,
'facebook': 5, 'twitter': 5, 'linkedin': 5, 'vk': 5, 'web_page': 10, #'logo': 20, 'facebook': 5, 'twitter': 5, 'linkedin': 5, 'vk': 5, 'web_page': 10, 'logo': 20,
'specialization': 5, 'description':15, 'foundation': 5, 'staff_number': 5}# участие и посещение доделать 'specialization': 5, 'description':15, 'foundation': 5, 'staff_number': 5}# участие и посещение доделать
rating_methods = {'theme': 10, 'tag': 5, 'photo':5} rating_methods = {'theme': 10, 'tag': 5, 'photo':5}
# base rating # base rating
@ -128,7 +128,13 @@ def calculate_rating(company):
if getattr(company, key): if getattr(company, key):
rating += value rating += value
themes = company.theme.all().count()
rating += themes * 10
tags = company.tag.all().count()
rating += tags * 10 if tags < 6 else 50
company.rating = rating company.rating = rating
# call to prevent recursion # call to prevent recursion
post_save.disconnect(create_company, sender=Company) post_save.disconnect(create_company, sender=Company)
company.save() company.save()
@ -139,4 +145,11 @@ def create_company(sender, instance, created, **kwargs):
post_save_handler(sender, instance=instance, **kwargs) post_save_handler(sender, instance=instance, **kwargs)
calculate_rating(instance) calculate_rating(instance)
def calculate_rating_for_translations(sender, instance, created, **kwargs):
company = instance.master
post_save.disconnect(calculate_rating_for_translations, sender=Company._meta.translations_model)
calculate_rating(company)
post_save.connect(calculate_rating_for_translations, sender=Company._meta.translations_model)
post_save.connect(create_company, sender=Company) post_save.connect(create_company, sender=Company)
post_save.connect(calculate_rating_for_translations, sender=Company._meta.translations_model)

@ -35,4 +35,7 @@ class CompanyExpositionIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchM
def index_queryset(self, using=None): def index_queryset(self, using=None):
return self.get_model().objects.filter() return self.get_model().objects.filter()
def get_updated_field(self):
return 'modified'

@ -1,40 +1,42 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from views import CompanyView, CompanySearchView, MemberDetail, MemberList, MemberTagList, MemberThemeList from views import CompanySearchView, MemberDetail, MemberList, MemberTagList, MemberThemeList
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from edit_views import * from edit_views import *
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'company/create-company/$', 'company.views.create_company'),
url(r'company/get-company/$', 'company.views.get_company'),
#
url(r'members/search/$', CompanySearchView.as_view()), url(r'members/search/$', CompanySearchView.as_view()),
#url(r'members/(?P<params>.*)/(?P<page>\d+)/$', CompanyView.as_view()), #url(r'members/(?P<params>.*)/(?P<page>\d+)/$', CompanyView.as_view()),
#url(r'members/(?P<page>\d+)/$', CompanyView.as_view()), #url(r'members/(?P<page>\d+)/$', CompanyView.as_view()),
#url(r'members/(?P<params>.*)/$', CompanyView.as_view()), #url(r'members/(?P<params>.*)/$', CompanyView.as_view()),
#url(r'members/$', CompanyView.as_view()), #url(r'members/$', CompanyView.as_view()),
url(r'members/theme/(?P<slug>.*)/page/(?P<page>\d+)/$', MemberThemeList.as_view()), url(r'members/theme/(?P<slug>.*)/page/(?P<page>\d+)/$', MemberThemeList.as_view(), {'meta_id':69}),
url(r'members/theme/(?P<slug>.*)/$', MemberThemeList.as_view()), url(r'members/theme/(?P<slug>.*)/$', MemberThemeList.as_view(), {'meta_id':69}),
url(r'members/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', MemberTagList.as_view()), url(r'members/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', MemberTagList.as_view(), {'meta_id':70}),
url(r'members/tag/(?P<slug>.*)/$', MemberTagList.as_view()), url(r'members/tag/(?P<slug>.*)/$', MemberTagList.as_view(), {'meta_id':70}),
url(r'members/page/(?P<page>\d+)/$', MemberList.as_view()), url(r'members/page/(?P<page>\d+)/$', MemberList.as_view(), {'meta_id':67}),
url(r'members/(?P<slug>.*)/$', MemberDetail.as_view()), url(r'members/(?P<slug>.*)/$', MemberDetail.as_view(), {'meta_id':68}),
url(r'members/$', MemberList.as_view()), url(r'members/$', MemberList.as_view(), {'meta_id':67}),
# #
url(r'company/create-company/$', 'company.views.create_company'), url(r'company/update/name/(?P<slug>.*)/$', login_required(NameView.as_view())),
url(r'company/get-company/$', 'company.views.get_company'), url(r'^company/update/home/(?P<slug>.*)/$', login_required(HomeView.as_view())),
# url(r'^company/update/specialization/(?P<slug>.*)/$', login_required(SpecializationView.as_view())),
url(r'company/update/name/$', login_required(NameView.as_view())), url(r'^company/update/phone/(?P<slug>.*)/$', login_required(PhoneView.as_view())),
url(r'^company/update/home/$', login_required(HomeView.as_view())), url(r'^company/update/email/(?P<slug>.*)/$', login_required(EmailView.as_view())),
url(r'^company/update/specialization/$', login_required(SpecializationView.as_view())), url(r'^company/update/web-page/(?P<slug>.*)/$', login_required(WebPageView.as_view())),
url(r'^company/update/phone/$', login_required(PhoneView.as_view())), url(r'^company/update/social/(?P<slug>.*)/$', login_required(SocialView.as_view())),
url(r'^company/update/email/$', login_required(EmailView.as_view())), url(r'^company/update/tag/(?P<slug>.*)/$', login_required(TagView.as_view())),
url(r'^company/update/web-page/$', login_required(WebPageView.as_view())), url(r'^company/update/theme/(?P<slug>.*)/$', login_required(ThemeView.as_view())),
url(r'^company/update/social/$', login_required(SocialView.as_view())), url(r'^company/update/foundation/(?P<slug>.*)/$', login_required(FoundationView.as_view())),
url(r'^company/update/tag/$', login_required(TagView.as_view())), url(r'^company/update/staff/(?P<slug>.*)/$', login_required(StaffView.as_view())),
url(r'^company/update/foundation/$', login_required(FoundationView.as_view())), url(r'^company/update/description/(?P<slug>.*)/$', login_required(DescriptionView.as_view())),
url(r'^company/update/staff/$', login_required(StaffView.as_view())), url(r'^company/update/address/(?P<slug>.*)/$', login_required(AddressView.as_view())),
url(r'^company/update/description/$', login_required(DescriptionView.as_view())), url(r'^company/update/logo/(?P<slug>.*)/$', login_required(LogoView.as_view())),
url(r'^company/update/address/$', login_required(AddressView.as_view())),
url(r'^company/update/logo/$', login_required(LogoView.as_view())),
) )

@ -15,7 +15,8 @@ from .edit_forms import NameForm as CompNameForm, HomeForm as CompHomeForm, Phon
EmailForm as CompEmailForm, WebPageForm as CompWebPageForm, SocialForm as CompSocialForm,\ EmailForm as CompEmailForm, WebPageForm as CompWebPageForm, SocialForm as CompSocialForm,\
TagForm as CompTagForm, DescriptionForm as CompDescr, StaffForm as CompStaff, \ TagForm as CompTagForm, DescriptionForm as CompDescr, StaffForm as CompStaff, \
FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress,\ FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress,\
LogoForm as CompLogo LogoForm as CompLogo, ThemeForm as CompThemeForm
from meta.views import MetadataMixin
class CompanySearchView(ListView): class CompanySearchView(ListView):
@ -51,7 +52,7 @@ class CompanySearchView(ListView):
class MemberList(ListView): class MemberList(MetadataMixin, ListView):
model = Company model = Company
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/company/companies_list.html' template_name = 'client/company/companies_list.html'
@ -61,7 +62,7 @@ class MemberList(ListView):
def get_queryset(self): def get_queryset(self):
return self.model.objects.order_by('-rating') return self.model.objects.order_by('-rating')
class MemberThemeList(ListView): class MemberThemeList(MetadataMixin, ListView):
model = Company model = Company
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/company/companies_list.html' template_name = 'client/company/companies_list.html'
@ -72,11 +73,12 @@ class MemberThemeList(ListView):
qs = super(MemberThemeList, self).get_queryset() qs = super(MemberThemeList, self).get_queryset()
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
theme = get_object_or_404(Theme, url=slug) theme = get_object_or_404(Theme, url=slug)
self.kwargs['theme'] = theme
qs = qs.filter(theme=theme) qs = qs.filter(theme=theme)
return qs return qs
class MemberTagList(ListView): class MemberTagList(MetadataMixin, ListView):
model = Company model = Company
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/company/companies_list.html' template_name = 'client/company/companies_list.html'
@ -87,13 +89,15 @@ class MemberTagList(ListView):
qs = super(MemberTagList, self).get_queryset() qs = super(MemberTagList, self).get_queryset()
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
tag = get_object_or_404(Tag, url=slug) tag = get_object_or_404(Tag, url=slug)
self.kwargs['tag'] = tag
qs = qs.filter(tag=tag) qs = qs.filter(tag=tag)
return qs return qs
class MemberDetail(DetailView): class MemberDetail(MetadataMixin, DetailView):
model = Company model = Company
slug_field = 'url' slug_field = 'url'
template_name = 'client/company/company_detail.html' template_name = 'client/company/company_detail.html'
@ -108,10 +112,21 @@ class MemberDetail(DetailView):
forms = { forms = {
'home_form': CompHomeForm(instance=company), 'phone_form': CompPhoneForm(instance=company), 'home_form': CompHomeForm(instance=company), 'phone_form': CompPhoneForm(instance=company),
'email_form': CompEmailForm(instance=company), 'web_page_form': CompWebPageForm(instance=company), 'email_form': CompEmailForm(instance=company), 'web_page_form': CompWebPageForm(instance=company),
'social_form': CompSocialForm(instance=company), 'tag_form': CompTagForm(instance=company), 'social_form': CompSocialForm(instance=company),
'staff_form': CompStaff(instance=company), 'found_form': CompFound(instance=company), 'staff_form': CompStaff(instance=company), 'found_form': CompFound(instance=company),
'logo_form': CompLogo(instance=company) 'logo_form': CompLogo(instance=company)
} }
tags = [{'id': str(tag.id), 'text': tag.name, 'url': '/members/tag/%s/'%tag.url} for tag in company.tag.all()]
tag_form = CompTagForm()
tag_form.fields['tag'].widget.attrs['data-predifined'] = json.dumps(tags)
tag_form.fields['tag'].widget.attrs['value'] = ''
#themes = [{'id': str(item.id), 'text': item.name } for item in company.theme.all()]
theme_form = CompThemeForm(instance=company)
#theme_form.fields['theme'].widget.attrs['data-predifined'] = json.dumps(themes)
#theme_form.fields['tag'].widget.attrs['value'] = ''
forms.update({'tag_form': tag_form, 'theme_form': theme_form})
lang = get_language() lang = get_language()
comp_transl = company.translations.get(language_code=lang) comp_transl = company.translations.get(language_code=lang)
@ -125,30 +140,6 @@ class MemberDetail(DetailView):
return context return context
class CompanyView(ExpoListView):
paginate_by = 10
model = Company
template_name = 'company_catalog.html'
search_form = CompanySearchForm
def get_context_data(self, **kwargs):
context = super(CompanyView, self).get_context_data(**kwargs)
context['type'] = 'members search'
return context
class CompanyExposition(CompanyView):
template_name = 'test_list.html'
def get_queryset(self):
params = self.get_params()
for param in params:
if param.get('type') == 'event':
company = Company.objects.safe_get(url=param.get('url'))
#query = exp.users
self.params = params
return company.exposition_companies.all()
def create_company(request): def create_company(request):
response = {'success': False} response = {'success': False}
@ -166,7 +157,7 @@ def get_company(request):
if request.is_ajax(): if request.is_ajax():
term = request.GET['term'] term = request.GET['term']
qs = Company.objects.language().filter(translations__name__contains=term).distinct() qs = Company.objects.language().filter(translations__name__contains=term).distinct()
result = [{'id': company.id, 'label': company.name} for company in qs] result = [{'id': company.id, 'label': company.name, 'logo': company.logo.url if company.logo else settings.NO_LOGO } for company in qs]
return HttpResponse(json.dumps(result), content_type='application/json') return HttpResponse(json.dumps(result), content_type='application/json')
else: else:
return HttpResponse('not ajax') return HttpResponse('not ajax')

@ -13,13 +13,14 @@ from forms import ConferenceChangeForm, ConferenceCreateForm, ConferenceDeleteFo
from theme.models import Tag from theme.models import Tag
from city.models import City from city.models import City
from file.models import FileModel, TmpFile from file.models import FileModel, TmpFile
from file.forms import FileModelForm from file.forms import FileModelForm, FileForm
from photologue.forms import PhotoForm
#python #python
import random import random
#custom views #custom views
from functions.custom_views import objects_list, delete_object from functions.custom_views import objects_list, delete_object
from functions.views_help import get_referer from functions.views_help import get_referer
from functions.admin_views import AdminListView from functions.admin_views import AdminListView, AdminView, upload_photo
def conference_all(request): def conference_all(request):
@ -214,7 +215,84 @@ def conference_change(request, url):
return render_to_response('conference_add.html', args) return render_to_response('conference_add.html', args)
class ConferenceView(AdminView):
form_class = ConferenceCreateForm
model = Conference
success_url = '/admin/conference/all/'
template_name = 'admin/conference/conference.html'
def form_valid(self, form):
self.set_obj()
expo = form.save(obj=self.obj)
return HttpResponseRedirect(self.success_url)
def get_form(self, form_class):
if self.request.POST:
return super(ConferenceView, self).get_form(form_class)
obj = self.set_obj()
if obj:
data = {'web_page':obj.web_page, 'foundation_year': obj.foundation_year,
'data_begin':obj.data_begin, 'data_end':obj.data_end, 'currency':obj.currency,
'tax':obj.tax, 'min_price':obj.min_price, 'max_price':obj.max_price,
'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],
'quality_label': [item for item, bool in obj.quality_label if bool==True]}
if obj.place:
data['place'] = obj.place.id
data['theme'] = [item.id for item in obj.theme.all()]
data['tag'] = ','.join(['%s:%s'%(item.id, item.name) for item in obj.tag.all()])
data['organiser'] = [item.id for item in obj.organiser.all()]
data['company'] = [item.id for item in obj.company.all()]
data['country'] = obj.country_id
data['city'] = obj.city_id
for code, name in settings.LANGUAGES:
trans_obj = self.model._meta.translations_model.objects.get(language_code = code,master__id=obj.id) #access to translated fields
data['name_%s' % code] = obj.name
data['description_%s' % code] = trans_obj.description
data['main_title_%s' % code] = trans_obj.main_title
data['time_%s' % code] = trans_obj.time
data['main_themes_%s' % code] = trans_obj.main_themes
data['discount_description_%s' % code] = trans_obj.discount_description
data['title_%s' % code] = trans_obj.title
data['keywords_%s' % code] = trans_obj.keywords
data['descriptions_%s' % code] = trans_obj.descriptions
form =form_class(initial=data)
form.fields['city'].widget.attrs['data-init-text'] = obj.city.name
form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.language().filter(theme__in=data['theme'])]
return form
else:
return form_class()
def get_context_data(self, **kwargs):
context = super(ConferenceView, self).get_context_data(**kwargs)
obj = self.set_obj()
if obj:
context['stat_form'] = StatisticForm()
context['file_form'] = FileForm(initial={'model': 'conference.Conference'})
files = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(obj),object_id=getattr(obj, 'id'))
context['files'] = files
context['photo_form'] = PhotoForm()
context['timetable_form'] = TimeTableForm()
context['timetables'] = TimeTable.objects.filter(conference=obj)
return context
class ConferenceListView(AdminListView): class ConferenceListView(AdminListView):
template_name = 'admin/conference/conference_list.html' template_name = 'admin/conference/conference_list.html'
form_class = ConferenceFilterForm form_class = ConferenceFilterForm
model = Conference model = Conference
def upload_conference_photo(request, conf_id):
return upload_photo(request, conf_id, Conference)

@ -1,13 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from admin import ConferenceListView from admin import ConferenceListView, ConferenceView
urlpatterns = patterns('conference.admin', urlpatterns = patterns('conference.admin',
url(r'^add.*/$', 'conference_add'), url(r'^upload-photo/(?P<conf_id>.*)/$', 'upload_conference_photo'),
url(r'^delete/(?P<url>.*)$', 'conference_delete'), url(r'^delete/(?P<url>.*)$', 'conference_delete'),
url(r'^change/(?P<url>.*)/$', 'conference_change'),
url(r'^copy/(?P<url>.*)/$', 'conference_copy'),
url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'conference_switch'),
#url(r'^all/$', 'conference_all'),
url(r'^all/$', ConferenceListView.as_view()), url(r'^all/$', ConferenceListView.as_view()),
#url(r'^change/(?P<url>.*)/$', 'conference_change'),
url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'conference_switch'),
url(r'^(?P<url>.*)/$', ConferenceView.as_view()),
url(r'^$', ConferenceView.as_view()),
) )

@ -5,10 +5,10 @@ from ckeditor.widgets import CKEditorWidget
from django.forms.util import ErrorList from django.forms.util import ErrorList
from django.core.validators import validate_email, URLValidator from django.core.validators import validate_email, URLValidator
#models #models
from models import Conference, TimeTable, CURRENCY, Statistic from models import Conference, TimeTable, CURRENCY, Statistic, BIT_AUDIENCE
from country.models import Country from country.models import Country
from city.models import City from city.models import City
from theme.models import Theme from theme.models import Theme, Tag
from organiser.models import Organiser from organiser.models import Organiser
from accounts.models import User from accounts.models import User
from company.models import Company from company.models import Company
@ -21,6 +21,9 @@ from functions.files import check_tmp_files
from functions.form_check import translit_with_separator from functions.form_check import translit_with_separator
from functions.admin_forms import AdminFilterForm from functions.admin_forms import AdminFilterForm
places = [(item.id, item.name) for item in PlaceConference.objects.language().all()]
places.insert(0,('', 'Не выбрано'))
class ConferenceCreateForm(forms.Form): class ConferenceCreateForm(forms.Form):
""" """
@ -31,18 +34,35 @@ class ConferenceCreateForm(forms.Form):
save function saves data in Conference object. If it doesnt exist create new object save function saves data in Conference object. If it doesnt exist create new object
""" """
PERIODIC = ((0, u'Не выбрано'),
(1.0, u'Ежегодно'), (2.0, u'2 раза в год'), (3.0, u'3 раза в год'),
(4.0, u'4 раза в год'), (5.0, u'5 раз в год'),
(0.5, u'Раз в 2 года'),(0.33, u'Раз в 3 года'),(0.25, u'Раз в 4 года'))
public = [(item1, item2) for item1, item2 in BIT_AUDIENCE]
currencies = [(item, item) for item in CURRENCY] currencies = [(item, item) for item in CURRENCY]
data_begin = forms.DateField(label='Дата начала') data_begin = forms.DateField(label=u'Дата начала', input_formats=['%Y-%m-%d', '%d.%m.%Y'])
data_end = forms.DateField(label='Дата окночания') 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()])
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()])
place = forms.ChoiceField(label=u'Место проведения', required=False,
choices=places)
country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None)
theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all())
place = forms.ModelChoiceField(label='Место проведения', queryset=PlaceConference.objects.all(),
empty_label='', required=False)
#creates select input with empty choices cause it will be filled with ajax #creates select input with empty choices cause it will be filled with ajax
city = forms.ChoiceField(label='Город', choices=[('','')]) city = forms.CharField(label=u'Город', widget=forms.HiddenInput())
tag = forms.MultipleChoiceField(label='Теги', required=False) tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False)
periodic = forms.ChoiceField(label=u'Периодичность', choices=PERIODIC, required=False)
audience = forms.MultipleChoiceField(label=u'Аудитория', choices=public, initial='', required=False)
web_page = forms.CharField(label='Веб страница', required=False) web_page = forms.CharField(label='Веб страница', required=False)
link = forms.CharField(label='Линк на регистрацию', required=False) link = forms.CharField(label='Линк на регистрацию', required=False)
@ -61,9 +81,7 @@ class ConferenceCreateForm(forms.Form):
quality_label = forms.MultipleChoiceField(label='Тип', required=False, quality_label = forms.MultipleChoiceField(label='Тип', required=False,
choices=[('ufi', 'UFI'), ('rsva', 'РСВЯ'), ('exporating', 'ExpoRating')], choices=[('ufi', 'UFI'), ('rsva', 'РСВЯ'), ('exporating', 'ExpoRating')],
widget=forms.CheckboxSelectMultiple()) widget=forms.CheckboxSelectMultiple())
#field for comparing tmp files
key = forms.CharField(required=False, widget=forms.HiddenInput())
#
conference_id = forms.CharField(required=False, widget=forms.HiddenInput()) conference_id = forms.CharField(required=False, widget=forms.HiddenInput())
@ -99,14 +117,8 @@ class ConferenceCreateForm(forms.Form):
widget=forms.TextInput(attrs={'style':'width: 550px'})) widget=forms.TextInput(attrs={'style':'width: 550px'}))
#!service has bitfield. uncomment when country data will be filled
#services = [(item.id, item.name) for item in Service.objects.all()]
#self.fields['service'] = forms.ChoiceField(label='Услуги', choices=services, required=False)
def save(self, id=None): def save(self, obj=None):
""" """
changes Conference model object with id = id changes Conference model object with id = id
N/A add new Conference model object N/A add new Conference model object
@ -115,15 +127,18 @@ class ConferenceCreateForm(forms.Form):
""" """
data = self.cleaned_data data = self.cleaned_data
#create new conference object or get exists #create new conference object or get exists
if not id: if not obj:
conference = Conference() conference = Conference()
else: else:
conference = Conference.objects.get(id=id) conference = obj
conference.theme.clear() conference.theme.clear()
conference.tag.clear() conference.tag.clear()
#simple fields #simple fields
conference.url = translit_with_separator(data['name_ru'].strip()).lower() conference.url = translit_with_separator(data['name_ru'].strip()).lower()
if data.get('logo'):
conference.logo = data['logo']
conference.data_begin = data['data_begin'] conference.data_begin = data['data_begin']
conference.data_end = data['data_end'] conference.data_end = data['data_end']
conference.link = data['link'] conference.link = data['link']
@ -141,6 +156,7 @@ class ConferenceCreateForm(forms.Form):
conference.expohit = data['expohit'] conference.expohit = data['expohit']
conference.canceled = data['canceled'] conference.canceled = data['canceled']
conference.moved = data['moved'] conference.moved = data['moved']
conference.periodic = data['periodic']
# generates bitfield # generates bitfield
flag = 0 flag = 0
if data['quality_label']: if data['quality_label']:
@ -148,32 +164,36 @@ class ConferenceCreateForm(forms.Form):
conference.quality_label = flag conference.quality_label = flag
audience = 0
if data['audience']:
audience = reduce(lambda x,y: x|y, (getattr(Conference.audience, item) for item in data['audience']))
conference.audience = audience
if data.get('country'): if data.get('country'):
conference.country = Country.objects.get(id=data['country'].id)#.id cause select uses queryset conference.country = Country.objects.get(id=data['country'])#.id cause select uses queryset
if data.get('city'): if data.get('city'):
conference.city = City.objects.get(id=data['city']) conference.city = City.objects.get(id=data['city'])
if data.get('place'): if data.get('place'):
conference.place = PlaceConference.objects.get(id=data['place'].id)#.id cause select uses queryset conference.place = PlaceConference.objects.get(id=data['place'])
else:
conference.place = None
# fill translated fields and save object # fill translated fields and save object
fill_with_signal(Conference, conference, data) fill_with_signal(Conference, conference, data)
#fill manytomany fields conference.theme.add(*data['theme'])
for item in data['theme']: conference.tag.add(*Tag.objects.filter(id__in=data['tag']))
conference.theme.add(item.id)#.id cause select uses queryset conference.organiser.add(*Organiser.objects.filter(id__in=data.get('organiser', [])))
for item in data['tag']:
conference.tag.add(item)
# uses because in the next loop data will be overwritten
conference.save() conference.save()
#save files
check_tmp_files(conference, data['key'])
return conference return conference
"""
def clean(self): def clean(self):
id = self.cleaned_data.get('conference_id') id = self.cleaned_data.get('conference_id')
name_ru = self.cleaned_data.get('name_ru') name_ru = self.cleaned_data.get('name_ru')
@ -185,6 +205,20 @@ class ConferenceCreateForm(forms.Form):
del self.cleaned_data['name_ru'] del self.cleaned_data['name_ru']
return self.cleaned_data return self.cleaned_data
"""
def clean_tag(self):
tags = self.cleaned_data.get('tag')
if tags:
res = []
for id in tags.split(','):
try:
res.append(int(id))
except:
continue
return res
else:
return []
def clean_web_page(self): def clean_web_page(self):
""" """

@ -1,8 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.utils.translation import ugettext as _
from django.db import models from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save, pre_save from django.db.models.signals import post_save, pre_save
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from exposition.manager import ClientManager
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from functions.translate import fill_with_signal
from photologue.models import Gallery
from functions.signal_handlers import post_save_handler, pre_save_handler from functions.signal_handlers import post_save_handler, pre_save_handler
import copy import copy
from bitfield import BitField from bitfield import BitField
@ -12,11 +17,14 @@ from functions.db import db_table_exists
from functions.custom_fields import EnumField from functions.custom_fields import EnumField
from functions.models_methods import ExpoManager from functions.models_methods import ExpoManager
from functions.model_mixin import EventMixin, ExpoMixin from functions.model_mixin import EventMixin, ExpoMixin
from functions.models_methods import hvad_to_dict
# check if table exist and create flags if true # check if table exist and create flags if true
flags = [str(item.id) for item in Service.objects.all()] if db_table_exists('service_service') else [] flags = [item.url for item in Service.objects.all()] if db_table_exists('service_service') else []
from django.conf import settings
CURRENCY = ('RUB', 'USD', 'EUR') CURRENCY = settings.CURRENCY
BIT_AUDIENCE = settings.BIT_AUDIENCE
class Conference(TranslatableModel, EventMixin, ExpoMixin): class Conference(TranslatableModel, EventMixin, ExpoMixin):
""" """
@ -25,17 +33,23 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
Uses hvad.TranslatableModel which is child of django.db.models class Uses hvad.TranslatableModel which is child of django.db.models class
""" """
catalog = '/conference/' catalog = '/conference/'
catalog_name = _(u'Конференции:')
# type of event # type of event
event_type = 'conf' event_type = 'conf'
#set manager of this model #set manager of this model
objects = ExpoManager() objects = ExpoManager()
enable = ClientManager()
url = models.SlugField(unique=True) url = models.SlugField(unique=True, max_length=255)
old_url = models.SlugField(unique=True, max_length=255)
data_begin = models.DateField(verbose_name='Дата начала') data_begin = models.DateField(verbose_name='Дата начала')
data_end = models.DateField(verbose_name='Дата окончания') data_end = models.DateField(verbose_name='Дата окончания')
services = BitField(flags=flags)
#relations #relations
country = models.ForeignKey('country.Country', verbose_name='Страна', on_delete=models.PROTECT) country = models.ForeignKey('country.Country', verbose_name='Страна', on_delete=models.PROTECT,
city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT) related_name='conference_country')
city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT,
related_name='conference_city')
place = models.ForeignKey('place_conference.PlaceConference', verbose_name='Место проведения', place = models.ForeignKey('place_conference.PlaceConference', verbose_name='Место проведения',
blank=True, null=True, on_delete=models.PROTECT, related_name='conference_place') blank=True, null=True, on_delete=models.PROTECT, related_name='conference_place')
theme = models.ManyToManyField('theme.Theme', verbose_name='Тематики', theme = models.ManyToManyField('theme.Theme', verbose_name='Тематики',
@ -48,15 +62,20 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
blank=True, null=True, related_name='conference_companies') blank=True, null=True, related_name='conference_companies')
users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки', users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки',
blank=True, null=True, related_name='conference_users') blank=True, null=True, related_name='conference_users')
#!service has bitfield uncomment when country data will be filled photogallery = models.ForeignKey('photologue.Gallery', blank=True, null=True)
services = BitField(flags=flags) logo = models.ImageField(verbose_name='Logo', upload_to='conference/logo/', blank=True)
#service = models.ManyToManyField('service.Service', verbose_name='Услуги', blank=True, null=True) rating = models.IntegerField(default=0, db_index=True) # добавить индекс в базе
quality_label = BitField(flags=['ufi', 'rsva', 'exporating'])
periodic = models.FloatField(verbose_name='Переодичность', blank=True, null=True)
audience = BitField(flags=[k for k, v in BIT_AUDIENCE])
web_page = models.CharField(verbose_name='Вебсайт', max_length=255, blank=True) web_page = models.CharField(verbose_name='Вебсайт', max_length=255, blank=True)
link = models.CharField(verbose_name='Линк на регистрацию', max_length=255, blank=True) link = models.CharField(verbose_name='Линк на регистрацию', max_length=255, blank=True)
quality_label = BitField(flags=['ufi', 'rsva', 'exporating'])
discount = models.PositiveIntegerField(verbose_name='Скидка', blank=True, null=True) discount = models.PositiveIntegerField(verbose_name='Скидка', blank=True, null=True)
# #
currency = EnumField(values=CURRENCY, default='RUB')
currency = EnumField(values=CURRENCY, default='USD')
tax = models.BooleanField(verbose_name='Налог', default=1) tax = models.BooleanField(verbose_name='Налог', default=1)
min_price = models.PositiveIntegerField(verbose_name='Минимальная цена', blank=True, null=True) min_price = models.PositiveIntegerField(verbose_name='Минимальная цена', blank=True, null=True)
max_price = models.PositiveIntegerField(verbose_name='Максимальная цена', blank=True, null=True) max_price = models.PositiveIntegerField(verbose_name='Максимальная цена', blank=True, null=True)
@ -69,6 +88,7 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
is_published = models.BooleanField(default=0) is_published = models.BooleanField(default=0)
files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id') files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id')
note = generic.GenericRelation('note.Note', content_type_field='content_type', object_id_field='object_id')
# statistic # statistic
foundation_year = models.PositiveIntegerField(verbose_name='Год основания', blank=True, null=True) foundation_year = models.PositiveIntegerField(verbose_name='Год основания', blank=True, null=True)
visitors = models.PositiveIntegerField(verbose_name='Посетитеил', blank=True, null=True) visitors = models.PositiveIntegerField(verbose_name='Посетитеил', blank=True, null=True)
@ -98,54 +118,33 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk)) return self.lazy_translation_getter('name', unicode(self.pk))
def get_services(self):
country_ids = [item for item, bool in self.country.services if bool==True]
ids = [item for item, bool in self.services if bool==True]
qs = Service.objects.filter(Q(Q(url__in=country_ids) & Q(type=Service.type.conference)) | Q(url__in=ids))
return list(qs)
#return list(Service.objects.language().filter(url__in=ids, type=Service.type.conference).order_by('sort'))
def get_nearest_events(self): def get_nearest_events(self):
conferences = Conference.objects.all()[:5] conferences = Conference.objects.all()[:5]
return conferences return conferences
def get_catalog_url(self): def get_catalog_url(self):
return '/conferences/' return '/conference/'
def clone(self): def get_audience(self):
""" checked = [item for item, bool in self.audience if bool==True]
Return an identical copy of the instance with a new ID. audience = []
""" for k, v in BIT_AUDIENCE:
if not self.pk: for item in checked:
raise ValueError('Instance must be saved before it can be cloned.') if item == k:
audience.append(v)
duplicate = copy.copy(self)
# Setting pk to None. Django thinking this is a new object. return ', '.join(audience)
duplicate.pk = None
# url must be unique
duplicate.url += '_copy'
if Conference.objects.safe_get(url=duplicate.url):
#already has copy this instance
return
# duplicate should not be published
duplicate.is_published = False
duplicate.cancel_by_administrator = False
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.save()
# but lost all ManyToMany relations and Translations.
# 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
def get_calendar_url(self): def get_calendar_url(self):
return '/conference-add-calendar/%s/'%self.id return '/conference-add-calendar/%s/'%self.id
@ -153,12 +152,51 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
def get_visit_url(self): def get_visit_url(self):
return '/conference-visit/%s/'%self.id return '/conference-visit/%s/'%self.id
def get_note_by_user(self, user_id):
note = self.note.filter(user__id=user_id)
try:
return note.get().text
except:
return ''
def tags(self):
return self.tag.language().all()
def get_gallery(self):
if self.photogallery:
return self.photogallery
class Statistic(models.Model): data = {}
model = type(self)
for code, name in settings.LANGUAGES:
obj = model._meta.translations_model.objects.get(language_code = code,master__id=self.id) #access to translated fields
data['title_%s'%code] = obj.name
data['description_%s'%code] = obj.description
gallery = Gallery()
fill_with_signal(Gallery, gallery, data)
self.photogallery = gallery
self.save()
return gallery
class Statistic(TranslatableModel):
conference = models.ForeignKey(Conference, related_name='statistic') conference = models.ForeignKey(Conference, related_name='statistic')
year = models.PositiveIntegerField(verbose_name='Год') year = models.PositiveIntegerField(verbose_name='Год')
members = models.PositiveIntegerField(verbose_name='Посетители') members = models.PositiveIntegerField(verbose_name='Посетители', blank=True, null=True)
visitors = models.PositiveIntegerField(verbose_name='Участники') visitors = models.PositiveIntegerField(verbose_name='Участники', blank=True, null=True)
area = models.PositiveIntegerField(verbose_name='Площадь', blank=True, null=True)
countries_number = models.PositiveIntegerField(verbose_name='Количество стран', blank=True, null=True)
translations = TranslatedFields(
countries = models.TextField(blank=True)
)
def to_dict(self):
return hvad_to_dict(self)
class TimeTable(TranslatableModel): class TimeTable(TranslatableModel):
@ -166,13 +204,27 @@ class TimeTable(TranslatableModel):
TimeTable for business program TimeTable for business program
""" """
exposition = models.ForeignKey(Conference, related_name='business_program') conference = models.ForeignKey(Conference, related_name='business_program')
begin = models.DateTimeField(verbose_name='Начало') begin = models.DateTimeField(verbose_name='Начало')
end = models.DateTimeField(verbose_name='Конец') end = models.DateTimeField(verbose_name='Конец')
timetable_organiser = models.ForeignKey('organiser.Organiser', null=True, blank=True,
related_name='conf_timetable')
#
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
#translated fields #translated fields
translations = TranslatedFields( translations = TranslatedFields(
name = models.CharField(verbose_name='Название', max_length=255) name = models.CharField(verbose_name='Название программы', max_length=255, blank=True),
programe = models.TextField(verbose_name='Программа'),
speaker = models.CharField(verbose_name='Спикеры', max_length=255, blank=True),
place = models.CharField(verbose_name='Место проведения', max_length=255, blank=True)
) )
def to_dict(self):
return hvad_to_dict(self)
pre_save.connect(pre_save_handler, sender=Conference) pre_save.connect(pre_save_handler, sender=Conference)
post_save.connect(post_save_handler, sender=Conference) post_save.connect(post_save_handler, sender=Conference)
post_save.connect(post_save_handler, sender=TimeTable)
post_save.connect(post_save_handler, sender=Statistic)

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from haystack import indexes from haystack import indexes
from models import Conference from models import Conference
@ -5,6 +6,32 @@ from models import Conference
class ConferenceIndex(indexes.SearchIndex, indexes.Indexable): class ConferenceIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True) text = indexes.CharField(document=True, use_template=True)
where = indexes.MultiValueField() where = indexes.MultiValueField()
url = indexes.CharField()
data_begin = indexes.DateField(model_attr='data_begin')
data_end = indexes.DateField(model_attr='data_end')
theme = indexes.MultiValueField()
tag = indexes.MultiValueField()
country_id = indexes.IntegerField()
city_id = indexes.IntegerField()
area_id = indexes.IntegerField()
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 None
def prepare_catalog_name_en(self, obj):
return u'Conferences'
def prepare_catalog_name_ru(self, obj):
return u'Конференции'
def prepare_where(self, obj): def prepare_where(self, obj):
country = [tr.name for tr in obj.country.translations.all()] country = [tr.name for tr in obj.country.translations.all()]
city = [tr.name for tr in obj.city.translations.all()] city = [tr.name for tr in obj.city.translations.all()]
@ -18,3 +45,5 @@ class ConferenceIndex(indexes.SearchIndex, indexes.Indexable):
return self.get_model().objects.filter(is_published=True) return self.get_model().objects.filter(is_published=True)
def get_updated_field(self):
return "modified"

@ -1,15 +1,74 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from views import ConferenceView from views import ConferenceDetail, ConferenceList, ConferenceByCity, ConferenceByCountry, ConferenceByTheme,\
ConferenceCountryCatalog, ConferenceCityCatalog, ConferenceTagCatalog, ConferenceThemeCatalog, ConferenceMembers,\
ConferenceVisitors, ConferenceServiceView
from exposition.views import ExpositionSearchView
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'conferences/(?P<params>.*)/(?P<page>\d+)/$', ConferenceView.as_view()),
url(r'conferences/(?P<page>\d+)/$', ConferenceView.as_view()),
url(r'conferences/(?P<params>.*)/$', ConferenceView.as_view()), url(r'conference/add-note/(?P<slug>.*)/$', 'conference.views.add_note'),
url(r'conferences/$', ConferenceView.as_view()),
#
url(r'conference-add-calendar/(?P<id>\d+)/$', 'conference.views.conference_add_calendar'), url(r'conference-add-calendar/(?P<id>\d+)/$', 'conference.views.conference_add_calendar'),
url(r'conference-remove-calendar/(?P<id>\d+)/$', 'conference.views.conference_remove_calendar'),
url(r'conference-visit/(?P<id>\d+)/$', 'conference.views.conference_visit'), url(r'conference-visit/(?P<id>\d+)/$', 'conference.views.conference_visit'),
url(r'conference-unvisit/(?P<id>\d+)/$', 'conference.views.conference_unvisit'), # search
url(r'conference/search/', ExpositionSearchView.as_view()),
# country catalog
url(r'conference/country/$', ConferenceByCountry.as_view(), {'meta_id':51}),
url(r'conference/country/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ConferenceCountryCatalog.as_view(), {'meta_id':25}),
url(r'conference/country/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ConferenceCountryCatalog.as_view(), {'meta_id':24}),
url(r'conference/country/(?P<slug>.*)/page/(?P<page>\d+)/$', ConferenceCountryCatalog.as_view(), {'meta_id':23}),
url(r'conference/country/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ConferenceCountryCatalog.as_view(), {'meta_id':25}),
url(r'conference/country/(?P<slug>.*)/(?P<year>\d+)/$', ConferenceCountryCatalog.as_view(), {'meta_id':24}),
url(r'conference/country/(?P<slug>.*)/$', ConferenceCountryCatalog.as_view(), {'meta_id':23}),
# city catalog
url(r'conference/city/$', ConferenceByCity.as_view(), {'meta_id':52}),
url(r'conference/city/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ConferenceCityCatalog.as_view(), {'meta_id':28}),
url(r'conference/city/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ConferenceCityCatalog.as_view(), {'meta_id':27}),
url(r'conference/city/(?P<slug>.*)/page/(?P<page>\d+)/$', ConferenceCityCatalog.as_view(), {'meta_id':26}),
url(r'conference/city/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ConferenceCityCatalog.as_view(), {'meta_id':28}),
url(r'conference/city/(?P<slug>.*)/(?P<year>\d+)/$', ConferenceCityCatalog.as_view(), {'meta_id':27}),
url(r'conference/city/(?P<slug>.*)/$', ConferenceCityCatalog.as_view(), {'meta_id':26}),
# theme catalog
url(r'conference/theme/$', ConferenceByTheme.as_view(), {'meta_id':50}),
url(r'conference/theme/(?P<slug>.*)/country/(?P<country_slug>.*)/page/(?P<page>\d+)/$', ConferenceThemeCatalog.as_view()),
url(r'conference/theme/(?P<slug>.*)/country/(?P<country_slug>.*)/$', ConferenceThemeCatalog.as_view()),
url(r'conference/theme/(?P<slug>.*)/city/(?P<city_slug>.*)/page/(?P<page>\d+)/$', ConferenceThemeCatalog.as_view()),
url(r'conference/theme/(?P<slug>.*)/city/(?P<city_slug>.*)/$', ConferenceThemeCatalog.as_view()),
url(r'conference/theme/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ConferenceThemeCatalog.as_view(), {'meta_id':31}),
url(r'conference/theme/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ConferenceThemeCatalog.as_view(), {'meta_id':30}),
url(r'conference/theme/(?P<slug>.*)/page/(?P<page>\d+)/$', ConferenceThemeCatalog.as_view(), {'meta_id':29}),
url(r'conference/theme/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ConferenceThemeCatalog.as_view(), {'meta_id':31}),
url(r'conference/theme/(?P<slug>.*)/(?P<year>\d+)/$', ConferenceThemeCatalog.as_view(), {'meta_id':30}),
url(r'conference/theme/(?P<slug>.*)/$', ConferenceThemeCatalog.as_view(), {'meta_id':29}),
# tag catalog
url(r'conference/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ConferenceTagCatalog.as_view(), {'meta_id':34}),
url(r'conference/tag/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ConferenceTagCatalog.as_view(), {'meta_id':33}),
url(r'conference/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', ConferenceTagCatalog.as_view(), {'meta_id':32}),
url(r'conference/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ConferenceTagCatalog.as_view(), {'meta_id':34}),
url(r'conference/tag/(?P<slug>.*)/(?P<year>\d+)/$', ConferenceTagCatalog.as_view(), {'meta_id':33}),
url(r'conference/tag/(?P<slug>.*)/$', ConferenceTagCatalog.as_view(), {'meta_id':32}),
# conf additional pages
url(r'conference/(?P<slug>.*)/visitors/page/(?P<page>\d+)/$', ConferenceVisitors.as_view()),
url(r'conference/(?P<slug>.*)/visitors/$', ConferenceVisitors.as_view()),
url(r'conference/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ConferenceMembers.as_view()),
url(r'conference/(?P<slug>.*)/members/$', ConferenceMembers.as_view()),
url(r'conference/(?P<slug>.*)/service/(?P<service_url>.*)/', ConferenceServiceView.as_view()),
# conf list
url(r'conference/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ConferenceList.as_view(), {'meta_id':22}),
url(r'conference/(?P<year>\d+)/page/(?P<page>\d+)/$', ConferenceList.as_view(), {'meta_id':21}),
url(r'conference/(?P<year>\d+)/(?P<month>.*)/$', ConferenceList.as_view(), {'meta_id':22}),
url(r'conference/(?P<year>\d+)/$', ConferenceList.as_view(), {'meta_id':21}),
url(r'conference/page/(?P<page>\d+)/$', ConferenceList.as_view(), {'meta_id':20}),
# conf page
url(r'conference/(?P<slug>.*)/$', ConferenceDetail.as_view(), {'meta_id':35}),
url(r'conference/$', ConferenceList.as_view(), {'meta_id':20}),
) )
"""
"""

@ -1,12 +1,387 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.http import HttpResponse
from models import Conference
from functions.custom_views import ExpoListView
import json import json
import datetime
from django.conf import settings
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.contrib import messages
from django.shortcuts import get_object_or_404
from django.contrib.contenttypes.models import ContentType
from django.views.generic import ListView, DetailView
from django.views.generic.edit import FormMixin
from django.utils.translation import ugettext as _
from django.utils import translation
from note.models import Note
from models import Conference
from accounts.models import User
from country.models import Country
from city.models import City
from theme.models import Theme, Tag
from service.order_forms import AdvertiseForm
from functions.search_forms import ExpositionSearchForm
from meta.views import MetadataMixin
from functions.cache_mixin import JitterCacheMixin, CacheMixin
MONTHES = settings.MONTHES
class ConferenceBy(JitterCacheMixin, MetadataMixin, ListView):
cache_range = settings.CACHE_RANGE
template_name = 'conference/conference_by.html'
title1 = ''
title2 = ''
"""
abstact class
"""
def get_context_data(self, **kwargs):
context = super(ConferenceBy, self).get_context_data(**kwargs)
context.update({'title1': self.title1, 'title2': self.title2, 'catalog': self.catalog})
return context
class ConferenceByCountry(ConferenceBy):
model = Country
title1 = _(u'По странам')
title2 = _(u'Коференции мира по странам')
catalog = 'country/'
def get_queryset(self):
return self.model.objects.conference_countries_with_count()
#lang = translation.get_language()
#return self.model.objects.select_related('conference_country')\
# .filter(conference_country__country__isnull=False, translations__language_code=lang)\
# .order_by('translations__name').distinct()
class ConferenceByTheme(ConferenceBy):
model = Theme
title1 = _(u'По тематикам')
title2 = _(u'Коференции мира по тематикам')
catalog = 'theme/'
def get_queryset(self):
return self.model.active.conference_themes_with_count()
#lang = translation.get_language()
#return self.model.objects.select_related('conference_themes')\
# .filter(conference_themes__theme__isnull=False, translations__language_code=lang)\
# .order_by('translations__name').distinct()
class ConferenceByCity(ConferenceBy):
model = City
title1 = _(u'По городам')
title2 = _(u'Коференции мира по городам')
catalog = 'city/'
def get_queryset(self):
return self.model.used.conference_cities_with_count()
#lang = translation.get_language()
#return self.model.objects.select_related('conference_city')\
# .filter(conference_city__city__isnull=False, translations__language_code=lang)\
# .order_by('translations__name').distinct()
class ConferenceCatalog(JitterCacheMixin, MetadataMixin, ListView):
cache_range = settings.CACHE_RANGE
model = Conference
paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/conference/catalog.html'
search_form = ExpositionSearchForm
filter_object = None
year = None
month = None
country = None
city = None
def get_filtered_qs(self):
# diferent for views
pass
def get_queryset(self):
qs = self.get_filtered_qs()
year = self.kwargs.get('year')
if year:
qs = self.model.enable.filter(data_end__year=year)
filter_object = self.filter_object
if isinstance(filter_object, Country):
qs = qs.filter(country=filter_object)
elif isinstance(filter_object, City):
qs = qs.filter(city=filter_object)
elif isinstance(filter_object, Theme):
qs = qs.filter(theme=filter_object)
if self.kwargs.get('country'):
qs = qs.filter(country=self.kwargs.get('country'))
if self.kwargs.get('city'):
qs = qs.filter(city=self.kwargs.get('city'))
elif isinstance(filter_object, Tag):
qs = qs.filter(tag=filter_object)
# info for breadscrumbs
self.year = {'text': year, 'link': '%s%s/%s/'%(self.catalog_url, self.filter_object.url, year)}
month = self.kwargs.get('month')
monthes = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')},
'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')},
'may': {'value': 5, 'name': _(u'Май')}, 'jun': {'value': 6, 'name': _(u'Июнь')},
'jul': {'value': 7, 'name': _(u'Июль')}, 'aug': {'value': 8, 'name': _(u'Август')},
'sep': {'value': 9, 'name': _(u'Сентябрь')}, 'oct': {'value': 10, 'name': _(u'Октябрь')},
'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}}
if month and monthes.get(month):
qs = qs.filter(data_begin__month=monthes[month]['value'])
if self.country:
self.month = {'text': monthes[month]['name'], 'link': '%s%s/country/%s/%s/%s/'%
(self.catalog_url, self.filter_object.url, self.country.url, year, month)}
elif self.city:
self.month = {'text': monthes[month]['name'], 'link': '%s%s/city/%s/%s/%s/'%
(self.catalog_url, self.filter_object.url, self.city.url, year, month)}
else:
self.month = {'text': monthes[month]['name'], 'link': '%s%s/%s/%s/'%(self.catalog_url, self.filter_object.url, year, month)}
return qs.order_by('data_begin')
def get_context_data(self, **kwargs):
context = super(ConferenceCatalog, self).get_context_data(**kwargs)
context['search_form'] = self.search_form
context['filter_object'] = self.filter_object
context['year'] = self.year
context['month'] = self.month
context['catalog_url'] = self.catalog_url
return context
class ConferenceCountryCatalog(ConferenceCatalog):
catalog_url = '/conference/country/'
def get_filtered_qs(self):
#this method used in parent get_queryset
slug = self.kwargs.get('slug')
country = get_object_or_404(Country, url=slug)
self.kwargs['country'] = country
self.filter_object = country
qs = self.model.enable.upcoming().filter(country=country)
return qs
class ConferenceCityCatalog(ConferenceCatalog):
catalog_url = '/conference/city/'
def get_filtered_qs(self):
#this method used in parent get_queryset
slug = self.kwargs.get('slug')
city = get_object_or_404(City, url=slug)
self.kwargs['city'] = city
qs = self.model.enable.upcoming().filter(city=city)
self.filter_object = city
return qs
class ConferenceThemeCatalog(ConferenceCatalog):
template_name = 'conference/catalog_theme.html'
catalog_url = '/conference/theme/'
country = None
city = None
def get_filtered_qs(self):
#this method used in parent get_queryset
slug = self.kwargs.get('slug')
country_slug = self.kwargs.get('country_slug')
city_slug = self.kwargs.get('city_slug')
theme = get_object_or_404(Theme, url=slug)
self.kwargs['theme'] = theme
qs = self.model.enable.upcoming().filter(theme=theme)
if country_slug:
country = get_object_or_404(Country, url=country_slug)
self.country = country
qs = qs.filter(country=country)
if city_slug:
city = get_object_or_404(City, url=city_slug)
self.city = city
qs = qs.filter(city=city)
self.filter_object = theme
return qs
def get_context_data(self, **kwargs):
context = super(ConferenceThemeCatalog, self).get_context_data(**kwargs)
if self.country:
context['country'] = self.country
if self.city:
context['city'] = self.city
return context
class ConferenceTagCatalog(ConferenceCatalog):
catalog_url = '/conference/tag/'
def get_filtered_qs(self):
#this method used in parent get_queryset
slug = self.kwargs.get('slug')
tag = get_object_or_404(Tag, url=slug)
self.kwargs['tag'] = tag
qs = self.model.enable.upcoming().filter(tag=tag)
self.filter_object = tag
return qs
class ConferenceVisitors(MetadataMixin, ListView):
paginate_by = settings.CLIENT_PAGINATION
model = Conference
#template_name = 'event_visitors.html'
template_name = 'client/conference/visitors.html'
obj = None
search_form = ExpositionSearchForm
def get_queryset(self):
slug = self.kwargs.get('slug')
conference = get_object_or_404(self.model, url=slug)
self.obj = conference
return conference.users.all()
def get_context_data(self, **kwargs):
context = super(ConferenceVisitors, self).get_context_data(**kwargs)
context['object'] = self.obj
context['search_form'] = self.search_form
return context
class ConferenceMembers(MetadataMixin, ListView):
paginate_by = settings.CLIENT_PAGINATION
model = Conference
#template_name = 'event_visitors.html'
template_name = 'client/conference/members.html'
obj = None
search_form = ExpositionSearchForm
def get_queryset(self):
slug = self.kwargs.get('slug')
conference = get_object_or_404(self.model, url=slug)
self.obj = conference
return conference.company.all()
def get_context_data(self, **kwargs):
context = super(ConferenceMembers, self).get_context_data(**kwargs)
context['object'] = self.obj
context['search_form'] = self.search_form
return context
from service.models import Service
from service.views import order_forms
class ConferenceServiceView(FormMixin, DetailView):
model = Conference
slug_field = 'url'
service = None
success_url = '/service/thanks/'
def post(self, request, *args, **kwargs):
self.object = self.get_object()
service_url = self.kwargs.get('service_url')
service = get_object_or_404(Service, url=service_url)
service_form = order_forms.get(service_url)
self.form_class = service_form
form = self.get_form(service_form)
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_context_data(self, **kwargs):
context = super(ConferenceServiceView, self).get_context_data(**kwargs)
service_url = self.kwargs.get('service_url')
service = get_object_or_404(Service, url=service_url)
self.service = service
self.template_name = service.template
form = order_forms.get(service_url)
self.form_class = form
if not form:
raise Http404
context['form'] = self.get_form(self.form_class)
context['service'] = service
context['object'] = self.get_object()
return context
def form_valid(self, form):
order = form.save(commit=False)
order.conference = self.object
order.save()
messages.success(self.request, _(u'Ваш запрос был успешно отправлен'))
return HttpResponseRedirect(self.success_url)
def get_initial(self):
"""
Returns the initial data to use for forms on this view.
"""
if self.request.user.is_authenticated():
user = self.request.user
initial = {'person_inf': user.get_full_name(),
'person': user.email,
'country': user.profile.country.name if user.profile.country else '',
'city':user.profile.city.name if user.profile.city else '',
'phone': user.profile.phone if user.profile.phone else ''}
class ConferenceView(ExpoListView):
return initial
else:
return self.initial.copy()
class ConferenceDetail(JitterCacheMixin, DetailView):
cache_range = settings.CACHE_RANGE
model = Conference model = Conference
template_name = 'event_catalog.html' slug_field = 'url'
template_name = 'client/conference/conference_detail.html'
def get_context_data(self, **kwargs):
context = super(ConferenceDetail, self).get_context_data(**kwargs)
context['advertising_form'] = AdvertiseForm()
return context
class ConferenceList(MetadataMixin, JitterCacheMixin, ListView):
cache_range = settings.CACHE_RANGE
model = Conference
paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/conference/conference_list.html'
search_form = ExpositionSearchForm
catalog_url = '/conference/'
year = None
month = None
def get_queryset(self):
if self.request.user.is_staff:
qs = self.model.objects.upcoming()
else:
qs = self.model.enable.upcoming()
year = self.kwargs.get('year')
if year:
qs = self.model.enable.filter(data_end__year=year)
# info for breadscrumbs
self.year = {'text': year, 'link': '%s%s/'%(self.catalog_url, year)}
month = self.kwargs.get('month')
if month and MONTHES.get(month):
qs = qs.filter(data_begin__month=MONTHES[month]['value'])
self.month = {'text': MONTHES[month]['name'], 'link': '%s%s/%s/'%(self.catalog_url, year, month)}
return qs
def get_context_data(self, **kwargs):
context = super(ConferenceList, self).get_context_data(**kwargs)
context['month'] = self.month
context['catalog_url'] = self.catalog_url
context['search_form'] = self.search_form
context['year'] = self.year
context['month'] = self.month
return context
def conference_add_calendar(request, id): def conference_add_calendar(request, id):
args = {'success': False} args = {'success': False}
@ -14,38 +389,32 @@ def conference_add_calendar(request, id):
if user.is_authenticated(): if user.is_authenticated():
conf = Conference.objects.safe_get(id=id) conf = Conference.objects.safe_get(id=id)
if conf: if conf in user.calendar.get_confs():
user.calendar.conferences.remove(conf)
args['in'] = False
else:
user.calendar.conferences.add(conf) user.calendar.conferences.add(conf)
args['success'] = True args['in'] = True
else:
args['not_authorized'] = True
args['success'] = True args['success'] = True
return HttpResponse(json.dumps(args), content_type='application/json')
def conference_remove_calendar(request, id):
args = {'success': False}
if request.user:
user = request.user
conf = Conference.objects.safe_get(id=id)
if conf:
user.calendar.conferences.remove(conf)
args['success'] = True
else: else:
args['not_authorized'] = True args['not_authorized'] = True
args['success'] = True args['success'] = True
return HttpResponse(json.dumps(args), content_type='application/json') return HttpResponse(json.dumps(args), content_type='application/json')
def conference_visit(request, id): def conference_visit(request, id):
args = {'success': False} args = {'success': False}
user = request.user user = request.user
if user.is_authenticated(): if user.is_authenticated():
conf = Conference.objects.safe_get(id=id) conf = Conference.objects.safe_get(id=id)
if conf: if user in conf.users.all():
conf.users.remove(user)
args['in'] = False
else:
conf.users.add(user) conf.users.add(user)
args['success'] = True args['in'] = True
args['success'] = True
else: else:
args['not_authorized'] = True args['not_authorized'] = True
@ -53,18 +422,34 @@ def conference_visit(request, id):
return HttpResponse(json.dumps(args), content_type='application/json') return HttpResponse(json.dumps(args), content_type='application/json')
def conference_unvisit(request, id): def add_note(request, slug):
args = {'success': False} args = {'success': False}
user = request.user
if user.is_authenticated():
conf = Conference.objects.safe_get(id=id)
if conf:
conf.users.remove(user)
else:
args['not_authorized'] = True
args['success'] = True
return HttpResponse(json.dumps(args), content_type='application/json') if request.user.is_authenticated():
if request.GET:
text = request.GET['note_text']
try:
conf = Conference.objects.get(url=slug)
except Conference.DoesNotExist:
raise Http404
ct = ContentType.objects.get_for_model(conf)
object_id = conf.id
user = User.objects.get(id=request.user.id)
if Note.objects.filter(user=user, content_type=ct, object_id=object_id).exists():
Note.objects.filter(user=user, content_type=ct, object_id=object_id).update(text=text)
else:
Note.objects.create(content_type=ct, object_id=object_id, user=user, text=text)
user.calendar.conferences.add(conf)
args['success'] = True
args['text'] = text
else:
args['not_authorized'] = True
args['success'] = True
return HttpResponse(json.dumps(args), content_type='application/json')

@ -1,23 +1,25 @@
import json import json
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.shortcuts import HttpResponse from django.shortcuts import HttpResponse
from forms import CallbackForm #from forms import CallbackForm
from service.order_forms import CallBackForm
from meta.views import MetadataMixin
class AdvertisingView(TemplateView): class AdvertisingView(MetadataMixin, TemplateView):
template_name = 'simple_pages/advertising.html' template_name = 'simple_pages/advertising.html'
class AboutView(TemplateView): class AboutView(MetadataMixin, TemplateView):
template_name = 'simple_pages/about.html' template_name = 'simple_pages/about.html'
def callback(request): def callback(request):
response = {'success': False} response = {'success': False}
if request.GET: if request.GET:
form = CallbackForm(request.GET) form = CallBackForm(request.GET)
if form.is_valid(): if form.is_valid():
form.send() form.save()
response['success'] = True response['success'] = True
else: else:
response['errors'] = form.errors response['errors'] = form.errors

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from django.utils import translation
from country.models import Country
def get_from_old(country):
db = MySQLdb.connect(host="localhost",
user="kotzilla",
passwd="qazedc",
db="test2",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
sql = """SELECT url, inflect FROM old_expomap.products_places WHERE title="%(name)s" """%{'name': country.name.encode('utf-8')}
#print(country.name.encode('utf-8'))
# print(sql)
cursor.execute(sql)
result = cursor.fetchone()
return result
class Command(BaseCommand):
def handle(self, *args, **options):
translation.activate('ru')
for country in Country.objects.all():
old_data = get_from_old(country)
if old_data is None:
continue
country.old_url = old_data['url']
country.inflect = old_data['inflect']
try:
country.save()
print(country)
except:
continue

@ -0,0 +1,105 @@
import datetime
from django.utils import translation
from django.core.cache import cache
from django.utils.translation import get_language as lang
from hvad.models import TranslationManager
class CountryManager(TranslationManager):
cache_time = 600
def all(self):
"""
hack
"""
return super(TranslationManager, self).all().filter(translations__language_code=lang()).order_by('translations__name')
def safe_get(self, **kwargs):
model = self.model
try:
return model.objects.get(**kwargs)
except:
return None
def expo_countries(self):
lang = translation.get_language()
key = 'used_expo_countries_%s'%lang
cached_countries = cache.get(key)
if cached_countries:
return cached_countries
else:
from exposition.models import Exposition
countries_id = [item['country_id'] for item in Exposition.objects.values('country_id').distinct()]
countries = list(self.language().filter(id__in=countries_id))
cache.set(key, countries, self.cache_time)
return countries
def expo_countries_with_count(self):
lang = translation.get_language()
key = 'used_expo_countries_count_%s'%lang
cached_countries = cache.get(key)
if cached_countries:
return cached_countries
else:
from exposition.models import Exposition
sql = {'expo_count':
"""SELECT COUNT(*)
FROM exposition_exposition
WHERE exposition_exposition.country_id = country_country.id
AND exposition_exposition.data_end >= CURDATE()
AND exposition_exposition.is_published = 1"""}
now = datetime.datetime.now().date()
# id of unique countries
countries_id = [item['country_id'] for item in Exposition.objects.filter(is_published=True, data_end__gte=now).values('country_id').distinct()]
countries = set(list(self.language().filter(id__in=countries_id).extra(select=sql)))
countries = sorted(countries, key=lambda x: x.name)
cache.set(key, countries, self.cache_time)
return countries
def conference_countries_with_count(self):
lang = translation.get_language()
key = 'used_conference_countries_count_%s'%lang
cached_countries = cache.get(key)
if cached_countries:
return cached_countries
else:
from conference.models import Conference
sql = {'conference_count':
"""SELECT COUNT(*)
FROM conference_conference
WHERE conference_conference.country_id = country_country.id
AND conference_conference.data_end >= CURDATE()
AND conference_conference.is_published = 1"""}
now = datetime.datetime.now().date()
# id of unique countries
countries_id = [item['country_id'] for item in Conference.objects.filter(is_published=True, data_end__gte=now).values('country_id').distinct()]
countries = set(list(self.language().filter(id__in=countries_id).extra(select=sql)))
countries = sorted(countries, key=lambda x: x.name)
cache.set(key, countries, self.cache_time)
return countries
def conference_countries(self):
lang = translation.get_language()
key = 'used_conference_countries_%s'%lang
cached_countries = cache.get(key)
if cached_countries:
return cached_countries
else:
from conference.models import Conference
countries_id = [item['country_id'] for item in Conference.objects.values('country_id').distinct()]
countries = list(self.language().filter(id__in=countries_id))
cache.set(key, countries, self.cache_time)
return countries
class AreaManager(TranslationManager):
def all_sorted(self):
"""
return list, not queryset
"""
model = self.model
result = list(model.objects.filter())
result.sort(key=lambda x: len(x.expos()), reverse=True)
return result

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import date from datetime import date
from django.db import models from django.db import models
from django.utils.translation import ugettext as _
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from django.db.models.signals import post_save, pre_save from django.db.models.signals import post_save
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields
from bitfield import BitField from bitfield import BitField
from manager import CountryManager, AreaManager
# models # models
from directories.models import Language, Currency from directories.models import Language, Currency
from city.models import City from city.models import City
@ -13,42 +13,18 @@ from service.models import Service
from exposition.models import Exposition from exposition.models import Exposition
from place_exposition.models import PlaceExposition from place_exposition.models import PlaceExposition
from organiser.models import Organiser from organiser.models import Organiser
from conference.models import Conference
from seminar.models import Seminar
from webinar.models import Webinar
# func # func
from functions.custom_fields import EnumField
from functions.db import db_table_exists from functions.db import db_table_exists
from functions.signal_handlers import post_save_handler, pre_save_handler from functions.signal_handlers import post_save_handler, pre_save_handler
from django.utils.translation import get_language as lang
from django.utils import translation from django.utils import translation
# check if table exist and create flags if true # check if table exist and create flags if true
flags = [str(item.url) for item in Service.objects.all()] if db_table_exists('service_service') else [] flags = [str(item.url) for item in Service.objects.all()] if db_table_exists('service_service') else []
class CountryManager(TranslationManager):
def all(self):
"""
hack
"""
return super(TranslationManager, self).all().filter(translations__language_code=lang()).order_by('translations__name')
def safe_get(self, **kwargs):
model = self.model
try:
return model.objects.get(**kwargs)
except:
return None
class AreaManager(TranslationManager):
def all_sorted(self):
"""
return list, not queryset
"""
model = self.model
result = list(model.objects.filter())
result.sort(key=lambda x: len(x.expos()), reverse=True)
return result
class Area(TranslatableModel): class Area(TranslatableModel):
translations = TranslatedFields( translations = TranslatedFields(
@ -56,13 +32,16 @@ class Area(TranslatableModel):
) )
objects = AreaManager() objects = AreaManager()
class Meta:
ordering = ['translations__name']
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk)) return self.lazy_translation_getter('name', unicode(self.pk))
def countries(self): def countries(self):
lang = translation.get_language() lang = translation.get_language()
return Country.objects.select_related('exposition_country')\ return Country.objects.select_related('exposition_country')\
.filter(exposition_country__country__isnull=False, translations__language_code=lang, area=self).distinct() .filter(exposition_country__country__isnull=False, translations__language_code=lang, area=self).distinct().order_by('translations__name')
def expos(self): def expos(self):
countries = self.countries() countries = self.countries()
@ -77,9 +56,6 @@ class Area(TranslatableModel):
return parent return parent
class Country(TranslatableModel): class Country(TranslatableModel):
""" """
Create Country model Create Country model
@ -87,12 +63,12 @@ class Country(TranslatableModel):
Uses hvad.TranslatableModel which is child of django.db.models class Uses hvad.TranslatableModel which is child of django.db.models class
""" """
objects = CountryManager() objects = CountryManager()
catalog = '/country/' catalog = '/country/'
services = BitField(flags=flags) services = BitField(flags=flags)
url = models.SlugField(unique=True) url = models.SlugField(unique=True)
old_url = models.CharField(unique=True, max_length=55)
inflect = models.CharField(max_length=255, blank=True)
# relations # relations
area = models.ForeignKey(Area) area = models.ForeignKey(Area)
big_cities = models.ManyToManyField(City, blank=True, null=True, related_name='cities') big_cities = models.ManyToManyField(City, blank=True, null=True, related_name='cities')
@ -104,14 +80,12 @@ class Country(TranslatableModel):
teritory = models.PositiveIntegerField(blank=True, null=True) teritory = models.PositiveIntegerField(blank=True, null=True)
timezone = models.FloatField(blank=True, null=True) timezone = models.FloatField(blank=True, null=True)
phone_code = models.PositiveIntegerField(blank=True, null=True) phone_code = models.PositiveIntegerField(blank=True, null=True)
time_delivery = models.PositiveSmallIntegerField(blank=True, null=True) time_delivery = models.PositiveSmallIntegerField(blank=True, null=True)
latitude = models.FloatField(blank=True, null=True) latitude = models.FloatField(blank=True, null=True)
longitude = models.FloatField(blank=True, null=True) longitude = models.FloatField(blank=True, null=True)
# fields saves information about creating and changing model
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True) modified = models.DateTimeField(auto_now=True)
country_code = models.CharField(max_length=2)
# connection with FileModel by ContentType # connection with FileModel by ContentType
files = generic.GenericRelation('file.FileModel',content_type_field='content_type', object_id_field='object_id') files = generic.GenericRelation('file.FileModel',content_type_field='content_type', object_id_field='object_id')
#translated fields #translated fields
@ -127,12 +101,10 @@ class Country(TranslatableModel):
title = models.CharField(max_length=255), title = models.CharField(max_length=255),
descriptions = models.CharField(max_length=255), descriptions = models.CharField(max_length=255),
keywords = models.CharField(max_length=255), keywords = models.CharField(max_length=255),
) )
country_code = models.CharField(max_length=2)
# class Meta: class Meta:
# ordering = ['translations__name'] ordering = ['translations__name']
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk)) return self.lazy_translation_getter('name', unicode(self.pk))
@ -160,10 +132,24 @@ class Country(TranslatableModel):
return len(Exposition.objects.filter(country=self.id)) return len(Exposition.objects.filter(country=self.id))
def conferences_number(self):
return Conference.objects.filter(country=self.id).count()
def seminars_number(self):
return Seminar.objects.filter(country=self.id).count()
def webinars_number(self):
return Webinar.objects.filter(country=self.id).count()
def active_cities(self): def active_cities(self):
return City.used.active_qs().filter(country=self)
lang = translation.get_language() lang = translation.get_language()
return City.objects.select_related('exposition_city')\ #return City.objects.select_related('exposition_city')\
.filter(exposition_city__city__isnull=False, translations__language_code=lang, country=self).distinct() # .filter(exposition_city__city__isnull=False, translations__language_code=lang, country=self).distinct().order_by('translations__name')
def get_sub_categories(self): def get_sub_categories(self):
objects = [{'text':item.name, 'id':item.id, 'name':'ci', 'sub': False} for item in self.active_cities()] objects = [{'text':item.name, 'id':item.id, 'name':'ci', 'sub': False} for item in self.active_cities()]

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.core.context_processors import csrf from django.core.context_processors import csrf
@ -8,6 +9,7 @@ from django.forms.models import modelformset_factory
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
# models and forms # models and forms
from haystack.query import SearchQuerySet
from models import Exposition, TimeTable, Statistic, TmpTimeTable from models import Exposition, TimeTable, Statistic, TmpTimeTable
from forms import ExpositionCreateForm, ExpositionDeleteForm, TimeTableForm, StatisticForm, ExpositionFilterForm from forms import ExpositionCreateForm, ExpositionDeleteForm, TimeTableForm, StatisticForm, ExpositionFilterForm
from theme.models import Tag from theme.models import Tag
@ -241,11 +243,11 @@ class ExpositionView(AdminView):
template_name = 'admin/exposition/exposition.html' template_name = 'admin/exposition/exposition.html'
def form_valid(self, form): def form_valid(self, form):
StatisticFormSet = formset_factory(StatisticForm) #StatisticFormSet = formset_factory(StatisticForm)
formset_statistic = StatisticFormSet(self.request.POST) #formset_statistic = StatisticFormSet(self.request.POST)
self.set_obj() self.set_obj()
expo = form.save(obj=self.obj) expo = form.save(obj=self.obj)
"""
# delete old halls # delete old halls
Statistic.objects.filter(exposition=getattr(expo, 'id')).delete() Statistic.objects.filter(exposition=getattr(expo, 'id')).delete()
@ -255,7 +257,7 @@ class ExpositionView(AdminView):
statistic = item.save(commit=False) statistic = item.save(commit=False)
statistic.exposition = expo statistic.exposition = expo
statistic.save() statistic.save()
"""
return HttpResponseRedirect(self.success_url) return HttpResponseRedirect(self.success_url)
@ -331,20 +333,22 @@ class ExpositionView(AdminView):
context = super(ExpositionView, self).get_context_data(**kwargs) context = super(ExpositionView, self).get_context_data(**kwargs)
obj = self.set_obj() obj = self.set_obj()
if obj: if obj:
StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('exposition',)) #StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('exposition',))
# get existing statistic # get existing statistic
statistic = Statistic.objects.filter(exposition=getattr(obj, 'id')) #statistic = Statistic.objects.filter(exposition=getattr(obj, 'id'))
# fill HallFormSet # fill HallFormSet
formset_statistic = StatisticFormSet(queryset=statistic) #formset_statistic = StatisticFormSet(queryset=statistic)
context['stat_form'] = StatisticForm()
context['file_form'] = FileForm(initial={'model': 'exposition.Exposition'}) context['file_form'] = FileForm(initial={'model': 'exposition.Exposition'})
files = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(obj),object_id=getattr(obj, 'id')) files = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(obj),object_id=getattr(obj, 'id'))
context['files'] = files context['files'] = files
else: else:
StatisticFormSet = formset_factory(StatisticForm) #StatisticFormSet = formset_factory(StatisticForm)
formset_statistic = StatisticFormSet() #formset_statistic = StatisticFormSet()
pass
context['formset_statistic'] = formset_statistic #context['formset_statistic'] = formset_statistic
context['photo_form'] = PhotoForm() context['photo_form'] = PhotoForm()
context['timetable_form'] = TimeTableForm() context['timetable_form'] = TimeTableForm()
@ -358,4 +362,26 @@ class ExpositionListView(AdminListView):
def upload_exposition_photo(request, expo_id): def upload_exposition_photo(request, expo_id):
return upload_photo(request, expo_id, Exposition) return upload_photo(request, expo_id, Exposition)
def get_by_lang(item, field, lang='en'):
"""
:param item: searchresult object
field: translated field
:return:
"""
return getattr(item, field+'_'+lang)
from django.utils import translation
def search_expo(request):
term = request.GET['term'].capitalize()
lang = translation.get_language()
if not term:
qs = SearchQuerySet().models(Exposition).order_by('text')[:30]
else:
qs = SearchQuerySet().models(Exposition).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')

@ -6,13 +6,16 @@ urlpatterns = patterns('exposition.admin',
url(r'^upload-photo/(?P<expo_id>.*)/$', 'upload_exposition_photo'), url(r'^upload-photo/(?P<expo_id>.*)/$', 'upload_exposition_photo'),
#url(r'^add.*/$', 'exposition_add'), #url(r'^add.*/$', 'exposition_add'),
#url(r'^delete/(?P<url>.*)/$', 'exposition_delete'), url(r'^delete/(?P<url>.*)/$', 'exposition_delete'),
#url(r'^change/(?P<url>.*)/$', 'exposition_change'), #url(r'^change/(?P<url>.*)/$', 'exposition_change'),
url(r'^all/$', ExpositionListView.as_view()), url(r'^all/$', ExpositionListView.as_view()),
url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'exposition_switch'), url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'exposition_switch'),
#url(r'^copy/(?P<url>.*)$', 'exposition_copy'), #url(r'^copy/(?P<url>.*)$', 'exposition_copy'),
url(r'^search/$', 'search_expo'),
url(r'^(?P<url>.*)/$', ExpositionView.as_view()), url(r'^(?P<url>.*)/$', ExpositionView.as_view()),
url(r'^$', ExpositionView.as_view()), url(r'^$', ExpositionView.as_view()),
) )

@ -28,6 +28,8 @@ from functions.admin_forms import AdminFilterForm
places = [(item.id, item.name) for item in PlaceExposition.objects.language().all()] places = [(item.id, item.name) for item in PlaceExposition.objects.language().all()]
places.insert(0,('', 'Не выбрано')) places.insert(0,('', 'Не выбрано'))
class ExpositionCreateForm(forms.Form): class ExpositionCreateForm(forms.Form):
""" """
Create Exposition form for creating exposition Create Exposition form for creating exposition
@ -44,7 +46,7 @@ class ExpositionCreateForm(forms.Form):
currencies = [(item, item) for item in CURRENCY] currencies = [(item, item) for item in CURRENCY]
data_begin = forms.DateField(label=u'Дата начала', input_formats=['%Y-%m-%d', '%d.%m.%Y']) data_begin = forms.DateField(label=u'Дата начала', input_formats=['%Y-%m-%d', '%d.%m.%Y'])
data_end = forms.DateField(label=u'Дата окночания', input_formats=['%Y-%m-%d', '%d.%m.%Y']) data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y'])
logo = forms.ImageField(label='Logo', required=False) logo = forms.ImageField(label='Logo', required=False)
organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False, organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
@ -77,13 +79,9 @@ class ExpositionCreateForm(forms.Form):
widget=forms.CheckboxSelectMultiple()) widget=forms.CheckboxSelectMultiple())
# #
currency = forms.ChoiceField(label=u'Валюта', choices=currencies, required=False) currency = forms.ChoiceField(label=u'Валюта', choices=currencies, required=False)
application_deadline = forms.DateField(label=u'Срок подачи стэнда', required=False) application_deadline = forms.DateField(label=u'Срок подачи стенда', required=False)
min_stand_size = forms.CharField(label=u'Минимальный размер стэнда', required=False) min_stand_size = forms.CharField(label=u'Минимальный размер стенда', required=False)
#price_day = forms.CharField(label=u'Цена за 1 день', required=False)
#price_all = forms.CharField(label=u'Цена за все дни', required=False)
#price_day_bar = forms.CharField(label=u'Цена на стойке 1 день', required=False)
#price_all_bar = forms.CharField(label=u'Цена на стойке все дни', required=False)
price_catalog = forms.CharField(label=u'Цена за каталог', required=False) price_catalog = forms.CharField(label=u'Цена за каталог', required=False)
tax = forms.BooleanField(label=u'Налог включен', initial=True, required=False) tax = forms.BooleanField(label=u'Налог включен', initial=True, required=False)
min_closed_area = forms.CharField(label=u'Минимальная цена закрытой НЕ оборудованной площади', required=False) min_closed_area = forms.CharField(label=u'Минимальная цена закрытой НЕ оборудованной площади', required=False)
@ -227,6 +225,8 @@ class ExpositionCreateForm(forms.Form):
if data.get('place'): if data.get('place'):
exposition.place = PlaceExposition.objects.get(id=data['place']) exposition.place = PlaceExposition.objects.get(id=data['place'])
else:
exposition.place = None
# fill translated fields and save object # fill translated fields and save object
fill_with_signal(Exposition, exposition, data) fill_with_signal(Exposition, exposition, data)
@ -462,14 +462,48 @@ class ExpositionDeleteForm(forms.ModelForm):
fields = ('url',) fields = ('url',)
class StatisticForm(forms.ModelForm): class StatisticForm(forms.Form):
year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'})) year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), label='Год')
visitors = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) visitors = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label='Посетители')
members = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) members = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label='Участники')
area = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) area = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label='Площадь')
class Meta: countries_number = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label='Число стран')
model = Statistic
exclude = ('exposition') def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
"""
super(StatisticForm, self).__init__(*args, **kwargs)
#creates translated forms example: name_ru, name_en
# len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs
if len(settings.LANGUAGES) in range(10):
for lid, (code, name) in enumerate(settings.LANGUAGES):
# uses enumerate for detect iteration number
# first iteration is a default lang so it required fields
required = True if lid == 0 else False
self.fields['countries_%s' % code] = forms.CharField(label=u'Участвующие страны',
required=False,
widget=forms.TextInput(attrs={'style':'width: 250px'}))
def save(self, exposition=None):
data = self.cleaned_data
if not exposition:
return None
else:
stat = Statistic()
# simple fields
stat.exposition = exposition
stat.year = data['year']
stat.visitors = data.get('visitors')
stat.members = data.get('members')
stat.area = data.get('area')
stat.countries_number = data.get('countries_number')
fill_with_signal(Statistic, stat, data)
return stat
def clean_year(self): def clean_year(self):
cleaned_data = super(StatisticForm, self).clean() cleaned_data = super(StatisticForm, self).clean()
@ -486,6 +520,11 @@ class StatisticForm(forms.ModelForm):
visitors = cleaned_data.get('visitors').strip() visitors = cleaned_data.get('visitors').strip()
return is_positive_integer(visitors) return is_positive_integer(visitors)
def clean_countries_number(self):
cleaned_data = super(StatisticForm, self).clean()
countries_number = cleaned_data.get('countries_number').strip()
return is_positive_integer(countries_number)
from functions.files import check_tmp_timetables from functions.files import check_tmp_timetables
class TimeTableForm(forms.Form): class TimeTableForm(forms.Form):

@ -0,0 +1,201 @@
# -*- coding: utf-8 -*-
import os
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand
from django.conf import settings
from exposition.models import Exposition
from conference.management.commands.conf_old import filter_city, filter_country, get_periodic, get_logo, get_places
from django.core.files import File
from functions.translate import fill_with_signal
from country.models import Country
from city.models import City
file_path = settings.MEDIA_ROOT + 'exposition/bad_expos.txt'
import datetime
from theme.models import Theme
from conference.models import Conference
'''
class Command(BaseCommand):
def handle(self, *args, **options):
db = MySQLdb.connect(host="localhost",
user="expomap",
passwd="7FbLtAGjse",
db="old_db",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
conf_old = """
SELECT DISTINCT (products_to_categories.products_id), url as old_url
FROM `products_to_categories`
LEFT JOIN `products` ON products_to_categories.products_id=products.products_id
LEFT JOIN `products_description` ON products_to_categories.products_id=products_description.products_id
WHERE `products_status` =1
AND `conference` =0
"""
find_themes = "SELECT categories_id FROM `products_to_categories` WHERE `products_id` =%d"
cursor.execute(conf_old)
conferences = cursor.fetchall()
#for item in conferences:
cursor.execute(find_themes%conferences[0]['products_id'])
day = datetime.date.today()
day = day.replace(month=1, day=1)
for item in conferences:
old_url = item['old_url']
if not old_url:
continue
try:
expo = Exposition.objects.get(old_url=old_url)
except:
continue
if expo.data_begin > day:
continue
cursor.execute(find_themes%item['products_id'])
themes_id = [i['categories_id'] for i in cursor.fetchall()]
theme_qs = Theme.objects.filter(id__in=themes_id)
expo.theme.add(*theme_qs)
print(expo)
# if item['categories_id'] == 0:
# continue
# Theme.objects.get(id=item['categories_id'])
#print(result)
'''
from haystack.query import SearchQuerySet
from django.db import IntegrityError
from django.utils import translation
class Command(BaseCommand):
def handle(self, *args, **options):
db = MySQLdb.connect(host="localhost",
user="expomap",
passwd="7FbLtAGjse",
db="old_db",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
sql = """
SELECT products.products_id as id, products_date_added as created, products_last_modified as modified,
discount, expohit, ufi, products_name as name, products_description as description,
products_short_description as main_title, products_viewed as viewed, products_period as period,
products_org as organiser,products_products as products, products_official as web_page,
products_img1 as logo, products_startdate as data_begin, products_enddate as data_end,
url as old_url, places_id
FROM `products`
LEFT JOIN `products_description` ON products.products_id=products_description.products_id
WHERE `products_status` =1
AND `conference` =0 AND places_id >0
ORDER BY products.products_id DESC
"""
translation.activate('ru')
expos = list(Exposition.objects.language().filter(old_url=''))
find_expo = "SELECT products_name, url from products_description WHERE products_name = '%s'"
for expo in expos:
cursor.execute(find_expo%expo.name)
result = cursor.fetchall()
if result:
expo.old_url = result[0]['url']
expo.save()
print(expo)
#cursor.execute(sql)
#result = cursor.fetchall()
#names = [item['name'] for item in result]
#media = settings.MEDIA_ROOT.replace('media/', '')
#counter = 0
#bad_cities = {}
bad_expos = []
'''
for i, item in enumerate(result):
qs = SearchQuerySet().models(Exposition).filter(name_ru=item['name'])
if not item:
continue
if not qs.count()>0:
continue
expo =qs[0].object
if not expo or expo.old_url:
continue
print(expo)
expo.old_url = item['old_url']
try:
expo.save()
except IntegrityError:
continue
"""
print('number: %d, errors: %d'%(i, len(bad_expos)))
name = item['name']
if Exposition.objects.filter(translations__name=name).exists():
msg = u'%s|||%s|||%s'%(name, item['old_url'], 'already exist')
bad_expos.append(msg)
continue
data_begin = item['data_begin']
data_end= item['data_end']
place_id = item['places_id'] # convert to country and city
country, city = get_places(place_id)
if not country or not city:
msg = u'%s|||%s|||%s'%(name, item['old_url'], 'bad country or city')
bad_expos.append(msg)
continue
old_url = item['old_url']
periodic = item['period']
periodic = get_periodic(periodic)
web_page = item['web_page']
currency = 'USD'
expohit = item['expohit']
ufi = item['ufi']
if ufi:
ufi = 1
else:
ufi = 0
created = item['created']
modified = item['modified']
data = {'name_ru': name, 'main_title_ru': item['main_title'], 'description_ru': item['description'],
'products_ru': item['products'], 'discount_description_ru': '', 'time_ru': '', 'price_day_ru':'',
'price_all_ru': '', 'price_day_bar_ru': '', 'price_all_bar_ru': '', 'stat_countries_ru': '',
'pre_condition_ru':'', 'stand_condition_ru': '', 'visit_note_ru': '', 'participation_note_ru': '',
'title_ru': '', 'descriptions_ru': '', 'keywords_ru': ''}
exposition = Exposition(data_begin=data_begin, data_end=data_end, city=city, country=country,
web_page=web_page, old_url=old_url, periodic=periodic, currency=currency,
expohit=expohit, created=created, modified=modified, quality_label=ufi)
try:
fill_with_signal(Exposition, exposition, data)
except Exception as e:
msg = u'%s|||%s|||%s'%(name, item['old_url'], str(e))
bad_expos.append(msg)
continue
"""
'''

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
import xlrd
from django.core.management.base import BaseCommand
from django.conf import settings
from functions.form_check import translit_with_separator
from exposition.models import Exposition
from organiser.models import Organiser
CHINA_FILE = settings.MEDIA_ROOT+'/import/expo_china_ru.xlsx'
GERMANY_FILE = settings.MEDIA_ROOT+'/import/expo_germany_ru.xlsx'
# 391 row not imported(same url)
ITALY_FILE = settings.MEDIA_ROOT+'/import/expo_italy_ru.xlsx'
# moscow 3 exps
F = settings.MEDIA_ROOT+'/import/exp.xlsx'
LA_FILE = settings.MEDIA_ROOT+'/import/expo_la.xlsx'
NA_EU_ASIA_FILE = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa.xls'
NA_EU_ASIA_FILE2 = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa_part2.xls'
RUSSIA_FILE = settings.MEDIA_ROOT+'/import/expo_russia.xls'
class Command(BaseCommand):
def handle(self, *args, **options):
f = open(RUSSIA_FILE, 'r')
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)]
labels = [label for label in row_list[0]]
for row_number, row in enumerate(row_list[1:]):
exp_url = translit_with_separator(row[2])
try:
exp = Exposition.objects.get(url=exp_url)
except Exposition.DoesNotExist:
continue
cell1 = row[11].split(';')
cell2 = row[12].split(';')
orgs = [item.strip() for item in cell1+cell2 if item]
exp.organiser.clear()
for org in orgs:
url = translit_with_separator(org)
try:
organiser = Organiser.objects.get(url=url)
except Organiser.DoesNotExist:
organiser = Organiser(url=url)
organiser.translate('ru')
organiser.name = org
organiser.save()
except Organiser.MultipleObjectsReturned:
continue
if not exp.organiser.filter(url=organiser.url).exists():
exp.organiser.add(organiser)
print(exp)

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
import xlrd
import urllib2
from django.core.management.base import BaseCommand
from django.conf import settings
from functions.form_check import translit_with_separator
from functions.files import get_alternative_filename
from exposition.models import Exposition, Statistic
from organiser.models import Organiser
CHINA_FILE = settings.MEDIA_ROOT+'/import/expo_china_ru.xlsx'
GERMANY_FILE = settings.MEDIA_ROOT+'/import/expo_germany_ru.xlsx'
# 391 row not imported(same url)
ITALY_FILE = settings.MEDIA_ROOT+'/import/expo_italy_ru.xlsx'
# moscow 3 exps
F = settings.MEDIA_ROOT+'/import/exp.xlsx'
LA_FILE = settings.MEDIA_ROOT+'/import/expo_la.xlsx'
NA_EU_ASIA_FILE = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa.xls'
NA_EU_ASIA_FILE2 = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa_part2.xls'
# 44
class Command(BaseCommand):
def handle(self, *args, **options):
qs = Statistic.objects.language('ru').exclude(translations__countries='')
comas = 0
enters = 0
main = 0
spaces = 0
word = 0
number = 0
for i in qs:
if ';' in i.countries:
main +=1
a = i.countries.split(';')
new = [item.strip() for item in a]
st = ';'.join(new)
#print st.encode('utf8')
i.countries = st
#i.save()
elif ',' in i.countries:
comas += 1
elif '\n' in i.countries:
enters += 1
elif ' ' in i.countries:
spaces += 1
print(i.countries.encode('utf8'))
if '55' in i.countries:
continue
elif '.' in i.countries:
number += 1
#print(i.countries)
#a = i.countries.split('.')
#i.countries_number = int(a[0])
#i.countries = ''
#i.save()
else:
word += 1
#print(i.countries.encode('utf8'))
print('all: %d'%qs.count())
print('main: %d'%main)
print('comas: %d'%comas)
print('enter: %d'%enters)
print('spaces: %d'%spaces)
print('word: %d'%word)
print('number: %d'%number)

@ -4,6 +4,8 @@ from django.core.management.base import BaseCommand
from django.conf import settings from django.conf import settings
from exposition.models import Exposition from exposition.models import Exposition
from import_xls.excel_settings import event_sett from import_xls.excel_settings import event_sett
from django.db import IntegrityError
from django.utils import translation
CHINA_FILE = settings.MEDIA_ROOT+'/import/expo_china_ru.xlsx' CHINA_FILE = settings.MEDIA_ROOT+'/import/expo_china_ru.xlsx'
GERMANY_FILE = settings.MEDIA_ROOT+'/import/expo_germany_ru.xlsx' GERMANY_FILE = settings.MEDIA_ROOT+'/import/expo_germany_ru.xlsx'
@ -14,35 +16,57 @@ F = settings.MEDIA_ROOT+'/import/exp.xlsx'
LA_FILE = settings.MEDIA_ROOT+'/import/expo_la.xlsx' LA_FILE = settings.MEDIA_ROOT+'/import/expo_la.xlsx'
NA_EU_ASIA_FILE = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa.xls' NA_EU_ASIA_FILE = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa.xls'
NA_EU_ASIA_FILE2 = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa_part2.xls'
RUSSIA_FILE = settings.MEDIA_ROOT+'/import/expo_russia.xls'
GEORGIA_FILE = settings.MEDIA_ROOT+'/import/georgia.xls'
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
f = open(NA_EU_ASIA_FILE, 'r')
f = open(GEORGIA_FILE, 'r')
book = xlrd.open_workbook(file_contents=f.read()) book = xlrd.open_workbook(file_contents=f.read())
sheet = book.sheet_by_index(0) sheet = book.sheet_by_index(0)
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
labels = [label for label in row_list[0]] labels = [label for label in row_list[0]]
existing = 0
for row_number, row in enumerate(row_list[1:]): for row_number, row in enumerate(row_list[1:]):
print(row_number) #print(row_number)
name = row[2]
if row[0] != '': if row[0] != '':
# in first column ids # in first column ids
try: try:
object = Exposition.objects.language('ru').get(id=int(row[0])) object = Exposition.objects.language('ru').get(id=int(row[0]))
existing += 1
except ValueError: except ValueError:
object = Exposition() object = Exposition()
object.translate('ru') object.translate('ru')
except Exposition.DoesNotExist: except Exposition.DoesNotExist:
object = Exposition(id= int(row[0])) object = Exposition(id= int(row[0]))
object.translate('ru') object.translate('ru')
existing += 1
else: else:
# if id blank - its a new place # if id blank - its a new place
object = Exposition() object = Exposition()
object.translate('ru') object.translate('ru')
"""
try:
object = Exposition.objects.language('ru').filter(translations__name=name)[0]
existing += 1
except IndexError:
pass
"""
methods = [] methods = []
for col_number, cell in enumerate(row): for col_number, cell in enumerate(row):
label = labels[col_number] label = labels[col_number]
@ -76,11 +100,16 @@ class Command(BaseCommand):
pass pass
else: else:
setattr(object, field_name, value) setattr(object, field_name, value)
#object.save()
try:
object.save()
except IntegrityError:
continue
print('post save %s'% str(object)) print('post save %s'% str(object))
"""
for method in methods: for method in methods:
func = method['func'] func = method['func']
if method.get('purpose'): if method.get('purpose'):
@ -90,4 +119,5 @@ class Command(BaseCommand):
continue continue
else: else:
func(object, method['value']) func(object, method['value'])
"""
print(existing)

@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
import xlrd
import urllib2
from django.core.management.base import BaseCommand
from django.conf import settings
from functions.form_check import translit_with_separator
from functions.files import get_alternative_filename
from exposition.models import Exposition
from organiser.models import Organiser
CHINA_FILE = settings.MEDIA_ROOT+'/import/expo_china_ru.xlsx'
GERMANY_FILE = settings.MEDIA_ROOT+'/import/expo_germany_ru.xlsx'
# 391 row not imported(same url)
ITALY_FILE = settings.MEDIA_ROOT+'/import/expo_italy_ru.xlsx'
# moscow 3 exps
F = settings.MEDIA_ROOT+'/import/exp.xlsx'
LA_FILE = settings.MEDIA_ROOT+'/import/expo_la.xlsx'
NA_EU_ASIA_FILE = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa.xls'
NA_EU_ASIA_FILE2 = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa_part2.xls'
class Command(BaseCommand):
def handle(self, *args, **options):
f = open(CHINA_FILE, 'r')
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)]
labels = [label for label in row_list[0]]
for row_number, row in enumerate(row_list[1:]):
exp_url = translit_with_separator(row[2])
try:
exp = Exposition.objects.get(url=exp_url)
except Exposition.DoesNotExist:
continue
if exp.logo or row[19] == '':# or row[16].startswith('http') or row[16].startswith('https') or not row[16].startswith('/') or row[16].startswith('../'):
continue
path = row[19]
file_name = path.split('/')[-1]
logo_path = exp.logo.field.upload_to
full_path = settings.MEDIA_ROOT + logo_path
try:
alt_name = get_alternative_filename(full_path, file_name)
except UnicodeEncodeError:
continue
download_to = full_path+alt_name
if path.startswith('http') or path.startswith('https'):
url = path
elif path.startswith('/'):
url = 'http://expomap.ru' + path
elif path.startswith('images'):
url = 'http://expomap.ru/' + path
else:
continue
#print('------------------------------------')
#print(path)
#print(url)
#print('------------------------------------')
try:
response = urllib2.urlopen(url, timeout=15)
except:
continue
if response.code != 200:
continue
with open(download_to,'wb') as f:
try:
f.write(response.read())
f.close()
except:
# can be timeout
continue
exp.logo = logo_path + alt_name
try:
exp.save()
print(exp)
except:
print('logo exception. logo: %s'%exp.logo)
continue

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
import xlrd
import urllib2
from django.core.management.base import BaseCommand
from django.conf import settings
from functions.form_check import translit_with_separator
from functions.files import get_alternative_filename
from exposition.models import Exposition, Statistic
from organiser.models import Organiser
CHINA_FILE = settings.MEDIA_ROOT+'/import/expo_china_ru.xlsx'
GERMANY_FILE = settings.MEDIA_ROOT+'/import/expo_germany_ru.xlsx'
# 391 row not imported(same url)
ITALY_FILE = settings.MEDIA_ROOT+'/import/expo_italy_ru.xlsx'
# moscow 3 exps
F = settings.MEDIA_ROOT+'/import/exp.xlsx'
LA_FILE = settings.MEDIA_ROOT+'/import/expo_la.xlsx'
NA_EU_ASIA_FILE = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa.xls'
NA_EU_ASIA_FILE2 = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa_part2.xls'
RUSSIA_FILE = settings.MEDIA_ROOT+'/import/expo_russia.xls'
class Command(BaseCommand):
def handle(self, *args, **options):
f = open(RUSSIA_FILE, 'r')
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)]
labels = [label for label in row_list[0]]
for row_number, row in enumerate(row_list[1:]):
exp_url = translit_with_separator(row[2])
try:
exp = Exposition.objects.language('ru').get(url=exp_url)
except Exposition.DoesNotExist:
continue
if not row[30]:
continue
year = int(row[30])
try:
countries_number = int(exp.stat_countries)
countries = ''
except ValueError:
countries_number = None
countries = exp.stat_countries
members = exp.members
visitors = exp.visitors
area = exp.area
s = Statistic(exposition=exp,
year=year,
countries_number=countries_number,
members=members,
visitors=visitors,
area=area)
s.translate('ru')
s.countries = countries
s.save()
print(exp)

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand
from meta.models import MetaSetting
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()

@ -5,9 +5,10 @@ from hvad.models import TranslationManager
class ClientManager(TranslationManager): class ClientManager(TranslationManager):
def get_query_set(self): def get_query_set(self):
now = datetime.datetime.now().date() return self.language().select_related('country', 'city', 'place').filter(is_published=True).order_by('data_begin')
return super(ClientManager, self).get_query_set().filter(is_published=True, data_begin__gte=now).order_by('data_begin')
def upcoming(self):
return self.filter(data_begin__gte=datetime.datetime.now().date())
""" """

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import copy, datetime import copy, datetime
from django.db import models from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save, pre_save from django.db.models.signals import post_save, pre_save
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils import translation from django.utils import translation
@ -19,6 +20,8 @@ from functions.model_mixin import EventMixin, ExpoMixin
from functions.translate import fill_with_signal from functions.translate import fill_with_signal
from photologue.models import Gallery from photologue.models import Gallery
from import_xls.model_utils import ExpoImportManager from import_xls.model_utils import ExpoImportManager
from functions.models_methods import hvad_to_dict
AUDIENCE1 = ((None,_(u'Не выбрано')), AUDIENCE1 = ((None,_(u'Не выбрано')),
('experts', _(u'Специалисты')), ('experts', _(u'Специалисты')),
@ -28,14 +31,13 @@ AUDIENCE1 = ((None,_(u'Не выбрано')),
AUDIENCE = (None,'experts', 'experts and consumers', 'general public') AUDIENCE = (None,'experts', 'experts and consumers', 'general public')
BIT_AUDIENCE = (('experts', _(u'Специалисты')), ('experts and consumers', _(u'Специалисты и потребители')), BIT_AUDIENCE = settings.BIT_AUDIENCE
('general public', _(u'Широкая публика')))
CURRENCY = ('RUB', 'USD', 'EUR', 'RMB', 'GBP') CURRENCY = settings.CURRENCY
# check if table exist and create flags if true # check if table exist and create flags if true
flags = [str(item.id) for item in Service.objects.all()] if db_table_exists('service_service') else [] flags = [item.url for item in Service.objects.all()] if db_table_exists('service_service') else []
class Exposition(TranslatableModel, EventMixin, ExpoMixin): class Exposition(TranslatableModel, EventMixin, ExpoMixin):
@ -52,6 +54,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
event_type = 'expo' event_type = 'expo'
url = models.SlugField(unique=True, max_length=255) url = models.SlugField(unique=True, max_length=255)
old_url = models.SlugField(unique=True, max_length=255)
data_begin = models.DateField(verbose_name='Дата начала') data_begin = models.DateField(verbose_name='Дата начала')
data_end = models.DateField(verbose_name='Дата окончания') data_end = models.DateField(verbose_name='Дата окончания')
services = BitField(flags=flags) services = BitField(flags=flags)
@ -161,8 +164,19 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk)) return self.lazy_translation_getter('name', unicode(self.pk))
def get_services(self):
country_ids = [item for item, bool in self.country.services if bool==True]
ids = [item for item, bool in self.services if bool==True]
qs = Service.objects.language().filter(Q(Q(url__in=country_ids) & Q(type=Service.type.expo)) | Q(url__in=ids))
return list(qs)
def get_parent(self): def get_parent(self):
return {} return {}
def get_absolute_url(self):
return self.get_permanent_url()
def get_index_text(self): def get_index_text(self):
translation.activate('ru') translation.activate('ru')
@ -231,7 +245,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
for k, v in BIT_AUDIENCE: for k, v in BIT_AUDIENCE:
for item in checked: for item in checked:
if item == k: if item == k:
audience.append(v) audience.append(unicode(v))
return ', '.join(audience) return ', '.join(audience)
@ -246,7 +260,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
if self.theme.all(): if self.theme.all():
theme = self.theme.all()[0] theme = self.theme.all()[0]
now = datetime.datetime.now() now = datetime.datetime.now()
now = now.replace(day=now.day-1) now = now - datetime.timedelta(days=1)
expositions = Exposition.objects.filter(theme__in=[theme], data_begin__gt=now).exclude(id=self.id).order_by('data_begin') expositions = Exposition.objects.filter(theme__in=[theme], data_begin__gt=now).exclude(id=self.id).order_by('data_begin')
return expositions[:3] return expositions[:3]
else: else:
@ -284,58 +298,22 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
return code return code
return cur return cur
def clone(self):
"""
Return an identical copy of the instance with a new ID.
"""
if not self.pk:
raise ValueError('Instance must be saved before it can be cloned.')
duplicate = copy.copy(self)
# Setting pk to None. Django thinking this is a new object.
duplicate.pk = None
# url must be unique
duplicate.url += '_copy'
if Exposition.objects.safe_get(url=duplicate.url):
#already has copy this instance
return
# duplicate should not be published
duplicate.is_published = False
duplicate.cancel_by_administrator = False
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.save()
# but lost all ManyToMany relations and Translations.
# 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
class Statistic(models.Model): class Statistic(TranslatableModel):
exposition = models.ForeignKey(Exposition, related_name='statistic') exposition = models.ForeignKey(Exposition, related_name='statistic')
year = models.PositiveIntegerField(verbose_name='Год') year = models.PositiveIntegerField(verbose_name='Год')
members = models.PositiveIntegerField(verbose_name='Посетители') members = models.PositiveIntegerField(verbose_name='Посетители', blank=True, null=True)
visitors = models.PositiveIntegerField(verbose_name='Участники') visitors = models.PositiveIntegerField(verbose_name='Участники', blank=True, null=True)
area = models.PositiveIntegerField(verbose_name='Площадь') area = models.PositiveIntegerField(verbose_name='Площадь', blank=True, null=True)
countries_number = models.PositiveIntegerField(verbose_name='Количество стран', blank=True, null=True)
translations = TranslatedFields(
countries = models.TextField(blank=True)
)
def to_dict(self):
return hvad_to_dict(self)
from django.core import serializers
from functions.models_methods import hvad_to_dict
class TimeTable(TranslatableModel): class TimeTable(TranslatableModel):
""" """
@ -379,34 +357,10 @@ class TmpTimeTable(TranslatableModel):
place = models.CharField(verbose_name='Место проведения', max_length=255, blank=True) place = models.CharField(verbose_name='Место проведения', max_length=255, blank=True)
) )
def clone(self, exposition=None):
"""
Return an identical copy of the instance with a new ID.
"""
if not self.pk:
raise ValueError('Instance must be saved before it can be cloned.')
duplicate = copy.copy(self)
# Setting pk to None. Django thinking this is a new object.
duplicate.pk = None
duplicate.exposition = exposition
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.save()
return duplicate
pre_save.connect(pre_save_handler, sender=Exposition) pre_save.connect(pre_save_handler, sender=Exposition)
post_save.connect(post_save_handler, sender=Exposition) post_save.connect(post_save_handler, sender=Exposition)
post_save.connect(post_save_handler, sender=TimeTable) post_save.connect(post_save_handler, sender=TimeTable)
post_save.connect(post_save_handler, sender=TmpTimeTable) post_save.connect(post_save_handler, sender=TmpTimeTable)
post_save.connect(post_save_handler, sender=Statistic)

@ -48,4 +48,7 @@ class ExpositionIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
elif lang=='en': elif lang=='en':
return self.name_en return self.name_en
else: else:
return self.name_ru return self.name_ru
def get_updated_field(self):
return 'modified'

@ -4,82 +4,80 @@ from views import ExpositionStatistic, ExpositionPrice,\
ExpositionProgramme, ExpositionSearchView, ExpositionByCountry, ExpositionByTheme, ExpositionByCity ExpositionProgramme, ExpositionSearchView, ExpositionByCountry, ExpositionByTheme, ExpositionByCity
from django.http import HttpResponse from django.views.decorators.cache import cache_page
from views import ExpositionServiceView from views import ExpositionServiceView
from views import ExpoCountryCatalog, ExpoCityCatalog, ExpoThemeCatalog, ExpoTagCatalog, ExpoList, ExpoDetail,\ from views import ExpoCountryCatalog, ExpoCityCatalog, ExpoThemeCatalog, ExpoTagCatalog, ExpoList, ExpoDetail,\
ExpoVisitors, ExpoMembers ExpoVisitors, ExpoMembers
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'expo/add-note/(?P<slug>.*)/$', 'exposition.views.add_note'), url(r'^expo/add-note/(?P<slug>.*)/$', 'exposition.views.add_note'),
url(r'exposition-add-calendar/(?P<id>\d+)/$', 'exposition.views.exposition_add_calendar'), url(r'^exposition-add-calendar/(?P<id>\d+)/$', 'exposition.views.exposition_add_calendar'),
url(r'exposition-visit/(?P<id>\d+)/$', 'exposition.views.exposition_visit'), url(r'^exposition-visit/(?P<id>\d+)/$', 'exposition.views.exposition_visit'),
# search # search
url(r'expo/search/', ExpositionSearchView.as_view()), url(r'^expo/search/', ExpositionSearchView.as_view()),
# country catalog # country catalog
url(r'expo/country/$', ExpositionByCountry.as_view()), url(r'^expo/country/$', ExpositionByCountry.as_view(), {'meta_id':54}),
url(r'expo/country/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view()), url(r'^expo/country/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view(), {'meta_id':7}),
url(r'expo/country/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view()), url(r'^expo/country/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view(), {'meta_id':6}),
url(r'expo/country/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view()), url(r'^expo/country/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view(), {'meta_id':5}),
url(r'expo/country/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoCountryCatalog.as_view()), url(r'^expo/country/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoCountryCatalog.as_view(), {'meta_id':7}),
url(r'expo/country/(?P<slug>.*)/(?P<year>\d+)/$', ExpoCountryCatalog.as_view()), url(r'^expo/country/(?P<slug>.*)/(?P<year>\d+)/$', ExpoCountryCatalog.as_view(), {'meta_id':6}),
url(r'expo/country/(?P<slug>.*)/$', ExpoCountryCatalog.as_view()), url(r'^expo/country/(?P<slug>.*)/$', ExpoCountryCatalog.as_view(), {'meta_id':5}),
# city catalog # city catalog
url(r'expo/city/$', ExpositionByCity.as_view()), url(r'^expo/city/$', ExpositionByCity.as_view(), {'meta_id':53}),
url(r'expo/city/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view()), url(r'^expo/city/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view(), {'meta_id':10}),
url(r'expo/city/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view()), url(r'^expo/city/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view(), {'meta_id':9}),
url(r'expo/city/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view()), url(r'^expo/city/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view(), {'meta_id':8}),
url(r'expo/city/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoCityCatalog.as_view()), url(r'^expo/city/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoCityCatalog.as_view(), {'meta_id':10}),
url(r'expo/city/(?P<slug>.*)/(?P<year>\d+)/$', ExpoCityCatalog.as_view()), url(r'^expo/city/(?P<slug>.*)/(?P<year>\d+)/$', ExpoCityCatalog.as_view(), {'meta_id':9}),
url(r'expo/city/(?P<slug>.*)/$', ExpoCityCatalog.as_view()), url(r'^expo/city/(?P<slug>.*)/$', ExpoCityCatalog.as_view(), {'meta_id':8}),
# theme catalog # theme catalog
url(r'expo/theme/$', ExpositionByTheme.as_view()), url(r'^expo/theme/$', ExpositionByTheme.as_view(), {'meta_id':55}),
url(r'expo/theme/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view()), url(r'^expo/theme/(?P<slug>.*)/country/(?P<country_slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':44}),
url(r'expo/theme/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view()), url(r'^expo/theme/(?P<slug>.*)/country/(?P<country_slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoThemeCatalog.as_view(), {'meta_id':44}),
url(r'expo/theme/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view()), url(r'^expo/theme/(?P<slug>.*)/country/(?P<country_slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':44}),
url(r'expo/theme/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoThemeCatalog.as_view()), url(r'^expo/theme/(?P<slug>.*)/country/(?P<country_slug>.*)/(?P<year>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':44}),
url(r'expo/theme/(?P<slug>.*)/(?P<year>\d+)/$', ExpoThemeCatalog.as_view()), url(r'^expo/theme/(?P<slug>.*)/country/(?P<country_slug>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':44}),
url(r'expo/theme/(?P<slug>.*)/$', ExpoThemeCatalog.as_view()), url(r'^expo/theme/(?P<slug>.*)/country/(?P<country_slug>.*)/$', ExpoThemeCatalog.as_view(), {'meta_id':44}),
url(r'^expo/theme/(?P<slug>.*)/city/(?P<city_slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':42}),
url(r'^expo/theme/(?P<slug>.*)/city/(?P<city_slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoThemeCatalog.as_view(), {'meta_id':42}),
url(r'^expo/theme/(?P<slug>.*)/city/(?P<city_slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':42}),
url(r'^expo/theme/(?P<slug>.*)/city/(?P<city_slug>.*)/(?P<year>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':42}),
url(r'^expo/theme/(?P<slug>.*)/city/(?P<city_slug>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':42}),
url(r'^expo/theme/(?P<slug>.*)/city/(?P<city_slug>.*)/$', ExpoThemeCatalog.as_view(), {'meta_id':42}),
url(r'^expo/theme/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':13}),
url(r'^expo/theme/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':12}),
url(r'^expo/theme/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':11}),
url(r'^expo/theme/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoThemeCatalog.as_view(), {'meta_id':13}),
url(r'^expo/theme/(?P<slug>.*)/(?P<year>\d+)/$', ExpoThemeCatalog.as_view(), {'meta_id':12}),
url(r'^expo/theme/(?P<slug>.*)/$', ExpoThemeCatalog.as_view(), {'meta_id':11}),
# tag catalog # tag catalog
url(r'expo/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view()), url(r'^expo/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view(), {'meta_id':17}),
url(r'expo/tag/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view()), url(r'^expo/tag/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view(), {'meta_id':15}),
url(r'expo/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view()), url(r'^expo/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view(), {'meta_id':14}),
url(r'expo/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoTagCatalog.as_view()), url(r'^expo/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoTagCatalog.as_view(), {'meta_id':17}),
url(r'expo/tag/(?P<slug>.*)/(?P<year>\d+)/$', ExpoTagCatalog.as_view()), url(r'^expo/tag/(?P<slug>.*)/(?P<year>\d+)/$', ExpoTagCatalog.as_view(), {'meta_id':15}),
url(r'expo/tag/(?P<slug>.*)/$', ExpoTagCatalog.as_view()), url(r'^expo/tag/(?P<slug>.*)/$', ExpoTagCatalog.as_view(), {'meta_id':14}),
# expo additional pages # expo additional pages
url(r'expo/(?P<slug>.*)/statistic/$', ExpositionStatistic.as_view()), url(r'^expo/(?P<slug>.*)/statistic/$', ExpositionStatistic.as_view(), {'meta_id':60}),
url(r'expo/(?P<slug>.*)/price/$', ExpositionPrice.as_view()), url(r'^expo/(?P<slug>.*)/price/$', ExpositionPrice.as_view(), {'meta_id':61}),
url(r'expo/(?P<slug>.*)/program/$', ExpositionProgramme.as_view()), url(r'^expo/(?P<slug>.*)/program/$', ExpositionProgramme.as_view(), {'meta_id':62}),
url(r'expo/(?P<slug>.*)/visitors/page/(?P<page>\d+)/$', ExpoVisitors.as_view()), url(r'^expo/(?P<slug>.*)/visitors/page/(?P<page>\d+)/$', ExpoVisitors.as_view(), {'meta_id':64}),
url(r'expo/(?P<slug>.*)/visitors/$', ExpoVisitors.as_view()), url(r'^expo/(?P<slug>.*)/visitors/$', ExpoVisitors.as_view(), {'meta_id':64}),
url(r'expo/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ExpoMembers.as_view()), 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()), url(r'^expo/(?P<slug>.*)/members/$', ExpoMembers.as_view(), {'meta_id':63}),
url(r'expo/(?P<slug>.*)/service/(?P<service_url>.*)/', ExpositionServiceView.as_view()), url(r'^expo/(?P<slug>.*)/service/(?P<service_url>.*)/', ExpositionServiceView.as_view()),
# expo list # expo list
url(r'expo/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoList.as_view()), url(r'^expo/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':4}),
url(r'expo/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoList.as_view()), url(r'^expo/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':3}),
url(r'expo/(?P<year>\d+)/(?P<month>.*)/$', ExpoList.as_view()), url(r'^expo/(?P<year>\d+)/(?P<month>.*)/$', ExpoList.as_view(), {'meta_id':4}),
url(r'expo/(?P<year>\d+)/$', ExpoList.as_view()), url(r'^expo/(?P<year>\d+)/$', ExpoList.as_view(), {'meta_id':3}),
url(r'expo/page/(?P<page>\d+)/$', ExpoList.as_view()), url(r'^expo/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':2}),
# expo page # expo page
url(r'expo/(?P<slug>.*)/$', ExpoDetail.as_view()),# event url(r'^expo/(?P<slug>.*)/$', ExpoDetail.as_view(), {'meta_id':18}),# event
url(r'expo/$', ExpoList.as_view()), url(r'^expo/$', ExpoList.as_view() , {'meta_id':2}),
#url(r'expo/(?P<slug>.*)/service/(?P<url>.*)/$', ExpositionServiceView.as_view()),
#url(r'expo/(?P<params>.*)/service/(?P<url>.*)/$', ExpositionServiceView.as_view()),
#url(r'expo/(?P<params>.*)/statistic/$', ExpositionStatistic.as_view()),
) )

@ -7,7 +7,7 @@ from django.contrib.contenttypes.models import ContentType
from django.conf import settings from django.conf import settings
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404, render_to_response
from django.http import Http404 from django.http import Http404
from django.utils import translation from django.utils import translation
#models #models
@ -19,18 +19,19 @@ from country.models import Country
from city.models import City from city.models import City
from theme.models import Theme, Tag from theme.models import Theme, Tag
from note.models import Note from note.models import Note
from functions.custom_views import ExpoSearchView from service.order_forms import AdvertiseForm
from functions.search_forms import ExpositionSearchForm from functions.search_forms import ExpositionSearchForm
from functions.custom_views import ExpoSearchView from functions.custom_views import ExpoSearchView
from meta.views import MetadataMixin
from functions.cache_mixin import JitterCacheMixin, CacheMixin
class ExpositionBy(ListView): class ExpositionBy(JitterCacheMixin, MetadataMixin, ListView):
template_name = 'exposition/exposition_by.html' template_name = 'exposition/exposition_by.html'
title1 = '' title1 = ''
title2 = '' title2 = ''
""" """
abstact class abstact class
""" """
@ -42,47 +43,54 @@ class ExpositionBy(ListView):
class ExpositionByCountry(ExpositionBy): class ExpositionByCountry(ExpositionBy):
cache_range = settings.CACHE_RANGE
model = Country model = Country
title1 = _(u'По странам') title1 = _(u'По странам')
title2 = _(u'Выставки мира по странам') title2 = _(u'Выставки мира по странам')
catalog = 'country/' catalog = 'country/'
def get_queryset(self): def get_queryset(self):
lang = translation.get_language() return self.model.objects.expo_countries_with_count()
return self.model.objects.select_related('exposition_country')\ #lang = translation.get_language()
.filter(exposition_country__country__isnull=False, translations__language_code=lang)\ #return self.model.objects.select_related('exposition_country')\
.order_by('translations__name').distinct() # .filter(exposition_country__country__isnull=False, translations__language_code=lang)\
# .order_by('translations__name').distinct()
class ExpositionByTheme(ExpositionBy): class ExpositionByTheme(ExpositionBy):
cache_range = settings.CACHE_RANGE
model = Theme model = Theme
title1 = _(u'По тематикам') title1 = _(u'По тематикам')
title2 = _(u'Выставки мира по тематикам') title2 = _(u'Выставки мира по тематикам')
catalog = 'theme/' catalog = 'theme/'
def get_queryset(self): def get_queryset(self):
lang = translation.get_language() return self.model.active.expo_themes_with_count()
return self.model.objects.select_related('exposition_themes')\ #lang = translation.get_language()
.filter(exposition_themes__theme__isnull=False, translations__language_code=lang)\ #return self.model.objects.select_related('exposition_themes')\
.order_by('translations__name').distinct() # .filter(exposition_themes__theme__isnull=False, translations__language_code=lang)\
# .order_by('translations__name').distinct()
class ExpositionByCity(ExpositionBy): class ExpositionByCity(ExpositionBy):
cache_range = settings.CACHE_RANGE
model = City model = City
title1 = _(u'По городам') title1 = _(u'По городам')
title2 = _(u'Выставки мира по городам') title2 = _(u'Выставки мира по городам')
catalog = 'city/' catalog = 'city/'
def get_queryset(self): def get_queryset(self):
lang = translation.get_language() return self.model.used.expo_cities_with_count()
return self.model.objects.select_related('exposition_city')\ #return self.model.used.expo_cities()
.filter(exposition_city__city__isnull=False, translations__language_code=lang)\ #lang = translation.get_language()
.order_by('translations__name').distinct() #return self.model.objects.select_related('exposition_city')\
# .filter(exposition_city__city__isnull=False, translations__language_code=lang)\
# .order_by('translations__name').distinct()
class ExpositionSearchView(ExpoSearchView): class ExpositionSearchView(ExpoSearchView):
#paginate_by = 10 #paginate_by = 10
template_name = 'exposition/search.html' template_name = 'client/exposition/search.html'
search_form = ExpositionSearchForm search_form = ExpositionSearchForm
model = Exposition model = Exposition
@ -119,12 +127,6 @@ def exposition_visit(request, id):
args['in'] = True args['in'] = True
args['success'] = True args['success'] = True
"""
if exp:
exp.users.add(user)
args['success'] = True
"""
else: else:
args['not_authorized'] = True args['not_authorized'] = True
args['success'] = True args['success'] = True
@ -133,34 +135,48 @@ def exposition_visit(request, id):
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
class ExpoDetail(DetailView): class ExpoDetail(JitterCacheMixin, MetadataMixin, DetailView):
cache_range = settings.CACHE_RANGE
model = Exposition model = Exposition
slug_field = 'url' slug_field = 'url'
template_name = 'client/exposition/exposition_detail.html' template_name = 'client/exposition/exposition_detail.html'
class ExpositionProgramme(DetailView): def get_context_data(self, **kwargs):
context = super(ExpoDetail, self).get_context_data(**kwargs)
context['advertising_form'] = AdvertiseForm()
return context
class ExpositionProgramme(MetadataMixin, DetailView):
model = Exposition model = Exposition
slug_field = 'url' slug_field = 'url'
template_name = 'client/exposition/programm.html' template_name = 'client/exposition/programm.html'
class ExpositionPrice(DetailView): class ExpositionPrice(MetadataMixin, DetailView):
model = Exposition model = Exposition
slug_field = 'url' slug_field = 'url'
template_name = 'client/exposition/price.html' template_name = 'client/exposition/price.html'
class ExpositionStatistic(DetailView): class ExpositionStatistic(MetadataMixin, DetailView):
model = Exposition model = Exposition
slug_field = 'url' slug_field = 'url'
template_name = 'client/exposition/statistic.html' template_name = 'client/exposition/statistic.html'
from django.views.generic.edit import FormMixin, ModelFormMixin from django.views.generic.edit import FormMixin, ModelFormMixin
class ExpositionServiceView(FormMixin, DetailView): class ExpositionServiceView(MetadataMixin, FormMixin, DetailView):
model = Exposition model = Exposition
slug_field = 'url' slug_field = 'url'
service = None service = None
success_url = '/service/thanks/'
def dispatch(self, request, *args, **kwargs):
service_url = self.kwargs.get('service_url')
service = get_object_or_404(Service, url=service_url)
self.service = service
self.template_name = service.template
return super(ExpositionServiceView, self).dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
@ -176,17 +192,16 @@ class ExpositionServiceView(FormMixin, DetailView):
return self.form_invalid(form) return self.form_invalid(form)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
kwargs.update({'meta_id': getattr(self.service, 'meta_id','')})
context = super(ExpositionServiceView, self).get_context_data(**kwargs) context = super(ExpositionServiceView, self).get_context_data(**kwargs)
service_url = self.kwargs.get('service_url') service_url = self.kwargs.get('service_url')
service = get_object_or_404(Service, url=service_url)
self.service = service
self.template_name = service.template
form = order_forms.get(service_url) form = order_forms.get(service_url)
self.form_class = form self.form_class = form
if not form: if not form:
raise Http404 raise Http404
context['form'] = self.get_form(self.form_class) context['form'] = self.get_form(self.form_class)
context['service'] = service context['service'] = self.service
context['object'] = self.get_object() context['object'] = self.get_object()
return context return context
@ -195,7 +210,7 @@ class ExpositionServiceView(FormMixin, DetailView):
order.exposition = self.object order.exposition = self.object
order.save() order.save()
messages.success(self.request, _(u'Ваш запрос был успешно отправлен')) messages.success(self.request, _(u'Ваш запрос был успешно отправлен'))
return HttpResponseRedirect(self.request.path) return HttpResponseRedirect(self.success_url)
def get_initial(self): def get_initial(self):
""" """
@ -217,7 +232,8 @@ class ExpositionServiceView(FormMixin, DetailView):
return self.initial.copy() return self.initial.copy()
class ExpoList(ListView): class ExpoList(MetadataMixin, JitterCacheMixin, ListView):
cache_range = settings.CACHE_RANGE
model = Exposition model = Exposition
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/exposition/exposition_list.html' template_name = 'client/exposition/exposition_list.html'
@ -228,15 +244,12 @@ class ExpoList(ListView):
def get_queryset(self): def get_queryset(self):
if self.request.user.is_staff: if self.request.user.is_staff:
now = datetime.datetime.now().date() qs = self.model.objects.upcoming()
qs = self.model.objects.filter(data_begin__gte=now).order_by('data_begin')
else: else:
qs = self.model.enable.all() qs = self.model.enable.upcoming()
year = self.kwargs.get('year') year = self.kwargs.get('year')
if year: if year:
qs = qs.filter(data_begin__year=year) qs = self.model.enable.filter(data_end__year=year)
# info for breadscrumbs # info for breadscrumbs
self.year = {'text': year, 'link': '%s%s/'%(self.catalog_url, year)} self.year = {'text': year, 'link': '%s%s/'%(self.catalog_url, year)}
@ -255,14 +268,9 @@ class ExpoList(ListView):
context['month'] = self.month context['month'] = self.month
return context return context
MONTHES = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')}, MONTHES = settings.MONTHES
'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')},
'may': {'value': 5, 'name': _(u'Май')}, 'jun': {'value': 6, 'name': _(u'Июнь')},
'jul': {'value': 7, 'name': _(u'Июль')}, 'aug': {'value': 8, 'name': _(u'Август')},
'sep': {'value': 9, 'name': _(u'Сентябрь')}, 'oct': {'value': 10, 'name': _(u'Октябрь')},
'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}}
class ExpoCatalog(ListView): class ExpoCatalog(MetadataMixin, ListView):
model = Exposition model = Exposition
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
template_name = 'exposition/catalog.html' template_name = 'exposition/catalog.html'
@ -270,6 +278,8 @@ class ExpoCatalog(ListView):
filter_object = None filter_object = None
year = None year = None
month = None month = None
country = None
city = None
def get_filtered_qs(self): def get_filtered_qs(self):
# diferent for views # diferent for views
@ -280,11 +290,24 @@ class ExpoCatalog(ListView):
year = self.kwargs.get('year') year = self.kwargs.get('year')
if year: if year:
qs = qs.filter(data_begin__year=year) qs = self.model.enable.filter(data_end__year=year)
filter_object = self.filter_object
if isinstance(filter_object, Country):
qs = qs.filter(country=filter_object)
elif isinstance(filter_object, City):
qs = qs.filter(city=filter_object)
elif isinstance(filter_object, Theme):
qs = qs.filter(theme=filter_object)
if self.kwargs.get('country'):
qs = qs.filter(country=self.kwargs.get('country'))
if self.kwargs.get('city'):
qs = qs.filter(city=self.kwargs.get('city'))
elif isinstance(filter_object, Tag):
qs = qs.filter(tag=filter_object)
# info for breadscrumbs # info for breadscrumbs
self.year = {'text': year, 'link': '%s%s/%s/'%(self.catalog_url, self.filter_object.url, year)} self.year = {'text': year, 'link': '%s%s/%s/'%(self.catalog_url, self.filter_object.url, year)}
month = self.kwargs.get('month') month = self.kwargs.get('month')
monthes = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')}, monthes = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')},
'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')}, 'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')},
@ -294,7 +317,14 @@ class ExpoCatalog(ListView):
'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}} 'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}}
if month and monthes.get(month): if month and monthes.get(month):
qs = qs.filter(data_begin__month=monthes[month]['value']) qs = qs.filter(data_begin__month=monthes[month]['value'])
self.month = {'text': monthes[month]['name'], 'link': '%s%s/%s/%s/'%(self.catalog_url, self.filter_object.url, year, month)} if self.country:
self.month = {'text': monthes[month]['name'], 'link': '%s%s/country/%s/%s/%s/'%
(self.catalog_url, self.filter_object.url, self.country.url, year, month)}
elif self.city:
self.month = {'text': monthes[month]['name'], 'link': '%s%s/city/%s/%s/%s/'%
(self.catalog_url, self.filter_object.url, self.city.url, year, month)}
else:
self.month = {'text': monthes[month]['name'], 'link': '%s%s/%s/%s/'%(self.catalog_url, self.filter_object.url, year, month)}
return qs.order_by('data_begin') return qs.order_by('data_begin')
@ -314,8 +344,9 @@ class ExpoCountryCatalog(ExpoCatalog):
#this method used in parent get_queryset #this method used in parent get_queryset
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
country = get_object_or_404(Country, url=slug) country = get_object_or_404(Country, url=slug)
self.kwargs['country'] = country
self.filter_object = country self.filter_object = country
qs = self.model.enable.filter(country=country) qs = self.model.enable.upcoming().filter(country=country)
return qs return qs
class ExpoCityCatalog(ExpoCatalog): class ExpoCityCatalog(ExpoCatalog):
@ -324,21 +355,51 @@ class ExpoCityCatalog(ExpoCatalog):
#this method used in parent get_queryset #this method used in parent get_queryset
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
city = get_object_or_404(City, url=slug) city = get_object_or_404(City, url=slug)
qs = self.model.enable.filter(city=city) self.kwargs['city'] = city
qs = self.model.enable.upcoming().filter(city=city)
self.filter_object = city self.filter_object = city
return qs return qs
class ExpoThemeCatalog(ExpoCatalog): class ExpoThemeCatalog(ExpoCatalog):
template_name = 'exposition/catalog_theme.html'
catalog_url = '/expo/theme/' catalog_url = '/expo/theme/'
country = None
city = None
def get_filtered_qs(self): def get_filtered_qs(self):
#this method used in parent get_queryset #this method used in parent get_queryset
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
country_slug = self.kwargs.get('country_slug')
city_slug = self.kwargs.get('city_slug')
theme = get_object_or_404(Theme, url=slug) theme = get_object_or_404(Theme, url=slug)
qs = self.model.enable.filter(theme=theme) self.kwargs['theme'] = theme
qs = self.model.enable.upcoming().filter(theme=theme)
if country_slug:
country = get_object_or_404(Country, url=country_slug)
self.country = country
self.kwargs['country'] = country
qs = qs.filter(country=country)
if city_slug:
city = get_object_or_404(City, url=city_slug)
self.city = city
self.kwargs['city'] = city
qs = qs.filter(city=city)
self.filter_object = theme self.filter_object = theme
return qs return qs
def get_context_data(self, **kwargs):
context = super(ExpoThemeCatalog, self).get_context_data(**kwargs)
if self.country:
context['country'] = self.country
if self.city:
context['city'] = self.city
context['theme_for_filter'] = self.kwargs['theme']
return context
class ExpoTagCatalog(ExpoCatalog): class ExpoTagCatalog(ExpoCatalog):
catalog_url = '/expo/tag/' catalog_url = '/expo/tag/'
@ -346,12 +407,13 @@ class ExpoTagCatalog(ExpoCatalog):
#this method used in parent get_queryset #this method used in parent get_queryset
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
tag = get_object_or_404(Tag, url=slug) tag = get_object_or_404(Tag, url=slug)
qs = self.model.enable.filter(tag=tag) self.kwargs['tag'] = tag
qs = self.model.enable.upcoming().filter(tag=tag)
self.filter_object = tag self.filter_object = tag
return qs return qs
class ExpoVisitors(ListView): class ExpoVisitors(MetadataMixin, ListView):
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
model = Exposition model = Exposition
#template_name = 'event_visitors.html' #template_name = 'event_visitors.html'
@ -365,6 +427,7 @@ class ExpoVisitors(ListView):
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
exposition = get_object_or_404(self.model, url=slug) exposition = get_object_or_404(self.model, url=slug)
self.obj = exposition self.obj = exposition
self.object = self.obj
return exposition.users.all() return exposition.users.all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -374,7 +437,7 @@ class ExpoVisitors(ListView):
return context return context
class ExpoMembers(ListView): class ExpoMembers(MetadataMixin, ListView):
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
model = Exposition model = Exposition
#template_name = 'event_visitors.html' #template_name = 'event_visitors.html'
@ -388,6 +451,7 @@ class ExpoMembers(ListView):
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
exposition = get_object_or_404(self.model, url=slug) exposition = get_object_or_404(self.model, url=slug)
self.obj = exposition self.obj = exposition
self.object = self.obj
return exposition.company.all() return exposition.company.all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

@ -17,8 +17,8 @@ import pytils, re
class FileForm(forms.Form): class FileForm(forms.Form):
file_path = forms.FileField(label='Выберите файл') file_path = forms.FileField(label='Выберите файл')
model = forms.CharField(required=False, widget=forms.HiddenInput()) model = forms.CharField(required=False, widget=forms.HiddenInput())
purposes = [('scheme teritory','Схема територии'),('preview','Превью')] purposes = [('scheme teritory','Схема территории'),('preview','Превью'), ('preview2','Превью2')]
purpose = forms.ChoiceField(label='Назаначение', choices=purposes) purpose = forms.ChoiceField(label='Назначение', choices=purposes)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """

@ -20,7 +20,8 @@ PURPOSES = (('photo', 'Фото'),
('map','Карта'), ('map','Карта'),
('scheme teritory','Схема територии'), ('scheme teritory','Схема територии'),
('diplom','Дипломы'), ('diplom','Дипломы'),
('preview','Превью') ('preview','Превью'),
('preview2','Превью'),
) )
class FileModel(TranslatableModel): class FileModel(TranslatableModel):

@ -44,6 +44,6 @@ class AdminFilterForm(forms.Form):
qs = model.objects.all() qs = model.objects.all()
if name: if name:
qs = qs.filter(translations__name__contains=name).distinct() qs = qs.filter(translations__name__icontains=name).distinct()
return qs return qs

@ -25,6 +25,11 @@ class AdminView(FormView):
obj = get_object_or_404(self.model, slug=slug) obj = get_object_or_404(self.model, slug=slug)
self.obj = obj self.obj = obj
return obj return obj
id = self.kwargs.get('id')
if id:
obj = get_object_or_404(self.model, id=id)
self.obj = obj
return obj
self.obj = None self.obj = None
return None return None

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
import random
from django.contrib.auth.decorators import login_required
from django.utils.cache import patch_response_headers
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page, never_cache
from django.views.decorators.csrf import csrf_exempt
class NeverCacheMixin(object):
@method_decorator(never_cache)
def dispatch(self, *args, **kwargs):
return super(NeverCacheMixin, self).dispatch(*args, **kwargs)
class LoginRequiredMixin(object):
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(LoginRequiredMixin, self).dispatch(*args, **kwargs)
class CacheMixin(object):
cache_timeout = 60
def get_cache_timeout(self):
return self.cache_timeout
def dispatch(self, *args, **kwargs):
return cache_page(self.get_cache_timeout())(super(CacheMixin, self).dispatch)(*args, **kwargs)
class CacheControlMixin(object):
cache_timeout = 60
def get_cache_timeout(self):
return self.cache_timeout
def dispatch(self, *args, **kwargs):
response = super(CacheControlMixin, self).dispatch(*args, **kwargs)
patch_response_headers(response, self.get_cache_timeout())
return response
class JitterCacheMixin(CacheControlMixin):
cache_range = [60, 120]
def get_cache_range(self):
return self.cache_range
def get_cache_timeout(self):
return random.randint(*self.get_cache_range())

@ -227,7 +227,7 @@ class ExpoListView(ExpoMixin, ListView):
""" """
""" """
paginate_by = 10 paginate_by = settings.CLIENT_PAGINATION
params = None params = None
single_page = False single_page = False
search_form = None search_form = None
@ -320,17 +320,16 @@ class EventDetail(ExpoMixin, DetailView):
from haystack.query import EmptySearchQuerySet from haystack.query import EmptySearchQuerySet
class ExpoSearchView(ListView): class ExpoSearchView(ListView):
paginate_by = 10 paginate_by = settings.CLIENT_PAGINATION
template_name = None template_name = None
search_form = None search_form = None
model = None model = None
def get_queryset(self):
def get_queryset(self):
if self.request.GET: if self.request.GET:
form = self.search_form(self.request.GET) form = self.search_form(self.request.GET)
if form.is_valid(): if form.is_valid():
return form.search() return form.search()
else: else:
return EmptySearchQuerySet() return EmptySearchQuerySet()
@ -340,10 +339,13 @@ class ExpoSearchView(ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ExpoSearchView, self).get_context_data(**kwargs) context = super(ExpoSearchView, self).get_context_data(**kwargs)
form = self.search_form(self.request.GET)
if self.request.GET: if self.request.GET:
form = self.search_form(self.request.GET)
if form.is_valid(): if form.is_valid():
form.data_with_parents = form.get_form_data() form.data_with_parents = form.get_form_data()
else:
form = self.search_form()
context['search_form'] = form context['search_form'] = form
@ -352,4 +354,5 @@ class ExpoSearchView(ListView):
del queries['page'] del queries['page']
context['queries'] = queries context['queries'] = queries
return context return context

@ -20,7 +20,7 @@ from slugify import slugify
def translit_with_separator(string, separator='-'): def translit_with_separator(string, separator='-'):
return slugify(string, to_lower=True) #return slugify(string)
""" """
Trsanslit string and replace "bad" symbols for separator Trsanslit string and replace "bad" symbols for separator

@ -77,8 +77,9 @@ class EventMixin(object):
def get_services(self): def get_services(self):
ids = [item for item, bool in self.country.services if bool==True] country_ids = [item for item, bool in self.country.services if bool==True]
##sasa ids = [item for item, bool in self.services if bool==True and item in country_ids]
return list(Service.objects.language().filter(url__in=ids).order_by('sort')) return list(Service.objects.language().filter(url__in=ids).order_by('sort'))
def duration_days(self, month=None): def duration_days(self, month=None):

@ -1,7 +1,17 @@
import datetime
from django.utils.translation import get_language from django.utils.translation import get_language
from django.db.models import Q
from django.core.cache import cache
from django.utils import translation
from hvad.models import TranslationManager from hvad.models import TranslationManager
class ExpoManager(TranslationManager): class ExpoManager(TranslationManager):
def upcoming(self):
return self.language().select_related('country', 'city', 'place').filter(data_begin__gte=datetime.datetime.now().date()).order_by('data_begin')
def all(self, lang=None): def all(self, lang=None):
if lang: if lang:
return super(ExpoManager, self).language(lang).all().order_by('name') return super(ExpoManager, self).language(lang).all().order_by('name')
@ -16,6 +26,110 @@ class ExpoManager(TranslationManager):
return None return None
class CityManager(TranslationManager):
cache_time = 600
def all(self):
lang = get_language()
qs = super(CityManager, self).select_related('exposition_city', 'conference_city')
qs = qs.filter(Q(exposition_city__city__isnull=False) | Q(conference_city__city__isnull=False))\
.order_by('translations__name').distinct()
return qs
def active_qs(self):
from exposition.models import Exposition
cities_id = [item['city_id'] for item in Exposition.objects.values('city_id').distinct()]
return self.language().filter(id__in=cities_id)
def expo_cities(self):
lang = translation.get_language()
key = 'used_expo_cities_%s'%lang
cached_cities = cache.get(key)
if cached_cities:
return cached_cities
else:
from exposition.models import Exposition
cities_id = [item['city_id'] for item in Exposition.objects.values('city_id').distinct()]
cities = list(self.language().filter(id__in=cities_id))
cache.set(key, cities, self.cache_time)
return cities
def expo_cities_with_count(self):
lang = translation.get_language()
key = 'used_expo_cities_count_%s'%lang
cached_cities = cache.get(key)
if cached_cities:
return cached_cities
else:
from exposition.models import Exposition
sql = {'expo_count':
"""SELECT COUNT(*)
FROM exposition_exposition
WHERE exposition_exposition.city_id = city_city.id
AND exposition_exposition.data_end >= CURDATE()
AND exposition_exposition.is_published = 1"""}
now = datetime.datetime.now().date()
# id of unique cities
cities_id = [item['city_id'] for item in Exposition.objects.filter(is_published=True, data_end__gte=now).values('city_id').distinct()]
cities = set(list(self.language().filter(id__in=cities_id).extra(select=sql)))
cities = sorted(cities, key=lambda x: x.name)
cache.set(key, cities, self.cache_time)
return cities
def conference_cities_with_count(self):
lang = translation.get_language()
key = 'used_conference_cities_count_%s'%lang
cached_cities = cache.get(key)
if cached_cities:
return cached_cities
else:
from conference.models import Conference
sql = {'conference_count':
"""SELECT COUNT(*)
FROM conference_conference
WHERE conference_conference.city_id = city_city.id
AND conference_conference.data_end >= CURDATE()
AND conference_conference.is_published = 1"""}
now = datetime.datetime.now().date()
# id of unique countries
cities_id = [item['city_id'] for item in Conference.objects.filter(is_published=True, data_end__gte=now).values('city_id').distinct()]
cities = set(list(self.language().filter(id__in=cities_id).extra(select=sql)))
cities = sorted(cities, key=lambda x: x.name)
cache.set(key, cities, self.cache_time)
return cities
def conference_cities(self):
lang = translation.get_language()
key = 'used_conference_cities_%s'%lang
cached_cities = cache.get(key)
if cached_cities:
return cached_cities
else:
from conference.models import Conference
cities_id = [item['city_id'] for item in Conference.objects.values('city_id').distinct()]
cities = list(self.language().filter(id__in=cities_id))
cache.set(key, cities, self.cache_time)
return cities
def cities(self):
"""
not finished
"""
lang = translation.get_language()
key = 'used_cities_%s'%lang
cached_cities = cache.get(key)
if cached_cities:
return cached_cities
else:
from exposition.models import Exposition
cities_id = [item['city_id'] for item in Exposition.objects.values('city_id').distinct()]
cities = list(self.language().filter(id__in=cities_id))
cache.set(key, cities, self.cache_time)
return cities
def hvad_to_dict(object): def hvad_to_dict(object):
""" """

@ -22,7 +22,7 @@ from place_conference.models import PlaceConference
class AbstactSearchForm(forms.Form): class AbstactSearchForm(forms.Form):
q = forms.CharField(label=_(u'Я ищу'), required=False) q = forms.CharField(label=_(u'Я ищу'), required=False, widget=forms.TextInput(attrs={'placeholder':_(u'Тематика, слово или название')}))
w = forms.CharField(label=_(u'Где'), required=False) w = forms.CharField(label=_(u'Где'), required=False)
models = None models = None
data_with_parents = None data_with_parents = None
@ -99,6 +99,8 @@ class AbstactSearchForm(forms.Form):
return result return result
def get_places_display(self): def get_places_display(self):
if self.is_valid(): if self.is_valid():
area = self.cleaned_data['area'] area = self.cleaned_data['area']
@ -219,11 +221,7 @@ class AbstactSearchForm(forms.Form):
sqs = sqs.filter(place_filter) sqs = sqs.filter(place_filter)
return sqs#.order_by('data_begin') return sqs#.order_by('data_begin')
import datetime
class ExpositionSearchForm(AbstactSearchForm): class ExpositionSearchForm(AbstactSearchForm):
search_url = '/expo/search/' search_url = '/expo/search/'
autocomplete_url = '/search-form/autosearch/exposition/' autocomplete_url = '/search-form/autosearch/exposition/'
@ -236,24 +234,21 @@ class ExpositionSearchForm(AbstactSearchForm):
#co = forms.CharField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple()) #co = forms.CharField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple())
#tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple()) #tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple())
area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.all_sorted()], area = forms.MultipleChoiceField(label=_(u'Регион'),
choices=[(item.id, item.name) for item in Area.objects.language().all()],
required=False, widget=forms.CheckboxSelectMultiple()) required=False, widget=forms.CheckboxSelectMultiple())
co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(), co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\ choices=[(item.id, item.name) for item in Country.objects.expo_countries()]
.filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
) )
ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(), ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in City.objects.select_related('exposition_city')\ choices=[(item.id, item.name) for item in City.used.expo_cities()]
.filter(exposition_city__city__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
) )
fr = forms.DateField(required=False, fr = forms.DateField(required=False, input_formats=('%d.%m.%Y',),
widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateFrom', widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateFrom',
'placeholder': _(u'дд.мм.гггг')})) 'placeholder': _(u'дд.мм.гггг')}))
to = forms.DateField(required=False, to = forms.DateField(required=False, input_formats=('%d.%m.%Y',),
widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateTo', widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateTo',
'placeholder': _(u'дд.мм.гггг')})) 'placeholder': _(u'дд.мм.гггг')}))
@ -269,6 +264,8 @@ class ExpositionSearchForm(AbstactSearchForm):
q = self.cleaned_data.get('q') q = self.cleaned_data.get('q')
w = self.cleaned_data.get('w') w = self.cleaned_data.get('w')
fr = self.cleaned_data.get('fr') fr = self.cleaned_data.get('fr')
if not fr:
fr = datetime.date.today()
to = self.cleaned_data.get('to') to = self.cleaned_data.get('to')
th = self.cleaned_data.get('th') th = self.cleaned_data.get('th')
tg = self.cleaned_data.get('tg') tg = self.cleaned_data.get('tg')
@ -276,6 +273,7 @@ class ExpositionSearchForm(AbstactSearchForm):
ci = self.cleaned_data.get('ci') ci = self.cleaned_data.get('ci')
area = self.cleaned_data.get('area') area = self.cleaned_data.get('area')
sqs = SearchQuerySet().models(Exposition).all() sqs = SearchQuerySet().models(Exposition).all()
if q: if q:
@ -325,18 +323,14 @@ class PlaceSearchForm(AbstactSearchForm):
title = _(u'ПОИСК МЕСТ') title = _(u'ПОИСК МЕСТ')
models = [PlaceExposition, PlaceConference] models = [PlaceExposition, PlaceConference]
# place fields # place fields
area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.all_sorted()], area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in list(Area.objects.language().all())],
required=False, widget=forms.CheckboxSelectMultiple()) required=False, widget=forms.CheckboxSelectMultiple())
co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(), co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\ choices=[(item.id, item.name) for item in list(Country.objects.expo_countries())]
.filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
) )
ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(), ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in City.objects.select_related('exposition_city')\ choices=[(item.id, item.name) for item in list(City.used.expo_cities())]
.filter(exposition_city__city__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
) )
# #
place_type = forms.MultipleChoiceField(label=_(u'Тип'), required=False, choices=[]) place_type = forms.MultipleChoiceField(label=_(u'Тип'), required=False, choices=[])
@ -356,23 +350,19 @@ class CompanySearchForm(AbstactSearchForm):
required=False, widget=forms.CheckboxSelectMultiple()) required=False, widget=forms.CheckboxSelectMultiple())
tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple()) tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple())
area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.all_sorted()], area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.language().all()],
required=False, widget=forms.CheckboxSelectMultiple()) required=False, widget=forms.CheckboxSelectMultiple())
co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(), co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\ choices=[(item.id, item.name) for item in Country.objects.expo_countries()]
.filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
) )
ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(), ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in City.objects.select_related('exposition_city')\ choices=[(item.id, item.name) for item in City.used.expo_cities()]
.filter(exposition_city__city__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
) )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(CompanySearchForm, self).__init__(*args, **kwargs) super(CompanySearchForm, self).__init__(*args, **kwargs)
self.theme_classes = {item.id:item.generate_search_class() for item in Theme.objects.all()} self.theme_classes = {item.id:item.generate_search_class() for item in list(Theme.objects.language().all())}
def search(self): def search(self):
q = self.cleaned_data.get('q') q = self.cleaned_data.get('q')
@ -431,4 +421,5 @@ class EventSearchForm(forms.Form):
if w: if w:
sqs = sqs.filter(where__contains=w) sqs = sqs.filter(where__contains=w)
return sqs return sqs

@ -6,7 +6,7 @@ from functions.form_check import translit_with_separator
def pre_save_handler(sender, **kwargs): def pre_save_handler(sender, **kwargs):
obj = kwargs['instance'] obj = kwargs['instance']
if obj.language_code =='en': if hasattr(obj, 'language_code') and obj.language_code =='en':
try: try:
name = getattr(obj, 'name') name = getattr(obj, 'name')
obj.url = translit_with_separator(name) obj.url = translit_with_separator(name)

@ -101,20 +101,27 @@ def fill_with_signal(model, obj, data):
# translated fields # translated fields
fields = [field.name for field in model.translations.related.editable_fields() if field.name not in bad_fields] fields = [field.name for field in model.translations.related.editable_fields() if field.name not in bad_fields]
# translate to first language(require) # translate to first language(require)
# ! first save method call signal that fill require language to all translated fields # ! first save method call signal that fill require language to all translated fields
if not obj.id: if not obj.id:
# new object # new object
obj.translate(all_langs[0]) obj.translate(all_langs[0])
# go through all fields and set value # go through all fields and set value
for field in fields: for field in fields:
setattr(obj, field, data.get('%s_%s'%(field, all_langs[0])).strip()) value = data.get('%s_%s'%(field, all_langs[0]), '')
if value:
setattr(obj, field, value.strip())
obj.save() obj.save()
else: else:
trans_obj = model._meta.translations_model.objects.get(language_code = all_langs[0], trans_obj = model._meta.translations_model.objects.get(language_code = all_langs[0],
master__id=getattr(obj, 'id')) master__id=getattr(obj, 'id'))
for field in fields: for field in fields:
setattr(trans_obj, field, data.get('%s_%s'%(field, all_langs[0])).strip())
value = data.get('%s_%s'%(field, all_langs[0]), '')
if value:
setattr(trans_obj, field, value.strip())
trans_obj.save() trans_obj.save()
@ -126,7 +133,7 @@ def fill_with_signal(model, obj, data):
# start from second language # start from second language
trans_obj = model._meta.translations_model.objects.get(language_code = code,master__id=getattr(obj, 'id')) trans_obj = model._meta.translations_model.objects.get(language_code = code,master__id=getattr(obj, 'id'))
for field in fields: for field in fields:
val = data.get('%s_%s'%(field, code)).strip() val = data.get('%s_%s'%(field, code), '').strip()
if val == '': if val == '':
# get value from require translation # get value from require translation
setattr(trans_obj, field, getattr(require_transl, field)) setattr(trans_obj, field, getattr(require_transl, field))

@ -11,7 +11,8 @@ import xlrd
from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, ImportOrganiserForm,\ from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, ImportOrganiserForm,\
ImportPlaceConferenceForm, ImportPlaceExpositionForm ImportPlaceConferenceForm, ImportPlaceExpositionForm
from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\ from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\
ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\
ExportCityForm
from django.views.generic import FormView from django.views.generic import FormView
from django.contrib import messages from django.contrib import messages
@ -78,6 +79,18 @@ class ExportPlaceExposition(ExportView):
form_class = ExportPlaceExpositionForm form_class = ExportPlaceExpositionForm
success_url = '/admin/export-place_exposition' success_url = '/admin/export-place_exposition'
class ExportBlog(ExportView):
form_class = ExportBlogForm
success_url = '/admin/export-blog/'
class ExportBlog(ExportView):
form_class = ExportBlogForm
success_url = '/admin/export-blog/'
class ExportCity(ExportView):
form_class = ExportCityForm
success_url = '/admin/export-city/'
from exposition.models import Exposition from exposition.models import Exposition

@ -3,7 +3,7 @@ from django.conf.urls import patterns, url
from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference
from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\ from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\
ExportPlaceConference, ExportCompany, ExportUser ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^import-event/$', ImportEvent.as_view()), url(r'^import-event/$', ImportEvent.as_view()),
@ -21,5 +21,7 @@ urlpatterns = patterns('',
url(r'^export-place_conference/$', ExportPlaceConference.as_view()), url(r'^export-place_conference/$', ExportPlaceConference.as_view()),
url(r'^export-user/$', ExportUser.as_view()), url(r'^export-user/$', ExportUser.as_view()),
url(r'^export-company/$', ExportCompany.as_view()), url(r'^export-company/$', ExportCompany.as_view()),
url(r'^export-blog/$', ExportBlog.as_view()),
url(r'^export-city/$', ExportCity.as_view()),
) )

@ -247,7 +247,6 @@ def to_phone(value):
value = value.replace(elem, '') value = value.replace(elem, '')
value = to_int(value) value = to_int(value)
print(value)
return value return value
@ -279,9 +278,16 @@ def save_halls(obj, value):
name = l[0].strip() name = l[0].strip()
res.append({'area': area, 'name':name, 'number': number}) res.append({'area': area, 'name':name, 'number': number})
Hall.objects.filter(place_exposition=obj).delete()
for hall in res: for hall in res:
h = Hall(place_exposition = obj, name=hall.get('name'), number=hall.get('number'), capacity=hall.get('area')) h = Hall(place_exposition = obj, name=hall.get('name'), number=hall.get('number'), capacity=hall.get('area'))
h.save() try:
h.save()
except Exception, e:
print('---------------hall error---------')
print e
print('---------------------------------')
place_exp_sett = { place_exp_sett = {
u'ID':{u'field': u'id', u'func': to_int}, u'ID':{u'field': u'id', u'func': to_int},
@ -295,7 +301,7 @@ place_exp_sett = {
u'Тел.':{u'field': u'phone', u'func': to_phone}, u'Тел.':{u'field': u'phone', u'func': to_phone},
u'Факс':{u'field': u'fax', u'func': to_phone}, u'Факс':{u'field': u'fax', u'func': to_phone},
u'Фото':{u'field': u'photo', u'func': save_photo, u'method': True}, u'Фото':{u'field': u'photo', u'func': save_photo, u'method': True},
u'Лого':{u'field': u'logo', u'func': save_file, u'method': True, u'purpose': 'logo'}, u'Лого':{u'field': u'logo', u'func': save_logo, u'method': True},
u'Веб-сайт':{u'field': u'web_page', u'func': unicode}, u'Веб-сайт':{u'field': u'web_page', u'func': unicode},
u'Email':{u'field': u'email', u'func': unicode}, u'Email':{u'field': u'email', u'func': unicode},
u'Карта проезда':{u'field': u'map', u'func': save_file, u'method': True, u'purpose': 'map'}, u'Карта проезда':{u'field': u'map', u'func': save_file, u'method': True, u'purpose': 'map'},
@ -324,6 +330,17 @@ place_exp_sett = {
u'Мобильное приложение':{u'field': u'mobile_application', u'func': bool}, u'Мобильное приложение':{u'field': u'mobile_application', u'func': bool},
} }
article_sett = {
u'ID':{u'field': u'id', u'func': to_int},
u'Заголовок':{u'field': u'main_title', u'func': unicode},
u'Описание':{u'field': u'description', u'func': unicode},
u'Айди автора':{u'field': u'author', u'func': to_user},
u'Создана':{u'field': u'created', u'func': to_datetime}
}
event_sett = { event_sett = {
u'ID':{u'field': u'id', u'func': to_int}, u'ID':{u'field': u'id', u'func': to_int},
u'Url':{u'field': u'url', u'func': unicode}, u'Url':{u'field': u'url', u'func': unicode},
@ -332,16 +349,19 @@ event_sett = {
u'Дата начала:(YYYY-MM-DD)':{u'field': u'data_begin', u'func': to_date}, u'Дата начала:(YYYY-MM-DD)':{u'field': u'data_begin', u'func': to_date},
u'Дата окончания:(YYYY-MM-DD)':{u'field': u'data_end', u'func': to_date}, u'Дата окончания:(YYYY-MM-DD)':{u'field': u'data_end', u'func': to_date},
u'Страна':{u'field': u'country', u'func': to_country}, u'Страна':{u'field': u'country', u'func': to_country},
u'Город':{u'field': u'city', u'func': to_city, 'extra_values': 'country'}, u'Город':{u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Место проведения':{u'field': u'place', u'func': to_place}, #u'Место проведения':{u'field': u'place', u'func': to_place},
u'ID Тематики':{u'field': u'theme', u'func': to_theme, u'method': True},### u'ID Тематики':{u'field': u'theme', u'func': to_theme, u'method': True},###
u'Теги':{u'field': u'tag', u'func': to_tag, u'method': True}, u'Теги':{u'field': u'tag', u'func': to_tag, u'method': True},
#u'Организатор №1':{u'field': u'organiser', u'func': to_tag},#### #u'Организатор №1':{u'field': u'organiser', u'func': to_tag},####
#u'Организатор №2':{u'field': u'organiser', u'func': to_tag},#### #u'Организатор №2':{u'field': u'organiser', u'func': to_tag},####
u'Описание события':{u'field': u'description', u'func': unicode}, u'Описание события':{u'field': u'description', u'func': unicode},
u'Основные темы':{u'field': u'main_themes', u'func': unicode},
u'Условия и скидка':{u'field': u'discount_description', u'func': unicode},
u'Периодичность':{u'field': u'periodic', u'func': to_periodic},### u'Периодичность':{u'field': u'periodic', u'func': to_periodic},###
u'Аудитория':{u'field': u'audience', u'func': to_audience}, u'Аудитория':{u'field': u'audience', u'func': to_audience},
u'Официальный веб-сайт':{u'field': u'web_page', u'func': to_url}, u'Официальный веб-сайт':{u'field': u'web_page', u'func': to_url},
u'Линк на регистрацию':{u'field': u'link', u'func': to_url},
u'Экспонируемые продукты':{u'field': u'products', u'func': unicode}, u'Экспонируемые продукты':{u'field': u'products', u'func': unicode},
u'Время работы':{u'field': u'time', u'func': unicode}, u'Время работы':{u'field': u'time', u'func': unicode},
u'Логотип':{u'field': u'logo', u'func': save_logo, u'method': True}, u'Логотип':{u'field': u'logo', u'func': save_logo, u'method': True},
@ -366,7 +386,7 @@ event_sett = {
u'Min_Pack кв.м.':{u'field': u'min_closed_equipped_area', u'func': to_int}, u'Min_Pack кв.м.':{u'field': u'min_closed_equipped_area', u'func': to_int},
u'Max_Pack кв.м.':{u'field': u'max_closed_equipped_area', u'func': to_int}, u'Max_Pack кв.м.':{u'field': u'max_closed_equipped_area', u'func': to_int},
u'Открытая площадь':{u'field': u'max_open_area', u'func': to_int}, u'Открытая площадь':{u'field': u'max_open_area', u'func': to_int},
u'Мин. Площадь кв.м.':{u'field': u'min_open_area', u'func': to_int}, u'Мин. Площадь кв.м.':{u'field': u'min_stand_size', u'func': to_int},
u'Регистрационный взнос':{u'field': u'registration_payment', u'func': to_int}, u'Регистрационный взнос':{u'field': u'registration_payment', u'func': to_int},
u'Примечание по участии':{u'field': u'participation_note', u'func': unicode}, u'Примечание по участии':{u'field': u'participation_note', u'func': unicode},
u'Крайний срок подачи заявки':{u'field': u'application_deadline', u'func': to_date}, u'Крайний срок подачи заявки':{u'field': u'application_deadline', u'func': to_date},

@ -1,11 +1,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.utils import translation
from theme.models import Theme, Tag from theme.models import Theme, Tag
from country.models import Country from country.models import Country
from city.models import City
from organiser.models import Organiser from organiser.models import Organiser
from accounts.models import User from accounts.models import User
from company.models import Company from company.models import Company
from article.models import Article
from place_exposition.models import PlaceExposition from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference from place_conference.models import PlaceConference
from django.db.models.loading import get_model from django.db.models.loading import get_model
@ -149,6 +152,25 @@ class ExportCompanyForm(ExportForm):
def get_fname(self): def get_fname(self):
return 'companies.xls' return 'companies.xls'
class ExportBlogForm(ExportForm):
model = Article
def get_fname(self):
return 'blogs.xls'
def get_objects(self, data):
translation.activate(data['language'])
return self.model.objects.blogs()
class ExportCityForm(ExportForm):
model = City
def get_fname(self):
return 'cities.xls'
def get_objects(self, data):
translation.activate(data['language'])
return self.model.used.all()
class ExportEventForm(forms.Form): class ExportEventForm(forms.Form):

@ -12,6 +12,7 @@ from city.models import City
from theme.models import Theme, Tag from theme.models import Theme, Tag
from functions.files import get_alternative_filename from functions.files import get_alternative_filename
from exposition.models import BIT_AUDIENCE from exposition.models import BIT_AUDIENCE
from accounts.models import User
def to_int(val): def to_int(val):
@ -29,19 +30,32 @@ def to_date(value):
return None return None
if isinstance(value, unicode) or isinstance(value, str): if isinstance(value, unicode) or isinstance(value, str):
try:
t = time.strptime(value, "%d.%m.%Y") t = time.strptime(value, "%d.%m.%Y")
except ValueError:
t = time.strptime(value, "%d/%m/%Y")
if isinstance(value, float): if isinstance(value, float):
t = xlrd.xldate_as_tuple(value, 0)+(0,0,0) t = xlrd.xldate_as_tuple(value, 0)+(0,0,0)
return time.strftime("%Y-%m-%d", t) return time.strftime("%Y-%m-%d", t)
def to_datetime(value):
if not value:
return None
if isinstance(value, unicode) or isinstance(value, str):
t = time.strptime(value, "%Y-%m-%d %H:%M:%S")
return time.strftime("%Y-%m-%d %H:%M:%S", t)
def to_country(value): def to_country(value):
try: try:
query = get_translation_aware_manager(Country) query = get_translation_aware_manager(Country)
country = query.filter(name=value)[0] country = query.filter(name=value)[0]
return country return country
except IndexError: except IndexError:
print('---------------------')
print(value.encode('utf8')) print(value.encode('utf8'))
print('AAAAAAAA')
return None return None
def to_city(value, lang, country): def to_city(value, lang, country):
@ -51,9 +65,9 @@ def to_city(value, lang, country):
# except IndexError if no found # except IndexError if no found
city = City.objects.filter(translations__name=value, country=country)[0] city = City.objects.filter(translations__name=value, country=country)[0]
# print(city) # print(city)
return city return city.id
except IndexError: except IndexError:
print('---------------------') print('---------city error------------')
print(value.encode('utf8')) print(value.encode('utf8'))
print('---------------------') print('---------------------')
return None return None
@ -70,6 +84,9 @@ def to_theme(obj, value):
else: else:
theme_ids = value.split(',') theme_ids = value.split(',')
if theme_ids == ['']:
return
obj.theme.clear()
obj.theme.add(*Theme.objects.filter(id__in=theme_ids)) obj.theme.add(*Theme.objects.filter(id__in=theme_ids))
def to_tag(obj,value): def to_tag(obj,value):
@ -78,6 +95,7 @@ def to_tag(obj,value):
names = value.split(',') names = value.split(',')
translation.activate('en') translation.activate('en')
if names: if names:
obj.tag.clear()
obj.tag.add(*Tag.objects.filter(translations__name__in=names, theme__in=obj.theme.all())) obj.tag.add(*Tag.objects.filter(translations__name__in=names, theme__in=obj.theme.all()))
else: else:
return return
@ -140,16 +158,23 @@ def save_logo(obj, path):
logo_path = obj.logo.field.upload_to logo_path = obj.logo.field.upload_to
full_path = settings.MEDIA_ROOT + logo_path full_path = settings.MEDIA_ROOT + logo_path
try:
alt_name = get_alternative_filename(full_path, file_name) alt_name = get_alternative_filename(full_path, file_name)
except UnicodeEncodeError:
return None
download_to = full_path+alt_name download_to = full_path+alt_name
if path.startswith('http://') or path.startswith('https://'): if path.startswith('http://') or path.startswith('https://'):
url = path url = path
else: elif path.startswith('/'):
url = 'http://expomap.ru' + path url = 'http://expomap.ru' + path
elif path.startswith('images'):
url = 'http://expomap.ru/' + path
else:
return None
try: try:
response = urllib2.urlopen(url, timeout=15) response = urllib2.urlopen(url, timeout=15)
@ -181,4 +206,11 @@ def check_quality_label(obj, value, label):
return bit return bit
if value: if value:
setattr(bit, label, True) setattr(bit, label, True)
return bit return bit
def to_user(value):
try:
return User.objects.get(id=value)
except User.DoesNotExist:
return User.objects.get(id=1)

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.core.context_processors import csrf
from django.conf import settings
from django.forms.formsets import BaseFormSet, formset_factory
from django.forms.models import modelformset_factory
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.decorators import login_required
#models and forms
from models import MetaSetting
from forms import MetaForm, MetaFilterForm
from functions.admin_views import AdminListView, AdminView
class MetaListView(AdminListView):
template_name = 'admin/meta/meta_list.html'
form_class = MetaFilterForm
model = MetaSetting
class MetaView(AdminView):
form_class = MetaForm
model = MetaSetting
success_url = '/admin/meta/all/'
template_name = 'admin/meta/meta_setting.html'
def form_valid(self, form):
self.set_obj()
expo = form.save(obj=self.obj)
return HttpResponseRedirect(self.success_url)
def get_form(self, form_class):
if self.request.POST:
return super(MetaView, self).get_form(form_class)
obj = self.set_obj()
if obj:
data = {'name':obj.name}
for code, name in settings.LANGUAGES:
trans_obj = self.model._meta.translations_model.objects.get(language_code = code,master__id=obj.id) #access to translated fields
data['title_%s' % code] = trans_obj.title
data['description_%s' % code] = trans_obj.description
data['keywords_%s' % code] = trans_obj.keywords
data['h1_%s' % code] = trans_obj.h1
form =form_class(initial=data)
return form
else:
return form_class()
def get_context_data(self, **kwargs):
context = super(MetaView, self).get_context_data(**kwargs)
obj = self.set_obj()
return context

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from admin import MetaListView, MetaView
urlpatterns = patterns('conference.admin',
url(r'^all/$', MetaListView.as_view()),
#url(r'^change/(?P<url>.*)/$', 'conference_change'),
url(r'^(?P<id>.*)/$', MetaView.as_view()),
url(r'^$', MetaView.as_view()),
)

@ -0,0 +1,23 @@
from meta.views import Meta
def add_meta(view):
def wrapper(request, *args, **kwargs):
"""
meta = Meta(
title=title,
description=description,
keywords=keywords,
meta_extras = {
'viewport': 'width=device-width, initial-scale=1.0, minimum-scale=1.0'
}
'extra_custom_props': [
('http-equiv', 'Content-Type', 'text/html; charset=UTF-8'),
]
)
"""
r = view(request, *args, **kwargs)
r.context_data = {'foo': 'bar'}
return r.render()
return wrapper

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
from django import forms
from django.conf import settings
from models import MetaSetting
from functions.translate import fill_with_signal
from functions.admin_forms import AdminFilterForm
class MetaForm(forms.Form):
name = forms.CharField(label=u'Название страницы')
def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
"""
super(MetaForm, self).__init__(*args, **kwargs)
#creates translated forms example: name_ru, name_en
# len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs
if len(settings.LANGUAGES) in range(10):
for lid, (code, name) in enumerate(settings.LANGUAGES):
# uses enumerate for detect iteration number
# first iteration is a default lang so it required fields
required = True if lid == 0 else False
self.fields['title_%s' % code] = forms.CharField(label=u'Title', required=required,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['description_%s' % code] = forms.CharField(label=u'Description', required=required,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['keywords_%s' % code] = forms.CharField(label=u'Keywords', required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['h1_%s' % code] = forms.CharField(label=u'H1', required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
def save(self, obj=None):
data = self.cleaned_data
if not obj:
meta = MetaSetting()
else:
meta = obj
meta.name = data['name']
# fill translated fields and save object
fill_with_signal(MetaSetting, meta, data)
meta.save()
class MetaFilterForm(AdminFilterForm):
model = MetaSetting

@ -1,8 +1,44 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.db import models from django.db import models
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from django.utils import translation from django.utils import translation
from django.db.models.signals import post_save
from django.utils.translation import ugettext_lazy as _
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from pymorphy.django_conf import default_morph as morph from pymorphy.django_conf import default_morph as morph
from functions.signal_handlers import post_save_handler
# additional funcs
MONTHES = {'jan': _(u'январе'), 'feb': _(u'феврале'), 'mar': _(u'марте'), 'apr': _(u'апреле'),
'may': _(u'мае'), 'jun': _(u'июне'), u'jul': _(u'июле'), 'aug': _(u'августе'),
'sep': _(u'сентябре'), 'oct': _(u'октябре'), 'nov': _(u'ноябре'), 'dec': _(u'декабре'),}
def get_month_inflect(value, key):
return {key: MONTHES.get(value, '') }
def get_obj_inflect(obj, key):
if translation.get_language() == 'ru':
result = {key: getattr(obj, 'inflect', '')}
else:
result = {key: getattr(obj, 'name', '')}
return result
def get_theme_inflect(obj, key):
if translation.get_language() == 'ru':
result = {'theme_inflect': getattr(obj, 'inflect', ''),
'theme_name': getattr(obj, 'name', '')}
else:
result = {'theme_inflect': getattr(obj, 'name', ''),
'theme_name': getattr(obj, 'name', '')}
return result
def get_tag_inflect(obj, key):
if translation.get_language() == 'ru':
result = {'tag_inflect': getattr(obj, 'inflect', ''),
'tag_name': getattr(obj, 'name', '')}
else:
result = {'tag_inflect': getattr(obj, 'name', ''),
'tag_name': getattr(obj, 'name', '')}
return result
class MetaSetting(TranslatableModel): class MetaSetting(TranslatableModel):
name = models.CharField(max_length=100, unique=True) name = models.CharField(max_length=100, unique=True)
@ -13,32 +49,41 @@ class MetaSetting(TranslatableModel):
h1 = models.CharField(max_length=255, blank=True), h1 = models.CharField(max_length=255, blank=True),
) )
params = {'EXPONAME':{'name': 'name'}, object_params = {'object_name': 'name', 'object_title': 'main_title', 'city': 'city', 'country': 'country'}
'EXPONAME_YA':{'name': 'name', 'inflect': True},
'EXPOCOUNTRY':{'name': 'country'}, params = {'month': get_month_inflect, 'country': get_obj_inflect, 'city': get_obj_inflect,
'EXPOCOUNTRY_YA':{'name': 'country', 'inflect': True}, 'theme': get_theme_inflect, 'tag': get_tag_inflect}
'EXPOPLACE':{'name': 'place'}, monthes = {'jan': _(u'январе'), 'feb': _(u'феврале'), 'mar': _(u'марте'), 'apr': _(u'апреле'),
'EXPOCITY':{'name': 'city'}, 'may': _(u'мае'), 'jun': _(u'июне'), u'jul': _(u'июле'), 'aug': _(u'августе'),
'EXPOTHEME':{'name': 'theme'}, 'sep': _(u'сентябре'), 'oct': _(u'октябре'), 'nov': _(u'ноябре'), 'dec': _(u'декабре'),}
'EXPOTAG':{'name': 'tag'},
'EXPOMONTH':{'name': 'month'},
'EXPOYEAR':{'name': 'year'},
}
def __unicode__(self): def __unicode__(self):
return self.name return self.name
def generate_meta(self, obj):
def generate_meta(self, params, obj=None):
""" """
obj must be in current language obj must be in current language
""" """
lang = translation.get_language() lang = translation.get_language()
params = {'EXPONAME': getattr(obj, 'name', '')} updates = {}
if obj:
for key, value in self.object_params.iteritems():
updates.update({key: getattr(obj, value, '')})
for key, value in params.iteritems():
if key in self.params:
updates.update(self.params[key](value, key))
params.update(updates)
tr = self.translations.get(language_code=lang) tr = self.translations.get(language_code=lang)
title = tr.title.format(**params) title = tr.title.format(**params)
description = tr.description.format(**params) description = tr.description.format(**params)
keywords = []#tr.keywords.format(**params) keywords = []#tr.keywords.format(**params)
h1 = tr.h1.format(**params) h1 = tr.h1.format(**params)
return {'title': title, 'description': description, 'keywords': keywords, 'h1': h1} return {'title': title, 'description': description, 'keywords': keywords, 'h1': h1}
def get_param(self, obj, field): def get_param(self, obj, field):
@ -51,6 +96,21 @@ class MetaSetting(TranslatableModel):
return s return s
def get_title(self):
title = self.title
return title
def get_h1(self):
h1 = self.h1
return h1
def get_description(self):
description = self.description
return description
def get_keywords(self):
keywords = self.keywords
return []
post_save.connect(post_save_handler, sender=MetaSetting)

@ -1,6 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from models import MetaSetting
from . import settings from . import settings
@ -150,18 +151,40 @@ class MetadataMixin(object):
return self.site_name or settings.SITE_NAME return self.site_name or settings.SITE_NAME
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(MetadataMixin, self).get_context_data(**kwargs) context = super(MetadataMixin, self).get_context_data(**kwargs)
context['meta'] = self.get_meta_class()(
use_og=self.use_og, meta_id = self.kwargs.get('meta_id')
use_sites=self.use_sites, if not meta_id:
title=self.get_meta_title(context=context), meta_id = kwargs.get('meta_id')
h1=self.get_meta_h1(context=context),
if meta_id:
description=self.get_meta_description(context=context), try:
keywords=self.get_meta_keywords(context=context), meta_set = MetaSetting.objects.language().get(id=meta_id)
image=self.get_meta_image(context=context), except MetaSetting.DoesNotExist:
url=self.get_meta_url(context=context), return context
object_type=self.get_meta_object_type(context=context), params = dict(self.kwargs)
site_name=self.get_meta_site_name(context=context), if getattr(self, 'object', None):
) data = meta_set.generate_meta(params, self.object)
return context else:
data = meta_set.generate_meta(params)
self.title = data.get('title')
self.h1 = data.get('h1')
self.description = data.get('description')
self.keywords = data.get('keywords', [])
context['meta'] = self.get_meta_class()(
use_og=self.use_og,
use_sites=self.use_sites,
title=self.get_meta_title(context=context),
h1=self.get_meta_h1(context=context),
description=self.get_meta_description(context=context),
keywords=self.get_meta_keywords(context=context),
image=self.get_meta_image(context=context),
url=self.get_meta_url(context=context),
object_type=self.get_meta_object_type(context=context),
site_name=self.get_meta_site_name(context=context),
)
return context

@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from organiser.models import Organiser from organiser.models import Organiser
from theme.models import Theme, Tag from theme.models import Theme, Tag
from functions.form_check import translit_with_separator from functions.form_check import translit_with_separator
from accounts.models import User
import MySQLdb import MySQLdb
from MySQLdb.cursors import DictCursor from MySQLdb.cursors import DictCursor
@ -21,9 +23,9 @@ def convert_to_int(st):
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
db = MySQLdb.connect(host="localhost", db = MySQLdb.connect(host="localhost",
user="root", user="kotzilla",
passwd="qazedc", passwd="qazedc",
db="expomap_ru", db="old_expomap",
charset='utf8', charset='utf8',
cursorclass=DictCursor) cursorclass=DictCursor)
@ -31,18 +33,18 @@ class Command(BaseCommand):
sql = """SELECT DISTINCT(customers_company) as name, specialize, otrasly as theme, tags, adress, sql = """SELECT DISTINCT(customers_company) as name, customers_email_address as user_email, specialize, otrasly as theme, tags, adress,
phone, fax, email, website, twitter, about, customers_company.url phone, fax, email, website, twitter, about, customers_company.url, company_last_modified as modified
FROM customers FROM customers
LEFT JOIN customers_company LEFT JOIN customers_company
ON customers.customers_company=customers_company.title ON customers.customers_id = customers_company.customers_id
WHERE customers_status = 4 WHERE customers_status = 4
""" """
cursor.execute(sql) cursor.execute(sql)
res = cursor.fetchall() res = cursor.fetchall()
print(res[0].get('user_email'))
for o in res: for o in res:
if not o.get('name'): if not o.get('name'):
@ -66,7 +68,7 @@ class Command(BaseCommand):
organiser.description = o.get('about') organiser.description = o.get('about')
if organiser.name: if organiser.name:
print('not_saved: %s'%o['name']) print('not_saved: %s'%o['name'].encode('utf8'))
organiser.save() organiser.save()
print('saved: %s'%str(organiser)) print('saved: %s'%str(organiser))
@ -75,12 +77,10 @@ class Command(BaseCommand):
if theme_id: if theme_id:
try: try:
theme = Theme.objects.get(id=theme_id) theme = Theme.objects.get(id=theme_id)
organiser.theme.add(theme)
except Theme.DoesNotExist: except Theme.DoesNotExist:
continue pass
organiser.theme.add(theme)
if not theme:
continue
tags = o.get('tags') tags = o.get('tags')
if tags: if tags:
@ -104,5 +104,14 @@ class Command(BaseCommand):
organiser.save() organiser.save()
print(organiser) print(organiser)
user_email = o.get('user_email')
if user_email:
try:
user = User.objects.get(username=user_email)
user.organiser = organiser
user.save()
except User.DoesNotExist:
print('no user with this email: %s'%user_email)
print('success') print('success')

@ -75,6 +75,7 @@ class Organiser(TranslatableModel):
#fields saves information about creating and changing model #fields saves information about creating and changing model
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True) modified = models.DateTimeField(auto_now=True)
active = models.NullBooleanField(default=0)
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', self.pk) return self.lazy_translation_getter('name', self.pk)

@ -0,0 +1,114 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html style="margin: 0; padding: 0; height: 100%;">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
</head>
<body style="margin: 0; padding: 0; min-height: 100%; background: #f4f2ee;">
<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%" bgcolor="#f4f2ee" style="font-family: Arial, sans-serif; background: #f4f2ee;">
<tr>
<td align="center" style="padding: 50px 0">
<table cellpadding="0" cellspacing="0" border="0" width="600" style="width: 600px;">
<tr>
<td style="vertical-align: top;">
<div class="logo">
<a style="text-decoration: none; color: #a2a2a2; font-size: 12px;" href="#">
<img src="cid:logo" alt="Expomap.ru" />
<b style="display: block; padding-left: 67px; margin-top: -5px;">Выставки, конференции, семинары</b>
</a>
</div>
</td>
<td style="vertical-align: top; padding-top: 22px;">
<ul class="t-links" style="margin: 0 0 15px; padding: 0; list-style: none; text-align: right; font-size: 16px; line-height: 17px; font-weight: bold;">
<li style="display: inline-block;"><a style="text-decoration: none; color: #ff6600" href="#">СОБЫТИЯ</a></li>
<li style="display: inline-block; margin-left: 20px;"><a style="text-decoration: none; color: #ff6600" href="#">МЕСТА</a></li>
<li style="display: inline-block; margin-left: 20px;"><a style="text-decoration: none; color: #ff6600" href="#">УЧАСТНИКИ</a></li>
</ul>
<ul class="soc-media-buttons" style="margin: 0; padding: 0; list-style: none; text-align: right;">
<li style="display: inline-block;"><a href="#"><img src="cid:rss" title="RSS" alt="RSS" /></a></li>
<li style="display: inline-block; margin-left: 5px;"><a href="#"><img src="cid:fb" title="Facebook" alt="Facebook" /></a></li>
<li style="display: inline-block; margin-left: 5px;"><a href="#"><img src="cid:linkedin" title="LinkedIn" alt="LinkedIn" /></a></li>
<li style="display: inline-block; margin-left: 5px;"><a href="#"><img src="cid:vk" title="В контакте" alt="В контакте" /></a></li>
<li style="display: inline-block; margin-left: 5px;"><a href="#"><img src="cid:twit" title="Twitter" alt="Twitter" /></a></li>
</ul>
</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" border="0" width="600" style="width: 600px; margin-bottom: 10px;">
<tr>
<td style="padding: 20px 0 0;"><p style="display: block; padding: 25px 30px; text-decoration: none; background: #ff6600; color: #ffffff; font-size: 20px; line-height: 26px; margin-bottom: 0;" >Воостановление пароля на портале <a href="http://expomap.ru/" style="color: #ffffff;text-decoration: none;border-bottom: 1px dashed #ee3824;">Expomap</a></p></td>
</tr>
<tr>
<td style="padding: 10px 30px 15px; background: #faf9f7;">
<table cellpadding="0" cellspacing="0" border="0" width="540" style="margin-bottom: 15px;">
<tr valign="top">
<td style="padding: 15px 0 36px 0;">
<p style="font-weight: bold;color: #003e79;margin: 0;">Добрый день, {{ user.first_name }}!</p>
</td>
</tr>
<tr valign="top">
<td style="padding: 0 0 23px 0;">
Вы или кто-то еще сделал запрос на сброс пароля на сайте <a href="{{ domain }}" style="text-decoration: none;border-bottom: 1px dashed #ee3824;color: #645a5a;">{{ domain }}</a>
</td>
</tr>
<tr valign="top">
<td style="padding: 0 0 32px 0;">
Вы можете восстановить доступ, нажав на кнопку ниже и указав новый пароль:
</td>
</tr>
<tr valign="top">
<td style="padding: 0 0 32px 0; text-align: center;">
<a class="button" style="display: inline-block; padding: 4px 10px 3px; text-decoration: none; color: #2592c5; font-size: 14px; font-weight: bold; line-height: 14px; border: 1px solid #90c7e0; text-transform: uppercase; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; width: 336px;" href="http{% if secure %}s{% endif %}://{{ site.domain }}{% url "password_reset_reset" token %}">востановить пароль</a>
</td>
</tr>
<tr valign="top">
<td style="padding: 0 0 20px 0; text-align: left; ">
Если вы не хотите сбрасывать пароль, просто <span style="border-bottom: 1px dashed #ee3824;">проигнорируйте</span> это сообщение
</td>
</tr>
</table>
</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" border="0" width="600" style="width: 600px; border-bottom: 1px dotted #cccccc;">
<tr>
<td style="vertical-align: top; padding: 15px 0 10px;">
<div class="logo">
<a style="text-decoration: none; color: #a2a2a2; font-size: 12px;" href="#">
<img src="cid:logo2" alt="Expomap.ru" />
</a>
</div>
</td>
<td style="vertical-align: top; padding: 25px 0 5px;">
<ul class="t-links" style="margin: 0 0 15px; padding: 0; list-style: none; text-align: right; font-size: 14px; line-height: 15px; font-weight: bold;">
<li style="display: inline-block;"><a style="text-decoration: none; color: #ff6600" href="#">СОБЫТИЯ</a></li>
<li style="display: inline-block; margin-left: 20px;"><a style="text-decoration: none; color: #ff6600" href="#">МЕСТА</a></li>
<li style="display: inline-block; margin-left: 20px;"><a style="text-decoration: none; color: #ff6600" href="#">УЧАСТНИКИ</a></li>
</ul>
</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" border="0" width="600" style="width: 600px; font-size: 12px; line-height: 15px;">
<tr>
<td style="vertical-align: top; padding: 15px 0 15px; color: #a2a2a2; text-align: right;">
© 2018 — 2013 <a style="color: #a2a2a2; text-decoration: none;" href="#">Expomap.ru</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

@ -1,15 +1,18 @@
import datetime import datetime
from django.core.mail import EmailMessage
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import Site, RequestSite from django.contrib.sites.models import Site, RequestSite
from django.core import signing from django.core import signing
from django.core.mail import send_mail from django.core.mail import send_mail
from django.template import Context
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.http import Http404 from django.http import Http404
from django.template import loader from django.template import loader
from django.utils import timezone from django.utils import timezone
from django.views import generic from django.views import generic
from django.template.loader import get_template
from email.MIMEImage import MIMEImage
from .forms import PasswordRecoveryForm, PasswordResetForm from .forms import PasswordRecoveryForm, PasswordResetForm
from .utils import get_user_model, get_username from .utils import get_user_model, get_username
@ -52,7 +55,7 @@ class Recover(SaltMixin, generic.FormView):
form_class = PasswordRecoveryForm form_class = PasswordRecoveryForm
template_name = 'password_reset/recovery_form.html' template_name = 'password_reset/recovery_form.html'
success_url_name = 'password_reset_sent' success_url_name = 'password_reset_sent'
email_template_name = 'password_reset/recovery_email.txt' email_template_name = 'password_reset/recovery_email_expo.html'
email_subject_template_name = 'password_reset/recovery_email_subject.txt' email_subject_template_name = 'password_reset/recovery_email_subject.txt'
search_fields = ['username', 'email'] search_fields = ['username', 'email']
@ -85,12 +88,35 @@ class Recover(SaltMixin, generic.FormView):
'token': signing.dumps(self.user.pk, salt=self.salt), 'token': signing.dumps(self.user.pk, salt=self.salt),
'secure': self.request.is_secure(), 'secure': self.request.is_secure(),
} }
body = loader.render_to_string(self.email_template_name,
context).strip() #body = loader.render_to_string(self.email_template_name,
# context).strip()
message = get_template(self.email_template_name).render(Context(context))
subject = loader.render_to_string(self.email_subject_template_name, subject = loader.render_to_string(self.email_subject_template_name,
context).strip() context).strip()
send_mail(subject, body, settings.DEFAULT_FROM_EMAIL,
[self.user.email]) msg = EmailMessage(subject, message, settings.DEFAULT_FROM_EMAIL, [self.user.email])
msg.content_subtype = "html"
images =(('/img/logo_reg.png', 'logo'),
('/img/soc-medias/sm-icon-rss.png', 'rss'),
('/img/soc-medias/sm-icon-fb.png', 'fb'),
('/img/soc-medias/sm-icon-lin.png', 'linkedin'),
('/img/soc-medias/sm-icon-vk.png', 'vk'),
('/img/soc-medias/sm-icon-twit.png', 'twit'),
('/img/mail-logo-2.jpg','logo2'))
for img in images:
fp = open(settings.STATIC_ROOT+img[0], 'rb')
msg_img = MIMEImage(fp.read())
fp.close()
msg_img.add_header('Content-ID', '<'+img[1]+'>')
msg.attach(msg_img)
msg.send()
#send_mail(subject, body, settings.DEFAULT_FROM_EMAIL,
# [self.user.email])
def form_valid(self, form): def form_valid(self, form):
self.user = form.cleaned_data['user'] self.user = form.cleaned_data['user']

@ -20,7 +20,7 @@ import random
#custom fields #custom fields
from functions.custom_views import objects_list, delete_object from functions.custom_views import objects_list, delete_object
from functions.views_help import get_referer from functions.views_help import get_referer
from functions.admin_views import AdminView, AdminListView, upload_photo from functions.admin_views import AdminView, AdminListView, upload_photo, FormView
def exposition_all(request): def exposition_all(request):
@ -282,3 +282,28 @@ class PlaceExpositionListView(AdminListView):
def upload_place_photo(request, place_id): def upload_place_photo(request, place_id):
return upload_photo(request, place_id, PlaceExposition) return upload_photo(request, place_id, PlaceExposition)
def edit_hall(request, place_url, hall_id):
place = get_object_or_404(PlaceExposition, url=place_url)
hall = get_object_or_404(Hall, id=hall_id)
if request.POST:
form = HallForm(request.POST)
if form.is_valid():
form.save(place, hall_id)
return HttpResponseRedirect('/admin/place_exposition/%s/'%place.url)
else:
data = {'capacity': hall.capacity, 'number': hall.number}
for code, name in settings.LANGUAGES:
trans_obj = Hall._meta.translations_model.objects.get(language_code = code, master__id=hall.id) #access to translated fields
data['name_%s'%code] = trans_obj.name
form = HallForm(initial=data)
context = {'form': form, 'languages': settings.LANGUAGES}
context.update(csrf(request))
return render_to_response('admin/place_exposition/hall.html', context)

@ -7,10 +7,11 @@ urlpatterns = patterns('place_exposition.admin',
url(r'^add-hall/(?P<place_id>.*)/$', 'add_hall'), url(r'^add-hall/(?P<place_id>.*)/$', 'add_hall'),
url(r'^delete-hall/(?P<hall_id>.*)/$', 'delete_hall'), url(r'^delete-hall/(?P<hall_id>.*)/$', 'delete_hall'),
url(r'^upload-photo/(?P<place_id>.*)/$', 'upload_place_photo'), url(r'^upload-photo/(?P<place_id>.*)/$', 'upload_place_photo'),
url(r'^hall/(?P<place_url>.*)/(?P<hall_id>.*)/$', 'edit_hall'),
url(r'^all/$', PlaceExpositionListView.as_view()), url(r'^all/$', PlaceExpositionListView.as_view()),
#url(r'^add.*/$', 'exposition_add'), #url(r'^add.*/$', 'exposition_add'),
#url(r'^delete/(?P<url>.*)/$', 'exposition_delete'), url(r'^delete/(?P<url>.*)/$', 'exposition_delete'),
#url(r'^change/(?P<url>.*)/$', 'exposition_change'), #url(r'^change/(?P<url>.*)/$', 'exposition_change'),
#url(r'^copy/(?P<url>.*)/$', 'place_exposition_copy'), #url(r'^copy/(?P<url>.*)/$', 'place_exposition_copy'),
url(r'^(?P<url>.*)/$', PlaceExpositionView.as_view()), url(r'^(?P<url>.*)/$', PlaceExpositionView.as_view()),

@ -27,13 +27,13 @@ class ExpositionForm(forms.Form):
""" """
types = [(item1, item2) for item1, item2 in EXPOSITION_TYPE] types = [(item1, item2) for item1, item2 in EXPOSITION_TYPE]
type = forms.ChoiceField(required=False, choices=types) type = forms.ChoiceField(required=False, choices=types)
logo = forms.ImageField(label='Logo', required=False) logo = forms.ImageField(label='Logo', required=False, max_length=500)
country = forms.ChoiceField(label='Страна', choices=[(c.id, c.name) for c in Country.objects.all()]) country = forms.ChoiceField(label='Страна', choices=[(c.id, c.name) for c in Country.objects.all()])
# creates select input with empty choices cause it will be filled with ajax # creates select input with empty choices cause it will be filled with ajax
city = forms.CharField(label='Город', widget=forms.HiddenInput()) city = forms.CharField(label='Город', widget=forms.HiddenInput())
address = forms.CharField(label='Адресс', widget=LocationWidget, required=False) address = forms.CharField(label='Адрес', widget=LocationWidget, required=False)
phone = forms.CharField(label='Телефон', required=False, phone = forms.CharField(label='Телефон', required=False,
widget=forms.TextInput(attrs={'placeholder': 'Введите телефон'})) widget=forms.TextInput(attrs={'placeholder': 'Введите телефон'}))
@ -48,7 +48,7 @@ class ExpositionForm(forms.Form):
widget=forms.TextInput(attrs={'placeholder': 'Год основания'})) widget=forms.TextInput(attrs={'placeholder': 'Год основания'}))
total_area = forms.CharField(label='Общая выставочная площадь', required=False, total_area = forms.CharField(label='Общая выставочная площадь', required=False,
widget=forms.TextInput(attrs={'placeholder': 'Общая выст. площадь'})) widget=forms.TextInput(attrs={'placeholder': 'Общая выст. площадь'}))
closed_area = forms.CharField(label='Закрытая выствочная площадь', required=False, closed_area = forms.CharField(label='Закрытая выставочная площадь', required=False,
widget=forms.TextInput(attrs={'placeholder': 'Закр. выст. площадь'})) widget=forms.TextInput(attrs={'placeholder': 'Закр. выст. площадь'}))
open_area = forms.CharField(label='Открытая выставочная площадь', required=False, open_area = forms.CharField(label='Открытая выставочная площадь', required=False,
widget=forms.TextInput(attrs={'placeholder': 'Откр. выст. площадь'})) widget=forms.TextInput(attrs={'placeholder': 'Откр. выст. площадь'}))
@ -62,10 +62,10 @@ class ExpositionForm(forms.Form):
children_room = forms.BooleanField(label='Детская комната', required=False) children_room = forms.BooleanField(label='Детская комната', required=False)
disabled_service = forms.BooleanField(label='Сервис для инвалидов', required=False) disabled_service = forms.BooleanField(label='Сервис для инвалидов', required=False)
conference_centre = forms.BooleanField(label='Конгресс-центр', required=False) conference_centre = forms.BooleanField(label='Конгресс-центр', required=False)
business_centre = forms.BooleanField(label='Бизнес центр', required=False) business_centre = forms.BooleanField(label='Бизнес-центр', required=False)
online_registration = forms.BooleanField(label='Онлайн регистрация', required=False) online_registration = forms.BooleanField(label='Онлайн регистрация', required=False)
cafe = forms.BooleanField(label='Кафе', required=False) cafe = forms.BooleanField(label='Кафе', required=False)
terminals = forms.BooleanField(label='Информационые терминалы', required=False) terminals = forms.BooleanField(label='Информационные терминалы', required=False)
parking = forms.BooleanField(label='Парковка', required=False) parking = forms.BooleanField(label='Парковка', required=False)
press_centre = forms.BooleanField(label='Пресс-центр', required=False) press_centre = forms.BooleanField(label='Пресс-центр', required=False)
mobile_application = forms.BooleanField(label='Мобильное приложение', required=False) mobile_application = forms.BooleanField(label='Мобильное приложение', required=False)
@ -278,8 +278,10 @@ class HallForm(forms.ModelForm):
class HallForm(forms.Form): class HallForm(forms.Form):
url = '/admin/place_exposition/add-hall/' url = '/admin/place_exposition/add-hall/'
number = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:30px'}),required=False) number = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:30px'}),required=False,
capacity = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:60px'}), required=False) label='Номер')
capacity = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:60px'}), required=False,
label='Вместимость')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
create dynamical translated fields fields create dynamical translated fields fields
@ -294,11 +296,6 @@ class HallForm(forms.Form):
required = True if lid == 0 else False required = True if lid == 0 else False
self.fields['name_%s' % code] = forms.CharField(label='Название', required=required) self.fields['name_%s' % code] = forms.CharField(label='Название', required=required)
def clean_number(self):
cleaned_data = super(HallForm, self).clean()
number = cleaned_data.get('number').strip()
return is_positive_integer(number, 'Номер должен состоять из цифр')
def clean_capacity(self): def clean_capacity(self):
cleaned_data = super(HallForm, self).clean() cleaned_data = super(HallForm, self).clean()
capacity = cleaned_data.get('capacity').strip() capacity = cleaned_data.get('capacity').strip()
@ -314,6 +311,7 @@ class HallForm(forms.Form):
hall.number = data['number'] hall.number = data['number']
hall.place_exposition = place_exposition hall.place_exposition = place_exposition
fill_with_signal(Hall, hall, data) fill_with_signal(Hall, hall, data)
hall.save()
return hall return hall

@ -27,15 +27,9 @@ def handle_place(place):
place.save() place.save()
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
for place in PlaceExposition.objects.all('en'): for place in PlaceExposition.objects.all('en'):
if place.files.filter(purpose='logo').exists(): if place.files.filter(purpose='logo').exists():
handle_place(place) handle_place(place)
print(place) print(place)

@ -1,99 +1,114 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
import xlrd
from place_exposition.models import PlaceExposition from place_exposition.models import PlaceExposition
import xlrd, xlwt
from import_xls.excel_settings import import_settings, place_exp_sett from import_xls.excel_settings import import_settings, place_exp_sett
from django.conf import settings from django.conf import settings
from import_xls.import_forms import google_address
PLACE_FILE = settings.MEDIA_ROOT+'import/places_ru.xls'
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
f = open(settings.MEDIA_ROOT+'/import/places_ru.xlsx', 'r') f = open(PLACE_FILE, 'r')
book = xlrd.open_workbook(file_contents=f.read()) book = xlrd.open_workbook(file_contents=f.read())
sheet = book.sheet_by_index(0) sheet = book.sheet_by_index(0)
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
labels = [label for label in row_list[0]] labels = [label for label in row_list[0]]
for row_number, row in enumerate(row_list): existing = 0
for row_number, row in enumerate(row_list[1:]):
new = 0
# go through all rows in file # go through all rows in file
if row_number > 0: if row[0] != '':
# first field is label # in first column ids
if row[0] != '':
# in first column ids
try: try:
object = PlaceExposition.objects.language('ru').get(id=int(row[0])) object = PlaceExposition.objects.language('ru').get(id=int(row[0]))
except ValueError: existing += 1
object = PlaceExposition() except ValueError:
object.translate('ru') object = PlaceExposition()
except PlaceExposition.DoesNotExist:
object = PlaceExposition(id= int(row[0]))
object.translate('ru')
else:
# if id blank - its a new place
object = PlaceExposition
object.translate('ru') object.translate('ru')
methods = [] new = 1
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'): except PlaceExposition.DoesNotExist:
if cell != "": object = PlaceExposition(id= int(row[0]))
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')}) object.translate('ru')
continue existing += 1
new = 1
else:
# if id blank - its a new place
object = PlaceExposition
object.translate('ru')
field_name = setting['field']
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
# in function we add language(need for relation fields)
# and extra value from object (like for city need country)
value = func(cell, 'ru', getattr(object, extra_value))
else:
value = func(cell)
#if field_name =='adress':
# setattr(object, 'address', google_address(value))
setattr(object, field_name, value)
object.save()
print('post save %s'% str(object))
"""
try:
print(object)
#object.save()
except IntegrityError: 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 continue
#url = object.url + translit_with_separator(object.city.name)
#object.url = url if setting.get('method'):
#object.save() if cell != "":
""" methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')})
continue
for method in methods:
func = method['func'] field_name = setting['field']
if method.get('purpose'): func = setting.get('func')
try:
func(object, method['value'], method['purpose']) if func is not None:
except: extra_value = setting.get('extra_values')
continue 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)
value = func(cell, 'ru', getattr(object, extra_value))
else:
value = func(cell)
#if field_name =='adress':
# setattr(object, 'address', google_address(value))
if field_name == 'city' and new == 0:
pass
else: else:
try: try:
func(object, method['value']) setattr(object, field_name, value)
except: except ValueError, e:
continue print(value, field_name)
object.save()
print('post save %s'% str(object))
"""
try:
print(object)
#object.save()
except IntegrityError:
continue
#url = object.url + translit_with_separator(object.city.name)
#object.url = url
#object.save()
"""
for method in methods:
func = method['func']
if method.get('purpose'):
try:
func(object, method['value'], method['purpose'])
except:
continue
else:
try:
func(object, method['value'])
except:
continue

@ -78,8 +78,9 @@ class PlaceExposition(TranslatableModel, ExpoMixin):
press_centre = models.NullBooleanField() press_centre = models.NullBooleanField()
mobile_application = models.NullBooleanField() mobile_application = models.NullBooleanField()
# #
logo = models.ImageField(verbose_name='Logo', upload_to=logo_name, blank=True) logo = models.ImageField(verbose_name='Logo', upload_to=logo_name, blank=True, max_length=255)
rating = models.IntegerField(default=0) rating = models.IntegerField(default=0)
partner = models.NullBooleanField(default=0)
# delete after profiling # delete after profiling
files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id') files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id')
@ -255,7 +256,7 @@ class Hall(TranslatableModel):
Create Hall model which saves information about halls in PlaceExposition Create Hall model which saves information about halls in PlaceExposition
""" """
place_exposition = models.ForeignKey(PlaceExposition, related_name='halls') place_exposition = models.ForeignKey(PlaceExposition, related_name='halls')
number = models.PositiveIntegerField(blank=True, null=True) number = models.CharField(blank=True, max_length=6)
capacity = models.PositiveIntegerField(blank=True, null=True) capacity = models.PositiveIntegerField(blank=True, null=True)
translations = TranslatedFields( translations = TranslatedFields(
name = models.CharField(max_length=255, blank=True) name = models.CharField(max_length=255, blank=True)
@ -263,7 +264,42 @@ class Hall(TranslatableModel):
def calculate_rating(place):
rating_simple = {'address': 20, 'phone': 5, 'fax': 5, 'email': 5,
'web_page': 5, 'logo': 20, 'event_in_year': 5, 'total_area': 5, 'closed_area': 5,
'total_pavilions': 5, 'description':15, 'foundation_year': 5, 'total_halls': 5, 'virtual_tour': 5 }
rating_methods = {'theme': 10, 'tag': 5, 'photo':5}
# base rating
rating = 100
for key, value in rating_simple.iteritems():
if getattr(place, key):
rating += value
place.rating = rating
# call to prevent recursion
post_save.disconnect(create_place, sender=PlaceExposition)
place.save()
post_save.connect(create_place, sender=PlaceExposition)
def create_place(sender, instance, created, **kwargs):
post_save_handler(sender, instance=instance, **kwargs)
calculate_rating(instance)
#test #test
pre_save.connect(pre_save_handler, sender=PlaceExposition) pre_save.connect(pre_save_handler, sender=PlaceExposition)
post_save.connect(post_save_handler, sender=PlaceExposition) post_save.connect(create_place, sender=PlaceExposition)
post_save.connect(post_save_handler, sender=Hall) post_save.connect(post_save_handler, sender=Hall)
"""
def calculate_rating_for_translations(sender, instance, created, **kwargs):
company = instance.master
post_save.disconnect(calculate_rating_for_translations, sender=Company._meta.translations_model)
calculate_rating(company)
post_save.connect(calculate_rating_for_translations, sender=Company._meta.translations_model)
post_save.connect(create_company, sender=Company)
post_save.connect(calculate_rating_for_translations, sender=Company._meta.translations_model)
"""

@ -9,18 +9,17 @@ urlpatterns = patterns('',
url(r'search/', PlaceSearchView.as_view()), url(r'search/', PlaceSearchView.as_view()),
# correct # correct
#url(r'country/$', PlaceCountryCatalog.as_view()), #url(r'country/$', PlaceCountryCatalog.as_view()),
url(r'country/(?P<slug>.*)/page/(?P<page>\d+)/$', PlaceCountryCatalog.as_view()), url(r'country/(?P<slug>.*)/page/(?P<page>\d+)/$', PlaceCountryCatalog.as_view(), {'meta_id':49}),
url(r'country/(?P<slug>.*)/$', PlaceCountryCatalog.as_view()), url(r'country/(?P<slug>.*)/$', PlaceCountryCatalog.as_view(), {'meta_id':49}),
# correct # correct
#url(r'expo/city/$', ExpositionByCity.as_view()), #url(r'expo/city/$', ExpositionByCity.as_view()),
url(r'city/(?P<slug>.*)/page/(?P<page>\d+)/$', PlaceCityCatalog.as_view()), url(r'city/(?P<slug>.*)/page/(?P<page>\d+)/$', PlaceCityCatalog.as_view(), {'meta_id':48}),
url(r'city/(?P<slug>.*)/$', PlaceCityCatalog.as_view()), url(r'city/(?P<slug>.*)/$', PlaceCityCatalog.as_view(), {'meta_id':48}),
#!!! #!!!
url(r'(?P<slug>.*)/photo/page/(?P<page>\d+)/$', PlacePhoto.as_view()), url(r'(?P<slug>.*)/photo/page/(?P<page>\d+)/$', PlacePhoto.as_view()),
url(r'(?P<slug>.*)/photo/$', PlacePhoto.as_view()), url(r'(?P<slug>.*)/photo/$', PlacePhoto.as_view()),
#url(r'expo/(?P<slug>.*)/service/(?P<url>.*)/$', ExpositionServiceView.as_view()), #url(r'expo/(?P<slug>.*)/service/(?P<url>.*)/$', ExpositionServiceView.as_view()),
url(r'(?P<slug>.*)/$', PlaceDetail.as_view()), url(r'page/(?P<page>\d+)/$', PlaceList.as_view(), {'meta_id':46}),
url(r'page/(?P<page>\d+)/$', PlaceList.as_view()), url(r'(?P<slug>.*)/$', PlaceDetail.as_view(), {'meta_id':47}),
url(r'$', PlaceList.as_view()), url(r'$', PlaceList.as_view(), {'meta_id':46}),
) )

@ -13,6 +13,10 @@ from place_conference.models import PlaceConference
from country.models import Country from country.models import Country
from city.models import City from city.models import City
from models import PlaceExposition from models import PlaceExposition
from meta.views import MetadataMixin
from django.conf import settings
from functions.cache_mixin import JitterCacheMixin, CacheMixin
def catalog(request): def catalog(request):
expo = list(PlaceExposition.objects.all()) expo = list(PlaceExposition.objects.all())
@ -47,7 +51,8 @@ class PlaceSearchView(ExpoSearchView):
search_form = PlaceSearchForm search_form = PlaceSearchForm
model = PlaceExposition model = PlaceExposition
class PlaceDetail(DetailView): class PlaceDetail(JitterCacheMixin, MetadataMixin, DetailView):
cache_range = settings.CACHE_RANGE
model = PlaceExposition model = PlaceExposition
search_form = PlaceSearchForm search_form = PlaceSearchForm
slug_field = 'url' slug_field = 'url'
@ -97,7 +102,6 @@ class PlaceDetail(DetailView):
class PlacePhoto(ListView): class PlacePhoto(ListView):
template_name = 'client/place/photo.html' template_name = 'client/place/photo.html'
obj = None obj = None
search_form = PlaceSearchForm
def get_queryset(self): def get_queryset(self):
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
@ -115,11 +119,10 @@ class PlacePhoto(ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(PlacePhoto, self).get_context_data(**kwargs) context = super(PlacePhoto, self).get_context_data(**kwargs)
context['object'] = self.obj context['object'] = self.obj
context['search_form'] = self.search_form
return context return context
class PlaceList(ListView): class PlaceList(JitterCacheMixin, MetadataMixin, ListView):
model = PlaceExposition model = PlaceExposition
paginate_by = 10 paginate_by = 10
template_name = 'client/place/place_list.html' template_name = 'client/place/place_list.html'
@ -127,8 +130,8 @@ class PlaceList(ListView):
def get_queryset(self): def get_queryset(self):
lang = translation.get_language() #qs = super(PlaceList, self).get_queryset().order_by('-rating')
qs = super(PlaceList, self).get_queryset().filter(language_code=lang) qs= PlaceExposition.objects.language().select_related('country', 'city').all().order_by('-rating')
conf_qs = PlaceConference.objects.language().all() conf_qs = PlaceConference.objects.language().all()
return list(qs)+list(conf_qs) return list(qs)+list(conf_qs)
@ -138,17 +141,16 @@ class PlaceList(ListView):
return context return context
class PlaceCatalog(ListView): class PlaceCatalog(JitterCacheMixin, MetadataMixin, ListView):
cache_range = settings.CACHE_RANGE
model = PlaceExposition model = PlaceExposition
paginate_by = 10 paginate_by = 10
template_name = 'place/catalog.html' template_name = 'client/place/catalog.html'
search_form = PlaceSearchForm
filter_object = None filter_object = None
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(PlaceCatalog, self).get_context_data(**kwargs) context = super(PlaceCatalog, self).get_context_data(**kwargs)
context['search_form'] = self.search_form
context['filter_object'] = self.filter_object context['filter_object'] = self.filter_object
context['catalog_url'] = self.catalog_url context['catalog_url'] = self.catalog_url
@ -161,9 +163,10 @@ class PlaceCountryCatalog(PlaceCatalog):
def get_queryset(self): def get_queryset(self):
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
country = get_object_or_404(Country, url=slug) country = get_object_or_404(Country, url=slug)
self.kwargs['country'] = country
self.filter_object = country self.filter_object = country
qs = self.model.objects.language().filter(country=country).order_by('-rating') qs = self.model.objects.language().select_related('country', 'city').filter(country=country).order_by('-rating')
conf_qs = PlaceConference.objects.language().filter(country=country) conf_qs = PlaceConference.objects.language().select_related('country', 'city').filter(country=country)
return list(qs) + list(conf_qs) return list(qs) + list(conf_qs)
@ -174,7 +177,8 @@ class PlaceCityCatalog(PlaceCatalog):
def get_queryset(self): def get_queryset(self):
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
city = get_object_or_404(City, url=slug) city = get_object_or_404(City, url=slug)
self.kwargs['city'] = city
self.filter_object = city self.filter_object = city
qs = self.model.objects.language().filter(city=city).order_by('-rating') qs = self.model.objects.language().select_related('country', 'city').filter(city=city).order_by('-rating')
conf_qs = PlaceConference.objects.language().filter(city=city) conf_qs = PlaceConference.objects.language().select_related('country', 'city').filter(city=city)
return list(qs) + list(conf_qs) return list(qs) + list(conf_qs)

@ -9,9 +9,11 @@ from file.models import TmpFile, FileModel
from file.forms import FileModelForm, FileForm from file.forms import FileModelForm, FileForm
from city.models import City from city.models import City
from theme.models import Tag from theme.models import Tag
from article.models import Article
from django.db.models.loading import get_model from django.db.models.loading import get_model
def admin_home(request): def admin_home(request):
return render_to_response('base.html') return render_to_response('base.html')
@ -39,6 +41,24 @@ def ajax_tag(request):
else: else:
#request empty - send empty array #request empty - send empty array
return HttpResponse('[]', content_type='application/json') return HttpResponse('[]', content_type='application/json')
def get_news(request):
"""
return array of tags (id, name) filtered by theme values from request
"""
term = request.GET['term'].capitalize()
if not term:
qs = Article.objects.news()[:50]
else:
qs = Article.objects.news().filter(translations__main_title__contains=term)
result = [{'id': item.id, 'label': item.main_title} for item in qs]
return HttpResponse(json.dumps(result), content_type='application/json')
''' '''
def ajax_post_file(request, obj_id=None): def ajax_post_file(request, obj_id=None):
""" """
@ -159,6 +179,38 @@ def ajax_post_timetable(request, obj_id=None):
else: else:
return HttpResponse('error') return HttpResponse('error')
from exposition.models import Statistic
from exposition.forms import StatisticForm
def ajax_post_stat(request, obj_id=None):
response = {'success': False}
if request.GET:
form = StatisticForm(request.GET)
if form.is_valid():
exp = Exposition.objects.safe_get(id=obj_id)
if exp:
form.save(exp)
response['success'] = True
else:
response.update({'errors': form.errors})
return HttpResponse(json.dumps(response), content_type='application/json')
def ajax_delete_stat(request, id):
redirect_to = request.META.get('HTTP_REFERER')
if id:
try:
Statistic.objects.get(id=id).delete()
except Statistic.DoesNotExist:
pass
return HttpResponseRedirect(redirect_to)
def ajax_delete_timetable(request): def ajax_delete_timetable(request):
if request.GET: if request.GET:

@ -29,6 +29,7 @@ urlpatterns = required(
url(r'^translator/', include('translator.admin_urls')), url(r'^translator/', include('translator.admin_urls')),
url(r'^webinar/', include('webinar.admin_urls')), url(r'^webinar/', include('webinar.admin_urls')),
url(r'^settings/', include('settings.admin_urls')), url(r'^settings/', include('settings.admin_urls')),
url(r'^meta/', include('meta.admin_urls')),
url(r'^language/add/', 'directories.admin.language_add'), url(r'^language/add/', 'directories.admin.language_add'),
url(r'^currency/add/', 'directories.admin.currency_add'), url(r'^currency/add/', 'directories.admin.currency_add'),
# ajax requests # ajax requests
@ -36,6 +37,8 @@ urlpatterns = required(
url(r'^ajax_post_file/', 'proj.admin.ajax_post_file'), url(r'^ajax_post_file/', 'proj.admin.ajax_post_file'),
url(r'^ajax_post_photo/(?P<obj_id>\d+)/$', 'proj.admin.ajax_post_photo'),#must be before /ajax_post_photo/ url(r'^ajax_post_photo/(?P<obj_id>\d+)/$', 'proj.admin.ajax_post_photo'),#must be before /ajax_post_photo/
url(r'^ajax_post_photo/', 'proj.admin.ajax_post_photo'), url(r'^ajax_post_photo/', 'proj.admin.ajax_post_photo'),
url(r'^ajax_post_stat/(?P<obj_id>\d+)/$', 'proj.admin.ajax_post_stat'),
url(r'^ajax_delete_stat/(?P<id>\d+)/', 'proj.admin.ajax_delete_stat'),
url(r'^ajax_post_timetable/(?P<obj_id>\d+)/$', 'proj.admin.ajax_post_timetable'),#must be before /ajax_post_timetable/ url(r'^ajax_post_timetable/(?P<obj_id>\d+)/$', 'proj.admin.ajax_post_timetable'),#must be before /ajax_post_timetable/
url(r'^ajax_post_timetable/', 'proj.admin.ajax_post_timetable'), url(r'^ajax_post_timetable/', 'proj.admin.ajax_post_timetable'),
url(r'^ajax_delete_timetable/', 'proj.admin.ajax_delete_timetable'), url(r'^ajax_delete_timetable/', 'proj.admin.ajax_delete_timetable'),
@ -43,6 +46,7 @@ urlpatterns = required(
url(r'^ajax_delete_file/', 'proj.admin.ajax_delete_file'), url(r'^ajax_delete_file/', 'proj.admin.ajax_delete_file'),
url(r'^ajax_city/', 'proj.admin.ajax_city'), url(r'^ajax_city/', 'proj.admin.ajax_city'),
url(r'^ajax_tag/', 'proj.admin.ajax_tag'), url(r'^ajax_tag/', 'proj.admin.ajax_tag'),
url(r'^ajax/get-news/', 'proj.admin.get_news'),
# #
url(r'^ckeditor/', include('ckeditor.urls')), url(r'^ckeditor/', include('ckeditor.urls')),
url(r'^tinymce/', include('tinymce.urls')), url(r'^tinymce/', include('tinymce.urls')),

@ -1,6 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Django local settings # Django local settings
DEBUG = True # изменить когда будет продакшн DEBUG = False
ALLOWED_HOSTS = ['hit.expomap.ru', '195.66.79.152', '195.66.79.145', 'expomap.ru']
DATABASES = { DATABASES = {
'default': { 'default': {

@ -22,23 +22,27 @@ DATABASES = {
'NAME': 'test2', 'NAME': 'test2',
'USER': 'kotzilla', 'USER': 'kotzilla',
'PASSWORD': 'qazedc', 'PASSWORD': 'qazedc',
'HOST': '', 'HOST': '195.66.79.152',
'PORT': '', 'PORT': '',
} }
} }
'''
CACHES = { CACHES = {
'default': { "default": {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', "BACKEND": "redis_cache.cache.RedisCache",
'LOCATION': '127.0.0.1:11211', "LOCATION": "127.0.0.1:6379:1",
"OPTIONS": {
"CLIENT_CLASS": "redis_cache.client.DefaultClient",
},
} }
} }
'''
# Hosts/domain names that are valid for this site; required if DEBUG is False # Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = [] ALLOWED_HOSTS = ['hit.expomap.ru', '195.66.79.152', '195.66.79.145', 'expomap.ru']
# Local time zone for this installation. Choices can be found here: # Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
@ -71,15 +75,14 @@ USE_I18N = True
# If you set this to False, Django will not format dates, numbers and # If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale. # calendars according to the current locale.
USE_L10N = True USE_L10N = False
# If you set this to False, Django will not use timezone-aware datetimes. # If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True USE_TZ = False
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/" MEDIA_ROOT = os.path.join(SITE_ROOT, 'media/')
MEDIA_ROOT = os.path.join(SITE_ROOT, 'media/')#'/home/kotzilla/Documents/qwer/proj/media/' CKEDITOR_UPLOAD_PATH = os.path.join(SITE_ROOT, 'media/upload')
CKEDITOR_UPLOAD_PATH = os.path.join(SITE_ROOT, 'media/upload')#'/home/kotzilla/Documents/qwer/proj/media/upload'
CKEDITOR_CONFIGS = { CKEDITOR_CONFIGS = {
@ -95,37 +98,13 @@ CKEDITOR_CONFIGS = {
}, },
} }
#TINYMCE_JS_URL = os.path.join(MEDIA_ROOT, "js/tiny_mce/tiny_mce.js")
#TINYMCE_DEFAULT_CONFIG = {
# 'plugins': "table,spellchecker,paste,searchreplace",
# 'theme': "advanced",
# 'cleanup_on_startup': True,
# 'custom_undo_redo_levels': 10,
# 'width' : 565,
# 'height' : 100
#}
#TINYMCE_SPELLCHECKER = True
#TINYMCE_COMPRESSOR = True
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = os.path.join(SITE_ROOT, 'static') STATIC_ROOT = os.path.join(SITE_ROOT, 'static')
# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/' STATIC_URL = '/static/'
# Additional locations of static files
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = ( STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
@ -135,7 +114,7 @@ STATICFILES_FINDERS = (
# Make this unique, and don't share it with anybody. # Make this unique, and don't share it with anybody.
SECRET_KEY = '=yz1@ko%1s8bmel)c84#s*xpxn%4(1e+smdnh*@rdm*5%v!mln' SECRET_KEY = '=yz1@ko%1s8bmel)c84#s*xpxn%4(1e+smdnh*@rdm*5%v!mln'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = ( TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader', 'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader', 'django.template.loaders.app_directories.Loader',
@ -160,8 +139,6 @@ TEMPLATE_CONTEXT_PROCESSORS = (
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
# 'django.middleware.cache.UpdateCacheMiddleware', # 'django.middleware.cache.UpdateCacheMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', 'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
@ -173,7 +150,6 @@ MIDDLEWARE_CLASSES = (
# Uncomment the next line for simple clickjacking protection: # Uncomment the next line for simple clickjacking protection:
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
#'debug_toolbar.middleware.DebugToolbarMiddleware',
) )
@ -187,7 +163,7 @@ TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows. # Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths. # Don't forget to use absolute paths, not relative paths.
os.path.join(SITE_ROOT, 'templates'), # os.path.join(SITE_ROOT, 'templates/debug_toolbar'),
os.path.join(SITE_ROOT, 'templates/admin'), os.path.join(SITE_ROOT, 'templates/admin'),
os.path.join(SITE_ROOT, 'templates/admin/accounts'), os.path.join(SITE_ROOT, 'templates/admin/accounts'),
os.path.join(SITE_ROOT, 'templates/admin/article'), os.path.join(SITE_ROOT, 'templates/admin/article'),
@ -215,6 +191,7 @@ TEMPLATE_DIRS = (
os.path.join(SITE_ROOT, 'templates/client/exposition'), os.path.join(SITE_ROOT, 'templates/client/exposition'),
os.path.join(SITE_ROOT, 'templates/client/photoreport'), os.path.join(SITE_ROOT, 'templates/client/photoreport'),
os.path.join(SITE_ROOT, 'templates/client/includes'), os.path.join(SITE_ROOT, 'templates/client/includes'),
os.path.join(SITE_ROOT, 'templates'),
#os.path.join(SITE_ROOT, 'templates/client/popups'), #os.path.join(SITE_ROOT, 'templates/client/popups'),
) )
@ -223,16 +200,13 @@ LOGIN_URL='/'
#registration info #registration info
ACCOUNT_ACTIVATION_DAYS=2 ACCOUNT_ACTIVATION_DAYS=2
# mail settings # mail settings
EMAIL_USE_TLS = True EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com' EMAIL_HOST = 'localhost'
#EMAIL_HOST = 'localhost' EMAIL_HOST_USER = ''
#EMAIL_HOST_USER = 'kotzilla' EMAIL_HOST_PASSWORD = ''
EMAIL_HOST_USER = 'kotzillla@gmail.com' EMAIL_USE_TLS = False
EMAIL_HOST_PASSWORD = 'fitteR2006!' EMAIL_PORT = 25
DEFAULT_FROM_EMAIL = "expomap.ru"
EMAIL_PORT = 587
#DEFAULT_FROM_EMAIL = 'kotzillla@gmail.com'
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
@ -303,6 +277,7 @@ INSTALLED_APPS = (
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.humanize', 'django.contrib.humanize',
'django.contrib.sitemaps',
'haystack', 'haystack',
#custom modules #custom modules
'accounts', 'accounts',
@ -330,32 +305,27 @@ INSTALLED_APPS = (
'translator', 'translator',
'webinar', 'webinar',
'meta', 'meta',
'banners',
#django modules #django modules
'sorl.thumbnail', 'sorl.thumbnail', # for logos
'photologue', 'photologue', # photogallery
'sortedm2m', 'sortedm2m', # photologue dependence
'hvad', 'hvad', #
'tinymce', 'tinymce', # ???
'ckeditor', 'ckeditor', # wysiwig editor in admin
'django_messages', 'django_messages', # messages
'bitfield', 'bitfield',
'djutils', 'djutils', # ??
'pytils', 'pytils', # ??
'pymorphy', 'pymorphy', # ??
'password_reset', 'password_reset', # reset password
#'social_auth', 'django_crontab', # crons
'social.apps.django_app.default', 'social.apps.django_app.default', # social auth
# 'south',
#'debug_toolbar',
) )
INTERNAL_IPS = ('176.121.5.82',)
DEBUG_TOOLBAR_PATCH_SETTINGS = False
#DEBUG_TOOLBAR_PANELS = (
# 'debug_toolbar.panels.profiling.ProfilingPanel',
#)
PYMORPHY_DICTS = { PYMORPHY_DICTS = {
'ru': { 'dir': '/home/www/proj/settings/russian_dicts' }, 'ru': { 'dir': os.path.join(SITE_ROOT, 'settings/russian_dicts')} #'/home/www/proj/settings/russian_dicts' },
} }
# search backend # search backend
@ -398,18 +368,82 @@ LOGGING = {
} }
} }
THUMBNAIL_DEBUG = True
CRONJOBS = [
('0 */1 * * *', 'django.core.management.call_command', ['update_index conference --age=1']),
('0 */1 * * *', 'django.core.management.call_command', ['update_index exposition --age=1']),
('0 */12 * * *', 'django.core.management.call_command', ['update_index place_exposition --age=12']),
('0 */24 * * *', 'django.core.management.call_command', ['update_index company --age=24']),
('0 */24 * * *', 'django.core.management.call_command', ['update_index theme --age=24']),
('0 */24 * * *', 'django.core.management.call_command', ['update_index tag --age=24']),
]
THUMBNAIL_DEBUG = DEBUG
CALLBACK_EMAIL = 'kotzilla@ukr.net' CALLBACK_EMAIL = 'kotzilla@ukr.net'
BOOKING_AID = '333667' BOOKING_AID = '333667'
"""
ADMIN_PAGINATION = 20
CLIENT_PAGINATION = 15
TEMPLATE_DEBUG = DEBUG
NO_LOGO = '/static/client/img/no-logo.png'
# events settings
CURRENCY = ('RUB', 'USD', 'EUR', 'RMB', 'GBP', 'AED', 'SGD', 'TRY', 'CZK', 'CHF', 'SEK', 'LKR', 'UAH', 'IDR', 'PLN','JPY')
BIT_AUDIENCE = (('experts', _(u'Специалисты')), ('experts and consumers', _(u'Специалисты и потребители')),
('general public', _(u'Широкая публика')))
MONTHES = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')},
'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')},
'may': {'value': 5, 'name': _(u'Май')}, 'jun': {'value': 6, 'name': _(u'Июнь')},
'jul': {'value': 7, 'name': _(u'Июль')}, 'aug': {'value': 8, 'name': _(u'Август')},
'sep': {'value': 9, 'name': _(u'Сентябрь')}, 'oct': {'value': 10, 'name': _(u'Октябрь')},
'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}}
SNG_COUNTRIES = [159, 186, 31, 6, 99, 13, 189, 64]
# cache pages in random seconds. random in this range
CACHE_RANGE = [60, 120]
try: try:
from local import * from local import *
except ImportError, e: except ImportError, e:
from production import * pass
# debug_toolbar settings
""" """
ADMIN_PAGINATION = 20 if DEBUG:
CLIENT_PAGINATION = 15 DEBUG_TOOLBAR_PATCH_SETTINGS = False
TEMPLATE_DEBUG = DEBUG INTERNAL_IPS = ('127.0.0.1','176.121.5.82', '176.121.11.162', '77.123.47.46')
MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
INSTALLED_APPS += (
'debug_toolbar',
)
JQUERY_URL = os.path.join(SITE_ROOT, 'static/client/js/jquery-ui-1.10.4.custom.min.js'),
DEBUG_TOOLBAR_PANELS = [
#'debug_toolbar.panels.versions.VersionsPanel',
#'debug_toolbar.panels.timer.TimerPanel',
#'debug_toolbar.panels.settings.SettingsPanel',
#'debug_toolbar.panels.headers.HeadersPanel',
#'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLPanel',
#'debug_toolbar.panels.staticfiles.StaticFilesPanel',
#'debug_toolbar.panels.templates.TemplatesPanel',
#'debug_toolbar.panels.cache.CachePanel',
#'debug_toolbar.panels.signals.SignalsPanel',
#'debug_toolbar.panels.logging.LoggingPanel',
#'debug_toolbar.panels.redirects.RedirectsPanel',
]
#DEBUG_TOOLBAR_CONFIG = {
# 'INTERCEPT_REDIRECTS': False,
#}
"""

@ -0,0 +1,141 @@
import datetime
from django.contrib.sitemaps import Sitemap
from exposition.models import Exposition
from conference.models import Conference
from city.models import City
from country.models import Country
from theme.models import Theme, Tag
from article.models import Article
from django.core.urlresolvers import reverse
from django.core.paginator import Paginator
class Abstract(Sitemap):
changefreq = 'weekly'
priority = 0.8
def lastmod(self, obj):
return datetime.date.today()
class ExpoCard(Abstract):
changefreq = 'weekly'
priority = 0.8
def items(self):
return Exposition.enable.upcoming()
def lastmod(self, obj):
return obj.modified
class ExpoCity(Abstract):
def items(self):
return City.used.expo_cities()
def location(self, obj):
return "/expo/city/%s/" % obj.url
class ExpoCountry(Abstract):
def items(self):
return Country.objects.expo_countries()
def location(self, obj):
return "/expo/country/%s/" % obj.url
class ExpoTheme(Abstract):
def items(self):
return Theme.active.expo_themes()
def location(self, obj):
return "/expo/theme/%s/" % obj.url
class ExpoTag(Abstract):
def items(self):
return Tag.active.expo_tag()
def location(self, obj):
return "/expo/tag/%s/" % obj.url
class ConfCard(Sitemap):
changefreq = 'weekly'
priority = 0.8
def items(self):
return Conference.enable.upcoming()
def lastmod(self, obj):
return obj.modified
def location(self, obj):
return "/conference/%s/" % obj.url
class ConfCity(Abstract):
def items(self):
return City.used.conference_cities()
def location(self, obj):
return "/conference/city/%s/" % obj.url
class ConfCountry(Abstract):
def items(self):
return Country.objects.conference_countries()
def location(self, obj):
return "/conference/country/%s/" % obj.url
class ConfTheme(Abstract):
def items(self):
return Theme.active.conference_themes_with_count()
def location(self, obj):
return "/conference/theme/%s/" % obj.url
class ConfTag(Abstract):
def items(self):
return Tag.active.conference_tags()
def location(self, obj):
return "/conference/tag/%s/" % obj.url
class NewsSiteMap(Abstract):
priority = 0.5
def items(self):
return Article.objects.news().filter(publish_date__isnull=False)
def location(self, obj):
return "/news/%s/" % obj.slug
class BlogsSiteMap(Abstract):
priority = 0.5
def items(self):
return Article.objects.blogs().filter(publish_date__isnull=False)
def location(self, obj):
return "/blogs/%s/" % obj.slug
class SimpleAbstract(Sitemap):
priority = 0.5
def location(self, item):
return item
class Important(SimpleAbstract):
priority = 1
def items(self):
return ['', '/expo/', '/conference/', '/conference/country/', '/conference/city/', '/conference/theme/',
'/expo/theme/', '/expo/country/', '/expo/city/']
class Additional(SimpleAbstract):
priority = 0.5
def items(self):
return ['/blogs/', '/news/', '/partners/', '/about/', '/advertising/', '/contacts/']

@ -1,23 +1,44 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf import settings from django.conf import settings
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from core.views import PlaceListView, PlacePhotoView, EventSearchView
from core.simple_index_view import AdvertisingView, AboutView from core.simple_index_view import AdvertisingView, AboutView
from views import MainPageView, MainPageViewTest from views import MainPageView
from place_exposition.views import PlaceSearchView from django.contrib.sitemaps import views
import debug_toolbar
from django.views.generic.base import TemplateView
from django.http import HttpResponse class Robot(TemplateView):
template_name = 'robots.txt'
content_type = 'text/plain'
from django.contrib.sitemaps import Sitemap
from exposition.models import Exposition
from sitemaps import ExpoCard, ExpoCity, ExpoCountry, ExpoTheme, ExpoTag, ConfCard, ConfCity, ConfCountry, ConfTheme,\
ConfTag, NewsSiteMap, BlogsSiteMap, Additional, Important
sitemaps = {
'expo_card': ExpoCard(), 'news': NewsSiteMap(), 'blogs': BlogsSiteMap(), 'expo_city': ExpoCity(), \
'expo_country': ExpoCountry(), 'expo_theme': ExpoTheme(), \
'conference_card': ConfCard(), 'expo_tag': ExpoTag(), 'conference_city': ConfCity(), 'conference_country': ConfCountry(),\
'conference_theme': ConfTheme(), 'conference_tag': ConfTag(), 'main': Important(), 'additional': Additional()
}
urlpatterns = patterns('', urlpatterns = patterns('',
#url(r'^__debug__/', include(debug_toolbar.urls)),
url(r'^admin/', include('proj.admin_urls')), url(r'^admin/', include('proj.admin_urls')),
#url(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
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'^$', MainPageView.as_view()), url(r'^$', MainPageView.as_view()),
url(r'^main_page/$', MainPageViewTest.as_view()),
url(r'^theme/', include('theme.urls')), url(r'^theme/', include('theme.urls')),
url(r'^places/', include('place_exposition.urls')), url(r'^places/', include('place_exposition.urls')),
url(r'^', include('accounts.urls')), url(r'^', include('accounts.urls')),
url(r'^', include('exposition.urls')), url(r'^', include('exposition.urls')),
url(r'^', include('settings.conference_old_urls')), # conference redirects from old version
url(r'^', include('conference.urls')), url(r'^', include('conference.urls')),
url(r'^', include('seminar.urls')), url(r'^', include('seminar.urls')),
url(r'^', include('webinar.urls')), url(r'^', include('webinar.urls')),
@ -28,47 +49,30 @@ urlpatterns = patterns('',
url(r'^city/', include('city.urls')), url(r'^city/', include('city.urls')),
url(r'^organiser/', include('organiser.urls')), url(r'^organiser/', include('organiser.urls')),
url(r'^gallery/', include('photologue.client_urls')), url(r'^gallery/', include('photologue.client_urls')),
url(r'^', include('file.urls')), url(r'^', include('file.urls')),
url(r'^', include('django_messages.expomap_urls')), url(r'^', include('django_messages.expomap_urls')),
url(r'^messages/', include('django_messages.urls')), url(r'^messages/', include('django_messages.urls')),
url(r'^advertising/$', AdvertisingView.as_view(), {'meta_id':58}),
url(r'^advertising/$', AdvertisingView.as_view()), url(r'^about/$', AboutView.as_view(), {'meta_id':56}),
url(r'^about/$', AboutView.as_view()), url(r'^partners/$', AboutView.as_view(), {'meta_id':57}),
url(r'^partners/$', AboutView.as_view()), url(r'^contacts/$', AboutView.as_view(), {'meta_id':59}),
url(r'^contacts/$', AboutView.as_view()),
#url(r'^events/search/$', EventSearchView.as_view()),
#url(r'^places/search/$', PlaceSearchView.as_view()),
#url(r'^places/(?P<params>.*)/photo/(?P<page>\d+)/$', PlacePhotoView.as_view()),
#url(r'^places/(?P<params>.*)/photo/$', PlacePhotoView.as_view()),
#url(r'^places/(?P<params>.*)/(?P<page>\d+)/$', PlaceListView.as_view()),
#url(r'^places/(?P<page>\d+)/$', PlaceListView.as_view()),
#url(r'^places/(?P<params>.*)/$', PlaceListView.as_view()),
#url(r'^places/$', PlaceListView.as_view()),
url(r'^social/', include('social.apps.django_app.urls', namespace='social')), url(r'^social/', include('social.apps.django_app.urls', namespace='social')),
url(r'^login/', 'registration.backends.default.views.LoginView'), url(r'^login/', 'registration.backends.default.views.LoginView'),
url(r'^logout/', 'registration.backends.default.views.LogoutView'), url(r'^logout/', 'registration.backends.default.views.LogoutView'),
#url(r'^profile/$', 'accounts.views.profile'),
url(r'^accounts/', include('registration.backends.default.urls')), url(r'^accounts/', include('registration.backends.default.urls')),
#url(r'^places/$', 'place_exposition.views.catalog'),
#url(r'^places/(?P<url>.*)/(?P<photo>photo)', 'place_exposition.views.place'),
#url(r'^places/(?P<url>.*)', 'place_exposition.views.place'),
#url(r'^company/(?P<url>.*)', 'core.views.company'),
url(r'^', include('password_reset.urls')), url(r'^', include('password_reset.urls')),
url(r'^i18n/', include('django.conf.urls.i18n')), url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^redirect/', include('banners.urls')),
#url(r'^social/', include('social_auth.urls')), #url(r'^social/', include('social_auth.urls')),
url(r'^', include('settings.old_urls')),
#url(r'^search/', include('haystack.urls')),
# admin part
url(r'^search/', include('haystack.urls')),
url(r'^', include('service.urls')), url(r'^', include('service.urls')),
) )
# ajax urls # ajax urls
urlpatterns += patterns('', urlpatterns += patterns('',
url(r'^registration/reply/$', 'registration.backends.default.views.RegisterReply'),
url(r'^register/', 'registration.backends.default.views.RegisterAjaxView'), url(r'^register/', 'registration.backends.default.views.RegisterAjaxView'),
url(r'^register-complete/', 'registration.backends.default.views.complete_registration'), url(r'^register-complete/', 'registration.backends.default.views.complete_registration'),
url(r'^callback/', 'core.simple_index_view.callback'), url(r'^callback/', 'core.simple_index_view.callback'),
@ -78,17 +82,13 @@ urlpatterns += patterns('',
url(r'^search-form/autosearch/exposition/$', 'settings.views.expo_autosearch'), url(r'^search-form/autosearch/exposition/$', 'settings.views.expo_autosearch'),
url(r'^search-form/autosearch/place/$', 'settings.views.place_autosearch'), url(r'^search-form/autosearch/place/$', 'settings.views.place_autosearch'),
url(r'^search-form/autosearch/company/$', 'settings.views.company_autosearch'), url(r'^search-form/autosearch/company/$', 'settings.views.company_autosearch'),
url(r'^', include('settings.old_urls')),
url(r'^', include('accounts.user_catalog_urls')), url(r'^', include('accounts.user_catalog_urls')),
) )
"""
if settings.DEBUG: if settings.DEBUG:
import debug_toolbar import debug_toolbar
urlpatterns += patterns('', urlpatterns += patterns('',
url(r'^__debug__/', include(debug_toolbar.urls)), url(r'^__debug__/', include(debug_toolbar.urls)),
) )
"""

@ -8,6 +8,7 @@ from exposition.models import Exposition
from theme.models import Theme from theme.models import Theme
from news.models import News from news.models import News
from article.models import Article from article.models import Article
from functions.cache_mixin import JitterCacheMixin, CacheMixin
from functions.forms import ThemeSearch, PlaceSearch from functions.forms import ThemeSearch, PlaceSearch
@ -16,62 +17,37 @@ from functions.custom_views import ExpoListView
from accounts.forms import RegistrationCompleteForm from accounts.forms import RegistrationCompleteForm
def expo_context(request): def expo_context(request):
cont = {'theme_search_form': ThemeSearch(), 'search_form': ExpositionSearchForm(), 'expo_catalog': Exposition.catalog, cont = {'theme_search_form': ThemeSearch(), 'expo_catalog': Exposition.catalog,
'book_aid': settings.BOOKING_AID} 'book_aid': settings.BOOKING_AID, 'blogs': Article.objects.main_page_blogs(),
'news_list': Article.objects.main_page_news(), 'sng_countries': settings.SNG_COUNTRIES
}
user = request.user user = request.user
if not user.is_anonymous() and not user.url: if not user.is_anonymous() and not user.url:
cont.update({'reg_complete': RegistrationCompleteForm(instance=user)}) cont.update({'reg_complete': RegistrationCompleteForm(instance=user)})
if not request.GET:
cont.update({'search_form': ExpositionSearchForm()})
return cont return cont
class MainPageView(TemplateView): class MainPageView(JitterCacheMixin,TemplateView):
cache_range = settings.CACHE_RANGE
template_name = 'index.html' template_name = 'index.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(MainPageView, self).get_context_data(**kwargs) context = super(MainPageView, self).get_context_data(**kwargs)
events = Exposition.objects.all().order_by('-main_page')[:5]
exposition_themes = Theme.objects.order_by('-main_page').filter(types=Theme.types.exposition)[:6]
conference_themes = Theme.objects.order_by('-main_page').filter(types=Theme.types.conference)[:6]
seminar_themes = Theme.objects.order_by('-main_page').filter(types=Theme.types.seminar)[:6]
news_list = News.objects.order_by('-main_page').all()[:3]
articles = Article.objects.order_by('-main_page').all()[:2]
args = {'events': events, 'exposition_themes': exposition_themes, events = Exposition.objects.language().select_related('country', 'city', 'place').filter(main_page=1)
'conference_themes': conference_themes, 'seminar_themes': seminar_themes, exposition_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.exposition)[:6]
'news_list': news_list, 'articles': articles, 'search_form': EventSearchForm, conference_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.conference)[:6]
'search_action': '/events/search/'}
args = {'events': events, 'exposition_themes': exposition_themes, 'conference_themes': conference_themes,
'search_form': ExpositionSearchForm, 'search_action': '/expo/search/'}
context.update(args) context.update(args)
return context return context
class MainPageViewTest(TemplateView):
template_name = 'client/main_page.html'
def get_context_data(self, **kwargs):
context = super(MainPageViewTest, self).get_context_data(**kwargs)
events = Exposition.objects.all().order_by('-main_page')[:5]
exposition_themes = Theme.objects.order_by('-main_page').filter(types=Theme.types.exposition)[:6]
conference_themes = Theme.objects.order_by('-main_page').filter(types=Theme.types.conference)[:6]
seminar_themes = Theme.objects.order_by('-main_page').filter(types=Theme.types.seminar)[:6]
news_list = News.objects.order_by('-main_page').all()[:3]
articles = Article.objects.order_by('-main_page').all()[:2]
args = {'events': events, 'exposition_themes': exposition_themes,
'conference_themes': conference_themes, 'seminar_themes': seminar_themes,
'news_list': news_list, 'articles': articles}
context.update(args)
return context
class AdvertisingView(TemplateView): class AdvertisingView(TemplateView):
template_name = 'simple_pages/advertising.html' template_name = 'simple_pages/advertising.html'

@ -2,6 +2,7 @@
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import RequestSite from django.contrib.sites.models import RequestSite
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.utils.translation import ugettext as _
from registration import signals from registration import signals
from registration.models import RegistrationProfile from registration.models import RegistrationProfile
@ -34,7 +35,7 @@ class RegistrationView(BaseRegistrationView):
* The creation of the templates * The creation of the templates
``registration/activation_email_subject.txt`` and ``registration/activation_email_subject.txt`` and
``registration/activation_email.txt``, which will be used for ``registration/activation_email.html``, which will be used for
the activation email. See the notes for this backends the activation email. See the notes for this backends
``register`` method for details regarding these templates. ``register`` method for details regarding these templates.
@ -187,6 +188,35 @@ def RegisterAjaxView(request):
# 404 # 404
# return HttpResponse('not ajax') # return HttpResponse('not ajax')
def RegisterReply(request):
if request.GET:
email = request.GET['email']
try:
user = User.objects.get(username=email)
except User.DoesNotExist:
response = {'errors': {'email': _(u'Пользователя с таким email не существует')}}
return HttpResponse(json.dumps(response), content_type='application/json')
if user.is_active:
response = {'errors': {'email': _(u'Пользователя с таким email уже активирован')}}
return HttpResponse(json.dumps(response), content_type='application/json')
else:
try:
registration_profile = user.registrationprofile_set.all()[0]
except IndexError:
registration_profile = RegistrationProfile.create_profile(user)
if Site._meta.installed:
site = Site.objects.get_current()
else:
site = RequestSite(request)
registration_profile.send_activation_email(site)
response = {'success': True}
return HttpResponse(json.dumps(response), content_type='application/json')
else:
return HttpResponse('no data')
from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import AuthenticationForm
from registration.forms import LoginForm from registration.forms import LoginForm
@ -199,7 +229,7 @@ def LogoutView(request):
def LoginView(request): def LoginView(request):
if request.POST: if request.POST:
form = AuthenticationForm(data=request.POST) form = LoginForm(data=request.POST)
#return HttpResponse(form.username) #return HttpResponse(form.username)
@ -210,6 +240,8 @@ def LoginView(request):
#return HttpResponseRedirect(request.META.get('HTTP_REFERER','/')) #return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
else: else:
response={'success':False, 'errors': form.errors} response={'success':False, 'errors': form.errors}
if getattr(form, 'inactive', None):
response.update({'inactive': True})
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
@ -222,8 +254,9 @@ def complete_registration(request):
response = {'success': False} response = {'success': False}
form = RegistrationCompleteForm(request.POST, instance=request.user) form = RegistrationCompleteForm(request.POST, instance=request.user)
if form.is_valid(): if form.is_valid():
form.save() user = form.save()
response['success']=True response['success']=True
response['redirect'] = user.get_permanent_url()
else: else:
response['errors'] = form.errors response['errors'] = form.errors
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')

@ -127,6 +127,33 @@ class RegistrationFormNoFreeEmail(RegistrationForm):
raise forms.ValidationError(_("Registration using free email addresses is prohibited. Please supply a different email address.")) raise forms.ValidationError(_("Registration using free email addresses is prohibited. Please supply a different email address."))
return self.cleaned_data['email'] return self.cleaned_data['email']
from django.contrib.auth import authenticate
class LoginForm(AuthenticationForm): class LoginForm(AuthenticationForm):
username = forms.CharField(max_length=254, widget=forms.TextInput(attrs={'placeholder': _(u'Ваш адрес электронной почты')})) inactive = False
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput(attrs={'placeholder': _(u'Ваш Пароль')})) def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
data = self.cleaned_data
if username and password:
self.user_cache = authenticate(username=username,
password=password)
if self.user_cache is None:
self._errors['password'] = ErrorList([self.error_messages['invalid_login'] % {
'username': self.username_field.verbose_name
}])
del data['password']
elif not self.user_cache.is_active:
self._errors['username'] = ErrorList([self.error_messages['inactive']])
self.inactive = True
del data['username']
self.check_for_test_cookie()
return data

@ -2,13 +2,15 @@ import datetime
import hashlib import hashlib
import random import random
import re import re
from django.core.mail import EmailMessage
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models from django.db import models
from django.db import transaction from django.db import transaction
from django.template.loader import render_to_string from django.template.loader import render_to_string, get_template
from django.template import Context
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from email.MIMEImage import MIMEImage
try: try:
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
@ -232,7 +234,7 @@ class RegistrationProfile(models.Model):
text; output longer than one line will be forcibly joined text; output longer than one line will be forcibly joined
into only a single line. into only a single line.
``registration/activation_email.txt`` ``registration/activation_email.html``
This template will be used for the body of the email. This template will be used for the body of the email.
These templates will each receive the following context These templates will each receive the following context
@ -256,15 +258,33 @@ class RegistrationProfile(models.Model):
framework for details regarding these objects' interfaces. framework for details regarding these objects' interfaces.
""" """
user = self.user
ctx_dict = {'activation_key': self.activation_key, ctx_dict = {'activation_key': self.activation_key,
'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
'site': site} 'site': site,
'user': user}
subject = render_to_string('registration/activation_email_subject.txt', subject = render_to_string('registration/activation_email_subject.txt',
ctx_dict) ctx_dict)
# Email subject *must not* contain newlines # Email subject *must not* contain newlines
subject = ''.join(subject.splitlines()) subject = ''.join(subject.splitlines())
message = get_template('registration/activation_email.html').render(Context(ctx_dict))
msg = EmailMessage(subject, message, settings.DEFAULT_FROM_EMAIL, [user.email])
msg.content_subtype = "html"
images =(('/img/logo_reg.png', 'logo'),
('/img/soc-medias/sm-icon-rss.png', 'rss'),
('/img/soc-medias/sm-icon-fb.png', 'fb'),
('/img/soc-medias/sm-icon-lin.png', 'linkedin'),
('/img/soc-medias/sm-icon-vk.png', 'vk'),
('/img/soc-medias/sm-icon-twit.png', 'twit'),
('/img/mail-logo-2.jpg','logo2'))
for img in images:
fp = open(settings.STATIC_ROOT+img[0], 'rb')
msg_img = MIMEImage(fp.read())
fp.close()
msg_img.add_header('Content-ID', '<'+img[1]+'>')
msg.attach(msg_img)
msg.send()
message = render_to_string('registration/activation_email.txt', #self.user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
ctx_dict)
self.user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)

@ -28,16 +28,15 @@ class ServiceForm(forms.Form):
url = forms.CharField(label='url', required=False) url = forms.CharField(label='url', required=False)
price = forms.IntegerField(label='Цена', required=False, price = forms.IntegerField(label='Цена', required=False,
widget=forms.TextInput(attrs={'placeholder':'Валюта'})) widget=forms.TextInput(attrs={'placeholder':'Валюта'}))
#price = forms.CharField(label='Цена', required=False, #price = forms.CharField(label='Цена', required=False,
# widget=forms.TextInput(attrs={'placeholder':'Валюта'})) # widget=forms.TextInput(attrs={'placeholder':'Валюта'}))
currency_list = [('USD','USD'), ('EUR','EUR'), ('RUB','RUB')] currency_list = [('USD','USD'), ('EUR','EUR'), ('RUB','RUB')]
currency = forms.ChoiceField(choices=currency_list) currency = forms.ChoiceField(choices=currency_list)
type = forms.MultipleChoiceField(label='Тип', choices=[('expo', 'expo'), ('conference', 'conference')])
service_id = forms.CharField(required=False, widget=forms.HiddenInput()) service_id = forms.CharField(required=False, widget=forms.HiddenInput())
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(ServiceForm, self).__init__(*args, **kwargs) super(ServiceForm, self).__init__(*args, **kwargs)
# creates translated form fields, example: name_ru, name_en # creates translated form fields, example: name_ru, name_en
@ -76,6 +75,8 @@ class ServiceForm(forms.Form):
service.price = data['price'] service.price = data['price']
service.currency = data['currency'] service.currency = data['currency']
#data['type']
fill_with_signal(Service, service, data) fill_with_signal(Service, service, data)

@ -2,9 +2,10 @@
from django.db import models from django.db import models
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from functions.custom_fields import EnumField from functions.custom_fields import EnumField
from bitfield import BitField
CURENCIES = ('USD', 'RUB', 'EUR') CURENCIES = ('', 'USD', 'RUB', 'EUR')
@ -12,12 +13,12 @@ CURENCIES = ('USD', 'RUB', 'EUR')
class Service(TranslatableModel): class Service(TranslatableModel):
url = models.SlugField(unique=True) url = models.SlugField(unique=True)
currency = EnumField(values=CURENCIES, blank=True, default='USD') currency = EnumField(values=CURENCIES, blank=True, default='USD')
price = models.PositiveIntegerField(blank=True, null=True) price = models.PositiveIntegerField(blank=True, null=True)
params = models.CharField(max_length=255, blank=True) params = models.CharField(max_length=255, blank=True)
template = models.CharField(max_length=255, blank=True) template = models.CharField(max_length=255, blank=True)
type = BitField(flags=['expo', 'conference'])
#translated fields #translated fields
translations = TranslatedFields( translations = TranslatedFields(
name = models.CharField(max_length=50), name = models.CharField(max_length=50),
@ -31,6 +32,7 @@ class Service(TranslatableModel):
) )
sort = models.PositiveIntegerField(default=0, db_index=True) sort = models.PositiveIntegerField(default=0, db_index=True)
main_page = models.PositiveIntegerField(default=0, db_index=True) main_page = models.PositiveIntegerField(default=0, db_index=True)
meta_id = models.IntegerField(null=True)
def __unicode__(self): def __unicode__(self):
@ -65,15 +67,20 @@ class AbstractOrder(models.Model):
exposition = models.ForeignKey('exposition.Exposition', null=True) exposition = models.ForeignKey('exposition.Exposition', null=True)
conference = models.ForeignKey('conference.Conference', null=True) conference = models.ForeignKey('conference.Conference', null=True)
seminar = models.ForeignKey('seminar.Seminar', null=True) seminar = models.ForeignKey('seminar.Seminar', null=True)
created = models.DateTimeField(auto_now_add=True)
viewed = models.DateTimeField(null=True, blank=True)
class Meta: class Meta:
abstract = True abstract = True
ordering = ['-created']
class Catalog(AbstractOrder): class Catalog(AbstractOrder):
pass pass
class BuildStand(AbstractOrder):
pass
class Tickets(AbstractOrder): class Tickets(AbstractOrder):
days = models.SmallIntegerField() days = models.SmallIntegerField()
@ -81,7 +88,7 @@ class Tickets(AbstractOrder):
class Remote(AbstractOrder): class Remote(AbstractOrder):
interested_participants = models.TextField(blank=True) interested_participants = models.TextField(blank=True)
additional = models.CharField(max_length=255) additional = models.CharField(max_length=255, blank=True)
class Participation(AbstractOrder): class Participation(AbstractOrder):
@ -90,12 +97,12 @@ class Participation(AbstractOrder):
company_inf = models.TextField() company_inf = models.TextField()
class Translation(AbstractOrder): class Translation(AbstractOrder):
days = models.IntegerField() days = models.IntegerField(null=True,blank=True)
hours = models.IntegerField() hours = models.IntegerField(null=True, blank=True)
fr = models.DateField() fr = models.DateField(blank=True)
to = models.DateField() to = models.DateField(blank=True)
languages = models.TextField() languages = models.TextField(blank=True)
themes = models.TextField() themes = models.TextField(blank=True)
class Visit(AbstractOrder): class Visit(AbstractOrder):
fr = models.DateField() fr = models.DateField()
@ -122,3 +129,15 @@ class Visit(AbstractOrder):
excursion = models.BooleanField() excursion = models.BooleanField()
notes = models.TextField(blank=True) notes = models.TextField(blank=True)
class Advertising(AbstractOrder):
pass
class CallBack(models.Model):
phone = models.CharField(max_length=30)
person_inf = models.CharField(max_length=255)
created = models.DateTimeField(auto_now_add=True)
viewed = models.DateTimeField(null=True, blank=True)
class Meta:
ordering = ['-created']

@ -2,7 +2,7 @@
from django import forms from django import forms
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from accounts.models import User from accounts.models import User
from models import Catalog, Tickets, Remote, Participation, Translation, Visit, CURENCIES from models import Catalog, Tickets, Remote, Participation, Translation, Visit, CURENCIES, Advertising, CallBack, BuildStand
from exposition.models import Exposition from exposition.models import Exposition
from conference.models import Conference from conference.models import Conference
from seminar.models import Seminar from seminar.models import Seminar
@ -15,7 +15,7 @@ class AbstractOrderForm(forms.ModelForm):
phone = forms.CharField(widget=forms.TextInput(attrs={'placeholder': _(u'Контактный номер телефона')})) phone = forms.CharField(widget=forms.TextInput(attrs={'placeholder': _(u'Контактный номер телефона')}))
person = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': _(u'Электронная почта')})) person = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': _(u'Электронная почта')}))
currency = forms.CharField(widget=forms.HiddenInput()) currency = forms.CharField(widget=forms.HiddenInput(), required=False)
exposition = forms.CharField(widget=forms.HiddenInput(), required=False) exposition = forms.CharField(widget=forms.HiddenInput(), required=False)
conference = forms.CharField(widget=forms.HiddenInput(), required=False) conference = forms.CharField(widget=forms.HiddenInput(), required=False)
@ -89,6 +89,10 @@ class CatalogForm(AbstractOrderForm):
class Meta: class Meta:
model = Catalog model = Catalog
class BuildStandForm(AbstractOrderForm):
class Meta:
model = BuildStand
class TicketsForm(AbstractOrderForm): class TicketsForm(AbstractOrderForm):
class Meta: class Meta:
@ -101,7 +105,7 @@ ADDITIONAL_REMOTE_CHOICES = [(_(u'официальный каталог'), _(u'
] ]
class RemoteForm(AbstractOrderForm): class RemoteForm(AbstractOrderForm):
additional = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), choices=ADDITIONAL_REMOTE_CHOICES) additional = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), choices=ADDITIONAL_REMOTE_CHOICES, required=False)
class Meta: class Meta:
model = Remote model = Remote
@ -126,12 +130,10 @@ LANGS = [(_(u'Русский'), _(u'Русский'))]
from theme.models import Theme from theme.models import Theme
class TranslationForm(AbstractOrderForm): class TranslationForm(AbstractOrderForm):
languages = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), languages = forms.CharField(required=False)
choices=LANGS) themes = forms.CharField(required=False)
themes = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), fr = forms.DateField(widget=forms.DateInput(attrs={'class': 'date dateFrom', 'placeholder': _(u'дд.мм.гггг')}), required=False)
choices=[(theme.id, theme.id) for theme in Theme.objects.language().filter()]) to = forms.DateField(widget=forms.DateInput(attrs={'class': 'date dateTo', 'placeholder': _(u'дд.мм.гггг')}), required=False)
fr = forms.DateField(widget=forms.DateInput(attrs={'class': 'date dateFrom', 'placeholder': _(u'дд.мм.гггг')}))
to = forms.DateField(widget=forms.DateInput(attrs={'class': 'date dateTo', 'placeholder': _(u'дд.мм.гггг')}))
class Meta: class Meta:
model = Translation model = Translation
@ -195,4 +197,14 @@ class VisitForm(AbstractOrderForm):
if not avia_type: if not avia_type:
return '' return ''
else: else:
return ', '.join(avia_type) return ', '.join(avia_type)
class AdvertiseForm(AbstractOrderForm):
action = '/service/com_rek/'
class Meta:
model = Advertising
class CallBackForm(forms.ModelForm):
class Meta:
model = CallBack
fields=('phone', 'person_inf')

@ -1,8 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from views import ServiceView from views import ServiceView, CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \
ParticipationListView, RemoteListView,TicketsListView, Thanks
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'service/thanks/$', Thanks.as_view()),
url(r'service/order/callback/$', CallBackListView.as_view()),
url(r'service/order/visit/$', VisitListView.as_view()),
url(r'service/order/translation/$', TranslationListView.as_view()),
url(r'service/order/advertising/$', AdvertisingListView.as_view()),
url(r'service/order/participation/$', ParticipationListView.as_view()),
url(r'service/order/remote/$', RemoteListView.as_view()),
url(r'service/order/tickets/$', TicketsListView.as_view()),
url(r'service/com_rek/$', 'service.views.advertise'),
url(r'service/(?P<url>.*)/$', ServiceView.as_view()), url(r'service/(?P<url>.*)/$', ServiceView.as_view()),
) )

@ -7,13 +7,14 @@ from haystack.query import EmptySearchQuerySet
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.http import Http404 from django.http import Http404
import json import json
from functions.search_forms import CompanySearchForm #from functions.search_forms import CompanySearchForm
from order_forms import TranslationForm, CatalogForm, VisitForm, RemoteForm, ParticipationForm, TicketsForm from order_forms import TranslationForm, CatalogForm, VisitForm, RemoteForm, ParticipationForm, TicketsForm,\
AdvertiseForm, BuildStandForm
order_forms = {'translator': TranslationForm, 'catalog': CatalogForm, 'participation': ParticipationForm, order_forms = {'translator': TranslationForm, 'catalog': CatalogForm, 'participation': ParticipationForm,
'remote': RemoteForm, 'tickets': TicketsForm, 'visit': VisitForm} 'remote': RemoteForm, 'tickets': TicketsForm, 'visit': VisitForm, 'buildstand': BuildStandForm}
class ServiceView(FormView): class ServiceView(FormView):
@ -34,3 +35,51 @@ class ServiceView(FormView):
return service.template return service.template
def advertise(request):
if request.POST:
response = {'success': False}
form = AdvertiseForm(request.POST)
if form.is_valid():
form.save()
response['success'] = True
else:
response['errors'] = form.errors
return HttpResponse(json.dumps(response), content_type='application/json')
else:
raise HttpResponse('not ajax')
from service.models import CallBack, Visit, Translation, Advertising, Participation, Remote, Tickets
class AbstractOrderListView(ListView):
template_name = 'admin/service/order_list.html'
paginate_by = 20
class CallBackListView(AbstractOrderListView):
model = CallBack
class VisitListView(AbstractOrderListView):
model = Visit
class TranslationListView(AbstractOrderListView):
model = Translation
class AdvertisingListView(AbstractOrderListView):
model = Advertising
class ParticipationListView(AbstractOrderListView):
model = Participation
class RemoteListView(AbstractOrderListView):
model = Remote
class TicketsListView(AbstractOrderListView):
model = Tickets
class Thanks(TemplateView):
template_name = 'client/service/thank_u_page.html'

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

Loading…
Cancel
Save