Compare commits

..

No commits in common. 'stage8' and 'master' have entirely different histories.

  1. 4
      .dockerignore
  2. 2
      .gitignore
  3. 12
      Dockerfile
  4. 36
      Dockerfile.django
  5. 4
      Dockerfile.nginx
  6. 149
      Dockerfile.solr
  7. 6
      Makefile
  8. 40
      README.md
  9. 1
      apps/article/models.py
  10. 3
      apps/article/views.py
  11. 0
      apps/comments/__init__.py
  12. 97
      apps/comments/admin.py
  13. 22
      apps/comments/forms.py
  14. 73
      apps/comments/matfilter.py
  15. 208
      apps/comments/migrations/0001_initial.py
  16. 0
      apps/comments/migrations/__init__.py
  17. 37
      apps/comments/models.py
  18. 16
      apps/comments/tests.py
  19. 55
      apps/comments/views.py
  20. 3
      apps/company/admin.py
  21. 40
      apps/conference/models.py
  22. 35
      apps/conference/tests/test_models.py
  23. 8
      apps/conference/tests/test_views.py
  24. 7
      apps/conference/urls.py
  25. 45
      apps/conference/views.py
  26. 2
      apps/country/admin.py
  27. 2
      apps/country/manager.py
  28. 3
      apps/emencia/django/newsletter/admin_urls.py
  29. 26
      apps/emencia/django/newsletter/forms.py
  30. 1
      apps/emencia/django/newsletter/mailer.py
  31. 8
      apps/emencia/django/newsletter/models.py
  32. 3
      apps/emencia/django/newsletter/urls/__init__.py
  33. 20
      apps/emencia/django/newsletter/views/admin_views.py
  34. 51
      apps/emencia/django/newsletter/views/expo_views.py
  35. 8
      apps/expobanner/forms.py
  36. 23
      apps/expobanner/views.py
  37. 3
      apps/exposition/forms.py
  38. 32
      apps/exposition/models.py
  39. 5
      apps/exposition/urls.py
  40. 34
      apps/exposition/views.py
  41. 4
      apps/functions/custom_views.py
  42. 88
      apps/functions/model_mixin.py
  43. 22
      apps/import_xls/admin.py
  44. 1
      apps/import_xls/excel_settings.py
  45. 19
      apps/import_xls/export_forms.py
  46. 0
      apps/note/__init__.py
  47. 13
      apps/note/models.py
  48. 16
      apps/note/tests.py
  49. 1
      apps/note/views.py
  50. 1
      apps/place_exposition/views.py
  51. 2
      apps/service/models.py
  52. 2
      apps/service/urls.py
  53. 14
      apps/service/views.py
  54. 9
      apps/settings/templatetags/template_filters.py
  55. 85
      proj/settings.py
  56. 2
      proj/urls.py
  57. 4
      proj/views.py
  58. 19
      requirements.txt
  59. 4
      schema.xml
  60. 17
      static/client.old/js/main.js
  61. 400
      static/client/css/main.css
  62. 2
      static/client/css_min/main.min.css
  63. 12
      static/client/html-cut/paid_exposition.html
  64. 8
      static/client/html-cut/subscribe.html
  65. BIN
      static/client/img/expo_default.png
  66. BIN
      static/client/img/exposition_small_logo.png
  67. BIN
      static/client/img/partners/new/РАЭК.jpg
  68. BIN
      static/client/img/sprites.png
  69. BIN
      static/client/img/sprites_backup.png
  70. 81
      static/client/js/_modules/block.exposition.list.js
  71. 4789
      static/client/js/_modules/block.search.js
  72. 3708
      static/client/js/_modules/page.events.feed.js
  73. 335
      static/client/js/_modules/page.exposition.object.js
  74. 74
      static/client/js/_modules/page.index.js
  75. 33
      static/client/js/main.js
  76. 8
      static/client/js/rejs/tops.js
  77. 102
      static/client/js/scripts.js
  78. 135
      static/client/js/vendor.js
  79. 2
      static/client/js_min/_modules/block.exposition.list.min.js
  80. 2
      static/client/js_min/_modules/block.search.min.js
  81. 2
      static/client/js_min/_modules/page.events.feed.min.js
  82. 2
      static/client/js_min/_modules/page.exposition.object.min.js
  83. 1
      static/client/js_min/_modules/page.index.min.js
  84. 16
      static/client/js_min/vendor.min.js
  85. BIN
      static/img/gallery/.tmb/l1_MS5qcGc1344290228.png
  86. BIN
      static/img/gallery/.tmb/l1_MTAuanBn1344290212.png
  87. BIN
      static/img/gallery/.tmb/l1_MTEuanBn1344290212.png
  88. BIN
      static/img/gallery/.tmb/l1_MTIuanBn1344290216.png
  89. BIN
      static/img/gallery/.tmb/l1_MTMuanBn1344290218.png
  90. BIN
      static/img/gallery/.tmb/l1_MTQuanBn1344290218.png
  91. BIN
      static/img/gallery/.tmb/l1_MTUuanBn1344290220.png
  92. BIN
      static/img/gallery/.tmb/l1_MTYuanBn1344290222.png
  93. BIN
      static/img/gallery/.tmb/l1_MTcuanBn1344290224.png
  94. BIN
      static/img/gallery/.tmb/l1_MTguanBn1344290226.png
  95. BIN
      static/img/gallery/.tmb/l1_MTkuanBn1344290228.png
  96. BIN
      static/img/gallery/.tmb/l1_Mi5qcGc1344290242.png
  97. BIN
      static/img/gallery/.tmb/l1_MjAuanBn1344290232.png
  98. BIN
      static/img/gallery/.tmb/l1_MjEuanBn1344290232.png
  99. BIN
      static/img/gallery/.tmb/l1_MjIuanBn1344290236.png
  100. BIN
      static/img/gallery/.tmb/l1_MjMuanBn1344290238.png
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,4 +0,0 @@
data
media
collected_static
node_modules

2
.gitignore vendored

@ -17,6 +17,4 @@ collected_static
# gulp
node_modules
package-lock.json
npm-debug.log
data

@ -1,12 +0,0 @@
FROM expomap/django
ENV PYTHONUNBUFFERED 1
ENV LANG ru_RU.UTF-8
RUN mkdir /code
WORKDIR /code
ADD manage.py /code/
ADD templates /code/templates
ADD proj /code/proj
ADD apps /code/apps

@ -1,36 +0,0 @@
FROM python:2.7.13
ENV PYTHONUNBUFFERED 1
ENV LANG ru_RU.UTF-8
ADD ./requirements.txt /
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \
&& apt-get update \
\
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
\
build-essential \
libtiff5-dev \
libjpeg62-turbo-dev \
zlib1g-dev \
libfreetype6-dev \
liblcms2-dev \
libwebp-dev \
tcl8.5-dev \
tk8.5-dev \
python-tk \
pngquant \
gifsicle \
libmemcached-dev \
locales \
uwsgi \
\
&& rm -rf /var/lib/apt/lists/* \
\
&& sed -i -e 's/# ru_RU.UTF-8 UTF-8/ru_RU.UTF-8 UTF-8/' /etc/locale.gen \
&& echo 'LANG="ru_RU.UTF-8"'>/etc/default/locale \
&& dpkg-reconfigure --frontend=noninteractive locales \
&& update-locale LANG=ru_RU.UTF-8 \
&& pip install -r requirements.txt

@ -1,4 +0,0 @@
FROM nginx
ADD ./static /expomap/app/static

@ -1,149 +0,0 @@
FROM ubuntu:12.04.5
# defines root user, to perform privileged operations
USER root
# enable apt mirrors (best performance due to use the closest repository)
RUN readonly APT_SOURCES="/etc/apt/sources.list" \
&& readonly UBUNTU_RELEASE_NAME="$(cat /etc/lsb-release | grep CODENAME | cut -d '=' -f2)" \
&& sed --in-place \
--regexp-extended \
--expression \
"1s/^/deb mirror:\/\/mirrors\.ubuntu\.com\/mirrors\.txt "${UBUNTU_RELEASE_NAME}"-security main restricted universe multiverse\n\n/" \
--expression \
"1s/^/deb mirror:\/\/mirrors\.ubuntu\.com\/mirrors\.txt "${UBUNTU_RELEASE_NAME}"-backports main restricted universe multiverse\n/" \
--expression \
"1s/^/deb mirror:\/\/mirrors\.ubuntu\.com\/mirrors\.txt "${UBUNTU_RELEASE_NAME}"-updates main restricted universe multiverse\n/" \
--expression \
"1s/^/deb mirror:\/\/mirrors\.ubuntu\.com\/mirrors\.txt "${UBUNTU_RELEASE_NAME}" main restricted universe multiverse\n/" \
--expression \
"1s/^/\# Enable Ubuntu mirrors and multiverse\n/" \
"${APT_SOURCES}"
# upgrade Ubuntu packages, install security updates and required packages
RUN readonly UBUNTU_PACKAGES=" \
curl \
" \
&& apt-get update \
&& apt-get upgrade --assume-yes \
&& apt-get install --no-install-recommends \
--assume-yes \
${UBUNTU_PACKAGES} \
# remove apt cache in order to improve Docker image size
&& apt-get clean
## Solr
# environment variables
ENV SOLR_VERSION 3.5.0
ENV SOLR_USER solr
ENV SOLR_UID 8983
ENV SOLR_PORT 8983
# declare required packages
RUN readonly SOLR_PACKAGES=" \
openjdk-6-jre-headless \
tomcat6 \
" \
# install packages
&& apt-get install \
--no-install-recommends \
--assume-yes \
${SOLR_PACKAGES} \
# remove apt cache in order to improve Docker image size
&& apt-get clean
# create group
RUN groupadd \
--system \
--gid ${SOLR_UID} \
${SOLR_USER} \
# create user and add to group
&& useradd \
--system \
--uid ${SOLR_UID} \
--gid ${SOLR_USER} \
${SOLR_USER}
# create temp folder
RUN mkdir /tmp/solr \
&& cd /tmp/solr \
# download Solr
&& curl \
--silent \
--show-error \
--location \
--output apache-solr-${SOLR_VERSION}.tgz \
https://archive.apache.org/dist/lucene/solr/${SOLR_VERSION}/apache-solr-${SOLR_VERSION}.tgz \
# extract Solr
&& tar \
--extract \
--gunzip \
--file \
apache-solr-${SOLR_VERSION}.tgz \
--directory \
/opt \
# link Solr folder
&& ln \
--symbolic \
--force \
/opt/apache-solr-${SOLR_VERSION} \
/opt/solr \
# change permissions
&& chown \
--recursive \
${SOLR_USER}:${SOLR_USER} \
/opt/apache-solr-${SOLR_VERSION} \
&& chown \
--recursive \
${SOLR_USER}:${SOLR_USER} \
/opt/solr \
# purge source files
&& cd / \
&& rm \
--recursive \
--force \
/tmp/solr
ADD schema.xml /opt/apache-solr-3.5.0/example/solr/conf/schema.xml
## DUMB-init
# more information at: https://github.com/Yelp/dumb-init
# environment variables
ENV DUMB_INIT_VERSION 1.2.0
# download
RUN mkdir \
--parents \
/tmp/dumb-init \
&& cd /tmp/dumb-init \
&& curl \
--silent \
--show-error \
--location \
--remote-name \
https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_amd64.deb \
# install
&& dpkg \
--install \
dumb-init_${DUMB_INIT_VERSION}_amd64.deb \
# remove temp folder
&& cd / \
&& rm \
--force \
--recursive \
/tmp/dumb-init
## Docker specifics
# expose Solr service port
EXPOSE ${SOLR_PORT}
# drop back to the regular Solr user - good practice
USER ${SOLR_USER}
# change workdir to Solr folder
WORKDIR /opt/solr/example
# docker entrypoint/cmd configuration
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["java","-Xmx256m","-jar","start.jar"]

@ -16,7 +16,7 @@ freeze:
syncdb:
-@echo "### Creating database tables and loading fixtures"
@PYTHONPATH=$(PYTHONPATH):. DJANGO_SETTINGS_MODULE=$(project_name).settings ipython manage.py syncdb
@PYTHONPATH=$(PYTHONPATH):. DJANGO_SETTINGS_MODULE=$(project_name).settings ipython manage.py syncdb --noinput
@PYTHONPATH=$(PYTHONPATH):. DJANGO_SETTINGS_MODULE=$(project_name).settings ipython manage.py migrate
run:
@ -35,10 +35,10 @@ solrstop:
/opt/solr/bin/solr stop -all
makemessages:
-@python manage.py makemessages --all
-@ipython manage.py makemessages --all
compilemessages:
-@python manage.py compilemessages
-@ipython manage.py compilemessages
collectstatic:
@ipython manage.py collectstatic

@ -22,6 +22,12 @@ RAVEN_CONFIG = {
# -*- coding: utf-8 -*-
from settings import *
DEBUG = True
# emencia.django.newsletter
LOCAL_DEV = True
# sorl.thumbnail
THUMBNAIL_DEBUG = True
DEFAULT_HTTP_SCHEME = 'http'
DATABASES = {
@ -45,7 +51,41 @@ DATABASES = {
}
}
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
INSTALLED_APPS += ('south',)
# debug_toolbar settings
DEBUG_TOOLBAR_PATCH_SETTINGS = False
INTERNAL_IPS = ('127.0.0.1',)
MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
INSTALLED_APPS += (
'debug_toolbar',
)
JQUERY_URL = os.path.join(SITE_ROOT, 'static/client/js/jquery-ui-1.10.4.custom.min.js'),
DEBUG_TOOLBAR_PANELS = [
#'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
]
# копия бд для тестов должна начинаться с приставки test_
TEST_RUNNER = 'proj.test.CustomTestRunner'

@ -99,6 +99,7 @@ class Article(TranslatableModel):
)
files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id')
comments = generic.GenericRelation('comments.Comment')
class Meta:
ordering = ['-publish_date']

@ -10,6 +10,7 @@ from functions.custom_views import ListView
from theme.models import Tag, Theme
from meta.views import MetadataMixin
from comments.views import CommentMixin
from .models import Article
from .forms import BlogFilterForm, NewsFilterForm
@ -148,7 +149,7 @@ class BlogList(MetadataMixin, ListView):
return context
class BlogDetail(MetadataMixin, DetailView):
class BlogDetail(CommentMixin, MetadataMixin, DetailView):
model = Article
slug_field = 'slug'
template_name = 'client/article/article.html'

@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
from functools import update_wrapper, partial
from django.contrib import admin
from django.contrib.admin.util import unquote
from django.conf.urls import patterns, url
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse_lazy, reverse
from django.http import Http404
from django.utils.translation import ugettext_lazy as _
from django.utils.html import escape
from django.utils.encoding import force_text
from functions.admin import DefaultAdmin
from functions.http import JsonResponse
from .models import Comment
class CommentAdmin(DefaultAdmin):
class Media:
js = (
"js/jquery.truncator.js",
"admin/js/comments_manage.js",
)
# css = {
# 'all': ("admin/css/comments_manage.css",),
# }
list_display = ['text', 'ip', 'user', 'hide']
list_select_related = True
list_filter = ('hidden', )
date_hierarchy = 'created'
readonly_fields = ['ip', 'created', 'parent', 'user']
fieldsets = (
(None,
{'fields': (('created', 'hidden',),
'ip',
'user',
'text', )}),
)
def hide(self, obj):
body = u'<img src="{url}" alt={alt}>' \
u'&nbsp;<a class="action" href="{href}">{label}</a>' \
u'&nbsp;|&nbsp;<a class="action" href="{href2}">{label2}</a>'\
.format(**self.get_yesno_image_data(obj))
return body
hide.short_description = _(u'Модерирование')
hide.allow_tags = True
def urls(self):
urlpatterns = self.get_urls()
def wrap(view):
def wrapper(*args, **kwargs):
return self.admin_site.admin_view(view)(*args, **kwargs)
return update_wrapper(wrapper, view)
info = self.model._meta.app_label, self.model._meta.module_name
_urlpatterns = patterns('',
url(r'^(?P<object_id>\d+)/ajax/(?P<action>hide|show|banro|unbanro)/$',
wrap(self.ajax_view),
name='%s_%s_ajax' % info),
)
return _urlpatterns + urlpatterns
urls = property(urls)
def get_yesno_image_data(self, obj):
return {
'url': '/static/admin/img/icon-{0}.gif'.format('no' if obj.hidden else 'yes'),
'alt': str(not obj.hidden),
'href': reverse('admin:comments_comment_ajax', args=[obj.id, 'hide' if not obj.hidden else 'show']),
'label': unicode(_(u'Опубликовать') if obj.hidden else _(u'Скрыть')),
'href2': reverse('admin:comments_comment_ajax', args=[obj.id, 'banro' if not obj.user.readonly else 'unbanro']),
'label2': unicode(_(u'Снять RO') if obj.user.readonly else _(u'Наложить RO')),
}
def ajax_view(self, request, object_id, extra_context=None, *args, **kwargs):
"The 'change' admin view for this model."
action = kwargs.get('action')
model = self.model
opts = model._meta
obj = self.get_object(request, unquote(object_id))
if not self.has_change_permission(request, obj) or not request.is_ajax():
raise PermissionDenied
if obj is None:
raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)})
if action in ['hide', 'show']:
obj.hidden = True if action == 'hide' else False
obj.save()
else:
obj.user.readonly = True if action == 'banro' else False
obj.user.save()
return JsonResponse(dict({'success': True}, **self.get_yesno_image_data(obj)))
ajax_view.csrf_exempt = True
admin.site.register(Comment, CommentAdmin)

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from django import forms
from django.utils.translation import ugettext as _
from functions.forms import EmptySelect
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['parent', 'text']
widgets = dict(parent=EmptySelect)
def save(self, commit=True):
obj = super(CommentForm, self).save(commit=False)
return obj
def clean(self):
if getattr(self._user, 'readonly', True):
raise forms.ValidationError(_(u'Вы не можете оставлять комментарии. Вам выдано ограничение ReadOnly.'))
return super(CommentForm, self).clean()

@ -0,0 +1,73 @@
# -*- encoding: utf-8 -*-
version = "0.0.1"
version_info = (0,0,1)
"""
Модуль для поиска нецензурных слов (мата) в тексте
Лицензия: LGPL (http://www.opensource.org/licenses/lgpl-2.1.php)
Пример:
from matfilter import matfilter
some_data = "любой текст для проверки"
if len(matfilter(some_data)):
print "Пожалуйста, уберите из текста нецензурные выражения."
Источник:
https://bitbucket.org/spanasik/django-matfilter
"""
import re
PATTERNS = (ur"(\b[сs]{1}[сsц]{0,1}[uуy](?:[ч4]{0,1}[иаakк][^ц])\w*\b)",
ur"(\b(?!пло|стра|[тл]и)(\w(?!(у|пло)))*[хx][уy](й|йа|[еeё]|и|я|ли|ю)(?!га)\w*\b)",
ur"(\b(п[oо]|[нз][аa])*[хx][eе][рp]\w*\b)",
ur"(\b[мm][уy][дd]([аa][кk]|[oо]|и)\w*\b)",
ur"(\b\w*д[рp](?:[oо][ч4]|[аa][ч4])(?!л)\w*\b)",
ur"(\b(?!(?:кило)?[тм]ет)(?!смо)[а-яa-z]*(?<!с)т[рp][аa][хx]\w*\b)",
ur"(\b[к|k][аaoо][з3z]+[eе]?ё?л\w*\b)",
ur"(\b(?!со)\w*п[еeё]р[нд](и|иc|ы|у|н|е|ы)\w*\b)",
ur"(\b\w*[бп][ссз]д\w+\b)",
ur"(\b([нnп][аa]?[оo]?[xх])\b)",
ur"(\b([аa]?[оo]?[нnпбз][аa]?[оo]?)?([cс][pр][аa][^зжбсвм])\w*\b)",
ur"(\b\w*([оo]т|вы|[рp]и|[оo]|и|[уy]){0,1}([пnрp][iиеeё]{0,1}[3zзсcs][дd])\w*\b)",
ur"(\b(вы)?у?[еeё]?би?ля[дт]?[юоo]?\w*\b)",
ur"(\b(?!вело|ски|эн)\w*[пpp][eеиi][дd][oaоаеeирp](?![цянгюсмйчв])[рp]?(?![лт])\w*\b)",
ur"(\b(?!в?[ст]{1,2}еб)(?:(?:в?[сcз3о][тяaа]?[ьъ]?|вы|п[рp][иоo]|[уy]|р[aа][з3z][ьъ]?|к[оo]н[оo])?[её]б[а-яa-z]*)|(?:[а-яa-z]*[^хлрдв][еeё]б)\b)",
ur"(\b[з3z][аaоo]л[уy]п[аaeеин]\w*\b)",)
def CheckMatches(matches):
if len(matches):
result = []
for match in matches:
if type(match) == tuple:
result.append(match[0].strip())
else:
result.append(match.strip())
return result
return ()
def matfilter(text, npattern=None):
"""Находит в тексте мат.
Возвращает список найденных слов"""
text = text.replace("\r\n", " ")
text = text.replace("\n", " ")
if npattern is not None:
result = CheckMatches(re.findall(
PATTERNS[npattern], text,
re.IGNORECASE | re.VERBOSE | re.UNICODE | re.DOTALL))
if len(result):
return result
else:
for pattern in PATTERNS:
result = CheckMatches(re.findall(
pattern, text,
re.IGNORECASE | re.VERBOSE | re.UNICODE | re.DOTALL))
if len(result):
return result
return ()

@ -8,15 +8,24 @@ from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Exposition.main_image'
db.add_column(u'exposition_exposition', 'main_image',
self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True),
keep_default=False)
# Adding model 'Comment'
db.create_table(u'comments_comment', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('ip', self.gf('django.db.models.fields.GenericIPAddressField')(max_length=39, null=True, blank=True)),
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('hidden', self.gf('django.db.models.fields.BooleanField')(default=False)),
('parent', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['comments.Comment'], null=True, blank=True)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['accounts.User'])),
('text', self.gf('django.db.models.fields.TextField')()),
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
))
db.send_create_signal(u'comments', ['Comment'])
def backwards(self, orm):
# Deleting field 'Exposition.main_image'
db.delete_column(u'exposition_exposition', 'main_image')
# Deleting model 'Comment'
db.delete_table(u'comments_comment')
models = {
@ -165,13 +174,6 @@ class Migration(SchemaMigration):
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
u'events.targetaudience': {
'Meta': {'ordering': "['title']", 'object_name': 'TargetAudience'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'title_en': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'title_ru': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
},
u'expobanner.banner': {
'Meta': {'ordering': "['sort']", 'object_name': 'Banner'},
'alt': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
@ -180,7 +182,7 @@ class Migration(SchemaMigration):
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'customer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Customer']", 'null': 'True', 'blank': 'True'}),
'flash': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2017, 6, 27, 0, 0)'}),
'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2017, 1, 19, 0, 0)'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'banners'", 'null': 'True', 'to': u"orm['expobanner.BannerGroup']"}),
'html': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
@ -220,32 +222,6 @@ class Migration(SchemaMigration):
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
u'expobanner.mainpage': {
'Meta': {'ordering': "['-public']", 'object_name': 'MainPage'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'link': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Banner']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'position': ('django.db.models.fields.PositiveIntegerField', [], {'default': '2', 'null': 'True', 'blank': 'True'}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'stat_pswd': ('django.db.models.fields.CharField', [], {'max_length': '16'})
},
u'expobanner.paid': {
'Meta': {'ordering': "['-public']", 'object_name': 'Paid'},
'catalog': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'paid_catalog'", 'to': u"orm['expobanner.Banner']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'kind': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1', 'db_index': 'True'}),
'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'official': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'paid_official'", 'to': u"orm['expobanner.Banner']"}),
'organiser': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'participants_list': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'paid_participants_list'", 'null': 'True', 'to': u"orm['expobanner.Banner']"}),
'participation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'paid_participation'", 'null': 'True', 'to': u"orm['expobanner.Banner']"}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'stat_pswd': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
'tickets': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'paid_tickets'", 'to': u"orm['expobanner.Banner']"})
},
u'expobanner.top': {
'Meta': {'ordering': "['position']", 'object_name': 'Top'},
'base_catalog': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
@ -254,7 +230,7 @@ class Migration(SchemaMigration):
'country': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['country.Country']", 'null': 'True', 'blank': 'True'}),
'excluded_cities': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['city.City']", 'null': 'True', 'blank': 'True'}),
'excluded_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Tag']", 'null': 'True', 'blank': 'True'}),
'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2017, 6, 27, 0, 0)'}),
'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2017, 1, 19, 0, 0)'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'link': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Banner']"}),
'months': ('functions.custom_fields.MonthMultiSelectField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
@ -275,154 +251,6 @@ class Migration(SchemaMigration):
'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'url': ('django.db.models.fields.CharField', [], {'max_length': '2048'})
},
u'exposition.exposition': {
'Meta': {'unique_together': '()', 'object_name': 'Exposition', 'index_together': '()'},
'application_deadline': ('django.db.models.fields.DateField', [], {'null': 'True'}),
'area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'audience': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['events.TargetAudience']", 'null': 'True', 'symmetrical': 'False'}),
'bad_url': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'canceled_by_administrator': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'city': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'exposition_city'", 'on_delete': 'models.PROTECT', 'to': u"orm['city.City']"}),
'company': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'exposition_companies'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['company.Company']"}),
'country': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'exposition_country'", 'on_delete': 'models.PROTECT', 'to': u"orm['country.Country']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'exposition_creator'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['accounts.User']"}),
'currency': ('functions.custom_fields.EnumField', [], {'default': "'RUB'", 'values': "('RUB', 'USD', 'EUR', 'RMB', 'GBP', 'AED', 'SGD', 'TRY', 'CZK', 'CHF', 'SEK', 'LKR', 'UAH', 'IDR', 'PLN', 'JPY')"}),
'data_begin': ('django.db.models.fields.DateField', [], {'db_index': 'True'}),
'data_end': ('django.db.models.fields.DateField', [], {}),
'discount': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'expohit': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'foundation_year': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_published': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'main': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.MainPage']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
'main_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'main_page': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'db_index': 'True'}),
'max_closed_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'max_closed_equipped_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'max_open_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'members': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'members_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'min_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'min_closed_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'min_closed_equipped_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'min_open_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'min_stand_size': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'moved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'old_url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
'org': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'organiser': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'exposition_organisers'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['organiser.Organiser']"}),
'paid_new': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Paid']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
'periodic': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
'photogallery': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['photologue.Gallery']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
'place': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'exposition_place'", 'null': 'True', 'on_delete': 'models.PROTECT', 'to': u"orm['place_exposition.PlaceExposition']"}),
'place_alt': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'price_catalog': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'price_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'price_choice_eur': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'price_eur': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'price_rub': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'quality_label': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}),
'rating': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'registration_link': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}),
'registration_payment': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'services': ('django.db.models.fields.BigIntegerField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'tag': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'exposition_tags'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['theme.Tag']"}),
'tax': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'theme': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'exposition_themes'", 'symmetrical': 'False', 'to': u"orm['theme.Theme']"}),
'top': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Top']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'exposition_users'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['accounts.User']"}),
'views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
'visitors': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'visitors_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'web_page': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'exposition.expositiontranslation': {
'Meta': {'unique_together': "[('language_code', 'master')]", 'object_name': 'ExpositionTranslation', 'db_table': "u'exposition_exposition_translation'", 'index_together': '()'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'descriptions': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'discount_description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'keywords': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'language_code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
'main_title': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'master': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'null': 'True', 'to': u"orm['exposition.Exposition']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'participation_note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'pre_condition': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'price_all': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'price_all_bar': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'price_day': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'price_day_bar': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'products': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'stand_condition': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'stat_countries': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'time': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'visit_note': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'exposition.statistic': {
'Meta': {'unique_together': '()', 'object_name': 'Statistic', 'index_together': '()'},
'area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'countries_number': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'exposition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'statistic'", 'to': u"orm['exposition.Exposition']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'members': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'visitors': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'year': ('django.db.models.fields.PositiveIntegerField', [], {})
},
u'exposition.statistictranslation': {
'Meta': {'unique_together': "[('language_code', 'master')]", 'object_name': 'StatisticTranslation', 'db_table': "u'exposition_statistic_translation'", 'index_together': '()'},
'countries': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language_code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
'master': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'null': 'True', 'to': u"orm['exposition.Statistic']"})
},
u'exposition.timetable': {
'Meta': {'unique_together': '()', 'object_name': 'TimeTable', 'index_together': '()'},
'begin': ('django.db.models.fields.DateTimeField', [], {}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'end': ('django.db.models.fields.DateTimeField', [], {}),
'exposition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'business_program'", 'to': u"orm['exposition.Exposition']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'timetable_organiser': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['organiser.Organiser']", 'null': 'True', 'blank': 'True'})
},
u'exposition.timetabletranslation': {
'Meta': {'unique_together': "[('language_code', 'master')]", 'object_name': 'TimeTableTranslation', 'db_table': "u'exposition_timetable_translation'", 'index_together': '()'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language_code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
'master': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'null': 'True', 'to': u"orm['exposition.TimeTable']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'place': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'programe': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'speaker': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'exposition.tmptimetable': {
'Meta': {'unique_together': '()', 'object_name': 'TmpTimeTable', 'index_together': '()'},
'begin': ('django.db.models.fields.DateTimeField', [], {}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'end': ('django.db.models.fields.DateTimeField', [], {}),
'exposition': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['exposition.Exposition']", 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'timetable_organiser': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['organiser.Organiser']", 'null': 'True', 'blank': 'True'})
},
u'exposition.tmptimetabletranslation': {
'Meta': {'unique_together': "[('language_code', 'master')]", 'object_name': 'TmpTimeTableTranslation', 'db_table': "u'exposition_tmptimetable_translation'", 'index_together': '()'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language_code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
'master': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'null': 'True', 'to': u"orm['exposition.TmpTimeTable']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'place': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'programe': ('django.db.models.fields.TextField', [], {}),
'speaker': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'file.filemodel': {
'Meta': {'unique_together': '()', 'object_name': 'FileModel', 'index_together': '()'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']", 'null': 'True'}),
@ -621,4 +449,4 @@ class Migration(SchemaMigration):
}
}
complete_apps = ['exposition']
complete_apps = ['comments']

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.utils.translation import ugettext_lazy as _
from accounts.models import User
# from core.utils import UCrypto
class Comment(models.Model):
class Meta:
verbose_name = u'Комментарий'
verbose_name_plural = u'Комментарии'
get_latest_by = 'created'
ip = models.GenericIPAddressField(_(u'IP address'), unpack_ipv4=True, blank=True, null=True)
created = models.DateTimeField(_(u'дата создания'), auto_now_add=True)
hidden = models.BooleanField(_(u'скрыть'), default=False, help_text=_(u'Будет скрыто, если отмечено'))
parent = models.ForeignKey('self', verbose_name=_(u'Родительский комментарий'), null=True, blank=True)
user = models.ForeignKey(User, verbose_name=_(u'Пользователь'))
text = models.TextField(_(u'сообщение'))
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
def get_name(self):
return self.user.get_full_name()
def get_date(self):
return self.created.strftime('%d %B %Y %H:%M')
def __unicode__(self):
return self.get_date()

@ -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,55 @@
# -*- coding: utf-8 -*-
from django.views.generic.edit import FormMixin
from functions.http import JsonResponse
from .forms import CommentForm
class CommentMixin(FormMixin):
form_class = CommentForm
def get_comment_form(self):
form_class = self.get_form_class()
form = self.get_form(form_class)
form._user = self.request.user
return form
def post(self, request, *args, **kwargs):
self.commentform = None
if request.method == 'POST' and request.is_ajax():
self.commentform = self.get_comment_form()
if self.commentform.is_valid():
self.object = self.get_object()
self.save_comment()
return JsonResponse({'success': True})
else:
return JsonResponse({'success': False, 'errors': self.commentform.errors})
return self.get(request, *args, **kwargs)
def save_comment(self):
comment = self.commentform.save(commit=False)
comment.user_id = self.request.user.pk
comment.content_object = self.object
comment.ip = self.request.META['REMOTE_ADDR']
comment.save()
def get_context_data(self, **kwargs):
context = super(CommentMixin, self).get_context_data(**kwargs)
self.commentform = self.get_comment_form()
if self.request.method == 'POST' and self.commentform.is_valid():
self.save_comment()
context['commentform'] = self.commentform
_comments = list(self.object.comments.filter(hidden=False))
comments = {x.pk: x for x in filter(lambda x: x.parent is None, _comments)}
for comment in filter(lambda x: x.parent is not None, _comments):
try:
p = comments[comment.parent_id]
if hasattr(p, 'childs'):
p.childs.append(comment)
else:
p.childs = [comment]
except IndexError:
pass
context['comments'] = comments.values()
return context

@ -78,8 +78,7 @@ def company_change(request, url):
data['descriptions_%s' % code] = obj.descriptions
# fill form
form = CompanyForm(initial=data)
if company.city:
form.fields['city'].widget.attrs['data-init-text'] = company.city.name
form.fields['city'].widget.attrs['data-init-text'] = company.city.name
# set choices filled by ajax
# form.fields['city'].choices = [(item.id, item.name) for item in City.objects.filter(country=data['country'])]
form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.filter(theme__in=data['theme'])]

@ -96,6 +96,7 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
is_published = models.BooleanField(default=0, db_index=True)
files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id')
note = generic.GenericRelation('note.Note', content_type_field='content_type', object_id_field='object_id')
# statistic
foundation_year = models.PositiveIntegerField(verbose_name=_(u'Год основания'), blank=True, null=True)
visitors = models.PositiveIntegerField(verbose_name=_(u'Посетитеил'), blank=True, null=True)
@ -141,9 +142,35 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
_(u'Минимальная цена'), choices=PRICE_EUR, blank=True, null=True, db_index=True)
price_eur = models.PositiveIntegerField(verbose_name=_(u'Цена в евро'), blank=True, null=True)
comments = generic.GenericRelation('comments.Comment')
def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk))
def get_services(self):
return self.get_services_detail()
# country_ids = [item for item, bool in self.country.services if bool==True]
# ids = [item for item, bool in self.services if bool==True]
# qs = Service.objects.filter(Q(Q(url__in=country_ids) & Q(type=Service.type.conference)) | Q(url__in=ids))
# return list(qs)
#return list(Service.objects.language().filter(url__in=ids, type=Service.type.conference).order_by('sort'))
def get_services_detail(self):
# excluded = ['tickets']
return super(Conference, self).get_services_detail(None, Service.type.conference)
# def get_nearest_events(self):
# if self.theme.all():
# theme = self.theme.all()[0]
# now = datetime.datetime.now()
# now = now - datetime.timedelta(days=1)
# conferences = Conference.objects.filter(theme__in=[theme], data_begin__gt=now).exclude(id=self.id).order_by('data_begin')
# return conferences[:3]
# else:
# return []
def get_audience(self):
return self.audience.all()
@ -161,6 +188,19 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
'events:event_visit', args=['conference', self.id]
)
def get_note_url(self):
return reverse_lazy(
'conference_add_note',
args=[self.url]
)
def get_note_by_user(self, user_id):
note = self.note.filter(user__id=user_id)
try:
return note.get().text
except:
return ''
def tags(self):
return self.tag.language().all()

@ -1,8 +1,12 @@
import datetime
from accounts.models import User
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse, NoReverseMatch
from django.test import TestCase
from expobanner.models import Paid, Banner
from note.models import Note
from service.models import Service
from stats_collector.models import ObjectStats
from theme.models import Tag, Theme
@ -68,6 +72,16 @@ class ConferenceTest(TestCase):
'name', unicode(self.conference.pk))
)
def test_method_get_services(self):
services = [item for item, bool in self.conference.services if bool]
qs = Service.objects.language()
qs = qs.filter(url__in=services)
self.assertEqual(
sorted(self.conference.get_services(), key=lambda x: x.pk),
sorted(list(qs), key=lambda x: x.pk)
)
def test_method_get_news_url(self):
self.assertEqual(
self.conference.get_news_url(),
@ -98,6 +112,27 @@ class ConferenceTest(TestCase):
)
)
def test_method_get_note_url(self):
self.assertEqual(
self.conference.get_note_url(),
reverse('conference_add_note', args=[self.conference.url])
)
def test_method_get_note_by_user(self):
user = User.objects.all()[0]
self.assertEqual(self.conference.get_note_by_user(user.id), '')
text = 'Great'
ct = ContentType.objects.get_for_model(self.conference)
object_id = self.conference.id
Note.objects.create(
content_type=ct, object_id=object_id,
user=user, text=text
)
self.assertEqual(self.conference.get_note_by_user(user.id), text)
def test_method_tags(self):
self.assertFalse(self.conference.tags())

@ -74,7 +74,7 @@ class CanFilterAndSidePopular(object):
class ConferenceByCountryTest(ConferenceByTest, CanFilterAndSidePopular, TestCase):
url = reverse('conference_country')
title1 = _(u'По странам')
title2 = _(u'Конференции мира по странам')
title2 = _(u'Коференции мира по странам')
catalog = 'country/'
model = Country
@ -82,21 +82,21 @@ class ConferenceByCountryTest(ConferenceByTest, CanFilterAndSidePopular, TestCas
class ConferenceByThemeTest(ConferenceByTest, TestCase):
url = reverse('conference_theme')
title1 = _(u'По тематикам')
title2 = _(u'Конференции мира по тематикам')
title2 = _(u'Коференции мира по тематикам')
catalog = 'theme/'
class ConferenceByTagTest(ConferenceByTest, TestCase):
url = reverse('conference_tag')
title1 = _(u'По тегам')
title2 = _(u'Конференции мира по тегам')
title2 = _(u'Коференции мира по тегам')
catalog = 'tag/'
class ConferenceByCityTest(ConferenceByTest, CanFilterAndSidePopular, TestCase):
url = reverse('conference_city')
title1 = _(u'По городам')
title2 = _(u'Конференции мира по городам')
title2 = _(u'Коференции мира по городам')
catalog = 'city/'
model = City

@ -21,6 +21,13 @@ from .views import (
)
urlpatterns = patterns('',
url(
r'^conference/add-note/(?P<slug>[^/]*)/$',
'conference.views.add_note',
name='conference_add_note'
),
url(r'^conference-add-calendar/(?P<id>\d+)/$',
'conference.views.conference_add_calendar',
name='conference_add_calendar'

@ -19,6 +19,7 @@ from django.utils.translation import ugettext as _
from django.views.generic import DetailView
from django.views.generic.edit import FormMixin
from comments.views import CommentMixin
from functions.cache_mixin import CacheMixin, JitterCacheMixin
from functions.custom_views import ListView, ReverseOrderMixin
from functions.views_help import get_side_items
@ -29,6 +30,7 @@ from city.models import City
from country.models import Country
from meta.views import MetadataMixin
from models import Conference
from note.models import Note
from service.models import Service
from service.order_forms import AdvertiseForm
from service.views import order_forms, get_userlog_data
@ -63,7 +65,7 @@ class ConferenceBy(ConfFilterMixin, ConfSectionMixin, JitterCacheMixin, Metadata
class ConferenceByCountry(ConferenceBy):
model = Country
title1 = _(u'По странам')
title2 = _(u'Конференции мира по странам')
title2 = _(u'Коференции мира по странам')
catalog = 'country/'
stat_kind = 'country'
@ -84,7 +86,7 @@ class ConferenceByCountry(ConferenceBy):
class ConferenceByTag(ConferenceBy):
model = Tag
title1 = _(u'По тегам')
title2 = _(u'Конференции мира по тегам')
title2 = _(u'Коференции мира по тегам')
catalog = 'tag/'
stat_kind = 'tag'
@ -95,7 +97,7 @@ class ConferenceByTag(ConferenceBy):
class ConferenceByTheme(ConferenceBy):
model = Theme
title1 = _(u'По тематикам')
title2 = _(u'Конференции мира по тематикам')
title2 = _(u'Коференции мира по тематикам')
catalog = 'theme/'
stat_kind = 'theme'
@ -110,7 +112,7 @@ class ConferenceByTheme(ConferenceBy):
class ConferenceByCity(ConferenceBy):
model = City
title1 = _(u'По городам')
title2 = _(u'Конференции мира по городам')
title2 = _(u'Коференции мира по городам')
catalog = 'city/'
stat_kind = 'city'
@ -431,7 +433,7 @@ class ConferenceServiceView(FormMixin, DetailView):
return self.initial.copy()
class ConferenceDetail(ObjectStatMixin, JitterCacheMixin, MetadataMixin, DetailView):
class ConferenceDetail(ObjectStatMixin, CommentMixin, JitterCacheMixin, MetadataMixin, DetailView):
cache_range = settings.CACHE_RANGE
model = Conference
slug_field = 'url'
@ -587,6 +589,39 @@ def conference_add_calendar(request, id):
# return HttpResponse(json.dumps(args), content_type='application/json')
def add_note(request, slug):
args = {'success': False}
if request.user.is_authenticated():
if request.GET:
text = request.GET['note_text']
try:
conf = Conference.objects.get(url=slug)
except Conference.DoesNotExist:
raise Http404
ct = ContentType.objects.get_for_model(conf)
object_id = conf.id
user = User.objects.get(id=request.user.id)
if Note.objects.filter(user=user, content_type=ct, object_id=object_id).exists():
Note.objects.filter(user=user, content_type=ct, object_id=object_id).update(text=text)
else:
Note.objects.create(content_type=ct, object_id=object_id, user=user, text=text)
user.calendar.conferences.add(conf)
args['success'] = True
args['text'] = text
else:
args['not_authorized'] = True
args['success'] = True
return HttpResponse(json.dumps(args), content_type='application/json')
def send_to_organiser(request, slug):
exposition = get_object_or_404(Conference, url=slug)
mail_send = 'evm@expomap.ru'

@ -81,7 +81,7 @@ def country_change(request, url):
'logo': c.logo}
if c.capital:
data['capital'] = c.capital_id
data['capital'] = c.capital.id
#data from translated fields
for code, name in settings.LANGUAGES:

@ -133,7 +133,7 @@ class AreaManager(TranslationManager):
result = cache.get(key)
else:
model = self.model
result = set(model.objects.language().filter())
result = list(model.objects.language().filter())
#result.sort(key=lambda x: len(x.expos()), reverse=True)
cache.set(key, result, self.cache_time)
return result

@ -25,7 +25,7 @@ from emencia.django.newsletter.views.admin_views import (
RecommendsList,
RecommendsCreateorEdit,
RecommendsDelete,
export_contacts
)
urlpatterns = patterns('',
@ -57,7 +57,6 @@ urlpatterns = patterns('',
url(r'^mailinglist/all/$', MailingListView.as_view(), name='newsletters_mailinglist'),
url(r'^mailinglist/(?P<pk>\d+)/edit/', UpdateMailingList.as_view(), name='newsletters_mailinglist_update'),
url(r'^mailinglist/(?P<pk>\d+)/', DeleteMailingList.as_view(), name='newsletters_mailinglist_delete'),
url(r'^export_contacts/(?P<pk>\d+)/', export_contacts, name='newsletters_export_contacts'),
url(r'^mailinglist/filter/', CreateMailingList.as_view(), {'filter': True}, name='newsletters_mailinglist_create_filter'),
url(r'^mailinglist/', CreateMailingList.as_view(), name='newsletters_mailinglist_create'),

@ -107,12 +107,15 @@ class MailingSettingsForm(forms.ModelForm):
model = Contact
fields = [
'email', 'first_name', 'moscow', 'russia', 'r_cities', 'foreign',
'content_news', 'content_overview', 'content_articles',
'periodic', 'periodic_day', 'content_news', 'content_overview',
'content_articles',
]
widgets = {
'first_name': forms.TextInput(attrs={'placeholder': _(u'Ваше имя')}),
'moscow': forms.CheckboxInput(),
'foreign': forms.CheckboxInput(),
'periodic': forms.RadioSelect(),
'periodic_day': forms.RadioSelect(),
'content_news': forms.CheckboxInput(),
'content_overview': forms.CheckboxInput(),
'content_articles': forms.CheckboxInput(),
@ -434,6 +437,27 @@ class AbstractSubscribeForm(forms.ModelForm):
return Theme.objects.filter(id__in=themes)
class SubscribeAssideForm(AbstractSubscribeForm):
city = forms.CharField(
widget=forms.HiddenInput(attrs={'id': 'id_subscription_city', 'placeholder': _(u'Город')}),
required=False)
periodic = forms.ChoiceField(
choices=ContactSettings.PERIODIC_CHOICES, required=False,
widget=forms.Select(attrs={'placeholder': _(u'Периодичность'), 'id': 'id_subscription_periodic'}))
def __init__(self, *args, **kwargs):
super(SubscribeAssideForm, self).__init__(*args, **kwargs)
lang = translation.get_language()
self.fields['theme'] = forms.MultipleChoiceField(
choices=[(item.pk, get_by_lang(item, 'name', lang)) for item in SearchQuerySet().models(Theme).all()],
widget=forms.SelectMultiple(attrs={'placeholder': _(u'Тематики'), 'id': 'id_subscription_theme'}))
self.fields['country'] = forms.MultipleChoiceField(
choices=[(item.pk, get_by_lang(item, 'name', lang)) for item in SearchQuerySet().models(Country).all()],
required=False,
widget=forms.SelectMultiple(attrs={'placeholder': _(u'Страны'), 'id': 'id_subscription_country'}))
class SubscribeSettingsForm(AbstractSubscribeForm):
NA_ID = 12
ASIA_ID = 9

@ -412,6 +412,7 @@ class NewsLetterSender(object):
})
if self.announce:
# render template by default announce template
# template = get_template('newsletter/announce_template.html')
template = get_template('newsletter/AutomaticEmail_v2.html')
context.update(announce_context)
content = template.render(context)

@ -159,10 +159,10 @@ class Contact(models.Model):
from_users = models.BooleanField(default=False)
dailymailing = models.BooleanField(default=False)
moscow = models.BooleanField(_(u'Москва'), blank=True, default=True)
russia = models.BooleanField(_(u'Россия'), blank=True, default=True)
moscow = models.BooleanField(_(u'Москва'), blank=True, default=False)
russia = models.BooleanField(_(u'Россия'), blank=True, default=False)
r_cities = models.ManyToManyField('city.City', blank=True, null=True, verbose_name=_(u'Города России'))
foreign = models.BooleanField(_(u'Зарубеж'), blank=True, default=True)
foreign = models.BooleanField(_(u'Зарубеж'), blank=True, default=False)
f_countries = models.ManyToManyField('country.Country', blank=True, null=True, verbose_name=_(u'Зарубежные страны'))
area = models.ManyToManyField('country.Area', blank=True, null=True, verbose_name=_(u'Географическая зона'))
periodic = models.PositiveSmallIntegerField(_(u'Периодичность отправки'),
@ -170,7 +170,7 @@ class Contact(models.Model):
periodic_day = models.PositiveSmallIntegerField(_(u'День отправки'),
choices=PERIODIC_DAY_CHOICES, default=PERIODIC_DAY_CHOICES.WED)
content_news = models.BooleanField(_(u'Новости событий'), blank=True, default=True)
content_overview = models.BooleanField(_(u'Статьи для экспонентов'), blank=True, default=False)
content_overview = models.BooleanField(_(u'Статьи для экспонентов'), blank=True, default=True)
content_articles = models.BooleanField(_(u'Статьи для организаторов событий'), blank=True, default=True)
tags = models.ManyToManyField('theme.Tag', verbose_name=_(u'Теги'), blank=True, null=True)
themes = models.ManyToManyField('theme.Theme', blank=True, null=True, verbose_name=_(u'Тематики'))

@ -12,6 +12,7 @@ urlpatterns = patterns('',
url(r'^statistics/', include('emencia.django.newsletter.urls.statistics')),
url(r'^', include('emencia.django.newsletter.urls.newsletter')),
url(r'^test-letter/', TemplateView.as_view(template_name='client/newsletters/announce_template.html'), name='newsletter_test_letter'),
url(r'^activation/send/', TemplateView.as_view(template_name='client/newsletters/activation_send.html'),
name='subscription_activation_send'),
url(r'^activation/complete/', TemplateView.as_view(template_name='client/newsletters/activation_complete.html'),
@ -21,5 +22,7 @@ urlpatterns = patterns('',
name='newsletter_subscription_popup_validate'),
url(r'^partisipation/validate/$', 'emencia.django.newsletter.views.expo_views.landing_partisipation_validate',
name='landing_partisipation_validate'),
url(r'^subsribe/aside/$', 'emencia.django.newsletter.views.expo_views.subscribe_aside',
name='newsletter_subscription_aside'),
url(r'^$', SubscribeView.as_view(), name='newsletter_subscription'),
)

@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
import datetime
import csv
from django.conf import settings
from django.core.urlresolvers import reverse_lazy, reverse
@ -258,25 +257,6 @@ class UpdateMailingList(MailingListMixin, UpdateView):
pass
def export_contacts(request, pk):
contacts = Contact.objects.filter(
mailinglist_subscriber__pk=pk
).values(
'email', 'first_name', 'last_name'
)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="contacts.csv"'
writer = csv.writer(response)
for contact in contacts:
writer.writerow(
[contact['email'], contact['first_name'].encode('utf-8'), contact['last_name'].encode('utf-8')]
)
return response
class DailyMailSuccesUrlMixin(object):
def get_success_url(self):
if self.object.dailymail == True:

@ -2,18 +2,19 @@
import json
from django.core.urlresolvers import reverse_lazy
from django.db.models import Count
from django.views.generic import TemplateView, FormView
from django.http import HttpResponse
from django.shortcuts import redirect
from emencia.django.newsletter.forms import ContactForm
from emencia.django.newsletter.models import Contact, MailingList
from emencia.django.newsletter.forms import MailingSettingsForm
from emencia.django.newsletter.forms import (
SubscribeAssideForm, MailingSettingsForm
)
from accounts.models import User
from accounts.views import GetUserMixin
from functions.http import JsonResponse
from city.models import City
from theme.models import Theme
class SubscribeView(GetUserMixin, FormView):
@ -80,7 +81,6 @@ class SubscribeView(GetUserMixin, FormView):
ctx['object'] = self.object
ctx['r_cities'] = self.get_russian_cities()
ctx['checked_th'] = self.get_checked_th()
ctx['popular_themes'] = self.get_popular_themes()
if self.object is not None:
if self.request.GET.get('unsibscribe') and self.object.subscriber:
@ -105,17 +105,6 @@ class SubscribeView(GetUserMixin, FormView):
return self.object.themes.values_list('pk', flat=True)
return []
def get_popular_themes(self):
"""
:return: 7 популярных тем (где больше всего подписчиков)
"""
qs = Theme.objects.annotate(c=Count('contact'))\
.values('pk', 'c')\
.order_by('-c')[:7]
return Theme.objects.language()\
.filter(pk__in=[x['pk'] for x in qs])\
.order_by('name')
class ActivationView(TemplateView):
http_method_names = ['get']
@ -148,6 +137,34 @@ class ActivationView(TemplateView):
return ('subscription_activation_complete', (), {})
def subscribe_aside(request):
if request.POST:
response = {'success': False}
form = SubscribeAssideForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
try:
user = User.objects.get(username=email)
except User.DoesNotExist:
user = None
contact = Contact.objects.create_contact(email, user)
contact_setting = form.save(commit=False)
contact_setting.contact = contact
contact_setting.exponent_practicum = True
contact_setting.organiser_practicum = True
contact_setting.save()
form.save_m2m()
response['success'] = True
else:
errors = form.errors
if 'theme' in errors:
errors['id_subscription_theme'] = errors['theme']
response['errors'] = errors
return HttpResponse(json.dumps(response, indent=2), content_type='application/json')
else:
return HttpResponse('not form request')
def popup_validate(request):
response = {'success': False}
if request.GET:
@ -157,9 +174,7 @@ def popup_validate(request):
contact.send_activation()
response['success'] = True
response['redirect'] = True
response['redirect_url'] = str(
reverse_lazy('subscription_activation_send')
)
response['redirect_url'] = SubscribeView.success_url
else:
response['errors'] = form.errors

@ -314,11 +314,6 @@ class MainUpdateForm(forms.ModelForm):
class TopMixinForm(forms.ModelForm, FieldsetMixin):
cities = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput() ,required=False)
country = forms.MultipleChoiceField(
label=u'Страны',
choices=[[x.pk, x.name] for x in list(set(Country.objects.all()))],
required=False
)
class Meta:
model = Top
@ -361,9 +356,6 @@ class TopMixinForm(forms.ModelForm, FieldsetMixin):
old_save_m2m = self.save_m2m
def save_m2m():
print 111111111
print self
print self.cleaned_data['country']
old_save_m2m()
# This is where we actually link the pizza with toppings
top.theme.clear()

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
import json
import re
from datetime import date
from django.http import HttpResponse
from django.shortcuts import redirect, get_object_or_404, render
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
@ -101,15 +100,9 @@ def get_top(request):
'catalog': catalog,
'month': request.GET.get('month')}
tops = Top.cached.filter(fr__lte=date.today(), to__gte=date.today()).order_by('?')
events = get_top_events(tops, params, request)[:3]
ctx = {'objects': events}
if not events:
return HttpResponse('')
tops = Top.cached.all()
events = get_top_events(tops, params, request)
context = {'objects': events}
if catalog == 'places':
return render(
request, 'client/includes/exposition/expo_top_place.html', ctx
)
return render(request, 'client/includes/exposition/expo_top.html', ctx)
return render_to_response('client/includes/exposition/expo_top_place.html', context, context_instance=RequestContext(request))
return render_to_response('client/includes/exposition/expo_top.html', context, context_instance=RequestContext(request))

@ -42,7 +42,6 @@ class ExpositionCreateForm(forms.Form):
data_begin = forms.DateField(label=_(u'Дата начала'), input_formats=['%Y-%m-%d', '%d.%m.%Y'])
data_end = forms.DateField(label=_(u'Дата окончания'), input_formats=['%Y-%m-%d', '%d.%m.%Y'])
logo = forms.ImageField(label=_('Logo'), required=False)
main_image = forms.ImageField(label=_(u'Основное изображение'), required=False)
#organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
# choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
@ -175,8 +174,6 @@ class ExpositionCreateForm(forms.Form):
exposition.url = translit_with_separator(data['name_ru'].strip()).lower()
if data.get('logo'):
exposition.logo = data['logo']
if data.get('main_image'):
exposition.logo = data['main_image']
exposition.org = data['org']
exposition.data_begin = data['data_begin']

@ -5,6 +5,7 @@ from django.contrib.contenttypes import generic
from django.core.urlresolvers import reverse_lazy
from django.db import models
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from django.utils import translation
from django.utils.translation import ugettext as _
from events.models import TargetAudience
@ -44,7 +45,6 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
data_begin = models.DateField(verbose_name=_(u'Дата начала'), db_index=True)
data_end = models.DateField(verbose_name=_(u'Дата окончания'))
services = BitField(flags=flags, blank=True, null=True)
main_image = models.ImageField(verbose_name=_(u'Основное изображение'), upload_to='exposition/main_images/', blank=True, null=True)
# relations
creator = models.ForeignKey('accounts.User', verbose_name=_(u'Создатель'), on_delete=models.SET_NULL,
related_name='exposition_creator', blank=True, null=True)
@ -115,6 +115,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
)
files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id')
note = generic.GenericRelation('note.Note', content_type_field='content_type', object_id_field='object_id')
#about
periodic = models.FloatField(verbose_name=_(u'Переодичность'), blank=True, null=True)
@ -171,6 +172,19 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def get_price(self):
return self.price_day or self.price_all
def get_services(self):
return self.get_services_detail()
# country_ids = [item for item, bool in self.country.services if bool==True]
# ids = [item for item, bool in self.services if bool==True]
# qs = Service.objects.language().filter(Q(Q(url__in=country_ids) & Q(type=Service.type.expo)) | Q(url__in=ids))
# return list(qs)
def get_services_detail(self):
excluded = ['visit']
return super(Exposition, self).get_services_detail(excluded, Service.type.expo)
def get_parent(self):
return {}
@ -189,6 +203,13 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
tags = ' '.join([' '.join(tag.get_all_names()) for tag in self.tag.all()])
return names + ' ' + titles + ' ' + themes + ' ' + tags
def get_note_by_user(self, user_id):
note = self.note.filter(user__id=user_id)
try:
return note.get().text
except:
return ''
def upload_photo_url(self):
return '/admin/exposition/upload-photo/%s/' % self.id
@ -219,6 +240,9 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def get_visit_url(self):
return '/exposition-visit/%s/'%self.id
def get_note_url(self):
return '/expo/add-note/%s/'%self.url
def get_timetables_days(self):
tables = list(self.business_program.all())
days = []
@ -241,12 +265,6 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def get_objectstat_views(self):
return sum(self.objectstats_set.all().values_list('value', flat=True))
def get_data_begin_month(self):
return self.data_begin.month
def get_data_end_month(self):
return self.data_end.month
class Statistic(TranslatableModel):
exposition = models.ForeignKey(Exposition, related_name='statistic')

@ -24,6 +24,7 @@ from .views import (
)
urlpatterns = patterns('',
url(r'^expo/add-note/(?P<slug>.*)/$', 'exposition.views.add_note'),
url(r'^exposition-add-calendar/(?P<id>\d+)/$', 'exposition.views.exposition_add_calendar'),
# url(r'^exposition-visit/(?P<id>\d+)/$', 'exposition.views.exposition_visit'),
# search
@ -77,7 +78,7 @@ urlpatterns = patterns('',
# expo additional pages
url(r'^expo/(?P<slug>[^/]*)/send_to_organiser/$', 'exposition.views.send_to_organiser'),
url(r'^expo/(?P<slug>[^/]*)/statistic/$', ExpositionStatistic.as_view(), {'meta_id':60}),
url(r'^expo/(?P<slug>[^/]*)/price/$', ExpositionPrice.as_view(), {'meta_id':61}, name='expo_price'),
url(r'^expo/(?P<slug>[^/]*)/price/$', ExpositionPrice.as_view(), {'meta_id':61}),
url(r'^expo/(?P<slug>[^/]*)/program/$', ExpositionProgramme.as_view(), {'meta_id':62}),
url(r'^expo/(?P<slug>[^/]*)/visitors/page/(?P<page>\d+)/$', ExpoVisitors.as_view(), {'meta_id':64}),
url(r'^expo/(?P<slug>[^/]*)/visitors/$', ExpoVisitors.as_view(), {'meta_id':64}),
@ -87,7 +88,7 @@ urlpatterns = patterns('',
url(r'^expo/(?P<slug>[^/]*)/members/$', ExpoMembers.as_view(), {'meta_id':63}),
url(r'^expo/(?P<slug>[^/]*)/service/thanks/', ExpositionThankView.as_view()),
url(r'^expo/(?P<slug>[^/]*)/service/visit/', 'exposition.views.visit_redirect'),
url(r'^expo/(?P<slug>[^/]*)/service/(?P<service_url>[^/]*)/', ExpositionServiceView.as_view(), name='expo_service'),
url(r'^expo/(?P<slug>[^/]*)/service/(?P<service_url>[^/]*)/', ExpositionServiceView.as_view()),
# expo list
url(r'^expo/(?P<year>\d+)/(?P<month>[^/]*)/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':4}),
url(r'^expo/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':3}),

@ -9,7 +9,6 @@ from country.models import Country
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.mail import EmailMessage
from django.db.models import Q
from django.http import (
Http404,
HttpResponse,
@ -30,6 +29,7 @@ from functions.views_help import get_side_items
from meta.views import MetadataMixin
from models import Exposition
from note.models import Note
from service.models import Service
from service.order_forms import AdvertiseForm
from service.views import order_forms, get_userlog_data
@ -648,6 +648,38 @@ class ExpoPhotoView(MetadataMixin, ListView):
return context
def add_note(request, slug):
args = {'success': False}
if request.user.is_authenticated():
if request.GET:
text = request.GET['note_text']
try:
e = Exposition.objects.get(url=slug)
except Exposition.DoesNotExist:
raise Http404
ct = ContentType.objects.get_for_model(e)
object_id = e.id
user = User.objects.get(id=request.user.id)
if Note.objects.filter(user=user, content_type=ct, object_id=object_id).exists():
Note.objects.filter(user=user, content_type=ct, object_id=object_id).update(text=text)
else:
Note.objects.create(content_type=ct, object_id=object_id, user=user, text=text)
user.calendar.expositions.add(e)
args['success'] = True
args['text'] = text
else:
args['not_authorized'] = True
args['success'] = True
return HttpResponse(json.dumps(args), content_type='application/json')
def send_to_organiser(request, slug):
exposition = get_object_or_404(Exposition, url=slug)
mail_send = 'evm@expomap.ru'

@ -569,7 +569,6 @@ class ReverseOrderMixin(ContextMixin):
if isinstance(children, tuple):
if children[0].startswith('data_begin'):
continue
childrens.append(children)
elif isinstance(children, SearchNode):
node_childrens = list(filter(lambda x: not x[0].startswith('data_begin'), children.children))
if node_childrens:
@ -578,8 +577,7 @@ class ReverseOrderMixin(ContextMixin):
qs.query.query_filter.children = childrens
self.extra_ctx['events_reversed'] = True
qs.query.clear_order_by()
qs = qs.filter(data_begin__lte=datetime.now()).order_by('-data_begin')
return qs
return qs.filter(data_begin__lte=datetime.now()).order_by('-data_begin')
def get_queryset(self):
qs = super(ReverseOrderMixin, self).get_queryset()

@ -5,7 +5,6 @@ from itertools import chain
from pytils.dt import ru_strftime
import datetime
from datetime import date
from dateutil.relativedelta import relativedelta
from django.conf import settings
@ -140,7 +139,7 @@ class EventMixin(object):
exclude_pks)
def get_nearest_events(self):
if getattr(self, '_nearest_events', None) is None or self._nearest_events == []:
if getattr(self, '_nearest_events', None) is None:
model = self.__class__
result = []
tags = list(self.tag.all().values_list('pk', flat=True))
@ -154,59 +153,6 @@ class EventMixin(object):
self._nearest_events = result[:3]
return self._nearest_events
def get_recommend_expos_incl(self, _qs, tags, themes, exclude=None):
now = datetime.datetime.now()
month = now + relativedelta(months=1)
month2 = now + relativedelta(months=2)
exclude_pks = exclude or set([self.pk])
events_m2 = []
events_m = []
events = []
for params in [{'tag__in': tags}, {'theme__in': themes}]:
qs = _qs.filter(**params).order_by('data_begin').distinct()
events_m2.extend(list(qs.filter(data_begin__gte=month2).exclude(pk__in=exclude_pks)[3:5]))
exclude_pks.update([x.pk for x in events_m2])
events_m.extend(list(qs.filter(data_begin__gte=month).exclude(pk__in=exclude_pks)[3:5]))
exclude_pks.update([x.pk for x in events_m])
events.extend(list(qs.filter(data_begin__gte=now).exclude(pk__in=exclude_pks)[3:5]))
exclude_pks.update([x.pk for x in events])
return (list(sorted(list(chain(*zip(*[x for x in [events_m2, events_m, events] if x])))[3:5], key=lambda x: x.data_begin)), exclude_pks)
def get_recommend_expos(self):
if getattr(self, '_recommend_expos', None) is None or self._recommend_expos == []:
model = self.__class__
result = []
tags = list(self.tag.all().values_list('pk', flat=True))
themes = list(self.theme.all().values_list('pk', flat=True))
top_expos = list(
model.objects.filter(
top__isnull=False,
theme__in=themes,
top__fr__lte=date.today(),
top__to__gte=date.today()
).order_by('?')
)
paid_expos = list(
model.objects.filter(
paid_new__isnull=False,
theme__in=themes,
top__fr__lte=date.today(),
top__to__gte=date.today()
).order_by('?')
)
qs = model.objects.language().filter(country_id=self.country_id)
result, exclude = self.get_recommend_expos_incl(qs, tags, themes)
if len(result) > 5:
qs = model.objects.language()
r, e = self.get_recommend_expos_incl(qs, tags, themes, exclude)
result += r
result = list(set(top_expos + paid_expos + result))
if len(result) < 5:
self._recommend_expos = result[:2]
else:
self._recommend_expos = result[3:5]
return self._recommend_expos
def get_nearest_events_url(self):
url_params = QueryDict('', mutable=True)
url_params.update({
@ -299,6 +245,38 @@ class EventMixin(object):
def cancel(self):
self.canceled_by_administrator = True
def get_services(self):
country_ids = [item for item, bool in self.country.services if bool==True]
ids = [item for item, bool in self.services if bool==True and item in country_ids]
return list(Service.objects.language().filter(url__in=ids).order_by('sort'))
def get_services_detail(self, excluded, _type):
if not isinstance(getattr(self, '_get_services_detail', None), list):
# excluded = ['visit', 'tickets']
# country_ids = [item for item, bool in self.country.services if bool==True]
services = [item for item, bool in self.services if bool]
qs = Service.objects.language()
if excluded is not None:
qs = qs.exclude(url__in=excluded)
# qs = qs.filter(Q(Q(url__in=country_ids) & Q(type=_type)) | Q(url__in=ids))
qs = qs.filter(url__in=services)
self._get_services_detail = list(qs)
# import pdb; pdb.set_trace()
#двигаем билеты сразу за переводом
if excluded is None or 'tickets' not in excluded:
translator_idx = tickets = None
for idx, service in enumerate(self._get_services_detail):
if service.url == 'translator':
translator_idx = idx + 1
elif service.url == 'tickets':
tickets = service
if tickets and translator_idx:
self._get_services_detail.remove(tickets)
self._get_services_detail.insert(translator_idx, tickets)
return self._get_services_detail
def duration_days(self, month=None):
if not month:
d = self.data_end - self.data_begin

@ -45,7 +45,7 @@ class ExportView(FormView):
def form_valid(self, form):
workbook = form.export()
if workbook is not None:
if workbook:
f_name = form.get_fname()
else:
messages.error(self.request, _('No objects found'))
@ -55,32 +55,32 @@ class ExportView(FormView):
class ExportTheme(ExportView):
form_class = ExportThemeForm
success_url = '/admin/export-theme/'
success_url = '/admin/export-theme'
class ExportTag(ExportView):
form_class = ExportTagForm
success_url = '/admin/export-tag/'
success_url = '/admin/export-tag'
class ExportUser(ExportView):
form_class = ExportUserForm
success_url = '/admin/export-user/'
success_url = '/admin/export-user'
class ExportCompany(ExportView):
form_class = ExportCompanyForm
success_url = '/admin/export-company/'
success_url = '/admin/export-company'
class ExportPlaceConference(ExportView):
form_class = ExportPlaceConferenceForm
success_url = '/admin/export-place_conference/'
success_url = '/admin/export-place_conference'
class ExportPlaceExposition(ExportView):
form_class = ExportPlaceExpositionForm
success_url = '/admin/export-place_exposition/'
success_url = '/admin/export-place_exposition'
class ExportBlog(ExportView):
@ -120,7 +120,7 @@ class ImportPlaceExposition(FormView):
class ImportPlaceConference(ImportView):
form_class = ImportPlaceConferenceForm
success_url = '/admin/import-place_conference/'
success_url = '/admin/import-place_conference'
def form_valid(self, form):
errors = form.save_file_debug()
@ -129,12 +129,12 @@ class ImportPlaceConference(ImportView):
class ImportTheme(ImportView):
form_class = ImportThemeForm
success_url = '/admin/import-theme/'
success_url = '/admin/import-theme'
class ImportTag(ImportView):
form_class = ImportTagForm
success_url = '/admin/import-tag/'
success_url = '/admin/import-tag'
@ -143,7 +143,7 @@ class ImportTag(ImportView):
class ExportEvent(ExportView):
form_class = ExportEventForm
template_name = 'export_event.html'
success_url = '/admin/export-event/'
success_url = '/admin/export-event'
class LogList(ListView):

@ -59,7 +59,6 @@ def get_periodic(value):
def get_quality(value, field):
# print value, field
flags = {u'UFI': 'ufi', u'РСВЯ': 'rsva', u'EXPORATING': 'exporating'}
v = flags.get(field)
if v:

@ -174,8 +174,8 @@ class ExportEventForm(forms.Form):
language = forms.ChoiceField(label=_(u'Выберите язык'), choices=languages)
date_from = forms.DateField(label=_(u'С'), input_formats=settings.CLIENT_DATE_FORMAT)
date_to = forms.DateField(label=_(u'До'), input_formats=settings.CLIENT_DATE_FORMAT)
theme = forms.ModelMultipleChoiceField(label=_(u'Направление'), queryset=Theme.objects.language().all(), required=False)
country = forms.ModelMultipleChoiceField(label=_(u'Страны'), queryset=Country.objects.language().all(), required=False)
theme = forms.ModelMultipleChoiceField(label=_(u'Направление'), queryset=Theme.objects.all(), required=False)
country = forms.ModelMultipleChoiceField(label=_(u'Страны'), queryset=Country.objects.all(), required=False)
def export(self):
data = self.cleaned_data
@ -185,17 +185,20 @@ class ExportEventForm(forms.Form):
lang, date_from, date_to, co, th = data['language'], data['date_from'], data['date_to'], data['country'], data['theme']
# get objects
qs = model.objects.language(lang).filter(data_begin__gte=date_from, data_begin__lte=date_to).select_related('place', 'country', 'city').prefetch_related('theme', 'tag', 'organiser', 'audience').distinct()
qs = model.objects.language(lang).filter(data_begin__range=[date_from, date_to])
if co:
qs = qs.filter(country__in=co)
if th:
qs = qs.filter(theme__in=th)
if not qs.exists():
# not found any objects
objects = list(qs.distinct())
if not objects:
# not found any objects
return None
workbook = xlwt.Workbook(encoding='utf8')
workbook = xlwt.Workbook(encoding = 'utf8')
# new tab
worksheet = workbook.add_sheet('My Worksheet')
@ -207,7 +210,7 @@ class ExportEventForm(forms.Form):
# Create the Style
style.font = font
for row, object in enumerate(qs):
for row, object in enumerate(objects):
# column number
col = 0
@ -219,7 +222,7 @@ class ExportEventForm(forms.Form):
continue
if row == 0:
# first iteration. set names. set columns width
# first iteration. set names. set columns width
worksheet.write(0, col, field.get('verbose_name', 'default'), style)
worksheet.col(col).width = field.get('width', 3333)
if field['name'] != 'quality_label':

@ -0,0 +1,13 @@
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Note(models.Model):
content_type = models.ForeignKey(ContentType, null=True)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk")
user = models.ForeignKey('accounts.User')
text = models.TextField(verbose_name='Note')

@ -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 @@
# Create your views here.

@ -237,6 +237,7 @@ class PlaceExpositionListView(MetadataMixin, ListView):
места, по ссылке "Все события"
"""
template_name = 'client/place/place_exposition_list.html'
# cache_range = settings.CACHE_RANGE
def get_object(self):
slug = self.kwargs.get('slug')

@ -6,7 +6,7 @@ from django.db.models.signals import post_save
from django.utils.translation import ugettext as _
from functions.custom_fields import EnumField
from functions.signal_handlers import post_save_handler
from hvad.models import TranslatableModel, TranslatedFields
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
CURENCIES = ('', 'USD', 'RUB', 'EUR')

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from django.conf.urls import patterns, include, url
from views import ServiceView, CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \
ParticipationListView, RemoteListView,TicketsListView, Thanks

@ -2,17 +2,23 @@
import json
from itertools import chain
from django.http import HttpResponse
from django.views.generic import ListView, FormView, TemplateView
from django.shortcuts import get_object_or_404
from django.http import Http404
from django.http import HttpResponseRedirect, HttpResponse
from haystack.query import EmptySearchQuerySet
from meta.views import MetadataMixin
from accounts.models import UserLog
from exposition.models import Exposition
from conference.models import Conference
from functions.custom_views import ExpoListView
from models import Service
from order_forms import TranslationForm, CatalogForm, VisitForm, RemoteForm, ParticipationForm, TicketsForm,\
AdvertiseForm, BuildStandForm
from service.models import CallBack, Visit, Translation, Advertising, Participation, Remote, Tickets
#from functions.search_forms import CompanySearchForm
order_forms = {'translator': TranslationForm, 'catalog': CatalogForm, 'participation': ParticipationForm,
@ -115,12 +121,12 @@ def advertise(request, catalog=None, event_url=None):
raise HttpResponse('not ajax')
from service.models import CallBack, Visit, Translation, Advertising, Participation, Remote, Tickets
class AbstractOrderListView(ListView):
template_name = 'c_admin/service/order_list.html'
paginate_by = 20
class CallBackListView(AbstractOrderListView):
model = CallBack
@ -132,19 +138,15 @@ class VisitListView(AbstractOrderListView):
class TranslationListView(AbstractOrderListView):
model = Translation
class AdvertisingListView(AbstractOrderListView):
model = Advertising
class ParticipationListView(AbstractOrderListView):
model = Participation
class RemoteListView(AbstractOrderListView):
model = Remote
class TicketsListView(AbstractOrderListView):
model = Tickets

@ -237,6 +237,13 @@ def without_page(value):
result = '/'.join(l[:l.index('page')])+'/'
return result
@register.filter
def note_by_user(obj, user):
if obj and user.is_authenticated():
return obj.get_note_by_user(user.id)
return ''
@register.filter
def isdigit(value):
@ -353,4 +360,4 @@ def str_to_int(value):
try:
return int(value)
except ValueError:
return value
return value

@ -14,11 +14,7 @@ SITE_ROOT = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0]
# Adding modules directory to python path
sys.path.insert(0, os.path.join(SITE_ROOT, 'apps'))
DEBUG = False
if os.environ.get('DEBUG') == 'True':
DEBUG = True
LOCAL_DEV = os.environ.get('DEBUG', False)
DEBUG = True
ADMINS = (
@ -30,10 +26,10 @@ MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('MYSQL_DATABASE'),
'USER': os.environ.get('MYSQL_USER'),
'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
'HOST': os.environ.get('MYSQL_HOST'),
'NAME': 'expomap',
'USER': 'kotzilla',
'PASSWORD': 'qazedc',
'HOST': '',
'PORT': '',
'TEST_CHARSET': 'utf8',
}
@ -43,7 +39,7 @@ DATABASES = {
CACHES = {
"default": {
"BACKEND": "redis_cache.RedisCache",
"LOCATION": "%s:%s" % (os.environ.get('REDIS_HOST'), os.environ.get('REDIS_PORT')),
"LOCATION": "localhost:6379",
'OPTIONS': {
'CLIENT_CLASS': 'redis_cache.client.DefaultClient',
}
@ -55,7 +51,7 @@ SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = ['*']
ALLOWED_HOSTS = ['expomap.ru']
DEFAULT_HTTP_SCHEME = 'https'
# Local time zone for this installation. Choices can be found here:
@ -228,9 +224,7 @@ LOGIN_URL='/'
#registration info
ACCOUNT_ACTIVATION_DAYS=2
# mail settings
EMAIL_BACKEND = os.environ.get(
'EMAIL_BACKEND', 'django.core.mail.backends.smtp.EmailBackend'
)
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'mail.expomap.ru'
EMAIL_HOST_USER = 'noreply@expomap.ru'
EMAIL_HOST_PASSWORD = 'Very$tr0ngPa$$word'
@ -357,6 +351,7 @@ INSTALLED_APPS = (
'emencia.django.newsletter',
'accounts',
'article',
'comments',
'city',
'company',
'conference',
@ -368,6 +363,7 @@ INSTALLED_APPS = (
'file',
'import_xls',
'news',
'note',
'organiser',
'place_conference',
'place_exposition',
@ -403,7 +399,6 @@ INSTALLED_APPS = (
'rosetta',
'widget_tweaks',
'captcha',
'raven.contrib.django.raven_compat',
)
CRONJOBS = [
@ -438,9 +433,8 @@ PYMORPHY_DICTS = {
# search backend
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': os.environ.get('SEARCH_ENGINE'),
'URL': os.environ.get('SEARCH_URI'),
'INDEX_NAME': os.environ.get('SEARCH_INDEX_NAME'),
'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
'URL': 'http://localhost:8983/solr'
},
}
@ -510,54 +504,9 @@ RECAPTCHA_PUBLIC_KEY = '6LffshgUAAAAALQSBrZusJgfqNsREZbiL9ZT4Jlv'
RECAPTCHA_PRIVATE_KEY = '6LffshgUAAAAAF7zZnMbONB36CmOueKKD097UvMg'
NOCAPTCHA = True
if not os.path.exists(MEDIA_ROOT + '/upload'):
os.makedirs(MEDIA_ROOT + '/upload')
# debug_toolbar settings
DEBUG_TOOLBAR_PATCH_SETTINGS = False
INTERNAL_IPS = ('127.0.0.1',)
JQUERY_URL = os.path.join(SITE_ROOT, 'static/client/js/jquery-ui-1.10.4.custom.min.js'),
DEBUG_TOOLBAR_PANELS = [
#'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
]
def show_toolbar(request):
if request.is_ajax():
return False
return True
DEBUG_TOOLBAR_CONFIG = {
'SHOW_TOOLBAR_CALLBACK': 'proj.settings.show_toolbar',
}
try:
from proj.local import *
except ImportError, e:
pass
if DEBUG:
MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
INSTALLED_APPS += (
'debug_toolbar',
)
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
THUMBNAIL_DEBUG = True
if os.environ.get('DEBUG') == 'False':
INSTALLED_APPS += (
'raven.contrib.django.raven_compat',
)
RAVEN_CONFIG = {
'dsn': 'http://474617c96350412d80735900c6717b9a:330285c9034947a181cbae8b52bb15d8@88.198.17.35:9000/3',
}
THUMBNAIL_DEBUG = DEBUG

@ -9,7 +9,6 @@ from core.simple_index_view import (
from django.conf import settings
from django.conf.urls import include, patterns, url
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.sitemaps import views
from django.views.generic.base import TemplateView
@ -69,7 +68,6 @@ urlpatterns += solid_i18n_patterns('',
url(r'^rss/', include('core.urls')),
url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}),
url(r'^admin/', include('proj.admin_urls')),
url(r'^djadmin/', include(admin.site.urls)),
url(r'^sitemap\.xml$', views.index, {'sitemaps': sitemaps}),
url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap, {'sitemaps': sitemaps}),

@ -16,6 +16,8 @@ from theme.models import Theme
from article.models import Article
from exposition.models import Exposition
from conference.models import Conference
from emencia.django.newsletter.forms import SubscribeAssideForm
from django.db.models.loading import get_model
@ -38,7 +40,7 @@ def expo_context(request):
'main_page_blogs': Article.objects.main_page_blogs(),
'blogs': Article.objects.every_page_blogs(),
'news_list': Article.objects.main_page_news(), 'sng_countries': settings.SNG_COUNTRIES,
'seo_text': add_seo(request),
'seo_text': add_seo(request), 'announce_subscribe': SubscribeAssideForm(),
'NO_EXTERNAL_JS': getattr(settings, 'NO_EXTERNAL_JS', False),
'NO_BANNERS': getattr(settings, 'NO_BANNERS', False),
'SUBSCRIBERS_COUNT': get_subscribers_count(),

@ -1,6 +1,6 @@
awesome-slugify==1.6.5
awesome-slugify==1.6
BeautifulSoup==3.2.1
beautifulsoup4==4.6.0
beautifulsoup4==4.4.0
chainmap==1.0.2
chardet==2.3.0
contextlib2==0.5.4
@ -14,7 +14,7 @@ django-debug-toolbar==1.2.1
django-haystack==2.3.2
django-hvad==1.2.2
django-model-utils==2.2
django-modeltranslation==0.12.1
django-modeltranslation==0.12
django-recaptcha==1.2.1
django-redis==4.0.0
django-redis-cache==0.13.1
@ -39,7 +39,6 @@ pandas==0.19.2
phonenumbers==6.0.0
Pillow==3.4.2
polib==1.0.8
pyelasticsearch==1.4
pylibmc==1.2.3
pymorphy==0.5.6
pymorphy2==0.8
@ -51,9 +50,9 @@ python-memcached==1.48
python-openid==2.2.5
python-social-auth==0.1.23
pytils==0.3
pytz==2017.2
raven==6.1.0
redis==2.10.5
pytz==2016.10
raven==5.32.0
redis==2.10.1
redis-collections==0.4.2
regex==2014.11.14
requests==2.2.1
@ -67,8 +66,8 @@ South==1.0.2
sqlparse==0.1.11
suds==0.4
Unidecode==0.4.16
uWSGI==2.0.15
uWSGI==2.0.14
vobject==0.8.2
wstools==0.4.3
xlrd==1.0.0
xlwt==1.2.0
xlrd==0.9.2
xlwt==0.7.5

@ -71,7 +71,7 @@
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords_en.txt"
words="lang/stopwords_en.txt"
enablePositionIncrements="true"
/>
<filter class="solr.LowerCaseFilterFactory"/>
@ -87,7 +87,7 @@
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords_en.txt"
words="lang/stopwords_en.txt"
enablePositionIncrements="true"
/>
<filter class="solr.LowerCaseFilterFactory"/>

@ -1020,6 +1020,23 @@ function placeInput(width){
$scrollContainer.mCustomScrollbar(customScrollOptions);
});
/* Открыть диалог подписки на нужной вкладке */
$('#subscribe-sm').each(function () {
var $container = $(this);
var $links = $container.find('a');
$links.on('click', function () {
var $link = $(this);
var index = $links.index(this);
var popupSubscribe = $('#pw-subscribe');
$.fancybox(popupSubscribe, fbPopupOptions);
var $tabs = popupSubscribe.find('ul.tabs > li');
$tabs.eq(index).trigger('click');
return false;
});
});
/* Обработка поведения вкладок */
$("ul.tabs > li").on('click', function () {
var $curTab = $(this);

@ -2678,9 +2678,6 @@ a.icon-big-ical {
margin-top: 30px;
display: block
}
.modals .pwf-buttons-line button + button {
margin-left: 5px;
}
.pw-form .pwf-buttons-line>div,
.pw-form .pwf-line>div {
display: inline-block;
@ -5389,13 +5386,6 @@ dl.add-info dd ul li {
}
.i-tags.grey,.i-tags.grey a{
color: #a2a2a2;
font-size: 11px;
line-height: 16px;
}
.i-tags.grey a{
display: inline-block;
line-height: 11px;
margin-bottom: 5px;
}
.i-tags.grey a:hover{
color: #FF6600;
@ -5635,25 +5625,7 @@ dl.add-info dd ul li {
width: 11px;
height: 13px;
background: url(../img/sprites.png) -211px 0 no-repeat;
margin: -1px 10px 0 0;
}
.i-event-additional .e-docs a.translator:before {
width: 15px;
height: 15px;
background: url(../img/sprites.png) -427px -130px no-repeat;
margin-left: -2px;
}
.i-event-additional .e-docs a.car_rent:before {
width: 15px;
height: 11px;
background: url(../img/sprites.png) -427px -164px no-repeat;
margin-left: -2px;
}
.i-event-additional .e-docs a.find_hotel:before {
width: 15px;
height: 15px;
background: url(../img/sprites.png) -427px -147px no-repeat;
margin-left: -2px;
margin: -1px 5px 0 0
}
.i-event-additional .add-info {
width: 70%;
@ -5934,18 +5906,6 @@ dl.add-info dd ul li {
.h-booking a.more {
font-size: 11px
}
.h-booking ul.flexing_for_one_row {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-justify-content: space-around;
-ms-flex-pack: distribute;
justify-content: space-around;
}
.h-booking ul {
margin: 0;
padding: 0 0 0 4px;
@ -14510,360 +14470,4 @@ h1 .preview_toggle:hover{
text-decoration: none;
float: right;
margin-top: -5px;
}
/*937x244*/
.exposition_main_image {
height: 244px;
background: url('../img/expo_default.png') no-repeat center;
background-size: cover;
border-radius: 3px;
margin-bottom: 35px;
}
.exposition_main_image .buttons {
width: 345px;
height: 100%;
background-color: rgba(255,255,255,.9);
border-radius: 3px;
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-webkit-align-items: center;
-moz-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.exposition_main_image .buttons a {
line-height: 43px;
width: 260px;
height: 43px;
text-align: center;
color: #fff;
text-decoration: none;
text-transform: uppercase;
border-radius: 5px;
font-family: dindisplay_pro, sans-serif;
font-weight: bold;
font-size: 16px;
text-shadow: 2px 2px 3px rgba(0,0,0,.16);
-webkit-transition: line-height .3s;
-o-transition: line-height .3s;
transition: line-height .3s;
}
.exposition_main_image .buttons a:hover {
line-height: 45px;
box-shadow: inset 0 0 2px rgba(0,0,0,.16);
-webkit-transition: line-height .3s;
-o-transition: line-height .3s;
transition: line-height .3s;
}
.exposition_main_image .buttons a.orange {
background-color: #ff6600;
}
.exposition_main_image .buttons a.green {
background-color: #87c525;
}
.exposition_main_image .buttons a.pink {
background-color: #cc486d;
}
.exposition_main_image .buttons a + a {
margin-top:16px;
}
.i-tags.grey a {
color: #a2a2a2;
}
.expo_description {
font-family: Arial, sans-serif;
color: #333333;
font-size: 16px;
line-height: 28px;
}
.expo_description:after {
content: '';
display: block;
clear: both;
}
.expo_description h2 {
font-family: dindisplay_pro, sans-serif;
font-weight: 400;
font-size: 38px;
}
.expo_description h1,
.expo_description h3,
.expo_description h4,
.expo_description h5,
.expo_description h6 {
font-family: dindisplay_pro, sans-serif;
}
.right_grey_block {
-moz-box-sizing: border-box;
box-sizing: border-box;
background-color: #f2f2f0;
padding: 20px;
border-radius: 5px;
width: 260px;
float: right;
margin: 0 0 10px 40px;
}
.right_grey_block + .right_grey_block {
margin-top: 30px;
}
.expo_description_right {
float: right;
margin: 0 0 40px 40px;
}
.right_grey_block h4{
margin-top: 0;
text-align: center;
font-family: dindisplay_pro, sans-serif;
color: #333333;
font-size: 26px;
font-weight: 100;
margin-bottom: 17px;
}
.exposition_members {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1;
-webkit-flex: 1;
-moz-box-flex: 1;
-ms-flex: 1;
flex: 1;
font-family: dindisplay_pro, sans-serif;
}
.exposition_members > div {
width: 50%;
text-align: center;
padding: 7px;
font-size: 18px;
}
.exposition_members > div + div {
border-left: 1px dotted #cccccc;
}
.exposition_members h5 {
margin-top: 0;
margin-bottom: 15px;
font-weight: 100;
font-size: 18px;
}
.exposition_members span {
font-weight: bold;
}
.right_grey_block .logos {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1;
-webkit-flex: 1;
-moz-box-flex: 1;
-ms-flex: 1;
flex: 1;
-webkit-box-pack: center;
-webkit-justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
padding-top: 19px;
}
.right_grey_block .logos .img_wrapper {
width: 46px;
height: 46px;
background-color: #fff;
border-radius: 5px;
box-shadow: 1px 1px 2px rgba(0,0,0,.2);
line-height: 45px;
margin: 0 7px;
text-align: center;
}
.right_grey_block .logos .img_wrapper img{
width: 30px;
height: auto;
display: inline-block;
vertical-align: middle;
}
/*.exposition_participants {
padding-top: 30px;
}
.exposition_participants:after {
content: '';
display: block;
clear: both;
}
.exposition_participants > h3 {
font-family: dindisplay_pro, sans-serif;
font-size: 22px;
font-weight: 500;
color: #333;
}
.exposition_participants ul,
.exposition_participants p{
font-size: 14px;
color: #333333;
}
.exposition_participants li {
margin-bottom: 20px;
}*/
.recommended_expositions .recommended {
padding: 12px 0;
font-family: dindisplay_pro, sans-serif;
}
.recommended_expositions .recommended a{
font-size: 24px;
text-decoration: none;
color: #FF6600;
}
.recommended_expositions .recommended p{
margin: 5px 0 0 0;
font-size: 16px;
font-weight: 100;
color: #333333;
}
.recommended_expositions .recommended + .recommended {
border-top: 1px dotted #ccc;
}
.conference_slider h2 a {
text-decoration: none;
color: #333;
-webkit-transition: color .3s;
-o-transition: color .3s;
transition: color .3s;
}
.conference_slider h2 a:hover {
color: #ff6600;
-webkit-transition: color .3s;
-o-transition: color .3s;
transition: color .3s;
}
#recommended_expositions,
#expo_statistics {
display: none;
}
.exposition_news {
padding-top: 35px;
}
.exposition_news .sect-title span {
font-size: 26px;
font-weight: 500;
color: #333;
}
.cli-m-buttons .new_subribe_btn {
float: none;
}
/*Hotels: 4 items for row*/
/*.exposition_booking_block .h-booking ul li:last-child {*/
/*margin-right: 0;*/
/*}*/
.exposition_booking_block .h-booking .sect-title a {
color: #40bbea;
}
.exposition_booking_block .h-booking .sect-title a:hover {
color: #1d447d;
}
.exposition_additional {
padding-left: 30px;
}
.exposition_additional:after {
content: '';
display: block;
clear: both;
}
.exposition_additional .sect-title {
font-size: 22px;
color: #333333;
font-weight: 600;
}
.exposition_additional .add-info {
font-size: 14px;
color: #808080;
line-height: 22px;
}
.exposition_additional .add-info a {
color: #808080;
text-decoration: underline;
}
.exposition_additional dl.add-info dd,
.exposition_additional dl.add-info dt {
margin-bottom: 20px;
}
.exposition_additional .e-docs {
padding-top: 22px;
}
.exposition_additional .e-docs li{
margin-bottom: 13px;
}
.exposition_nearest .sect-title {
font-size: 23px;
font-weight: 500;
}
}

File diff suppressed because one or more lines are too long

@ -1877,6 +1877,18 @@
<a class="button blue icon-calendar addcalendar " href="/exposition-add-calendar/3391/">В расписание</a>
<div class="note-wrap">
<a class="button green icon-note note-button" href="/expo/add-note//">заметка</a>
<div class="note-overlay">
<form action="">
<textarea name="note_text" class="note-text"> </textarea>
</form>
</div>
</div>
</div>

@ -442,6 +442,14 @@
<a class="button icon-check visit" href="">Я планирую посетить</a>
<a style="display:none;" class="button icon-check unvisit" href="">Не планирую посещать</a>
<a class="button blue icon-calendar addcalendar " href="/conference-add-calendar/498/">В расписание</a>
<div class="note-wrap-disabled">
<a class="button green icon-note note-button" href="/expo/add-note//">заметка</a>
<div class="note-overlay">
<form action="">
<textarea name="note_text" class="note-text"> </textarea>
</form>
</div>
</div>
</div>
<div class="ib-add"><a class="button blue2 icon-find" href="http://www.booking.com/searchresults.html?aid=333667&city=-2960561">Найти отель</a></div>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

@ -1,27 +1,78 @@
var EXPO = EXPO || {}; //isolated namespace
EXPO.exposition = EXPO.exposition || {};
if (EXPO.exposition.list){
console.warn('WARNING: EXPO.place.object is already defined!');
console.warn('WARNING: EXPO.place.object is already defined!');
}else {
EXPO.exposition.list = (function () {
EXPO.exposition.list = (function () {
// dependencies
var com = EXPO.common;
var com = EXPO.common;
// variables
var that = {};
that.opt = {}; //свойства по умолчанию
var that = {},
Note = function (it, opt) {
this.opt = opt;
this.DOMthis = it;
this.DOMbutton = it.querySelector('.'+opt.buttonClass);
this.DOMinput = it.querySelector('.'+opt.inputClass);
this.inputName = this.DOMinput.getAttribute('name');
this.url = this.DOMbutton.getAttribute('href');
this._controller();
};
Note.prototype = {
_init: function () {
},
_controller: function () {
var self = this;
$(this.DOMinput).on('blur', function () {
self.send();
});
$(this.DOMbutton).on('click', function () {
return false;
});
},
send: function () {
var data = {},
response,
self = this,
handler = function (data) {
if (data.success) {
console.log('ok');
$(self.DOMbutton).addClass('active');
} else {
console.log('data not send');
}
};
data[this.inputName] = this.DOMinput.value;
response = com.getRequest(data,this.url,handler);
}
};
that.opt = {}; //свойства по умолчанию
//private
$(function () {
});
$(function () {
});
// methods
//инициализация общих свойств
that.init = function (options) {
$.extend(this.opt, options);
com.opt.addCalendarText = this.opt.addCalendarText;
com.opt.removeCalendarText = this.opt.removeCalendarText;
};
return that;
}());
//инициализация общих свойств
that.init = function (options) {
$.extend(this.opt, options);
this.notes = [];
var self = this;
$('.'+this.opt.note.wrapClass).each(function () {
var note = new Note(this,self.opt.note);
self.notes.push(note);
});
$('.'+this.opt.note.wrapDisabledClass).on('click', function () {
$.fancybox.open('#pw-login');
return false;
});
com.opt.addCalendarText = this.opt.addCalendarText;
com.opt.removeCalendarText = this.opt.removeCalendarText;
};
return that;
}());
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,157 +1,202 @@
var EXPO = EXPO || {}; //isolated namespace
EXPO.exposition = EXPO.exposition || {};
if (EXPO.exposition.object){
console.warn('WARNING: EXPO.exposition.object is already defined!');
console.warn('WARNING: EXPO.exposition.object is already defined!');
}else {
EXPO.exposition.object = (function () {
EXPO.exposition.object = (function () {
// dependencies
var com = EXPO.common,
$waiter;
var com = EXPO.common,
$waiter;
// variables
var that = {};
that.opt = {}; //свойства по умолчанию
var that = {},
Note = function (it, opt) {
this.opt = opt;
this.DOMthis = it;
this.DOMbutton = it.querySelector('.'+opt.buttonClass);
this.DOMinput = it.querySelector('.'+opt.inputClass);
this.inputName = this.DOMinput.getAttribute('name');
this.url = this.DOMbutton.getAttribute('href');
this._controller();
};
Note.prototype = {
_init: function () {
},
_controller: function () {
var self = this;
$(this.DOMinput).on('blur', function () {
self.send();
});
$(this.DOMbutton).on('click', function () {
return false;
});
},
send: function () {
var data = {},
response,
self = this,
handler = function (data) {
if (data.success){
console.log('ok');
$(self.DOMbutton).addClass('active');
}else{
console.log('data not send');
}
};
data[this.inputName] = this.DOMinput.value;
response = com.getRequest(data,this.url,handler);
}
};
that.opt = {}; //свойства по умолчанию
//private
$(function () {
$waiter = $('#wait-ajax:not(.absolute)').css({'z-index': '8031'});
});
$(function () {
$waiter = $('#wait-ajax:not(.absolute)').css({'z-index': '8031'});
});
// methods
//инициализация общих свойств
that.init = function (options) {
$.extend(this.opt, options);
var self = this,
$visitButtons = $('.'+this.opt.visit.activeClass+', .'+this.opt.visit.passiveClass);
com.opt.addCalendarText = this.opt.addCalendarText;
com.opt.removeCalendarText = this.opt.removeCalendarText;
/**
* visit buttons
*/
$visitButtons.off('click');
$visitButtons.on('click', function () {
if (!$(this).hasClass('no_auth')) {
if ($(this).hasClass(self.opt.visit.activeClass)) {
/**
* I plan to visit
*/
$('.' + self.opt.visit.activeClass).hide().siblings('.' + self.opt.visit.passiveClass).show();
$('#' + self.opt.visit.visitorsListId).append(self.opt.visit.currentHtml);
$('#' + self.opt.visit.somebodyId).removeClass("hidden");
$('#' + self.opt.visit.nobodyId).addClass("hidden");
} else {
/**
* refuse to visit
*/
$('.' + self.opt.visit.passiveClass).hide().siblings('.' + self.opt.visit.activeClass).show();
$('#' + self.opt.visit.visitorsListId).children(".current").remove();
if ($('#' + self.opt.visit.visitorsListId).children().length == 0) {
$('#' + self.opt.visit.somebodyId).addClass("hidden");
$('#' + self.opt.visit.nobodyId).removeClass("hidden");
}
}
}
return false;
});
/**
* advertise form validation
*/
$('#'+this.opt.advertise.id).on("submit", function () {
var formData = $(this).serialize(),
formUrl = $(this).attr("action"),
$form = $(this),
/**
* executes after AJAX get request is complete
* @param data - data recieved from server ex
*/
handler = function (data) {
var clearValue = function () {
$('.err',$form).removeClass("err");
$('.pwf-msg',$form).text('');
};
if (data.success !== true){
clearValue();
for (var k in data.errors){
if (data.errors.hasOwnProperty(k)) {
$('input[name="'+k+'"]',$form)
.closest(".required").addClass("err")
.siblings(".pwf-msg").text(data.errors[k]);
}
}
}else{
clearValue();
//инициализация общих свойств
that.init = function (options) {
$.extend(this.opt, options);
var self = this,
$visitButtons = $('.'+this.opt.visit.activeClass+', .'+this.opt.visit.passiveClass);
this.notes = [];
$('.'+this.opt.note.wrapClass).each(function () {
var note = new Note(this,self.opt.note);
self.notes.push(note);
});
$('.'+this.opt.note.wrapDisabledClass).on('click', function () {
$.fancybox.open('#pw-login');
return false;
});
com.opt.addCalendarText = this.opt.addCalendarText;
com.opt.removeCalendarText = this.opt.removeCalendarText;
/**
* visit buttons
*/
$visitButtons.off('click');
$visitButtons.on('click', function () {
if ($(this).hasClass(self.opt.visit.activeClass)){
/**
* I plan to visit
*/
$('.'+self.opt.visit.activeClass).hide().siblings('.'+self.opt.visit.passiveClass).show();
$('#'+self.opt.visit.visitorsListId).append(self.opt.visit.currentHtml);
$('#'+self.opt.visit.somebodyId).removeClass("hidden");
$('#'+self.opt.visit.nobodyId).addClass("hidden");
}else{
/**
* refuse to visit
*/
$('.'+self.opt.visit.passiveClass).hide().siblings('.'+self.opt.visit.activeClass).show();
$('#'+self.opt.visit.visitorsListId).children(".current").remove();
if($('#'+self.opt.visit.visitorsListId).children().length == 0){
$('#'+self.opt.visit.somebodyId).addClass("hidden");
$('#'+self.opt.visit.nobodyId).removeClass("hidden");
}
}
return false;
});
/**
* advertise form validation
*/
$('#'+this.opt.advertise.id).on("submit", function () {
var formData = $(this).serialize(),
formUrl = $(this).attr("action"),
$form = $(this),
/**
* executes after AJAX get request is complete
* @param data - data recieved from server ex
*/
handler = function (data) {
var clearValue = function () {
$('.err',$form).removeClass("err");
$('.pwf-msg',$form).text('');
};
if (data.success != true){
clearValue();
for (var k in data.errors){
if (data.errors.hasOwnProperty(k)) {
$('input[name="'+k+'"]',$form)
.closest(".required").addClass("err")
.siblings(".pwf-msg").text(data.errors[k]);
}
}
}else{
clearValue();
dataLayer.push({'event': 'advmemberform'});
$('input:text',$form).val('');
$.fancybox.close();
}
$waiter.hide();
};
$waiter.show();
com.postRequest(formData,formUrl,handler);
return false;
});
/**
* event news subscribe form validation
*/
$(function () {
$('#'+self.opt.event_news_subscribe.id).on("submit", function () {
var formData = $(this).serialize(),
formUrl = $(this).attr("action"),
$form = $(this),
/**
* executes after AJAX get request is complete
* @param data - data recieved from server ex
*/
handler = function (data) {
var clearValue = function () {
$('.err',$form).removeClass("err");
$('.pwf-msg',$form).text('');
};
if (data.success != true){
clearValue();
for (var k in data.errors){
if (data.errors.hasOwnProperty(k)) {
$('input[name="'+k+'"]',$form)
.closest(".required").addClass("err")
.siblings(".pwf-msg").text(data.errors[k]);
}
}
} else {
clearValue();
dataLayer.push({'event': 'event-news-subscribe-form'});
$('input:text',$form).val('');
$('p#success').show();
if (data.sent == true) {
window.location = data.redirect_url;
} else {
window.setTimeout(function () {
$.fancybox.close();
}, 1000);
}
}
$waiter.hide();
};
$waiter.show();
com.postRequest(formData,formUrl,handler);
return false;
});
});
};
return that;
}());
$('input:text',$form).val('');
$.fancybox.close();
}
$waiter.hide();
};
$waiter.show();
com.postRequest(formData,formUrl,handler);
return false;
});
/**
* event news subscribe form validation
*/
$('#'+this.opt.event_news_subscribe.id).on("submit", function () {
var formData = $(this).serialize(),
formUrl = $(this).attr("action"),
$form = $(this),
/**
* executes after AJAX get request is complete
* @param data - data recieved from server ex
*/
handler = function (data) {
var clearValue = function () {
$('.err',$form).removeClass("err");
$('.pwf-msg',$form).text('');
};
if (data.success != true){
clearValue();
for (var k in data.errors){
console.log(data.errors.hasOwnProperty(k));
console.log(k);
if (data.errors.hasOwnProperty(k)) {
$('input[name="'+k+'"]',$form)
.closest(".required").addClass("err")
.siblings(".pwf-msg").text(data.errors[k]);
}
}
}else{
clearValue();
dataLayer.push({'event': 'event-news-subscribe-form'});
$('input:text',$form).val('');
$('p#success').show();
if (data.sent == true) {
window.location = data.redirect_url;
} else {
window.setTimeout(function () {
$.fancybox.close();
}, 1000);
}
}
$waiter.hide();
};
$waiter.show();
com.postRequest(formData,formUrl,handler);
return false;
});
};
return that;
}());
}

@ -0,0 +1,74 @@
var EXPO = EXPO || {}; //isolated namespace
if (EXPO.index) {
console.warn('WARNING: EXPO.eventsFeed is already defined!');
} else {
EXPO.index = (function () {
// variables
var that = {};
//default module setting
that.opt = {};
//dependence's
var com = EXPO.common;
//private
var Note = function (it, opt) {
this.opt = opt;
this.DOMthis = it;
this.DOMbutton = it.querySelector('.'+opt.buttonClass);
this.DOMinput = it.querySelector('.'+opt.inputClass);
this.inputName = this.DOMinput.getAttribute('name');
this.url = this.DOMbutton.getAttribute('href');
this._controller();
};
Note.prototype = {
_init: function () {
},
_controller: function () {
var self = this;
$(this.DOMinput).on('blur', function () {
self.send();
});
$(this.DOMbutton).on('click', function () {
return false;
});
},
send: function () {
var data = {},
response,
self = this,
handler = function (data) {
if (data.success){
console.log('ok');
$(self.DOMbutton).addClass('active');
}else{
console.log('data not send');
}
};
data[this.inputName] = this.DOMinput.value;
response = com.getRequest(data,this.url,handler);
}
};
///////////////////////////
//инициализация общих свойств
that.init = function (options) {
// settings extending
$.extend(this.opt, options);
// begin of initialization
var self = this;
this.notes = [];
$('.'+this.opt.note.wrapClass).each(function () {
var note = new Note(this,self.opt.note);
self.notes.push(note);
});
$('.'+this.opt.note.wrapDisabledClass).on('click', function () {
$.fancybox.open('#pw-login');
return false;
});
};
return that;
}());
}

@ -81,20 +81,6 @@ function placeInput(width){
var $body = $('body');
var $doc = $(document);
var $event_news_subscribe_form = $('#event-news-subscribe-form'),
$modal_title = $('#pw-event-news-subscribe').find('.pw-title');
$('.new_subribe_btn').on('click', function () {
var $this = $(this),
// Null will be on detail page
name = $this.parents('.cl-item').find('.cli-title a').text() || null;
if (name) {
$modal_title.text($modal_title.text() + ' ' + name);
}
$event_news_subscribe_form.attr('action', $(this).data('url'));
});
$.widget( "custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function( ul, items ) {
@ -708,6 +694,23 @@ function placeInput(width){
$scrollContainer.mCustomScrollbar(customScrollOptions);
});
/* Открыть диалог подписки на нужной вкладке */
$('#subscribe-sm').each(function () {
var $container = $(this);
var $links = $container.find('a');
$links.on('click', function () {
var $link = $(this);
var index = $links.index(this);
var popupSubscribe = $('#pw-subscribe');
$.fancybox(popupSubscribe, fbPopupOptions);
var $tabs = popupSubscribe.find('ul.tabs > li');
$tabs.eq(index).trigger('click');
return false;
});
});
/* Обработка поведения вкладок */
$("ul.tabs > li").on('click', function () {
var $curTab = $(this);
@ -1112,7 +1115,7 @@ function placeInput(width){
$('div.request-form').each(function () {
var $mContainer = $(this);
var $switchContainer = $mContainer.find('div.rq-btn-to-hide');
var $switchBtn = $switchContainer.find('a:not(.link)');
var $switchBtn = $switchContainer.find('a');
var $formContainer = $mContainer.find('div.rq-form');
var $hideData = $mContainer.find('div.rq-to-hide');
var $formBtnContainer = $formContainer.find('div.rq-btn-wrap');

@ -72,16 +72,16 @@
$('div#' + PARENT_ID + ' ul li.cl-item').each(function(index, el) {
$('div.page-body ul.cat-list li.cl-item[data-slug=\'' + $(el).data('slug') + '\']').not(el).remove();
});
};
}
var insertTops = function (text) {
var parent = document.getElementById(PARENT_ID);
if (parent) {
parent.innerHTML = text;
// $(document).ready(function () {
// removeDublicates();
// });
$(document).ready(function () {
removeDublicates();
});
}
};

@ -88,7 +88,6 @@ function build_filters_period () {
function submit_search_form () {
var $form = $('.filter_form'),
params = $form.serialize(),
paramsForTop = $form.serializeArray(),
filters_url = $form.data('formurl'),
results_url = $form.data('resultsurl'),
$loader = $('#wait-ajax');
@ -102,7 +101,7 @@ function submit_search_form () {
$.getJSON(results_url, params, function(data) {
if (data.success) {
$('.page-body').html(data.results).prepend('<div id="expo_top_events"></div>');
$('.page-body').html(data.results);
build_sidebar();
$loader.hide();
}
@ -116,105 +115,6 @@ function submit_search_form () {
build_filters_period();
}
})
var API_URL_ROOT = "/expo-b/get-tops/";
var PARENT_ID = "expo_top_events";
var getUrl = function () {
var search = [];
var parts = /^\/([^\/]+)(?:\/|$)/i.exec(location.pathname);
if (parts) {
search.push("catalog=" + encodeURIComponent(parts[1]));
} else {
search.push("catalog=");
}
var data = window.sendData, theme = [];
$.each(paramsForTop, function(i,val){
if(val.name === 'theme') {
theme.push(parseInt(val.value));
}
});
data.theme = theme;
console.log('NEW:',data);
if (data instanceof Object) {
for (var key in data) {
if (data.hasOwnProperty(key)) {
var value = data[key];
if (value instanceof Array) {
for (var i = 0, l = value.length; i < l; i++) {
search.push(encodeURIComponent(key) + "=" + encodeURIComponent(value[i]));
}
} else {
search.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
}
}
}
}
return API_URL_ROOT + "?" + search.join("&");
};
var runCallback = function (callback, arg) {
try {
callback(arg);
} catch (error) {
// do nothing
}
// console.info('callback Done');
};
var getTops = function (url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function (event) {
if (event.target.readyState === 4) {
if (event.target.status === 200) {
if (document.readyState === "loading" && !window.marker_DOMtopjsElementInserted) {
// console.info('setting DOMContentLoaded event listener');
// console.info('setting DOMtopjsElementInserted event listener');
// document.addEventListener("DOMContentLoaded", function() {
document.addEventListener("DOMtopjsElementInserted", function() {
runCallback(callback, event.target.responseText);
});
} else {
runCallback(callback, event.target.responseText);
}
}
}
};
xhr.send();
};
var removeDublicates = function () {
$('div#' + PARENT_ID + ' ul li.cl-item').each(function(index, el) {
$('div.page-body ul.cat-list li.cl-item[data-slug=\'' + $(el).data('slug') + '\']').not(el).remove();
});
};
var insertTops = function (text) {
var parent = document.getElementById(PARENT_ID);
if (parent) {
parent.innerHTML = text;
// $(document).ready(function () {
// removeDublicates();
// });
}
};
var main = function () {
getTops(getUrl(), insertTops);
};
// main();
// window.addEventListener("load", main);
// document.addEventListener("DOMContentLoaded", main);
main();
}
$(document).ready(function () {

@ -3760,20 +3760,6 @@ function placeInput(width){
var $body = $('body');
var $doc = $(document);
var $event_news_subscribe_form = $('#event-news-subscribe-form'),
$modal_title = $('#pw-event-news-subscribe').find('.pw-title');
$('.new_subribe_btn').on('click', function () {
var $this = $(this),
// Null will be on detail page
name = $this.parents('.cl-item').find('.cli-title a').text() || null;
if (name) {
$modal_title.text($modal_title.text() + ' ' + name);
}
$event_news_subscribe_form.attr('action', $(this).data('url'));
});
$.widget( "custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function( ul, items ) {
@ -4387,6 +4373,23 @@ function placeInput(width){
$scrollContainer.mCustomScrollbar(customScrollOptions);
});
/* Открыть диалог подписки на нужной вкладке */
$('#subscribe-sm').each(function () {
var $container = $(this);
var $links = $container.find('a');
$links.on('click', function () {
var $link = $(this);
var index = $links.index(this);
var popupSubscribe = $('#pw-subscribe');
$.fancybox(popupSubscribe, fbPopupOptions);
var $tabs = popupSubscribe.find('ul.tabs > li');
$tabs.eq(index).trigger('click');
return false;
});
});
/* Обработка поведения вкладок */
$("ul.tabs > li").on('click', function () {
var $curTab = $(this);
@ -4791,7 +4794,7 @@ function placeInput(width){
$('div.request-form').each(function () {
var $mContainer = $(this);
var $switchContainer = $mContainer.find('div.rq-btn-to-hide');
var $switchBtn = $switchContainer.find('a:not(.link)');
var $switchBtn = $switchContainer.find('a');
var $formContainer = $mContainer.find('div.rq-form');
var $hideData = $mContainer.find('div.rq-to-hide');
var $formBtnContainer = $formContainer.find('div.rq-btn-wrap');
@ -4947,7 +4950,6 @@ function build_filters_period () {
function submit_search_form () {
var $form = $('.filter_form'),
params = $form.serialize(),
paramsForTop = $form.serializeArray(),
filters_url = $form.data('formurl'),
results_url = $form.data('resultsurl'),
$loader = $('#wait-ajax');
@ -4961,7 +4963,7 @@ function submit_search_form () {
$.getJSON(results_url, params, function(data) {
if (data.success) {
$('.page-body').html(data.results).prepend('<div id="expo_top_events"></div>');
$('.page-body').html(data.results);
build_sidebar();
$loader.hide();
}
@ -4975,105 +4977,6 @@ function submit_search_form () {
build_filters_period();
}
})
var API_URL_ROOT = "/expo-b/get-tops/";
var PARENT_ID = "expo_top_events";
var getUrl = function () {
var search = [];
var parts = /^\/([^\/]+)(?:\/|$)/i.exec(location.pathname);
if (parts) {
search.push("catalog=" + encodeURIComponent(parts[1]));
} else {
search.push("catalog=");
}
var data = window.sendData, theme = [];
$.each(paramsForTop, function(i,val){
if(val.name === 'theme') {
theme.push(parseInt(val.value));
}
});
data.theme = theme;
console.log('NEW:',data);
if (data instanceof Object) {
for (var key in data) {
if (data.hasOwnProperty(key)) {
var value = data[key];
if (value instanceof Array) {
for (var i = 0, l = value.length; i < l; i++) {
search.push(encodeURIComponent(key) + "=" + encodeURIComponent(value[i]));
}
} else {
search.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
}
}
}
}
return API_URL_ROOT + "?" + search.join("&");
};
var runCallback = function (callback, arg) {
try {
callback(arg);
} catch (error) {
// do nothing
}
// console.info('callback Done');
};
var getTops = function (url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function (event) {
if (event.target.readyState === 4) {
if (event.target.status === 200) {
if (document.readyState === "loading" && !window.marker_DOMtopjsElementInserted) {
// console.info('setting DOMContentLoaded event listener');
// console.info('setting DOMtopjsElementInserted event listener');
// document.addEventListener("DOMContentLoaded", function() {
document.addEventListener("DOMtopjsElementInserted", function() {
runCallback(callback, event.target.responseText);
});
} else {
runCallback(callback, event.target.responseText);
}
}
}
};
xhr.send();
};
var removeDublicates = function () {
$('div#' + PARENT_ID + ' ul li.cl-item').each(function(index, el) {
$('div.page-body ul.cat-list li.cl-item[data-slug=\'' + $(el).data('slug') + '\']').not(el).remove();
});
};
var insertTops = function (text) {
var parent = document.getElementById(PARENT_ID);
if (parent) {
parent.innerHTML = text;
// $(document).ready(function () {
// removeDublicates();
// });
}
};
var main = function () {
getTops(getUrl(), insertTops);
};
// main();
// window.addEventListener("load", main);
// document.addEventListener("DOMContentLoaded", main);
main();
}
$(document).ready(function () {

@ -1 +1 @@
var EXPO=EXPO||{};EXPO.exposition=EXPO.exposition||{},EXPO.exposition.list?console.warn("WARNING: EXPO.place.object is already defined!"):EXPO.exposition.list=function(){var t=EXPO.common,e={};return e.opt={},$(function(){}),e.init=function(e){$.extend(this.opt,e),t.opt.addCalendarText=this.opt.addCalendarText,t.opt.removeCalendarText=this.opt.removeCalendarText},e}();
var EXPO=EXPO||{};EXPO.exposition=EXPO.exposition||{},EXPO.exposition.list?console.warn("WARNING: EXPO.place.object is already defined!"):EXPO.exposition.list=function(){var t=EXPO.common,n={},o=function(t,n){this.opt=n,this.DOMthis=t,this.DOMbutton=t.querySelector("."+n.buttonClass),this.DOMinput=t.querySelector("."+n.inputClass),this.inputName=this.DOMinput.getAttribute("name"),this.url=this.DOMbutton.getAttribute("href"),this._controller()};return o.prototype={_init:function(){},_controller:function(){var t=this;$(this.DOMinput).on("blur",function(){t.send()}),$(this.DOMbutton).on("click",function(){return!1})},send:function(){var n,o={},i=this,e=function(t){t.success?(console.log("ok"),$(i.DOMbutton).addClass("active")):console.log("data not send")};o[this.inputName]=this.DOMinput.value,n=t.getRequest(o,this.url,e)}},n.opt={},$(function(){}),n.init=function(n){$.extend(this.opt,n),this.notes=[];var i=this;$("."+this.opt.note.wrapClass).each(function(){var t=new o(this,i.opt.note);i.notes.push(t)}),$("."+this.opt.note.wrapDisabledClass).on("click",function(){return $.fancybox.open("#pw-login"),!1}),t.opt.addCalendarText=this.opt.addCalendarText,t.opt.removeCalendarText=this.opt.removeCalendarText},n}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
var EXPO=EXPO||{};EXPO.exposition=EXPO.exposition||{},EXPO.exposition.object?console.warn("WARNING: EXPO.exposition.object is already defined!"):EXPO.exposition.object=function(){var s,t=EXPO.common,i={};return i.opt={},$(function(){s=$("#wait-ajax:not(.absolute)").css({"z-index":"8031"})}),i.init=function(i){$.extend(this.opt,i);var e=this,o=$("."+this.opt.visit.activeClass+", ."+this.opt.visit.passiveClass);t.opt.addCalendarText=this.opt.addCalendarText,t.opt.removeCalendarText=this.opt.removeCalendarText,o.off("click"),o.on("click",function(){return $(this).hasClass("no_auth")||($(this).hasClass(e.opt.visit.activeClass)?($("."+e.opt.visit.activeClass).hide().siblings("."+e.opt.visit.passiveClass).show(),$("#"+e.opt.visit.visitorsListId).append(e.opt.visit.currentHtml),$("#"+e.opt.visit.somebodyId).removeClass("hidden"),$("#"+e.opt.visit.nobodyId).addClass("hidden")):($("."+e.opt.visit.passiveClass).hide().siblings("."+e.opt.visit.activeClass).show(),$("#"+e.opt.visit.visitorsListId).children(".current").remove(),0==$("#"+e.opt.visit.visitorsListId).children().length&&($("#"+e.opt.visit.somebodyId).addClass("hidden"),$("#"+e.opt.visit.nobodyId).removeClass("hidden")))),!1}),$("#"+this.opt.advertise.id).on("submit",function(){var i=$(this).serialize(),e=$(this).attr("action"),o=$(this),r=function(t){var i=function(){$(".err",o).removeClass("err"),$(".pwf-msg",o).text("")};if(t.success!==!0){i();for(var e in t.errors)t.errors.hasOwnProperty(e)&&$('input[name="'+e+'"]',o).closest(".required").addClass("err").siblings(".pwf-msg").text(t.errors[e])}else i(),dataLayer.push({event:"advmemberform"}),$("input:text",o).val(""),$.fancybox.close();s.hide()};return s.show(),t.postRequest(i,e,r),!1}),$(function(){$("#"+e.opt.event_news_subscribe.id).on("submit",function(){var i=$(this).serialize(),e=$(this).attr("action"),o=$(this),r=function(t){var i=function(){$(".err",o).removeClass("err"),$(".pwf-msg",o).text("")};if(1!=t.success){i();for(var e in t.errors)t.errors.hasOwnProperty(e)&&$('input[name="'+e+'"]',o).closest(".required").addClass("err").siblings(".pwf-msg").text(t.errors[e])}else i(),dataLayer.push({event:"event-news-subscribe-form"}),$("input:text",o).val(""),$("p#success").show(),1==t.sent?window.location=t.redirect_url:window.setTimeout(function(){$.fancybox.close()},1e3);s.hide()};return s.show(),t.postRequest(i,e,r),!1})})},i}();
var EXPO=EXPO||{};EXPO.exposition=EXPO.exposition||{},EXPO.exposition.object?console.warn("WARNING: EXPO.exposition.object is already defined!"):EXPO.exposition.object=function(){var t,s=EXPO.common,i={},e=function(t,s){this.opt=s,this.DOMthis=t,this.DOMbutton=t.querySelector("."+s.buttonClass),this.DOMinput=t.querySelector("."+s.inputClass),this.inputName=this.DOMinput.getAttribute("name"),this.url=this.DOMbutton.getAttribute("href"),this._controller()};return e.prototype={_init:function(){},_controller:function(){var t=this;$(this.DOMinput).on("blur",function(){t.send()}),$(this.DOMbutton).on("click",function(){return!1})},send:function(){var t,i={},e=this,o=function(t){t.success?(console.log("ok"),$(e.DOMbutton).addClass("active")):console.log("data not send")};i[this.inputName]=this.DOMinput.value,t=s.getRequest(i,this.url,o)}},i.opt={},$(function(){t=$("#wait-ajax:not(.absolute)").css({"z-index":"8031"})}),i.init=function(i){$.extend(this.opt,i);var o=this,n=$("."+this.opt.visit.activeClass+", ."+this.opt.visit.passiveClass);this.notes=[],$("."+this.opt.note.wrapClass).each(function(){var t=new e(this,o.opt.note);o.notes.push(t)}),$("."+this.opt.note.wrapDisabledClass).on("click",function(){return $.fancybox.open("#pw-login"),!1}),s.opt.addCalendarText=this.opt.addCalendarText,s.opt.removeCalendarText=this.opt.removeCalendarText,n.off("click"),n.on("click",function(){return $(this).hasClass(o.opt.visit.activeClass)?($("."+o.opt.visit.activeClass).hide().siblings("."+o.opt.visit.passiveClass).show(),$("#"+o.opt.visit.visitorsListId).append(o.opt.visit.currentHtml),$("#"+o.opt.visit.somebodyId).removeClass("hidden"),$("#"+o.opt.visit.nobodyId).addClass("hidden")):($("."+o.opt.visit.passiveClass).hide().siblings("."+o.opt.visit.activeClass).show(),$("#"+o.opt.visit.visitorsListId).children(".current").remove(),0==$("#"+o.opt.visit.visitorsListId).children().length&&($("#"+o.opt.visit.somebodyId).addClass("hidden"),$("#"+o.opt.visit.nobodyId).removeClass("hidden"))),!1}),$("#"+this.opt.advertise.id).on("submit",function(){var i=$(this).serialize(),e=$(this).attr("action"),o=$(this),n=function(s){var i=function(){$(".err",o).removeClass("err"),$(".pwf-msg",o).text("")};if(1!=s.success){i();for(var e in s.errors)s.errors.hasOwnProperty(e)&&$('input[name="'+e+'"]',o).closest(".required").addClass("err").siblings(".pwf-msg").text(s.errors[e])}else i(),dataLayer.push({event:"advmemberform"}),$("input:text",o).val(""),$.fancybox.close();t.hide()};return t.show(),s.postRequest(i,e,n),!1}),$("#"+this.opt.event_news_subscribe.id).on("submit",function(){var i=$(this).serialize(),e=$(this).attr("action"),o=$(this),n=function(s){var i=function(){$(".err",o).removeClass("err"),$(".pwf-msg",o).text("")};if(1!=s.success){i();for(var e in s.errors)console.log(s.errors.hasOwnProperty(e)),console.log(e),s.errors.hasOwnProperty(e)&&$('input[name="'+e+'"]',o).closest(".required").addClass("err").siblings(".pwf-msg").text(s.errors[e])}else i(),dataLayer.push({event:"event-news-subscribe-form"}),$("input:text",o).val(""),$("p#success").show(),1==s.sent?window.location=s.redirect_url:window.setTimeout(function(){$.fancybox.close()},1e3);t.hide()};return t.show(),s.postRequest(i,e,n),!1})},i}();

@ -0,0 +1 @@
var EXPO=EXPO||{};EXPO.index?console.warn("WARNING: EXPO.eventsFeed is already defined!"):EXPO.index=function(){var t={};t.opt={};var n=EXPO.common,i=function(t,n){this.opt=n,this.DOMthis=t,this.DOMbutton=t.querySelector("."+n.buttonClass),this.DOMinput=t.querySelector("."+n.inputClass),this.inputName=this.DOMinput.getAttribute("name"),this.url=this.DOMbutton.getAttribute("href"),this._controller()};return i.prototype={_init:function(){},_controller:function(){var t=this;$(this.DOMinput).on("blur",function(){t.send()}),$(this.DOMbutton).on("click",function(){return!1})},send:function(){var t,i={},o=this,e=function(t){t.success?(console.log("ok"),$(o.DOMbutton).addClass("active")):console.log("data not send")};i[this.inputName]=this.DOMinput.value,t=n.getRequest(i,this.url,e)}},t.init=function(t){$.extend(this.opt,t);var n=this;this.notes=[],$("."+this.opt.note.wrapClass).each(function(){var t=new i(this,n.opt.note);n.notes.push(t)}),$("."+this.opt.note.wrapDisabledClass).on("click",function(){return $.fancybox.open("#pw-login"),!1})},t}();

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

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

Loading…
Cancel
Save