downloaded from remote

remotes/origin/1203
Ivan_Home_PC 11 years ago
parent ad071cb0c9
commit 958ba883c3
  1. 1
      .gitignore
  2. 8
      accounts/admin.py
  3. 4
      accounts/admin_urls.py
  4. 28
      accounts/forms.py
  5. 3
      accounts/models.py
  6. 3
      accounts/views.py
  7. 13
      article/admin.py
  8. 3
      article/admin_urls.py
  9. 5
      article/views.py
  10. 5
      company/views.py
  11. 3
      conference/views.py
  12. 11
      core/forms.py
  13. 49
      core/models.py
  14. 87
      core/utils.py
  15. 80
      core/views.py
  16. 158
      expobanner/admin.py
  17. 14
      expobanner/admin_urls.py
  18. 111
      expobanner/forms.py
  19. 2
      expobanner/management/commands/banner_log_update.py
  20. 6
      expobanner/managers.py
  21. 39
      expobanner/models.py
  22. 63
      expobanner/utils.py
  23. 31
      expobanner/views.py
  24. 16
      exposition/forms.py
  25. 1
      exposition/manager.py
  26. 18
      exposition/models.py
  27. 7
      exposition/views.py
  28. 6
      functions/admin_views.py
  29. 49
      functions/custom_views.py
  30. 15
      functions/models_methods.py
  31. 2
      import_xls/excel_settings.py
  32. BIN
      locale/en/LC_MESSAGES/django.po
  33. 0
      logs/django_request.log
  34. 16
      logs/mylog.log
  35. 7056
      logs/mylog.log.1
  36. 12
      meta/admin.py
  37. 11
      meta/admin_urls.py
  38. 17
      meta/forms.py
  39. 80
      meta/models.py
  40. 11
      meta/views.py
  41. 439
      photologue/locale/en/LC_MESSAGES/django.po
  42. 2
      photologue/views.py
  43. 3
      place_exposition/views.py
  44. 6
      proj/admin.py
  45. 1
      proj/admin_urls.py
  46. 14
      proj/settings.py
  47. 5
      proj/urls.py
  48. 7
      proj/views.py
  49. 75
      registration/locale/en/LC_MESSAGES/django.po
  50. 2
      service/urls.py
  51. 1
      service/views.py
  52. 20
      settings/views.py
  53. 0
      specialist_catalog/__init__.py
  54. 18
      specialist_catalog/admin_urls.py
  55. 65
      specialist_catalog/forms.py
  56. 1
      specialist_catalog/management/__init__.py
  57. 1
      specialist_catalog/management/commands/__init__.py
  58. 41
      specialist_catalog/management/commands/create_city_page.py
  59. 42
      specialist_catalog/management/commands/create_country_page.py
  60. 108
      specialist_catalog/models.py
  61. 16
      specialist_catalog/tests.py
  62. 11
      specialist_catalog/urls.py
  63. 217
      specialist_catalog/views.py
  64. 2
      static/ckeditor/ckeditor/build-config.js
  65. 2
      static/ckeditor/ckeditor/lang/en.js
  66. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js
  67. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ar.js
  68. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/bg.js
  69. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ca.js
  70. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/cs.js
  71. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/cy.js
  72. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/da.js
  73. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/de.js
  74. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/el.js
  75. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/en.js
  76. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/eo.js
  77. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/es.js
  78. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/et.js
  79. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/fa.js
  80. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/fi.js
  81. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/fr.js
  82. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/gu.js
  83. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/he.js
  84. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/hi.js
  85. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/hr.js
  86. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/hu.js
  87. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/it.js
  88. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ja.js
  89. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/km.js
  90. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ku.js
  91. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/lt.js
  92. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/lv.js
  93. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/mk.js
  94. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/mn.js
  95. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/nb.js
  96. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/nl.js
  97. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/no.js
  98. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/pl.js
  99. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/pt-br.js
  100. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/pt.js
  101. Some files were not shown because too many files have changed in this diff Show More

1
.gitignore vendored

@ -7,6 +7,7 @@
.idea/ .idea/
media/ media/
media media
logs/
Thumbs.db Thumbs.db
npm-debug.log npm-debug.log
/proj/local.py /proj/local.py

@ -13,14 +13,20 @@ from django.utils.translation import ugettext as _
from models import User from models import User
from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnouncementForm, UserFilterForm from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnouncementForm, UserFilterForm
#custom views #custom views
from functions.admin_views import AdminView, AdminListView
from django.views.generic import UpdateView from django.views.generic import UpdateView
from functions.admin_views import AdminView, AdminListView, paginate_results
class UserListView(AdminListView): class UserListView(AdminListView):
template_name = 'admin/accounts/user_list.html' template_name = 'admin/accounts/user_list.html'
form_class = UserFilterForm form_class = UserFilterForm
model = User model = User
def get_context_data(self, **kwargs):
context = super(UserListView, self).get_context_data(**kwargs)
qs = self.model.objects.all()
result = paginate_results(qs, page=self.request.GET.get('page'))
context['object_list'] = result
return context
class EditUser(UpdateView): class EditUser(UpdateView):
model = User model = User

@ -3,10 +3,6 @@ from django.conf.urls import patterns, url
from admin import UserListView, EditUser from admin import UserListView, EditUser
urlpatterns = patterns('', urlpatterns = patterns('',
#url(r'^registration/$', 'accounts.admin.registration'),
#url(r'^create_admin/$', 'accounts.admin.create_admin'),
#url(r'^create_md5user/$', 'accounts.admin.create_md5'),
# url(r'^change/(?P<pk>.*)/$', EditUser.as_view()),
url(r'^change/(?P<url>.*)/$', 'accounts.admin.user_change'), url(r'^change/(?P<url>.*)/$', 'accounts.admin.user_change'),
url(r'^all/$', UserListView.as_view()), url(r'^all/$', UserListView.as_view()),
url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'), url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'),

@ -83,9 +83,7 @@ class UserForm(forms.ModelForm):
company = forms.ChoiceField(label='Компания', company = forms.ChoiceField(label='Компания',
choices=[(item.id, item.name) for item in Company.objects.language().all()], choices=[(item.id, item.name) for item in Company.objects.language().all()],
required=False) required=False)
organiser = forms.ChoiceField(label='Организатор',
choices=[(item.id, item.name) for item in Organiser.objects.language().all()],
required=False, initial=None)
title = forms.CharField(widget=forms.TextInput(attrs={'style': 'width: 550px'}), required=False) title = forms.CharField(widget=forms.TextInput(attrs={'style': 'width: 550px'}), required=False)
descriptions = forms.CharField(widget=forms.TextInput(attrs={'style': 'width: 550px'}), required=False) descriptions = forms.CharField(widget=forms.TextInput(attrs={'style': 'width: 550px'}), required=False)
keywords = forms.CharField(widget=forms.TextInput(attrs={'style': 'width: 550px'}), required=False) keywords = forms.CharField(widget=forms.TextInput(attrs={'style': 'width: 550px'}), required=False)
@ -105,9 +103,9 @@ class UserForm(forms.ModelForm):
class Meta: class Meta:
model = User model = User
exclude = ('username', 'email', 'last_login', 'password', 'is_admin', 'rating', 'is_superuser', 'is_staff' exclude = ('organiser', 'username', 'email', 'last_login', 'password', 'is_admin', 'rating', 'is_superuser', 'is_staff'
'date_joined', 'date_joined',
'date_registered', 'date_modified') 'date_registered', 'date_modified', 'is_active')
def save(self, force_insert=False, force_update=False, commit=True): def save(self, force_insert=False, force_update=False, commit=True):
@ -139,16 +137,16 @@ class UserForm(forms.ModelForm):
profile.save() profile.save()
return user return user
def clean_url(self): #def clean_url(self):
url = self.cleaned_data.get('url') # url = self.cleaned_data.get('url')
if url: # if url:
if User.objects.get(url=translit_with_separator(url)): # if User.objects.get(url=translit_with_separator(url)):
raise forms.ValidationError('Такой урл уже занят') # raise forms.ValidationError('Такой урл уже занят')
else: # else:
return url # return url
def clean_organiser(self): #def clean_organiser(self):
return clean_relation_field(self, 'organiser', Organiser) # return clean_relation_field(self, 'organiser', Organiser)
def clean_company(self): def clean_company(self):
return clean_relation_field(self, 'company', Company) return clean_relation_field(self, 'company', Company)

@ -144,6 +144,9 @@ class User(AbstractBaseUser, PermissionsMixin):
class Meta: class Meta:
ordering=['-rating'] ordering=['-rating']
def is_organiser(self):
return bool(self.organiser)
def get_full_name(self): def get_full_name(self):
""" """
Returns the first_name plus the last_name, with a space in between. Returns the first_name plus the last_name, with a space in between.

@ -8,7 +8,8 @@ from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _, get_language from django.utils.translation import ugettext as _, get_language
from django.utils import timezone from django.utils import timezone
from django_messages.forms import SendForm from django_messages.forms import SendForm
from django.views.generic import TemplateView, FormView, ListView from django.views.generic import TemplateView, FormView
from functions.custom_views import ListView
from sorl.thumbnail import get_thumbnail from sorl.thumbnail import get_thumbnail
from .forms import ChangePasswordForm, EmailAnnouncementForm, FeedFilterForm from .forms import ChangePasswordForm, EmailAnnouncementForm, FeedFilterForm
from company.forms import CreateCompanyForm from company.forms import CreateCompanyForm

@ -5,6 +5,7 @@ from django.core.context_processors import csrf
from django.conf import settings from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.views.generic import DeleteView
#models and forms #models and forms
from forms import ArticleForm, ArticleDeleteForm, Article, NewsForm from forms import ArticleForm, ArticleDeleteForm, Article, NewsForm
from theme.models import Tag from theme.models import Tag
@ -16,6 +17,18 @@ from functions.custom_views import objects_list, add_object_with_file, delete_ob
from functions.views_help import get_referer from functions.views_help import get_referer
class ArticleDeleteView(DeleteView):
model = Article
template_name = "admin/article/article_confirm_delete.html"
def get_success_url(self):
if self.object.type == 1:
type = "blog"
else:
type = "news"
return "/admin/article/%s/all/" % type
def article_all(request): def article_all(request):
""" """
Return list of all articles with pagination Return list of all articles with pagination

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from admin import BlogList, BlogView, NewsList, NewsView from admin import BlogList, BlogView, NewsList, NewsView, ArticleDeleteView
urlpatterns = patterns('article.admin', urlpatterns = patterns('article.admin',
@ -11,6 +11,7 @@ urlpatterns = patterns('article.admin',
#url(r'^all/$', 'article_all'), #url(r'^all/$', 'article_all'),
url(r'^blog/all/$', BlogList.as_view()), url(r'^blog/all/$', BlogList.as_view()),
url(r'^blog/$', BlogView.as_view()), url(r'^blog/$', BlogView.as_view()),
url(r'^delete/(?P<slug>.*)/$', ArticleDeleteView.as_view()),
url(r'^news/all/$', NewsList.as_view()), url(r'^news/all/$', NewsList.as_view()),
url(r'^news/$', NewsView.as_view()), url(r'^news/$', NewsView.as_view()),

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
from django.views.generic import DetailView, ListView from django.views.generic import DetailView
from functions.custom_views import ListView
from django.http import HttpResponse from django.http import HttpResponse
from models import Article from models import Article
from forms import ArticleFilterForm from forms import ArticleFilterForm
@ -9,6 +10,7 @@ from meta.views import MetadataMixin
class NewsList(MetadataMixin, ListView): class NewsList(MetadataMixin, ListView):
model = Article model = Article
template_name = 'article/news_list.html' template_name = 'article/news_list.html'
@ -52,7 +54,6 @@ class NewsList(MetadataMixin, ListView):
return context return context
class NewsDetail(MetadataMixin, DetailView): class NewsDetail(MetadataMixin, DetailView):
model = Article model = Article
slug_field = 'slug' slug_field = 'slug'

@ -2,7 +2,8 @@
import json import json
from django.http import HttpResponse from django.http import HttpResponse
from django.conf import settings from django.conf import settings
from django.views.generic import ListView, DetailView from django.views.generic import DetailView
from functions.custom_views import ListView
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext as _, get_language from django.utils.translation import ugettext as _, get_language
from haystack.query import EmptySearchQuerySet from haystack.query import EmptySearchQuerySet
@ -21,7 +22,7 @@ from meta.views import MetadataMixin
class CompanySearchView(ListView): class CompanySearchView(ListView):
paginate_by = 10 paginate_by = 10
template_name = 'company/search.html' template_name = 'client/company/search.html'
search_form = CompanySearchForm search_form = CompanySearchForm
model = Company model = Company

@ -6,7 +6,8 @@ from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpRespons
from django.contrib import messages from django.contrib import messages
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.views.generic import ListView, DetailView from django.views.generic import DetailView
from functions.custom_views import ListView
from django.views.generic.edit import FormMixin from django.views.generic.edit import FormMixin
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils import translation from django.utils import translation

@ -61,21 +61,12 @@ class PageForm(TranslatableModelForm):
class Meta: class Meta:
model = Page model = Page
fields = ['url','title','h1','descriptions','keywords', 'body' ] fields = ['url','title','h1','descriptions','keywords', 'body']
widgets = { widgets = {
'body':CKEditorWidget, 'body':CKEditorWidget,
'keywords':Textarea, 'keywords':Textarea,
'descriptions':Textarea, 'descriptions':Textarea,
} }
def clean_url(self):
url = self.cleaned_data.get('url', None)
if url[0] == '/':
url = url[1:]
if url[-1] == '/':
url = url[:-1]
if ' ' in url:
url.replace(' ', '_')
return url

@ -4,7 +4,7 @@ from django.shortcuts import get_object_or_404
from django.db import models from django.db import models
from exposition.models import Exposition from exposition.models import Exposition
from settings.models import create_transl_fields import copy
from theme.models import Theme from theme.models import Theme
from country.models import Country from country.models import Country
from city.models import City from city.models import City
@ -114,24 +114,39 @@ class Page(TranslatableModel):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('page_view', args=[self.url]) return reverse('page_view', args=[self.url])
def __init__(self, *args, **kwargs):
super(Page, self).__init__(*args, **kwargs)
self.cache_fields = ['h1', 'body','title', 'description', 'keywords']
self.var_cache = {var: copy.copy(getattr(self, var)) for var in self.cache_fields}
self.is_new = True
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super(Page,self).save(*args, **kwargs) super(Page,self).save(*args, **kwargs)
self.initial_language = 'ru'
all_field_names = list(self._translated_field_names)
clear_f_n = [] new_values = {field: getattr(self, field) for field in self.cache_fields}
for field_name in all_field_names: langs = [code for code, _ in settings.LANGUAGES]
if field_name not in ['master', 'master_id',u'id', 'language_code']: if self.is_new:
clear_f_n.append(field_name) for lang in langs:
field_items = {field_name:getattr(self, field_name) for field_name in clear_f_n} if lang not in self.get_available_languages():
self.translate(lang)
langs = [lan[0] for lan in settings.LANGUAGES] for key, value in new_values.items():
for lang in langs: setattr(self, key, value)
if lang not in self.get_available_languages(): self.save_translations(self)
self.translate(lang) else:
for field in clear_f_n: translations = {obj.language_code:obj for obj in list(self.translations.all())}
setattr(self, field, field_items.get(field, '')) for lang in langs:
obj = super(Page,self).save(*args, **kwargs) if lang is not self.initial_language:
return obj tr = translations[lang]
for key, value in new_values.items():
#if u'%s' % getattr(self, key) is u'' or getattr(self, key) is u'%s' % self.var_cache[key]:
setattr(tr, key, value)
tr.save()
self.lazy_translation_getter(self.initial_language)
self.var_cache = {var: copy.copy(getattr(self, var)) for var in self.cache_fields}
self.is_new = False
return self
def __unicode__(self): def __unicode__(self):
return self.url return self.url

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
http://www.simplistix.co.uk/presentations/python-excel.pdf
"""
import xlwt import xlwt
import datetime import datetime
from exposition.models import Exposition
from conference.models import Conference
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
HEADER_STYLE = xlwt.easyxf('font: bold on') HEADER_STYLE = xlwt.easyxf('font: bold on')
@ -16,6 +16,7 @@ CELL_STYLE_MAP = (
(bool, xlwt.easyxf(num_format_str='BOOLEAN')), (bool, xlwt.easyxf(num_format_str='BOOLEAN')),
) )
def multi_getattr(obj, attr, default=None): def multi_getattr(obj, attr, default=None):
attributes = attr.split(".") attributes = attr.split(".")
for i in attributes: for i in attributes:
@ -42,33 +43,65 @@ def get_column_cell(obj, name):
return ', '.join(unicode(x).strip() for x in attr.all()) return ', '.join(unicode(x).strip() for x in attr.all())
return attr return attr
def queryset_to_workbook(queryset, columns, header_style=None, default_style=None, cell_style_map=None):
def queryset_to_workbook(queryset, columns, report_date = None):
# defining styles for different types of cells
main_style = xlwt.Style.easyxf(
"font: name Calibri, height 600, bold False;"
"borders: left thin, right thin, top thin, bottom thin;"
"alignment: horizontal left, vertical center, indent 7;"
"pattern: pattern solid, fore_colour white;"
)
header_style = xlwt.Style.easyxf(
'font: name Calibri, height 400, bold False;'
'borders: left no_line, right no_line, top thin, bottom thin;'
'alignment: horizontal center, shrink_to_fit True;'
'pattern: pattern solid, fore_color gray_ega;',
)
odd_style = xlwt.Style.easyxf(
'font: name Calibri, height 300, bold False;'
'borders: left thin, right thin, top thin, bottom thin;'
'alignment: horizontal center, wrap True;'
'pattern: pattern solid, fore_color white;',
)
even_style = xlwt.Style.easyxf(
'font: name Calibri, height 300, bold False;'
'borders: left thin, right thin, top thin, bottom thin;'
'alignment: horizontal center, wrap True;'
'pattern: pattern solid, fore_color silver_ega;',
)
# creating workbook and adding sheet
workbook = xlwt.Workbook() workbook = xlwt.Workbook()
report_date = datetime.date.today() report_date = report_date or datetime.date.today()
sheet_name = 'Export {0}'.format(report_date.strftime('%Y-%m-%d')) sheet_name = u'My calendar {0}'.format(report_date.strftime('%Y-%B'))
sheet = workbook.add_sheet(sheet_name) sheet = workbook.add_sheet(sheet_name)
if not header_style: # drawing head part with image
header_style = HEADER_STYLE sheet.write_merge(0, 6, 0, 6, u'Мой календарь собитий на %s года' % report_date.strftime("%B %Y"), main_style)
if not default_style: for i in range(7):
default_style = DEFAULT_STYLE sheet.row(i).set_style(xlwt.Style.easyxf('font:height 300;'))
if not cell_style_map: sheet.insert_bitmap('/home/www/proj/media/logo.bmp', row=0, col=5, x=0, y=0, scale_x=0.3, scale_y=2)
cell_style_map = CELL_STYLE_MAP
# drawing headers
obj = queryset[0] header_list = [u'#', u'Название события',u'Даты',u'Краткое описание',u'Место проведения', u'Заметка', u'Ссылка на событие']
for i, column in enumerate(columns):
for y, column in enumerate(columns): sheet.write(8, i, header_list[i], header_style)
header_list=[u'Название события',u'Страна',u'Город',u'Место проведения', u'Дата начала', u'Дата окончания'] sheet.col(i).width = 8000
sheet.col(0).width = 2000
sheet.write(0, y, header_list[y], header_style)
# fill data
for x, obj in enumerate(queryset, start=1): for x, obj in enumerate(queryset, start=9):
for y, column in enumerate(columns): for y, column in enumerate(columns):
value = get_column_cell(obj, column) try:
style = default_style value = getattr(obj, column)
for value_type, cell_style in cell_style_map: except:
if isinstance(value, value_type): value = "-"
style = cell_style if x % 2 == 0:
style = even_style
else:
style = odd_style
sheet.write(x, y, value, style) sheet.write(x, y, value, style)
return workbook return workbook

@ -1,10 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from country.models import Country from country.models import Country
from city.models import City from city.models import City
from place_exposition.models import PlaceExposition from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference from place_conference.models import PlaceConference
from django.views.generic import ListView, CreateView, DeleteView, UpdateView, DetailView from django.views.generic import CreateView, DeleteView, UpdateView, DetailView
from functions.custom_views import ListView
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
from functions.views_help import split_params from functions.views_help import split_params
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
@ -218,11 +218,14 @@ class PageList(ListView):
template_name = 'page_admin_list.html' template_name = 'page_admin_list.html'
model = Page model = Page
order = 'created' order = 'created'
from django import forms
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
import datetime
class EditPage(UpdateView): class EditPage(UpdateView):
model = Page model = Page
template_name = 'new_page.html' template_name = 'admin/page/new_page.html'
form_class = PageForm form_class = PageForm
slug_url_kwarg = 'url' slug_url_kwarg = 'url'
slug_field = 'url' slug_field = 'url'
@ -233,7 +236,8 @@ class EditPage(UpdateView):
return context return context
def get_success_url(self): def get_success_url(self):
return HttpResponseRedirect('/admin/page/all/') return reverse_lazy('page_list')
class DeletePage(DeleteView): class DeletePage(DeleteView):
template_name = 'admin/page/page_confirm_delete.html' template_name = 'admin/page/page_confirm_delete.html'
@ -244,39 +248,57 @@ class DeletePage(DeleteView):
class PageDetailed(DetailView): class PageDetailed(DetailView):
model = Page model = Page
template_name = 'client/base_catalog.html' template_name = 'admin/page/page_template_view.html'
slug_field = 'url' slug_field = 'url'
slug_url_kwarg = 'url' slug_url_kwarg = 'url'
# ------------ XLS Export ---------------- # ------------ XLS Export ----------------
from django.http import HttpResponse from django.http import HttpResponse
from django.utils.translation import get_language
from .utils import queryset_to_workbook from .utils import queryset_to_workbook
from exposition.models import Exposition from exposition.models import Exposition
from conference.models import Conference from conference.models import Conference
from django.core.urlresolvers import reverse
def download_workbook(request): def download_workbook(request):
data = [(36539, 'expo'),(36602, 'expo'), (3033, 'conf'), (3053, 'conf')] lang = get_language()
qs = [] data = request.GET
for obj in data: if data:
if obj[1] == 'expo': qs = []
qs.append(Exposition.objects.get(id=obj[0])) for i,obj in enumerate(data):
if obj[1] == 'conf': if data.get('data[%i][name]'%i) == 'expo':
qs.append(Conference.objects.get(id=obj[0])) qs.append(Exposition.objects.language(lang).get(id=data['data[%i][value]'%i]))
columns = ( elif data.get('data[%i][name]'%i) == 'conf':
'name', qs.append(Conference.objects.language(lang).get(id=data['data[%i][value]'%i]))
'country.name',
'city.name', earliest_event = qs[0].data_begin
'place.name', for i, obj in enumerate(qs, start=1):
'data_begin', if obj.data_begin < earliest_event:
'data_end') earliest_event = obj.data_begin
setattr(obj, 'number', i)
workbook = queryset_to_workbook(qs, columns) setattr(obj, 'dates', u'%s - %s'%(obj.data_begin.strftime('%d %B %Y'),obj.data_end.strftime('%d %B %Y')))
response = HttpResponse(content_type='application/vnd.ms-excel') setattr(obj, 'full_place', u'%s, %s, %s' % (obj.country, obj.city, getattr(obj.place, 'name', '')))
response['Content-Disposition'] = 'attachment; filename="export.xls"' try:
workbook.save(response) setattr(obj, 'link', u'http://www.expomap.ru%s)'%obj.get_absolute_url())
return response except:
setattr(obj, 'link', u'http://www.expomap.ru%s)'%obj.get_permanent_url())
columns = (
'number',
'name',
'dates',
'main_title',
'full_place',
'participation_note',
'link')
workbook = queryset_to_workbook(qs, columns, earliest_event)
response = HttpResponse(content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="My calendar.xls"'
workbook.save(response)
return response
else:
return HttpResponseRedirect(request.META.get('HTTP_REFERER'), "/profile/calendar/")

@ -3,9 +3,10 @@ from django.views.generic import TemplateView, CreateView, ListView, UpdateView,
from django.conf import settings from django.conf import settings
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from expobanner.models import URL, BannerGroup, Banner, Paid from django.db.models import Sum
from expobanner.models import URL, BannerGroup, Banner, Paid, MainPage, Top
from expobanner.forms import UrlCreateForm, BannerCreateGroupForm, BannerCreateForm, BannerGroupUpdateForm,\ from expobanner.forms import UrlCreateForm, BannerCreateGroupForm, BannerCreateForm, BannerGroupUpdateForm,\
PaidCreateForm, PaidUpdateForm, TopCreateForm PaidCreateForm, PaidUpdateForm, TopCreateForm, BannerLinkCreateForm, MainCreateForm, MainUpdateForm, TopUpdateForm
from exposition.models import Exposition from exposition.models import Exposition
@ -33,6 +34,11 @@ class CreateBanner(AbstractCreate):
form_class = BannerCreateForm form_class = BannerCreateForm
class CreateLink(AbstractCreate):
model = Banner
form_class = BannerLinkCreateForm
# LISTS VIEWS # LISTS VIEWS
class AbstractList(ListView): class AbstractList(ListView):
paginate_by = settings.ADMIN_PAGINATION paginate_by = settings.ADMIN_PAGINATION
@ -63,6 +69,17 @@ class BannerList(AbstractList):
qs = qs.filter(group__isnull=False) qs = qs.filter(group__isnull=False)
return qs return qs
class LinkList(AbstractList):
model = Banner
verbose = u'Список ссылок'
template_name = 'admin/expobanner/link_list.html'
def get_queryset(self):
qs = super(LinkList, self).get_queryset()
qs = qs.filter(link=True)
return qs
# UPDATE VIEWS # UPDATE VIEWS
class AbstractUpdate(UpdateView): class AbstractUpdate(UpdateView):
template_name = 'admin/expobanner/default_form.html' template_name = 'admin/expobanner/default_form.html'
@ -84,23 +101,48 @@ class BannerUpdate(AbstractUpdate):
form_class = BannerCreateForm form_class = BannerCreateForm
class LinkUpdate(AbstractUpdate):
model = Banner
form_class = BannerLinkCreateForm
class BannerStat(DetailView): class BannerStat(DetailView):
model = Banner model = Banner
template_name = 'admin/expobanner/banner_stat.html' template_name = 'admin/expobanner/banner_stat.html'
def get_context_data(self, **kwargs):
context = super(BannerStat, self).get_context_data(**kwargs)
obj = self.object
qs = obj.banner_stat.all()
date_from, date_to = self.request.GET.get('date_from'), self.request.GET.get('date_to')
if date_from:
date_from = datetime.strptime(date_from, "%d.%m.%Y")
qs = qs.filter(date__gte=date_from)
if date_to:
date_to = datetime.strptime(date_to, "%d.%m.%Y")
qs = qs.filter(date__lte=date_to)
context['stats'] = qs
return context
class PaidList(ListView): class PaidList(ListView):
model = Exposition model = Exposition
template_name = 'admin/expobanner/paid_list.html' template_name = 'admin/expobanner/paid_list.html'
paginate_by = settings.ADMIN_PAGINATION paginate_by = settings.ADMIN_PAGINATION
def get_queryset(self): def get_queryset(self):
return self.model.objects.language().filter(paid_new__isnull=False) qs = self.model.objects.language().filter(paid_new__isnull=False).order_by('-paid_new__public')
if self.request.GET.get('onlypublic'):
qs = qs.filter(paid_new__public=True)
return qs
class PaidCreate(CreateView): class PaidCreate(CreateView):
form_class = PaidCreateForm form_class = PaidCreateForm
template_name = 'admin/expobanner/paid_create.html' template_name = 'admin/expobanner/paid_create.html'
success_url = '/admin/expobanners/paid/list/' success_url = '/admin/expobanners/paid/list/'
class PaidUpdate(UpdateView): class PaidUpdate(UpdateView):
model = Paid model = Paid
form_class = PaidUpdateForm form_class = PaidUpdateForm
@ -140,6 +182,97 @@ class PaidStat(DetailView):
model = Paid model = Paid
template_name = 'admin/expobanner/paid_stat.html' template_name = 'admin/expobanner/paid_stat.html'
def get_context_data(self, **kwargs):
context = super(PaidStat, self).get_context_data(**kwargs)
obj = self.object
context['all'] = obj.paidstat_set.aggregate(
official=Sum('official_clicks'),
ticket=Sum('tickets_clicks'),
participation=Sum('participation_clicks'),
catalog=Sum('catalog_clicks')
)
qs = obj.paidstat_set.all()
date_from, date_to = self.request.GET.get('date_from'), self.request.GET.get('date_to')
if date_from:
date_from = datetime.strptime(date_from, "%d.%m.%Y")
qs = qs.filter(date__gte=date_from)
if date_to:
date_to = datetime.strptime(date_to, "%d.%m.%Y")
qs = qs.filter(date__lte=date_to)
context['stats'] = qs
return context
# ----------------------------------
class MainList(ListView):
model = Exposition
template_name = 'admin/expobanner/main_list.html'
paginate_by = settings.ADMIN_PAGINATION
def get_queryset(self):
qs = self.model.objects.language().filter(main__isnull=False).order_by('-main__public')
if self.request.GET.get('onlypublic'):
qs = qs.filter(main__public=True)
return qs
class MainCreate(CreateView):
form_class = MainCreateForm
template_name = 'admin/expobanner/paid_create.html'
success_url = '/admin/expobanners/main/list/'
class MainUpdate(UpdateView):
model = MainPage
form_class = MainUpdateForm
template_name = 'admin/expobanner/default_form.html'
success_url = '/admin/expobanners/main/list/'
def get_context_data(self, **kwargs):
context = super(MainUpdate, self).get_context_data(**kwargs)
obj = self.object
context['exposition'] = obj.get_event()
return context
def main_turn(request, pk, status):
main = get_object_or_404(MainPage, pk=pk)
if status == 'on':
main.public = True
else:
main.public = False
main.save()
return HttpResponseRedirect('/admin/expobanners/main/list/')
from datetime import datetime
class MainStat(DetailView):
model = MainPage
template_name = 'admin/expobanner/main_stat.html'
def get_context_data(self, **kwargs):
context = super(MainStat, self).get_context_data(**kwargs)
obj = self.object
context['all'] = obj.link.banner_stat.aggregate(
views=Sum('view'),
clicks=Sum('click'),
unique_clicks=Sum('unique_click'),
unique_views=Sum('unique_view')
)
qs = obj.link.banner_stat.all()
date_from, date_to = self.request.GET.get('date_from'), self.request.GET.get('date_to')
if date_from:
date_from = datetime.strptime(date_from, "%d.%m.%Y")
qs = qs.filter(date__gte=date_from)
if date_to:
date_to = datetime.strptime(date_to, "%d.%m.%Y")
qs = qs.filter(date__lte=date_to)
context['stats'] = qs
return context
# ------------------------------------
from datetime import date
class TopList(ListView): class TopList(ListView):
model = Exposition model = Exposition
@ -147,10 +280,27 @@ class TopList(ListView):
paginate_by = settings.ADMIN_PAGINATION paginate_by = settings.ADMIN_PAGINATION
def get_queryset(self): def get_queryset(self):
return self.model.objects.language().filter(top__isnull=False) qs = self.model.objects.language().filter(top__isnull=False).order_by('-top__fr')
if self.request.GET.get('onlypublic'):
qs = qs.filter(top__fr__lte=date.today(), top__to__gte=date.today())
return qs
class TopCreate(CreateView): class TopCreate(CreateView):
form_class = TopCreateForm form_class = TopCreateForm
template_name = 'admin/expobanner/top_create.html' template_name = 'admin/expobanner/top_create.html'
success_url = '/admin/expobanners/top/list/' success_url = '/admin/expobanners/top/list/'
class TopUpdate(UpdateView):
model = Top
form_class = TopUpdateForm
template_name = 'admin/expobanner/top_create.html'
success_url = '/admin/expobanners/top/list/'
def get_context_data(self, **kwargs):
context = super(TopUpdate, self).get_context_data(**kwargs)
obj = self.object
context['exposition'] = obj.get_event()
return context

@ -8,13 +8,17 @@ urlpatterns = patterns('expobanner.admin',
url(r'^banners/url/$', CreateUrl.as_view(), name='expobanner-create_url'), url(r'^banners/url/$', CreateUrl.as_view(), name='expobanner-create_url'),
url(r'^banners/group/$', CreateBannerGroup.as_view(), name='expobanner-create_group'), url(r'^banners/group/$', CreateBannerGroup.as_view(), name='expobanner-create_group'),
url(r'^banners/banner/$', CreateBanner.as_view(), name='expobanner-create_banner'), url(r'^banners/banner/$', CreateBanner.as_view(), name='expobanner-create_banner'),
url(r'^banners/link/$', CreateLink.as_view(), name='expobanner-create_link'),
url(r'^banners/url/list/$', UrlList.as_view(), name='expobanner-list_url'), url(r'^banners/url/list/$', UrlList.as_view(), name='expobanner-list_url'),
url(r'^banners/group/list/$', BannerGroupList.as_view(), name='expobanner-list_group'), url(r'^banners/group/list/$', BannerGroupList.as_view(), name='expobanner-list_group'),
url(r'^banners/banner/list/$', BannerList.as_view(), name='expobanner-list_banner'), url(r'^banners/banner/list/$', BannerList.as_view(), name='expobanner-list_banner'),
url(r'^banners/link/list/$', LinkList.as_view(), name='expobanner-list_link'),
url(r'^banners/url/(?P<pk>\d+)/edit/$', UrlUpdate.as_view(), name='expobanner-update_url'), url(r'^banners/url/(?P<pk>\d+)/edit/$', UrlUpdate.as_view(), name='expobanner-update_url'),
url(r'^banners/group/(?P<pk>\d+)/edit/$', BannerGroupUpdate.as_view(), name='expobanner-update_group'), url(r'^banners/group/(?P<pk>\d+)/edit/$', BannerGroupUpdate.as_view(), name='expobanner-update_group'),
url(r'^banners/banner/(?P<pk>\d+)/edit/$', BannerUpdate.as_view(), name='expobanner-update_banner'), url(r'^banners/banner/(?P<pk>\d+)/edit/$', BannerUpdate.as_view(), name='expobanner-update_banner'),
url(r'^banners/link/(?P<pk>\d+)/edit/$', LinkUpdate.as_view(), name='expobanner-update_link'),
url(r'^banners/banner/(?P<pk>\d+)/stat/$', BannerStat.as_view(), name='expobanner_stat_banner'), url(r'^banners/banner/(?P<pk>\d+)/stat/$', BannerStat.as_view(), name='expobanner_stat_banner'),
url(r'^banners/banner/(?P<pk>\d+)/stat/$', BannerStat.as_view(), name='expobanner_stat_link'),
# paid # paid
url(r'^paid/list/$', PaidList.as_view(), name='expobanner-list_paid'), url(r'^paid/list/$', PaidList.as_view(), name='expobanner-list_paid'),
url(r'^paid/(?P<pk>\d+)/edit/$', PaidUpdate.as_view(), name='expobanner-update_paid'), url(r'^paid/(?P<pk>\d+)/edit/$', PaidUpdate.as_view(), name='expobanner-update_paid'),
@ -23,7 +27,13 @@ urlpatterns = patterns('expobanner.admin',
url(r'^paid/(?P<pk>\d+)/stat/$', PaidStat.as_view(), name='expobanner_stat_paid'), url(r'^paid/(?P<pk>\d+)/stat/$', PaidStat.as_view(), name='expobanner_stat_paid'),
# top # top
url(r'^top/list/$', TopList.as_view(), name='expobanner-list_top'), url(r'^top/list/$', TopList.as_view(), name='expobanner-list_top'),
url(r'^top/(?P<pk>\d+)/edit/$', PaidUpdate.as_view(), name='expobanner-update_top'), url(r'^top/(?P<pk>\d+)/edit/$', TopUpdate.as_view(), name='expobanner-update_top'),
url(r'^top/$', TopCreate.as_view(), name='expobanner-create_top'), url(r'^top/$', TopCreate.as_view(), name='expobanner-create_top'),
url(r'^top/(?P<pk>\d+)/stat/$', PaidStat.as_view(), name='expobanner_stat_top'), url(r'^top/(?P<pk>\d+)/stat/$', MainStat.as_view(), name='expobanner_stat_top'),
# main page
url(r'^main/list/$', MainList.as_view(), name='expobanner-list_main'),
url(r'^main/(?P<pk>\d+)/edit/$', MainUpdate.as_view(), name='expobanner-update_main'),
url(r'^main/$', MainCreate.as_view(), name='expobanner-create_main'),
url(r'^main/turn/(?P<pk>\d+)/(?P<status>.*)/$', main_turn, name='expobanner-main-turn'),
url(r'^main/(?P<pk>\d+)/stat/$', MainStat.as_view(), name='expobanner_stat_main'),
) )

@ -1,14 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django import forms from django import forms
from expobanner.models import URL, BannerGroup, Banner, Paid, Top from expobanner.models import URL, BannerGroup, Banner, Paid, Top, MainPage
from exposition.models import Exposition from exposition.models import Exposition
from country.models import Country from country.models import Country
from city.models import City from ckeditor.widgets import CKEditorWidget
from theme.models import Theme, Tag from theme.models import Theme, Tag
class UrlCreateForm(forms.ModelForm): class UrlCreateForm(forms.ModelForm):
verbose = u'Создать урл' verbose = u'Создать урл'
class Meta: class Meta:
model = URL model = URL
exclude = ['created_at', 'updated_at', 'sites'] exclude = ['created_at', 'updated_at', 'sites']
@ -16,12 +17,14 @@ class UrlCreateForm(forms.ModelForm):
class BannerCreateGroupForm(forms.ModelForm): class BannerCreateGroupForm(forms.ModelForm):
verbose = u'Создать групу' verbose = u'Создать групу'
class Meta: class Meta:
model = BannerGroup model = BannerGroup
exclude = ['created_at', 'updated_at', 'speed'] exclude = ['created_at', 'updated_at', 'speed']
class BannerGroupUpdateForm(BannerCreateGroupForm): class BannerGroupUpdateForm(BannerCreateGroupForm):
verbose = u'Изменить групу' verbose = u'Изменить групу'
class Meta: class Meta:
model = BannerGroup model = BannerGroup
exclude = ['created_at', 'updated_at', 'slug', 'speed'] exclude = ['created_at', 'updated_at', 'slug', 'speed']
@ -29,15 +32,28 @@ class BannerGroupUpdateForm(BannerCreateGroupForm):
class BannerCreateForm(forms.ModelForm): class BannerCreateForm(forms.ModelForm):
verbose = u'Создать банер' verbose = u'Создать банер'
#country = forms.ChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) text = forms.CharField(label=u'Текст', required=False, widget=CKEditorWidget)
#theme = forms.ChoiceField(label=u'Тематика', required=False, class Meta:
# choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) model = Banner
#city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) exclude = ['created_at', 'updated_at', 'often', 'paid', 'stat_pswd', 'cookie', 'link']
#tag = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False)
class BannerLinkCreateForm(forms.ModelForm):
verbose = u'Отслеживаемую ссылку'
class Meta: class Meta:
model = Banner model = Banner
exclude = ['created_at', 'updated_at', 'often', 'paid', 'stat_pswd'] fields = ['public', 'alt', 'url']
exclude = ['created_at', 'updated_at', 'often', 'paid', 'stat_pswd', 'cookie', 'link']
def save(self, commit=True):
banner = super(BannerLinkCreateForm, self).save(commit=False)
if commit:
banner.link =True
banner.save()
return banner
class ClientStatForm(forms.Form): class ClientStatForm(forms.Form):
@ -91,6 +107,36 @@ class PaidCreateForm(forms.ModelForm):
raise forms.ValidationError(u'Такой выставки не существует') raise forms.ValidationError(u'Такой выставки не существует')
return expo return expo
class MainCreateForm(forms.ModelForm):
verbose = u'Добавить выставку на главную'
exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput())
class Meta:
model = MainPage
fields = ['position', 'public']
def save(self, commit=True):
main = super(MainCreateForm, self).save(commit=False)
if commit:
expo = self.cleaned_data['exposition']
link = expo.get_permanent_url()
link_b = Banner.objects.create_for_paid(expo, link, 'main_page_link')
main.link = link_b
main.save()
expo.main = main
expo.save()
return main
def clean_exposition(self):
expo_id = self.cleaned_data['exposition']
try:
expo = Exposition.objects.get(id=expo_id)
except Exposition.DoesNotExist:
raise forms.ValidationError(u'Такой выставки не существует')
return expo
class PaidUpdateForm(forms.ModelForm): class PaidUpdateForm(forms.ModelForm):
tickets = forms.URLField(label=u'Линк на билеты') tickets = forms.URLField(label=u'Линк на билеты')
participation = forms.URLField(label=u'Линк на участие') participation = forms.URLField(label=u'Линк на участие')
@ -126,17 +172,23 @@ class PaidUpdateForm(forms.ModelForm):
return paid return paid
class MainUpdateForm(forms.ModelForm):
class Meta:
model = MainPage
fields = ['position', 'public']
class TopCreateForm(forms.ModelForm): class TopCreateForm(forms.ModelForm):
verbose = u'Создать выставку в топе' verbose = u'Создать выставку в топе'
exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput()) exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput())
country = forms.MultipleChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) country = forms.MultipleChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False)
theme = forms.MultipleChoiceField(label=u'Тематика', required=False, theme = forms.MultipleChoiceField(label=u'Тематика', required=False,
choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()])
excluded_cities = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) #excluded_cities = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False)
excluded_tags = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) #excluded_tags = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False)
class Meta: class Meta:
model = Top model = Top
fields = ['catalog', 'position', 'theme', 'excluded_tags', 'country', 'excluded_cities', 'fr', 'to'] fields = ['catalog', 'position', 'theme', 'country', 'fr', 'to']
def save(self, commit=True): def save(self, commit=True):
top = super(TopCreateForm, self).save(commit=False) top = super(TopCreateForm, self).save(commit=False)
@ -149,15 +201,22 @@ class TopCreateForm(forms.ModelForm):
top.theme.clear() top.theme.clear()
for theme in self.cleaned_data['theme']: for theme in self.cleaned_data['theme']:
top.theme.add(theme) top.theme.add(theme)
top.country.clear()
for country in self.cleaned_data['country']:
top.country.add(country)
self.save_m2m = save_m2m self.save_m2m = save_m2m
if commit: if commit:
expo = self.cleaned_data['exposition'] expo = self.cleaned_data['exposition']
link = expo.get_permanent_url()
link_b = Banner.objects.create_for_paid(expo, link, 'top_link')
top.link = link_b
top.save() top.save()
self.save_m2m() self.save_m2m()
expo.top = top expo.top = top
expo.save() expo.save()
return top return top
def clean_theme(self): def clean_theme(self):
@ -179,3 +238,33 @@ class TopCreateForm(forms.ModelForm):
except Exposition.DoesNotExist: except Exposition.DoesNotExist:
raise forms.ValidationError(u'Такой выставки не существует') raise forms.ValidationError(u'Такой выставки не существует')
return expo return expo
class TopUpdateForm(forms.ModelForm):
verbose = u'Изменить выставку'
class Meta:
model = Top
fields = ['catalog', 'position', 'theme', 'country', 'fr', 'to']
def save(self, commit=True):
top = super(TopUpdateForm, self).save(commit=False)
# Prepare a 'save_m2m' method for the form,
old_save_m2m = self.save_m2m
def save_m2m():
old_save_m2m()
# This is where we actually link the pizza with toppings
top.theme.clear()
for theme in self.cleaned_data['theme']:
top.theme.add(theme)
top.country.clear()
for country in self.cleaned_data['country']:
top.country.add(country)
self.save_m2m = save_m2m
if commit:
top.save()
self.save_m2m()
return top

@ -9,7 +9,7 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
today = date.today() today = date.today()
# banners # banners
for banner in Banner.objects.select_related('group').filter(public=True, group__isnull=False): for banner in Banner.objects.select_related('group').filter(public=True):
try: try:
logstat = LogStat.objects.get(banner=banner, group=banner.group, date=today) logstat = LogStat.objects.get(banner=banner, group=banner.group, date=today)
except LogStat.DoesNotExist: except LogStat.DoesNotExist:

@ -51,7 +51,7 @@ class BannerGroupCached(models.Manager):
for group in groups: for group in groups:
result[group.slug] = list(group.banners.prefetch_related('urls', 'theme', 'country')\ result[group.slug] = list(group.banners.prefetch_related('urls', 'theme', 'country')\
.filter(public=True, fr__lte=today)\ .filter(public=True, fr__lte=today)\
.filter(Q(to__gte=today) | Q(to__isnull=True)).extra({})) .filter(Q(to__gte=today) | Q(to__isnull=True)))
cache.set(key, result, 70) cache.set(key, result, 70)
return result return result
@ -71,7 +71,9 @@ class TopCached(models.Manager):
key = 'expo_b_top_all' key = 'expo_b_top_all'
result = cache.get(key) result = cache.get(key)
if not result: if not result:
result = list(self.prefetch_related('theme', 'country', 'excluded_tags', 'excluded_cities').all()) today = date.today()
result = list(self.prefetch_related('theme', 'country', 'excluded_tags', 'excluded_cities').
filter(fr__lte=today).filter(Q(to__gte=today) | Q(to__isnull=True)))
cache.set(key, result, 80) cache.set(key, result, 80)
return result return result

@ -95,8 +95,11 @@ class Banner(models.Model, StatMixin):
html = models.BooleanField(verbose_name=_('HTML?'), default=False) html = models.BooleanField(verbose_name=_('HTML?'), default=False)
flash = models.BooleanField(verbose_name=_('Flash?'), default=False) flash = models.BooleanField(verbose_name=_('Flash?'), default=False)
js = models.BooleanField(verbose_name=_('Javascript?'), default=False) popup = models.BooleanField(verbose_name=_('Popup?'), default=False)
paid = models.BooleanField(verbose_name=_('Is Paid event link?'), default=False) paid = models.BooleanField(verbose_name=_('Is Paid event link?'), default=False)
link = models.BooleanField(verbose_name=_('Is simple link?'), default=False)
# for detecting popups
cookie = models.CharField(max_length=30, blank=True, null=True, default=settings.DEFAULT_POPUP_COOKIE)
public = models.BooleanField(verbose_name=u'Активный', default=True) public = models.BooleanField(verbose_name=u'Активный', default=True)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
@ -110,7 +113,6 @@ class Banner(models.Model, StatMixin):
def get_admin_url(self): def get_admin_url(self):
return '/admin/expobanners/banners/banner/%d/edit/'%self.id return '/admin/expobanners/banners/banner/%d/edit/'%self.id
def key(slef): def key(slef):
if hasattr(settings, 'SECRET_KEY'): if hasattr(settings, 'SECRET_KEY'):
key = str(datetime.now()) + settings.SECRET_KEY key = str(datetime.now()) + settings.SECRET_KEY
@ -203,6 +205,9 @@ class LogStat(models.Model):
def __unicode__(self): def __unicode__(self):
return '%s - (%s)' % (self.banner, self.date) return '%s - (%s)' % (self.banner, self.date)
class Meta:
ordering = ['-date']
# ------------------ # ------------------
class Paid(models.Model, StatMixin): class Paid(models.Model, StatMixin):
@ -221,9 +226,10 @@ class Paid(models.Model, StatMixin):
ordering = ['-public'] ordering = ['-public']
def get_event(self): def get_event(self):
if self.exposition_set.all().exists(): try:
return self.exposition_set.all()[0] return self.exposition_set.all()[0]
return None except IndexError:
return None
class PaidStat(models.Model): class PaidStat(models.Model):
@ -237,8 +243,12 @@ class PaidStat(models.Model):
participation_clicks = models.PositiveIntegerField(default=0) participation_clicks = models.PositiveIntegerField(default=0)
official_clicks = models.PositiveIntegerField(default=0) official_clicks = models.PositiveIntegerField(default=0)
class Meta:
ordering = ['-date']
class Top(models.Model, StatMixin): class Top(models.Model, StatMixin):
link = models.ForeignKey(Banner)
catalog = models.CharField(max_length=16, verbose_name=u'Каталог для топа') catalog = models.CharField(max_length=16, verbose_name=u'Каталог для топа')
position = models.PositiveIntegerField(blank=True, default=2, null=True, verbose_name=u'Позиция') position = models.PositiveIntegerField(blank=True, default=2, null=True, verbose_name=u'Позиция')
theme = models.ManyToManyField('theme.Theme', blank=True, null=True, verbose_name=u'Тематики') theme = models.ManyToManyField('theme.Theme', blank=True, null=True, verbose_name=u'Тематики')
@ -261,6 +271,7 @@ class Top(models.Model, StatMixin):
except IndexError: except IndexError:
return None return None
class TopStat(models.Model): class TopStat(models.Model):
date = models.DateField() date = models.DateField()
theme = models.ForeignKey('theme.Theme', blank=True, null=True) theme = models.ForeignKey('theme.Theme', blank=True, null=True)
@ -270,6 +281,25 @@ class TopStat(models.Model):
views = models.PositiveIntegerField(default=0) views = models.PositiveIntegerField(default=0)
clicks = models.PositiveIntegerField(default=0) clicks = models.PositiveIntegerField(default=0)
class MainPage(models.Model, StatMixin):
link = models.ForeignKey(Banner)
position = models.PositiveIntegerField(blank=True, default=2, null=True, verbose_name=u'Позиция')
public = models.BooleanField(default=True, verbose_name=u'Активная')
stat_pswd = models.CharField(max_length=16)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-public']
def get_event(self):
try:
return self.exposition_set.all()[0]
except IndexError:
return None
def generatePassword(length=5): def generatePassword(length=5):
""" """
generate random password generate random password
@ -293,7 +323,6 @@ def generate_stat_pass(sender, **kwargs):
obj.save() obj.save()
post_save.connect(generate_stat_pass, sender=Banner) post_save.connect(generate_stat_pass, sender=Banner)
post_save.connect(generate_stat_pass, sender=Paid) post_save.connect(generate_stat_pass, sender=Paid)
post_save.connect(generate_stat_pass, sender=Top) post_save.connect(generate_stat_pass, sender=Top)

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import re
import random import random
import datetime
from django.db import connection from django.db import connection
def get_client_ip(request): def get_client_ip(request):
@ -10,6 +12,32 @@ def get_client_ip(request):
ip = request.META.get('REMOTE_ADDR') ip = request.META.get('REMOTE_ADDR')
return ip return ip
def get_referer_view(request, default=None):
'''
Return the referer view of the current request
Example:
def some_view(request):
...
referer_view = get_referer_view(request)
return HttpResponseRedirect(referer_view, '/accounts/login/')
'''
# if the user typed the url directly in the browser's address bar
referer = request.META.get('HTTP_REFERER')
if not referer:
return default
# remove the protocol and split the url at the slashes
referer = re.sub('^https?:\/\/', '', referer).split('/')
if referer[0] != request.META.get('SERVER_NAME'):
return default
# add the slash at the relative path's view and finished
referer = u'/' + u'/'.join(referer[1:])
return referer
def get_by_sort(banner_list): def get_by_sort(banner_list):
max_sort = 0 max_sort = 0
for banner in banner_list: for banner in banner_list:
@ -19,12 +47,26 @@ def get_by_sort(banner_list):
result = [banner for banner in banner_list if banner.sort == max_sort] result = [banner for banner in banner_list if banner.sort == max_sort]
return result return result
def set_cookie(response, key, value, days_expire = 7):
if days_expire is None:
max_age = 365 * 24 * 60 * 60 #one year
else:
max_age = days_expire * 24 * 60 * 60
expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age), "%a, %d-%b-%Y %H:%M:%S GMT")
response.set_cookie(key, value, max_age=max_age, expires=expires)
return response
def get_banner_by_params(banners_list, urls, params): def get_banner_by_params(banners_list, urls, params, request):
thematic_banners = [] thematic_banners = []
url_banners = [] url_banners = []
for banner in banners_list: for banner in banners_list:
# check popups
if banner.popup:
cookie = request.COOKIES.get(banner.cookie)
if cookie:
continue
# check by theme # check by theme
banner_theme_ids = [str(theme.id) for theme in banner.theme.all()] banner_theme_ids = [str(theme.id) for theme in banner.theme.all()]
if banner_theme_ids: if banner_theme_ids:
@ -64,14 +106,18 @@ def get_banner_by_params(banners_list, urls, params):
continue continue
if thematic_banners: if thematic_banners:
return random.choice(thematic_banners) result = thematic_banners
if url_banners: elif url_banners:
return random.choice(url_banners) result = url_banners
return None else:
result = []
#print('END. NUMBER of queries = %d'%len(connection.queries)) if result:
sort_result = get_by_sort(result)
return random.choice(sort_result)
else:
return None
def get_top_events(tops, params): def get_top_events(tops, params, request):
catalog = params.get('catalog') catalog = params.get('catalog')
country = params.get('country', '') country = params.get('country', '')
theme = params.get('theme', []) theme = params.get('theme', [])
@ -108,5 +154,6 @@ def get_top_events(tops, params):
for top in sorted_top: for top in sorted_top:
event = top.get_event() event = top.get_event()
if event: if event:
top.link.log(request, 1)
events.append(event) events.append(event)
return events return events

@ -6,7 +6,7 @@ from django.shortcuts import redirect, get_object_or_404
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.template import RequestContext from django.template import RequestContext
from .models import Banner, BannerGroup, URL, Top from .models import Banner, BannerGroup, URL, Top
from expobanner.utils import get_by_sort, get_banner_by_params, get_client_ip, get_top_events from expobanner.utils import get_banner_by_params, get_client_ip, get_top_events, get_referer_view, set_cookie
def click(request, banner_id): def click(request, banner_id):
@ -21,8 +21,7 @@ def view(request, banner_id):
return redirect(banner.img.url) return redirect(banner.img.url)
def get_banners(request): def get_banners(request):
#url = request.GET.get('url', '/') url = get_referer_view(request, default='/')
url = request.META.get('HTTP_REFERER', '/')
# get urls by current url # get urls by current url
urls = URL.cached.all() urls = URL.cached.all()
good_urls = [] good_urls = []
@ -42,18 +41,27 @@ def get_banners(request):
group_banners = BannerGroup.cached.group_banners() group_banners = BannerGroup.cached.group_banners()
result = [] result = []
cookie = None
# get banners for all groups # get banners for all groups
places = request.GET.getlist('places', [])
for group, banners in group_banners.iteritems(): for group, banners in group_banners.iteritems():
banner = get_banner_by_params(banners, good_urls, params) if group not in places:
# on this page there is no such group
continue
banner = get_banner_by_params(banners, good_urls, params, request)
if banner: if banner:
if banner.js or banner.html: if banner.html:
text = banner.text text = banner.text
img = '' img = ''
alt = '' alt = ''
is_img = False is_img = False
else: else:
text = '' text = ''
img = banner.img.url try:
img = banner.img.url
except ValueError:
continue
alt = banner.alt alt = banner.alt
is_img = True is_img = True
result.append({'id': group, result.append({'id': group,
@ -61,15 +69,20 @@ def get_banners(request):
'is_html': banner.html, 'is_html': banner.html,
'is_flash': banner.flash, 'is_flash': banner.flash,
'is_img': is_img, 'is_img': is_img,
'is_js': banner.js, 'is_popup': banner.popup,
'img': img, 'img': img,
'alt': alt, 'alt': alt,
'text': text 'text': text
}) })
if banner.popup:
cookie = banner.cookie
# add view log # add view log
banner.log(request, 1) banner.log(request, 1)
response = HttpResponse(json.dumps(result, indent=4), content_type='application/json')
if cookie:
response = set_cookie(response, cookie, '1')
return HttpResponse(json.dumps(result, indent=4), content_type='application/json') return response
def get_top(request): def get_top(request):
params = {'theme': request.GET.getlist('theme', []), params = {'theme': request.GET.getlist('theme', []),
@ -79,6 +92,6 @@ def get_top(request):
'catalog': request.GET.get('catalog')} 'catalog': request.GET.get('catalog')}
tops = Top.cached.all() tops = Top.cached.all()
events = get_top_events(tops, params) events = get_top_events(tops, params, request)
context = {'objects': events} context = {'objects': events}
return render_to_response('client/includes/exposition/expo_top.html', context, context_instance=RequestContext(request)) return render_to_response('client/includes/exposition/expo_top.html', context, context_instance=RequestContext(request))

@ -2,8 +2,6 @@
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from ckeditor.widgets import CKEditorWidget from ckeditor.widgets import CKEditorWidget
from tinymce.widgets import TinyMCE
from django.core.exceptions import ValidationError
from django.forms.util import ErrorList from django.forms.util import ErrorList
from django.core.validators import validate_email, URLValidator from django.core.validators import validate_email, URLValidator
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
@ -13,15 +11,11 @@ from theme.models import Tag
from country.models import Country from country.models import Country
from theme.models import Theme from theme.models import Theme
from organiser.models import Organiser from organiser.models import Organiser
from accounts.models import User
from company.models import Company
from city.models import City from city.models import City
from service.models import Service
from place_exposition.models import PlaceExposition from place_exposition.models import PlaceExposition
#functions #functions
from functions.translate import populate_all, fill_trans_fields_all, fill_with_signal from functions.translate import fill_with_signal
from functions.form_check import is_positive_integer from functions.form_check import is_positive_integer
from functions.files import check_tmp_files
from functions.form_check import translit_with_separator from functions.form_check import translit_with_separator
from settings.settings import date_formats from settings.settings import date_formats
from functions.admin_forms import AdminFilterForm from functions.admin_forms import AdminFilterForm
@ -223,7 +217,6 @@ class ExpositionCreateForm(forms.Form):
exposition.country = Country.objects.get(id=data['country']) exposition.country = Country.objects.get(id=data['country'])
exposition.city = City.objects.get(id=data['city']) exposition.city = City.objects.get(id=data['city'])
if data.get('place'): if data.get('place'):
exposition.place = PlaceExposition.objects.get(id=data['place']) exposition.place = PlaceExposition.objects.get(id=data['place'])
else: else:
@ -365,7 +358,6 @@ class ExpositionCreateForm(forms.Form):
price_catalog = cleaned_data.get('price_catalog').strip() price_catalog = cleaned_data.get('price_catalog').strip()
return is_positive_integer(price_catalog) return is_positive_integer(price_catalog)
def clean_visitors(self): def clean_visitors(self):
""" """
checking visitors checking visitors
@ -455,6 +447,12 @@ class ExpositionCreateForm(forms.Form):
discount = cleaned_data.get('discount').strip() discount = cleaned_data.get('discount').strip()
return is_positive_integer(discount) return is_positive_integer(discount)
class ExpositionDeleteForm(forms.ModelForm): class ExpositionDeleteForm(forms.ModelForm):
url = forms.CharField(widget=forms.HiddenInput()) url = forms.CharField(widget=forms.HiddenInput())

@ -10,6 +10,7 @@ class ClientManager(TranslationManager):
def upcoming(self): def upcoming(self):
return self.filter(data_begin__gte=datetime.datetime.now().date()) return self.filter(data_begin__gte=datetime.datetime.now().date())
""" """
from exposition.models import Exposition from exposition.models import Exposition

@ -59,6 +59,8 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
data_end = models.DateField(verbose_name='Дата окончания') data_end = models.DateField(verbose_name='Дата окончания')
services = BitField(flags=flags) services = BitField(flags=flags)
# relations # relations
creator = models.ForeignKey('accounts.User', verbose_name=u'Создатель', on_delete=models.SET_NULL,
related_name='exposition_creator', blank=True, null=True)
country = models.ForeignKey('country.Country', verbose_name='Страна', on_delete=models.PROTECT, country = models.ForeignKey('country.Country', verbose_name='Страна', on_delete=models.PROTECT,
related_name='exposition_country') related_name='exposition_country')
city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT, city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT,
@ -158,14 +160,12 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
paid_new = models.ForeignKey('expobanner.Paid', blank=True, null=True, on_delete=models.SET_NULL) paid_new = models.ForeignKey('expobanner.Paid', blank=True, null=True, on_delete=models.SET_NULL)
top = models.ForeignKey('expobanner.Top', blank=True, null=True, on_delete=models.SET_NULL) top = models.ForeignKey('expobanner.Top', blank=True, null=True, on_delete=models.SET_NULL)
main = models.ForeignKey('expobanner.MainPage', blank=True, null=True, on_delete=models.SET_NULL)
#set manager of this model(fisrt manager is default) #set manager of this model(fisrt manager is default)
objects = ExpoManager() objects = ExpoManager()
enable = ClientManager() enable = ClientManager()
imports = ExpoImportManager() imports = ExpoImportManager()
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk)) return self.lazy_translation_getter('name', unicode(self.pk))
@ -306,6 +306,18 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def theme_ids(self): def theme_ids(self):
return [item['id'] for item in self.theme.all().values('id')] return [item['id'] for item in self.theme.all().values('id')]
def get_main_link(self):
if self.main:
return self.main.link.get_click_link()
else:
return self.get_permanent_url()
def get_top_link(self):
if self.top:
return self.top.link.get_click_link()
else:
return self.get_permanent_url()
class Statistic(TranslatableModel): class Statistic(TranslatableModel):
exposition = models.ForeignKey(Exposition, related_name='statistic') exposition = models.ForeignKey(Exposition, related_name='statistic')

@ -4,7 +4,8 @@ import datetime
from django.http import HttpResponseRedirect, HttpResponse, HttpResponsePermanentRedirect from django.http import HttpResponseRedirect, HttpResponse, HttpResponsePermanentRedirect
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.conf import settings from django.conf import settings
from django.views.generic import ListView, DetailView from django.views.generic import DetailView
from functions.custom_views import ListView
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.http import Http404 from django.http import Http404
@ -433,7 +434,9 @@ class ExpoCityCatalog(ExpoCatalog):
return qs return qs
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ExpoCityCatalog, self).get_context_data(**kwargs) context = super(ExpoCityCatalog, self).get_context_data(**kwargs)
context['city'] = str(self.kwargs['city'].id) city = self.kwargs['city']
context['country'] = str(city.country_id)
context['city'] = str(city.id)
return context return context

@ -90,6 +90,7 @@ def paginate_results(qs, page=None):
return result return result
from hvad.models import TranslatableModel
class AdminListView(FormView): class AdminListView(FormView):
def get_form(self, form_class): def get_form(self, form_class):
@ -126,7 +127,10 @@ class AdminListView(FormView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(AdminListView, self).get_context_data(**kwargs) context = super(AdminListView, self).get_context_data(**kwargs)
qs = self.model.objects.language().all().order_by('name') if issubclass(self.model, TranslatableModel):
qs = self.model.objects.language('all').all().order_by('name')
else:
qs = self.model.objects.all().order_by('name')
result = paginate_results(qs, page=self.request.GET.get('page')) result = paginate_results(qs, page=self.request.GET.get('page'))
context['object_list'] = result context['object_list'] = result
return context return context

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.core.context_processors import csrf from django.core.context_processors import csrf
from django.conf import settings from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@ -18,8 +18,51 @@ from hvad.utils import get_translation_aware_manager
#python #python
import random import random
from django.views.generic import ListView as OldListView
from country.models import Country class ListView(OldListView):
"""
List of modules, where overrided ListView is used:
- accounts.views
- article.views
- company.views
- conference.views
- core.views
- exposition.views
- photologue.views
- place_exposition.views
- specialist_catalog.views
- translator.views
"""
def paginate_queryset(self, queryset, page_size):
"""
Paginate the queryset, if needed.
"""
paginator = self.get_paginator(queryset, page_size, allow_empty_first_page=self.get_allow_empty())
page_kwarg = self.page_kwarg
page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1
try:
page_number = int(page)
except ValueError:
if page == 'last':
page_number = paginator.num_pages
else:
raise Http404(_("Page is not 'last', nor can it be converted to an int."))
try:
page = paginator.page(page_number)
self.kwargs['home'] = False
except EmptyPage as e:
page = paginator.page(1)
self.kwargs['home'] = True
return (paginator, page, page.object_list, page.has_other_pages())
def get(self, request, *args, **kwargs):
response = super(ListView, self).get(request, *args, **kwargs)
if self.kwargs.get("home"):
return HttpResponseRedirect("/")
else:
return response
@login_required @login_required
@ -186,7 +229,7 @@ def delete_object(request, Model, Form, url, prev_page,):
return render_to_response('delete.html', args) return render_to_response('delete.html', args)
#-----class------------------ #-----class------------------
from django.views.generic import ListView, DetailView from django.views.generic import DetailView
from functions.views_help import split_params from functions.views_help import split_params
from city.models import City from city.models import City

@ -25,6 +25,21 @@ class ExpoManager(TranslationManager):
except: except:
return None return None
def expo_main(self):
lang = translation.get_language()
key = 'expo_main_page_key_%s'%lang
result = cache.get(key)
if not result:
result = list(self.language(lang).
select_related('country', 'city', 'place', 'main').
prefetch_related('tag').
filter(main__isnull=False).
filter(main__public=True))
cache.set(key, result, 45)
return result
class CityManager(TranslationManager): class CityManager(TranslationManager):
cache_time = 600 cache_time = 600

@ -27,7 +27,7 @@ def get_theme(value):
def get_tag(value): def get_tag(value):
tag_names = [item['name'] for item in value.all().values('name')] tag_names = [item['name'] for item in value.language('ru').all().values('name')]
return ','.join(tag_names) return ','.join(tag_names)
def get_place_type(value): def get_place_type(value):

Binary file not shown.

@ -0,0 +1,16 @@
2015-07-28 12:23:39,172 [DEBUG] django.db.backends: (0.001) SHOW TABLES; args=()
2015-07-28 12:23:39,175 [DEBUG] django.db.backends: (0.000) SELECT `service_service`.`id`, `service_service`.`url`, `service_service`.`currency`, `service_service`.`price`, `service_service`.`params`, `service_service`.`template`, `service_service`.`type`, `service_service`.`sort`, `service_service`.`main_page`, `service_service`.`meta_id` FROM `service_service`; args=()
2015-07-28 12:23:39,200 [DEBUG] django.db.backends: (0.002) SHOW TABLES; args=()
2015-07-28 12:23:39,201 [DEBUG] django.db.backends: (0.000) SELECT `service_service`.`id`, `service_service`.`url`, `service_service`.`currency`, `service_service`.`price`, `service_service`.`params`, `service_service`.`template`, `service_service`.`type`, `service_service`.`sort`, `service_service`.`main_page`, `service_service`.`meta_id` FROM `service_service`; args=()
2015-07-28 12:23:39,232 [DEBUG] django.db.backends: (0.001) SHOW TABLES; args=()
2015-07-28 12:23:39,233 [DEBUG] django.db.backends: (0.000) SELECT `service_service`.`id`, `service_service`.`url`, `service_service`.`currency`, `service_service`.`price`, `service_service`.`params`, `service_service`.`template`, `service_service`.`type`, `service_service`.`sort`, `service_service`.`main_page`, `service_service`.`meta_id` FROM `service_service`; args=()
2015-07-28 12:23:39,247 [DEBUG] django.db.backends: (0.001) SHOW TABLES; args=()
2015-07-28 12:23:39,248 [DEBUG] django.db.backends: (0.000) SELECT `service_service`.`id`, `service_service`.`url`, `service_service`.`currency`, `service_service`.`price`, `service_service`.`params`, `service_service`.`template`, `service_service`.`type`, `service_service`.`sort`, `service_service`.`main_page`, `service_service`.`meta_id` FROM `service_service`; args=()
2015-07-28 12:23:39,284 [DEBUG] django.db.backends: (0.001) SHOW TABLES; args=()
2015-07-28 12:23:39,285 [DEBUG] django.db.backends: (0.000) SELECT `service_service`.`id`, `service_service`.`url`, `service_service`.`currency`, `service_service`.`price`, `service_service`.`params`, `service_service`.`template`, `service_service`.`type`, `service_service`.`sort`, `service_service`.`main_page`, `service_service`.`meta_id` FROM `service_service`; args=()
2015-07-28 12:23:39,304 [DEBUG] django.db.backends: (0.001) SHOW TABLES; args=()
2015-07-28 12:23:39,305 [DEBUG] django.db.backends: (0.000) SELECT `service_service`.`id`, `service_service`.`url`, `service_service`.`currency`, `service_service`.`price`, `service_service`.`params`, `service_service`.`template`, `service_service`.`type`, `service_service`.`sort`, `service_service`.`main_page`, `service_service`.`meta_id` FROM `service_service`; args=()
2015-07-28 12:23:39,460 [DEBUG] root: Using default logger
2015-07-28 12:23:39,460 [DEBUG] root: Using default logger
2015-07-28 12:24:17,361 [DEBUG] django.db.backends: (0.001) SELECT `accounts_user`.`id`, `accounts_user`.`password`, `accounts_user`.`last_login`, `accounts_user`.`is_superuser`, `accounts_user`.`email`, `accounts_user`.`username`, `accounts_user`.`first_name`, `accounts_user`.`last_name`, `accounts_user`.`rating`, `accounts_user`.`url`, `accounts_user`.`is_active`, `accounts_user`.`is_staff`, `accounts_user`.`is_admin`, `accounts_user`.`date_joined`, `accounts_user`.`date_registered`, `accounts_user`.`date_modified`, `accounts_user`.`organiser_id`, `accounts_user`.`translator_id`, `accounts_user`.`company_id`, `accounts_user`.`position` FROM `accounts_user` WHERE `accounts_user`.`email` = 'vaniakov95@gmail.com' ; args=('vaniakov95@gmail.com',)
2015-07-28 12:24:25,526 [DEBUG] django.db.backends: (0.000) SELECT `accounts_user`.`id`, `accounts_user`.`password`, `accounts_user`.`last_login`, `accounts_user`.`is_superuser`, `accounts_user`.`email`, `accounts_user`.`username`, `accounts_user`.`first_name`, `accounts_user`.`last_name`, `accounts_user`.`rating`, `accounts_user`.`url`, `accounts_user`.`is_active`, `accounts_user`.`is_staff`, `accounts_user`.`is_admin`, `accounts_user`.`date_joined`, `accounts_user`.`date_registered`, `accounts_user`.`date_modified`, `accounts_user`.`organiser_id`, `accounts_user`.`translator_id`, `accounts_user`.`company_id`, `accounts_user`.`position` FROM `accounts_user` WHERE `accounts_user`.`email` = 'vaniakov95@gmail.com' ; args=('vaniakov95@gmail.com',)

File diff suppressed because one or more lines are too long

@ -1,13 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.shortcuts import render_to_response from django.http import HttpResponseRedirect
from django.http import HttpResponseRedirect, HttpResponse
from django.core.context_processors import csrf
from django.conf import settings from django.conf import settings
from django.forms.formsets import BaseFormSet, formset_factory # models and forms
from django.forms.models import modelformset_factory
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.decorators import login_required
#models and forms
from models import MetaSetting from models import MetaSetting
from forms import MetaForm, MetaFilterForm from forms import MetaForm, MetaFilterForm
from functions.admin_views import AdminListView, AdminView from functions.admin_views import AdminListView, AdminView
@ -45,7 +39,7 @@ class MetaView(AdminView):
data['keywords_%s' % code] = trans_obj.keywords data['keywords_%s' % code] = trans_obj.keywords
data['h1_%s' % code] = trans_obj.h1 data['h1_%s' % code] = trans_obj.h1
form =form_class(initial=data) form = form_class(initial=data)
return form return form
else: else:
return form_class() return form_class()

@ -1,16 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, url
from admin import MetaListView, MetaView from views import CreateSeoText, SeoTextList, EditSeoText, DeleteSeoText
from .views import CreateSeoText, SeoTextList, EditSeoText, DeleteSeoText from .admin import MetaListView, MetaView
urlpatterns = patterns('conference.admin',
urlpatterns = patterns('',
url(r'^seo/new/$', CreateSeoText.as_view(), name='seo_new'), url(r'^seo/new/$', CreateSeoText.as_view(), name='seo_new'),
url(r'^seo/all/$', SeoTextList.as_view(), name='seo_all'), url(r'^seo/all/$', SeoTextList.as_view(), name='seo_all'),
url(r'^seo/edit/(?P<pk>\d{1,5})/$', EditSeoText.as_view(), name='seo_edit'), url(r'^seo/edit/(?P<pk>\d{1,5})/$', EditSeoText.as_view(), name='seo_edit'),
url(r'^seo/delete/(?P<pk>\d{1,5})/$', DeleteSeoText.as_view(), name='seo_delete'), url(r'^seo/delete/(?P<pk>\d{1,5})/$', DeleteSeoText.as_view(), name='seo_delete'),
url(r'^all/$', MetaListView.as_view()), url(r'^all/$', MetaListView.as_view()),
#url(r'^change/(?P<url>.*)/$', 'conference_change'), url(r'^(?P<id>\d{1,6})/$', MetaView.as_view()),
url(r'^(?P<id>.*)/$', MetaView.as_view()),
url(r'^$', MetaView.as_view()), url(r'^$', MetaView.as_view()),
) )

@ -1,9 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from models import MetaSetting from models import MetaSetting, SeoText
from functions.translate import fill_with_signal from functions.translate import fill_with_signal
from functions.admin_forms import AdminFilterForm from functions.admin_forms import AdminFilterForm
from ckeditor.widgets import CKEditorWidget
from hvad.forms import TranslatableModelForm
class MetaForm(forms.Form): class MetaForm(forms.Form):
@ -14,7 +16,7 @@ class MetaForm(forms.Form):
create dynamical translated fields fields create dynamical translated fields fields
""" """
super(MetaForm, self).__init__(*args, **kwargs) super(MetaForm, self).__init__(*args, **kwargs)
#creates translated forms example: name_ru, name_en # creates translated forms example: name_ru, name_en
# len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs # len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs
if len(settings.LANGUAGES) in range(10): if len(settings.LANGUAGES) in range(10):
for lid, (code, name) in enumerate(settings.LANGUAGES): for lid, (code, name) in enumerate(settings.LANGUAGES):
@ -44,17 +46,14 @@ class MetaForm(forms.Form):
fill_with_signal(MetaSetting, meta, data) fill_with_signal(MetaSetting, meta, data)
meta.save() meta.save()
class MetaFilterForm(AdminFilterForm): class MetaFilterForm(AdminFilterForm):
model = MetaSetting model = MetaSetting
from .models import SeoText
from ckeditor.widgets import CKEditorWidget
from hvad.forms import TranslatableModelForm
class SeoTextForm(TranslatableModelForm): class SeoTextForm(TranslatableModelForm):
# lang = forms.ChoiceField(choices=settings.LANGUAGES)
class Meta: class Meta:
model = SeoText model = SeoText
fields = ['url', 'title', 'body'] fields = ['url', 'title', 'page_title', 'description', 'body']
widgets = {'body':CKEditorWidget} widgets = {'body': CKEditorWidget}

@ -3,9 +3,15 @@ from django.db import models
from django.utils import translation from django.utils import translation
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.utils.translation import ugettext_lazy as _ 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 hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from pymorphy.django_conf import default_morph as morph from pymorphy.django_conf import default_morph as morph
from functions.signal_handlers import post_save_handler from functions.signal_handlers import post_save_handler
import copy
# additional funcs # additional funcs
MONTHES = {'jan': _(u'январе'), 'feb': _(u'феврале'), 'mar': _(u'марте'), 'apr': _(u'апреле'), MONTHES = {'jan': _(u'январе'), 'feb': _(u'феврале'), 'mar': _(u'марте'), 'apr': _(u'апреле'),
@ -118,62 +124,70 @@ post_save.connect(post_save_handler, sender=MetaSetting)
# SEO - tests # # SEO - tests #
from django.db import models
from hvad.models import TranslatableModel, TranslatedFields
from django.conf import settings
from django.core.urlresolvers import reverse_lazy
from django.core.cache import cache
class SeoTextManager(TranslationManager): class SeoTextManager(TranslationManager):
cache_time = 120 cache_time = 120
def cache_get(self, *args, **kwargs): def cache_get(self, *args, **kwargs):
url = kwargs.get('url') url = kwargs.get('url')
lang = kwargs.get('lang')[:2] or translation.get_language()[:2] lang = kwargs.get('lang')[:2] or translation.get_language()[:2]
key = 'seo_text_cache' key = 'seo_text_cache'
result = cache.get(key) result = cache.get(key)
if result: if result:
return result.get(lang+'_' + url) return result.get("%s_%s" % (lang, url))
qs = list(SeoText.objects.language('all')) qs = list(SeoText.objects.language('all'))
value_dict = {obj.language_code+'_'+obj.url:obj for obj in qs} value_dict = {obj.language_code+'_'+obj.url: obj for obj in qs}
cache.set(key, value_dict, self.cache_time) cache.set(key, value_dict, self.cache_time)
return value_dict.get(lang+'_'+url) return value_dict.get("%s_%s" % (lang, url))
class SeoText(TranslatableModel): class SeoText(TranslatableModel):
url = models.CharField(max_length=50, unique=True, verbose_name=u"URL: www.expomap.ru")
url = models.CharField(max_length=50, unique=True)
translations = TranslatedFields( translations = TranslatedFields(
title=models.CharField(max_length=255), title=models.CharField(max_length=255, verbose_name=u"Заголовок"),
body=models.TextField() page_title=models.CharField(max_length=255, verbose_name=u"Тайтл страницы"),
description=models.CharField(max_length=1000, verbose_name=u"Дескрипшн"),
body=models.TextField(verbose_name=u"Текст")
) )
objects = SeoTextManager() objects = SeoTextManager()
def __init__(self, *args, **kwargs):
super(SeoText, self).__init__(*args, **kwargs)
self.cache_fields = ['title', 'body', 'page_title', 'description']
self.is_new = True
def get_absolute_url(self): def get_absolute_url(self):
return reverse_lazy('seo_all') return self.url
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super(SeoText,self).save(*args, **kwargs) super(SeoText, self).save(*args, **kwargs)
self.initial_language = 'ru'
all_field_names = list(self._translated_field_names)
clear_f_n = [] new_values = {field: getattr(self, field) for field in self.cache_fields}
for field_name in all_field_names: langs = [code for code, _ in settings.LANGUAGES]
if field_name not in ['master', 'master_id', u'id', 'language_code']: if self.is_new:
clear_f_n.append(field_name) for lang in langs:
field_items = {field_name:getattr(self, field_name) for field_name in clear_f_n} if lang not in self.get_available_languages():
self.translate(lang)
langs = [lan[0] for lan in settings.LANGUAGES] for key, value in new_values.items():
for lang in langs: setattr(self, key, value)
if lang not in self.get_available_languages(): self.save_translations(self)
self.translate(lang) else:
for field in clear_f_n: translations = {obj.language_code:obj for obj in list(self.translations.all())}
setattr(self, field, field_items.get(field, '')) for lang in langs:
super(SeoText,self).save(*args, **kwargs) if lang is not self.initial_language:
return SeoText tr = translations[lang]
for key, value in new_values.items():
#if u'%s' % getattr(self, key) is u'' or getattr(self, key) is u'%s' % self.var_cache[key]:
setattr(tr, key, value)
tr.save()
self.lazy_translation_getter(self.initial_language)
self.var_cache = {var: copy.copy(getattr(self, var)) for var in self.cache_fields}
self.is_new = False
return self
def __unicode__(self): def __unicode__(self):
return self.url return self.url

@ -1,9 +1,9 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from . import settings
from django.views.generic import CreateView, UpdateView, DeleteView, ListView
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from models import MetaSetting from models import MetaSetting
from .forms import SeoTextForm, SeoText
from . import settings
class Meta(object): class Meta(object):
@ -189,10 +189,6 @@ class MetadataMixin(object):
return context return context
from django.views.generic import CreateView, UpdateView, DeleteView, ListView
from .models import SeoText
from .forms import SeoTextForm
class CreateSeoText(CreateView): class CreateSeoText(CreateView):
form_class = SeoTextForm form_class = SeoTextForm
@ -212,6 +208,7 @@ class EditSeoText(UpdateView):
template_name = "admin/meta/create_seo_text.html" template_name = "admin/meta/create_seo_text.html"
class DeleteSeoText(DeleteView): class DeleteSeoText(DeleteView):
model = SeoText model = SeoText
template_name = "admin/meta/seo_confirm_delete.html" template_name = "admin/meta/seo_confirm_delete.html"

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Photologue\n" "Project-Id-Version: Photologue\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-08-25 09:56+0000\n" "POT-Creation-Date: 2015-09-08 13:44+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,171 +17,91 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: admin.py:67 #: photologue/models.py:59
msgid "The following photo does not belong to the same site(s)"
msgid_plural "The following photos do not belong to the same site(s)"
msgstr[0] ""
msgstr[1] ""
#: admin.py:79
#, python-format
msgid "The gallery has been successfully added to %(site)s"
msgid_plural "The galleries have been successfully added to %(site)s"
msgstr[0] ""
msgstr[1] ""
#: admin.py:86
msgid "Add selected galleries from the current site"
msgstr ""
#: admin.py:92
#, python-format
msgid "The gallery has been successfully removed from %(site)s"
msgid_plural ""
"The selected galleries have been successfully removed from %(site)s"
msgstr[0] ""
msgstr[1] ""
#: admin.py:99
msgid "Remove selected galleries from the current site"
msgstr ""
#: admin.py:106
#, python-format
msgid ""
"All photos in gallery %(galleries)s have been successfully added to %(site)s"
msgid_plural ""
"All photos in galleries %(galleries)s have been successfully added to "
"%(site)s"
msgstr[0] ""
msgstr[1] ""
#: admin.py:117
msgid "Add all photos of selected galleries to the current site"
msgstr ""
#: admin.py:124
#, python-format
msgid ""
"All photos in gallery %(galleries)s have been successfully removed from "
"%(site)s"
msgid_plural ""
"All photos in galleries %(galleries)s have been successfully removed from "
"%(site)s"
msgstr[0] ""
msgstr[1] ""
#: admin.py:135
msgid "Remove all photos in selected galleries from the current site"
msgstr ""
#: admin.py:186
#, python-format
msgid "The photo has been successfully added to %(site)s"
msgid_plural "The selected photos have been successfully added to %(site)s"
msgstr[0] ""
msgstr[1] ""
#: admin.py:193
msgid "Add selected photos to the current site"
msgstr ""
#: admin.py:199
#, python-format
msgid "The photo has been successfully removed from %(site)s"
msgid_plural "The selected photos have been successfully removed from %(site)s"
msgstr[0] ""
msgstr[1] ""
#: admin.py:206
msgid "Remove selected photos from the current site"
msgstr ""
#: models.py:56
msgid "Separate tags with spaces, put quotes around multiple-word tags." msgid "Separate tags with spaces, put quotes around multiple-word tags."
msgstr "" msgstr ""
#: models.py:67 #: photologue/models.py:70
msgid "Django-tagging was not found, tags will be treated as plain text." msgid "Django-tagging was not found, tags will be treated as plain text."
msgstr "" msgstr ""
#: models.py:115 #: photologue/models.py:121
msgid "Very Low" msgid "Very Low"
msgstr "" msgstr ""
#: models.py:116 #: photologue/models.py:122
msgid "Low" msgid "Low"
msgstr "" msgstr ""
#: models.py:117 #: photologue/models.py:123
msgid "Medium-Low" msgid "Medium-Low"
msgstr "" msgstr ""
#: models.py:118 #: photologue/models.py:124
msgid "Medium" msgid "Medium"
msgstr "" msgstr ""
#: models.py:119 #: photologue/models.py:125
msgid "Medium-High" msgid "Medium-High"
msgstr "" msgstr ""
#: models.py:120 #: photologue/models.py:126
msgid "High" msgid "High"
msgstr "" msgstr ""
#: models.py:121 #: photologue/models.py:127
msgid "Very High" msgid "Very High"
msgstr "" msgstr ""
#: models.py:126 #: photologue/models.py:132
msgid "Top" msgid "Top"
msgstr "" msgstr ""
#: models.py:127 #: photologue/models.py:133
msgid "Right" msgid "Right"
msgstr "" msgstr ""
#: models.py:128 #: photologue/models.py:134
msgid "Bottom" msgid "Bottom"
msgstr "" msgstr ""
#: models.py:129 #: photologue/models.py:135
msgid "Left" msgid "Left"
msgstr "" msgstr ""
#: models.py:130 #: photologue/models.py:136
msgid "Center (Default)" msgid "Center (Default)"
msgstr "" msgstr ""
#: models.py:134 #: photologue/models.py:140
msgid "Flip left to right" msgid "Flip left to right"
msgstr "" msgstr ""
#: models.py:135 #: photologue/models.py:141
msgid "Flip top to bottom" msgid "Flip top to bottom"
msgstr "" msgstr ""
#: models.py:136 #: photologue/models.py:142
msgid "Rotate 90 degrees counter-clockwise" msgid "Rotate 90 degrees counter-clockwise"
msgstr "" msgstr ""
#: models.py:137 #: photologue/models.py:143
msgid "Rotate 90 degrees clockwise" msgid "Rotate 90 degrees clockwise"
msgstr "" msgstr ""
#: models.py:138 #: photologue/models.py:144
msgid "Rotate 180 degrees" msgid "Rotate 180 degrees"
msgstr "" msgstr ""
#: models.py:142 #: photologue/models.py:148
msgid "Tile" msgid "Tile"
msgstr "" msgstr ""
#: models.py:143 #: photologue/models.py:149
msgid "Scale" msgid "Scale"
msgstr "" msgstr ""
#: models.py:154 #: photologue/models.py:160
#, python-format #, python-format
msgid "" msgid ""
"Chain multiple filters using the following pattern \"FILTER_ONE->FILTER_TWO-" "Chain multiple filters using the following pattern \"FILTER_ONE->FILTER_TWO-"
@ -189,408 +109,505 @@ msgid ""
"filters are available: %s." "filters are available: %s."
msgstr "" msgstr ""
#: models.py:159 #: photologue/models.py:174 photologue/models.py:301 photologue/models.py:696
msgid "date published" msgid "title"
msgstr "" msgstr ""
#: models.py:161 models.py:250 models.py:646 #: photologue/models.py:175 photologue/models.py:316 photologue/models.py:815
msgid "title" msgid "description"
msgstr "" msgstr ""
#: models.py:164 #: photologue/models.py:177
msgid "title slug" msgid "date published"
msgstr "" msgstr ""
#: models.py:166 models.py:651 #: photologue/models.py:180
msgid "A \"slug\" is a unique URL-friendly title for an object." msgid "title slug"
msgstr "" msgstr ""
#: models.py:167 models.py:263 models.py:730 #: photologue/models.py:182 photologue/models.py:704
msgid "description" msgid "A \"slug\" is a unique URL-friendly title for an object."
msgstr "" msgstr ""
#: models.py:169 models.py:266 models.py:656 #: photologue/models.py:185 photologue/models.py:319 photologue/models.py:709
msgid "is public" msgid "is public"
msgstr "" msgstr ""
#: models.py:171 #: photologue/models.py:187
msgid "Public galleries will be displayed in the default views." msgid "Public galleries will be displayed in the default views."
msgstr "" msgstr ""
#: models.py:175 models.py:669 #: photologue/models.py:191 photologue/models.py:724
msgid "photos" msgid "photos"
msgstr "" msgstr ""
#: models.py:178 models.py:273 models.py:659 #: photologue/models.py:197 photologue/models.py:326 photologue/models.py:712
msgid "tags" msgid "tags"
msgstr "" msgstr ""
#: models.py:179 models.py:660 #: photologue/models.py:198 photologue/models.py:713
msgid "sites" msgid "sites"
msgstr "" msgstr ""
#: models.py:187 models.py:255 #: photologue/models.py:206 photologue/models.py:308
msgid "gallery" msgid "gallery"
msgstr "" msgstr ""
#: models.py:188 #: photologue/models.py:207
msgid "galleries" msgid "galleries"
msgstr "" msgstr ""
#: models.py:225 #: photologue/models.py:276
msgid "count" msgid "count"
msgstr "" msgstr ""
#: models.py:247 #: photologue/models.py:298
msgid "images file (.zip)" msgid "images file (.zip)"
msgstr "" msgstr ""
#: models.py:249 #: photologue/models.py:300
msgid "Select a .zip file of images to upload into a new Gallery." msgid "Select a .zip file of images to upload into a new Gallery."
msgstr "" msgstr ""
#: models.py:252 #: photologue/models.py:305
msgid "" msgid ""
"All uploaded photos will be given a title made up of this title + a " "All uploaded photos will be given a title made up of this title + a "
"sequential number." "sequential number."
msgstr "" msgstr ""
#: models.py:258 #: photologue/models.py:311
msgid "" msgid ""
"Select a gallery to add these images to. Leave this empty to create a new " "Select a gallery to add these images to. Leave this empty to create a new "
"gallery from the supplied title." "gallery from the supplied title."
msgstr "" msgstr ""
#: models.py:260 models.py:652 #: photologue/models.py:313 photologue/models.py:698
msgid "caption" msgid "caption"
msgstr "" msgstr ""
#: models.py:262 #: photologue/models.py:315
msgid "Caption will be added to all photos." msgid "Caption will be added to all photos."
msgstr "" msgstr ""
#: models.py:265 #: photologue/models.py:318
msgid "A description of this Gallery." msgid "A description of this Gallery."
msgstr "" msgstr ""
#: models.py:268 #: photologue/models.py:321
msgid "" msgid ""
"Uncheck this to make the uploaded gallery and included photographs private." "Uncheck this to make the uploaded gallery and included photographs private."
msgstr "" msgstr ""
#: models.py:276 #: photologue/models.py:329
msgid "gallery upload" msgid "gallery upload"
msgstr "" msgstr ""
#: models.py:277 #: photologue/models.py:330
msgid "gallery uploads" msgid "gallery uploads"
msgstr "" msgstr ""
#: models.py:289 #: photologue/models.py:342
msgid "A gallery with that title already exists." msgid "A gallery with that title already exists."
msgstr "" msgstr ""
#: models.py:293 #: photologue/models.py:346
msgid "Select an existing gallery or enter a new gallery name." msgid "Select an existing gallery or enter a new gallery name."
msgstr "" msgstr ""
#: models.py:329 #: photologue/models.py:382
#, python-brace-format
msgid "" msgid ""
"Ignoring file \"{filename}\" as it is in a subfolder; all images should be " "Ignoring file \"{filename}\" as it is in a subfolder; all images should be "
"in the top folder of the zip." "in the top folder of the zip."
msgstr "" msgstr ""
#: models.py:349 #: photologue/models.py:402
#, python-format #, python-format, python-brace-format
msgid "" msgid ""
"Did not create photo \"%(filename)s\" with slug \"{1}\" as a photo with that " "Did not create photo \"%(filename)s\" with slug \"{1}\" as a photo with that "
"slug already exists." "slug already exists."
msgstr "" msgstr ""
#: models.py:375 #: photologue/models.py:428
#, python-brace-format
msgid "Could not process file \"{0}\" in the .zip archive." msgid "Could not process file \"{0}\" in the .zip archive."
msgstr "" msgstr ""
#: models.py:392 models.py:863 #: photologue/models.py:445 photologue/models.py:949
msgid "image" msgid "image"
msgstr "" msgstr ""
#: models.py:395 #: photologue/models.py:448
msgid "date taken" msgid "date taken"
msgstr "" msgstr ""
#: models.py:399 #: photologue/models.py:452
msgid "view count" msgid "view count"
msgstr "" msgstr ""
#: models.py:402 #: photologue/models.py:455
msgid "crop from" msgid "crop from"
msgstr "" msgstr ""
#: models.py:411 #: photologue/models.py:464
msgid "effect" msgid "effect"
msgstr "" msgstr ""
#: models.py:429 #: photologue/models.py:488
msgid "An \"admin_thumbnail\" photo size has not been defined." msgid "An \"admin_thumbnail\" photo size has not been defined."
msgstr "" msgstr ""
#: models.py:437 #: photologue/models.py:496
msgid "Thumbnail" msgid "Thumbnail"
msgstr "" msgstr ""
#: models.py:649 #: photologue/models.py:702
msgid "slug" msgid "slug"
msgstr "" msgstr ""
#: models.py:654 #: photologue/models.py:707
msgid "date added" msgid "date added"
msgstr "" msgstr ""
#: models.py:658 #: photologue/models.py:711
msgid "Public photographs will be displayed in the default views." msgid "Public photographs will be displayed in the default views."
msgstr "" msgstr ""
#: models.py:668 #: photologue/models.py:723
msgid "photo" msgid "photo"
msgstr "" msgstr ""
#: models.py:727 models.py:889 #: photologue/models.py:812 photologue/models.py:981
msgid "name" msgid "name"
msgstr "" msgstr ""
#: models.py:801 #: photologue/models.py:887
msgid "rotate or flip" msgid "rotate or flip"
msgstr "" msgstr ""
#: models.py:805 models.py:827 #: photologue/models.py:891 photologue/models.py:913
msgid "color" msgid "color"
msgstr "" msgstr ""
#: models.py:807 #: photologue/models.py:893
msgid "" msgid ""
"A factor of 0.0 gives a black and white image, a factor of 1.0 gives the " "A factor of 0.0 gives a black and white image, a factor of 1.0 gives the "
"original image." "original image."
msgstr "" msgstr ""
#: models.py:808 #: photologue/models.py:894
msgid "brightness" msgid "brightness"
msgstr "" msgstr ""
#: models.py:810 #: photologue/models.py:896
msgid "" msgid ""
"A factor of 0.0 gives a black image, a factor of 1.0 gives the original " "A factor of 0.0 gives a black image, a factor of 1.0 gives the original "
"image." "image."
msgstr "" msgstr ""
#: models.py:811 #: photologue/models.py:897
msgid "contrast" msgid "contrast"
msgstr "" msgstr ""
#: models.py:813 #: photologue/models.py:899
msgid "" msgid ""
"A factor of 0.0 gives a solid grey image, a factor of 1.0 gives the original " "A factor of 0.0 gives a solid grey image, a factor of 1.0 gives the original "
"image." "image."
msgstr "" msgstr ""
#: models.py:814 #: photologue/models.py:900
msgid "sharpness" msgid "sharpness"
msgstr "" msgstr ""
#: models.py:816 #: photologue/models.py:902
msgid "" msgid ""
"A factor of 0.0 gives a blurred image, a factor of 1.0 gives the original " "A factor of 0.0 gives a blurred image, a factor of 1.0 gives the original "
"image." "image."
msgstr "" msgstr ""
#: models.py:817 #: photologue/models.py:903
msgid "filters" msgid "filters"
msgstr "" msgstr ""
#: models.py:821 #: photologue/models.py:907
msgid "size" msgid "size"
msgstr "" msgstr ""
#: models.py:823 #: photologue/models.py:909
msgid "" msgid ""
"The height of the reflection as a percentage of the orignal image. A factor " "The height of the reflection as a percentage of the orignal image. A factor "
"of 0.0 adds no reflection, a factor of 1.0 adds a reflection equal to the " "of 0.0 adds no reflection, a factor of 1.0 adds a reflection equal to the "
"height of the orignal image." "height of the orignal image."
msgstr "" msgstr ""
#: models.py:824 #: photologue/models.py:910
msgid "strength" msgid "strength"
msgstr "" msgstr ""
#: models.py:826 #: photologue/models.py:912
msgid "The initial opacity of the reflection gradient." msgid "The initial opacity of the reflection gradient."
msgstr "" msgstr ""
#: models.py:830 #: photologue/models.py:916
msgid "" msgid ""
"The background color of the reflection gradient. Set this to match the " "The background color of the reflection gradient. Set this to match the "
"background color of your page." "background color of your page."
msgstr "" msgstr ""
#: models.py:833 models.py:924 #: photologue/models.py:919 photologue/models.py:1016
msgid "photo effect" msgid "photo effect"
msgstr "" msgstr ""
#: models.py:834 #: photologue/models.py:920
msgid "photo effects" msgid "photo effects"
msgstr "" msgstr ""
#: models.py:865 #: photologue/models.py:951
msgid "style" msgid "style"
msgstr "" msgstr ""
#: models.py:869 #: photologue/models.py:955
msgid "opacity" msgid "opacity"
msgstr "" msgstr ""
#: models.py:871 #: photologue/models.py:957
msgid "The opacity of the overlay." msgid "The opacity of the overlay."
msgstr "" msgstr ""
#: models.py:874 #: photologue/models.py:960
msgid "watermark" msgid "watermark"
msgstr "" msgstr ""
#: models.py:875 #: photologue/models.py:961
msgid "watermarks" msgid "watermarks"
msgstr "" msgstr ""
#: models.py:893 #: photologue/models.py:985
msgid "" msgid ""
"Photo size name should contain only letters, numbers and underscores. " "Photo size name should contain only letters, numbers and underscores. "
"Examples: \"thumbnail\", \"display\", \"small\", \"main_page_widget\"." "Examples: \"thumbnail\", \"display\", \"small\", \"main_page_widget\"."
msgstr "" msgstr ""
#: models.py:898 #: photologue/models.py:990
msgid "width" msgid "width"
msgstr "" msgstr ""
#: models.py:900 #: photologue/models.py:992
msgid "" msgid ""
"If width is set to \"0\" the image will be scaled to the supplied height." "If width is set to \"0\" the image will be scaled to the supplied height."
msgstr "" msgstr ""
#: models.py:901 #: photologue/models.py:993
msgid "height" msgid "height"
msgstr "" msgstr ""
#: models.py:903 #: photologue/models.py:995
msgid "" msgid ""
"If height is set to \"0\" the image will be scaled to the supplied width" "If height is set to \"0\" the image will be scaled to the supplied width"
msgstr "" msgstr ""
#: models.py:904 #: photologue/models.py:996
msgid "quality" msgid "quality"
msgstr "" msgstr ""
#: models.py:907 #: photologue/models.py:999
msgid "JPEG image quality." msgid "JPEG image quality."
msgstr "" msgstr ""
#: models.py:908 #: photologue/models.py:1000
msgid "upscale images?" msgid "upscale images?"
msgstr "" msgstr ""
#: models.py:910 #: photologue/models.py:1002
msgid "" msgid ""
"If selected the image will be scaled up if necessary to fit the supplied " "If selected the image will be scaled up if necessary to fit the supplied "
"dimensions. Cropped sizes will be upscaled regardless of this setting." "dimensions. Cropped sizes will be upscaled regardless of this setting."
msgstr "" msgstr ""
#: models.py:911 #: photologue/models.py:1003
msgid "crop to fit?" msgid "crop to fit?"
msgstr "" msgstr ""
#: models.py:913 #: photologue/models.py:1005
msgid "" msgid ""
"If selected the image will be scaled and cropped to fit the supplied " "If selected the image will be scaled and cropped to fit the supplied "
"dimensions." "dimensions."
msgstr "" msgstr ""
#: models.py:914 #: photologue/models.py:1006
msgid "pre-cache?" msgid "pre-cache?"
msgstr "" msgstr ""
#: models.py:916 #: photologue/models.py:1008
msgid "If selected this photo size will be pre-cached as photos are added." msgid "If selected this photo size will be pre-cached as photos are added."
msgstr "" msgstr ""
#: models.py:917 #: photologue/models.py:1009
msgid "increment view count?" msgid "increment view count?"
msgstr "" msgstr ""
#: models.py:919 #: photologue/models.py:1011
msgid "" msgid ""
"If selected the image's \"view_count\" will be incremented when this photo " "If selected the image's \"view_count\" will be incremented when this photo "
"size is displayed." "size is displayed."
msgstr "" msgstr ""
#: models.py:929 #: photologue/models.py:1021
msgid "watermark image" msgid "watermark image"
msgstr "" msgstr ""
#: models.py:933 #: photologue/models.py:1025
msgid "photo size" msgid "photo size"
msgstr "" msgstr ""
#: models.py:934 #: photologue/models.py:1026
msgid "photo sizes" msgid "photo sizes"
msgstr "" msgstr ""
#: models.py:951 #: photologue/models.py:1043
msgid "Can only crop photos if both width and height dimensions are set." msgid "Can only crop photos if both width and height dimensions are set."
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/gallery_archive.html:5 #: photologue/templates/photologue/gallery_archive.html:4
#: contrib/bootstrap/templates/photologue/gallery_archive.html:11 #: photologue/templates/photologue/gallery_archive.html:9
msgid "Latest Photo Galleries" msgid "Latest Photo Galleries"
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/gallery_archive.html:20 #: photologue/templates/photologue/gallery_archive.html:14
#: contrib/bootstrap/templates/photologue/gallery_detail.html:12 #: photologue/templates/photologue/photo_archive.html:16
#: contrib/bootstrap/templates/photologue/gallery_list.html:20 msgid "Filter by year"
#: contrib/bootstrap/templates/photologue/photo_detail.html:13
msgid "Published"
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/gallery_archive.html:31 #: photologue/templates/photologue/gallery_archive.html:30
#: contrib/bootstrap/templates/photologue/gallery_list.html:31 #: photologue/templates/photologue/gallery_list.html:30
msgid "No galleries were found" msgid "No galleries were found"
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/gallery_archive.html:36 #: photologue/templates/photologue/gallery_archive_day.html:4
#: contrib/bootstrap/templates/photologue/gallery_detail.html:21 #: photologue/templates/photologue/gallery_archive_day.html:8
#, python-format
msgid "Galleries for %(show_day)s"
msgstr ""
#: photologue/templates/photologue/gallery_archive_day.html:15
#: photologue/templates/photologue/gallery_archive_month.html:30
#: photologue/templates/photologue/gallery_archive_year.html:30
msgid "No galleries were found."
msgstr ""
#: photologue/templates/photologue/gallery_archive_day.html:19
msgid "View all galleries for month"
msgstr ""
#: photologue/templates/photologue/gallery_archive_month.html:4
#: photologue/templates/photologue/gallery_archive_month.html:9
#, python-format
msgid "Galleries for %(show_month)s"
msgstr ""
#: photologue/templates/photologue/gallery_archive_month.html:14
#: photologue/templates/photologue/photo_archive_month.html:14
msgid "Filter by day"
msgstr ""
#: photologue/templates/photologue/gallery_archive_month.html:34
msgid "View all galleries for year"
msgstr ""
#: photologue/templates/photologue/gallery_archive_year.html:4
#: photologue/templates/photologue/gallery_archive_year.html:9
#, python-format
msgid "Galleries for %(show_year)s"
msgstr ""
#: photologue/templates/photologue/gallery_archive_year.html:14
#: photologue/templates/photologue/photo_archive_year.html:15
msgid "Filter by month"
msgstr ""
#: photologue/templates/photologue/gallery_archive_year.html:34
#: photologue/templates/photologue/gallery_detail.html:20
msgid "View all galleries" msgid "View all galleries"
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/gallery_list.html:5 #: photologue/templates/photologue/gallery_detail.html:11
#: contrib/bootstrap/templates/photologue/gallery_list.html:11 #: photologue/templates/photologue/gallery_list.html:19
#: photologue/templates/photologue/includes/gallery_sample.html:8
#: photologue/templates/photologue/photo_detail.html:13
msgid "Published"
msgstr ""
#: photologue/templates/photologue/gallery_list.html:4
#: photologue/templates/photologue/gallery_list.html:10
msgid "All Galleries" msgid "All Galleries"
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/gallery_list.html:37 #: photologue/templates/photologue/includes/paginator.html:5
#: contrib/bootstrap/templates/photologue/gallery_list.html:39 #: photologue/templates/photologue/includes/paginator.html:7
msgid "Previous" msgid "Previous"
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/gallery_list.html:42 #: photologue/templates/photologue/includes/paginator.html:10
#, python-format #, python-format
msgid "" msgid ""
"\n" "\n"
"\t\t\t\t page %(page_number)s of %(total_pages)s\n" "\t\t\t page %(page_number)s of %(total_pages)s\n"
"\t\t\t\t" "\t\t\t"
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/gallery_list.html:47 #: photologue/templates/photologue/includes/paginator.html:15
#: contrib/bootstrap/templates/photologue/gallery_list.html:49 #: photologue/templates/photologue/includes/paginator.html:17
msgid "Next" msgid "Next"
msgstr "" msgstr ""
#: contrib/bootstrap/templates/photologue/photo_detail.html:21 #: photologue/templates/photologue/photo_archive.html:4
#: photologue/templates/photologue/photo_archive.html:10
msgid "Latest Photos"
msgstr ""
#: photologue/templates/photologue/photo_archive.html:36
#: photologue/templates/photologue/photo_archive_day.html:19
#: photologue/templates/photologue/photo_archive_month.html:34
#: photologue/templates/photologue/photo_archive_year.html:35
#: photologue/templates/photologue/photo_list.html:23
msgid "No photos were found"
msgstr ""
#: photologue/templates/photologue/photo_archive_day.html:4
#: photologue/templates/photologue/photo_archive_day.html:8
#, python-format
msgid "Photos for %(show_day)s"
msgstr ""
#: photologue/templates/photologue/photo_archive_day.html:23
msgid "View all photos for month"
msgstr ""
#: photologue/templates/photologue/photo_archive_month.html:4
#: photologue/templates/photologue/photo_archive_month.html:9
#, python-format
msgid "Photos for %(show_month)s"
msgstr ""
#: photologue/templates/photologue/photo_archive_month.html:38
msgid "View all photos for year"
msgstr ""
#: photologue/templates/photologue/photo_archive_year.html:4
#: photologue/templates/photologue/photo_archive_year.html:10
#, python-format
msgid "Photos for %(show_year)s"
msgstr ""
#: photologue/templates/photologue/photo_archive_year.html:39
msgid "View all photos"
msgstr ""
#: photologue/templates/photologue/photo_detail.html:21
msgid "This photo is found in the following galleries" msgid "This photo is found in the following galleries"
msgstr "" msgstr ""
#: photologue/templates/photologue/photo_list.html:4
#: photologue/templates/photologue/photo_list.html:10
msgid "All Photos"
msgstr ""

@ -3,7 +3,7 @@ import warnings
from django.conf import settings from django.conf import settings
from django.views.generic.dates import ArchiveIndexView, DateDetailView, DayArchiveView, MonthArchiveView, YearArchiveView from django.views.generic.dates import ArchiveIndexView, DateDetailView, DayArchiveView, MonthArchiveView, YearArchiveView
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from django.views.generic.list import ListView from functions.custom_views import ListView
from .models import Photo, Gallery from .models import Photo, Gallery
# Number of galleries to display per page. # Number of galleries to display per page.

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.views.generic import ListView, DetailView, FormView from django.views.generic import DetailView, FormView
from functions.custom_views import ListView
from django.utils import translation from django.utils import translation
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.template import RequestContext from django.template import RequestContext

@ -3,7 +3,7 @@ from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.conf import settings from django.conf import settings
from django.views.generic import TemplateView from django.views.generic import TemplateView, DeleteView
from file.models import TmpFile, FileModel from file.models import TmpFile, FileModel
from file.forms import FileModelForm, FileForm from file.forms import FileModelForm, FileForm
from city.models import City from city.models import City
@ -13,6 +13,10 @@ from django.db.models.loading import get_model
class AdminIndex(TemplateView): class AdminIndex(TemplateView):
template_name = 'admin/base.html' template_name = 'admin/base.html'

@ -34,6 +34,7 @@ urlpatterns = required(
url(r'^settings/', include('settings.admin_urls')), url(r'^settings/', include('settings.admin_urls')),
url(r'^meta/', include('meta.admin_urls')), url(r'^meta/', include('meta.admin_urls')),
url(r'^import_xls/', include('import_xls.admin_urls')), url(r'^import_xls/', include('import_xls.admin_urls')),
url(r'^translator_catalog/', include('specialist_catalog.admin_urls')),
url(r'^language/add/', 'directories.admin.language_add'), url(r'^language/add/', 'directories.admin.language_add'),
url(r'^currency/add/', 'directories.admin.currency_add'), url(r'^currency/add/', 'directories.admin.currency_add'),

@ -242,7 +242,6 @@ SOCIAL_AUTH_INACTIVE_USER_URL = '/inactive-user/'
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True
from social.pipeline.social_auth import social_details
SOCIAL_AUTH_PIPELINE = ( SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details', 'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid', 'social.pipeline.social_auth.social_uid',
@ -354,6 +353,7 @@ INSTALLED_APPS = (
'password_reset', # reset password 'password_reset', # reset password
'social.apps.django_app.default', # social auth 'social.apps.django_app.default', # social auth
'core', 'core',
'specialist_catalog',
) )
@ -422,10 +422,14 @@ THUMBNAIL_DEBUG = DEBUG
CALLBACK_EMAIL = 'kotzilla@ukr.net' CALLBACK_EMAIL = 'kotzilla@ukr.net'
BOOKING_AID = '333667' BOOKING_AID = '333667'
try:
from functions.overrides import SeoPaginator as Paginator
except ImportError:
from django.core.paginator import Paginator
DEFAULT_PAGINATOR = Paginator
ADMIN_PAGINATION = 20 ADMIN_PAGINATION = 20
CLIENT_PAGINATION = 15 CLIENT_PAGINATION = 15
TEMPLATE_DEBUG = DEBUG TEMPLATE_DEBUG = DEBUG
NO_LOGO = '/static/client/img/no-logo.png' NO_LOGO = '/static/client/img/no-logo.png'
@ -449,6 +453,8 @@ CLIENT_DATE_FORMAT = ["%d.%m.%Y"]
# cache pages in random seconds. random in this range # cache pages in random seconds. random in this range
CACHE_RANGE = [60, 120] CACHE_RANGE = [60, 120]
DEFAULT_POPUP_COOKIE = 'expo_b_default_popup'
try: try:
from local import * from local import *
except ImportError, e: except ImportError, e:
@ -503,3 +509,5 @@ if DEBUG:
#} #}
""" """
# -- PAGINATION -- #

@ -29,6 +29,7 @@ sitemaps = {
handler404 = 'proj.views.error404' handler404 = 'proj.views.error404'
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^acquire_email/$', 'registration.backends.default.views.acquire_email', name = 'acquire_email'),
url(r'^rss/', include('core.urls')), url(r'^rss/', include('core.urls')),
#url(r'^__debug__/', include(debug_toolbar.urls)), #url(r'^__debug__/', include(debug_toolbar.urls)),
url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}), url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}),
@ -42,7 +43,8 @@ urlpatterns = patterns('',
url(r'^page/', include('core.simple_urls')), url(r'^page/', include('core.simple_urls')),
url(r'^theme/', include('theme.urls')), url(r'^theme/', include('theme.urls')),
url(r'^places/', include('place_exposition.urls')), url(r'^places/', include('place_exposition.urls')),
url(r'^translators/', include('translator.urls')), #url(r'^translators/', include('translator.urls')),
url(r'^translators/', include('specialist_catalog.urls')),
url(r'^expo-b/', include('expobanner.urls')), url(r'^expo-b/', include('expobanner.urls')),
url(r'^', include('accounts.urls')), url(r'^', include('accounts.urls')),
url(r'^', include('exposition.urls')), url(r'^', include('exposition.urls')),
@ -78,7 +80,6 @@ urlpatterns = patterns('',
# ajax urls # ajax urls
urlpatterns += patterns('', urlpatterns += patterns('',
url(r'^ajax/get_popover/$', 'settings.views.get_popover_info'),
url(r'^registration/reply/$', 'registration.backends.default.views.RegisterReply'), url(r'^registration/reply/$', 'registration.backends.default.views.RegisterReply'),
url(r'^register/', 'registration.backends.default.views.RegisterAjaxView'), url(r'^register/', 'registration.backends.default.views.RegisterAjaxView'),
url(r'^register-complete/', 'registration.backends.default.views.complete_registration'), url(r'^register-complete/', 'registration.backends.default.views.complete_registration'),

@ -77,8 +77,11 @@ class MainPageView(JitterCacheMixin, TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(MainPageView, self).get_context_data(**kwargs) context = super(MainPageView, self).get_context_data(**kwargs)
ev = Exposition.objects.expo_main()
events = Exposition.objects.language().select_related('country', 'city', 'place').filter(main_page__gte=1).order_by('-main_page') events = sorted(ev, key=lambda x: x.main.position)
# update main_page counter
for event in events:
event.main.link.log(self.request, 1)
exposition_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.exposition)[:6] exposition_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.exposition)[:6]
conference_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.conference)[:6] conference_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.conference)[:6]

@ -8,82 +8,107 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-10-12 14:09-0500\n" "POT-Creation-Date: 2015-09-08 13:44+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: admin.py:23 #: registration/admin.py:23
msgid "Activate users" msgid "Activate users"
msgstr "" msgstr ""
#: admin.py:43 #: registration/admin.py:43
msgid "Re-send activation emails" msgid "Re-send activation emails"
msgstr "" msgstr ""
#: forms.py:35 #: registration/backends/default/views.py:197
msgid "username" msgid "Пользователя с таким email не существует"
msgstr "" msgstr ""
#: forms.py:36 #: registration/backends/default/views.py:200
msgid "This value must contain only letters, numbers and underscores." msgid "Пользователя с таким email уже активирован"
msgstr "" msgstr ""
#: forms.py:39 #: registration/forms.py:44
msgid "Email address" msgid "First name"
msgstr "" msgstr ""
#: forms.py:41 #: registration/forms.py:45 registration/forms.py:50
msgid "Password" msgid "This value may contain only letters, numbers and @/./+/-/_ characters."
msgstr "" msgstr ""
#: forms.py:43 #: registration/forms.py:46
msgid "Password (again)" msgid "Имя"
msgstr ""
#: registration/forms.py:49
msgid "Last name"
msgstr ""
#: registration/forms.py:51
msgid "Фамилия"
msgstr ""
#: registration/forms.py:53
msgid "E-mail"
msgstr "" msgstr ""
#: forms.py:55 #: registration/forms.py:53
msgid "A user with that username already exists." msgid "Адрес электронной почты"
msgstr "" msgstr ""
#: forms.py:67 #: registration/forms.py:54
msgid "The two password fields didn't match." msgid "Придумайте пароль"
msgstr ""
#: registration/forms.py:55
msgid "Password"
msgstr ""
#: registration/forms.py:56
msgid "Повторите пароль"
msgstr ""
#: registration/forms.py:57
msgid "Password (again)"
msgstr "" msgstr ""
#: forms.py:78 #: registration/forms.py:83
msgid "I have read and agree to the Terms of Service" msgid "I have read and agree to the Terms of Service"
msgstr "" msgstr ""
#: forms.py:79 #: registration/forms.py:84
msgid "You must agree to the terms to register" msgid "You must agree to the terms to register"
msgstr "" msgstr ""
#: forms.py:95 #: registration/forms.py:100
msgid "" msgid ""
"This email address is already in use. Please supply a different email " "This email address is already in use. Please supply a different email "
"address." "address."
msgstr "" msgstr ""
#: forms.py:122 #: registration/forms.py:127
msgid "" msgid ""
"Registration using free email addresses is prohibited. Please supply a " "Registration using free email addresses is prohibited. Please supply a "
"different email address." "different email address."
msgstr "" msgstr ""
#: models.py:165 #: registration/models.py:184
msgid "user" msgid "user"
msgstr "" msgstr ""
#: models.py:166 #: registration/models.py:185
msgid "activation key" msgid "activation key"
msgstr "" msgstr ""
#: models.py:171 #: registration/models.py:190
msgid "registration profile" msgid "registration profile"
msgstr "" msgstr ""
#: models.py:172 #: registration/models.py:191
msgid "registration profiles" msgid "registration profiles"
msgstr "" msgstr ""

@ -4,7 +4,7 @@ from views import ServiceView, CallBackListView, VisitListView, TranslationListV
ParticipationListView, RemoteListView,TicketsListView, Thanks ParticipationListView, RemoteListView,TicketsListView, Thanks
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'service/thanks/$', Thanks.as_view()), url(r'service/thanks/$', Thanks.as_view(), name = "service_thanks"),
url(r'service/com_rek/(?P<catalog>.*)/(?P<event_url>.*)/$', 'service.views.advertise'), url(r'service/com_rek/(?P<catalog>.*)/(?P<event_url>.*)/$', 'service.views.advertise'),
url(r'service/com_rek/$', 'service.views.advertise'), url(r'service/com_rek/$', 'service.views.advertise'),
url(r'service/(?P<url>.*)/$', ServiceView.as_view()), url(r'service/(?P<url>.*)/$', ServiceView.as_view()),

@ -46,7 +46,6 @@ class ServiceView(MetadataMixin, FormView):
def form_valid(self, form): def form_valid(self, form):
order = form.save(commit=False) order = form.save(commit=False)
order.save() order.save()
#messages.success(self.request, _(u'Ваш запрос был успешно отправлен'))
return HttpResponseRedirect(self.success_url) return HttpResponseRedirect(self.success_url)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

@ -160,23 +160,3 @@ def get_popover(request):
response['html'] = html response['html'] = html
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
from banners.models import Redirect
from django.db.models import F
import datetime
def set_cookie(response, key, value, days_expire = 7):
if days_expire is None:
max_age = 365 * 24 * 60 * 60 #one year
else:
max_age = days_expire * 24 * 60 * 60
expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age), "%a, %d-%b-%Y %H:%M:%S GMT")
response.set_cookie(key, value, max_age=max_age, expires=expires)
def get_popover_info(request):
id = request.GET.get('rdr')
if id:
Redirect.objects.filter(id=id).update(views = F('views') + 1)
response = HttpResponse('success')
set_cookie(response, 'popover_test1', '1')
return response

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from django.conf.urls import url, patterns
from .views import *
urlpatterns = patterns('',
url(r'^specialist/new/$', SpecialistCreateView.as_view(), name='specialist_new'),
url(r'^specialist/all/$', SpecialistListView.as_view(), name='specialist_all'),
url(r'^specialist/edit/(?P<pk>\d{1,6})/$', SpecialistUpdateView.as_view(), name='specialist_edit'),
url(r'^specialist/delete/(?P<pk>\d{1,6})/$', SpecialistDeleteView.as_view(), name='specialist_delete'),
url(r'^catalog/new/$', CatalogCreateView.as_view(), name='catalog_new'),
url(r'^catalog/all/$', CatalogListView.as_view(), name='catalog_all'),
url(r'^catalog/edit/(?P<pk>\d{1,6})/$', CatalogUpdateView.as_view(), name='catalog_edit'),
url(r'^catalog/delete/(?P<pk>\d{1,6})/$', CatalogDeleteView.as_view(), name='catalog_delete'),
url(r'^catalog/(?P<catalog_pk>\d{1,6})/add_feedback/$', FeedbackCreateView.as_view(), name='feedback_new'),
#url(r'^catalog/(?P<pk>\d{1,4})/feedbacks/$', FeedbackListView.as_view(), name='feedback_all'),
url(r'^catalog/(?P<catalog_pk>\d{1,6})/feedback/(?P<id>\d{1,4})/$', FeedbackUpdateView.as_view(), name='feedback_edit'),
url(r'^feedback/delete/(?P<pk>\d{1,6})/$', FeedbackDeleteView.as_view(), name='feedback_delete'),
)

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
from django import forms
from hvad.forms import TranslatableModelForm
from .models import Specialist, SpecialistCatalog, Feedback, City, Country
from ckeditor.widgets import CKEditorWidget
from django.utils.translation import get_language
country_choices = [(c.id, c.name) for c in Country.objects.all()]
lang_code = get_language()[:2]
default_text = u"Планируете посетить выставку в %s?" \
u" Мы предлагаем Вам подобрать переводчика именно под Ваши цели и потребности. " \
u"Специализируясь уже более 7 лет на предоставлении переводчиков на выставки и конференции " \
u"%s, мы можем предоставить профессионалов со знанием разных " \
u"языков на гибких для Вас условиях. Каждый заказ индивидуален для нас, " \
u"и итоговая цена зависит от вида перевода, тематики, срочности подбора " \
u"специалиста, города и объема работы."
default_title = u"Переводчики в %s"
class SpecialistCatalogForm(TranslatableModelForm):
class Meta:
model = SpecialistCatalog
fields = ['price', 'currency', 'logo', 'main_descr', 'place_photo',
'specialists', 'city', 'country', 'type', 'title', 'benefits', 'big_cities']
widgets = {
'type': forms.Select(choices=(('1', 'Country'), ('2', 'City'))),
'city': forms.HiddenInput(attrs={'id': 'id_city'}),
'country': forms.Select(choices=country_choices, attrs={'id': 'id_country'}),
'main_descr': CKEditorWidget,
'benefits': CKEditorWidget,
'big_cities': CKEditorWidget,
}
def save(self, commit=True):
place = self.cleaned_data.get('city') or self.cleaned_data.get('country')
place_inflect = place.inflect or place.name
if not self.cleaned_data['title']:
self.cleaned_data['title'] = default_title % place_inflect
if not self.cleaned_data['main_descr']:
self.cleaned_data['main_descr'] = default_text % (place_inflect, place_inflect)
return super(SpecialistCatalogForm, self).save(commit=True)
class SpecialistForm(forms.ModelForm):
class Meta:
model = Specialist
fields = ['name','country', 'city', 'photo', 'languages']
widgets = {
'city': forms.HiddenInput(attrs={'id': 'id_city'}),
'country': forms.Select(choices=country_choices, attrs={'id': 'id_country'})
}
class FeedbackForm(forms.ModelForm):
class Meta:
model = Feedback
fields = ['company', 'name', 'text', 'logo', 'catalog']
widgets = {
'text':CKEditorWidget
}

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

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand
from django.utils.translation import activate
from city.models import City
from specialist_catalog.models import SpecialistCatalog
default_text = u"Планируете посетить выставку %s?" \
u" Мы предлагаем Вам подобрать переводчика именно под Ваши цели и потребности. " \
u"Специализируясь уже более 7 лет на предоставлении переводчиков на выставки и конференции " \
u"%s, мы можем предоставить профессионалов со знанием разных " \
u"языков на гибких для Вас условиях. Каждый заказ индивидуален для нас, " \
u"и итоговая цена зависит от вида перевода, тематики, срочности подбора " \
u"специалиста, города и объема работы."
default_title = u"Переводчики %s"
default_benefits = """<ul class="content_list">
<li>Эффективная цена</li>
<li>Опыт и профессионализм специалистов</li>
<li>Знание разных менталитетов и психологических аспектов проведения переговоров с зарубежными бизнесменами</li>
<li>Ориентированность в мировых выставочных комплексах</li>
<li>Гарантии, отчетность по договору, прозрачные безналичные расчеты в России</li>
</ul>"""
class Command(BaseCommand):
def handle(self, *args, **options):
activate('ru')
cities = set(City.used.expo_cities())
for cty in cities:
name = cty.inflect or cty.name
sc = SpecialistCatalog(
type=2,
country=cty.country,
city=cty,
title=default_title % name,
main_descr=default_text % (name, name),
benefits = default_benefits
)
sc.save()
print cty.url, " -> ", cty.country.url

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand
from django.utils.translation import activate
from country.models import Country
from specialist_catalog.models import SpecialistCatalog
from django.utils.translation import activate
activate('ru')
default_text = u"Планируете посетить выставку %s?" \
u" Мы предлагаем Вам подобрать переводчика именно под Ваши цели и потребности. " \
u"Специализируясь уже более 7 лет на предоставлении переводчиков на выставки и конференции " \
u"%s, мы можем предоставить профессионалов со знанием разных " \
u"языков на гибких для Вас условиях. Каждый заказ индивидуален для нас, " \
u"и итоговая цена зависит от вида перевода, тематики, срочности подбора " \
u"специалиста, города и объема работы."
default_title = u"Переводчики %s"
default_benefits = """<ul class="content_list">
<li>Эффективная цена</li>
<li>Опыт и профессионализм специалистов</li>
<li>Знание разных менталитетов и психологических аспектов проведения переговоров с зарубежными бизнесменами</li>
<li>Ориентированность в мировых выставочных комплексах</li>
<li>Гарантии, отчетность по договору, прозрачные безналичные расчеты в России</li>
</ul>"""
class Command(BaseCommand):
def handle(self, *args, **options):
activate('ru')
countries = set(Country.objects.expo_countries())
for cntry in countries:
name = cntry.inflect or cntry.name
sc = SpecialistCatalog(
type='1',
country=cntry,
title=default_title % name,
main_descr=default_text % (name, name),
benefits = default_benefits
)
sc.save()
print "created for: %s" % cntry.url

@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.conf import settings
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from city.models import City
from country.models import Country
from django.core.urlresolvers import reverse_lazy
from django.utils.translation import get_language
import copy
# types of catalog
_country = 1
_city = 2
class Specialist(models.Model):
name = models.CharField(max_length=255, verbose_name=u"Полное имя", blank=False)
languages = models.CharField(max_length=255, verbose_name=u"Языки")
city = models.ForeignKey(City, on_delete=models.PROTECT, verbose_name=u"Город", blank=True)
country = models.ForeignKey(Country, on_delete=models.PROTECT, verbose_name=u"Страна")
photo = models.ImageField(verbose_name=u"Фото", upload_to="specialist_catalog/specialist_photo/", blank=True)
def __unicode__(self):
return u"%s" % self.name
class SpecialistCatalog(TranslatableModel):
price = models.IntegerField(verbose_name=u"Цена", default=200)
currency = models.CharField(max_length=255, verbose_name=u"Валюта", default=u"EUR")
logo = models.ImageField(db_column= "logo_preview", verbose_name=u"Логотип", blank=True, upload_to='specialist_catalog/logo_preview/')
place_photo = models.ImageField(verbose_name=u"Фото для города", blank=True, upload_to='specialist_catalog/place_photo/')
specialists = models.ManyToManyField(Specialist, verbose_name=u"Специалисты", blank=True)
city = models.ForeignKey(City, on_delete=models.PROTECT, verbose_name=u"Город", blank=True, null=True)
country = models.ForeignKey(Country, on_delete=models.PROTECT, verbose_name=u"Страна", blank=False)
type = models.PositiveSmallIntegerField(verbose_name=u"Тип(Страна/Город)", default=2)
objects = TranslationManager()
translations = TranslatedFields(
title=models.CharField(max_length=255, verbose_name=u"Заголовок"),
main_descr=models.CharField(max_length=1000, verbose_name=u"Краткое описание"),
benefits=models.CharField(max_length=2000, verbose_name=u"Преимущества"),
big_cities=models.TextField(verbose_name=u"Крупные города", blank=True)
)
def __init__(self, *args, **kwargs):
super(SpecialistCatalog, self).__init__(*args, **kwargs)
self.cache_fields = ['title', 'main_descr', 'benefits']
self.is_new = True
def get_absolute_url(self):
global _country, _city
if self.type == _country:
return reverse_lazy('spec_catalog_country', kwargs={'slug': self.country.url})
return reverse_lazy('spec_catalog_city', kwargs={'slug': self.city.url})
def save(self, *args, **kwargs):
super(SpecialistCatalog, self).save(*args, **kwargs)
self.initial_language = get_language()[:2] or 'ru'
new_values = {field: getattr(self, field) for field in self.cache_fields}
langs = [code for code, _ in settings.LANGUAGES]
if self.is_new:
for lang in langs:
if lang not in self.get_available_languages():
self.translate(lang)
for key, value in new_values.items():
setattr(self, key, value)
self.save_translations(self)
else:
translations = {obj.language_code: obj for obj in list(self.translations.all())}
for lang in langs:
if lang is not self.initial_language:
tr = translations[lang]
for key, value in new_values.items():
#if u'%s' % getattr(tr, key) is u'%s' % self.var_cache[key]:
setattr(tr, key, value)
tr.save()
self.lazy_translation_getter(self.initial_language)
self.var_cache = {var: copy.copy(getattr(self, var)) for var in self.cache_fields}
self.is_new = False
return self
def __unicode__(self):
return self.lazy_translation_getter('title', unicode(self.pk))
def place(self):
if self.type == _country:
return self.country
elif self.type == _city:
return self.city
else:
return None
class Feedback(models.Model):
company = models.CharField(max_length=255, verbose_name=u"Название компании")
name = models.CharField(max_length=100, verbose_name=u"Имя")
text = models.CharField(max_length=5000, verbose_name=u"Текст отзыва")
logo = models.ImageField(verbose_name=u"Логотип компании", upload_to='specialist_catalog/feedback_logo/', blank=True)
catalog = models.ForeignKey(SpecialistCatalog, verbose_name=u"Страница", blank=False)
def __unicode__(self):
return "Feedback from %s" % self.company

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

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
from django.conf.urls import url, patterns
from .views import CatalogDetailedView, SpecCatalog
urlpatterns = patterns('',
url(r'^city/$', SpecCatalog.as_view(), {'type': 'city'}, name="spec_city"),
url(r'^country/$', SpecCatalog.as_view(), {'type': 'country'}, name="spec_country"),
url(r'^city/(?P<slug>.*)/$', CatalogDetailedView.as_view(), {'type': 'city'}, name="spec_catalog_city"),
url(r'^country/(?P<slug>.*)/$', CatalogDetailedView.as_view(), {'type': 'country'}, name="spec_catalog_country"),
)

@ -0,0 +1,217 @@
# -*- coding: utf-8 -*-
from django.views.generic import CreateView, UpdateView, DeleteView, FormView, DetailView
from functions.custom_views import ListView
from django.views.generic.detail import SingleObjectMixin
from django.utils.translation import ugettext as _
from .forms import *
from django.core.urlresolvers import reverse_lazy
from django.conf import settings
from django.shortcuts import get_object_or_404
from service.order_forms import TranslationForm
from django.http import HttpResponseRedirect, Http404
from .models import _city, _country
# =========== ADMIN VIEWS ===========
# Specialist views
class SpecialistCreateView(CreateView):
form_class = SpecialistForm
model = Specialist
template_name = 'admin/specialist/specialist_new.html'
success_url = reverse_lazy("specialist_all")
from hvad.utils import get_translation_aware_manager
class SpecialistListView(ListView):
model = Specialist
template_name = 'admin/specialist/specialist_all.html'
paginate_by = settings.ADMIN_PAGINATION
def get_queryset(self):
name = self.request.GET.get('name', None)
city = self.request.GET.get('city', None)
qs = get_translation_aware_manager(Specialist).all()
if name:
qs = qs.filter(name__icontains=name)
if city:
qs = qs.filter(city__name__icontains=city)
return qs
class SpecialistUpdateView(UpdateView):
form_class = SpecialistForm
model = Specialist
template_name = 'admin/specialist/specialist_new.html'
success_url = reverse_lazy("specialist_all")
def get_form(self, form_class):
form = super(SpecialistUpdateView, self).get_form(form_class)
form.fields['city'].widget.attrs['data-init-text'] = self.object.city.name
return form
class SpecialistDeleteView(DeleteView):
model = Specialist
template_name = 'admin/specialist/specialist_confirm_delete.html'
success_url = reverse_lazy("specialist_all")
# Catalog views
class CatalogCreateView(CreateView):
form_class = SpecialistCatalogForm
model = SpecialistCatalog
template_name = 'admin/specialist/catalog_new.html'
success_url = reverse_lazy("catalog_all")
class CatalogListView(ListView):
model = SpecialistCatalog
template_name = 'admin/specialist/catalog_all.html'
paginate_by = settings.ADMIN_PAGINATION
paginator_class = settings.DEFAULT_PAGINATOR
def get_queryset(self):
_GET = self.request.GET
query, city, country, only_cntry = _GET.get('query'), _GET.get('city'), _GET.get('country'), _GET.get('only_countries')
qs = self.model.objects.language()
if only_cntry:
qs = qs.filter(type=1)
if query:
qs = qs.filter(title__icontains=query)
if city:
qs = qs.filter(city__translations__name__icontains=city)
if country:
qs = qs.filter(country__translations__name__icontains=country)
return qs
class CatalogUpdateView(UpdateView):
form_class = SpecialistCatalogForm
model = SpecialistCatalog
template_name = 'admin/specialist/catalog_new.html'
success_url = reverse_lazy("catalog_all")
def get_form(self, form_class):
form = super(CatalogUpdateView, self).get_form(form_class)
if self.object.type is 2: # city
form.fields['city'].widget.attrs['data-init-text'] = self.object.city.name
return form
class CatalogDeleteView(DeleteView):
model = SpecialistCatalog
template_name = 'admin/specialist/catalog_confirm_delete.html'
success_url = reverse_lazy("catalog_all")
# Feedback views
class FeedbackCreateView(CreateView):
form_class = FeedbackForm
model = Feedback
template_name = 'admin/specialist/feedback_new.html'
success_url = reverse_lazy("catalog_all")
def get_initial(self):
catalog = get_object_or_404(SpecialistCatalog, pk=self.kwargs.get('catalog_pk'))
return {'catalog': catalog}
class FeedbackUpdateView(UpdateView):
form_class = FeedbackForm
model = Feedback
template_name = 'admin/specialist/feedback_new.html'
success_url = reverse_lazy("catalog_all")
def get_initial(self):
catalog = get_object_or_404(SpecialistCatalog, pk=self.kwargs.get('catalog_pk'))
return {'catalog': catalog}
class FeedbackDeleteView(DeleteView):
model = Feedback
template_name = 'admin/specialist/feedback_confirm_delete.html'
success_url = reverse_lazy("catalog_all")
# ========= CLIENT VIEWS ============
class CatalogDetailedView(SingleObjectMixin, FormView):
model = SpecialistCatalog
form_class = TranslationForm
template_name = "client/specialist_catalog/catalog_detailed.html"
success_url = reverse_lazy("service_thanks")
def get_catalog_obj(self):
if self.kwargs.get('type') is "country":
try:
return self.model.objects.language().get(type=1, country__url=self.kwargs.get('slug'))
except self.model.DoesNotExist:
raise Http404
else:
try:
return self.model.objects.language().get(type=2, city__url=self.kwargs.get('slug'))
except self.model.DoesNotExist:
raise Http404
def get_object(self, queryset=None):
obj = self.get_catalog_obj()
self.object = obj
return obj
def get_context_data(self, **kwargs):
self.get_object()
context = super(CatalogDetailedView, self).get_context_data(**kwargs)
context['object'] = self.object
return context
def form_valid(self, form):
order = form.save(commit=False)
order.save()
return HttpResponseRedirect(self.success_url)
def get_initial(self):
obj = self.get_object()
init = {}
init['country'] = obj.country.name
if self.kwargs.get('type') is "city":
init['city'] = obj.city.name
return init
class SpecCatalog(ListView):
model = SpecialistCatalog
template_name = 'client/specialist_catalog/catalog.html'
def get_queryset(self):
if self.kwargs.get('type') == "country":
ctype = _country
else:
ctype = _city
qs = list(self.model.objects.language().select_related('country', 'city').filter(type=ctype))
if ctype == _country:
result = sorted(qs, key=lambda x: x.country.name)
else:
result = sorted(qs, key=lambda x: x.city.name)
return result
def get_context_data(self, **kwargs):
context = super(SpecCatalog, self).get_context_data(**kwargs)
if self.kwargs.get('type') == "country":
context['title'] = _(u'Переводчики по странам')
else:
context['title'] = _(u'Переводчики по городам')
return context

@ -1,4 +1,4 @@

/** /**
* @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.html or http://ckeditor.com/license * For licensing, see LICENSE.html or http://ckeditor.com/license

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */

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

Loading…
Cancel
Save