Merged from develop

remotes/origin/1203
Nazar Kotjuk 10 years ago
commit 7e39dea97a
  1. 32
      accounts/edit_forms.py
  2. 74
      accounts/forms.py
  3. 1
      accounts/management/__init__.py
  4. 1
      accounts/management/commands/__init__.py
  5. 82
      accounts/management/commands/load_accounts.py
  6. 178
      accounts/models.py
  7. 21
      accounts/search_indexes.py
  8. 16
      accounts/tests.py
  9. 20
      accounts/urls.py
  10. 7
      accounts/user_catalog_urls.py
  11. 125
      accounts/views.py
  12. 9
      article/admin.py
  13. 22
      article/forms.py
  14. 1
      article/management/__init__.py
  15. 1
      article/management/commands/__init__.py
  16. 62
      article/management/commands/article_load.py
  17. 77
      article/management/commands/articles_from_blog.py
  18. 63
      article/management/commands/articles_from_old.py
  19. 77
      article/management/commands/news_from_old.py
  20. 45
      article/management/commands/news_generate_file.py
  21. 69
      article/management/commands/update_news.py
  22. 49
      article/managers.py
  23. 154
      article/models.py
  24. 6
      article/signals.py
  25. 16
      article/tests.py
  26. 48
      article/urls.py
  27. 57
      article/views.py
  28. 0
      banners/__init__.py
  29. 15
      banners/models.py
  30. 16
      banners/tests.py
  31. 7
      banners/urls.py
  32. 10
      banners/views.py
  33. 78
      city/management/commands/city_lost_create.py
  34. 22
      city/management/commands/city_slug.py
  35. 30
      city/management/commands/city_update_from_old.py
  36. 26
      city/management/commands/create_hotels.py
  37. 16
      city/management/commands/hotel_photos.py
  38. 15
      city/management/commands/update_hotels_currency.py
  39. 23
      city/management/commands/update_hotels_price.py
  40. 136
      city/models.py
  41. 3
      city/signals.py
  42. 16
      city/tests.py
  43. 4
      city/urls.py
  44. 8
      city/views.py
  45. 1
      company/management/__init__.py
  46. 1
      company/management/commands/__init__.py
  47. 97
      company/management/commands/company_from_old_db.py
  48. 77
      company/management/commands/company_test.py
  49. 2
      conference/admin.py
  50. 11
      conference/forms.py
  51. 30
      conference/models.py
  52. 4
      conference/urls.py
  53. 26
      conference/views.py
  54. 1
      core/utils.py
  55. 1
      country/management/__init__.py
  56. 1
      country/management/commands/__init__.py
  57. 25
      country/management/commands/country_coordinates.py
  58. 39
      country/management/commands/country_update_from_old.py
  59. 9
      country/manager.py
  60. 139
      country/models.py
  61. 1
      country/signals.py
  62. 16
      country/tests.py
  63. 1
      country/urls.py
  64. 5
      country/views.py
  65. 36
      directories/management/commands/fill_currencies.py
  66. 9
      directories/models.py
  67. 98
      django_messages/expomap_views.py
  68. 5
      expobanner/views.py
  69. 46
      exposition/admin.py
  70. 3
      exposition/admin_urls.py
  71. 17
      exposition/forms.py
  72. 2
      exposition/management/commands/exposition_en.py
  73. 62
      exposition/models.py
  74. 8
      exposition/urls.py
  75. 24
      exposition/views.py
  76. 4
      functions/admin_views.py
  77. 33
      functions/model_mixin.py
  78. 22
      functions/signal_handlers.py
  79. 20
      functions/views_help.py
  80. 69
      import_xls/admin.py
  81. 10
      import_xls/admin_urls.py
  82. 501
      import_xls/excel_settings.py
  83. 22
      import_xls/export_forms.py
  84. 173
      import_xls/import_forms.py
  85. 12
      import_xls/models.py
  86. 55
      meta/models.py
  87. 250
      photologue/admin.py
  88. 2
      photologue/client_urls.py
  89. 9
      photologue/forms.py
  90. 26
      photologue/models.py
  91. 57
      place_conference/admin.py
  92. 4
      place_conference/admin_urls.py
  93. 53
      place_conference/forms.py
  94. 47
      place_conference/models.py
  95. 26
      place_exposition/forms.py
  96. 17
      place_exposition/models.py
  97. 13
      place_exposition/views.py
  98. 2
      proj/settings.py
  99. 3
      proj/urls.py
  100. 26
      registration/backends/default/views.py
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# forms for editing user data
from django import forms
from django.utils.translation import ugettext as _
from models import User, Profile
@ -6,13 +7,16 @@ from country.models import Country
from city.models import City
from company.models import Company
class AvatarForm(forms.ModelForm):
avatar = forms.ImageField(label=_(u'Выберите файл (GIF, JPG, PNG. Размер 100 × 100 пикселей)'),
required=False, widget=forms.FileInput(attrs={'class': 'input'}))
class Meta:
model = Profile
fields = ('avatar',)
class NameForm(forms.ModelForm):
first_name = forms.CharField(label=_(u'Введите ваше имя'))
last_name = forms.CharField(label=_(u'Введите вашу фамилию'))
@ -22,17 +26,19 @@ class NameForm(forms.ModelForm):
fields = ('first_name', 'last_name')
def get_full_name(self):
return u'%s %s'%(self.instance.first_name, self.instance.last_name,)
return u'%s %s' % (self.instance.first_name, self.instance.last_name,)
class HomeForm(forms.ModelForm):
city = forms.CharField(label='Город', required=False,
widget=forms.HiddenInput(attrs={'class': 'select2'}))
country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.all()], required=False,
widget=forms.Select(attrs={'class': 'select2'}))
country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.all()],
required=False, widget=forms.Select(attrs={'class': 'select2'}))
def __init__(self, *args, **kwargs):
super(HomeForm, self).__init__(*args, **kwargs)
if self.instance.city:
# city uses ajax select2 widget
self.fields['city'].widget = forms.HiddenInput(attrs={'class': 'select2', 'data-init-text': self.instance.city.name})
class Meta:
@ -48,7 +54,6 @@ class HomeForm(forms.ModelForm):
except City.DoesNotExist:
return None
def clean_country(self):
try:
return Country.objects.get(id=self.cleaned_data['country'])
@ -56,19 +61,18 @@ class HomeForm(forms.ModelForm):
return None
class WorkForm(forms.ModelForm):
position = forms.CharField(label=_(u'Укажите вашу должность'),
required=False, widget=forms.TextInput())
company = forms.CharField(label=_(u'Укажите вашу компанию'), required=False,
widget=forms.HiddenInput(attrs={'class': 'select2'}))
widget=forms.HiddenInput(attrs={'class': 'select2'}))
def __init__(self, *args, **kwargs):
super(WorkForm, self).__init__(*args, **kwargs)
if self.instance.company:
# for ajax select2 widget
self.fields['company'].widget = forms.HiddenInput(attrs={'class': 'select2', 'data-init-text': self.instance.company.name})
class Meta:
model = User
fields = ('position', 'company')
@ -84,7 +88,8 @@ class WorkForm(forms.ModelForm):
class AboutCompanyForm(forms.ModelForm):
about_company = forms.CharField(label=_(u'Описание компании'), required=False,
widget=forms.Textarea(attrs={'cols':'30'}))
widget=forms.Textarea(attrs={'cols': '30'}))
class Meta:
model = Profile
fields = ('about_company',)
@ -99,11 +104,11 @@ class PhoneForm(forms.ModelForm):
fields = ('phone', 'show_phone')
def clean_phone(self):
phone = self.cleaned_data['phone']
if not phone:
phone = self.cleaned_data['phone']
if not phone:
return
deduct = ('-','(',')','.',' ', '+')
deduct = ('-', '(', ')', '.', ' ', '+')
for elem in deduct:
phone = phone.replace(elem, '')
if phone.isdigit():
@ -112,7 +117,6 @@ class PhoneForm(forms.ModelForm):
raise forms.ValidationError(_(u'Введите правильный телефон'))
class EmailForm(forms.ModelForm):
email = forms.EmailField(label=_(u'Ваш e-mail'), required=False)
@ -120,6 +124,7 @@ class EmailForm(forms.ModelForm):
model = User
fields = ('email',)
class WebPageForm(forms.ModelForm):
web_page = forms.URLField(label=_(u'Адрес вашего сайта'), required=False)
@ -127,17 +132,18 @@ class WebPageForm(forms.ModelForm):
model = User
fields = ('web_page',)
class SocialForm(forms.ModelForm):
facebook = forms.CharField(label=_(u'Facebook'), required=False)
twitter = forms.CharField(label=_(u'Twitter'), required=False)
vk = forms.CharField(label=_(u'В контакте'), required=False)
linkedin = forms.CharField(label=_(u'LinkedIn'), required=False)
class Meta:
model = Profile
fields = ('facebook', 'twitter', 'vk', 'linkedin')
class AboutForm(forms.ModelForm):
about = forms.CharField(label=_(u'Немного о себе'), required=False,
widget=forms.Textarea(attrs={'cols':'30'}))

@ -6,16 +6,14 @@ from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.forms.util import ErrorList
from django.utils.translation import ugettext as _
from django.conf import settings
from models import User, Profile
from models import User
from django.db.models import Q
from theme.models import Theme, Tag
from country.models import Area
from django.utils import translation
from country.models import Country
from city.models import City
from company.models import Company
from organiser.models import Organiser
# functions
from functions.form_check import translit_with_separator, is_latin
from functions.form_check import is_latin
def clean_relation_field(inst, field_name, model):
@ -137,17 +135,6 @@ class UserForm(forms.ModelForm):
profile.save()
return user
#def clean_url(self):
# url = self.cleaned_data.get('url')
# if url:
# if User.objects.get(url=translit_with_separator(url)):
# raise forms.ValidationError('Такой урл уже занят')
# else:
# return url
#def clean_organiser(self):
# return clean_relation_field(self, 'organiser', Organiser)
def clean_company(self):
return clean_relation_field(self, 'company', Company)
@ -174,21 +161,6 @@ class UserForm(forms.ModelForm):
else:
raise forms.ValidationError('Введите правильный код страны')
"""
def clean_web_page(self):
cleaned_data = super(UserForm, self).clean()
web_page = cleaned_data.get('web_page')
if not web_page:
return web_page
import socket
try:
socket.getaddrinfo(web_page, 80)
return web_page
except:
return forms.ValidationError('Введите правильный адрес страници')
"""
class ChangePasswordForm(forms.Form):
"""
@ -319,24 +291,6 @@ class SocialRegistrationCompleteForm(RegistrationCompleteForm):
return user
class RecoveryForm(forms.Form):
email = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': _(u'Email')}))
def get_user(self):
email = self.cleaned_data['email']
return User.objects.get(email=email)
def clean_email(self):
email = self.cleaned_data['email']
try:
return User.objects.get(email=email)
except User.DoesNotExist:
raise forms.ValidationError(_(u'Пользователь с таким емейлом не зарегестрирован'))
from django.db.models import Q
class UserFilterForm(forms.Form):
model = User
search_req = forms.CharField(label=_(u'Введите e-mail, имя или фамилию для запроса'), required=False)
@ -450,21 +404,21 @@ class FeedFilterForm(forms.Form):
area = self.cleaned_data['area']
country = self.cleaned_data['co']
city = self.cleaned_data['ci']
filter = self.filter
filter_obj = self.filter
filter.theme.clear()
filter.theme.add(*Theme.objects.filter(id__in=theme))
filter_obj.theme.clear()
filter_obj.theme.add(*Theme.objects.filter(id__in=theme))
filter.tag.clear()
filter.tag.add(*Tag.objects.filter(id__in=tag))
filter_obj.tag.clear()
filter_obj.tag.add(*Tag.objects.filter(id__in=tag))
filter.area.clear()
filter.area.add(*Area.objects.filter(id__in=area))
filter.country.clear()
filter.country.add(*Country.objects.filter(id__in=country))
filter_obj.area.clear()
filter_obj.area.add(*Area.objects.filter(id__in=area))
filter_obj.country.clear()
filter_obj.country.add(*Country.objects.filter(id__in=country))
filter.city.clear()
filter.city.add(*City.objects.filter(id__in=city))
filter_obj.city.clear()
filter_obj.city.add(*City.objects.filter(id__in=city))
def clean_tg(self):

@ -1 +0,0 @@
__author__ = 'root'

@ -1,82 +0,0 @@
import os
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand
from accounts.models import User
def create_new_user(data):
email = data['email']
firstname = data['firstname']
lastname = data['lastname']
position = data['position']
web_page = data['web_page']
fb = data['fb']
li = data['li']
sk = data['sk']
about = data['about']
password = data['password']
url = data['url']
if not url:
url = str(data['id'])
user = User(username=email, first_name=firstname, last_name=lastname, email=email,
is_staff=False, is_active=True, is_superuser=False, password=password, position=position, url=url)
try:
user.save()
except:
return
profile = user.profile
profile.web_page = web_page
profile.facebook = fb
profile.linkedin = li
profile.skype = sk
profile.about = about
try:
profile.save()
except:
pass
return
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 customers_id as id, customers_email_address as email, customers_password as password, customers_firstname as firstname ,
customers_lastname as lastname , customers_telephone as phone, customers_job as `position`, customers_web as web_page,
customers_facebook as fb, customers_linkedin as li, customers_skype as sk, customers_about as about,
url
FROM `customers`
where customers_email_address!=''
"""
cursor.execute(sql)
result = cursor.fetchall()
#user.password = result[0]['customers_password']
for res in result:
email = res['email']
print(email)
try:
user = User.objects.get(username=email)
except User.DoesNotExist:
user = None
create_new_user(res)
if user:
password = res['password']
user.password = password
user.save()

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
import random, string
from django.db import models
from django.core.validators import email_re
from django.db.models import Q
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin
from django.core.mail import send_mail
@ -9,19 +7,9 @@ from django.utils import timezone
from django.utils.translation import ugettext as _
from django.db.models.signals import post_save
from django.db.models.loading import get_model
#custom functions
from functions.form_check import translit_with_separator
"""
from django.contrib.auth.hashers import check_password
from hashlib import md5
from django.contrib.auth import get_user_model
from django.db.models import get_model
"""
class UserManager(BaseUserManager):
"""
Creates and saves a User with the given email, first_name, last_name and password.
@ -31,10 +19,10 @@ class UserManager(BaseUserManager):
if not email:
raise ValueError('Вы должни ввести электронную почту')
user= self.model(
email = UserManager.normalize_email(email),
first_name = first_name,last_name = last_name,
username = UserManager.normalize_email(email),
user = self.model(
email=UserManager.normalize_email(email),
first_name=first_name,last_name = last_name,
username=UserManager.normalize_email(email),
is_staff=False, is_active=False, is_superuser=False,
last_login=now, date_joined=now, **extra_fields
)
@ -43,29 +31,6 @@ class UserManager(BaseUserManager):
user.save(using=self._db)
return user
def create_social_user(self, username, first_name, last_name, password=None, **extra_fields):
now = timezone.now()
# generate random password
digits = random.sample(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'), 4)
chars = random.sample(string.lowercase[:], 4)
password = chars + digits
random.shuffle(password)
password = ''.join(password)
user= self.model(first_name=first_name, last_name=last_name, username=username,
is_staff=False, is_active=True, is_superuser=False,
last_login=now, date_joined=now, **extra_fields)
check = True if email_re.match(username) else False
if check:
user.email = UserManager.normalize_email(username)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, first_name, last_name, password, **extra_fields):
if not username:
raise ValueError('Вы должни ввести электронную почту')
@ -73,9 +38,9 @@ class UserManager(BaseUserManager):
username = UserManager.normalize_email(username)
user = self.create_user(
email = username,
first_name = first_name,last_name = last_name,
password = password, **extra_fields
email=username,
first_name=first_name, last_name=last_name,
password=password, **extra_fields
)
user.is_staff = True
@ -85,7 +50,6 @@ class UserManager(BaseUserManager):
user.save(using=self._db)
return user
def safe_get(self, **kwargs):
model = self.model
try:
@ -108,24 +72,22 @@ class User(AbstractBaseUser, PermissionsMixin):
catalog = '/user/'
email = models.EmailField(
verbose_name = u'Email',
max_length = 255,
verbose_name=u'Email',
max_length=255,
#unique = True,
db_index = True,
db_index=True,
)
username = models.CharField(verbose_name='Email', max_length=255, unique=True, db_index=True)
first_name = models.CharField(verbose_name='First name', max_length=255)
last_name = models.CharField(verbose_name='Last name', max_length=255)
rating = models.IntegerField(default=100)# добавить индекс в базе
url = models.SlugField(blank=True)#, unique=True, null=True)
#
is_active = models.BooleanField(default=0) # СДЕЛАТЬ проверку на емейле
is_staff = models.BooleanField(default=0)
is_admin = models.BooleanField(default=0)
date_joined = models.DateTimeField(auto_now_add=True)
date_registered = models.DateTimeField(blank=True, null=True)#
date_modified = models.DateTimeField(auto_now=True)
first_name = models.CharField(verbose_name=_(u'First name'), max_length=255)
last_name = models.CharField(verbose_name=_(u'Last name'), max_length=255)
rating = models.IntegerField(verbose_name=_(u'Рейтинг'), default=100)# добавить индекс в базе
url = models.SlugField(verbose_name=_(u'Url'), blank=True)
is_active = models.BooleanField(verbose_name=_(u'Активный'), default=0)
is_staff = models.BooleanField(verbose_name=_(u'Сотрудник?'), default=0)
is_admin = models.BooleanField(verbose_name=_(u'Админ?'), default=0)
date_joined = models.DateTimeField(verbose_name=_(u'Дата создания'), auto_now_add=True)
date_registered = models.DateTimeField(verbose_name=_(u'Дата регистрации'), blank=True, null=True)
date_modified = models.DateTimeField(verbose_name=_(u'Изменен'), auto_now=True)
#relations
organiser = models.ForeignKey('organiser.Organiser', verbose_name='Организатор', blank=True, null=True,
unique=True,
@ -133,7 +95,8 @@ class User(AbstractBaseUser, PermissionsMixin):
translator = models.ForeignKey('translator.Translator', verbose_name='Переводчик', blank=True, null=True,
unique=True,
on_delete=models.PROTECT, related_name='user')
company = models.ForeignKey('company.Company', blank=True, null=True, related_name='users')
company = models.ForeignKey('company.Company', verbose_name=_(u'Компания'), blank=True, null=True,
related_name='users')
position = models.CharField(verbose_name='Должность', max_length=255, blank=True)
objects = UserManager()
@ -142,10 +105,7 @@ class User(AbstractBaseUser, PermissionsMixin):
REQUIRED_FIELDS = ['first_name', 'last_name']
class Meta:
ordering=['-rating']
def is_organiser(self):
return bool(self.organiser)
ordering = ['-rating']
def get_full_name(self):
"""
@ -154,16 +114,13 @@ class User(AbstractBaseUser, PermissionsMixin):
return u'%s %s'%(self.first_name, self.last_name)
def set_url(self, st):
"""
"""
self.url = translit_with_separator(u'%s'%st)
def __unicode__(self):
return self.email
def get_short_name(self):
"Returns the short name for the user."
"""Returns the short name for the user."""
return self.first_name
def email_user(self, subject, message, from_email=None):
@ -172,7 +129,6 @@ class User(AbstractBaseUser, PermissionsMixin):
"""
send_mail(subject, message, from_email, [self.email])
def has_perm(self, perm, obj=None):
return True
@ -201,81 +157,54 @@ class User(AbstractBaseUser, PermissionsMixin):
return n
def get_permanent_url(self):
if self.url:
return '/%s/'%self.url
#return self.catalog+self.url+'/'
return '/%d/'%self.id
#return self.catalog+str(self.id)+'/'
def get_translator_url(self):
if self.url:
return '/translators/%s/'%self.url
return '/translators/%d/'%self.id
return '/%s/' % self.url
return '/%d/' % self.id
def get_expos(self):
"""
return information about expos and them related data by 1 query
return information about expos and them related data by 1 query(reverse connection)
"""
return self.exposition_users.language().select_related('country', 'city', 'place').all()
def get_confs(self):
"""
return information about confs and them related data by 1 query
return information about confs and them related data by 1 query(reverse connection)
"""
return self.conference_users.language().select_related('country', 'city', 'place').all()
def get_seminars(self):
"""
return information about seminars and them related data by 1 query
"""
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):
"""
stores additional information about users
"""
user = models.OneToOneField(User)
country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True,
country = models.ForeignKey('country.Country', verbose_name=_(u'Страна'), blank=True, null=True,
on_delete=models.PROTECT, related_name='users')
city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True,
city = models.ForeignKey('city.City', verbose_name=_(u'Город'), blank=True, null=True,
on_delete=models.PROTECT)
about_company = models.TextField(verbose_name=_(u'Описание компании'), blank=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)
about = models.TextField(verbose_name='О себе', blank=True)
avatar = models.ImageField(verbose_name='Фото', upload_to='accounts/avatar/', blank=True)
skype = models.CharField(blank=True, max_length=255)
web_page = models.URLField(verbose_name=_(u'Вебсайт'),blank=True)
about = models.TextField(verbose_name=_(u'О себе'), blank=True)
avatar = models.ImageField(verbose_name=_(u'Фото'), upload_to='accounts/avatar/', blank=True)
skype = models.CharField(verbose_name=_(u'Skype'), blank=True, max_length=255)
facebook = models.URLField(verbose_name=_(u'Facebook'), blank=True, max_length=255)
twitter = models.URLField(verbose_name=_(u'Twitter'), blank=True,max_length=255)
linkedin = models.URLField(verbose_name=_(u'LinkedIn'), blank=True, max_length=255)
vk = models.URLField(verbose_name=_(u'В контакте'), blank=True, max_length=255)
# meta
title = models.CharField(max_length=255, blank=True)
descriptions = models.CharField(max_length=255, blank=True)
@ -288,10 +217,10 @@ class Calendar(models.Model):
every user has one calendar
"""
user = models.OneToOneField(User)
expositions = models.ManyToManyField('exposition.Exposition', null=True)
conferences = models.ManyToManyField('conference.Conference', null=True)
seminars = models.ManyToManyField('seminar.Seminar', null=True)
webinars = models.ManyToManyField('webinar.Webinar', null=True)
expositions = models.ManyToManyField('exposition.Exposition', verbose_name=_(u'Выставки'), null=True)
conferences = models.ManyToManyField('conference.Conference', verbose_name=_(u'Конфеернции'), null=True)
seminars = models.ManyToManyField('seminar.Seminar', verbose_name=_(u'Семинары'), null=True)
webinars = models.ManyToManyField('webinar.Webinar', verbose_name=_(u'Вебинары'), null=True)
def get_expos(self):
# 1 query
@ -345,15 +274,18 @@ class Calendar(models.Model):
class EventFilter(models.Model):
user = models.OneToOneField(User)
theme = models.ManyToManyField('theme.Theme', null=True)
tag = models.ManyToManyField('theme.Tag', null=True)
area = models.ManyToManyField('country.Area', null=True)
country = models.ManyToManyField('country.Country', null=True)
city = models.ManyToManyField('city.City', null=True)
fr = models.DateField(blank=True, null=True)
to = models.DateField(blank=True, null=True)
theme = models.ManyToManyField('theme.Theme', verbose_name=_(u'Тематики'), null=True)
tag = models.ManyToManyField('theme.Tag', verbose_name=_(u'Теги'), null=True)
area = models.ManyToManyField('country.Area', verbose_name=_(u'Геограифческие зоны'), null=True)
country = models.ManyToManyField('country.Country', verbose_name=_(u'Страны'), null=True)
city = models.ManyToManyField('city.City', verbose_name=_(u'Города'), null=True)
fr = models.DateField(blank=True, verbose_name=_(u'с'), null=True)
to = models.DateField(blank=True, verbose_name=_(u'до'), null=True)
def get_queryset(self):
"""
get filtered queryset
"""
Exposition = get_model('exposition', 'Exposition')
qs = Exposition.enable.upcoming()
themes = self.theme.all()
@ -380,9 +312,11 @@ class EventFilter(models.Model):
return qs.order_by('data_begin')
def calculate_rating(user):
"""
calculates user rating depending og user filled information
calls in post save signal of profile model
"""
user_rating_fields = {'position': 5, 'company': 5, 'url': 10}
profile_rating_fields = {'country': 5, 'city': 5, 'phone': 10, 'facebook': 5, 'twitter': 5, 'linkedin': 5, 'vk': 5,
'web_page': 10, 'avatar': 20, 'about': 15}
@ -396,7 +330,6 @@ def calculate_rating(user):
if getattr(user, key):
rating += value
for key, value in profile_rating_fields.iteritems():
if getattr(user.profile, key):
rating += value
@ -409,6 +342,9 @@ def calculate_rating(user):
def create_user_inf(sender, instance, created, **kwargs):
"""
create default models that is required for users
"""
if created:
Calendar.objects.create(user=instance)
Profile.objects.create(user=instance)
@ -416,10 +352,10 @@ def create_user_inf(sender, instance, created, **kwargs):
calculate_rating(instance)
def post_profile(sender, instance, created, **kwargs):
user = instance.user
calculate_rating(user)
post_save.connect(create_user_inf, sender=User)
post_save.connect(post_profile, sender=Profile)
post_save.connect(post_profile, sender=Profile)

@ -1,21 +0,0 @@
from haystack import indexes
from models import User
"""
class UserIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
# first_name = indexes.CharField(model_attr='first_name')
# last_name = indexes.CharField(model_attr='last_name')
email = indexes.NgramField(model_attr='email')
#email = indexes.CharField(model_attr='email')
def get_model(self):
return User
def index_queryset(self, using=None):
return self.get_model().objects.filter(is_active=True)
"""

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

@ -1,18 +1,12 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required
from views import SettingsView, ProfileView, CalendarView, UserView, UserExpositionsView, UserConferenceView, UserSeminarView
from views import SettingsView, CalendarView
from views import NameView, HomeView, AvatarView, WorkView, AboutCompanyView, PhoneView, WebPageView,\
SocialView, AboutView, ProfileCompanyView, Feed
#
from django.http import HttpResponse
def test(request):
return HttpResponse('123')
urlpatterns = patterns('',
url(r'^profile/$', login_required(ProfileView.as_view())),
url(r'^profile/company/$', login_required(ProfileCompanyView.as_view())),
url(r'^profile/settings/$', login_required(SettingsView.as_view()), name='accounts_settings'),
url(r'^profile/calendar/remove/$', 'accounts.views.remove_from_calendar'),
@ -20,20 +14,8 @@ urlpatterns = patterns('',
url(r'^profile/calendar/$', login_required(CalendarView.as_view())),
url(r'^profile/feed/page/(?P<page>\d+)/$', Feed.as_view()),
url(r'^profile/feed/$', login_required(Feed.as_view())),
url(r'^user/(?P<url>.*)/expositions/(?P<page>\d+)/$', UserExpositionsView.as_view()),
url(r'^user/(?P<url>.*)/expositions/$', UserExpositionsView.as_view()),
url(r'^user/(?P<url>.*)/seminars/(?P<page>\d+)/$', UserSeminarView.as_view()),
url(r'^user/(?P<url>.*)/seminars/$', UserSeminarView.as_view()),
url(r'^user/(?P<url>.*)/conferences/(?P<page>\d+)/$', UserConferenceView.as_view()),
url(r'^user/(?P<url>.*)/conferences/$', UserConferenceView.as_view()),
url(r'^user/(?P<url>.*)/events/(?P<page>\d+)/$', UserView.as_view()),
url(r'^user/(?P<url>.*)/events/$', UserView.as_view()),
url(r'^user/(?P<url>.*)/$', UserView.as_view()),
url(r'^inactive-user/$', 'registration.backends.default.views.inactive_user_message'),
#url(r'^profile/messages/(?P<user>.*)/$', login_required(MessagesView.as_view())),
#url(r'^profile/messages/$', login_required(MessagesView.as_view())),
# ajax
url(r'^profile/update/announce-settings/$', 'accounts.views.save_announce_settings', name='account_save_announce_settings'),
url(r'^profile/update/name/$', login_required(NameView.as_view())),

@ -1,16 +1,11 @@
from django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required
from views import SettingsView, ProfileView, CalendarView, UserView, UserExpositionsView, UserConferenceView, UserSeminarView
from views import UserView, UserExpositionsView, UserConferenceView
urlpatterns = patterns('',
url(r'^(?P<url>.*)/expositions/(?P<page>\d+)/$', UserExpositionsView.as_view(), {'meta_id': 72}),
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/$', UserSeminarView.as_view()),
url(r'^(?P<url>.*)/conferences/(?P<page>\d+)/$', UserConferenceView.as_view(), {'meta_id': 73}),
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/$', UserView.as_view()),
url(r'^(?P<url>.*)/$', UserView.as_view(), {'meta_id': 71}),
)

@ -1,24 +1,31 @@
# -*- coding: utf-8 -*-
import dateutil.relativedelta as rdelta
import json, datetime
import json
import datetime
import calendar as python_calendar
from django.shortcuts import get_object_or_404
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseForbidden
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _, get_language
from django_messages.forms import SendForm
from django.views.generic import TemplateView, FormView
from django.conf import settings
from functions.custom_views import ListView
from functions.views_help import dates_range, get_user
from sorl.thumbnail import get_thumbnail
from .forms import ChangePasswordForm, FeedFilterForm
from exposition.models import Exposition
from .forms import ChangePasswordForm, EmailAnnouncementForm, FeedFilterForm
from company.forms import CreateCompanyForm
from .models import User
from .edit_forms import AvatarForm, NameForm, HomeForm, WorkForm, AboutCompanyForm, PhoneForm, EmailForm,\
WebPageForm, SocialForm, AboutForm
from company.edit_forms import NameForm as CompNameForm, HomeForm as CompHomeForm, PhoneForm as CompPhoneForm,\
EmailForm as CompEmailForm, WebPageForm as CompWebPageForm, SocialForm as CompSocialForm,\
TagForm as CompTagForm, DescriptionForm as CompDescr, StaffForm as CompStaff, \
FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress
from meta.views import MetadataMixin
from emencia.django.newsletter.forms import SubscribeSettingsForm
from emencia.django.newsletter.models import Contact
from meta.views import MetadataMixin
class SettingsView(TemplateView):
@ -56,8 +63,6 @@ class SettingsView(TemplateView):
form = SubscribeSettingsForm(instance=setting, initial=initial)
return form
def get_context_data(self, **kwargs):
context = super(SettingsView, self).get_context_data(**kwargs)
context['change_password_form'] = ChangePasswordForm()
@ -66,13 +71,10 @@ class SettingsView(TemplateView):
return context
def save_announce_settings(request):
if request.POST:
user = request.user
email = request.POST.get('email') or user.username
# check if setting subscription already exist
try:
contact, created = user.contact_set.get(email=email), False
@ -94,16 +96,6 @@ def save_announce_settings(request):
return HttpResponseRedirect(reverse('accounts_settings'))
def dates_range(date1, date2):
delta = date2 - date1
dates = []
for i in range(delta.days + 1):
dates.append(date1 + datetime.timedelta(days=i))
return dates
class CalendarView(TemplateView):
"""
display template with user calendar(one month)
@ -119,7 +111,6 @@ class CalendarView(TemplateView):
- events - events in current months
- days - days in current month
- current_day
"""
context = super(CalendarView, self).get_context_data(**kwargs)
now = datetime.datetime.now().replace(microsecond=0, second=0, minute=0, hour=0)
@ -137,32 +128,27 @@ class CalendarView(TemplateView):
number_of_days = python_calendar.monthrange(now.year, now.month)[1]
# number of days in current month
days = [datetime.datetime(now.year, now.month, i+1) for i in range(number_of_days)]
#context['days'] = days
calendar = self.request.user.calendar
# events in current month
context['events'] = calendar.events_by_month(now)
else:
number_of_days = python_calendar.monthrange(year, month)[1]
# days in current month
days = [datetime.datetime(year, month, i+1) for i in range(number_of_days)]
# number of days in current month
#context['days'] = days
calendar = self.request.user.calendar
now = now.replace(year=year, month=month, day=1)
# events in current month
context['events'] = calendar.events_by_month(now)
# add days from previous mondey to next sunday
# add days from previous monday 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:
@ -171,9 +157,6 @@ class CalendarView(TemplateView):
days += b
events = context['events']
context['days'] = days
#days = context['days']
event_in_day = False
counter = 0
dates_with_events = []
for event in events:
dates_with_events += dates_range(event.data_begin, event.data_end)
@ -203,39 +186,6 @@ class CalendarView(TemplateView):
return context
class ProfileView(TemplateView):
"""
display template with user information forms
in template forms handles dynamically by ajax
"""
template_name = 'client/accounts/new_profile.html'
def get_context_data(self, **kwargs):
context = super(ProfileView, self).get_context_data(**kwargs)
user = self.request.user
profile = user.profile
profile_forms = {
'avatar_form': AvatarForm(instance=profile), 'name_form': NameForm(instance=user),
'home_form': HomeForm(instance=profile), 'work_form': WorkForm(instance=user),
'about_company_form': AboutCompanyForm(instance=profile), 'phone_form': PhoneForm(instance=profile),
'email_form': EmailForm(instance=user), 'web_page_form': WebPageForm(instance=profile),
'social_form': SocialForm(instance=profile), 'about_form': AboutForm(instance=profile)
}
if not user.company:
company_form = {'company_form': CreateCompanyForm()}
context.update(company_form)
context.update(profile_forms)
return context
from company.edit_forms import NameForm as CompNameForm, HomeForm as CompHomeForm, PhoneForm as CompPhoneForm,\
EmailForm as CompEmailForm, WebPageForm as CompWebPageForm, SocialForm as CompSocialForm,\
TagForm as CompTagForm, DescriptionForm as CompDescr, StaffForm as CompStaff, \
FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress
class ProfileCompanyView(TemplateView):
"""
display template with user company information forms
@ -270,8 +220,6 @@ class ProfileCompanyView(TemplateView):
return context
class UserView(MetadataMixin, TemplateView):
"""
display user information for another users
@ -306,8 +254,6 @@ class UserView(MetadataMixin, TemplateView):
context.update(profile_forms)
context['message_form'] = SendForm()
context['member'] = user
return context
@ -335,6 +281,7 @@ class BaseProfileView(ProfileInvalidView):
response = {'success': True, 'rating': profile.user.rating}
return HttpResponse(json.dumps(response), content_type='application/json')
class WorkView(ProfileInvalidView):
"""
instance user
@ -345,13 +292,11 @@ class WorkView(ProfileInvalidView):
user = self.request.user
form = self.form_class(self.request.POST, instance=user)
user = form.save()
#company = user.company
#response = {'success': True, 'url':company.get_permanent_url()}
response = {'success': True, 'rating': user.rating}
return HttpResponse(json.dumps(response), content_type='application/json')
class AvatarView(BaseProfileView):
"""
instance profile. save user avatar.
@ -413,6 +358,7 @@ class AboutView(BaseProfileView):
"""
form_class = AboutForm
class NameView(ProfileInvalidView):
"""
instance user
@ -427,25 +373,14 @@ class NameView(ProfileInvalidView):
return HttpResponse(json.dumps(response), content_type='application/json')
from exposition.models import Exposition
def get_user(url):
try:
url = int(url)
user = get_object_or_404(User, id=url)
except ValueError:
user = get_object_or_404(User, url=url)
return user
class UserEventView(ListView):
model = Exposition
template_name = 'accounts/user_events.html'
template_name = 'client/accounts/user_events.html'
paginate_by = 10
obj = None
event_type = None
def get_queryset(self):
url = self.kwargs.get('url')
user = get_user(url)
@ -458,6 +393,7 @@ class UserEventView(ListView):
context['event_type'] = self.event_type
return context
class UserExpositionsView(MetadataMixin, UserEventView):
"""
return template with list of expos that user joined
@ -485,17 +421,6 @@ class UserConferenceView(MetadataMixin, UserEventView):
self.kwargs['user_full_name'] = user.get_full_name()
return user.get_confs()
class UserSeminarView(UserEventView):
"""
return template with list of seminars that user joined
"""
event_type = _(u'Семинары')
def get_queryset(self):
url = self.kwargs.get('url')
user = get_user(url)
self.obj = user
return user.get_seminars()
@login_required
def change_password(request):
@ -525,10 +450,10 @@ def change_password(request):
else:
return HttpResponse(json.dumps(success), content_type='application/json')
from django.views.generic.edit import FormMixin
class Feed(ListView):
template_name = 'client/accounts/feed.html'
paginate_by = 10
paginate_by = settings.CLIENT_PAGINATION
model = Exposition
filter_form = FeedFilterForm
success_url = '/profile/feed/'
@ -540,11 +465,9 @@ class Feed(ListView):
form.filter_save()
return HttpResponseRedirect(self.success_url)
def get_queryset(self):
filter = self.request.user.eventfilter
qs = filter.get_queryset()
filter_obj = self.request.user.eventfilter
qs = filter_obj.get_queryset()
return qs
def get_context_data(self, **kwargs):

@ -171,7 +171,10 @@ class BlogView(FormView):
article = self.obj
data = {}
data['slug'] = article.slug
data['theme'] = [item.id for item in article.blog_theme.all()]
if self.obj.type == Article.blog:
data['theme'] = [item.id for item in article.blog_theme.all()]
else:
data['theme'] = [item.id for item in article.theme.all()]
if article.exposition:
data['exposition'] = article.exposition.id
if article.conference:
@ -200,13 +203,10 @@ class BlogView(FormView):
else:
return form_class()
def get_context_data(self, **kwargs):
context = super(BlogView, self).get_context_data(**kwargs)
self.set_obj()
context['article'] = self.obj
if context['article']:
context['file_form'] = FileForm(initial={'model': 'article.Article'})
@ -229,6 +229,7 @@ class NewsList(ListView):
context['news_flag'] = True
return context
class NewsView(BlogView):
form_class = NewsForm
template_name = 'admin/article/blog_form.html'

@ -1,15 +1,12 @@
# -*- coding: utf-8 -*-
from django import forms
from django.conf import settings
from ckeditor.widgets import CKEditorWidget
from django.core.exceptions import ValidationError
from django.forms.util import ErrorList
from django.utils.translation import ugettext as _
#functions
from ckeditor.widgets import CKEditorWidget
from functions.translate import fill_with_signal
from functions.files import check_tmp_files
from functions.form_check import translit_with_separator
#models
from models import Article
from accounts.models import User
from theme.models import Theme, Tag, ThemeBlog
@ -57,7 +54,9 @@ class BlogForm(forms.Form):
article.author = author
article.type = self.type
article.slug = data.get('slug')
if not getattr(article, 'slug', None):
article.slug = data['slug']
if data['logo']:
article.logo = data['logo']
article.publish_date = data['publish_date']
@ -95,21 +94,22 @@ class BlogForm(forms.Form):
else:
return []
class NewsForm(BlogForm):
type = Article.news
exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput(), required=False)
conference = forms.CharField(label=u'Конференция', widget=forms.HiddenInput(), required=False)
theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all(), required=False,
widget=forms.SelectMultiple(attrs={'style':'width: 550px'}))
#exposition = forms.ModelChoiceField(label = u'Выставка', required=False, queryset=Exposition.objects.all())
#conference = forms.ModelChoiceField(label = u'Конференция', required=False, queryset=Conference.objects.all())
def save(self, author, article=None):
article = super(NewsForm, self).save(author, article)
exposition = self.cleaned_data.get('exposition')
conference = self.cleaned_data.get('conference')
theme = self.cleaned_data.get('theme')
article.exposition = exposition
article.conference = conference
article.theme = theme
article.save()
return article
@ -267,7 +267,7 @@ class BlogForm(forms.ModelForm):
class ArticleFilterForm(forms.Form):
theme = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in ThemeBlog.objects.language().distinct()])
choices=[(item.id, item.name) for item in Theme.objects.language().distinct()])
tag = forms.CharField(label=_(u'Теги:'), widget=forms.HiddenInput(), required=False)
'''
@ -291,7 +291,7 @@ class BlogFilterForm(forms.Form):
create dynamical translated fields fields
"""
super(BlogFilterForm, self).__init__(*args, **kwargs)
ids = [item['theme'] for item in list(Article.objects.blogs().values('theme').distinct())]
ids = set([item['blog_theme'] for item in list(Article.objects.blogs().filter(blog_theme__isnull=False).values('blog_theme'))])
self.fields['theme'] = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in ThemeBlog.objects.language().filter(id__in=ids)])
@ -304,6 +304,6 @@ class NewsFilterForm(forms.Form):
create dynamical translated fields fields
"""
super(NewsFilterForm, self).__init__(*args, **kwargs)
ids = [item['theme'] for item in list(Article.objects.news().values('theme').distinct())]
ids = set([item['theme'] for item in list(Article.objects.news().values('theme'))])
self.fields['theme'] = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in Theme.objects.language().exclude(article__id=None).filter(id__in=ids)])
choices=[(item.id, item.name) for item in Theme.objects.language().filter(id__in=ids)])

@ -1 +0,0 @@
__author__ = 'root'

@ -1,62 +0,0 @@
# -*- coding: utf-8 -*-
import xlrd
from django.core.management.base import BaseCommand
from django.conf import settings
from article.models import Article
from import_xls.excel_settings import article_sett
from django.db import IntegrityError
NEWS_FILE = settings.MEDIA_ROOT+'/import/news.xls'
class Command(BaseCommand):
def handle(self, *args, **options):
f = open(NEWS_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]]
existing = 0
for row_number, row in enumerate(row_list[2:]):
published = row[4]
if row[0] != '':
# in first column ids
try:
object = Article.objects.language('ru').get(id=int(row[0]))
object.type = Article.news
object.save()
print(object.type)
continue
except ValueError:
object = Article(type=Article.news)
object.translate('ru')
except Article.DoesNotExist:
object = Article(id= int(row[0]))
object.translate('ru')
existing += 1
else:
# if id blank - its a new place
object = Article(type=Article.news)
object.translate('ru')
for col_number, cell in enumerate(row):
label = labels[col_number]
setting = article_sett.get(label)
if setting is None:
continue
field_name = setting['field']
func = setting.get('func')
value = func(cell)
setattr(object, field_name, value)
object.publish_date = published
try:
object.save()
except Exception, e:
print(e)

@ -1,77 +0,0 @@
# -*- coding: utf-8 -*-
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from functions.translate import fill_with_signal
from article.models import Article
from accounts.models import User
from theme.models import Theme,Tag
class Command(BaseCommand):
def handle(self, *args, **options):
db = MySQLdb.connect(host="localhost",
user="kotzilla",
passwd="qazedc",
db="expomap_old_blog",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
sql = """SELECT post.post_date as publish_date,
post.post_content as description,
post.post_modified as modified,
post.post_title as main_title,
post.post_name as slug,
tag.name as tag_name
FROM wp_posts post
INNER JOIN wp_term_relationships rel ON rel.object_id = post.ID
INNER JOIN wp_terms tag ON tag.term_id=rel.term_taxonomy_id
WHERE post_status = "publish";"""
cursor.execute(sql)
result = cursor.fetchall()
user = User.objects.get(id=1)
tags = {x.name: x.id for x in Tag.objects.language('ru')}
clear_result = {}
errors = []
for a in result:
if a.get('tag_name') in tags.keys():
tag_id = tags[a['tag_name']]
a['tag_id'] = [tag_id]
print a
else:
tag_id = None
if not clear_result.get(a['main_title']):
clear_result[a['main_title']] = a
else:
if clear_result[a['main_title']].get('paid_id') and tag_id:
clear_result[a['main_title']]['tag_id'].append(tag_id)
for a in clear_result.values():
article = Article(type=1,
created = a['publish_date'],
publish_date= a['publish_date'],
modified = a['modified'],
)
article.author = user
article.translate('ru')
article.main_title = a['main_title']
article.description = a['description']
article.slug = a['slug']
if a.get('tag_id'):
article.tag = [Tag.objects.language('ru').get(id=id) for id in a['tag_id']]
try:
article.save()
except Exception as e:
errors.append(e)
print errors

@ -1,63 +0,0 @@
# -*- coding: utf-8 -*-
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from functions.translate import fill_with_signal
from article.models import Article
from accounts.models import User
class Command(BaseCommand):
def handle(self, *args, **options):
db = MySQLdb.connect(host="localhost",
user="kotzilla",
passwd="qazedc",
db="old_expomap",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
sql = """SELECT articles_description.articles_id as id ,
articles_description.articles_name as main_title,
articles_description.articles_description as description,
articles.authors_id as author,
articles_description.articles_intro as preview,
articles.articles_date_added as created,
articles.articles_last_modified as modified,
articles.articles_date_available as publish_date,
articles_description.articles_head_title_tag as title,
articles_description.articles_head_desc_tag as descriptions,
articles_description.articles_head_keywords_tag as keywords
FROM `articles_description`
JOIN articles
ON articles_description.articles_id=articles.articles_id"""
cursor.execute(sql)
result = cursor.fetchall()
user = User.objects.get(id=1)
Article.objects.blogs().delete()
for a in result:
article = Article(type=Article.blog,
id=a['id'],
created=a['created'],
modified=a['modified'],
publish_date=a['publish_date'])
article.author = user
article.translate('ru')
article.main_title = a['main_title']
article.preview = a['preview']
article.description = a['description']
article.title = a['title']
article.keywords = a['keywords']
if len(a['descriptions'])<255:
article.descriptions = a['descriptions']
article.save()
print(article)
#print(a['main_title'])

@ -1,77 +0,0 @@
# -*- coding: utf-8 -*-
import datetime
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from functions.translate import fill_with_signal
from article.models import Article
from accounts.models import User
from django.db import IntegrityError
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 news_id as id ,
headline as main_title,
content as description,
cid as author,
date_added as created
FROM `payed_news`
WHERE status = 1
order by created DESC"""
cursor.execute(sql)
result = cursor.fetchall()
user = User.objects.get(id=1)
now = datetime.datetime.now()
#Article.objects.news().delete()
for a in result:
title = a['main_title']
id = a['id']
published = a['created']
#try:
# news = Article.objects.get(id=id)
#except Article.DoesNotExist:
# continue
#news.publish_date = published
#news.save()
if len(a['main_title'])>255 or not a['main_title']:
continue
article = Article(type=Article.news,
old_id=a['id'],
publish_date=a['created'],
created=now)
if a['author']:
try:
author = User.objects.get(id=a['author'])
except User.DoesNotExist:
author = user
else:
author = user
article.author = author
article.translate('ru')
article.main_title = a['main_title']
article.description = a['description']
try:
article.save()
print(article)
except :
print ('error. id:%d'%a['id'])
#print(a['main_title'])

@ -1,45 +0,0 @@
# -*- coding: utf-8 -*-
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from functions.translate import fill_with_signal
from article.models import Article
from accounts.models import User
from django.db import IntegrityError
import xlwt
from django.utils import translation
from django.conf import settings
class Command(BaseCommand):
def handle(self, *args, **options):
translation.activate('en')
workbook = xlwt.Workbook(encoding = 'utf8')
worksheet = workbook.add_sheet('My Worksheet')
font = xlwt.Font()
font.name = 'Times New Roman'
font.bold = True
style = xlwt.XFStyle()
# Create the Style
style.font = font
qs = Article.objects.news()
worksheet.write(0, 0, 'id')
worksheet.write(0, 1, 'url')
worksheet.write(0, 2, 'title')
row = 1
for a in qs:
print a.id
url = a.slug
id = a.id
name = a.main_title
worksheet.write(row, 0, id)
worksheet.write(row, 1, url)
worksheet.write(row, 2, name)
row += 1
workbook.save(settings.MEDIA_ROOT+'/import/exported_news.xls')

@ -1,69 +0,0 @@
# -*- coding: utf-8 -*-
import MySQLdb
import datetime
from django.utils.translation import activate
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
import xlrd
from import_xls.utils import to_theme, to_tag
from functions.translate import fill_with_signal
from article.models import Article
from accounts.models import User
from django.db import IntegrityError
from exposition.models import Exposition
NEWS_FILE = settings.MEDIA_ROOT+'/import/exported_news.xls'
BLOGS_FILE = settings.MEDIA_ROOT+'/import/blogs.xls'
class Command(BaseCommand):
def handle(self, *args, **options):
activate('ru')
f = open(BLOGS_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)]
print(len(row_list))
existing = 0
for row_number, row in enumerate(row_list[2:]):
id = int(row[0])
if id == 49:
continue
main_title = row[1]
theme = row[2]
tag = row[3]
description = row[4]
article = Article.objects.language('ru').get(id=id)
#article.main_title = main_title
#article.description = description
#article.save()
to_theme(article, theme)
to_tag(article, tag)
print(id)
"""
try:
expo = Exposition.objects.filter(translations__name=event)[0]
except IndexError:
expo = None
if expo:
article.exposition = expo
article.save()
print(id)
"""

@ -0,0 +1,49 @@
from django.utils import translation
from django.core.cache import cache
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
class ArticleManager(TranslationManager):
cache_time = 60
def safe_get(self, **kwargs):
model = self.model
try:
return model.objects.get(**kwargs)
except:
return None
def news(self):
"""
return queryset of news
"""
model = self.model
return self.language().filter(type=model.news)
def blogs(self):
"""
return queryset of blogs
"""
model = self.model
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', '-modified')[: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

@ -1,63 +1,16 @@
# -*- coding: utf-8 -*-
import copy
from django.db import models
from django.contrib.contenttypes import generic
from django.utils.translation import ugettext_lazy as _
from django.utils import translation
from django.utils.timezone import now
from django.db.models.signals import post_save
from functions.signal_handlers import post_save_handler
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from django.utils.html import strip_tags
from sorl.thumbnail import ImageField
from functions.url_utils import slugify, unique_slug
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):
cache_time = 60
def safe_get(self, **kwargs):
model = self.model
try:
return model.objects.get(**kwargs)
except:
return None
def news(self):
"""
return queryset of news
"""
model = self.model
return self.language().filter(type=model.news)
def blogs(self):
"""
return queryset of blogs
"""
model = self.model
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', '-modified')[: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
from article.managers import ArticleManager
class Article(TranslatableModel):
@ -67,36 +20,36 @@ class Article(TranslatableModel):
Uses hvad.TranslatableModel which is child of django.db.models class
"""
MAX_ON_MAIN_PAGE = 3
# types of article
blog = 1
news = 2
#set manager of this model
objects = ArticleManager()
slug = models.SlugField(unique=True, max_length=255)
old_id = models.IntegerField(blank=True, null=True)
logo = ImageField(upload_to='articles_preview', blank=True)
theme = models.ManyToManyField('theme.Theme')
blog_theme = models.ManyToManyField('theme.ThemeBlog')
tag = models.ManyToManyField('theme.Tag', blank=True, null=True)
author = models.ForeignKey('accounts.User', verbose_name='Автор',
slug = models.SlugField(verbose_name=_(u'Url'), unique=True, max_length=255)
# fields provides importing and reindexing new articles from previous site
old_id = models.IntegerField(verbose_name=_(u'Id из старой базы'), blank=True, null=True)
logo = ImageField(verbose_name=_(u'Логотип'), upload_to='articles_preview', blank=True)
theme = models.ManyToManyField('theme.Theme', verbose_name=_(u'Тематики'))
blog_theme = models.ManyToManyField('theme.ThemeBlog', verbose_name=_(u'Тематики для блогов'), )
tag = models.ManyToManyField('theme.Tag', blank=True, null=True, verbose_name=_(u'Теги'), )
author = models.ForeignKey('accounts.User', verbose_name=_(u'Автор'),
on_delete=models.PROTECT, related_name='articles')
exposition = models.ForeignKey('exposition.Exposition', blank=True, null=True)
conference = models.ForeignKey('conference.Conference', blank=True, null=True)
type = models.PositiveSmallIntegerField(default=1)
allow_comments = models.BooleanField(default=True)
exposition = models.ForeignKey('exposition.Exposition', blank=True, null=True, verbose_name=_(u'Выставка'))
conference = models.ForeignKey('conference.Conference', blank=True, null=True, verbose_name=_(u'Конференция'))
# type can be blog or news
type = models.PositiveSmallIntegerField(verbose_name=_(u'Тип'), default=1, db_index=True)
# do not use anywhere now
allow_comments = models.BooleanField(verbose_name=_(u'Позволить коментарии'), default=True)
# fields that provides features of a visible page on the website
publish_date = models.DateTimeField(blank=True, null=True)
publish_date = models.DateTimeField(verbose_name=_(u'Дата публикации'), blank=True, null=True, db_index=True)
expiry_date = models.DateTimeField(_("Expires on"),
help_text=_("With Published chosen, won't be shown after this time"),
blank=True, null=True)
in_sitemap = models.BooleanField(_("Show in sitemap"), default=False)
# fields that provides features of a visible on main page
main_page = models.BooleanField(default=False)
main_page = models.BooleanField(verbose_name=_(u'Показывать на главной'), default=False, db_index=True)
main_page_time = models.DateTimeField(blank=True, null=True)
# field that check if need generate description
@ -104,23 +57,22 @@ class Article(TranslatableModel):
help_text=_("If checked, the description will be automatically "
"generated from content. Uncheck if you want to manually "
"set a custom description."), default=False)
# published = models.
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
#translated fields
translations = TranslatedFields(
main_title = models.CharField(max_length=255),
preview = models.TextField(),
description = models.TextField(blank=False),
main_title=models.CharField(verbose_name=_(u'Заголовок'), max_length=255),
preview=models.TextField(verbose_name=_(u'Превью'), ),
description=models.TextField(verbose_name=_(u'Основной текст'), blank=False),
#-----meta
title = models.CharField(max_length=255, blank=True),
descriptions = models.CharField(max_length=255, blank=True),
keywords = models.CharField(max_length=255, blank=True),
title=models.CharField(max_length=255, blank=True),
descriptions=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 = ['-publish_date']
@ -130,8 +82,10 @@ class Article(TranslatableModel):
def translation_model(self):
return self._meta.translations_model
def publish(self):
"""
set publish date. uses when publish date is none
"""
self.in_sitemap = True
if not self.publish_date:
# save time only first time
@ -141,6 +95,10 @@ class Article(TranslatableModel):
return self
def get_event(self):
"""
get event connected to article
exposition has priority
"""
if self.exposition:
return self.exposition
elif self.conference:
@ -182,8 +140,10 @@ class Article(TranslatableModel):
return slugify(self.get_available_title())
def get_available_title(self):
#print self.lazy_translation_getter('main_title', self.pk)
return u'%s'%self.lazy_translation_getter('main_title', self.pk)
"""
get title from current language
"""
return u'%s' % self.lazy_translation_getter('main_title', self.pk)
def _get_next_or_previous_by_publish_date(self, is_next, **kwargs):
"""
@ -216,21 +176,28 @@ class Article(TranslatableModel):
"""
return self._get_next_or_previous_by_publish_date(False, **kwargs)
def admin_url(self):
"""
returns url for admin pages
"""
if self.type == 1:
return '/admin/article/blog/%s'%self.slug
return '/admin/article/blog/%s' % self.slug
elif self.type == 2:
return '/admin/article/news/%s'%self.slug
return '/admin/article/news/%s' % self.slug
def get_permanent_url(self):
"""
returns object url on site(get_absolute_url analog)
"""
if self.type == 1:
return '/blogs/%s/'%self.slug
return '/blogs/%s/' % self.slug
elif self.type == 2:
return '/news/%s/'%self.slug
return '/news/%s/' % self.slug
def get_blog_preview(self):
"""
returns preview(fildemodel) if it exist gor current object
"""
preview = self.files.filter(purpose='preview')
if preview:
return preview[0]
@ -238,7 +205,6 @@ class Article(TranslatableModel):
return None
def get_blog_preview2(self):
preview = self.files.filter(purpose='preview2')
if preview:
return preview[0]
@ -246,18 +212,26 @@ class Article(TranslatableModel):
return None
def get_catalog(self):
"""
get catalog for current objects
catalogs different for news and blogs
"""
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 functions.signal_handlers import post_save_handler
"""
returns list of articles with same type and themes
:return:
"""
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])
post_save.connect(post_save_handler, sender=Article)

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
from django.db.models.signals import post_save
from models import Article
from functions.signal_handlers import post_save_handler
#post_save.connect(post_save_handler, sender=Article)

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

@ -3,22 +3,38 @@ from django.conf.urls import patterns, url
from views import BlogList, NewsList, BlogDetail, NewsDetail, NewsTagCatalog, BlogsFilterCatalog
urlpatterns = patterns('',
url(r'^blogs/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', BlogsFilterCatalog.as_view(), {'meta_id':75, 'filter':'tag'}),
url(r'^blogs/theme/(?P<slug>.*)/page/(?P<page>\d+)/$', BlogsFilterCatalog.as_view(), {'filter':'theme'}),
url(r'^blogs/page/(?P<page>\d+)/$', BlogList.as_view(), {'meta_id':79}),
url(r'^blogs/tag/(?P<slug>.*)/$', BlogsFilterCatalog.as_view(), {'meta_id':75, 'filter':'tag'}),
url(r'^blogs/theme/(?P<slug>.*)/$', BlogsFilterCatalog.as_view(), {'filter':'theme'}),
url(r'^blogs/$', BlogList.as_view(), {'meta_id':79}),
url(r'^blogs/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', BlogsFilterCatalog.as_view(),
{'meta_id': 75, 'filter': 'tag'}),
url(r'^blogs/theme/(?P<slug>.*)/page/(?P<page>\d+)/$', BlogsFilterCatalog.as_view(),
{'filter': 'theme'}),
url(r'^blogs/page/(?P<page>\d+)/$', BlogList.as_view(),
{'meta_id': 79}),
url(r'^blogs/tag/(?P<slug>.*)/$', BlogsFilterCatalog.as_view(),
{'meta_id': 75, 'filter': 'tag'}),
url(r'^blogs/theme/(?P<slug>.*)/$', BlogsFilterCatalog.as_view(),
{'filter': 'theme'}),
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}),
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,22 +1,25 @@
# -*- coding: utf-8 -*-
import json
from django.views.generic import DetailView
from django.conf import settings
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext as _
from functions.custom_views import ListView
from django.http import HttpResponse
from models import Article
from forms import ArticleFilterForm
from theme.models import Tag, Theme, ThemeBlog
from forms import BlogFilterForm, NewsFilterForm
from theme.models import Tag, ThemeBlog
from meta.views import MetadataMixin
class NewsList(MetadataMixin, ListView):
model = Article
template_name = 'article/news_list.html'
paginate_by = 10
template_name = 'client/article/news_list.html'
paginate_by = settings.CLIENT_PAGINATION
def get_queryset(self):
"""
filters queryset by get params if they exists
"""
if self.request.GET:
qs = self.model.objects.news()
themes = self.request.GET.getlist('theme')
@ -32,12 +35,15 @@ class NewsList(MetadataMixin, ListView):
return qs
else:
return self.model.objects.news().filter(publish_date__isnull=False).order_by('-publish_date')
return self.model.objects.news().filter(publish_date__isnull=False)
def get_context_data(self, **kwargs):
"""
add filter form to context
"""
context = super(NewsList, self).get_context_data(object_list=self.object_list)
if self.request.GET:
filter_form = ArticleFilterForm(self.request.GET)
filter_form = NewsFilterForm(self.request.GET)
tags = self.request.GET.getlist('tag')
if u'' in tags:
tags.remove(u'')
@ -48,7 +54,7 @@ class NewsList(MetadataMixin, ListView):
filter_form.fields['tag'].widget.attrs['data-predifined'] = json.dumps(tags)
filter_form.fields['tag'].widget.attrs['value'] = ''
else:
filter_form = ArticleFilterForm()
filter_form = NewsFilterForm()
context['article_filter_form'] = filter_form
return context
@ -57,15 +63,18 @@ class NewsList(MetadataMixin, ListView):
class NewsDetail(MetadataMixin, DetailView):
model = Article
slug_field = 'slug'
template_name = 'article/news.html'
template_name = 'client/article/news.html'
class BlogList(MetadataMixin, ListView):
model = Article
template_name = 'article/blog_list.html'
paginate_by = 10
template_name = 'client/article/blog_list.html'
paginate_by = settings.CLIENT_PAGINATION
def get_queryset(self):
"""
filters queryset by get params if they exists
"""
if self.request.GET:
qs = self.model.objects.blogs()
@ -85,9 +94,12 @@ class BlogList(MetadataMixin, ListView):
return self.model.objects.blogs()
def get_context_data(self, **kwargs):
"""
add filter form to context
"""
context = super(BlogList, self).get_context_data(object_list=self.object_list)
if self.request.GET:
filter_form = ArticleFilterForm(self.request.GET)
filter_form = BlogFilterForm(self.request.GET)
tags = self.request.GET.getlist('tag')
if u'' in tags:
tags.remove(u'')
@ -98,25 +110,23 @@ class BlogList(MetadataMixin, ListView):
filter_form.fields['tag'].widget.attrs['data-predifined'] = json.dumps(tags)
filter_form.fields['tag'].widget.attrs['value'] = ''
else:
filter_form = ArticleFilterForm()
filter_form = BlogFilterForm()
context['article_filter_form'] = filter_form
return context
class BlogDetail(MetadataMixin, DetailView):
model = Article
slug_field = 'slug'
template_name = 'article/article.html'
template_name = 'client/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):
"""
returns queryset filtered by filtered_object and dates
filtered_object can be theme or tag
"""
model = Article
template_name = 'client/article/catalog.html'
catalog_url = '/news/tag/'
@ -152,7 +162,6 @@ class NewsTagCatalog(MetadataMixin, ListView):
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
@ -162,7 +171,6 @@ class NewsTagCatalog(MetadataMixin, ListView):
return context
class BlogsFilterCatalog(MetadataMixin, ListView):
model = Article
template_name = 'client/article/catalog.html'
@ -206,7 +214,6 @@ class BlogsFilterCatalog(MetadataMixin, ListView):
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(BlogsFilterCatalog, self).get_context_data(**kwargs)
context['filter_object'] = self.filter_object

@ -1,15 +0,0 @@
from django.db import models
# Create your models here.
class Redirect(models.Model):
redirect = models.URLField()
count = models.PositiveIntegerField(default=0)
views = models.PositiveIntegerField(default=0)
def __unicode__(self):
return self.redirect
def get_object_url(self):
return '/redirect/redirect/%d/'%self.id

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

@ -1,7 +0,0 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
urlpatterns = patterns('',
url(r'redirect/(?P<id>.*)/$', 'banners.views.redirect'),
)

@ -1,10 +0,0 @@
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from banners.models import Redirect
from django.db.models import F
def redirect(request, id):
redirect = get_object_or_404(Redirect, id=id)
Redirect.objects.filter(id=id).update(count=F('count')+1)
return HttpResponseRedirect(redirect.redirect)

@ -1,78 +0,0 @@
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand, CommandError
from city.models import City
from country.models import Country
cities = [
{'id':'-1563952', 'country':'11', 'url':'canberra-australia', 'ru':u'Канберра', 'en':'Canberra'},
]
"""
cities = [
{'id':'-1563952', 'country':'11', 'url':'canberra-australia', 'ru':u'Канберра', 'en':'Canberra'},
{'id':'-1586844', 'country':'11', 'url':'melbourne-australia', 'ru':u'Мельбурн', 'en':'Melbourne'},
{'id':'-1594675', 'country':'11', 'url':'perth-australia', 'ru':u'Перт', 'en':'Perth'},
{'id':'-1555188', 'country':'11', 'url':'adelaide-australia', 'ru':u'Аделаида', 'en':'Adelaide'},
{'id':'-1561728', 'country':'11', 'url':'brisbane-australia', 'ru':u'Брисбен', 'en':'Brisbane'},
{'id':'-1569058', 'country':'11', 'url':'darwin-australia', 'ru':u'Дарвин', 'en':'Darwin'},
{'id':'-1989985', 'country':'10', 'url':'salzburg-austria', 'ru':u'Зальцбург', 'en':'Salzburg'},
{'id':'-1981445', 'country':'10', 'url':'innsbruck-austria', 'ru':u'Инсбрук', 'en':'Innsbruck'},
{'id':'-1982354', 'country':'10', 'url':'klagenfurt-austria', 'ru':u'Клагенфурте', 'en':'Klagenfurt'},
{'id':'-979186', 'country':'8', 'url':'buenos-aires-argentina', 'ru':u'Буэнос-Айрес', 'en':'Buenos Aires'},
{'id':'-1955925', 'country':'17', 'url':'charleroi-belgium', 'ru':u'Шарлеруа', 'en':'Charleroi'},
{'id':'-1953257', 'country':'17', 'url':'antwerp-belgium', 'ru':u'Антверпен', 'en':'Antwerp'},
{'id':'-1955538', 'country':'17', 'url':'brussels-belgium', 'ru':u'Брюссель', 'en':'Brussels'},
{'id':'-1958757', 'country':'17', 'url':'ghent-belgium', 'ru':u'Гент', 'en':'Ghent'},
{'id':'-1963947', 'country':'17', 'url':'leuven-belgium', 'ru':u'Левен', 'en':'Leuven'},
{'id':'-1964016', 'country':'17', 'url':'liege-belgium', 'ru':u'Льеж', 'en':'Liège'},
{'id':'-1965564', 'country':'17', 'url':'mons-belgium', 'ru':u'Монс', 'en':'Mons'},
{'id':'-1956109', 'country':'17', 'url':'ciney-belgium', 'ru':u'Сине', 'en':'Ciney'},
{'id':'-1959925', 'country':'17', 'url':'hasselt-belgium', 'ru':u'Хасселт', 'en':'Hasselt'},
{'id':'-629138', 'country':'27', 'url':'belo-horizonte-brazil', 'ru':u'Белу-Оризонти', 'en':'Belo Horizonte'},
{'id':'-663509', 'country':'27', 'url':'porto-alegre-brazil', 'ru':u'Порту-Алегри', 'en':'Porto Alegre'},
{'id':'-629039', 'country':'27', 'url':'Belem-brazil', 'ru':u'Белем', 'en':'Belém'},
{'id':'-644901', 'country':'27', 'url':'goiania-brazil', 'ru':u'Гояния', 'en':'Goiânia'},
{'id':'-653186', 'country':'27', 'url':'manaus-brazil', 'ru':u'Манаус', 'en':'Manaus'},
{'id':'-657942', 'country':'27', 'url':'olinda-brazil', 'ru':u'Olinda', 'en':'Olinda'},
{'id':'-657510', 'country':'27', 'url':'novo-hamburgo-brazil', 'ru':u'Novo Hamburgo', 'en':'Novo Hamburgo'},
{'id':'-2112243', 'country':'84', 'url':'surat-india', 'ru':u'Сурат', 'en':'Sūrat'},
{'id':'-3102179', 'country':'85', 'url':'basrah-iraq', 'ru':u'Басра', 'en':'Basrah'},
{'id':'-559845', 'country':'33', 'url':'abbotsford-canada', 'ru':u'Abbotsford', 'en':'Abbotsford'},
{'id':'-561990', 'country':'33', 'url':'calgary-canada', 'ru':u'Калгари', 'en':'Calgary'},
{'id':'-571851', 'country':'33', 'url':'quebec-canada', 'ru':u'Квебек', 'en':'Quebec'},
{'id':'-569541', 'country':'33', 'url':'montreal-canada', 'ru':u'Монреаль', 'en':'Montreal'},
{'id':'-570760', 'country':'33', 'url':'ottawa-canada', 'ru':u'Оттава', 'en':'Ottawa'},
{'id':'-567785', 'country':'33', 'url':'laval-canada', 'ru':u'Лаваль', 'en':'Laval'},
{'id':'-564968', 'country':'33', 'url':'fredericton-canada', 'ru':u'Фредериктон', 'en':'Fredericton'},
{'id':'-564064', 'country':'33', 'url':'edmonton-canada', 'ru':u'Эдмонтон', 'en':'Edmonton'},
{'id':'-569498', 'country':'33', 'url':'moncton-canada', 'ru':u'Монктон', 'en':'Moncton'},
{'id':'-562447', 'country':'33', 'url':'charlottetown-canada', 'ru':u'Шарлоттаун', 'en':'Charlottetown'},
{'id':'-2764584', 'country':'147', 'url':'karachi-pakistan', 'ru':u'Карачи', 'en':'Karachi'},
{'id':'-2767043', 'country':'147', 'url':'lahore-pakistan', 'ru':u'Лахор', 'en':'Lahore'},
]
"""
class Command(BaseCommand):
def handle(self, *args, **options):
for city in cities:
#City.objects.get(id=city['id']).delete()
country = Country.objects.get(id=city['country'])
c = City(id=city['id'], country=country, url=city['url'])
c.translate('ru')
c.name = city['ru']
print('pre save %s'%str(c))
c.save()
print('post save %s'%str(c))

@ -1,22 +0,0 @@
# -*- 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())

@ -1,30 +0,0 @@
# -*- 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'))

@ -12,8 +12,8 @@ HOTEL_URL = 'https://distribution-xml.booking.com/json/bookings.getHotels?'
HOTEL_PHOTO_URL = 'https://distribution-xml.booking.com/json/bookings.getHotelPhotos?'
username = 'expomap'
password = '33xp00m33p'
username = settings.BOOKING_USERNAME
password = settings.BOOKING_PASSWORD
langs = [code for code, name in settings.LANGUAGES]
def create_hotels(hotels, city):
@ -34,8 +34,8 @@ def create_hotels(hotels, city):
tr_model.objects.bulk_create(dj_hotels_translation)
print('city: %s'%str(city))
def main():
def main():
cities = City.objects.select_related('place_expositions', 'place_conferences').\
filter(Q(place_expositions__city__isnull=False) | Q(place_conferences__city__isnull=False)).distinct()
for city in cities:
@ -67,22 +67,4 @@ def main():
class Command(BaseCommand):
def handle(self, *args, **options):
main()
"""
request = urllib2.Request(URL)
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string)
try:
response = urllib2.urlopen(request)
code = response.getcode()
except urllib2.HTTPError, e:
code = e.code
except urllib2.URLError, e:
code = e.code
json_hotels = response.read()
hotels = json.loads(json_hotels)
print(hotels)
"""
main()

@ -4,13 +4,14 @@ from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from city.models import Hotel, City
from functions.files import get_alternative_filename
from concurrent.futures import ThreadPoolExecutor
username = 'expomap'
password = '33xp00m33p'
username = settings.BOOKING_USERNAME
password = settings.BOOKING_PASSWORD
HOTEL_URL = 'https://distribution-xml.booking.com/json/bookings.getHotels?'
HOTEL_PHOTO_URL = 'https://distribution-xml.booking.com/json/bookings.getHotelPhotos?'
from concurrent.futures import ThreadPoolExecutor
def upload(photo):
@ -37,15 +38,6 @@ def download_photos(photos):
result[i[0]] = i[1]
return result
"""
result = {}
for photo in photos:
res = upload(photo)
result[res[0]] = res[1]
return result
"""
def run(hotels):
ids = [str(hotel.id) for hotel in hotels]# comment after testing
url = HOTEL_PHOTO_URL+'hotel_ids=%s'%','.join(ids)

@ -1,11 +1,13 @@
import urllib2, base64
import urllib2
import base64
import json
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from city.models import Hotel
HOTEL_URL = 'https://distribution-xml.booking.com/json/bookings.getHotels?'
username = 'expomap'
password = '33xp00m33p'
username = settings.BOOKING_USERNAME
password = settings.BOOKING_PASSWORD
def handle_hotels(hotel_ids):
@ -41,11 +43,10 @@ def main():
while hotels_todo > 0:
hotel_ids = [str(item.id) for item in list(Hotel.objects.filter(currency__isnull=True)[:100])]
handle_hotels(hotel_ids)
hotels_todo =Hotel.objects.filter(currency__isnull=True)[:100].count()
hotels_todo = Hotel.objects.filter(currency__isnull=True)[:100].count()
class Command(BaseCommand):
def handle(self, *args, **options):
main()
# fill hotel currencies
main()

@ -1,12 +1,14 @@
import urllib2, base64
import urllib2
import base64
import json
from django.core.management.base import BaseCommand, CommandError
from django.core.management.base import BaseCommand
from django.conf import settings
from city.models import Hotel
URL = 'https://distribution-xml.booking.com/json/bookings.getRooms?'
username = 'expomap'
password = '33xp00m33p'
test_id = '298239'
username = settings.BOOKING_USERNAME
password = settings.BOOKING_PASSWORD
def get_prices(rooms):
min_price = None
@ -28,6 +30,7 @@ def get_prices(rooms):
return min_price, max_price
def handle_hotels(hotel_id):
hotel_ids_str = hotel_id
new_url = URL + 'hotel_ids=%s'%hotel_ids_str
@ -48,21 +51,17 @@ def handle_hotels(hotel_id):
Hotel.objects.filter(id=hotel_id).update(min_price=min_price, max_price=max_price)
print('success')
def main():
hotel_id = test_id
for hotel in Hotel.objects.all():
try:
handle_hotels(str(hotel.id))
except:
continue
#hotels_todo = Hotel.objects.filter(currency__isnull=True)[:100].count()
#while hotels_todo > 0:
#hotel_ids = [str(item.id) for item in list(Hotel.objects.filter(currency__isnull=True)[:100])]
#handle_hotels(hotel_ids)
#hotels_todo = Hotel.objects.filter(currency__isnull=True)[:100].count()
class Command(BaseCommand):
def handle(self, *args, **options):
# update hotels prices
# runs one time in a week
main()

@ -3,147 +3,149 @@ from datetime import date
from django.db import models
from django.db.models.signals import post_save, pre_save
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from bitfield import BitField
from sorl.thumbnail import ImageField
# models
from directories.models import Iata
from service.models import Service
from exposition.models import Exposition
from place_exposition.models import PlaceExposition
from organiser.models import Organiser
from conference.models import Conference
from seminar.models import Seminar
from webinar.models import Webinar
# custom functions
from functions.db import db_table_exists
from functions.signal_handlers import post_save_handler, pre_save_handler
from functions.models_methods import ExpoManager, CityManager
from service.models import Service
#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 []
flags = ['catalog', 'translator', 'participation', 'remote', 'tickets', 'visit', 'buildstand']
class City(TranslatableModel):
"""
Create City model
Uses hvad.TranslatableModel which is child of django.db.models class
City describes cities with translations in the project
all cities with id from booking.com -> id city on booking equal this city objects
"""
objects = ExpoManager()
used = CityManager()
catalog = '/city/'
services = BitField(flags=flags)
url = models.SlugField(unique=True)
#
old_url = models.CharField(max_length=55)
inflect = models.CharField(max_length=255, blank=True)
#relations
country = models.ForeignKey('country.Country', null=True, on_delete=models.PROTECT, related_name='cities')
code_IATA = models.ForeignKey(Iata, blank=True, null=True)
population = models.PositiveIntegerField(blank=True, null=True)
phone_code = models.PositiveIntegerField(blank=True, null=True)
url = models.SlugField(verbose_name=_(u'Url'), unique=True)
logo = models.ImageField(verbose_name='Logo', upload_to='city/logo/', blank=True, max_length=255)
old_url = models.CharField(verbose_name=_(u'Url старой бд'), max_length=55)
# inflect name for russian language. example- в Москве
inflect = models.CharField(verbose_name=_(u'Склонение'), max_length=255, blank=True)
country = models.ForeignKey('country.Country', verbose_name=_(u'Страна'), null=True, on_delete=models.PROTECT,
related_name='cities')
code_IATA = models.ForeignKey(Iata, verbose_name=_(u'IATA'), blank=True, null=True)
population = models.PositiveIntegerField(verbose_name=_(u'Население'), blank=True, null=True)
phone_code = models.PositiveIntegerField(verbose_name=_(u'Тел. код '), blank=True, null=True)
#translated fields
translations = TranslatedFields(
name = models.CharField(max_length=50),
region = models.CharField(max_length=255),
transport = models.TextField(blank=True),
description = models.TextField(blank=True),
famous_places = models.TextField(blank=True),
shoping = models.TextField(blank=True),
name = models.CharField(verbose_name=_(u'Название'), max_length=50),
region = models.CharField(verbose_name=_(u'Регион'), max_length=255),
transport = models.TextField(verbose_name=_(u'Транспорт'), blank=True),
description = models.TextField(verbose_name=_(u'Описание'), blank=True),
famous_places = models.TextField(verbose_name=_(u'Знаменитые места'), blank=True),
shoping = models.TextField(verbose_name=_(u'Магазины'), blank=True),
#-----meta
title = models.CharField(max_length=255),
descriptions = models.CharField(max_length=255),
keywords = models.CharField(max_length=255),
)
# fields saves information about creating and changing model
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
logo = models.ImageField(verbose_name='Logo', upload_to='city/logo/', blank=True, max_length=255)
class Meta:
ordering = ['translations__name']
#class Meta:
#ordering = ['translations__name']
def __unicode__(self):
return self.lazy_translation_getter('name', self.pk)
def get_hotels(self):
"""
returns list of 4 hotels in current city
"""
return list(self.hotels.all()[:4])
def get_events(self):
"""
returns nearest expos in this city
"""
now = date.today()
return Exposition.objects.filter(data_begin__gte=now, city=self).order_by('data_begin')[:3]
def get_places(self):
return PlaceExposition.objects.filter(city=self)[:3]
def get_organisers(self):
return Organiser.objects.filter(city=self)
def get_permanent_url(self):
return self.catalog+self.url
def events_catalog(self):
return Exposition.catalog+'city-%s'%self.url
def places_catalog(self):
return PlaceExposition.catalog+'city-%s'%self.url
def expositions_number(self):
return Exposition.objects.filter(city=self.id).count()
return Exposition.objects.filter(city=self).count()
def conferences_number(self):
return Conference.objects.filter(city=self.id).count()
return Conference.objects.filter(city=self).count()
def seminars_number(self):
return Seminar.objects.filter(city=self.id).count()
return Seminar.objects.filter(city=self).count()
def webinars_number(self):
return Webinar.objects.filter(city=self.id).count()
return Webinar.objects.filter(city=self).count()
def get_parent(self):
parent = {'text' : self.country.name, 'id': self.country.id, 'name': 'co',
'parent':{'text' : self.country.area.name, 'id': self.country.area.id, 'name': 'area'}}
"""
returns dictionary of parents
uses in search in ajax requests
"""
parent = {'text': self.country.name, 'id': self.country.id, 'name': 'co',
'parent': {
'text': self.country.area.name,
'id': self.country.area.id,
'name': 'area'}
}
return parent
def get_sub_categories(self):
"""
uses in search
city has no children objects, so returns empty list
"""
return []
def get_index_text(self):
"""
returns string of names in all languages for indexing it in search engine
"""
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
return names
class Hotel(TranslatableModel):
url = models.URLField(max_length=255)
city = models.ForeignKey(City, related_name='hotels')
ranking = models.FloatField(blank=True, null=True)
hotel_class = models.CharField(max_length=10, blank=True)
latitude = models.FloatField(blank=True, null=True)
longitude = models.FloatField(blank=True, null=True)
photo = ImageField(upload_to='hotels')
currency = models.CharField(max_length=10)
min_price = models.FloatField(blank=True, null=True)
max_price = models.FloatField(blank=True, null=True)
checked = models.NullBooleanField(blank=True, null=True)
"""
Hotels downloaded from booking.com with booking api
"""
url = models.URLField(verbose_name=_(u'Url'), max_length=255)
city = models.ForeignKey(City, verbose_name=_(u'Город'), related_name='hotels')
ranking = models.FloatField(verbose_name=_(u'Рейтинг'), blank=True, null=True)
hotel_class = models.CharField(verbose_name=_(u'Клас отеля'), max_length=10, blank=True)
latitude = models.FloatField(verbose_name=_(u'Широта'), blank=True, null=True)
longitude = models.FloatField(verbose_name=_(u'Долгота'), blank=True, null=True)
photo = ImageField(verbose_name=_(u'Фото'), upload_to='hotels')
currency = models.CharField(verbose_name=_(u'Валюта'), max_length=10)
min_price = models.FloatField(verbose_name=_(u'Мин. цена'), blank=True, null=True)
max_price = models.FloatField(verbose_name=_(u'Макс. цена'), blank=True, null=True)
checked = models.NullBooleanField(verbose_name=_(u'Проверено'), blank=True, null=True)
translations = TranslatedFields(
name = models.CharField(max_length=255, blank=True),
address = models.CharField(max_length=255, blank=True)
name=models.CharField(verbose_name=_(u'Название'), max_length=255, blank=True),
address=models.CharField(verbose_name=_(u'Адрес'), max_length=255, blank=True)
)

@ -1,3 +0,0 @@
# -*- coding: utf-8 -*-

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

@ -4,6 +4,6 @@ from views import CityView
urlpatterns = patterns('',
url(r'get-city/', 'city.views.get_city'),
url(r'(?P<slug>.*)', CityView.as_view()),
# commented for good times
#url(r'(?P<slug>.*)', CityView.as_view()),
)

@ -8,12 +8,18 @@ from settings.views import get_by_lang
class CityView(DetailView):
"""
this view is not used yet
"""
model = City
slug_field = 'url'
template_name = 'city/city.html'
template_name = 'client/city/city.html'
def get_city(request):
"""
returns filtered cities in current language in json format
"""
if request.is_ajax():
country = request.GET.get('country')
term = request.GET.get('term', '').capitalize()

@ -1,97 +0,0 @@
from django.core.management.base import BaseCommand, CommandError
from company.models import Company
from theme.models import Theme, Tag
from accounts.models import User
from functions.form_check import translit_with_separator
import datetime
import MySQLdb
from MySQLdb.cursors import DictCursor
def convert_to_int(st):
if not st:
return None
deduct = ('-','(',')','.',' ')
for elem in deduct:
st = st.replace(elem, '')
if st.isdigit():
return int(st)
else:
return None
class Command(BaseCommand):
def handle(self, *args, **options):
db = MySQLdb.connect(host="localhost",
user="root",
passwd="qazedc",
db="expomap_ru",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
sql = "select * from customers_company"
cursor.execute(sql)
res = cursor.fetchall()
for c in res:
phone = convert_to_int(c.get('phone'))
fax = convert_to_int(c.get('fax'))
url = c['url']
if not url:
url = translit_with_separator(c.get('title'))
company = Company(id=c['company_id'], url=url, phone=phone, fax=fax,
email=c.get('email'), web_page=c.get('website'), twitter=c.get('twitter', ''))
company.translate('ru')
company.name = c.get('title')
company.specialization = c.get('specialize')
company.description = c.get('about')
company.address_inf = c.get('adress')
user = User.objects.safe_get(id=user_id)
company.creator = user
print('not_saved: %s'%c['title'])
company.save()
user_id = c['customers_id']
print('saved: %s'%str(company))
if user:
user.company = company
if not user.last_login:
now = datetime.datetime.now()
user.last_login = now
user.save()
theme = None
theme_id = c.get('otrasly')
if theme_id:
try:
theme = Theme.objects.get(id=theme_id)
except Theme.DoesNotExist:
continue
company.theme.add(theme)
if not theme:
continue
tags = c.get('tags')
if tags:
tags = tags.split(',')
if tags:
for tag_id in tags:
try:
tag = Tag.objects.get(id=tag_id)
except Tag.DoesNotExist:
continue
if tag.theme == theme:
company.tag.add(tag)
else:
continue
#print(str(type(res[0]['phone'])))
print('success')

@ -1,77 +0,0 @@
from django.core.management.base import BaseCommand, CommandError
from company.models import Company
from theme.models import Theme, Tag
from accounts.models import User
from functions.form_check import translit_with_separator
import datetime
import MySQLdb
from MySQLdb.cursors import DictCursor
def convert_to_int(st):
if not st:
return None
deduct = ('-','(',')','.',' ')
for elem in deduct:
st = st.replace(elem, '')
if st.isdigit():
return int(st)
else:
return None
class Command(BaseCommand):
def handle(self, *args, **options):
db = MySQLdb.connect(host="localhost",
user="root",
passwd="qazedc",
db="expomap_ru",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
sql = "select * from customers_company WHere otrasly>0"
cursor.execute(sql)
res = cursor.fetchall()
print(len(res))
for c in res:
id = c['company_id']
company = Company.objects.safe_get(id=id)
if not company:
continue
theme_id = c.get('otrasly')
tags = c.get('tags')
if theme_id:
try:
theme = Theme.objects.get(id=theme_id)
except Theme.DoesNotExist:
continue
print(theme)
print(company)
company.theme.add(theme)
print('add %s theme to %s company'%(str(theme), str(company)))
print('123')
if not theme:
continue
tags = c.get('tags')
if tags:
tags = tags.split(',')
if tags:
for tag_id in tags:
try:
tag = Tag.objects.get(id=tag_id)
except Tag.DoesNotExist:
continue
if tag.theme == theme:
company.tag.add(tag)
print('add %s tag to %s company'%(str(tag), str(company)))
else:
continue

@ -272,7 +272,6 @@ class ConferenceView(AdminView):
else:
return form_class()
def get_context_data(self, **kwargs):
context = super(ConferenceView, self).get_context_data(**kwargs)
obj = self.set_obj()
@ -294,6 +293,7 @@ class ConferenceListView(AdminListView):
form_class = ConferenceFilterForm
model = Conference
def upload_conference_photo(request, conf_id):
return upload_photo(request, conf_id, Conference)

@ -34,10 +34,9 @@ class ConferenceCreateForm(forms.Form):
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 года'))
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 года'), (0.2, u'Раз в 5 лет'))
public = [(item1, item2) for item1, item2 in BIT_AUDIENCE]
@ -68,8 +67,8 @@ class ConferenceCreateForm(forms.Form):
web_page = forms.CharField(label='Веб страница', required=False)
link = forms.CharField(label='Линк на регистрацию', required=False)
foundation_year = forms.CharField(label='Год основания', required=False)
members = forms.CharField(label='Посетители', required=False)
visitors = forms.CharField(label='Участники', required=False)
members = forms.CharField(label='Участники', required=False)
visitors = forms.CharField(label='Посетители', required=False)
discount = forms.CharField(label='Cкидка(%)', required=False)
#
currency = forms.ChoiceField(label='Валюта', choices=currencies, required=False)

@ -2,6 +2,7 @@
import datetime
from django.utils.translation import ugettext as _
from django.db import models
from django.conf import settings
from django.db.models import Q
from django.db.models.signals import post_save, pre_save
from django.contrib.contenttypes import generic
@ -22,8 +23,9 @@ from functions.model_mixin import EventMixin, ExpoMixin
from functions.models_methods import hvad_to_dict
# check if table exist and create flags if true
flags = [item.url for item in Service.objects.all()] if db_table_exists('service_service') else []
from django.conf import settings
#flags = [item.url for item in Service.objects.all()] if db_table_exists('service_service') else []
flags = ['catalog', 'translator', 'participation', 'remote', 'tickets', 'visit', 'buildstand']
CURRENCY = settings.CURRENCY
BIT_AUDIENCE = settings.BIT_AUDIENCE
@ -66,7 +68,7 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
blank=True, null=True, related_name='conference_companies')
users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки',
blank=True, null=True, related_name='conference_users')
photogallery = models.ForeignKey('photologue.Gallery', blank=True, null=True)
photogallery = models.ForeignKey('photologue.Gallery', blank=True, null=True, on_delete=models.SET_NULL)
logo = models.ImageField(verbose_name='Logo', upload_to='conference/logo/', blank=True)
rating = models.IntegerField(default=0, db_index=True) # добавить индекс в базе
@ -150,7 +152,6 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
else:
return []
def get_catalog_url(self):
return '/conference/'
@ -193,25 +194,8 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
tags = ' '.join([' '.join(tag.get_all_names()) for tag in self.tag.all()])
return names + ' ' + titles + ' ' + themes + ' ' + tags
def get_gallery(self):
if self.photogallery:
return self.photogallery
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
def upload_photo_url(self):
return '/admin/conference/upload-photo/%s/' % self.id
class Statistic(TranslatableModel):

@ -2,7 +2,7 @@
from django.conf.urls import patterns, include, url
from views import ConferenceDetail, ConferenceList, ConferenceByCity, ConferenceByCountry, ConferenceByTheme,\
ConferenceCountryCatalog, ConferenceCityCatalog, ConferenceTagCatalog, ConferenceThemeCatalog, ConferenceMembers,\
ConferenceVisitors, ConferenceServiceView, ConferenceThankView, ConferenceByTag
ConferenceVisitors, ConferenceServiceView, ConferenceThankView, ConferenceByTag, ConferencePhotoView
from exposition.views import ExpositionSearchView
urlpatterns = patterns('',
@ -61,6 +61,8 @@ urlpatterns = patterns('',
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>.*)/photo/page/(?P<page>\d+)/$', ConferencePhotoView.as_view()),
url(r'^conference/(?P<slug>.*)/photo/$', ConferencePhotoView.as_view()),
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()),

@ -28,7 +28,7 @@ MONTHES = settings.MONTHES
class ConferenceBy(JitterCacheMixin, MetadataMixin, ListView):
cache_range = settings.CACHE_RANGE
template_name = 'conference/conference_by.html'
template_name = 'client/conference/conference_by.html'
title1 = ''
title2 = ''
@ -437,6 +437,30 @@ class ConferenceList(MetadataMixin, JitterCacheMixin, ListView):
return context
class ConferencePhotoView(MetadataMixin, ListView):
template_name = 'client/conference/photo.html'
obj = None
paginate_by = settings.CLIENT_PAGINATION
def get_queryset(self):
slug = self.kwargs.get('slug')
conf = get_object_or_404(Conference, url=slug)
self.obj = conf
if conf.photogallery:
return conf.photogallery.photos.all()
else:
raise Http404()
def get_context_data(self, **kwargs):
context = super(ConferencePhotoView, self).get_context_data(**kwargs)
obj = self.obj
context['object'] = obj
context['city'] = str(obj.city_id)
context['country'] = str(obj.country_id)
context['themes'] = [str(item.id) for item in obj.theme.all()]
return context
def conference_add_calendar(request, id):
args = {'success': False}
user = request.user

@ -100,7 +100,6 @@ def queryset_to_workbook(queryset, columns, report_date = None):
sheet_name = u'My calendar {0}'.format(report_date.strftime('%Y-%B'))
sheet = workbook.add_sheet(sheet_name)
# drawing head part with image
sheet.write_merge(0, 6, 0, 6, main_header.format(
month = month_name,year = report_date.strftime("%Y")), main_style)

@ -1 +0,0 @@
__author__ = 'kotzilla'

@ -1 +0,0 @@
__author__ = 'kotzilla'

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from country.models import Country
class Command(BaseCommand):
def handle(self, *args, **options):
# local database(will not work on production)
db = MySQLdb.connect(host="localhost",
user="root",
passwd="qazedc",
db="test",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
# !!!database can change
sql = "SELECT country_code as code, geo_lat as latitude, geo_lng as longitude FROM test.country_country LEFT JOIN localization.meta_location ON test.country_country.country_code=localization.meta_location.iso COLLATE utf8_unicode_ci WHERE localization.meta_location.type='CO' AND geo_lat IS NOT NULL;"
cursor.execute(sql)
result = cursor.fetchall()
for item in result:
updates = Country.objects.filter(country_code=item['code']).update(latitude=item['latitude'], longitude=item['longitude'])
if updates:
print(item['code'])

@ -1,39 +0,0 @@
# -*- 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

@ -1,19 +1,12 @@
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:

@ -1,34 +1,36 @@
# -*- coding: utf-8 -*-
from datetime import date
from django.db import models
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes import generic
from django.db.models.signals import post_save, pre_save
from hvad.models import TranslatableModel, TranslatedFields
from bitfield import BitField
from manager import CountryManager, AreaManager
# models
from directories.models import Language, Currency
from city.models import City
from service.models import Service
from exposition.models import Exposition
from place_exposition.models import PlaceExposition
from organiser.models import Organiser
from conference.models import Conference
from seminar.models import Seminar
from webinar.models import Webinar
# func
from functions.db import db_table_exists
from functions.signal_handlers import post_save_handler, pre_save_handler
from django.utils import translation
from service.models import Service
from functions.db import db_table_exists
# 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 []
flags = ['catalog', 'translator', 'participation', 'remote', 'tickets', 'visit', 'buildstand']
class Area(TranslatableModel):
"""
Store information about geographical zones
"""
translations = TranslatedFields(
name = models.CharField(max_length=255),
name=models.CharField(verbose_name=_(u'Название'), max_length=255),
)
objects = AreaManager()
@ -39,23 +41,40 @@ class Area(TranslatableModel):
return self.lazy_translation_getter('name', unicode(self.pk))
def countries(self):
"""
returns countries of current area
"""
lang = translation.get_language()
return Country.objects.select_related('exposition_country')\
.filter(exposition_country__country__isnull=False, translations__language_code=lang, area=self).distinct().order_by('translations__name')
.filter(exposition_country__country__isnull=False, translations__language_code=lang, area=self)\
.distinct().order_by('translations__name')
def expos(self):
"""
return expos that occur in current area
"""
countries = self.countries()
return Exposition.objects.filter(country__in=countries)
def get_sub_categories(self):
objects = [{'text':item.name, 'id':item.id, 'name':'co', 'sub':True} for item in self.countries()]
"""
returns list with countries data that connected to current area
uses in search
"""
objects = [{'text': item.name, 'id': item.id, 'name': 'co', 'sub': True} for item in self.countries()]
return objects
def get_parent(self):
parent = {}
return parent
"""
returns empty dict, cause area has no parents
uses in search
"""
return {}
def get_index_text(self):
"""
returns string of names in all languages for indexing it in search engine
"""
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
@ -64,51 +83,46 @@ class Area(TranslatableModel):
class Country(TranslatableModel):
"""
Create Country model
Uses hvad.TranslatableModel which is child of django.db.models class
Stores information about countries
area- parent, city - child in search
"""
objects = CountryManager()
catalog = '/country/'
services = BitField(flags=flags)
url = models.SlugField(unique=True)
old_url = models.CharField(unique=True, max_length=55)
inflect = models.CharField(max_length=255, blank=True)
# relations
area = models.ForeignKey(Area)
big_cities = models.ManyToManyField(City, blank=True, null=True, related_name='cities')
capital = models.ForeignKey(City,blank=True, null=True, on_delete=models.PROTECT, related_name='capital')
url = models.SlugField(verbose_name=_(u'Url'), unique=True)
old_url = models.CharField(verbose_name=_(u'Старый урл'), unique=True, max_length=55)
# inflect name for russian language. example- в Росии
inflect = models.CharField(verbose_name=_(u'Склонение'), max_length=255, blank=True)
area = models.ForeignKey(Area, verbose_name=_(u'Географическая зона'))
logo = models.ImageField(verbose_name='Logo', upload_to='country/logo/', blank=True, max_length=255)
big_cities = models.ManyToManyField(City, verbose_name=_(u'Большые города'), blank=True, null=True, related_name='cities')
capital = models.ForeignKey(City, verbose_name=_(u'Столица'), blank=True, null=True, on_delete=models.PROTECT, related_name='capital')
language = models.ManyToManyField(Language, blank=True, null=True)
currency = models.ManyToManyField(Currency, blank=True, null=True)
population = models.PositiveIntegerField(blank=True, null=True)
teritory = models.PositiveIntegerField(blank=True, null=True)
timezone = models.FloatField(blank=True, null=True)
phone_code = models.PositiveIntegerField(blank=True, null=True)
currency = models.ManyToManyField(Currency, verbose_name=_(u'Валюта'), blank=True, null=True)
population = models.PositiveIntegerField(verbose_name=_(u'Население'), blank=True, null=True)
teritory = models.PositiveIntegerField(verbose_name=_(u'Територия'), blank=True, null=True)
timezone = models.FloatField(verbose_name=_(u'Часовой пояс'), blank=True, null=True)
phone_code = models.PositiveIntegerField(verbose_name=_(u'Тел. Код страны'), blank=True, null=True)
time_delivery = models.PositiveSmallIntegerField(blank=True, null=True)
latitude = models.FloatField(blank=True, null=True)
longitude = models.FloatField(blank=True, null=True)
latitude = models.FloatField(verbose_name=_(u'Широта'), blank=True, null=True)
longitude = models.FloatField(verbose_name=_(u'Долгота'), blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
country_code = models.CharField(max_length=2)
country_code = models.CharField(verbose_name=_(u'Код страны(Alpha2)'), max_length=2)
# connection with FileModel by ContentType
files = generic.GenericRelation('file.FileModel',content_type_field='content_type', object_id_field='object_id')
#translated fields
translations = TranslatedFields(
name = models.CharField(max_length=255),
description = models.TextField(blank=True),
transport = models.TextField(blank=True),
#------visa inf
rules = models.TextField(blank=True),
documents = models.TextField(blank=True),#pdf?
consulate = models.TextField(blank=True),
name=models.CharField(max_length=255),
description=models.TextField(blank=True),
transport=models.TextField(blank=True),
rules=models.TextField(blank=True),
documents=models.TextField(blank=True),
consulate=models.TextField(blank=True),
#-----meta data
title = models.CharField(max_length=255),
descriptions = models.CharField(max_length=255),
keywords = models.CharField(max_length=255),
title=models.CharField(max_length=255),
descriptions=models.CharField(max_length=255),
keywords=models.CharField(max_length=255),
)
logo = models.ImageField(verbose_name='Logo', upload_to='country/logo/', blank=True, max_length=255)
class Meta:
ordering = ['translations__name']
@ -117,63 +131,52 @@ class Country(TranslatableModel):
return self.lazy_translation_getter('name', unicode(self.pk))
def get_events(self):
"""
returns nearest expos in this country
"""
now = date.today()
return Exposition.objects.filter(data_begin__gte=now, country=self).order_by('data_begin')[:3]
def get_places(self):
return PlaceExposition.objects.filter(country=self)[:3]
def get_organisers(self):
return Organiser.objects.filter(country=self)
def get_permanent_url(self):
return self.catalog+self.url
def events_catalog(self):
return Exposition.catalog+'country-%s'%self.url
def places_catalog(self):
return PlaceExposition.catalog+'country-%s'%self.url
def expositions_number(self):
return len(Exposition.objects.filter(country=self.id))
return Exposition.objects.filter(country=self).count()
def conferences_number(self):
return Conference.objects.filter(country=self.id).count()
return Conference.objects.filter(country=self).count()
def seminars_number(self):
return Seminar.objects.filter(country=self.id).count()
return Seminar.objects.filter(country=self).count()
def webinars_number(self):
return Webinar.objects.filter(country=self.id).count()
return Webinar.objects.filter(country=self).count()
def active_cities(self):
result = list(set(City.used.active_qs().filter(country=self)))
result.sort(key=lambda x:x.name)
result.sort(key=lambda x: x.name)
return result
lang = translation.get_language()
#return City.objects.select_related('exposition_city')\
# .filter(exposition_city__city__isnull=False, translations__language_code=lang, country=self).distinct().order_by('translations__name')
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()]
return objects
def get_parent(self):
parent = {'text' : self.area.name, 'id': self.area.id, 'name': 'area'}
parent = {'text': self.area.name, 'id': self.area.id, 'name': 'area'}
return parent
def get_index_text(self):
"""
returns string of names in all languages for indexing it in search engine
"""
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
return names
pre_save.connect(pre_save_handler, sender=Country)
post_save.connect(post_save_handler, sender=Country)

@ -1 +0,0 @@
# -*- coding: utf-8 -*-

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

@ -4,5 +4,6 @@ from views import CountryView
urlpatterns = patterns('',
# does not uses yet
url(r'(?P<slug>.*)', CountryView.as_view()),
)

@ -3,6 +3,9 @@ from models import Country
class CountryView(DetailView):
"""
this view is not used yet
"""
model = Country
slug_field = 'url'
template_name = 'country/country.html'
template_name = 'client/country/country.html'

@ -1,36 +0,0 @@
# -*- coding: utf-8 -*-
import MySQLdb
from MySQLdb.cursors import DictCursor
from django.core.management.base import BaseCommand, CommandError
from directories.models import Currency
class Command(BaseCommand):
def handle(self, *args, **options):
# local database(will not work on production)
db = MySQLdb.connect(host="localhost",
user="root",
passwd="qazedc",
db="test",
charset='utf8',
cursorclass=DictCursor)
cursor = db.cursor()
# !!!database can change
sql = "SELECT code, name FROM localization.currencies;"
cursor.execute(sql)
result = cursor.fetchall()
for item in result:
try:
currency = Currency.objects.get(code=item['code'])
print('currency with code %s already exist'%currency.code)
continue
except Currency.DoesNotExist:
currency = Currency(code=item['code'])
currency.translate('ru')
currency.name = item['name']
currency.save()
currency.translate('en')
currency.name = item['name']
currency.save()
print(currency.code)

@ -5,7 +5,7 @@ from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
class Language(TranslatableModel):
"""
Creates Language model
stores information about languages used in Country model
"""
language = models.CharField(max_length=255)# native language name
code = models.CharField(max_length=2)
@ -19,7 +19,7 @@ class Language(TranslatableModel):
class Currency(TranslatableModel):
"""
Creates Currency model
stores information about curencies used in Country model
"""
code = models.CharField(max_length=3)
@ -32,11 +32,10 @@ class Currency(TranslatableModel):
class Iata (models.Model):
"""
Creates Iata model
stores information about iata codes used in City model
"""
airport = models.CharField(max_length=255)
code = models.CharField(max_length=4)
def __unicode__(self):
return self.code
return self.code

@ -1,18 +1,20 @@
# -*- coding: utf-8 -*-
import json
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
from django.views.generic import ListView, DetailView, TemplateView, FormView
from accounts.models import User
from django.shortcuts import get_object_or_404
from django.views.generic import TemplateView, FormView
from django.db.models import Q
from django.utils import timezone
from forms import ComposeForm, ReplyForm, SendForm
from accounts.models import User
from forms import ReplyForm, SendForm
from models import Message
import json
class InboxView(TemplateView):
template_name = 'accounts/messages.html'
"""
returns template with user messages
"""
template_name = 'client/accounts/messages.html'
def get_context_data(self, **kwargs):
context = super(InboxView, self).get_context_data(**kwargs)
@ -20,51 +22,18 @@ class InboxView(TemplateView):
context['senders'] = [{'sender': s, 'message': Message.objects.filter(recipient=self.request.user, sender=s)[0]}\
for s in senders]
reply_form = ReplyForm()
context['reply_form'] = reply_form
return context
def message_reply(request, message_id):
response = {'success': False}
if request.POST:
form = ReplyForm(request.POST)
if form.is_valid():
parent_msg =get_object_or_404(Message, id=message_id)# Message.objects.get(id=parent)
form.save(sender=request.user, parent_msg=parent_msg)
response['success'] = True
return HttpResponse(json.dumps(response), content_type='application/json')
else:
return HttpResponse('error')
return HttpResponse('not ajax')
def send_message(request, url):
response = {'success': False}
try:
url = int(url)
recipient = get_object_or_404(User, id=url)
except ValueError:
recipient = get_object_or_404(User, url=url)
if request.POST:
form = SendForm(request.POST)
if form.is_valid():
form.save(sender=request.user, recipient=recipient)
response['success'] = True
return HttpResponse(json.dumps(response), content_type='application/json')
else:
return HttpResponse('error')
return HttpResponse('not ajax')
class MessageHistory(FormView):
template_name = 'accounts/messages_history.html'
"""
returns message history with one user and form to reply to it
"""
template_name = 'client/accounts/messages_history.html'
form_class = ReplyForm
success_url = ''
def get_initial(self):
return {'recipient':self.kwargs.get('user_id')}
@ -84,13 +53,13 @@ class MessageHistory(FormView):
def form_invalid(self, form):
user_id = self.kwargs.get('user_id')
return HttpResponseRedirect('/profile/messages/history/'+user_id+'/')
def form_valid(self, form):
form.save(sender=self.request.user)
user_id = self.kwargs.get('user_id')
return HttpResponseRedirect('/profile/messages/history/'+user_id+'/')
"""
class ReplyView(FormView):
form_class = ComposeForm
@ -108,3 +77,42 @@ class ReplyView(FormView):
context['parent_msg'] = parent_msg
return context
"""
def message_reply(request, message_id):
"""
reply to message
"""
response = {'success': False}
if request.POST:
form = ReplyForm(request.POST)
if form.is_valid():
parent_msg = get_object_or_404(Message, id=message_id)
form.save(sender=request.user, parent_msg=parent_msg)
response['success'] = True
return HttpResponse(json.dumps(response), content_type='application/json')
else:
return HttpResponse('error')
return HttpResponse('not ajax')
def send_message(request, url):
"""
send message to user with url=url
"""
response = {'success': False}
try:
url = int(url)
recipient = get_object_or_404(User, id=url)
except ValueError:
recipient = get_object_or_404(User, url=url)
if request.POST:
form = SendForm(request.POST)
if form.is_valid():
form.save(sender=request.user, recipient=recipient)
response['success'] = True
return HttpResponse(json.dumps(response), content_type='application/json')
else:
return HttpResponse('error')
return HttpResponse('not ajax')

@ -27,7 +27,10 @@ def get_banners(request):
good_urls = []
for u in urls:
if u.regex:
url_re = re.compile(u.url)
try:
url_re = re.compile(u.url)
except:
continue
if url_re.findall(url):
good_urls.append(u)
elif url == u.url:

@ -243,22 +243,8 @@ class ExpositionView(AdminView):
template_name = 'admin/exposition/exposition.html'
def form_valid(self, form):
#StatisticFormSet = formset_factory(StatisticForm)
#formset_statistic = StatisticFormSet(self.request.POST)
self.set_obj()
expo = form.save(obj=self.obj)
"""
# delete old halls
Statistic.objects.filter(exposition=getattr(expo, 'id')).delete()
for item in formset_statistic.forms:
# saves new statistic if its valid and not empty
if item.is_valid() and item.has_changed():
statistic = item.save(commit=False)
statistic.exposition = expo
statistic.save()
"""
return HttpResponseRedirect(self.success_url)
def get_form(self, form_class):
@ -321,35 +307,22 @@ class ExpositionView(AdminView):
data['keywords_%s' % code] = trans_obj.keywords
data['descriptions_%s' % code] = trans_obj.descriptions
form =form_class(initial=data)
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(ExpositionView, self).get_context_data(**kwargs)
obj = self.set_obj()
if obj:
#StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('exposition',))
# get existing statistic
#statistic = Statistic.objects.filter(exposition=getattr(obj, 'id'))
# fill HallFormSet
#formset_statistic = StatisticFormSet(queryset=statistic)
context['stat_form'] = StatisticForm()
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'))
context['files'] = files
else:
#StatisticFormSet = formset_factory(StatisticForm)
#formset_statistic = StatisticFormSet()
pass
#context['formset_statistic'] = formset_statistic
context['photo_form'] = PhotoForm()
context['timetable_form'] = TimeTableForm()
context['timetables'] = TimeTable.objects.filter(exposition=obj)
@ -387,23 +360,6 @@ def search_expo(request):
return HttpResponse(json.dumps(result), content_type='application/json')
from django.views.generic import FormView
from forms import PaidForm
class PaidView(FormView):
form_class = PaidForm
success_url = '/admin/exposition/all/'
template_name = 'admin/exposition/paid.html'
def form_valid(self, form):
expo = Exposition.objects.get(url=self.kwargs.get('url'))
paid = form.save(commit=False)
paid.expo = expo
paid.save()
return HttpResponseRedirect(self.success_url)
def expo_copy(request):
response = {'redirect': ''}
expo = Exposition.objects.get(id=request.GET['id'])

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from admin import ExpositionListView, ExpositionView, PaidView
from admin import ExpositionListView, ExpositionView
urlpatterns = patterns('exposition.admin',
url(r'^upload-photo/(?P<expo_id>.*)/$', 'upload_exposition_photo'),
url(r'^copy/$', 'expo_copy'),
url(r'^(?P<url>.*)/paid/$', PaidView.as_view()),
#url(r'^add.*/$', 'exposition_add'),
url(r'^delete/(?P<url>.*)/$', 'exposition_delete'),

@ -32,10 +32,9 @@ class ExpositionCreateForm(forms.Form):
save function saves data in Exposition 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 года'))
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 года'), (0.2, u'Раз в 5 лет'))
public = [(item1, item2) for item1, item2 in BIT_AUDIENCE]
currencies = [(item, item) for item in CURRENCY]
@ -615,12 +614,4 @@ class ExpositionFilterForm(AdminFilterForm):
if month:
qs = qs.filter(data_begin__month=month)
return qs
from exposition.models import Paid
class PaidForm(forms.ModelForm):
class Meta:
model = Paid
exclude = ('expo',)
return qs

@ -4,7 +4,7 @@ from city.models import City
from country.models import Country
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 place_exp_sett
from django.conf import settings

@ -17,8 +17,7 @@ from functions.custom_fields import EnumField
from functions.signal_handlers import post_save_handler, pre_save_handler
from functions.models_methods import ExpoManager
from functions.model_mixin import EventMixin, ExpoMixin
from functions.translate import fill_with_signal
from photologue.models import Gallery
from import_xls.model_utils import ExpoImportManager
from functions.models_methods import hvad_to_dict
@ -37,7 +36,8 @@ BIT_AUDIENCE = settings.BIT_AUDIENCE
CURRENCY = settings.CURRENCY
# check if table exist and create flags if true
flags = [item.url 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 []
flags = ['catalog', 'translator', 'participation', 'remote', 'tickets', 'visit', 'buildstand']
class Exposition(TranslatableModel, EventMixin, ExpoMixin):
@ -79,7 +79,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
blank=True, null=True, related_name='exposition_companies')
users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки',
blank=True, null=True, related_name='exposition_users')
photogallery = models.ForeignKey('photologue.Gallery', blank=True, null=True)
photogallery = models.ForeignKey('photologue.Gallery', blank=True, null=True, on_delete=models.SET_NULL)
logo = models.ImageField(verbose_name='Logo', upload_to='exposition/logo/', blank=True)
rating = models.IntegerField(default=0) # добавить индекс в базе
@ -208,48 +208,13 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
return ''
def upload_photo_url(self):
return '/admin/exposition/upload-photo/%s/'%self.id
def get_gallery(self):
if self.photogallery:
return self.photogallery
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
return '/admin/exposition/upload-photo/%s/' % self.id
def tags(self):
return self.tag.language().all()
def statistic_exists(self):
return Statistic.objects,filter(exposition=self).exists()
def upload_photo(self, photo ,gallery=None):
"""
uploading photo to gallery
"""
if gallery is None:
gallery = self.get_gallery()
gallery.photos.add(photo)
# def get_index_text(self):
# names = [tr.name for tr in self.translations.all()]
# return names
return Statistic.objects.filter(exposition=self).exists()
def get_audience(self):
checked = [item for item, bool in self.audience if bool==True]
@ -261,11 +226,10 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
return ', '.join(audience)
def get_periodic(self):
periodic = {0: '', 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 года')}
0.33: _(u'Раз в 3 года'), 0.25: _(u'Раз в 4 года'), 0.2: _(u'Раз в 5 лет')}
return periodic.get(self.periodic)
def get_nearest_events(self):
@ -280,8 +244,6 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def get_catalog_url(self):
return self.catalog
#return '/expositions/'
def get_event_type(self):
return _(u'Выставки')
@ -344,7 +306,7 @@ class TimeTable(TranslatableModel):
TimeTable for business program
"""
exposition = models.ForeignKey(Exposition, related_name='business_program')
exposition = models.ForeignKey(Exposition, related_name='TimeTable')
begin = models.DateTimeField(verbose_name='Начало')
end = models.DateTimeField(verbose_name='Конец')
timetable_organiser = models.ForeignKey(Organiser, null=True, blank=True)
@ -386,14 +348,6 @@ def logo_name(instance, filename):
url = instance.expo.url
return '/'.join(['exposition', url, url+'_org_logo.jpg'])
class Paid(models.Model):
expo = models.OneToOneField(Exposition)
org_logo = models.ImageField(upload_to=logo_name, blank=True, max_length=255)
oficial_link = models.ForeignKey('banners.Redirect', null=True, blank=True, related_name='expo_oficial')
participation_link = models.ForeignKey('banners.Redirect', null=True, blank=True, related_name='expo_participation')
tickets_link = models.ForeignKey('banners.Redirect', null=True, blank=True, related_name='expo_tickets')
organiser = models.EmailField(blank=True)
pre_save.connect(pre_save_handler, sender=Exposition)
post_save.connect(post_save_handler, sender=Exposition)

@ -1,10 +1,8 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from views import ExpositionStatistic, ExpositionPrice,\
ExpositionProgramme, ExpositionSearchView, ExpositionByCountry, ExpositionByTheme, ExpositionByCity, ExpositionByTag
from views import ExpositionStatistic, ExpositionPrice, ExpositionProgramme, ExpositionSearchView, \
ExpositionByCountry, ExpositionByTheme, ExpositionByCity, ExpositionByTag, ExpoPhotoView
from django.views.decorators.cache import cache_page
from views import ExpositionServiceView
from views import ExpoCountryCatalog, ExpoCityCatalog, ExpoThemeCatalog, ExpoTagCatalog, ExpoList, ExpoDetail,\
ExpoVisitors, ExpoMembers, ExpositionThankView
@ -69,6 +67,8 @@ urlpatterns = patterns('',
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(), {'meta_id':64}),
url(r'^expo/(?P<slug>.*)/visitors/$', ExpoVisitors.as_view(), {'meta_id':64}),
url(r'^expo/(?P<slug>.*)/photo/page/(?P<page>\d+)/$', ExpoPhotoView.as_view()),
url(r'^expo/(?P<slug>.*)/photo/$', ExpoPhotoView.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(), {'meta_id':63}),
url(r'^expo/(?P<slug>.*)/service/thanks/', ExpositionThankView.as_view()),

@ -548,6 +548,30 @@ class ExpoMembers(MetadataMixin, ListView):
return context
class ExpoPhotoView(MetadataMixin, ListView):
template_name = 'client/exposition/photo.html'
obj = None
paginate_by = settings.CLIENT_PAGINATION
def get_queryset(self):
slug = self.kwargs.get('slug')
expo = get_object_or_404(Exposition, url=slug)
self.obj = expo
if expo.photogallery:
return expo.photogallery.photos.all()
else:
raise Http404()
def get_context_data(self, **kwargs):
context = super(ExpoPhotoView, self).get_context_data(**kwargs)
obj = self.obj
context['object'] = obj
context['city'] = str(obj.city_id)
context['country'] = str(obj.country_id)
context['themes'] = [str(item.id) for item in obj.theme.all()]
return context
def add_note(request, slug):
args = {'success': False}

@ -128,9 +128,9 @@ class AdminListView(FormView):
def get_context_data(self, **kwargs):
context = super(AdminListView, self).get_context_data(**kwargs)
if issubclass(self.model, TranslatableModel):
qs = self.model.objects.language('all').all().order_by('name')
qs = self.model.objects.language().all().order_by('name')
else:
qs = self.model.objects.all().order_by('name')
qs = self.model.objects.all().order_by('-modified')
result = paginate_results(qs, page=self.request.GET.get('page'))
context['object_list'] = result
return context

@ -1,7 +1,10 @@
# -*- coding: utf-8 -*-
import copy
from django.conf import settings
from functions.translate import fill_with_signal
import calendar as python_calendar
from service.models import Service
from photologue.models import Gallery
class ExpoMixin(object):
@ -103,6 +106,36 @@ class EventMixin(object):
return 0
def upload_photo(self, photo, gallery=None):
"""
uploading photo to gallery
"""
if gallery is None:
gallery = self.get_gallery()
gallery.photos.add(photo)
def get_gallery(self):
if self.photogallery:
return self.photogallery
data = {}
model = type(self)
for code, name in settings.LANGUAGES:
# access to translated fields
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
def copy(self, url):
"""
Copy event with new url

@ -1,5 +1,7 @@
import random
import string
from django.db.models.fields.files import FieldFile
from signal_additional_func import fill_missing_languages, fill_meta_information
import random, string
from functions.form_check import translit_with_separator
@ -34,14 +36,14 @@ def post_save_handler(sender, **kwargs):
fill_missing_languages(obj)
fill_meta_information(obj)
'''
def post_save_translation_handler(sender, **kwargs):
def file_cleanup(sender, instance, *args, **kwargs):
"""
receiver function
take object and change url
Deletes the file(s) associated with a model instance. The model
is not saved after deletion of the file(s) since this is meant
to be used with the pre_delete signal.
"""
obj = kwargs['instance']
if obj.language_code == 'ru':
obj.master.url = translit_with_separator(obj.name)
obj.master.save()
'''
for field_name, _ in instance.__dict__.iteritems():
field = getattr(instance, field_name)
if issubclass(field.__class__, FieldFile) and field.name:
field.delete(save=False)

@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
import re
import datetime
from django.shortcuts import get_object_or_404
from accounts.models import User
def get_referer(request, default=None):
referer = request.META.get('HTTP_REFERER')
@ -20,4 +23,19 @@ def split_params(st):
if n != -1:
params.append({'type': item[:n], 'url':item[n+1:]})
return params
return params
def dates_range(date1, date2):
delta = date2 - date1
dates = []
for i in range(delta.days + 1):
dates.append(date1 + datetime.timedelta(days=i))
return dates
def get_user(url):
try:
url = int(url)
user = get_object_or_404(User, id=url)
except ValueError:
user = get_object_or_404(User, url=url)
return user

@ -1,22 +1,17 @@
# -*- coding: utf-8 -*-
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
from django.db.models.loading import get_model
#
import xlwt
import xlrd
#
from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, ImportOrganiserForm,\
ImportPlaceConferenceForm, ImportPlaceExpositionForm
from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\
ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\
ExportCityForm
from django.views.generic import FormView, ListView, DeleteView
from django.conf import settings
from django.contrib import messages
from django.shortcuts import get_object_or_404
from import_xls.models import Log
from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, \
ImportPlaceConferenceForm, ImportPlaceExpositionForm
from export_forms import ExportEventForm, ExportThemeForm, ExportTagForm,\
ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\
ExportCityForm
def xls_to_response(xls, fname):
response = HttpResponse(mimetype="application/ms-excel")
@ -56,85 +51,93 @@ class ExportView(FormView):
return HttpResponseRedirect(self.success_url)
return xls_to_response(workbook, f_name)
class ExportOrganiser(ExportView):
form_class = ExportOrganiserForm
success_url = '/admin/export-organiser'
class ExportTheme(ExportView):
form_class = ExportThemeForm
success_url = '/admin/export-theme'
class ExportTag(ExportView):
form_class = ExportTagForm
success_url = '/admin/export-tag'
class ExportUser(ExportView):
form_class = ExportUserForm
success_url = '/admin/export-user'
class ExportCompany(ExportView):
form_class = ExportCompanyForm
success_url = '/admin/export-company'
class ExportPlaceConference(ExportView):
form_class = ExportPlaceConferenceForm
success_url = '/admin/export-place_conference'
class ExportPlaceExposition(ExportView):
form_class = ExportPlaceExpositionForm
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 import_xls.models import Log
class ImportEvent(FormView):
form_class = ImportEventForm
success_url = '/admin/import-event/'
template_name = 'admin/import templates/import_event.html'
def form_valid(self, form):
errors = form.save_file_debug()
return HttpResponseRedirect('/admin/import/log/')
#messages.success(self.request, 'Success')
#context = self.get_context_data()
#context['import_errors'] = errors
#context['form'] = form
#return render_to_response(self.template_name, context)
class ImportPlaceExposition(FormView):
form_class = ImportPlaceExpositionForm
success_url = '/admin/import-place_exposition/'
template_name = 'admin/import templates/import.html'
def form_valid(self, form):
errors = form.save_file_debug()
return HttpResponseRedirect(self.success_url)
class ImportPlaceConference(ImportView):
form_class = ImportPlaceConferenceForm
success_url = '/admin/import-place_conference'
def form_valid(self, form):
errors = form.save_file_debug()
return HttpResponseRedirect(self.success_url)
class ImportTheme(ImportView):
form_class = ImportThemeForm
success_url = '/admin/import-theme'
class ImportTag(ImportView):
form_class = ImportTagForm
success_url = '/admin/import-tag'
class ImportOrganiser(ImportView):
form_class = ImportOrganiserForm
success_url = '/admin/import-organiser'
class ImportPlaceExposition(ImportView):
form_class = ImportPlaceExpositionForm
success_url = '/admin/import-place_exposition'
class ImportPlaceConference(ImportView):
form_class = ImportPlaceConferenceForm
success_url = '/admin/import-place_conference'
class ExportEvent(ExportView):
form_class = ExportEventForm
@ -147,6 +150,7 @@ class LogList(ListView):
paginate_by = settings.ADMIN_PAGINATION
template_name = 'admin/import templates/log.html'
class LogDelete(DeleteView):
model = Log
success_url = '/admin/import/log/'
@ -162,11 +166,12 @@ def log_file(request, log_id):
response['X-Accel-Redirect'] = log.log.url
return response
def work_file(request, log_id):
log = get_object_or_404(Log, id=log_id)
response = HttpResponse()
response['content-type'] = 'application/x-executable'
filename = 'import_%s_file.xls'%str(log.id)
filename = 'import_%s_file.xls' % str(log.id)
response['content-disposition'] = 'attachment;filename=%s'%filename
response['X-Accel-Redirect'] = log.work_file.url
return response

@ -1,25 +1,21 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference
from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\
ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity, LogList
from import_xls.admin import LogDelete
from admin import ImportTheme, ImportEvent, ImportTag, ImportPlaceExposition, ImportPlaceConference
from admin import ExportTheme, ExportEvent, ExportTag, ExportPlaceExposition,\
ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity, LogList
urlpatterns = patterns('',
url(r'^import-event/$', ImportEvent.as_view()),
url(r'^import-theme/$', ImportTheme.as_view()),
url(r'^import-tag/$', ImportTag.as_view()),
url(r'^import-organiser/$', ImportOrganiser.as_view()),
url(r'^import-place_exposition/$', ImportPlaceExposition.as_view()),
url(r'^import-place_conference/$', ImportPlaceConference.as_view()),
#
url(r'^export-event/$', ExportEvent.as_view()),
url(r'^export-theme/$', ExportTheme.as_view()),
url(r'^export-tag/$', ExportTag.as_view()),
url(r'^export-organiser/$', ExportOrganiser.as_view()),
url(r'^export-place_exposition/$', ExportPlaceExposition.as_view()),
url(r'^export-place_conference/$', ExportPlaceConference.as_view()),
url(r'^export-user/$', ExportUser.as_view()),

@ -1,12 +1,22 @@
# -*- coding: utf-8 -*-
import urllib2
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.validators import validate_email, URLValidator
from file.models import FileModel
from functions.files import get_alternative_filename
from place_exposition.models import EXPOSITION_TYPE
from place_exposition.models import Hall
# bad practice of importing, but to many functions must be imported
from .utils import *
def get_bool(value):
if value:
return 1
return ''
def get_int(value):
if not value:
return ''
@ -30,12 +40,14 @@ def get_tag(value):
tag_names = [item['name'] for item in value.language('ru').all().values('name')]
return ','.join(tag_names)
def get_place_type(value):
for t in EXPOSITION_TYPE:
if value == t[0]:
return t[1]
return t[0][1]
def get_periodic(value):
if value:
value = float(value)
@ -45,6 +57,7 @@ def get_periodic(value):
return periodic.get(value, '')
return ''
def get_quality(value, field):
flags = {u'UFI': 'ufi', u'РСВЯ': 'rsva', u'EXPORATING': 'exporating'}
v = flags.get(field)
@ -56,45 +69,6 @@ def get_quality(value, field):
return ''
place_settings=[
{'name': 'id', 'verbose_name': u'id', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'URL', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'type', 'verbose_name': u'Тип', 'type': get_place_type},##########
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'address', 'verbose_name': u'Адресс', 'type': unicode},
{'name': 'phone', 'verbose_name': u'Тел.', 'type': get_int},
{'name': 'fax', 'verbose_name': u'Факс', 'type': get_int},
{'name': 'web_page', 'verbose_name': u'Веб-сайт', 'type': unicode},
{'name': 'email', 'verbose_name': u'Email', 'type': unicode},
{'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode},
{'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'event_in_year', 'verbose_name': u'Количество мероприятий в год', 'type': get_int},
{'name': 'total_area', 'verbose_name': u'Общая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'closed_area', 'verbose_name': u'Закрытая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'open_area', 'verbose_name': u'Открытая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'total_pavilions', 'verbose_name': u'Количество павильонов', 'type': get_int},
{'name': 'total_halls', 'verbose_name': u'Конференц-залы', 'type': get_int},
{'name': 'bank', 'verbose_name': u'Банк/Банкоматы/Обмен валюты', 'type': get_bool},
{'name': 'children_room', 'verbose_name': u'Детская комната', 'type': get_bool},
{'name': 'disabled_service', 'verbose_name': u'Сервис для людей с ограниченными физическими возможностями', 'type': get_bool},
{'name': 'conference_centre', 'verbose_name': u'Конгресс-центр', 'type': get_bool},
{'name': 'business_centre', 'verbose_name': u'Бизнес-центр', 'type': get_bool},
{'name': 'online_registration', 'verbose_name': u'On-line регистрация', 'type': get_bool},
{'name': 'wifi', 'verbose_name': u'Wi-Fi', 'type': get_bool},
{'name': 'cafe', 'verbose_name': u'Кафе и рестораны', 'type': get_bool},
{'name': 'terminals', 'verbose_name': u'Информационные терминалы', 'type': get_bool},
{'name': 'parking', 'verbose_name': u'Парковка', 'type': get_bool},
{'name': 'press_centre', 'verbose_name': u'Пресс-центр', 'type': get_bool},
{'name': 'mobile_application', 'verbose_name': u'Мобильное приложение', 'type': get_bool},
]
def to_theme_type(st):
if not st:
return 15
@ -105,37 +79,15 @@ def to_theme_type(st):
return flag
def to_currency(value):
if value=='USD':
return value
if value=='EUR':
return value
print(value)
return 'USD'
def to_logo(url):
return None
def to_photo(url):
return None
def to_map(url):
return None
from django.core.validators import validate_email, URLValidator
def to_url(url):
validate = URLValidator()
try:
validate(url)
except:
return ''
return url
def to_email(email):
try:
validate_email(email)
@ -143,12 +95,6 @@ def to_email(email):
return ''
return email
from file.models import FileModel
import urllib2
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from functions.files import get_alternative_filename
def save_file(obj, value, purpose):
if not obj.id:
@ -178,42 +124,13 @@ def save_file(obj, value, purpose):
file.save()
from file.models import Photo
def save_photo(obj, value):
if not obj.id:
return None
urls = value.split(';')
for url in urls:
file_name = url.split('/')[-1]
alt_name = get_alternative_filename(settings.MEDIA_ROOT+'imgs/', file_name)
download_to = settings.MEDIA_ROOT+'photos/'+alt_name
try:
response = urllib2.urlopen(url, timeout=3)
except:
continue
with open(download_to,'wb') as f:
f.write(response.read())
f.close()
file_name ='photos/'+alt_name
content_type = ContentType.objects.get_for_model(obj)
photo = Photo(file_path=file_name, file_type='JPG',
content_type=content_type, object_id=obj.id)
photo.save()
from place_exposition.models import EXPOSITION_TYPE
def to_type(value):
for t in EXPOSITION_TYPE:
if value == t[1]:
return t[0]
return 'Exposition complex'
def to_phone(value):
if value:
if isinstance(value, float) or isinstance(value, int):
@ -227,9 +144,6 @@ def to_phone(value):
return value
from place_exposition.models import Hall
def save_halls(obj, value):
halls = value.split(';')
res = []
@ -266,51 +180,11 @@ def save_halls(obj, value):
print('---------------------------------')
place_exp_sett = {
u'ID':{u'field': u'id', u'func': to_int},
u'Название ВЦ':{u'field': u'name', u'func': unicode},
u'Тип':{u'field': u'type', u'func': to_type},
u'Краткое описание':{u'field': u'main_title', u'func': unicode},
u'Страна':{u'field': u'country', u'func': to_country},
u'Город':{u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Описание':{u'field': u'description', u'func': unicode},
u'Адрес':{u'field': u'adress', u'func': unicode},
u'Тел.':{u'field': u'phone', 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'logo', u'func': save_logo, u'method': True},
u'Веб-сайт':{u'field': u'web_page', 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'virtual_tour', u'func': to_url},
u'Год основания':{u'field': u'foundation_year', u'func': to_int},
u'Валюта':{u'field': u'currency', u'func': to_currency},
u'Количество мероприятий в год':{u'field': u'event_in_year', u'func': to_int},
u'Общая выставочная площадь, кв. м.':{u'field': u'total_area', u'func': to_int},
u'Закрытая выставочная площадь, кв. м.':{u'field': u'closed_area', u'func': to_int},
u'Открытая выставочная площадь, кв. м.':{u'field': u'open_area', u'func': to_int},
u'Количество павильонов':{u'field': u'total_pavilions', u'func': to_int},
u'Площадь павильона':{u'field': u'halls', u'func': save_halls, u'method': True},
u'Конференц-залы':{u'field': u'total_halls', u'func': to_int},
u'Схема территории':{u'field': u'scheme', u'func': save_file, u'method': True, u'purpose': 'scheme teritory'},#сделать
u'Банк/Банкоматы/Обмен валюты':{u'field': u'bank', u'func': bool},
u'Детская комната':{u'field': u'children_room', u'func': bool},
u'Сервис для людей с ограниченными физическими возможностями':{u'field': u'disabled_service', u'func': bool},
u'Конгресс-центр':{u'field': u'conference_centre', u'func': bool},
u'Бизнес-центр':{u'field': u'business_centre', u'func': bool},
u'On-line регистрация':{u'field': u'online_registration', u'func': bool},
u'Wi-Fi':{u'field': u'wifi', u'func': bool},
u'Кафе и рестораны':{u'field': u'cafe', u'func': bool},
u'Информационные терминалы':{u'field': u'terminals', u'func': bool},
u'Парковка':{u'field': u'parking', u'func': bool},
u'Пресс-центр':{u'field': u'press_centre', u'func': bool},
u'Мобильное приложение':{u'field': u'mobile_application', u'func': bool},
}
def get_date(value):
try:
return value.strftime('%d.%m.%Y')
except AttributeError:
return ''
article_sett = {
@ -321,66 +195,7 @@ article_sett = {
u'Создана':{u'field': u'created', u'func': to_datetime}
}
def get_date(value):
try:
return value.strftime('%d.%m.%Y')
except AttributeError:
return ''
event_export_sett = [
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'data_begin', 'verbose_name': u'Дата начала:(YYYY-MM-DD)', 'type': get_date},
{'name': 'data_end', 'verbose_name': u'Дата окончания:(YYYY-MM-DD)', 'type': get_date},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place},
{'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000},
{'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000},
{'name': 'description', 'verbose_name': u'Описание события', 'type': unicode},
{'name': 'org', 'verbose_name': u'Организатор №1', 'type': get_int},
{'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic},
{'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience},
{'name': 'web_page', 'verbose_name': u'Официальный веб-сайт', 'type': unicode},
{'name': 'products', 'verbose_name': u'Экспонируемые продукты', 'type': unicode},
{'name': 'time', 'verbose_name': u'Время работы', 'type': unicode},
{'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode},
{'name': 'currency', 'verbose_name': u'Валюта', 'type': unicode},
{'name': 'price_day', 'verbose_name': u'Стоимость билета 1 день', 'type': unicode},
{'name': 'price_all', 'verbose_name': u'Стоимость билета все дни', 'type': unicode},
{'name': 'pre_condition', 'verbose_name': u'Условия предварительной регистрации', 'type': unicode},
{'name': 'price_day_bar', 'verbose_name': u'Стоимость на стойке 1 день', 'type': unicode},
{'name': 'price_all_bar', 'verbose_name': u'Стоимость на стойке все дни', 'type': unicode},
{'name': 'stand_condition', 'verbose_name': u'Условия регистрации на стойке', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Примечание по посещению', 'type': unicode},
{'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int},
{'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'visitors', 'verbose_name': u'Посетители', 'type': get_int},
{'name': 'members', 'verbose_name': u'Участники', 'type': get_int},
#{'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode}, !!! delete from import
{'name': 'area', 'verbose_name': u'Площадь', 'type': get_int},
{'name': 'min_closed_area', 'verbose_name': u'Min_Raw кв.м.', 'type': get_int},
{'name': 'max_closed_area', 'verbose_name': u'Max_Raw кв.м.', 'type': get_int},
{'name': 'min_closed_equipped_area', 'verbose_name': u'Min_Pack кв.м.', 'type': get_int},
{'name': 'max_closed_equipped_area', 'verbose_name': u'Max_Pack кв.м.', 'type': get_int},
{'name': 'max_open_area', 'verbose_name': u'Открытая площадь', 'type': get_int},
{'name': 'min_stand_size', 'verbose_name': u'Мин. Площадь кв.м.', 'type': get_int},
{'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int},
{'name': 'participation_note', 'verbose_name': u'Примечание по участии', 'type': unicode},
{'name': 'application_deadline', 'verbose_name': u'Крайний срок подачи заявки', 'type': get_date},
{'name': 'quality_label', 'verbose_name': u'UFI', 'type': get_quality}, #????
{'name': 'quality_label', 'verbose_name': u'РСВЯ', 'type': get_quality},#???
{'name': 'quality_label', 'verbose_name': u'EXPORATING', 'type': get_quality}, #???
{'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool},
{'name': 'expohit', 'verbose_name': u'ExpoHIT', 'type': get_bool},
{'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool},
]
# default export settings
field_settings = [
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
@ -412,8 +227,6 @@ field_settings = [
{'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int},
{'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'visit_note', 'verbose_name': u'Посетители', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Участники', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode},
@ -424,7 +237,6 @@ field_settings = [
{'name': 'visit_note', 'verbose_name': u'Max_Pack кв.м.', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Открытая площадь', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Мин. Площадь кв.м.', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Примечание по участии', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Крайний срок подачи заявки', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'UFI', 'type': unicode},
@ -432,21 +244,13 @@ field_settings = [
{'name': 'visit_note', 'verbose_name': u'EXPORATING', 'type': unicode},
{'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool},
{'name': 'visit_note', 'verbose_name': u'ExpoHIT', 'type': unicode},
{'name': 'address', 'verbose_name': u'Адрес', 'type': unicode},
{'name': 'email', 'verbose_name': u'Email', 'type': unicode},
{'name': 'phone', 'verbose_name': u'Телефон', 'type': get_int},
{'name': 'foundation', 'verbose_name': u'Год основания', 'type': get_int},
#{'name': 'events_number', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'staff_number', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'specialization', 'verbose_name': u'Год основания', 'type': unicode},
{'name': 'max_price', 'verbose_name': u'Максимальная цена', 'type': get_int},
{'name': 'min_price', 'verbose_name': u'Минимальная цена', 'type': get_int},
{'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int},
@ -459,68 +263,221 @@ field_settings = [
{'name': 'min_area', 'verbose_name': u'Минимальная площадь', 'type': get_int},
{'name': 'max_area', 'verbose_name': u'Максимальная площадь', 'type': get_int},
{'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool},
]
# ----------------------EVENT SETTINGS -------------------------
event_sett = {
u'ID':{u'field': u'id', u'func': to_int},
u'Url':{u'field': u'url', u'func': unicode},
u'Название':{u'field': u'name', u'func': unicode},
u'Краткое описание':{u'field': u'main_title', u'func': unicode},
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'Страна':{u'field': u'country', u'func': to_country},
u'Город':{u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Место проведения':{u'field': u'place', u'func': to_place},
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'Организатор №1':{u'field': u'org', u'func': unicode},####
u'ID': {u'field': u'id', u'func': to_int},
u'Url': {u'field': u'url', u'func': unicode},
u'Название': {u'field': u'name', u'func': unicode},
u'Краткое описание': {u'field': u'main_title', u'func': unicode},
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'Страна': {u'field': u'country', u'func': to_country},
u'Город': {u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Место проведения': {u'field': u'place', u'func': to_place},
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'Организатор №1': {u'field': u'org', u'func': unicode},####
#u'Организатор №2':{u'field': u'organiser', u'func': to_tag},####
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'audience', u'func': to_audience},
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'time', 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'audience', u'func': to_audience},
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'time', u'func': unicode},
u'Логотип':{u'field': u'logo', u'func': save_logo, u'method': True},
u'Валюта':{u'field': u'currency', u'func': unicode},
u'Стоимость билета 1 день':{u'field': u'price_day', u'func': unicode},
u'Стоимость билета все дни':{u'field': u'price_all', u'func': unicode},
u'Условия предварительной регистрации':{u'field': u'pre_condition', u'func': unicode},
u'Стоимость на стойке 1 день':{u'field': u'price_day_bar', u'func': unicode},
u'Стоимость на стойке все дни':{u'field': u'price_all_bar', u'func': unicode},
u'Условия регистрации на стойке':{u'field': u'stand_condition', u'func': unicode},
u'Примечание по посещению':{u'field': u'visit_note', u'func': unicode},
u'Каталог':{u'field': u'price_catalog', u'func': to_int},
u'Налог включен':{u'field': u'tax', u'func': bool},
u'Год основания':{u'field': u'foundation_year', u'func': to_int},
#???u'Данные за год':{u'field': u'periodic', u'func': to_int},
u'Посетители':{u'field': u'visitors', u'func': to_int},
u'Участники':{u'field': u'members', u'func': to_int},
u'Страны':{u'field': u'stat_countries', u'func': unicode},
u'Площадь':{u'field': u'area', u'func': to_int},
u'Мин стоимость':{u'field': u'min_price', u'func': to_int},
u'Макс стоимость':{u'field': u'max_price', u'func': to_int},
u'Min_Raw кв.м.':{u'field': u'min_closed_area', u'func': to_int},
u'Max_Raw кв.м.':{u'field': u'max_closed_area', u'func': to_int},
u'Min_Pack кв.м.':{u'field': u'min_closed_equipped_area', u'func': to_int},
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'min_stand_size', 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'application_deadline', u'func': to_date},
u'UFI':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'ufi'},
u'РСВЯ':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'rsva'},
u'EXPORATING':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'exporating'},
u'Отменена':{u'field': u'canceled', u'func': bool},
u'ExpoHIT':{u'field': u'expohit', u'func': bool},
u'Валюта': {u'field': u'currency', u'func': unicode},
u'Стоимость билета 1 день': {u'field': u'price_day', u'func': unicode},
u'Стоимость билета все дни': {u'field': u'price_all', u'func': unicode},
u'Условия предварительной регистрации': {u'field': u'pre_condition', u'func': unicode},
u'Стоимость на стойке 1 день': {u'field': u'price_day_bar', u'func': unicode},
u'Стоимость на стойке все дни': {u'field': u'price_all_bar', u'func': unicode},
u'Условия регистрации на стойке': {u'field': u'stand_condition', u'func': unicode},
u'Примечание по посещению': {u'field': u'visit_note', u'func': unicode},
u'Каталог': {u'field': u'price_catalog', u'func': to_int},
u'Налог включен': {u'field': u'tax', u'func': bool},
u'Год основания': {u'field': u'foundation_year', u'func': to_int},
u'Посетители': {u'field': u'visitors', u'func': to_int},
u'Участники': {u'field': u'members', u'func': to_int},
u'Страны': {u'field': u'stat_countries', u'func': unicode},
u'Площадь': {u'field': u'area', u'func': to_int},
u'Мин стоимость': {u'field': u'min_price', u'func': to_int},
u'Макс стоимость': {u'field': u'max_price', u'func': to_int},
u'Min_Raw кв.м.': {u'field': u'min_closed_area', u'func': to_int},
u'Max_Raw кв.м.': {u'field': u'max_closed_area', u'func': to_int},
u'Min_Pack кв.м.': {u'field': u'min_closed_equipped_area', u'func': to_int},
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'min_stand_size', 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'application_deadline', u'func': to_date},
u'UFI': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'ufi'},
u'РСВЯ': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'rsva'},
u'EXPORATING': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'exporating'},
u'Отменена': {u'field': u'canceled', u'func': bool},
u'ExpoHIT': {u'field': u'expohit', u'func': bool},
}
event_export_sett = [
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'data_begin', 'verbose_name': u'Дата начала:(YYYY-MM-DD)', 'type': get_date},
{'name': 'data_end', 'verbose_name': u'Дата окончания:(YYYY-MM-DD)', 'type': get_date},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place},
{'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000},
{'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000},
{'name': 'description', 'verbose_name': u'Описание события', 'type': unicode},
{'name': 'org', 'verbose_name': u'Организатор №1', 'type': get_int},
{'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic},
{'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience},
{'name': 'web_page', 'verbose_name': u'Официальный веб-сайт', 'type': unicode},
{'name': 'products', 'verbose_name': u'Экспонируемые продукты', 'type': unicode},
{'name': 'time', 'verbose_name': u'Время работы', 'type': unicode},
{'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode},
{'name': 'currency', 'verbose_name': u'Валюта', 'type': unicode},
{'name': 'price_day', 'verbose_name': u'Стоимость билета 1 день', 'type': unicode},
{'name': 'price_all', 'verbose_name': u'Стоимость билета все дни', 'type': unicode},
{'name': 'pre_condition', 'verbose_name': u'Условия предварительной регистрации', 'type': unicode},
{'name': 'price_day_bar', 'verbose_name': u'Стоимость на стойке 1 день', 'type': unicode},
{'name': 'price_all_bar', 'verbose_name': u'Стоимость на стойке все дни', 'type': unicode},
{'name': 'stand_condition', 'verbose_name': u'Условия регистрации на стойке', 'type': unicode},
{'name': 'visit_note', 'verbose_name': u'Примечание по посещению', 'type': unicode},
{'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int},
{'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'visitors', 'verbose_name': u'Посетители', 'type': get_int},
{'name': 'members', 'verbose_name': u'Участники', 'type': get_int},
#{'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode}, !!! delete from import
{'name': 'area', 'verbose_name': u'Площадь', 'type': get_int},
{'name': 'min_closed_area', 'verbose_name': u'Min_Raw кв.м.', 'type': get_int},
{'name': 'max_closed_area', 'verbose_name': u'Max_Raw кв.м.', 'type': get_int},
{'name': 'min_closed_equipped_area', 'verbose_name': u'Min_Pack кв.м.', 'type': get_int},
{'name': 'max_closed_equipped_area', 'verbose_name': u'Max_Pack кв.м.', 'type': get_int},
{'name': 'max_open_area', 'verbose_name': u'Открытая площадь', 'type': get_int},
{'name': 'min_stand_size', 'verbose_name': u'Мин. Площадь кв.м.', 'type': get_int},
{'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int},
{'name': 'participation_note', 'verbose_name': u'Примечание по участии', 'type': unicode},
{'name': 'application_deadline', 'verbose_name': u'Крайний срок подачи заявки', 'type': get_date},
{'name': 'quality_label', 'verbose_name': u'UFI', 'type': get_quality}, #????
{'name': 'quality_label', 'verbose_name': u'РСВЯ', 'type': get_quality},#???
{'name': 'quality_label', 'verbose_name': u'EXPORATING', 'type': get_quality}, #???
{'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool},
{'name': 'expohit', 'verbose_name': u'ExpoHIT', 'type': get_bool},
{'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool},
]
# -----------------------END EVENT SETTINGS ---------------------------------
# --------------PLACE EXPO SETTINGS-----------------------------
# import
place_exp_sett = {
u'ID': {u'field': u'id', u'func': to_int},
u'Название': {u'field': u'name', u'func': unicode},
u'Тип': {u'field': u'type', u'func': to_type},
u'Краткое описание': {u'field': u'main_title', u'func': unicode},
u'Страна': {u'field': u'country', u'func': to_country},
u'Город': {u'field': u'city_id', u'func': to_city, 'extra_values': 'country'},
u'Описание': {u'field': u'description', u'func': unicode},
u'Адрес': {u'field': u'adress', u'func': unicode},
u'Тел.': {u'field': u'phone', u'func': to_phone},
u'Факс': {u'field': u'fax', u'func': to_phone},
u'Лого': {u'field': u'logo', u'func': save_logo, u'method': True},
u'Веб-сайт': {u'field': u'web_page', 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'virtual_tour', u'func': to_url},
u'Год основания': {u'field': u'foundation_year', u'func': to_int},
u'Количество мероприятий в год': {u'field': u'event_in_year', u'func': to_int},
u'Общая выставочная площадь, кв. м.': {u'field': u'total_area', u'func': to_int},
u'Закрытая выставочная площадь, кв. м.': {u'field': u'closed_area', u'func': to_int},
u'Открытая выставочная площадь, кв. м.': {u'field': u'open_area', u'func': to_int},
u'Количество павильонов': {u'field': u'total_pavilions', u'func': to_int},
u'Площадь павильона': {u'field': u'halls', u'func': save_halls, u'method': True},
u'Конференц-залы': {u'field': u'total_halls', u'func': to_int},
u'Схема территории': {u'field': u'scheme', u'func': save_file, u'method': True, u'purpose': 'scheme teritory'},#сделать
u'Банк/Банкоматы/Обмен валюты': {u'field': u'bank', u'func': bool},
u'Детская комната': {u'field': u'children_room', u'func': bool},
u'Сервис для людей с ограниченными физическими возможностями': {u'field': u'disabled_service', u'func': bool},
u'Конгресс-центр': {u'field': u'conference_centre', u'func': bool},
u'Бизнес-центр': {u'field': u'business_centre', u'func': bool},
u'On-line регистрация': {u'field': u'online_registration', u'func': bool},
u'Wi-Fi': {u'field': u'wifi', u'func': bool},
u'Кафе и рестораны': {u'field': u'cafe', u'func': bool},
u'Информационные терминалы': {u'field': u'terminals', u'func': bool},
u'Парковка': {u'field': u'parking', u'func': bool},
u'Пресс-центр': {u'field': u'press_centre', u'func': bool},
u'Мобильное приложение': {u'field': u'mobile_application', u'func': bool},
# place_conf settings
u'Мультимедийное оборудование': {u'field': u'multimedia_equipment', u'func': bool},
u'Конференц-связь': {u'field': u'conference_call', u'func': bool},
u'Оборудование для синхронного перевода': {u'field': u'translate_equipment', u'func': bool},
u'Банкетный зал': {u'field': u'banquet_hall', u'func': bool},
u'Кейтеринг': {u'field': u'catering', u'func': bool},
u'Гостиница': {u'field': u'hotel', u'func': bool},
u'Выставочный зал': {u'field': u'exposition_hall', u'func': bool},
u'Площадь выст. зала': {u'field': u'exp_hall_area', u'func': to_int},
u'Общая вместимость': {u'field': u'total_capacity', u'func': to_int},
u'Количество залов': {u'field': u'amount_halls', u'func': bool},
}
# export
place_settings=[
{'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': u'Url', 'type': unicode},
{'name': 'name', 'verbose_name': u'Название', 'type': unicode},
{'name': 'type', 'verbose_name': u'Тип', 'type': get_place_type},##########
{'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode},
{'name': 'country', 'verbose_name': u'Страна', 'type': unicode},
{'name': 'city', 'verbose_name': u'Город', 'type': unicode},
{'name': 'adress', 'verbose_name': u'Адресс', 'type': unicode},
{'name': 'phone', 'verbose_name': u'Тел.', 'type': get_int},
{'name': 'fax', 'verbose_name': u'Факс', 'type': get_int},
{'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode},
{'name': 'web_page', 'verbose_name': u'Веб-сайт', 'type': unicode},
{'name': 'email', 'verbose_name': u'Email', 'type': unicode},
{'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode},
{'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int},
{'name': 'event_in_year', 'verbose_name': u'Количество мероприятий в год', 'type': get_int},
{'name': 'total_area', 'verbose_name': u'Общая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'closed_area', 'verbose_name': u'Закрытая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'open_area', 'verbose_name': u'Открытая выставочная площадь, кв. м.', 'type': get_int},
{'name': 'total_pavilions', 'verbose_name': u'Количество павильонов', 'type': get_int},
{'name': 'total_halls', 'verbose_name': u'Конференц-залы', 'type': get_int},
{'name': 'total_capacity', 'verbose_name': u'Общая вместимость', 'type': get_int},
{'name': 'exposition_hall', 'verbose_name': u'Выставочный зал', 'type': get_bool},
{'name': 'exp_hall_area', 'verbose_name': u'Площадь выст. зала', 'type': get_int},
{'name': 'amount_halls', 'verbose_name': u'Количество залов', 'type': get_int},
{'name': 'bank', 'verbose_name': u'Банк/Банкоматы/Обмен валюты', 'type': get_bool},
{'name': 'children_room', 'verbose_name': u'Детская комната', 'type': get_bool},
{'name': 'disabled_service', 'verbose_name': u'Сервис для людей с ограниченными физическими возможностями', 'type': get_bool},
{'name': 'conference_centre', 'verbose_name': u'Конгресс-центр', 'type': get_bool},
{'name': 'business_centre', 'verbose_name': u'Бизнес-центр', 'type': get_bool},
{'name': 'online_registration', 'verbose_name': u'On-line регистрация', 'type': get_bool},
{'name': 'wifi', 'verbose_name': u'Wi-Fi', 'type': get_bool},
{'name': 'cafe', 'verbose_name': u'Кафе и рестораны', 'type': get_bool},
{'name': 'terminals', 'verbose_name': u'Информационные терминалы', 'type': get_bool},
{'name': 'parking', 'verbose_name': u'Парковка', 'type': get_bool},
{'name': 'press_centre', 'verbose_name': u'Пресс-центр', 'type': get_bool},
{'name': 'mobile_application', 'verbose_name': u'Мобильное приложение', 'type': get_bool},
{'name': 'multimedia_equipment', 'verbose_name': u'Мультимедийное оборудование', 'type': get_bool},
{'name': 'conference_call', 'verbose_name': u'Конференц-связь', 'type': get_bool},
{'name': 'translate_equipment', 'verbose_name': u'Оборудование для синхронного перевода', 'type': get_bool},
{'name': 'banquet_hall', 'verbose_name': u'Банкетный зал', 'type': get_bool},
{'name': 'catering', 'verbose_name': u'Кейтеринг', 'type': get_bool},
{'name': 'hotel', 'verbose_name': u'Гостиница', 'type': get_bool},
]
# -----------------END PLACE EXPO SETTINGS------------------------------
# default import settings
import_settings={
'name': {'func': unicode},
'url': {'func': unicode},

@ -13,7 +13,7 @@ from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference
from django.db.models.loading import get_model
import xlwt
from excel_settings import import_settings, field_settings, event_export_sett
from excel_settings import field_settings, event_export_sett
languages = [code for code in settings.LANGUAGES]
@ -75,13 +75,6 @@ class ExportForm(forms.Form):
return self.workbook
class ExportOrganiserForm(ExportForm):
model = Organiser
def get_fname(self):
return 'organisers.xls'
class ExportUserForm(ExportForm):
model = User
@ -106,7 +99,9 @@ class ExportTagForm(ExportForm):
from excel_settings import place_settings
class ExportPlaceExpositionForm(ExportForm):
model = PlaceExposition
def export(self):
data = self.cleaned_data
objects = self.get_objects(data)
@ -130,21 +125,18 @@ class ExportPlaceExpositionForm(ExportForm):
self.worksheet.write(0, col, field.get('verbose_name', 'default'), self.style)
#self.worksheet.write(1, col, field.get('name'), self.style)
self.worksheet.col(col).width = field.get('width', 3333)
if field['name']=='tag':
self.worksheet.write(row+1, col, field.get('type')(value, object.theme))
else:
self.worksheet.write(row+1, col, field.get('type')(value))
self.worksheet.write(row+1, col, field.get('type')(value))
col += 1
return self.workbook
def get_fname(self):
return 'places.xls'
class ExportPlaceConferenceForm(ExportForm):
class ExportPlaceConferenceForm(ExportPlaceExpositionForm):
model = PlaceConference
def get_fname(self):
return 'places.xls'
class ExportCompanyForm(ExportForm):
model = Company

@ -1,18 +1,32 @@
# -*- coding: utf-8 -*-
import urllib
import json
import xlrd
from django.db import IntegrityError
from django import forms
from django.conf import settings
from django.db.models.loading import get_model
from theme.models import Theme, Tag
from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference
from country.models import Country
from organiser.models import Organiser
from django.db.models.loading import get_model
import xlrd, xlwt
from import_xls.models import Log
from excel_settings import import_settings
from functions.form_check import translit_with_separator
from excel_settings import place_exp_sett
from import_xls.excel_settings import event_sett
languages = [code for code in settings.LANGUAGES]
typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправильная страна или город',
'(1048, "Column \'country_id\' cannot be null")':u'Неправильная страна или город',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата окончания',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'}
def logcall(f, msg):
with open(f.file.name, 'a') as logfile:
logfile.write(msg.encode('utf8'))
class ImportForm(forms.Form):
"""
@ -82,19 +96,11 @@ class ImportForm(forms.Form):
object.save()
class ImportOrganiserForm(ImportForm):
model = Organiser
class ImportThemeForm(ImportForm):
model = Theme
from excel_settings import place_exp_sett
from django.db import IntegrityError
import urllib, json
def google_address(address):
if address:
address = address.encode('utf')
@ -112,13 +118,131 @@ def google_address(address):
return ''
return ''
from djutils.decorators import async
from djutils.queue.decorators import queue_command
# place
class ImportPlaceExpositionForm(ImportForm):
model = PlaceExposition
settings = place_exp_sett
def get_row_object(self, row):
if row[0] != '':
# in first column id
try:
obj = self.model.objects.language(self.lang).get(id=int(row[0]))
except ValueError:
obj = self.model()
obj.translate(self.lang)
except self.model.DoesNotExist:
obj = self.model(id= int(row[0]))
obj.translate(self.lang)
else:
# if id blank - its a new object
obj = self.model()
obj.translate(self.lang)
return obj
def save_file_debug(self):
data = self.cleaned_data
lang, self.lang = data['language'], data['language']
f = data['excel_file']
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)]
field_names = [name for name in row_list[0]]
model = self.model
labels = [label for label in row_list[0]]
errors = []
#log = Log.custom.create_log_name(f)
for row_number, row in enumerate(row_list):
if row_number == 0:
continue
#log_msg = u'[%s] %s: '%(str(row_number), row[2])
obj = self.get_row_object(row)
methods = []
# go through row cells
for col_number, cell in enumerate(row):
# get current label
label = labels[col_number]
setting = event_sett.get(label)
if setting is None:
# no label in settings
continue
if setting.get('method'):
# this cell contains data that must be written after creating object
if cell != "":
methods.append({'func': setting['func'], 'value': cell,
'purpose': setting.get('purpose'), 'field': label})
continue
field_name = setting['field']
func = setting.get('func')
if func is None:
# no function in settings
continue
extra_value = setting.get('extra_values')
if extra_value is not None:
# if setting has extra value then
# it is some field like city, tag
# that has relation and can be created
# in function we add language(need for relation fields)
# and extra value from object (like for city need country)
try:
extra = getattr(obj, extra_value)
except Exception:
continue
value = func(cell, 'ru', extra)
else:
value = func(cell)
#try:
setattr(obj, field_name, value)
#except ValueError:
# continue
if not obj.url:
obj.url = translit_with_separator(obj.name)
# try:
obj.save()
# except IntegrityError, e:
# error = str(e)
# if typical_errors.get(error):
# error = typical_errors[error]
# if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'):
#
# error = u'Событие с таким названием или урлом уже существует'
#
# errors.append([obj.name, error])
# log_msg += error
# logcall(log.log, log_msg + '\n')
# continue
for method in methods:
func = method['func']
if method.get('purpose'):
try:
func(obj, method['value'], method['purpose'])
except:
#log_msg += '(%s: Ошибка);'%method['field']
continue
else:
msg = func(obj, method['value'])
if msg:
#log_msg += '(%s: %s);'%(method['field'], msg)
pass
#logcall(log.log, log_msg + '\n')
def save_file(self):
data = self.cleaned_data
lang = data['language']
@ -234,27 +358,10 @@ class ImportPlaceExpositionForm(ImportForm):
return errors
class ImportPlaceConferenceForm(ImportForm):
class ImportPlaceConferenceForm(ImportPlaceExpositionForm):
model = PlaceConference
from import_xls.excel_settings import event_sett
typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправильная страна или город',
'(1048, "Column \'country_id\' cannot be null")':u'Неправильная страна или город',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата окончания',
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'}
# event
import time
def logcall(f, msg):
with open(f.file.name, 'a') as logfile:
logfile.write(msg.encode('utf8'))
from import_xls.models import Log
class ImportEventForm(ImportForm):
"""
extended form for importing one type of event
@ -359,8 +466,8 @@ class ImportEventForm(ImportForm):
except Exception:
setattr(obj, 'place_alt', cell)
if not obj.url:
a = obj.name
obj.url = translit_with_separator(obj.name)
obj.is_published = True
try:
obj.save()

@ -3,23 +3,13 @@ from django.db import models
from django.conf import settings
from django.db.models.fields.files import FieldFile
from django.db.models.signals import pre_delete
from functions.signal_handlers import file_cleanup
def get_doc_dir(instance, filename):
from pytils import translit
return u'import_xls/import/%s' %translit.translify(filename)
def file_cleanup(sender, instance, *args, **kwargs):
'''
Deletes the file(s) associated with a model instance. The model
is not saved after deletion of the file(s) since this is meant
to be used with the pre_delete signal.
'''
for field_name, _ in instance.__dict__.iteritems():
field = getattr(instance, field_name)
if issubclass(field.__class__, FieldFile) and field.name:
field.delete(save=False)
class LogManager(models.Manager):
def create_log(self, work_file, errors):
"""

@ -1,25 +1,25 @@
# -*- coding: utf-8 -*-
import copy
from django.db import models
from django.utils import translation
from django.db.models.signals import post_save
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.core.urlresolvers import reverse_lazy
from django.core.cache import cache
from functions.signal_handlers import post_save_handler
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from pymorphy.django_conf import default_morph as morph
from functions.signal_handlers import post_save_handler
import copy
# additional funcs
MONTHES = {'jan': _(u'январе'), 'feb': _(u'феврале'), 'mar': _(u'марте'), 'apr': _(u'апреле'),
def get_month_inflect(value, key):
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', '')}
@ -27,6 +27,7 @@ def get_obj_inflect(obj, key):
result = {key: getattr(obj, 'name', '')}
return result
def get_theme_inflect(obj, key):
if translation.get_language() == 'ru':
result = {'theme_inflect': getattr(obj, 'inflect', ''),
@ -36,6 +37,7 @@ def get_theme_inflect(obj, key):
'theme_name': getattr(obj, 'name', '')}
return result
def get_tag_inflect(obj, key):
if translation.get_language() == 'ru':
result = {'tag_inflect': getattr(obj, 'inflect', ''),
@ -47,47 +49,54 @@ def get_tag_inflect(obj, key):
class MetaSetting(TranslatableModel):
"""
setting that generates meta fields
"""
name = models.CharField(max_length=100, unique=True)
translations = TranslatedFields(
title = models.CharField(max_length=255, blank=True),
description = models.CharField(max_length=255, blank=True),
keywords = models.CharField(max_length=255, blank=True),
h1 = models.CharField(max_length=255, blank=True),
title=models.CharField(max_length=255, blank=True),
description=models.CharField(max_length=255, blank=True),
keywords=models.CharField(max_length=255, blank=True),
h1=models.CharField(max_length=255, blank=True),
)
# params that handles for objects
object_params = {'object_name': 'name', 'object_title': 'main_title', 'city': 'city', 'country': 'country'}
# default params
params = {'month': get_month_inflect, 'country': get_obj_inflect, 'city': get_obj_inflect,
'theme': get_theme_inflect, 'tag': get_tag_inflect}
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 __unicode__(self):
return self.name
def generate_meta(self, params, obj=None):
"""
generating meta fields by given params and current object fields
obj must be in current language
"""
# current language
lang = translation.get_language()
updates = {}
if obj:
# if objects - generate fields from object_params field
for key, value in self.object_params.iteritems():
updates.update({key: getattr(obj, value, '')})
for key, value in params.iteritems():
# iterate through default params
if key in self.params:
updates.update(self.params[key](value, key))
params.update(updates)
# current translation object
tr = self.translations.get(language_code=lang)
title = tr.title.format(**params)
description = tr.description.format(**params)
keywords = []#tr.keywords.format(**params)
keywords = []#tr.keywords.format(**params) uncoment if keywords need
h1 = tr.h1.format(**params)
return {'title': title, 'description': description, 'keywords': keywords, 'h1': h1}
@ -101,7 +110,6 @@ class MetaSetting(TranslatableModel):
s = morph.inflect_ru(s, u'пр')
return s
def get_title(self):
title = self.title
return title
@ -119,11 +127,6 @@ class MetaSetting(TranslatableModel):
return []
post_save.connect(post_save_handler, sender=MetaSetting)
# SEO - tests #
class SeoTextManager(TranslationManager):
cache_time = 120
@ -142,6 +145,9 @@ class SeoTextManager(TranslationManager):
class SeoText(TranslatableModel):
"""
store seo data for specified urls
"""
url = models.CharField(max_length=50, unique=True, verbose_name=u"URL: www.expomap.ru")
translations = TranslatedFields(
@ -191,3 +197,6 @@ class SeoText(TranslatableModel):
def __unicode__(self):
return self.url
post_save.connect(post_save_handler, sender=MetaSetting)

@ -14,247 +14,6 @@ MULTISITE = getattr(settings, 'PHOTOLOGUE_MULTISITE', False)
ENABLE_TAGS = getattr(settings, 'PHOTOLOGUE_ENABLE_TAGS', False)
"""
class GalleryAdminForm(forms.ModelForm):
class Meta:
model = Gallery
if MULTISITE:
exclude = []
else:
exclude = ['sites']
if not ENABLE_TAGS:
exclude.append('tags')
class GalleryAdmin(admin.ModelAdmin):
list_display = ('title', 'date_added', 'photo_count', 'is_public')
list_filter = ['date_added', 'is_public']
if MULTISITE:
list_filter.append('sites')
date_hierarchy = 'date_added'
prepopulated_fields = {'slug': ('title',)}
form = GalleryAdminForm
if MULTISITE:
filter_horizontal = ['sites']
if MULTISITE:
actions = [
'add_to_current_site',
'add_photos_to_current_site',
'remove_from_current_site',
'remove_photos_from_current_site'
]
def formfield_for_manytomany(self, db_field, request, **kwargs):
''' Set the current site as initial value. '''
if db_field.name == "sites":
kwargs["initial"] = [Site.objects.get_current()]
return super(GalleryAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
def save_related(self, request, form, *args, **kwargs):
'''
If the user has saved a gallery with a photo that belongs only to
different Sites - it might cause much confusion. So let them know.
'''
super(GalleryAdmin, self).save_related(request, form, *args, **kwargs)
orphaned_photos = form.instance.orphaned_photos()
if orphaned_photos:
msg = ungettext(
'The following photo does not belong to the same site(s)'
' as the gallery, so will never be displayed: %(photo_list)s.',
'The following photos do not belong to the same site(s)'
' as the gallery, so will never be displayed: %(photo_list)s.',
len(orphaned_photos)
) % {'photo_list': ", ".join([photo.title for photo in orphaned_photos])}
messages.warning(request, msg)
def add_to_current_site(modeladmin, request, queryset):
current_site = Site.objects.get_current()
current_site.gallery_set.add(*queryset)
msg = ungettext(
"The gallery has been successfully added to %(site)s",
"The galleries have been successfully added to %(site)s",
len(queryset)
) % {'site': current_site.name}
messages.success(request, msg)
add_to_current_site.short_description = \
_("Add selected galleries from the current site")
def remove_from_current_site(modeladmin, request, queryset):
current_site = Site.objects.get_current()
current_site.gallery_set.remove(*queryset)
msg = ungettext(
"The gallery has been successfully removed from %(site)s",
"The selected galleries have been successfully removed from %(site)s",
len(queryset)
) % {'site': current_site.name}
messages.success(request, msg)
remove_from_current_site.short_description = \
_("Remove selected galleries from the current site")
def add_photos_to_current_site(modeladmin, request, queryset):
photos = Photo.objects.filter(galleries__in=queryset)
current_site = Site.objects.get_current()
current_site.photo_set.add(*photos)
msg = ungettext(
'All photos in gallery %(galleries)s have been successfully added to %(site)s',
'All photos in galleries %(galleries)s have been successfully added to %(site)s',
len(queryset)
) % {
'site': current_site.name,
'galleries': ", ".join(["'{0}'".format(gallery.title)
for gallery in queryset])
}
messages.success(request, msg)
add_photos_to_current_site.short_description = \
_("Add all photos of selected galleries to the current site")
def remove_photos_from_current_site(modeladmin, request, queryset):
photos = Photo.objects.filter(galleries__in=queryset)
current_site = Site.objects.get_current()
current_site.photo_set.remove(*photos)
msg = ungettext(
'All photos in gallery %(galleries)s have been successfully removed from %(site)s',
'All photos in galleries %(galleries)s have been successfully removed from %(site)s',
len(queryset)
) % {
'site': current_site.name,
'galleries': ", ".join(["'{0}'".format(gallery.title)
for gallery in queryset])
}
messages.success(request, msg)
remove_photos_from_current_site.short_description = \
_("Remove all photos in selected galleries from the current site")
admin.site.register(Gallery, GalleryAdmin)
class GalleryUploadAdmin(admin.ModelAdmin):
def has_change_permission(self, request, obj=None):
return False # To remove the 'Save and continue editing' button
def save_model(self, request, obj, form, change):
# Warning the user when things go wrong in a zip upload.
obj.request = request
obj.save()
admin.site.register(GalleryUpload, GalleryUploadAdmin)
class PhotoAdminForm(forms.ModelForm):
class Meta:
model = Photo
if MULTISITE:
exclude = []
else:
exclude = ['sites']
if not ENABLE_TAGS:
exclude.append('tags')
class PhotoAdmin(admin.ModelAdmin):
list_display = ('title', 'date_taken', 'date_added',
'is_public', 'tags', 'view_count', 'admin_thumbnail')
list_filter = ['date_added', 'is_public']
if MULTISITE:
list_filter.append('sites')
search_fields = ['title', 'slug', 'caption']
list_per_page = 10
prepopulated_fields = {'slug': ('title',)}
form = PhotoAdminForm
if MULTISITE:
filter_horizontal = ['sites']
if MULTISITE:
actions = ['add_photos_to_current_site', 'remove_photos_from_current_site']
def formfield_for_manytomany(self, db_field, request, **kwargs):
''' Set the current site as initial value. '''
if db_field.name == "sites":
kwargs["initial"] = [Site.objects.get_current()]
return super(PhotoAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
def add_photos_to_current_site(modeladmin, request, queryset):
current_site = Site.objects.get_current()
current_site.photo_set.add(*queryset)
msg = ungettext(
'The photo has been successfully added to %(site)s',
'The selected photos have been successfully added to %(site)s',
len(queryset)
) % {'site': current_site.name}
messages.success(request, msg)
add_photos_to_current_site.short_description = \
_("Add selected photos to the current site")
def remove_photos_from_current_site(modeladmin, request, queryset):
current_site = Site.objects.get_current()
current_site.photo_set.remove(*queryset)
msg = ungettext(
'The photo has been successfully removed from %(site)s',
'The selected photos have been successfully removed from %(site)s',
len(queryset)
) % {'site': current_site.name}
messages.success(request, msg)
remove_photos_from_current_site.short_description = \
_("Remove selected photos from the current site")
admin.site.register(Photo, PhotoAdmin)
class PhotoEffectAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'color', 'brightness',
'contrast', 'sharpness', 'filters', 'admin_sample')
fieldsets = (
(None, {
'fields': ('name', 'description')
}),
('Adjustments', {
'fields': ('color', 'brightness', 'contrast', 'sharpness')
}),
('Filters', {
'fields': ('filters',)
}),
('Reflection', {
'fields': ('reflection_size', 'reflection_strength', 'background_color')
}),
('Transpose', {
'fields': ('transpose_method',)
}),
)
admin.site.register(PhotoEffect, PhotoEffectAdmin)
class PhotoSizeAdmin(admin.ModelAdmin):
list_display = ('name', 'width', 'height', 'crop', 'pre_cache', 'effect', 'increment_count')
fieldsets = (
(None, {
'fields': ('name', 'width', 'height', 'quality')
}),
('Options', {
'fields': ('upscale', 'crop', 'pre_cache', 'increment_count')
}),
('Enhancements', {
'fields': ('effect', 'watermark',)
}),
)
admin.site.register(PhotoSize, PhotoSizeAdmin)
class WatermarkAdmin(admin.ModelAdmin):
list_display = ('name', 'opacity', 'style')
admin.site.register(Watermark, WatermarkAdmin)
"""
#------------------EXPOMAP VIEWS----------------------------------------------
from django.views.generic import ListView, FormView
@ -301,7 +60,7 @@ class AdminViewObject(FormView):
class PhotoView(AdminViewObject):
model = Photo
form_class = PhotoForm
template_name = 'photogallery/admin_photo.html'
template_name = 'admin/photogallery/admin_photo.html'
success_url = '/admin/photogallery/photo/all/'
def get_form(self, form_class):
@ -315,6 +74,7 @@ class PhotoView(AdminViewObject):
photo = self.obj
data = {}
data['image'] = photo.image.url
data['sort'] = photo.sort
for code, name in settings.LANGUAGES:
obj = Photo._meta.translations_model.objects.get(language_code = code,master__id=getattr(photo, 'id')) #access to translated fields
@ -328,7 +88,7 @@ class PhotoView(AdminViewObject):
class GalleryView(AdminViewObject):
model = Gallery
form_class = GalleryForm
template_name = 'photogallery/admin_gallery.html'
template_name = 'admin/photogallery/admin_gallery.html'
success_url = '/admin/photogallery/gallery/all/'
def get_form(self, form_class):
@ -355,13 +115,13 @@ class GalleryView(AdminViewObject):
class PhotoListView(ListView):
paginate_by = settings.ADMIN_PAGINATION
model = Photo
template_name = 'photogallery/admin_photo_list.html'
template_name = 'admin/photogallery/admin_photo_list.html'
class GalleryListView(ListView):
paginate_by = settings.ADMIN_PAGINATION
model = Gallery
template_name = 'photogallery/admin_gallery_list.html'
template_name = 'admin/photogallery/admin_gallery_list.html'
def delete_photo(request, photo_id):

@ -5,7 +5,7 @@ from client_view import GalleryView, PhotoView
urlpatterns = patterns('',
#url(r'gallery/(?P<slug>.*)$', GalleryView.as_view()),
#url(r'photo/(?P<slug>.*)$', PhotoView.as_view()),
url(r'^show/photo/(?P<id>.*)$', 'photologue.client_view.ajax_photo'),
url(r'^show/photo/(?P<id>.*)/$', 'photologue.client_view.ajax_photo'),
)

@ -18,8 +18,8 @@ class GalleryForm(forms.Form):
# 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='Описание', required=required)
self.fields['description_%s' % code] = forms.CharField(label='Заголовок', required=required)
self.fields['title_%s' % code] = forms.CharField(label='Заголовок', required=required)
self.fields['description_%s' % code] = forms.CharField(label='Описание', required=False)
def save(self, obj=None):
data = self.cleaned_data
@ -35,6 +35,7 @@ class GalleryForm(forms.Form):
class PhotoForm(forms.Form):
image = forms.ImageField(label=u'Изображение', required=False)
sort = forms.IntegerField(label=u'Позиция', initial=10, required=False)
def __init__(self, *args, **kwargs):
"""
@ -60,9 +61,11 @@ class PhotoForm(forms.Form):
else:
photo = obj
photo.image = obj.image
if data.get('sort'):
photo.sort = data['sort']
fill_with_signal(Photo, photo, data)
photo.save()
return photo

@ -15,7 +15,7 @@ except ImportError:
import django
from django.utils.timezone import now
from django.db import models
from django.db.models.signals import post_init, post_save
from django.db.models.signals import post_init, post_save, pre_delete
from django.conf import settings
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
@ -29,6 +29,7 @@ from django.utils.encoding import python_2_unicode_compatible
from django.core.validators import RegexValidator
from django.contrib import messages
from django.contrib.sites.models import Site
from functions.signal_handlers import post_save_handler, file_cleanup
# Required PIL classes may or may not be available from the root namespace
# depending on the installation method used.
@ -171,8 +172,8 @@ class UserMark(models.Model):
@python_2_unicode_compatible
class Gallery(TranslatableModel):
translations = TranslatedFields(
title = models.CharField(_('title'), max_length=200),
description = models.TextField(_('description'), blank=True)
title=models.CharField(_('title'), max_length=200),
description=models.TextField(_('description'), blank=True)
)
date_added = models.DateTimeField(_('date published'),
default=now)
@ -693,17 +694,14 @@ class ImageModel(models.Model):
@python_2_unicode_compatible
class Photo(TranslatableModel, ImageModel):
translations = TranslatedFields(
title = models.CharField(_('title'),
max_length=200),
caption = models.TextField(_('caption'),
blank=True)
caption=models.TextField(_('caption'), blank=True),
title=models.CharField(_('title'), max_length=200)
)
slug = models.SlugField(_('slug'),
unique=True,
help_text=_('A "slug" is a unique URL-friendly title for an object.'),
max_length=200)
sort = models.PositiveIntegerField(verbose_name="Sort", null=True, default=10, db_index=True)
date_added = models.DateTimeField(_('date added'),
default=now)
is_public = models.BooleanField(_('is public'),
@ -712,19 +710,18 @@ class Photo(TranslatableModel, ImageModel):
tags = TagField(help_text=tagfield_help_text, verbose_name=_('tags'))
sites = models.ManyToManyField(Site, verbose_name=_(u'sites'),
blank=True, null=True)
users = models.ManyToManyField(UserMark, null=True)
objects = PhotologueManager()
class Meta:
ordering = ['-date_added']
ordering = ['sort']
get_latest_by = 'date_added'
verbose_name = _("photo")
verbose_name_plural = _("photos")
def __str__(self):
return self.get_available_title()
return str(self.id)
def translation_model(self):
return self._meta.translations_model
@ -1107,9 +1104,6 @@ def add_default_site(instance, created, **kwargs):
post_save.connect(add_default_site, sender=Gallery)
post_save.connect(add_default_site, sender=Photo)
from django.db.models.signals import post_save
from functions.signal_handlers import post_save_handler
pre_delete.connect(file_cleanup, sender=Photo)
post_save.connect(post_save_handler, sender=Photo)
post_save.connect(post_save_handler, sender=Gallery)

@ -189,6 +189,63 @@ def conference_change(request, url):
return render_to_response('place_conference_add.html', args)
from photologue.forms import PhotoForm
from functions.admin_views import AdminView
from file.forms import FileModelForm, FileForm
class PlaceConferenceView(AdminView):
form_class = ConferenceForm
model = PlaceConference
success_url = '/admin/place_conference/all/'
template_name = 'admin/place_conference/place_conference.html'
def get_form(self, form_class):
if self.request.POST:
return super(PlaceConferenceView, self).get_form(form_class)
obj = self.set_obj()
if obj:
data = {'type': obj.type, 'address': obj.address,
'phone': obj.phone, 'fax': obj.fax, 'web_page': obj.web_page, 'email': obj.email,
'foundation_year': obj.foundation_year, 'total_capacity': obj.total_capacity,
'amount_halls': obj.amount_halls, 'wifi':obj.wifi, 'multimedia_equipment': obj.multimedia_equipment,
'conference_call':obj.conference_call, 'translate_equipment': obj.translate_equipment,
'banquet_hall': obj.banquet_hall, 'catering': obj.catering, 'hotel': obj.hotel,
'video_link':obj.video_link, 'logo': obj.logo, 'exposition_hall': obj.exposition_hall,
'exp_hall_area': obj.exp_hall_area}
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['main_title_%s'%code] = obj.main_title
data['description_%s'%code] = obj.description
data['adress_%s'%code] = obj.adress
data['hall_capacity_%s'%code] = obj.hall_capacity
data['title_%s'%code] = obj.title
data['keywords_%s'%code] = obj.keywords
data['descriptions_%s'%code] = obj.descriptions
data['total_year_action_%s'%code] = obj.total_year_action
form = form_class(initial=data)
form.fields['city'].widget.attrs['data-init-text'] = obj.city.name
return form
else:
return form_class()
def get_context_data(self, **kwargs):
context = super(PlaceConferenceView, self).get_context_data(**kwargs)
obj = self.set_obj()
if obj:
context['file_form'] = FileForm(initial={'model': 'place_conference.PlaceConference'})
files = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(obj),object_id=getattr(obj, 'id'))
context['files'] = files
context['photo_form'] = PhotoForm()
return context
class PlaceConferenceListView(AdminListView):
template_name = 'admin/place_conference/place_conference_list.html'
form_class = PlaceConferenceFilterForm

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from admin import PlaceConferenceListView
from admin import PlaceConferenceListView, PlaceConferenceView
urlpatterns = patterns('place_conference.admin',
url(r'^add.*/$', 'conference_add'),
@ -9,4 +9,6 @@ urlpatterns = patterns('place_conference.admin',
url(r'^copy/(?P<url>.*)/$', 'place_conference_copy'),
#url(r'^all/$', 'conference_all'),
url(r'^all/$', PlaceConferenceListView.as_view()),
url(r'^(?P<url>.*)/$', PlaceConferenceView.as_view()),
url(r'^$', PlaceConferenceView.as_view()),
)

@ -28,12 +28,12 @@ class ConferenceForm(forms.Form):
"""
types = [(item1, item2) for item1, item2 in CONFERENCE_TYPE]
type = forms.ChoiceField(label='Краткое описание', required=False, choices=types)
logo = forms.ImageField(label='Logo', required=False, max_length=500)
country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None)
#creates select input with empty choices cause it will be filled with ajax
city = forms.ChoiceField(label='Город', choices=[('','')])
city = forms.CharField(label='Город', widget=forms.HiddenInput())
address = forms.CharField(label='Адресс', widget=LocationWidget)
address = forms.CharField(label='Адресс', widget=LocationWidget, required=False)
foundation_year = forms.CharField(label='Год основания', required=False,
widget=forms.TextInput(attrs={'placeholder': 'Год основания'}))
phone = forms.CharField(label='Телефон', required=False,
@ -108,7 +108,7 @@ class ConferenceForm(forms.Form):
"""
def save(self, id=None):
def save(self, obj=None):
"""
change PlaceConference model object with id = id
N/A add new PlaceConference model object
@ -117,13 +117,20 @@ class ConferenceForm(forms.Form):
"""
data = self.cleaned_data
#create new place_conference object or get exists
if not id:
if not obj:
place_conference = PlaceConference()
else:
place_conference = PlaceConference.objects.get(id=id)
place_conference = obj
if not getattr(place_conference, 'url'):
if data.get('name_en'):
place_conference.url = translit_with_separator(data['name_en'].strip()).lower()
else:
place_conference.url = translit_with_separator(data['name_ru'].strip()).lower()
if data.get('logo'):
place_conference.logo = data['logo']
#simple fields
place_conference.url = translit_with_separator(data['name_ru'].strip()).lower()
place_conference.type = data['type']
place_conference.address = data['address']
place_conference.phone = data['phone']
@ -152,22 +159,9 @@ class ConferenceForm(forms.Form):
fill_with_signal(PlaceConference, place_conference, data)
#save files
check_tmp_files(place_conference, data['key'])
return PlaceConference.objects.get(id=place_conference.id)
def clean(self):
id = self.cleaned_data.get('place_conference_id')
name_ru = self.cleaned_data.get('name_ru')
place_conference = PlaceConference.objects.filter(url=translit_with_separator(name_ru))
if place_conference and str(place_conference[0].id) != id:
msg = 'Место проведения с таким названием уже существует'
self._errors['name_ru'] = ErrorList([msg])
del self.cleaned_data['name_ru']
return self.cleaned_data
place_conference.save()
return place_conference
def clean_web_page(self):
"""
@ -318,4 +312,17 @@ class HallForm(forms.ModelForm):
class PlaceConferenceFilterForm(AdminFilterForm):
model = PlaceConference
model = PlaceConference
country = forms.MultipleChoiceField(choices=[(item.id, item.name) for item in list(Country.objects.all())],
required=False, widget=forms.SelectMultiple())
def filter(self):
qs = super(PlaceConferenceFilterForm, self).filter()
data = self.cleaned_data
country = data['country']
if country:
qs = qs.filter(country_id__in=country)
return qs

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.contenttypes import generic
from django.db.models.signals import post_save
from django.db.models.signals import post_save, pre_save
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from functions.custom_fields import EnumField
from functions.custom_fields import LocationField
from functions.signal_handlers import post_save_handler
from functions.signal_handlers import post_save_handler, pre_save_handler
from functions.models_methods import ExpoManager
import copy
from django.utils.translation import ugettext as _
@ -15,6 +15,11 @@ from functions.model_mixin import ExpoMixin
CONFERENCE_TYPE = (('Convention centre', 'Конгресс-центр'), ('Exposition centre', 'Конференц зал'),)
def logo_name(instance, filename):
url = instance.url
return '/'.join(['place_conference', url, url+'_logo.jpg'])
class PlaceConference(TranslatableModel, ExpoMixin):
"""
Create PlaceConference model
@ -22,28 +27,33 @@ class PlaceConference(TranslatableModel, ExpoMixin):
Uses hvad.TranslatableModel which is child of django.db.models class
"""
#set manager of this model
catalog = '/places/'
place = 'place_conference'
catalog_name = _(u'Места:')
search_name = None
objects = ExpoManager()
url = models.SlugField(unique=True)
country = models.ForeignKey('country.Country', on_delete=models.PROTECT)
city = models.ForeignKey('city.City', on_delete=models.PROTECT, related_name='place_conferences')
country = models.ForeignKey('country.Country', on_delete=models.PROTECT, verbose_name=_(u'Страна'))
city = models.ForeignKey('city.City', on_delete=models.PROTECT,
related_name='place_conferences', verbose_name=_(u'Город'))
#type uses EnumField for creating Enum type field in Mysql database
type = EnumField(values = [item1 for item1, item2 in CONFERENCE_TYPE])
type = EnumField(values = [item1 for item1, item2 in CONFERENCE_TYPE], default=CONFERENCE_TYPE[0][0],
verbose_name=_(u'Тип'))
#information
address = LocationField(verbose_name=_(u'Адресс'))
#
address= LocationField(verbose_name='Адресс')
#
phone = models.BigIntegerField(blank=True, null=True)
fax = models.BigIntegerField(blank=True, null=True)
web_page = models.URLField(blank=True)
email = models.EmailField(blank=True)
foundation_year = models.PositiveIntegerField(blank=True, null=True)
total_capacity = models.PositiveIntegerField(blank=True, null=True)
amount_halls = models.PositiveIntegerField(blank=True, null=True)
exposition_hall = models.NullBooleanField()
exp_hall_area = models.PositiveIntegerField(blank=True, null=True)
phone = models.BigIntegerField(blank=True, null=True, verbose_name=_(u'Телефон'))
fax = models.BigIntegerField(blank=True, null=True, verbose_name=_(u'Факс'))
web_page = models.URLField(blank=True, verbose_name=_(u'Веб сайт'))
email = models.EmailField(blank=True, verbose_name=_(u'Email'))
foundation_year = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Год основания'))
total_capacity = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Общая вместимость'))
amount_halls = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Количество залов'))
exposition_hall = models.NullBooleanField(verbose_name=_(u'Выставочный зал'))
exp_hall_area = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Площадь выст. зала'))
video_link = models.CharField(max_length=255, blank=True)
virtual_tour = models.URLField(blank=True, verbose_name=_(u'Виртуальный тур'))
#
wifi = models.NullBooleanField()
multimedia_equipment = models.NullBooleanField()
@ -53,6 +63,7 @@ class PlaceConference(TranslatableModel, ExpoMixin):
catering = models.NullBooleanField()
hotel = models.NullBooleanField()
#
logo = models.ImageField(verbose_name='Logo', upload_to=logo_name, blank=True, max_length=255)
files = generic.GenericRelation('file.FileModel',content_type_field='content_type', object_id_field='object_id')
#translations is translated fields
translations = TranslatedFields(
@ -162,5 +173,5 @@ class Hall(models.Model):
number = models.PositiveIntegerField(blank=True, null=True)
capacity = models.PositiveIntegerField(blank=True, null=True)
pre_save.connect(pre_save_handler, sender=PlaceConference)
post_save.connect(post_save_handler, sender=PlaceConference)

@ -112,7 +112,7 @@ class ExpositionForm(forms.Form):
else:
place_exposition = obj
#simple fields
if not getattr(place_exposition, 'url'):
if data.get('name_en'):
place_exposition.url = translit_with_separator(data['name_en'].strip()).lower()
@ -252,30 +252,6 @@ class PlaceExpositionFormDelete(forms.ModelForm):
model = PlaceExposition
fields = ('url',)
'''
class HallForm(forms.ModelForm):
"""
form for Hall model
uses ModelForm cause Hall doesnt have translated fields
"""
number = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:30px'}),required=False)
capacity = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:60px'}), required=False)
name = forms.CharField(required=False)
class Meta:
model = Hall
exclude = ('place_exposition',)
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):
cleaned_data = super(HallForm, self).clean()
capacity = cleaned_data.get('capacity').strip()
return is_positive_integer(capacity, 'Вместимость должна состоять из цифр')
'''
class HallForm(forms.Form):
url = '/admin/place_exposition/add-hall/'

@ -39,6 +39,7 @@ class PlaceExposition(TranslatableModel, ExpoMixin):
"""
catalog = '/places/'
place = 'place_exposition'
catalog_name = _(u'Места:')
search_name = None
#set manager of this model
@ -47,7 +48,7 @@ class PlaceExposition(TranslatableModel, ExpoMixin):
url = models.SlugField(unique=True, max_length=255)
country = models.ForeignKey('country.Country', on_delete=models.PROTECT)
city = models.ForeignKey('city.City', on_delete=models.PROTECT, related_name='place_expositions')
photogallery = models.ForeignKey('photologue.Gallery', null=True, blank=True)
photogallery = models.ForeignKey('photologue.Gallery', null=True, blank=True, on_delete=models.SET_NULL)
#type uses EnumField for creating Enum type field in Mysql database
type = EnumField(values = [item1 for item1, item2 in EXPOSITION_TYPE])
#information
@ -289,17 +290,3 @@ def create_place(sender, instance, created, **kwargs):
pre_save.connect(pre_save_handler, sender=PlaceExposition)
post_save.connect(create_place, sender=PlaceExposition)
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)
"""

@ -80,7 +80,7 @@ class PlaceDetail(JitterCacheMixin, MetadataMixin, DetailView):
obj = queryset.get()
except queryset.model.DoesNotExist:
try:
PlaceConference.objects.get(url=slug)
obj = PlaceConference.objects.get(url=slug)
except PlaceConference.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
@ -94,9 +94,11 @@ class PlaceDetail(JitterCacheMixin, MetadataMixin, DetailView):
context['country'] = str(obj.country_id)
return context
class PlacePhoto(ListView):
template_name = 'client/place/photo.html'
obj = None
paginate_by = settings.CLIENT_PAGINATION
def get_queryset(self):
slug = self.kwargs.get('slug')
@ -109,7 +111,10 @@ class PlacePhoto(ListView):
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': PlaceExposition._meta.verbose_name})
self.obj = place
return place.photogallery.photos.all()
if place.photogallery:
return place.photogallery.photos.all()
else:
raise Http404()
def get_context_data(self, **kwargs):
context = super(PlacePhoto, self).get_context_data(**kwargs)
@ -122,7 +127,7 @@ class PlacePhoto(ListView):
class PlaceList(JitterCacheMixin, MetadataMixin, ListView):
model = PlaceExposition
paginate_by = 10
paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/place/place_list.html'
@ -136,7 +141,7 @@ class PlaceList(JitterCacheMixin, MetadataMixin, ListView):
class PlaceCatalog(JitterCacheMixin, MetadataMixin, ListView):
cache_range = settings.CACHE_RANGE
model = PlaceExposition
paginate_by = 10
paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/place/catalog.html'
filter_object = None

@ -4,6 +4,7 @@ import os
import django
from django.utils.translation import ugettext_lazy as _
DJANGO_ROOT = os.path.dirname(os.path.realpath(django.__file__))
SITE_ROOT = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0]
@ -348,7 +349,6 @@ INSTALLED_APPS = (
'translator',
'webinar',
'meta',
'banners',
#django modules
'sorl.thumbnail', # for logos
'photologue', # photogallery

@ -56,13 +56,11 @@ urlpatterns = patterns('',
url(r'^', include('company.urls')),
url(r'^', include('photoreport.urls')),
url(r'^', include('article.urls')),
url(r'^country/', include('country.urls')),
url(r'^city/', include('city.urls')),
url(r'^organiser/', include('organiser.urls')),
url(r'^gallery/', include('photologue.client_urls')),
url(r'^', include('file.urls')),
url(r'^', include('django_messages.expomap_urls')),
url(r'^messages/', include('django_messages.urls')),
url(r'^advertising/$', AdvertisingView.as_view(), {'meta_id':58}),
url(r'^about/$', AboutView.as_view(), {'meta_id':56}),
url(r'^partners/$', AboutView.as_view(), {'meta_id':57}),
@ -73,7 +71,6 @@ urlpatterns = patterns('',
url(r'^accounts/', include('registration.backends.default.urls')),
url(r'^', include('password_reset.urls')),
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^redirect/', include('banners.urls')),
url(r'^', include('settings.old_urls')),
url(r'^', include('service.urls')),
)

@ -8,7 +8,8 @@ from registration import signals
from registration.models import RegistrationProfile
from registration.views import ActivationView as BaseActivationView
from registration.views import RegistrationView as BaseRegistrationView
from django.views.generic import View
from accounts.forms import RegistrationCompleteForm, SocialRegistrationCompleteForm
from social.apps.django_app.default.models import UserSocialAuth
import json
@ -248,8 +249,7 @@ def LoginView(request):
else:
HttpResponseRedirect('/')
from accounts.forms import RegistrationCompleteForm, RecoveryForm, SocialRegistrationCompleteForm
from social.apps.django_app.default.models import UserSocialAuth
def complete_registration(request):
@ -290,22 +290,4 @@ def acquire_email(request, template_name="registration/acquire_email.html"):
def inactive_user_message(request):
return render(request, 'registration/social_registration_complete.html')
def pswd_recovery(request):
#if request.is_ajax():
response = {'success': False}
form = RecoveryForm(request.POST)
if form.is_valid():
user = form.get_user()
user.se
response['success']=True
else:
response['errors'] = form.errors
return HttpResponse(json.dumps(response), content_type='application/json')
#else:
# return HttpResponse('not ajax')
return render(request, 'registration/social_registration_complete.html')

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

Loading…
Cancel
Save