remotes/origin/1203
Nazar Kotjuk 10 years ago
commit 0ea3ce2282
  1. 3
      .gitignore
  2. 8
      accounts/admin.py
  3. 4
      accounts/admin_urls.py
  4. 28
      accounts/forms.py
  5. 3
      accounts/models.py
  6. 2
      company/views.py
  7. 20
      core/admin_urls.py
  8. 11
      core/forms.py
  9. 49
      core/models.py
  10. 22
      core/urls.py
  11. 87
      core/utils.py
  12. 60
      core/views.py
  13. 374
      django_messages/locale/en/LC_MESSAGES/django.po
  14. 41
      expobanner/admin.py
  15. 2
      expobanner/forms.py
  16. 156
      expobanner/managers.py
  17. 651
      expobanner/models.py
  18. 146
      expobanner/templates/slider.html
  19. 148
      expobanner/templatetags/banner.py
  20. 26
      expobanner/urls.py
  21. 198
      expobanner/views.py
  22. 8
      exposition/forms.py
  23. 5
      exposition/models.py
  24. 6
      functions/admin_views.py
  25. 2
      import_xls/excel_settings.py
  26. BIN
      locale/en/LC_MESSAGES/django.po
  27. 12
      meta/admin.py
  28. 11
      meta/admin_urls.py
  29. 17
      meta/forms.py
  30. 80
      meta/models.py
  31. 11
      meta/views.py
  32. 122
      password_reset/locale/en/LC_MESSAGES/django.po
  33. 439
      photologue/locale/en/LC_MESSAGES/django.po
  34. 1
      proj/admin_urls.py
  35. 30
      proj/decorators.py
  36. 2
      proj/settings.py
  37. 4
      proj/urls.py
  38. 75
      registration/locale/en/LC_MESSAGES/django.po
  39. 2
      service/urls.py
  40. 1
      service/views.py
  41. 0
      specialist_catalog/__init__.py
  42. 20
      specialist_catalog/admin_urls.py
  43. 65
      specialist_catalog/forms.py
  44. 1
      specialist_catalog/management/__init__.py
  45. 1
      specialist_catalog/management/commands/__init__.py
  46. 41
      specialist_catalog/management/commands/create_city_page.py
  47. 42
      specialist_catalog/management/commands/create_country_page.py
  48. 107
      specialist_catalog/models.py
  49. 16
      specialist_catalog/tests.py
  50. 11
      specialist_catalog/urls.py
  51. 225
      specialist_catalog/views.py
  52. 2
      static/ckeditor/ckeditor/build-config.js
  53. 2
      static/ckeditor/ckeditor/lang/en.js
  54. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js
  55. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ar.js
  56. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/bg.js
  57. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ca.js
  58. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/cs.js
  59. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/cy.js
  60. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/da.js
  61. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/de.js
  62. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/el.js
  63. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/en.js
  64. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/eo.js
  65. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/es.js
  66. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/et.js
  67. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/fa.js
  68. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/fi.js
  69. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/fr.js
  70. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/gu.js
  71. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/he.js
  72. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/hi.js
  73. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/hr.js
  74. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/hu.js
  75. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/it.js
  76. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ja.js
  77. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/km.js
  78. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ku.js
  79. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/lt.js
  80. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/lv.js
  81. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/mk.js
  82. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/mn.js
  83. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/nb.js
  84. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/nl.js
  85. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/no.js
  86. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/pl.js
  87. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/pt-br.js
  88. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/pt.js
  89. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ro.js
  90. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ru.js
  91. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/sk.js
  92. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/sl.js
  93. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/sv.js
  94. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/th.js
  95. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/tr.js
  96. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/ug.js
  97. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/uk.js
  98. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/vi.js
  99. 2
      static/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/zh-cn.js
  100. 2
      static/ckeditor/ckeditor/plugins/about/dialogs/about.js
  101. Some files were not shown because too many files have changed in this diff Show More

3
.gitignore vendored

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

@ -13,14 +13,20 @@ from django.utils.translation import ugettext as _
from models import User
from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnouncementForm, UserFilterForm
#custom views
from functions.admin_views import AdminView, AdminListView
from django.views.generic import UpdateView
from functions.admin_views import AdminView, AdminListView, paginate_results
class UserListView(AdminListView):
template_name = 'admin/accounts/user_list.html'
form_class = UserFilterForm
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):
model = User

@ -3,10 +3,6 @@ from django.conf.urls import patterns, url
from admin import UserListView, EditUser
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'^all/$', UserListView.as_view()),
url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'),

@ -83,9 +83,7 @@ class UserForm(forms.ModelForm):
company = forms.ChoiceField(label='Компания',
choices=[(item.id, item.name) for item in Company.objects.language().all()],
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)
descriptions = 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:
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_registered', 'date_modified')
'date_registered', 'date_modified', 'is_active')
def save(self, force_insert=False, force_update=False, commit=True):
@ -139,16 +137,16 @@ class UserForm(forms.ModelForm):
profile.save()
return user
def clean_url(self):
url = self.cleaned_data.get('url')
if url:
if User.objects.get(url=translit_with_separator(url)):
raise forms.ValidationError('Такой урл уже занят')
else:
return url
def clean_organiser(self):
return clean_relation_field(self, 'organiser', Organiser)
#def clean_url(self):
# url = self.cleaned_data.get('url')
# if url:
# if User.objects.get(url=translit_with_separator(url)):
# raise forms.ValidationError('Такой урл уже занят')
# else:
# return url
#def clean_organiser(self):
# return clean_relation_field(self, 'organiser', Organiser)
def clean_company(self):
return clean_relation_field(self, 'company', Company)

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

@ -21,7 +21,7 @@ from meta.views import MetadataMixin
class CompanySearchView(ListView):
paginate_by = 10
template_name = 'company/search.html'
template_name = 'client/company/search.html'
search_form = CompanySearchForm
model = Company

@ -1,10 +1,10 @@
from django.conf.urls import url, patterns
from views import NewPage, PageList, EditPage, DeletePage, PageDetailed
urlpatterns = patterns('',
url(r'^new/$', NewPage.as_view(), name='new_page' ),
url(r'^all/$', PageList.as_view(), name = 'page_list'),
url(r'^edit/(?P<url>.*)/$', EditPage.as_view(), name='edit_page'),
url(r'^delete/(?P<url>.*)/$', DeletePage.as_view(), name='delete_page'),
url(r'^(?P<url>.*)/$', PageDetailed.as_view(), name='page_view'),
)
from django.conf.urls import url, patterns
from views import NewPage, PageList, EditPage, DeletePage, PageDetailed
urlpatterns = patterns('',
url(r'^new/$', NewPage.as_view(), name='new_page' ),
url(r'^all/$', PageList.as_view(), name = 'page_list'),
url(r'^edit/(?P<url>.*)/$', EditPage.as_view(), name='edit_page'),
url(r'^delete/(?P<url>.*)/$', DeletePage.as_view(), name='delete_page'),
url(r'^(?P<url>.*)/$', PageDetailed.as_view(), name='page_view'),
)

@ -61,21 +61,12 @@ class PageForm(TranslatableModelForm):
class Meta:
model = Page
fields = ['url','title','h1','descriptions','keywords', 'body' ]
fields = ['url','title','h1','descriptions','keywords', 'body']
widgets = {
'body':CKEditorWidget,
'keywords':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 exposition.models import Exposition
from settings.models import create_transl_fields
import copy
from theme.models import Theme
from country.models import Country
from city.models import City
@ -114,24 +114,39 @@ class Page(TranslatableModel):
def get_absolute_url(self):
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):
super(Page,self).save(*args, **kwargs)
all_field_names = list(self._translated_field_names)
clear_f_n = []
for field_name in all_field_names:
if field_name not in ['master', 'master_id',u'id', 'language_code']:
clear_f_n.append(field_name)
field_items = {field_name:getattr(self, field_name) for field_name in clear_f_n}
langs = [lan[0] for lan in settings.LANGUAGES]
for lang in langs:
if lang not in self.get_available_languages():
self.translate(lang)
for field in clear_f_n:
setattr(self, field, field_items.get(field, ''))
obj = super(Page,self).save(*args, **kwargs)
return obj
self.initial_language = '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(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):
return self.url

@ -1,11 +1,11 @@
from django.conf.urls import url, patterns
from models import LatestExpositions, CountryFeeds, CityFeeds, ThemeFeeds
urlpatterns = patterns('',
url(r'^latest/$', LatestExpositions()),
url(r'^country/(?P<slug>.*)/$', CountryFeeds()),
url(r'^city/(?P<slug>.*)/$', CityFeeds()),
url(r'^theme/(?P<slug>.*)/$', ThemeFeeds()),
)
from django.conf.urls import url, patterns
from models import LatestExpositions, CountryFeeds, CityFeeds, ThemeFeeds
urlpatterns = patterns('',
url(r'^latest/$', LatestExpositions()),
url(r'^country/(?P<slug>.*)/$', CountryFeeds()),
url(r'^city/(?P<slug>.*)/$', CityFeeds()),
url(r'^theme/(?P<slug>.*)/$', ThemeFeeds()),
)

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
"""
http://www.simplistix.co.uk/presentations/python-excel.pdf
"""
import xlwt
import datetime
from exposition.models import Exposition
from conference.models import Conference
from django.core.exceptions import ObjectDoesNotExist
HEADER_STYLE = xlwt.easyxf('font: bold on')
@ -16,6 +16,7 @@ CELL_STYLE_MAP = (
(bool, xlwt.easyxf(num_format_str='BOOLEAN')),
)
def multi_getattr(obj, attr, default=None):
attributes = attr.split(".")
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 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()
report_date = datetime.date.today()
sheet_name = 'Export {0}'.format(report_date.strftime('%Y-%m-%d'))
report_date = report_date or datetime.date.today()
sheet_name = u'My calendar {0}'.format(report_date.strftime('%Y-%B'))
sheet = workbook.add_sheet(sheet_name)
if not header_style:
header_style = HEADER_STYLE
if not default_style:
default_style = DEFAULT_STYLE
if not cell_style_map:
cell_style_map = CELL_STYLE_MAP
obj = queryset[0]
for y, column in enumerate(columns):
header_list=[u'Название события',u'Страна',u'Город',u'Место проведения', u'Дата начала', u'Дата окончания']
sheet.write(0, y, header_list[y], header_style)
for x, obj in enumerate(queryset, start=1):
# drawing head part with image
sheet.write_merge(0, 6, 0, 6, u'Мой календарь собитий на %s года' % report_date.strftime("%B %Y"), main_style)
for i in range(7):
sheet.row(i).set_style(xlwt.Style.easyxf('font:height 300;'))
sheet.insert_bitmap('/home/www/proj/media/logo.bmp', row=0, col=5, x=0, y=0, scale_x=0.3, scale_y=2)
# drawing headers
header_list = [u'#', u'Название события',u'Даты',u'Краткое описание',u'Место проведения', u'Заметка', u'Ссылка на событие']
for i, column in enumerate(columns):
sheet.write(8, i, header_list[i], header_style)
sheet.col(i).width = 8000
sheet.col(0).width = 2000
# fill data
for x, obj in enumerate(queryset, start=9):
for y, column in enumerate(columns):
value = get_column_cell(obj, column)
style = default_style
for value_type, cell_style in cell_style_map:
if isinstance(value, value_type):
style = cell_style
try:
value = getattr(obj, column)
except:
value = "-"
if x % 2 == 0:
style = even_style
else:
style = odd_style
sheet.write(x, y, value, style)
return workbook

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

@ -0,0 +1,374 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-08 13:44+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: django_messages/admin.py:21
msgid "group"
msgstr ""
#: django_messages/admin.py:22
msgid "Creates the message optionally for all users or a group of users."
msgstr ""
#: django_messages/admin.py:30
msgid "All users"
msgstr ""
#: django_messages/admin.py:48 django_messages/models.py:94
msgid "Message"
msgstr ""
#: django_messages/admin.py:55
msgid "Date/time"
msgstr ""
#: django_messages/apps.py:6 django_messages/models.py:95
msgid "Messages"
msgstr ""
#: django_messages/fields.py:56
#, python-format
msgid "The following usernames are incorrect: %(users)s"
msgstr ""
#: django_messages/forms.py:17 django_messages/forms.py:66
#: django_messages/models.py:55
#: django_messages/templates/django_messages/inbox.html:10
#: django_messages/templates/django_messages/outbox.html:10
#: django_messages/templates/django_messages/trash.html:10
#: django_messages/templates/django_messages/view.html:8
msgid "Subject"
msgstr ""
#: django_messages/forms.py:18 django_messages/forms.py:46
#: django_messages/forms.py:67 django_messages/models.py:56
msgid "Body"
msgstr ""
#: django_messages/forms.py:65 django_messages/models.py:58
#: django_messages/templates/django_messages/outbox.html:10
#: django_messages/templates/django_messages/view.html:14
msgid "Recipient"
msgstr ""
#: django_messages/management.py:9
msgid "Message Received"
msgstr ""
#: django_messages/management.py:9
msgid "you have received a message"
msgstr ""
#: django_messages/management.py:10
msgid "Message Sent"
msgstr ""
#: django_messages/management.py:10
msgid "you have sent a message"
msgstr ""
#: django_messages/management.py:11
msgid "Message Replied"
msgstr ""
#: django_messages/management.py:11
msgid "you have replied to a message"
msgstr ""
#: django_messages/management.py:12
msgid "Reply Received"
msgstr ""
#: django_messages/management.py:12
msgid "you have received a reply to a message"
msgstr ""
#: django_messages/management.py:13
msgid "Message Deleted"
msgstr ""
#: django_messages/management.py:13
msgid "you have deleted a message"
msgstr ""
#: django_messages/management.py:14
msgid "Message Recovered"
msgstr ""
#: django_messages/management.py:14
msgid "you have undeleted a message"
msgstr ""
#: django_messages/models.py:57
#: django_messages/templates/django_messages/inbox.html:10
#: django_messages/templates/django_messages/trash.html:10
#: django_messages/templates/django_messages/view.html:10
msgid "Sender"
msgstr ""
#: django_messages/models.py:59
msgid "Parent message"
msgstr ""
#: django_messages/models.py:60
msgid "sent at"
msgstr ""
#: django_messages/models.py:61
msgid "read at"
msgstr ""
#: django_messages/models.py:62
msgid "replied at"
msgstr ""
#: django_messages/models.py:63
msgid "Sender deleted at"
msgstr ""
#: django_messages/models.py:64
msgid "Recipient deleted at"
msgstr ""
#: django_messages/templates/django_messages/base.html:9
#: django_messages/templates/django_messages/inbox.html:6
#: django_messages/templates/django_messages/new_message.html:13
msgid "Inbox"
msgstr ""
#: django_messages/templates/django_messages/base.html:10
#: django_messages/templates/django_messages/outbox.html:6
msgid "Sent Messages"
msgstr ""
#: django_messages/templates/django_messages/base.html:11
msgid "New Message"
msgstr ""
#: django_messages/templates/django_messages/base.html:12
msgid "Trash"
msgstr ""
#: django_messages/templates/django_messages/compose.html:4
msgid "Compose Message"
msgstr ""
#: django_messages/templates/django_messages/compose.html:10
msgid "Send"
msgstr ""
#: django_messages/templates/django_messages/inbox.html:10
msgid "Received"
msgstr ""
#: django_messages/templates/django_messages/inbox.html:10
#: django_messages/templates/django_messages/outbox.html:10
#: django_messages/templates/django_messages/trash.html:10
msgid "Action"
msgstr ""
#: django_messages/templates/django_messages/inbox.html:22
#: django_messages/templates/django_messages/outbox.html:19
#: django_messages/templates/django_messages/trash.html:19
#: django_messages/templates/django_messages/view.html:13
msgid "DATETIME_FORMAT"
msgstr ""
#: django_messages/templates/django_messages/inbox.html:23
#: django_messages/templates/django_messages/outbox.html:20
msgid "delete"
msgstr ""
#: django_messages/templates/django_messages/inbox.html:29
#: django_messages/templates/django_messages/outbox.html:26
#: django_messages/templates/django_messages/trash.html:26
msgid "No messages."
msgstr ""
#: django_messages/templates/django_messages/new_message.html:4
#, python-format
msgid ""
"Hello %(recipient)s,\n"
"\n"
"you received a private message from %(sender)s with\n"
"the following contents:"
msgstr ""
#: django_messages/templates/django_messages/new_message.html:12
#, python-format
msgid "Sent from %(site_url)s"
msgstr ""
#: django_messages/templates/django_messages/new_message.html:14
#: django_messages/templates/django_messages/view.html:20
msgid "Reply"
msgstr ""
#: django_messages/templates/django_messages/outbox.html:10
msgid "Sent"
msgstr ""
#: django_messages/templates/django_messages/trash.html:6
msgid "Deleted Messages"
msgstr ""
#: django_messages/templates/django_messages/trash.html:10
#: django_messages/templates/django_messages/view.html:12
msgid "Date"
msgstr ""
#: django_messages/templates/django_messages/trash.html:20
msgid "undelete"
msgstr ""
#: django_messages/templates/django_messages/trash.html:29
msgid ""
"Deleted Messages are removed from the trash at unregular intervals, don't "
"rely on this feature for long-time storage."
msgstr ""
#: django_messages/templates/django_messages/view.html:6
msgid "View Message"
msgstr ""
#: django_messages/templates/django_messages/view.html:22
msgid "Delete"
msgstr ""
#: django_messages/templates/notification/messages_deleted/full.txt:1
#, python-format
msgid "You have deleted the message '%(message)s'."
msgstr ""
#: django_messages/templates/notification/messages_deleted/notice.html:1
#, python-format
msgid ""
"You have deleted the message <a href=\"%(message_url)s\">%(message)s</a>."
msgstr ""
#: django_messages/templates/notification/messages_received/full.txt:1
#, python-format
msgid ""
"%(message_sender)s has sent you a message:\n"
"\n"
"%(message)s\n"
"\n"
"%(message_body)s\n"
"\n"
"http://%(current_site)s%(message_url)s"
msgstr ""
#: django_messages/templates/notification/messages_received/notice.html:2
#, python-format
msgid ""
"You have received the message <a href=\"%(message_url)s\">%(message)s</a> "
"from %(message_sender)s."
msgstr ""
#: django_messages/templates/notification/messages_received/short.txt:1
#: django_messages/templates/notification/messages_reply_received/short.txt:1
#, python-format
msgid "%(notice)s by %(message_sender)s"
msgstr ""
#: django_messages/templates/notification/messages_recovered/full.txt:1
#, python-format
msgid "You have recovered the message '%(message)s'."
msgstr ""
#: django_messages/templates/notification/messages_recovered/notice.html:1
#, python-format
msgid ""
"You have recovered the message <a href=\"%(message_url)s\">%(message)s</a>."
msgstr ""
#: django_messages/templates/notification/messages_replied/full.txt:1
#, python-format
msgid ""
"You have replied to '%(message_parent_msg)s' from %(message_recipient)s."
msgstr ""
#: django_messages/templates/notification/messages_replied/notice.html:2
#, python-format
msgid ""
"You have replied to <a href=\"%(message_url)s\">%(message_parent_msg)s</a> "
"from %(message_recipient)s."
msgstr ""
#: django_messages/templates/notification/messages_reply_received/full.txt:1
#, python-format
msgid ""
"%(message_sender)s replied to '%(message_parent_msg)s':\n"
"\n"
"%(message)s\n"
"\n"
"%(message_body)s\n"
"\n"
"http://%(current_site)s%(message_url)s"
msgstr ""
#: django_messages/templates/notification/messages_reply_received/notice.html:2
#, python-format
msgid "%(message_sender)s has sent you a reply to %(message_parent_msg)s."
msgstr ""
#: django_messages/templates/notification/messages_sent/full.txt:1
#, python-format
msgid "You have sent the message '%(message)s' to %(message_recipient)s."
msgstr ""
#: django_messages/templates/notification/messages_sent/notice.html:2
#, python-format
msgid ""
"You have sent the message <a href=\"%(message_url)s\">%(message)s</a> to "
"%(message_recipient)s."
msgstr ""
#: django_messages/utils.py:26
#, python-format
msgid ""
"%(sender)s wrote:\n"
"%(body)s"
msgstr ""
#: django_messages/utils.py:54
#, python-format
msgid "Re%(prefix)s: %(subject)s"
msgstr ""
#: django_messages/utils.py:60
#, python-format
msgid "New Message: %(subject)s"
msgstr ""
#: django_messages/views.py:78 django_messages/views.py:114
msgid "Message successfully sent."
msgstr ""
#: django_messages/views.py:121
#, python-format
msgid "Re: %(subject)s"
msgstr ""
#: django_messages/views.py:157
msgid "Message successfully deleted."
msgstr ""
#: django_messages/views.py:184
msgid "Message successfully recovered."
msgstr ""

@ -3,6 +3,7 @@ from django.views.generic import TemplateView, CreateView, ListView, UpdateView,
from django.conf import settings
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.db.models import Sum
from expobanner.models import URL, BannerGroup, Banner, Paid, MainPage, Top
from expobanner.forms import UrlCreateForm, BannerCreateGroupForm, BannerCreateForm, BannerGroupUpdateForm,\
PaidCreateForm, PaidUpdateForm, TopCreateForm, BannerLinkCreateForm, MainCreateForm, MainUpdateForm, TopUpdateForm
@ -32,6 +33,7 @@ class CreateBanner(AbstractCreate):
model = Banner
form_class = BannerCreateForm
class CreateLink(AbstractCreate):
model = Banner
form_class = BannerLinkCreateForm
@ -67,6 +69,7 @@ class BannerList(AbstractList):
qs = qs.filter(group__isnull=False)
return qs
class LinkList(AbstractList):
model = Banner
verbose = u'Список ссылок'
@ -114,7 +117,10 @@ class PaidList(ListView):
paginate_by = settings.ADMIN_PAGINATION
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):
@ -162,6 +168,18 @@ class PaidStat(DetailView):
model = Paid
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')
)
return context
# ----------------------------------
class MainList(ListView):
model = Exposition
@ -169,7 +187,10 @@ class MainList(ListView):
paginate_by = settings.ADMIN_PAGINATION
def get_queryset(self):
return self.model.objects.language().filter(main__isnull=False)
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):
@ -202,6 +223,7 @@ def main_turn(request, pk, status):
return HttpResponseRedirect('/admin/expobanners/main/list/')
class MainStat(DetailView):
model = MainPage
template_name = 'admin/expobanner/main_stat.html'
@ -210,10 +232,16 @@ class MainStat(DetailView):
context = super(MainStat, self).get_context_data(**kwargs)
obj = self.object
context['stats'] = obj.link.banner_stat.all()
context['all'] = obj.link.banner_stat.aggregate(
views=Sum('view'),
clicks=Sum('click'),
unique_clicks=Sum('unique_click'),
unique_views=Sum('unique_view')
)
return context
# ------------------------------------
from datetime import date
class TopList(ListView):
model = Exposition
@ -221,7 +249,10 @@ class TopList(ListView):
paginate_by = settings.ADMIN_PAGINATION
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):
@ -241,4 +272,4 @@ class TopUpdate(UpdateView):
context = super(TopUpdate, self).get_context_data(**kwargs)
obj = self.object
context['exposition'] = obj.get_event()
return context
return context

@ -267,4 +267,4 @@ class TopUpdateForm(forms.ModelForm):
top.save()
self.save_m2m()
return top
return top

@ -1,79 +1,79 @@
# -*- coding: utf-8 -*
from datetime import date
from random import choice, shuffle
from django.db import models
from django.db.models import Q
from django.core.cache import cache
class BiasedManager(models.Manager):
def by_time(self, **kwargs):
all = super(BiasedManager, self).get_query_set().filter(**kwargs)
result = []
for i in all:
for j in range(i.often):
result.append(i)
return result
def one(self, **kwargs):
return choice(self.by_time(**kwargs))
def by_often(self, **kwargs):
result = self.by_time(**kwargs)
shuffle(result)
return result
def create_for_paid(self, expo, url, role):
try:
name = str(expo.name)
except UnicodeEncodeError, UnicodeDecodeError:
name = expo.url
alt = u'%s_%s'%(name, role)
return self.create(alt=alt, url=url, paid=True)
class BannerGroupCached(models.Manager):
def all(self):
key = 'banner_group_all'
result = cache.get(key)
if not result:
result = list(self.filter(public=True))
cache.set(key, result, 90)
return result
def group_banners(self):
key = 'banner_group_banners'
result = cache.get(key)
if not result:
groups = self.all()
today = date.today()
result = {}
for group in groups:
result[group.slug] = list(group.banners.prefetch_related('urls', 'theme', 'country')\
.filter(public=True, fr__lte=today)\
.filter(Q(to__gte=today) | Q(to__isnull=True)))
cache.set(key, result, 70)
return result
class URLCached(models.Manager):
def all(self):
key = 'banner_url_all'
result = cache.get(key)
if not result:
result = list(self.filter(public=True))
cache.set(key, result, 150)
return result
class TopCached(models.Manager):
def all(self):
key = 'expo_b_top_all'
result = cache.get(key)
if not result:
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)
# -*- coding: utf-8 -*
from datetime import date
from random import choice, shuffle
from django.db import models
from django.db.models import Q
from django.core.cache import cache
class BiasedManager(models.Manager):
def by_time(self, **kwargs):
all = super(BiasedManager, self).get_query_set().filter(**kwargs)
result = []
for i in all:
for j in range(i.often):
result.append(i)
return result
def one(self, **kwargs):
return choice(self.by_time(**kwargs))
def by_often(self, **kwargs):
result = self.by_time(**kwargs)
shuffle(result)
return result
def create_for_paid(self, expo, url, role):
try:
name = str(expo.name)
except UnicodeEncodeError, UnicodeDecodeError:
name = expo.url
alt = u'%s_%s'%(name, role)
return self.create(alt=alt, url=url, paid=True)
class BannerGroupCached(models.Manager):
def all(self):
key = 'banner_group_all'
result = cache.get(key)
if not result:
result = list(self.filter(public=True))
cache.set(key, result, 90)
return result
def group_banners(self):
key = 'banner_group_banners'
result = cache.get(key)
if not result:
groups = self.all()
today = date.today()
result = {}
for group in groups:
result[group.slug] = list(group.banners.prefetch_related('urls', 'theme', 'country')\
.filter(public=True, fr__lte=today)\
.filter(Q(to__gte=today) | Q(to__isnull=True)))
cache.set(key, result, 70)
return result
class URLCached(models.Manager):
def all(self):
key = 'banner_url_all'
result = cache.get(key)
if not result:
result = list(self.filter(public=True))
cache.set(key, result, 150)
return result
class TopCached(models.Manager):
def all(self):
key = 'expo_b_top_all'
result = cache.get(key)
if not result:
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)
return result

@ -1,323 +1,328 @@
# -*- coding: utf-8 -*-
import random
import hashlib
from datetime import datetime, date
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.contrib.sites.models import Site
from django.db.models.signals import post_save
from .managers import BiasedManager, BannerGroupCached, URLCached, TopCached
from .mixins import StatMixin
from theme.models import Theme
from country.models import Country
class URL(models.Model):
title = models.CharField(verbose_name=u'Заголовок', max_length=256)
url = models.CharField(verbose_name=u'URL or URL RegEx', max_length=2048)
regex = models.BooleanField(verbose_name=u'RegEx', default=False)
sites = models.ManyToManyField(Site, related_name='site_urls', verbose_name=_('Sites'), null=True, blank=True)
public = models.BooleanField(verbose_name=u'Активный', default=True)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
objects = models.Manager()
cached = URLCached()
def __unicode__(self):
return self.title
class Meta:
ordering = ['-created_at']
verbose_name = _('URL')
verbose_name_plural = _('URLs')
def get_admin_url(self):
return '/admin/expobanners/banners/url/%d/edit/'%self.id
class BannerGroup (models.Model):
name = models.CharField(verbose_name=u'Имя', max_length=255)
slug = models.SlugField(verbose_name=u'URL', unique=True)
width = models.PositiveSmallIntegerField(verbose_name=u'Ширина', default=0)
height = models.PositiveSmallIntegerField(verbose_name=u'Высота', default=0)
speed = models.PositiveSmallIntegerField(verbose_name=u'Скорость отображения', default=2000)
public = models.BooleanField(verbose_name=u'Активная', default=True)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
objects = models.Manager()
cached = BannerGroupCached()
def size(self):
return '%sx%s' % (self.width, self.height)
def __unicode__(self):
return '%s - [%s x %s]' % (self.name, self.width, self.height)
class Meta:
ordering = ['name']
verbose_name = _('Banner Group')
verbose_name_plural = _('Banner Groups')
def get_admin_url(self):
return '/admin/expobanners/banners/group/%d/edit/'%self.id
class Banner(models.Model, StatMixin):
objects = BiasedManager()
title = models.CharField(verbose_name=u'Заголовок', max_length=255, blank=True)
alt = models.CharField(verbose_name=_('Alt'), max_length=255)
text = models.TextField(verbose_name=u'Текст', blank=True, null=True)
img = models.FileField(verbose_name=u'Картинка', upload_to='expo_upload', blank=True, null=True)
url = models.CharField(verbose_name=u'URL', max_length=1024)
fr = models.DateField(default=date.today())
to = models.DateField(blank=True, null=True)
theme = models.ManyToManyField(Theme, blank=True, null=True, verbose_name=u'Тематика')
country = models.ManyToManyField(Country, blank=True, null=True, verbose_name=u'Страна')
sort = models.PositiveSmallIntegerField(verbose_name=u'Сорт', default=500)
group = models.ForeignKey(BannerGroup, related_name='banners', verbose_name=u'Место', null=True, blank=True)
often = models.PositiveSmallIntegerField(
verbose_name=_('Often'),
help_text=_('A ten will display 10 times more often that a one.'),
choices=[[i, i] for i in range(11)],
default=1
)
urls = models.ManyToManyField(URL, related_name='url_banners', verbose_name=_('URLs'), null=True, blank=True)
html = models.BooleanField(verbose_name=_('HTML?'), default=False)
flash = models.BooleanField(verbose_name=_('Flash?'), default=False)
popup = models.BooleanField(verbose_name=_('Popup?'), 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)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
stat_pswd = models.CharField(max_length=16)
class Meta:
ordering = ['-public']
def get_admin_url(self):
return '/admin/expobanners/banners/banner/%d/edit/'%self.id
def key(slef):
if hasattr(settings, 'SECRET_KEY'):
key = str(datetime.now()) + settings.SECRET_KEY
else:
key = str(datetime.now())
return hashlib.md5(key).hexdigest()
def log(self, request, type):
log = {
'type': type,
'banner': self,
'group': self.group,
'ip': request.META.get('REMOTE_ADDR'),
'user_agent': request.META.get('HTTP_USER_AGENT'),
'page': request.META.get('HTTP_REFERER'),
}
if request.user.is_authenticated():
log['user'] = request.user
return Log.objects.create(**log)
@models.permalink
def image(self):
return ('banner_view', (), {'banner_id': self.pk, 'key': self.key()})
def impressions(self):
return Log.objects.filter(banner=self.pk, type=0).count()
def views(self):
return Log.objects.filter(banner=self.pk, type=1).count()
def clicks(self):
return Log.objects.filter(banner=self.pk, type=2).count()
def __unicode__(self):
return self.title or self.alt
def get_absolute_url(self):
if self.url == '#':
return self.url
else:
@models.permalink
def get_absolute_url(self):
return ('banner_click', (), {'banner_id': self.pk, 'key': self.key()})
return get_absolute_url(self)
def get_click_link(self):
return '/expo-b/click/%d/'%self.id
class Meta:
ordering = ['sort']
verbose_name = _('Banner')
verbose_name_plural = _('Banners')
class Log(models.Model):
banner = models.ForeignKey(Banner, related_name='banner_logs')
group = models.ForeignKey(BannerGroup, related_name='group_logs', verbose_name=_('Group'), blank=True, null=True)
urls = models.ManyToManyField(URL, related_name='url_logs', verbose_name=_('URLs'), blank=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='users', verbose_name=_('User'))
datetime = models.DateTimeField(verbose_name=_('Clicked At'), auto_now_add=True)
ip = models.IPAddressField(verbose_name=_('IP'), null=True, blank=True)
user_agent = models.CharField(verbose_name=_('User Agent'), max_length=1024, null=True, blank=True)
page = models.URLField(verbose_name=_('Page'), null=True, blank=True)
key = models.CharField(verbose_name=_('User Agent'), max_length=32, null=True, blank=True)
TYPE_CHOICES = (
(0, 'impressions'),
(1, 'view'),
(2, 'click')
)
type = models.PositiveSmallIntegerField(verbose_name=_('Type'), max_length=1, default=0, choices=TYPE_CHOICES)
def __unicode__(self):
return '%s - (%s)' % (self.banner, self.datetime)
class LogStat(models.Model):
banner = models.ForeignKey(Banner, related_name='banner_stat', verbose_name=_('Banner'), blank=True)
group = models.ForeignKey(BannerGroup, related_name='group_stat', verbose_name=_('Group'), blank=True, null=True)
urls = models.ManyToManyField(URL, related_name='url_bloks', verbose_name=_('URLs'), null=True, blank=True)
date = models.DateField(verbose_name=_('Data'))
view = models.PositiveIntegerField(verbose_name=_('Views'))
click = models.PositiveIntegerField(verbose_name=_('Clicks'))
unique_click = models.PositiveIntegerField(verbose_name=_('Unique Views'), blank=True, null=True)
unique_view = models.PositiveIntegerField(verbose_name=_('Unique Clicks'))
def __unicode__(self):
return '%s - (%s)' % (self.banner, self.date)
# ------------------
class Paid(models.Model, StatMixin):
tickets = models.ForeignKey(Banner, related_name='paid_tickets')
participation = models.ForeignKey(Banner, related_name='paid_participation')
official = models.ForeignKey(Banner, related_name='paid_official')
catalog = models.ForeignKey(Banner, related_name='paid_catalog')
logo = models.ImageField(upload_to='expo-b/paid', blank=True)
organiser = models.CharField(max_length=100, blank=True)
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
class PaidStat(models.Model):
paid = models.ForeignKey(Paid)
date = models.DateField(verbose_name=_('Date'))
page_views = models.PositiveIntegerField(default=0)
price_views = models.PositiveIntegerField(default=0)
catalog_views = models.PositiveIntegerField(default=0)
catalog_clicks = models.PositiveIntegerField(default=0)
tickets_clicks = models.PositiveIntegerField(default=0)
participation_clicks = models.PositiveIntegerField(default=0)
official_clicks = models.PositiveIntegerField(default=0)
class Top(models.Model, StatMixin):
link = models.ForeignKey(Banner)
catalog = models.CharField(max_length=16, 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'Тематики')
excluded_tags = models.ManyToManyField('theme.Tag', blank=True, null=True, verbose_name=u'Исключить теги')
country = models.ManyToManyField('country.Country', blank=True, null=True, verbose_name=u'Страны')
excluded_cities = models.ManyToManyField('city.City', blank=True, null=True, verbose_name=u'Исключить города')
fr = models.DateField(default=date.today(), verbose_name=u'Начало')
to = models.DateField(blank=True, null=True, verbose_name=u'Конец')
stat_pswd = models.CharField(max_length=16)
objects = models.Manager()
cached = TopCached()
class Meta:
ordering = ['position']
def get_event(self):
try:
return self.exposition_set.all()[0]
except IndexError:
return None
class TopStat(models.Model):
date = models.DateField()
theme = models.ForeignKey('theme.Theme', blank=True, null=True)
tag = models.ForeignKey('theme.Tag', blank=True, null=True)
country = models.ForeignKey('country.Country', blank=True, null=True)
city = models.ForeignKey('city.City', blank=True, null=True)
views = models.PositiveIntegerField(default=0)
clicks = models.PositiveIntegerField(default=0)
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):
"""
generate random password
"""
SYMBOLS = [',', '.', '?', '!', '-', '+', '1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A',
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#']
PASSWORD_LENGTH = length
newPassword = []
for i in range(PASSWORD_LENGTH):
newPassword.append(SYMBOLS[random.randrange(0, len(SYMBOLS))])
return ''.join(newPassword)
def generate_stat_pass(sender, **kwargs):
obj = kwargs['instance']
if not obj.stat_pswd:
obj.stat_pswd = generatePassword()
obj.save()
post_save.connect(generate_stat_pass, sender=Banner)
post_save.connect(generate_stat_pass, sender=Paid)
post_save.connect(generate_stat_pass, sender=Top)
# -*- coding: utf-8 -*-
import random
import hashlib
from datetime import datetime, date
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.contrib.sites.models import Site
from django.db.models.signals import post_save
from .managers import BiasedManager, BannerGroupCached, URLCached, TopCached
from .mixins import StatMixin
from theme.models import Theme
from country.models import Country
class URL(models.Model):
title = models.CharField(verbose_name=u'Заголовок', max_length=256)
url = models.CharField(verbose_name=u'URL or URL RegEx', max_length=2048)
regex = models.BooleanField(verbose_name=u'RegEx', default=False)
sites = models.ManyToManyField(Site, related_name='site_urls', verbose_name=_('Sites'), null=True, blank=True)
public = models.BooleanField(verbose_name=u'Активный', default=True)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
objects = models.Manager()
cached = URLCached()
def __unicode__(self):
return self.title
class Meta:
ordering = ['-created_at']
verbose_name = _('URL')
verbose_name_plural = _('URLs')
def get_admin_url(self):
return '/admin/expobanners/banners/url/%d/edit/'%self.id
class BannerGroup (models.Model):
name = models.CharField(verbose_name=u'Имя', max_length=255)
slug = models.SlugField(verbose_name=u'URL', unique=True)
width = models.PositiveSmallIntegerField(verbose_name=u'Ширина', default=0)
height = models.PositiveSmallIntegerField(verbose_name=u'Высота', default=0)
speed = models.PositiveSmallIntegerField(verbose_name=u'Скорость отображения', default=2000)
public = models.BooleanField(verbose_name=u'Активная', default=True)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
objects = models.Manager()
cached = BannerGroupCached()
def size(self):
return '%sx%s' % (self.width, self.height)
def __unicode__(self):
return '%s - [%s x %s]' % (self.name, self.width, self.height)
class Meta:
ordering = ['name']
verbose_name = _('Banner Group')
verbose_name_plural = _('Banner Groups')
def get_admin_url(self):
return '/admin/expobanners/banners/group/%d/edit/'%self.id
class Banner(models.Model, StatMixin):
objects = BiasedManager()
title = models.CharField(verbose_name=u'Заголовок', max_length=255, blank=True)
alt = models.CharField(verbose_name=_('Alt'), max_length=255)
text = models.TextField(verbose_name=u'Текст', blank=True, null=True)
img = models.FileField(verbose_name=u'Картинка', upload_to='expo_upload', blank=True, null=True)
url = models.CharField(verbose_name=u'URL', max_length=1024)
fr = models.DateField(default=date.today())
to = models.DateField(blank=True, null=True)
theme = models.ManyToManyField(Theme, blank=True, null=True, verbose_name=u'Тематика')
country = models.ManyToManyField(Country, blank=True, null=True, verbose_name=u'Страна')
sort = models.PositiveSmallIntegerField(verbose_name=u'Сорт', default=500)
group = models.ForeignKey(BannerGroup, related_name='banners', verbose_name=u'Место', null=True, blank=True)
often = models.PositiveSmallIntegerField(
verbose_name=_('Often'),
help_text=_('A ten will display 10 times more often that a one.'),
choices=[[i, i] for i in range(11)],
default=1
)
urls = models.ManyToManyField(URL, related_name='url_banners', verbose_name=_('URLs'), null=True, blank=True)
html = models.BooleanField(verbose_name=_('HTML?'), default=False)
flash = models.BooleanField(verbose_name=_('Flash?'), default=False)
popup = models.BooleanField(verbose_name=_('Popup?'), 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)
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True)
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True)
stat_pswd = models.CharField(max_length=16)
class Meta:
ordering = ['-public']
def get_admin_url(self):
return '/admin/expobanners/banners/banner/%d/edit/'%self.id
def key(slef):
if hasattr(settings, 'SECRET_KEY'):
key = str(datetime.now()) + settings.SECRET_KEY
else:
key = str(datetime.now())
return hashlib.md5(key).hexdigest()
def log(self, request, type):
log = {
'type': type,
'banner': self,
'group': self.group,
'ip': request.META.get('REMOTE_ADDR'),
'user_agent': request.META.get('HTTP_USER_AGENT'),
'page': request.META.get('HTTP_REFERER'),
}
if request.user.is_authenticated():
log['user'] = request.user
return Log.objects.create(**log)
@models.permalink
def image(self):
return ('banner_view', (), {'banner_id': self.pk, 'key': self.key()})
def impressions(self):
return Log.objects.filter(banner=self.pk, type=0).count()
def views(self):
return Log.objects.filter(banner=self.pk, type=1).count()
def clicks(self):
return Log.objects.filter(banner=self.pk, type=2).count()
def __unicode__(self):
return self.title or self.alt
def get_absolute_url(self):
if self.url == '#':
return self.url
else:
@models.permalink
def get_absolute_url(self):
return ('banner_click', (), {'banner_id': self.pk, 'key': self.key()})
return get_absolute_url(self)
def get_click_link(self):
return '/expo-b/click/%d/'%self.id
class Meta:
ordering = ['sort']
verbose_name = _('Banner')
verbose_name_plural = _('Banners')
class Log(models.Model):
banner = models.ForeignKey(Banner, related_name='banner_logs')
group = models.ForeignKey(BannerGroup, related_name='group_logs', verbose_name=_('Group'), blank=True, null=True)
urls = models.ManyToManyField(URL, related_name='url_logs', verbose_name=_('URLs'), blank=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='users', verbose_name=_('User'))
datetime = models.DateTimeField(verbose_name=_('Clicked At'), auto_now_add=True)
ip = models.IPAddressField(verbose_name=_('IP'), null=True, blank=True)
user_agent = models.CharField(verbose_name=_('User Agent'), max_length=1024, null=True, blank=True)
page = models.URLField(verbose_name=_('Page'), null=True, blank=True)
key = models.CharField(verbose_name=_('User Agent'), max_length=32, null=True, blank=True)
TYPE_CHOICES = (
(0, 'impressions'),
(1, 'view'),
(2, 'click')
)
type = models.PositiveSmallIntegerField(verbose_name=_('Type'), max_length=1, default=0, choices=TYPE_CHOICES)
def __unicode__(self):
return '%s - (%s)' % (self.banner, self.datetime)
class LogStat(models.Model):
banner = models.ForeignKey(Banner, related_name='banner_stat', verbose_name=_('Banner'), blank=True)
group = models.ForeignKey(BannerGroup, related_name='group_stat', verbose_name=_('Group'), blank=True, null=True)
urls = models.ManyToManyField(URL, related_name='url_bloks', verbose_name=_('URLs'), null=True, blank=True)
date = models.DateField(verbose_name=_('Data'))
view = models.PositiveIntegerField(verbose_name=_('Views'))
click = models.PositiveIntegerField(verbose_name=_('Clicks'))
unique_click = models.PositiveIntegerField(verbose_name=_('Unique Views'), blank=True, null=True)
unique_view = models.PositiveIntegerField(verbose_name=_('Unique Clicks'))
def __unicode__(self):
return '%s - (%s)' % (self.banner, self.date)
class Meta:
ordering = ['-date']
# ------------------
class Paid(models.Model, StatMixin):
tickets = models.ForeignKey(Banner, related_name='paid_tickets')
participation = models.ForeignKey(Banner, related_name='paid_participation')
official = models.ForeignKey(Banner, related_name='paid_official')
catalog = models.ForeignKey(Banner, related_name='paid_catalog')
logo = models.ImageField(upload_to='expo-b/paid', blank=True)
organiser = models.CharField(max_length=100, blank=True)
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
class PaidStat(models.Model):
paid = models.ForeignKey(Paid)
date = models.DateField(verbose_name=_('Date'))
page_views = models.PositiveIntegerField(default=0)
price_views = models.PositiveIntegerField(default=0)
catalog_views = models.PositiveIntegerField(default=0)
catalog_clicks = models.PositiveIntegerField(default=0)
tickets_clicks = models.PositiveIntegerField(default=0)
participation_clicks = models.PositiveIntegerField(default=0)
official_clicks = models.PositiveIntegerField(default=0)
class Meta:
ordering = ['-date']
class Top(models.Model, StatMixin):
link = models.ForeignKey(Banner)
catalog = models.CharField(max_length=16, 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'Тематики')
excluded_tags = models.ManyToManyField('theme.Tag', blank=True, null=True, verbose_name=u'Исключить теги')
country = models.ManyToManyField('country.Country', blank=True, null=True, verbose_name=u'Страны')
excluded_cities = models.ManyToManyField('city.City', blank=True, null=True, verbose_name=u'Исключить города')
fr = models.DateField(default=date.today(), verbose_name=u'Начало')
to = models.DateField(blank=True, null=True, verbose_name=u'Конец')
stat_pswd = models.CharField(max_length=16)
objects = models.Manager()
cached = TopCached()
class Meta:
ordering = ['position']
def get_event(self):
try:
return self.exposition_set.all()[0]
except IndexError:
return None
class TopStat(models.Model):
date = models.DateField()
theme = models.ForeignKey('theme.Theme', blank=True, null=True)
tag = models.ForeignKey('theme.Tag', blank=True, null=True)
country = models.ForeignKey('country.Country', blank=True, null=True)
city = models.ForeignKey('city.City', blank=True, null=True)
views = models.PositiveIntegerField(default=0)
clicks = models.PositiveIntegerField(default=0)
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):
"""
generate random password
"""
SYMBOLS = [',', '.', '?', '!', '-', '+', '1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A',
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#']
PASSWORD_LENGTH = length
newPassword = []
for i in range(PASSWORD_LENGTH):
newPassword.append(SYMBOLS[random.randrange(0, len(SYMBOLS))])
return ''.join(newPassword)
def generate_stat_pass(sender, **kwargs):
obj = kwargs['instance']
if not obj.stat_pswd:
obj.stat_pswd = generatePassword()
obj.save()
post_save.connect(generate_stat_pass, sender=Banner)
post_save.connect(generate_stat_pass, sender=Paid)
post_save.connect(generate_stat_pass, sender=Top)

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

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

@ -1,13 +1,13 @@
from django.conf.urls import url
from expobanner.stat_views import *
from . import views
urlpatterns = [
url(r'^click/(?P<banner_id>\d{1,4})/$', views.click, name='banner_click'),
#url(r'^view/(?P<banner_id>\d+)/$', views.view, name='banner_view'),
#
url(r'^get-banners/$', views.get_banners),
url(r'^get-tops/$', views.get_top),
url(r'^banner/(?P<pk>\d+)/stat/$', BannerStat.as_view(), name='banner_stat_client'),
url(r'^paid/(?P<pk>\d+)/stat/$', PaidStat.as_view(), name='paid_stat_client'),
]
from django.conf.urls import url
from expobanner.stat_views import *
from . import views
urlpatterns = [
url(r'^click/(?P<banner_id>\d{1,4})/$', views.click, name='banner_click'),
#url(r'^view/(?P<banner_id>\d+)/$', views.view, name='banner_view'),
#
url(r'^get-banners/$', views.get_banners),
url(r'^get-tops/$', views.get_top),
url(r'^banner/(?P<pk>\d+)/stat/$', BannerStat.as_view(), name='banner_stat_client'),
url(r'^paid/(?P<pk>\d+)/stat/$', PaidStat.as_view(), name='paid_stat_client'),
]

@ -1,100 +1,100 @@
# -*- coding: utf-8 -*-
import json
import re
from django.http import HttpResponse
from django.shortcuts import redirect, get_object_or_404
from django.shortcuts import render_to_response
from django.template import RequestContext
from .models import Banner, BannerGroup, URL, Top
from expobanner.utils import get_banner_by_params, get_client_ip, get_top_events, get_referer_view, set_cookie
def click(request, banner_id):
banner = get_object_or_404(Banner, pk=banner_id)
banner.log(request, 2)
return redirect(banner.url)
def view(request, banner_id):
banner = get_object_or_404(Banner, pk=banner_id)
banner.log(request, 1)
return redirect(banner.img.url)
def get_banners(request):
url = get_referer_view(request, default='/')
# get urls by current url
urls = URL.cached.all()
good_urls = []
for u in urls:
if u.regex:
try:
url_re = re.compile(u.url)
except:
continue
if url_re.findall(url):
good_urls.append(u)
elif url == u.url:
good_urls.append(u)
# fill parameters dict
params = {'theme': request.GET.getlist('theme', []),
'tag': request.GET.get('tag'),
'country': request.GET.get('country'),
'city': request.GET.get('city'),
'ip': get_client_ip(request)}
group_banners = BannerGroup.cached.group_banners()
result = []
cookie = None
# get banners for all groups
places = request.GET.getlist('places', [])
for group, banners in group_banners.iteritems():
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.html:
text = banner.text
img = ''
alt = ''
is_img = False
else:
text = ''
try:
img = banner.img.url
except ValueError:
continue
alt = banner.alt
is_img = True
result.append({'id': group,
'url': banner.get_click_link(),
'is_html': banner.html,
'is_flash': banner.flash,
'is_img': is_img,
'is_popup': banner.popup,
'img': img,
'alt': alt,
'text': text
})
if banner.popup:
cookie = banner.cookie
# add view log
banner.log(request, 1)
response = HttpResponse(json.dumps(result, indent=4), content_type='application/json')
if cookie:
response = set_cookie(response, cookie, '1')
return response
def get_top(request):
params = {'theme': request.GET.getlist('theme', []),
'tag': request.GET.get('tag'),
'country': request.GET.get('country'),
'city': request.GET.get('city'),
'catalog': request.GET.get('catalog')}
tops = Top.cached.all()
events = get_top_events(tops, params, request)
context = {'objects': events}
# -*- coding: utf-8 -*-
import json
import re
from django.http import HttpResponse
from django.shortcuts import redirect, get_object_or_404
from django.shortcuts import render_to_response
from django.template import RequestContext
from .models import Banner, BannerGroup, URL, Top
from expobanner.utils import get_banner_by_params, get_client_ip, get_top_events, get_referer_view, set_cookie
def click(request, banner_id):
banner = get_object_or_404(Banner, pk=banner_id)
banner.log(request, 2)
return redirect(banner.url)
def view(request, banner_id):
banner = get_object_or_404(Banner, pk=banner_id)
banner.log(request, 1)
return redirect(banner.img.url)
def get_banners(request):
url = get_referer_view(request, default='/')
# get urls by current url
urls = URL.cached.all()
good_urls = []
for u in urls:
if u.regex:
try:
url_re = re.compile(u.url)
except:
continue
if url_re.findall(url):
good_urls.append(u)
elif url == u.url:
good_urls.append(u)
# fill parameters dict
params = {'theme': request.GET.getlist('theme', []),
'tag': request.GET.get('tag'),
'country': request.GET.get('country'),
'city': request.GET.get('city'),
'ip': get_client_ip(request)}
group_banners = BannerGroup.cached.group_banners()
result = []
cookie = None
# get banners for all groups
places = request.GET.getlist('places', [])
for group, banners in group_banners.iteritems():
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.html:
text = banner.text
img = ''
alt = ''
is_img = False
else:
text = ''
try:
img = banner.img.url
except ValueError:
continue
alt = banner.alt
is_img = True
result.append({'id': group,
'url': banner.get_click_link(),
'is_html': banner.html,
'is_flash': banner.flash,
'is_img': is_img,
'is_popup': banner.popup,
'img': img,
'alt': alt,
'text': text
})
if banner.popup:
cookie = banner.cookie
# add view log
banner.log(request, 1)
response = HttpResponse(json.dumps(result, indent=4), content_type='application/json')
if cookie:
response = set_cookie(response, cookie, '1')
return response
def get_top(request):
params = {'theme': request.GET.getlist('theme', []),
'tag': request.GET.get('tag'),
'country': request.GET.get('country'),
'city': request.GET.get('city'),
'catalog': request.GET.get('catalog')}
tops = Top.cached.all()
events = get_top_events(tops, params, request)
context = {'objects': events}
return render_to_response('client/includes/exposition/expo_top.html', context, context_instance=RequestContext(request))

@ -217,7 +217,6 @@ class ExpositionCreateForm(forms.Form):
exposition.country = Country.objects.get(id=data['country'])
exposition.city = City.objects.get(id=data['city'])
if data.get('place'):
exposition.place = PlaceExposition.objects.get(id=data['place'])
else:
@ -359,7 +358,6 @@ class ExpositionCreateForm(forms.Form):
price_catalog = cleaned_data.get('price_catalog').strip()
return is_positive_integer(price_catalog)
def clean_visitors(self):
"""
checking visitors
@ -449,6 +447,12 @@ class ExpositionCreateForm(forms.Form):
discount = cleaned_data.get('discount').strip()
return is_positive_integer(discount)
class ExpositionDeleteForm(forms.ModelForm):
url = forms.CharField(widget=forms.HiddenInput())

@ -59,6 +59,8 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
data_end = models.DateField(verbose_name='Дата окончания')
services = BitField(flags=flags)
# 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,
related_name='exposition_country')
city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT,
@ -164,9 +166,6 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
enable = ClientManager()
imports = ExpoImportManager()
def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk))

@ -90,6 +90,7 @@ def paginate_results(qs, page=None):
return result
from hvad.models import TranslatableModel
class AdminListView(FormView):
def get_form(self, form_class):
@ -126,7 +127,10 @@ class AdminListView(FormView):
def get_context_data(self, **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'))
context['object_list'] = result
return context

@ -27,7 +27,7 @@ def get_theme(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)
def get_place_type(value):

Binary file not shown.

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

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

@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from django import forms
from django.conf import settings
from models import MetaSetting
from models import MetaSetting, SeoText
from functions.translate import fill_with_signal
from functions.admin_forms import AdminFilterForm
from ckeditor.widgets import CKEditorWidget
from hvad.forms import TranslatableModelForm
class MetaForm(forms.Form):
@ -14,7 +16,7 @@ class MetaForm(forms.Form):
create dynamical translated fields fields
"""
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
if len(settings.LANGUAGES) in range(10):
for lid, (code, name) in enumerate(settings.LANGUAGES):
@ -44,17 +46,14 @@ class MetaForm(forms.Form):
fill_with_signal(MetaSetting, meta, data)
meta.save()
class MetaFilterForm(AdminFilterForm):
model = MetaSetting
from .models import SeoText
from ckeditor.widgets import CKEditorWidget
from hvad.forms import TranslatableModelForm
class SeoTextForm(TranslatableModelForm):
# lang = forms.ChoiceField(choices=settings.LANGUAGES)
class Meta:
model = SeoText
fields = ['url', 'title', 'body']
widgets = {'body':CKEditorWidget}
fields = ['url', 'title', 'page_title', 'description', 'body']
widgets = {'body': CKEditorWidget}

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

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

@ -0,0 +1,122 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-08 13:44+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: password_reset/forms.py:14
msgid "Sorry, this user doesn't exist."
msgstr ""
#: password_reset/forms.py:31
msgid "Username"
msgstr ""
#: password_reset/forms.py:32
msgid "Email"
msgstr ""
#: password_reset/forms.py:33
msgid "Для восстановления пароля укажите email, который Вы регистрировали"
msgstr ""
#: password_reset/forms.py:83
msgid "Unable to find user."
msgstr ""
#: password_reset/forms.py:89
msgid "New password"
msgstr ""
#: password_reset/forms.py:93
msgid "New password (confirm)"
msgstr ""
#: password_reset/forms.py:98
msgid "The two passwords didn't match."
msgstr ""
#: password_reset/templates/password_reset/recovery_done.html:3
msgid "New password set"
msgstr ""
#: password_reset/templates/password_reset/recovery_done.html:6
msgid ""
"Your password has successfully been reset. You can use it right now on the "
"login page."
msgstr ""
#: password_reset/templates/password_reset/recovery_email.txt:1
#, python-format
msgid "Dear %(username)s,"
msgstr ""
#: password_reset/templates/password_reset/recovery_email.txt:3
#, python-format
msgid ""
"You -- or someone pretending to be you -- has requested a password reset on "
"%(domain)s."
msgstr ""
#: password_reset/templates/password_reset/recovery_email.txt:5
msgid "You can set your new password by following this link:"
msgstr ""
#: password_reset/templates/password_reset/recovery_email.txt:9
msgid ""
"If you don't want to reset your password, simply ignore this email and it "
"will stay unchanged."
msgstr ""
#: password_reset/templates/password_reset/recovery_email_subject.txt:1
#, python-format
msgid "Password recovery on %(domain)s"
msgstr ""
#: password_reset/templates/password_reset/recovery_form.html:5
msgid "Password recovery"
msgstr ""
#: password_reset/templates/password_reset/recovery_form.html:10
msgid "Recover my password"
msgstr ""
#: password_reset/templates/password_reset/reset.html:5
#, python-format
msgid ""
"Sorry, this password reset link is invalid. You can still <a href="
"\"%(recovery_url)s\">request a new one</a>."
msgstr ""
#: password_reset/templates/password_reset/reset.html:7
#, python-format
msgid "Hi, <strong>%(username)s</strong>. Please choose your new password."
msgstr ""
#: password_reset/templates/password_reset/reset.html:11
msgid "Set new password"
msgstr ""
#: password_reset/templates/password_reset/reset_sent.html:4
msgid "Password recovery sent"
msgstr ""
#: password_reset/templates/password_reset/reset_sent.html:7
#, python-format
msgid ""
"An email was sent to <strong>%(email)s</strong> %(ago)s ago. Use the link in "
"it to set a new password."
msgstr ""

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

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

@ -1,16 +1,16 @@
from functools import wraps
from django.template import RequestContext
from django.shortcuts import render_to_response
def render_to(tpl):
def decorator(func):
@wraps(func)
def wrapper(request, *args, **kwargs):
out = func(request, *args, **kwargs)
if isinstance(out, dict):
out = render_to_response(tpl, out, RequestContext(request))
return out
return wrapper
from functools import wraps
from django.template import RequestContext
from django.shortcuts import render_to_response
def render_to(tpl):
def decorator(func):
@wraps(func)
def wrapper(request, *args, **kwargs):
out = func(request, *args, **kwargs)
if isinstance(out, dict):
out = render_to_response(tpl, out, RequestContext(request))
return out
return wrapper
return decorator

@ -242,7 +242,6 @@ SOCIAL_AUTH_INACTIVE_USER_URL = '/inactive-user/'
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True
from social.pipeline.social_auth import social_details
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid',
@ -354,6 +353,7 @@ INSTALLED_APPS = (
'password_reset', # reset password
'social.apps.django_app.default', # social auth
'core',
'specialist_catalog',
)

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

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

@ -4,7 +4,7 @@ from views import ServiceView, CallBackListView, VisitListView, TranslationListV
ParticipationListView, RemoteListView,TicketsListView, Thanks
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/$', 'service.views.advertise'),
url(r'service/(?P<url>.*)/$', ServiceView.as_view()),

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

@ -0,0 +1,20 @@
# -*- 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,4})/$', SpecialistUpdateView.as_view(), name='specialist_edit'),
url(r'^specialist/delete/(?P<pk>\d{1,4})/$', 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/city/$', CatalogCityView.as_view(), name='catalog_city'),
url(r'^catalog/country/$', CatalogCountryView.as_view(), name='catalog_country'),
url(r'^catalog/edit/(?P<pk>\d{1,4})/$', CatalogUpdateView.as_view(), name='catalog_edit'),
url(r'^catalog/delete/(?P<pk>\d{1,4})/$', CatalogDeleteView.as_view(), name='catalog_delete'),
url(r'^catalog/(?P<catalog_pk>\d{1,4})/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,4})/feedback/(?P<id>\d{1,4})/$', FeedbackUpdateView.as_view(), name='feedback_edit'),
url(r'^feedback/delete/(?P<pk>\d{1,4})/$', 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_preview', '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,107 @@
# -*- 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_preview = models.ImageField(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)
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,225 @@
# -*- coding: utf-8 -*-
from django.views.generic import CreateView, UpdateView, DeleteView, ListView, FormView, DetailView
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
class CatalogCityView(ListView):
model = SpecialistCatalog
template_name = 'admin/specialist/catalog_all.html'
paginate_by = settings.ADMIN_PAGINATION
def get_queryset(self):
query = self.request.GET.get('query', None)
qs = self.model.objects.language().filter(type=2)
if query:
qs = qs.filter(title__icontains=query)
return qs
class CatalogCountryView(ListView):
model = SpecialistCatalog
template_name = 'admin/specialist/catalog_all.html'
paginate_by = settings.ADMIN_PAGINATION
def get_queryset(self):
query = self.request.GET.get('query', None)
qs = self.model.objects.language().filter(type=1)
if query:
qs = qs.filter(title__icontains=query)
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.
* For licensing, see LICENSE.html or http://ckeditor.com/license

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -1,4 +1,4 @@
/*
/*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
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