commit
3a8ee32218
123 changed files with 5045 additions and 605 deletions
@ -1,12 +1,13 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
from django.conf.urls import patterns, url |
from django.conf.urls import patterns, url |
||||||
from admin import UserListView |
from admin import UserListView, EditUser |
||||||
|
|
||||||
urlpatterns = patterns('', |
urlpatterns = patterns('', |
||||||
#url(r'^registration/$', 'accounts.admin.registration'), |
#url(r'^registration/$', 'accounts.admin.registration'), |
||||||
#url(r'^create_admin/$', 'accounts.admin.create_admin'), |
#url(r'^create_admin/$', 'accounts.admin.create_admin'), |
||||||
#url(r'^create_md5user/$', 'accounts.admin.create_md5'), |
#url(r'^create_md5user/$', 'accounts.admin.create_md5'), |
||||||
url(r'^change/(.*)/$', 'accounts.admin.user_change'), |
# url(r'^change/(?P<pk>.*)/$', EditUser.as_view()), |
||||||
|
url(r'^change/(?P<url>.*)/$', 'accounts.admin.user_change'), |
||||||
url(r'^all/$', UserListView.as_view()), |
url(r'^all/$', UserListView.as_view()), |
||||||
url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'), |
url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'), |
||||||
) |
) |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
from django.conf.urls import url, patterns |
||||||
|
from views import NewPage, PageList, EditPage, DeletePage, PageDetailed |
||||||
|
|
||||||
|
urlpatterns = patterns('', |
||||||
|
url(r'^new/$', NewPage.as_view(), name='new_page' ), |
||||||
|
url(r'^all/$', PageList.as_view(), name = 'page_list'), |
||||||
|
url(r'^edit/(?P<url>.*)/$', EditPage.as_view(), name='edit_page'), |
||||||
|
url(r'^delete/(?P<url>.*)/$', DeletePage.as_view(), name='delete_page'), |
||||||
|
url(r'^(?P<url>.*)/$', PageDetailed.as_view(), name='page_view'), |
||||||
|
) |
||||||
@ -0,0 +1,76 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
|
||||||
|
import xlwt |
||||||
|
import datetime |
||||||
|
|
||||||
|
from exposition.models import Exposition |
||||||
|
from conference.models import Conference |
||||||
|
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist |
||||||
|
|
||||||
|
HEADER_STYLE = xlwt.easyxf('font: bold on') |
||||||
|
DEFAULT_STYLE = xlwt.easyxf() |
||||||
|
CELL_STYLE_MAP = ( |
||||||
|
(datetime.date, xlwt.easyxf(num_format_str='DD/MM/YYYY')), |
||||||
|
(datetime.time, xlwt.easyxf(num_format_str='HH:MM')), |
||||||
|
(bool, xlwt.easyxf(num_format_str='BOOLEAN')), |
||||||
|
) |
||||||
|
|
||||||
|
def multi_getattr(obj, attr, default=None): |
||||||
|
attributes = attr.split(".") |
||||||
|
for i in attributes: |
||||||
|
try: |
||||||
|
obj = getattr(obj, i) |
||||||
|
except AttributeError: |
||||||
|
if default: |
||||||
|
return default |
||||||
|
else: |
||||||
|
return '-' |
||||||
|
return obj |
||||||
|
|
||||||
|
|
||||||
|
def get_column_cell(obj, name): |
||||||
|
try: |
||||||
|
attr = multi_getattr(obj, name) |
||||||
|
except ObjectDoesNotExist: |
||||||
|
return '' |
||||||
|
if hasattr(attr, '_meta'): |
||||||
|
# A Django Model (related object) |
||||||
|
return unicode(attr).strip() |
||||||
|
elif hasattr(attr, 'all'): |
||||||
|
# A Django queryset (ManyRelatedManager) |
||||||
|
return ', '.join(unicode(x).strip() for x in attr.all()) |
||||||
|
return attr |
||||||
|
|
||||||
|
def queryset_to_workbook(queryset, columns, header_style=None, default_style=None, cell_style_map=None): |
||||||
|
workbook = xlwt.Workbook() |
||||||
|
report_date = datetime.date.today() |
||||||
|
sheet_name = 'Export {0}'.format(report_date.strftime('%Y-%m-%d')) |
||||||
|
sheet = workbook.add_sheet(sheet_name) |
||||||
|
|
||||||
|
if not header_style: |
||||||
|
header_style = HEADER_STYLE |
||||||
|
if not default_style: |
||||||
|
default_style = DEFAULT_STYLE |
||||||
|
if not cell_style_map: |
||||||
|
cell_style_map = CELL_STYLE_MAP |
||||||
|
|
||||||
|
obj = queryset[0] |
||||||
|
|
||||||
|
for y, column in enumerate(columns): |
||||||
|
header_list=[u'Название события',u'Страна',u'Город',u'Место проведения', u'Дата начала', u'Дата окончания'] |
||||||
|
|
||||||
|
sheet.write(0, y, header_list[y], header_style) |
||||||
|
|
||||||
|
for x, obj in enumerate(queryset, start=1): |
||||||
|
for y, column in enumerate(columns): |
||||||
|
value = get_column_cell(obj, column) |
||||||
|
style = default_style |
||||||
|
for value_type, cell_style in cell_style_map: |
||||||
|
if isinstance(value, value_type): |
||||||
|
style = cell_style |
||||||
|
sheet.write(x, y, value, style) |
||||||
|
|
||||||
|
return workbook |
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,156 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from django.views.generic import TemplateView, CreateView, ListView, UpdateView, DetailView |
||||||
|
from django.conf import settings |
||||||
|
from django.http import HttpResponseRedirect |
||||||
|
from django.shortcuts import get_object_or_404 |
||||||
|
from expobanner.models import URL, BannerGroup, Banner, Paid |
||||||
|
from expobanner.forms import UrlCreateForm, BannerCreateGroupForm, BannerCreateForm, BannerGroupUpdateForm,\ |
||||||
|
PaidCreateForm, PaidUpdateForm, TopCreateForm |
||||||
|
from exposition.models import Exposition |
||||||
|
|
||||||
|
|
||||||
|
class BannersControl(TemplateView): |
||||||
|
template_name = 'admin/expobanner/banners_control.html' |
||||||
|
|
||||||
|
# CREATE VIEWS |
||||||
|
class AbstractCreate(CreateView): |
||||||
|
template_name = 'admin/expobanner/default_form.html' |
||||||
|
success_url = '/admin/expobanners/banners/control/' |
||||||
|
|
||||||
|
|
||||||
|
class CreateUrl(AbstractCreate): |
||||||
|
model = URL |
||||||
|
form_class = UrlCreateForm |
||||||
|
|
||||||
|
|
||||||
|
class CreateBannerGroup(AbstractCreate): |
||||||
|
model = BannerGroup |
||||||
|
form_class = BannerCreateGroupForm |
||||||
|
|
||||||
|
|
||||||
|
class CreateBanner(AbstractCreate): |
||||||
|
model = Banner |
||||||
|
form_class = BannerCreateForm |
||||||
|
|
||||||
|
|
||||||
|
# LISTS VIEWS |
||||||
|
class AbstractList(ListView): |
||||||
|
paginate_by = settings.ADMIN_PAGINATION |
||||||
|
template_name = 'admin/expobanner/default_list.html' |
||||||
|
|
||||||
|
def get_context_data(self, **kwargs): |
||||||
|
context = super(AbstractList, self).get_context_data(**kwargs) |
||||||
|
context['verbose'] = self.verbose |
||||||
|
return context |
||||||
|
|
||||||
|
class UrlList(AbstractList): |
||||||
|
model = URL |
||||||
|
verbose = u'Список урлов' |
||||||
|
|
||||||
|
|
||||||
|
class BannerGroupList(AbstractList): |
||||||
|
model = BannerGroup |
||||||
|
verbose = u'Список груп' |
||||||
|
|
||||||
|
|
||||||
|
class BannerList(AbstractList): |
||||||
|
model = Banner |
||||||
|
verbose = u'Список банеров' |
||||||
|
template_name = 'admin/expobanner/banner_list.html' |
||||||
|
|
||||||
|
def get_queryset(self): |
||||||
|
qs = super(BannerList, self).get_queryset() |
||||||
|
qs = qs.filter(group__isnull=False) |
||||||
|
return qs |
||||||
|
|
||||||
|
# UPDATE VIEWS |
||||||
|
class AbstractUpdate(UpdateView): |
||||||
|
template_name = 'admin/expobanner/default_form.html' |
||||||
|
success_url = '/admin/expobanners/banners/control/' |
||||||
|
|
||||||
|
|
||||||
|
class UrlUpdate(AbstractUpdate): |
||||||
|
model = URL |
||||||
|
form_class = UrlCreateForm |
||||||
|
|
||||||
|
|
||||||
|
class BannerGroupUpdate(AbstractUpdate): |
||||||
|
model = BannerGroup |
||||||
|
form_class = BannerGroupUpdateForm |
||||||
|
|
||||||
|
|
||||||
|
class BannerUpdate(AbstractUpdate): |
||||||
|
model = Banner |
||||||
|
form_class = BannerCreateForm |
||||||
|
|
||||||
|
|
||||||
|
class BannerStat(DetailView): |
||||||
|
model = Banner |
||||||
|
template_name = 'admin/expobanner/banner_stat.html' |
||||||
|
|
||||||
|
class PaidList(ListView): |
||||||
|
model = Exposition |
||||||
|
template_name = 'admin/expobanner/paid_list.html' |
||||||
|
paginate_by = settings.ADMIN_PAGINATION |
||||||
|
|
||||||
|
def get_queryset(self): |
||||||
|
return self.model.objects.language().filter(paid_new__isnull=False) |
||||||
|
|
||||||
|
class PaidCreate(CreateView): |
||||||
|
form_class = PaidCreateForm |
||||||
|
template_name = 'admin/expobanner/paid_create.html' |
||||||
|
success_url = '/admin/expobanners/paid/list/' |
||||||
|
|
||||||
|
class PaidUpdate(UpdateView): |
||||||
|
model = Paid |
||||||
|
form_class = PaidUpdateForm |
||||||
|
template_name = 'admin/expobanner/paid_update.html' |
||||||
|
success_url = '/admin/expobanners/paid/list/' |
||||||
|
|
||||||
|
def get_initial(self): |
||||||
|
""" |
||||||
|
Returns the initial data to use for forms on this view. |
||||||
|
""" |
||||||
|
initial = super(PaidUpdate, self).get_initial() |
||||||
|
obj = self.object |
||||||
|
initial['tickets'] = obj.tickets.url |
||||||
|
initial['participation'] = obj.participation.url |
||||||
|
initial['official'] = obj.official.url |
||||||
|
|
||||||
|
return initial |
||||||
|
|
||||||
|
def get_context_data(self, **kwargs): |
||||||
|
context = super(PaidUpdate, self).get_context_data(**kwargs) |
||||||
|
obj = self.object |
||||||
|
context['exposition'] = obj.get_event() |
||||||
|
return context |
||||||
|
|
||||||
|
|
||||||
|
def paid_turn(request, pk, status): |
||||||
|
paid = get_object_or_404(Paid, pk=pk) |
||||||
|
if status == 'on': |
||||||
|
paid.public = True |
||||||
|
else: |
||||||
|
paid.public = False |
||||||
|
paid.save() |
||||||
|
return HttpResponseRedirect('/admin/expobanners/paid/list/') |
||||||
|
|
||||||
|
|
||||||
|
class PaidStat(DetailView): |
||||||
|
model = Paid |
||||||
|
template_name = 'admin/expobanner/paid_stat.html' |
||||||
|
|
||||||
|
|
||||||
|
class TopList(ListView): |
||||||
|
model = Exposition |
||||||
|
template_name = 'admin/expobanner/top_list.html' |
||||||
|
paginate_by = settings.ADMIN_PAGINATION |
||||||
|
|
||||||
|
def get_queryset(self): |
||||||
|
return self.model.objects.language().filter(top__isnull=False) |
||||||
|
|
||||||
|
|
||||||
|
class TopCreate(CreateView): |
||||||
|
form_class = TopCreateForm |
||||||
|
template_name = 'admin/expobanner/top_create.html' |
||||||
|
success_url = '/admin/expobanners/top/list/' |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from django.conf.urls import patterns, url |
||||||
|
from expobanner.admin import * |
||||||
|
|
||||||
|
urlpatterns = patterns('expobanner.admin', |
||||||
|
# banners |
||||||
|
url(r'^banners/control/$', BannersControl.as_view(), name='expobanner-baneers_control'), |
||||||
|
url(r'^banners/url/$', CreateUrl.as_view(), name='expobanner-create_url'), |
||||||
|
url(r'^banners/group/$', CreateBannerGroup.as_view(), name='expobanner-create_group'), |
||||||
|
url(r'^banners/banner/$', CreateBanner.as_view(), name='expobanner-create_banner'), |
||||||
|
url(r'^banners/url/list/$', UrlList.as_view(), name='expobanner-list_url'), |
||||||
|
url(r'^banners/group/list/$', BannerGroupList.as_view(), name='expobanner-list_group'), |
||||||
|
url(r'^banners/banner/list/$', BannerList.as_view(), name='expobanner-list_banner'), |
||||||
|
url(r'^banners/url/(?P<pk>\d+)/edit/$', UrlUpdate.as_view(), name='expobanner-update_url'), |
||||||
|
url(r'^banners/group/(?P<pk>\d+)/edit/$', BannerGroupUpdate.as_view(), name='expobanner-update_group'), |
||||||
|
url(r'^banners/banner/(?P<pk>\d+)/edit/$', BannerUpdate.as_view(), name='expobanner-update_banner'), |
||||||
|
url(r'^banners/banner/(?P<pk>\d+)/stat/$', BannerStat.as_view(), name='expobanner_stat_banner'), |
||||||
|
# paid |
||||||
|
url(r'^paid/list/$', PaidList.as_view(), name='expobanner-list_paid'), |
||||||
|
url(r'^paid/(?P<pk>\d+)/edit/$', PaidUpdate.as_view(), name='expobanner-update_paid'), |
||||||
|
url(r'^paid/$', PaidCreate.as_view(), name='expobanner-create_paid'), |
||||||
|
url(r'^paid/turn/(?P<pk>\d+)/(?P<status>.*)/$', paid_turn, name='expobanner-paid-turn'), |
||||||
|
url(r'^paid/(?P<pk>\d+)/stat/$', PaidStat.as_view(), name='expobanner_stat_paid'), |
||||||
|
# top |
||||||
|
url(r'^top/list/$', TopList.as_view(), name='expobanner-list_top'), |
||||||
|
url(r'^top/(?P<pk>\d+)/edit/$', PaidUpdate.as_view(), name='expobanner-update_top'), |
||||||
|
url(r'^top/$', TopCreate.as_view(), name='expobanner-create_top'), |
||||||
|
url(r'^top/(?P<pk>\d+)/stat/$', PaidStat.as_view(), name='expobanner_stat_top'), |
||||||
|
) |
||||||
@ -0,0 +1,181 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from django import forms |
||||||
|
from expobanner.models import URL, BannerGroup, Banner, Paid, Top |
||||||
|
from exposition.models import Exposition |
||||||
|
from country.models import Country |
||||||
|
from city.models import City |
||||||
|
from theme.models import Theme, Tag |
||||||
|
|
||||||
|
|
||||||
|
class UrlCreateForm(forms.ModelForm): |
||||||
|
verbose = u'Создать урл' |
||||||
|
class Meta: |
||||||
|
model = URL |
||||||
|
exclude = ['created_at', 'updated_at', 'sites'] |
||||||
|
|
||||||
|
|
||||||
|
class BannerCreateGroupForm(forms.ModelForm): |
||||||
|
verbose = u'Создать групу' |
||||||
|
class Meta: |
||||||
|
model = BannerGroup |
||||||
|
exclude = ['created_at', 'updated_at', 'speed'] |
||||||
|
|
||||||
|
class BannerGroupUpdateForm(BannerCreateGroupForm): |
||||||
|
verbose = u'Изменить групу' |
||||||
|
class Meta: |
||||||
|
model = BannerGroup |
||||||
|
exclude = ['created_at', 'updated_at', 'slug', 'speed'] |
||||||
|
|
||||||
|
|
||||||
|
class BannerCreateForm(forms.ModelForm): |
||||||
|
verbose = u'Создать банер' |
||||||
|
#country = forms.ChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) |
||||||
|
#theme = forms.ChoiceField(label=u'Тематика', required=False, |
||||||
|
# choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) |
||||||
|
#city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) |
||||||
|
#tag = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = Banner |
||||||
|
exclude = ['created_at', 'updated_at', 'often', 'paid', 'stat_pswd'] |
||||||
|
|
||||||
|
|
||||||
|
class ClientStatForm(forms.Form): |
||||||
|
stat_pswd = forms.CharField(label=u'Введите пароль:') |
||||||
|
|
||||||
|
def check_pass(self, obj): |
||||||
|
pswd = self.cleaned_data['stat_pswd'] |
||||||
|
return obj.stat_pswd == pswd |
||||||
|
|
||||||
|
|
||||||
|
class PaidCreateForm(forms.ModelForm): |
||||||
|
verbose = u'Создать проплаченую выставку' |
||||||
|
exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput()) |
||||||
|
tickets = forms.URLField(label=u'Линк на билеты') |
||||||
|
participation = forms.URLField(label=u'Линк на участие') |
||||||
|
official = forms.URLField(label=u'Линк на официальный сайт') |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = Paid |
||||||
|
fields = ['logo', 'organiser', 'public'] |
||||||
|
|
||||||
|
def save(self, commit=True): |
||||||
|
paid = super(PaidCreateForm, self).save(commit=False) |
||||||
|
if commit: |
||||||
|
expo = self.cleaned_data['exposition'] |
||||||
|
tickets = self.cleaned_data['tickets'] |
||||||
|
tickets_link = Banner.objects.create_for_paid(expo, tickets, 'tickets') |
||||||
|
participation = self.cleaned_data['participation'] |
||||||
|
participation_link = Banner.objects.create_for_paid(expo, participation, 'participation') |
||||||
|
official = self.cleaned_data['official'] |
||||||
|
official_link = Banner.objects.create_for_paid(expo, official, 'official') |
||||||
|
catalog = expo.get_permanent_url() |
||||||
|
catalog_link = Banner.objects.create_for_paid(expo, catalog, 'catalog') |
||||||
|
|
||||||
|
|
||||||
|
paid.tickets = tickets_link |
||||||
|
paid.participation = participation_link |
||||||
|
paid.official = official_link |
||||||
|
paid.catalog = catalog_link |
||||||
|
paid.save() |
||||||
|
|
||||||
|
expo.paid_new = paid |
||||||
|
expo.save() |
||||||
|
return paid |
||||||
|
|
||||||
|
def clean_exposition(self): |
||||||
|
expo_id = self.cleaned_data['exposition'] |
||||||
|
try: |
||||||
|
expo = Exposition.objects.get(id=expo_id) |
||||||
|
except Exposition.DoesNotExist: |
||||||
|
raise forms.ValidationError(u'Такой выставки не существует') |
||||||
|
return expo |
||||||
|
|
||||||
|
class PaidUpdateForm(forms.ModelForm): |
||||||
|
tickets = forms.URLField(label=u'Линк на билеты') |
||||||
|
participation = forms.URLField(label=u'Линк на участие') |
||||||
|
official = forms.URLField(label=u'Линк на официальный сайт') |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = Paid |
||||||
|
fields = ['logo', 'organiser', 'public'] |
||||||
|
|
||||||
|
def save(self, commit=True): |
||||||
|
paid = super(PaidUpdateForm, self).save(commit=False) |
||||||
|
if commit: |
||||||
|
tickets = self.cleaned_data['tickets'] |
||||||
|
b_tickets = paid.tickets |
||||||
|
if tickets != b_tickets.url: |
||||||
|
b_tickets.url = tickets |
||||||
|
b_tickets.save() |
||||||
|
|
||||||
|
participation = self.cleaned_data['participation'] |
||||||
|
b_participation = paid.participation |
||||||
|
if participation != b_participation.url: |
||||||
|
b_participation.url = participation |
||||||
|
b_participation.save() |
||||||
|
|
||||||
|
official = self.cleaned_data['official'] |
||||||
|
b_official = paid.official |
||||||
|
if official != b_official.url: |
||||||
|
b_official.url = official |
||||||
|
b_official.save() |
||||||
|
|
||||||
|
paid.save() |
||||||
|
|
||||||
|
return paid |
||||||
|
|
||||||
|
|
||||||
|
class TopCreateForm(forms.ModelForm): |
||||||
|
verbose = u'Создать выставку в топе' |
||||||
|
exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput()) |
||||||
|
country = forms.MultipleChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) |
||||||
|
theme = forms.MultipleChoiceField(label=u'Тематика', required=False, |
||||||
|
choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) |
||||||
|
excluded_cities = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) |
||||||
|
excluded_tags = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) |
||||||
|
class Meta: |
||||||
|
model = Top |
||||||
|
fields = ['catalog', 'position', 'theme', 'excluded_tags', 'country', 'excluded_cities', 'fr', 'to'] |
||||||
|
|
||||||
|
def save(self, commit=True): |
||||||
|
top = super(TopCreateForm, self).save(commit=False) |
||||||
|
# Prepare a 'save_m2m' method for the form, |
||||||
|
old_save_m2m = self.save_m2m |
||||||
|
|
||||||
|
def save_m2m(): |
||||||
|
old_save_m2m() |
||||||
|
# This is where we actually link the pizza with toppings |
||||||
|
top.theme.clear() |
||||||
|
for theme in self.cleaned_data['theme']: |
||||||
|
top.theme.add(theme) |
||||||
|
|
||||||
|
self.save_m2m = save_m2m |
||||||
|
|
||||||
|
if commit: |
||||||
|
expo = self.cleaned_data['exposition'] |
||||||
|
top.save() |
||||||
|
self.save_m2m() |
||||||
|
expo.top = top |
||||||
|
expo.save() |
||||||
|
return top |
||||||
|
|
||||||
|
def clean_theme(self): |
||||||
|
theme_ids = self.cleaned_data['theme'] |
||||||
|
if theme_ids: |
||||||
|
return Theme.objects.filter(id__in=theme_ids) |
||||||
|
return None |
||||||
|
|
||||||
|
def clean_country(self): |
||||||
|
country_ids = self.cleaned_data['country'] |
||||||
|
if country_ids: |
||||||
|
return Country.objects.filter(id__in=country_ids) |
||||||
|
return None |
||||||
|
|
||||||
|
def clean_exposition(self): |
||||||
|
expo_id = self.cleaned_data['exposition'] |
||||||
|
try: |
||||||
|
expo = Exposition.objects.get(id=expo_id) |
||||||
|
except Exposition.DoesNotExist: |
||||||
|
raise forms.ValidationError(u'Такой выставки не существует') |
||||||
|
return expo |
||||||
@ -0,0 +1 @@ |
|||||||
|
__author__ = 'kotzilla' |
||||||
@ -0,0 +1 @@ |
|||||||
|
__author__ = 'kotzilla' |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from datetime import date, timedelta |
||||||
|
from django.core.management.base import BaseCommand |
||||||
|
from expobanner.models import Log, LogStat, Banner |
||||||
|
from django.conf import settings |
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand): |
||||||
|
def handle(self, *args, **options): |
||||||
|
prev_day = date.today() - timedelta(days=1) |
||||||
|
for banner in Banner.objects.select_related('group').filter(): |
||||||
|
try: |
||||||
|
logstat = LogStat.objects.get(banner=banner, group=banner.group, date=prev_day) |
||||||
|
except LogStat.DoesNotExist: |
||||||
|
logstat = LogStat(banner=banner, group=banner.group, date=prev_day) |
||||||
|
|
||||||
|
views = Log.objects.filter(datetime__startswith=prev_day, |
||||||
|
banner=banner, |
||||||
|
group=banner.group, |
||||||
|
type=1).count() |
||||||
|
clicks = Log.objects.filter(datetime__startswith=prev_day, |
||||||
|
banner=banner, |
||||||
|
group=banner.group, |
||||||
|
type=2).count() |
||||||
|
unique_views = Log.objects.filter(datetime__startswith=prev_day, |
||||||
|
banner=banner, |
||||||
|
group=banner.group, |
||||||
|
type=1).values('ip').distinct().count() |
||||||
|
unique_clicks = Log.objects.filter(datetime__startswith=prev_day, |
||||||
|
banner=banner, |
||||||
|
group=banner.group, |
||||||
|
type=2).values('ip').distinct().count() |
||||||
|
|
||||||
|
if not logstat.click or logstat.click < clicks: |
||||||
|
logstat.click = clicks |
||||||
|
if not logstat.view or logstat.view < views: |
||||||
|
logstat.view = views |
||||||
|
if not logstat.unique_click or logstat.unique_click < unique_clicks: |
||||||
|
logstat.unique_click = unique_clicks |
||||||
|
if not logstat.unique_view or logstat.unique_view < unique_views: |
||||||
|
logstat.unique_view = unique_views |
||||||
|
logstat.save() |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from datetime import date |
||||||
|
from django.core.management.base import BaseCommand |
||||||
|
from expobanner.models import Log, LogStat, Banner, PaidStat |
||||||
|
from exposition.models import Exposition |
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand): |
||||||
|
def handle(self, *args, **options): |
||||||
|
today = date.today() |
||||||
|
# banners |
||||||
|
for banner in Banner.objects.select_related('group').filter(public=True, group__isnull=False): |
||||||
|
try: |
||||||
|
logstat = LogStat.objects.get(banner=banner, group=banner.group, date=today) |
||||||
|
except LogStat.DoesNotExist: |
||||||
|
logstat = LogStat(banner=banner, group=banner.group, date=today) |
||||||
|
|
||||||
|
views = Log.objects.filter(datetime__startswith=today, |
||||||
|
banner=banner, |
||||||
|
group=banner.group, |
||||||
|
type=1).count() |
||||||
|
clicks = Log.objects.filter(datetime__startswith=today, |
||||||
|
banner=banner, |
||||||
|
group=banner.group, |
||||||
|
type=2).count() |
||||||
|
unique_views = Log.objects.filter(datetime__startswith=today, |
||||||
|
banner=banner, |
||||||
|
group=banner.group, |
||||||
|
type=1).values('ip').distinct().count() |
||||||
|
unique_clicks = Log.objects.filter(datetime__startswith=today, |
||||||
|
banner=banner, |
||||||
|
group=banner.group, |
||||||
|
type=2).values('ip').distinct().count() |
||||||
|
logstat.click = clicks |
||||||
|
logstat.view = views |
||||||
|
logstat.unique_click = unique_clicks |
||||||
|
logstat.unique_view = unique_views |
||||||
|
logstat.save() |
||||||
|
|
||||||
|
# paid expos |
||||||
|
expos = list(Exposition.objects.select_related('paid_new').filter(paid_new__isnull=False)) |
||||||
|
for expo in expos: |
||||||
|
paid = expo.paid_new |
||||||
|
try: |
||||||
|
paidstat = PaidStat.objects.get(paid=paid, date=today) |
||||||
|
except PaidStat.DoesNotExist: |
||||||
|
paidstat = PaidStat(paid=paid, date=today) |
||||||
|
|
||||||
|
t_clicks = Log.objects.filter(datetime__startswith=today, banner=paid.tickets, type=2).count() |
||||||
|
p_clicks = Log.objects.filter(datetime__startswith=today, banner=paid.participation, type=2).count() |
||||||
|
o_clicks = Log.objects.filter(datetime__startswith=today, banner=paid.official, type=2).count() |
||||||
|
c_clicks = Log.objects.filter(datetime__startswith=today, banner=paid.catalog, type=2).count() |
||||||
|
|
||||||
|
paidstat.tickets_clicks = t_clicks |
||||||
|
paidstat.participation_clicks = p_clicks |
||||||
|
paidstat.official_clicks = o_clicks |
||||||
|
paidstat.catalog_clicks = c_clicks |
||||||
|
|
||||||
|
paidstat.save() |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,77 @@ |
|||||||
|
# -*- coding: utf-8 -* |
||||||
|
from datetime import date |
||||||
|
from random import choice, shuffle |
||||||
|
from django.db import models |
||||||
|
from django.db.models import Q |
||||||
|
from django.core.cache import cache |
||||||
|
|
||||||
|
|
||||||
|
class BiasedManager(models.Manager): |
||||||
|
def by_time(self, **kwargs): |
||||||
|
all = super(BiasedManager, self).get_query_set().filter(**kwargs) |
||||||
|
result = [] |
||||||
|
for i in all: |
||||||
|
for j in range(i.often): |
||||||
|
result.append(i) |
||||||
|
return result |
||||||
|
|
||||||
|
def one(self, **kwargs): |
||||||
|
return choice(self.by_time(**kwargs)) |
||||||
|
|
||||||
|
def by_often(self, **kwargs): |
||||||
|
result = self.by_time(**kwargs) |
||||||
|
shuffle(result) |
||||||
|
return result |
||||||
|
|
||||||
|
def create_for_paid(self, expo, url, role): |
||||||
|
try: |
||||||
|
name = str(expo.name) |
||||||
|
except UnicodeEncodeError, UnicodeDecodeError: |
||||||
|
name = expo.url |
||||||
|
|
||||||
|
alt = u'%s_%s'%(name, role) |
||||||
|
return self.create(alt=alt, url=url, paid=True) |
||||||
|
|
||||||
|
class BannerGroupCached(models.Manager): |
||||||
|
def all(self): |
||||||
|
key = 'banner_group_all' |
||||||
|
result = cache.get(key) |
||||||
|
if not result: |
||||||
|
result = list(self.filter(public=True)) |
||||||
|
cache.set(key, result, 90) |
||||||
|
return result |
||||||
|
|
||||||
|
def group_banners(self): |
||||||
|
key = 'banner_group_banners' |
||||||
|
result = cache.get(key) |
||||||
|
if not result: |
||||||
|
groups = self.all() |
||||||
|
today = date.today() |
||||||
|
result = {} |
||||||
|
for group in groups: |
||||||
|
result[group.slug] = list(group.banners.prefetch_related('urls', 'theme', 'country')\ |
||||||
|
.filter(public=True, fr__lte=today)\ |
||||||
|
.filter(Q(to__gte=today) | Q(to__isnull=True)).extra({})) |
||||||
|
cache.set(key, result, 70) |
||||||
|
|
||||||
|
return result |
||||||
|
|
||||||
|
|
||||||
|
class URLCached(models.Manager): |
||||||
|
def all(self): |
||||||
|
key = 'banner_url_all' |
||||||
|
result = cache.get(key) |
||||||
|
if not result: |
||||||
|
result = list(self.filter(public=True)) |
||||||
|
cache.set(key, result, 150) |
||||||
|
return result |
||||||
|
|
||||||
|
class TopCached(models.Manager): |
||||||
|
def all(self): |
||||||
|
key = 'expo_b_top_all' |
||||||
|
result = cache.get(key) |
||||||
|
if not result: |
||||||
|
result = list(self.prefetch_related('theme', 'country', 'excluded_tags', 'excluded_cities').all()) |
||||||
|
cache.set(key, result, 80) |
||||||
|
|
||||||
|
return result |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
class StatMixin(object): |
||||||
|
def get_cookie_name(self): |
||||||
|
return u'%s_%d'%(self._meta.db_table, self.id) |
||||||
@ -0,0 +1,294 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
import random |
||||||
|
import hashlib |
||||||
|
from datetime import datetime, date |
||||||
|
from django.db import models |
||||||
|
from django.utils.translation import ugettext_lazy as _ |
||||||
|
from django.conf import settings |
||||||
|
from django.contrib.sites.models import Site |
||||||
|
from django.db.models.signals import post_save |
||||||
|
from .managers import BiasedManager, BannerGroupCached, URLCached, TopCached |
||||||
|
from .mixins import StatMixin |
||||||
|
from theme.models import Theme |
||||||
|
from country.models import Country |
||||||
|
|
||||||
|
|
||||||
|
class URL(models.Model): |
||||||
|
title = models.CharField(verbose_name=u'Заголовок', max_length=256) |
||||||
|
url = models.CharField(verbose_name=u'URL or URL RegEx', max_length=2048) |
||||||
|
regex = models.BooleanField(verbose_name=u'RegEx', default=False) |
||||||
|
sites = models.ManyToManyField(Site, related_name='site_urls', verbose_name=_('Sites'), null=True, blank=True) |
||||||
|
|
||||||
|
public = models.BooleanField(verbose_name=u'Активный', default=True) |
||||||
|
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) |
||||||
|
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) |
||||||
|
|
||||||
|
objects = models.Manager() |
||||||
|
cached = URLCached() |
||||||
|
|
||||||
|
def __unicode__(self): |
||||||
|
return self.title |
||||||
|
|
||||||
|
class Meta: |
||||||
|
ordering = ['-created_at'] |
||||||
|
verbose_name = _('URL') |
||||||
|
verbose_name_plural = _('URLs') |
||||||
|
|
||||||
|
def get_admin_url(self): |
||||||
|
return '/admin/expobanners/banners/url/%d/edit/'%self.id |
||||||
|
|
||||||
|
|
||||||
|
class BannerGroup (models.Model): |
||||||
|
name = models.CharField(verbose_name=u'Имя', max_length=255) |
||||||
|
slug = models.SlugField(verbose_name=u'URL', unique=True) |
||||||
|
width = models.PositiveSmallIntegerField(verbose_name=u'Ширина', default=0) |
||||||
|
height = models.PositiveSmallIntegerField(verbose_name=u'Высота', default=0) |
||||||
|
speed = models.PositiveSmallIntegerField(verbose_name=u'Скорость отображения', default=2000) |
||||||
|
|
||||||
|
public = models.BooleanField(verbose_name=u'Активная', default=True) |
||||||
|
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) |
||||||
|
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) |
||||||
|
|
||||||
|
objects = models.Manager() |
||||||
|
cached = BannerGroupCached() |
||||||
|
|
||||||
|
def size(self): |
||||||
|
return '%sx%s' % (self.width, self.height) |
||||||
|
|
||||||
|
def __unicode__(self): |
||||||
|
return '%s - [%s x %s]' % (self.name, self.width, self.height) |
||||||
|
|
||||||
|
class Meta: |
||||||
|
ordering = ['name'] |
||||||
|
verbose_name = _('Banner Group') |
||||||
|
verbose_name_plural = _('Banner Groups') |
||||||
|
|
||||||
|
def get_admin_url(self): |
||||||
|
return '/admin/expobanners/banners/group/%d/edit/'%self.id |
||||||
|
|
||||||
|
|
||||||
|
class Banner(models.Model, StatMixin): |
||||||
|
objects = BiasedManager() |
||||||
|
|
||||||
|
title = models.CharField(verbose_name=u'Заголовок', max_length=255, blank=True) |
||||||
|
alt = models.CharField(verbose_name=_('Alt'), max_length=255) |
||||||
|
|
||||||
|
text = models.TextField(verbose_name=u'Текст', blank=True, null=True) |
||||||
|
img = models.FileField(verbose_name=u'Картинка', upload_to='expo_upload', blank=True, null=True) |
||||||
|
url = models.CharField(verbose_name=u'URL', max_length=1024) |
||||||
|
fr = models.DateField(default=date.today()) |
||||||
|
to = models.DateField(blank=True, null=True) |
||||||
|
|
||||||
|
theme = models.ManyToManyField(Theme, blank=True, null=True, verbose_name=u'Тематика') |
||||||
|
country = models.ManyToManyField(Country, blank=True, null=True, verbose_name=u'Страна') |
||||||
|
|
||||||
|
sort = models.PositiveSmallIntegerField(verbose_name=u'Сорт', default=500) |
||||||
|
|
||||||
|
group = models.ForeignKey(BannerGroup, related_name='banners', verbose_name=u'Место', null=True, blank=True) |
||||||
|
often = models.PositiveSmallIntegerField( |
||||||
|
verbose_name=_('Often'), |
||||||
|
help_text=_('A ten will display 10 times more often that a one.'), |
||||||
|
choices=[[i, i] for i in range(11)], |
||||||
|
default=1 |
||||||
|
) |
||||||
|
urls = models.ManyToManyField(URL, related_name='url_banners', verbose_name=_('URLs'), null=True, blank=True) |
||||||
|
|
||||||
|
html = models.BooleanField(verbose_name=_('HTML?'), default=False) |
||||||
|
flash = models.BooleanField(verbose_name=_('Flash?'), default=False) |
||||||
|
js = models.BooleanField(verbose_name=_('Javascript?'), default=False) |
||||||
|
paid = models.BooleanField(verbose_name=_('Is Paid event link?'), default=False) |
||||||
|
|
||||||
|
public = models.BooleanField(verbose_name=u'Активный', default=True) |
||||||
|
created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) |
||||||
|
updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) |
||||||
|
|
||||||
|
stat_pswd = models.CharField(max_length=16) |
||||||
|
|
||||||
|
class Meta: |
||||||
|
ordering = ['-public'] |
||||||
|
|
||||||
|
def get_admin_url(self): |
||||||
|
return '/admin/expobanners/banners/banner/%d/edit/'%self.id |
||||||
|
|
||||||
|
|
||||||
|
def key(slef): |
||||||
|
if hasattr(settings, 'SECRET_KEY'): |
||||||
|
key = str(datetime.now()) + settings.SECRET_KEY |
||||||
|
else: |
||||||
|
key = str(datetime.now()) |
||||||
|
return hashlib.md5(key).hexdigest() |
||||||
|
|
||||||
|
def log(self, request, type): |
||||||
|
log = { |
||||||
|
'type': type, |
||||||
|
'banner': self, |
||||||
|
'group': self.group, |
||||||
|
'ip': request.META.get('REMOTE_ADDR'), |
||||||
|
'user_agent': request.META.get('HTTP_USER_AGENT'), |
||||||
|
'page': request.META.get('HTTP_REFERER'), |
||||||
|
} |
||||||
|
|
||||||
|
if request.user.is_authenticated(): |
||||||
|
log['user'] = request.user |
||||||
|
return Log.objects.create(**log) |
||||||
|
|
||||||
|
@models.permalink |
||||||
|
def image(self): |
||||||
|
return ('banner_view', (), {'banner_id': self.pk, 'key': self.key()}) |
||||||
|
|
||||||
|
def impressions(self): |
||||||
|
return Log.objects.filter(banner=self.pk, type=0).count() |
||||||
|
|
||||||
|
def views(self): |
||||||
|
return Log.objects.filter(banner=self.pk, type=1).count() |
||||||
|
|
||||||
|
def clicks(self): |
||||||
|
return Log.objects.filter(banner=self.pk, type=2).count() |
||||||
|
|
||||||
|
def __unicode__(self): |
||||||
|
return self.title or self.alt |
||||||
|
|
||||||
|
def get_absolute_url(self): |
||||||
|
if self.url == '#': |
||||||
|
return self.url |
||||||
|
else: |
||||||
|
@models.permalink |
||||||
|
def get_absolute_url(self): |
||||||
|
return ('banner_click', (), {'banner_id': self.pk, 'key': self.key()}) |
||||||
|
return get_absolute_url(self) |
||||||
|
|
||||||
|
def get_click_link(self): |
||||||
|
return '/expo-b/click/%d/'%self.id |
||||||
|
|
||||||
|
class Meta: |
||||||
|
ordering = ['sort'] |
||||||
|
verbose_name = _('Banner') |
||||||
|
verbose_name_plural = _('Banners') |
||||||
|
|
||||||
|
|
||||||
|
class Log(models.Model): |
||||||
|
banner = models.ForeignKey(Banner, related_name='banner_logs') |
||||||
|
group = models.ForeignKey(BannerGroup, related_name='group_logs', verbose_name=_('Group'), blank=True, null=True) |
||||||
|
urls = models.ManyToManyField(URL, related_name='url_logs', verbose_name=_('URLs'), blank=True) |
||||||
|
|
||||||
|
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='users', verbose_name=_('User')) |
||||||
|
datetime = models.DateTimeField(verbose_name=_('Clicked At'), auto_now_add=True) |
||||||
|
ip = models.IPAddressField(verbose_name=_('IP'), null=True, blank=True) |
||||||
|
user_agent = models.CharField(verbose_name=_('User Agent'), max_length=1024, null=True, blank=True) |
||||||
|
page = models.URLField(verbose_name=_('Page'), null=True, blank=True) |
||||||
|
key = models.CharField(verbose_name=_('User Agent'), max_length=32, null=True, blank=True) |
||||||
|
TYPE_CHOICES = ( |
||||||
|
(0, 'impressions'), |
||||||
|
(1, 'view'), |
||||||
|
(2, 'click') |
||||||
|
) |
||||||
|
|
||||||
|
type = models.PositiveSmallIntegerField(verbose_name=_('Type'), max_length=1, default=0, choices=TYPE_CHOICES) |
||||||
|
|
||||||
|
def __unicode__(self): |
||||||
|
return '%s - (%s)' % (self.banner, self.datetime) |
||||||
|
|
||||||
|
|
||||||
|
class LogStat(models.Model): |
||||||
|
banner = models.ForeignKey(Banner, related_name='banner_stat', verbose_name=_('Banner'), blank=True) |
||||||
|
group = models.ForeignKey(BannerGroup, related_name='group_stat', verbose_name=_('Group'), blank=True, null=True) |
||||||
|
urls = models.ManyToManyField(URL, related_name='url_bloks', verbose_name=_('URLs'), null=True, blank=True) |
||||||
|
|
||||||
|
date = models.DateField(verbose_name=_('Data')) |
||||||
|
view = models.PositiveIntegerField(verbose_name=_('Views')) |
||||||
|
click = models.PositiveIntegerField(verbose_name=_('Clicks')) |
||||||
|
unique_click = models.PositiveIntegerField(verbose_name=_('Unique Views'), blank=True, null=True) |
||||||
|
unique_view = models.PositiveIntegerField(verbose_name=_('Unique Clicks')) |
||||||
|
|
||||||
|
def __unicode__(self): |
||||||
|
return '%s - (%s)' % (self.banner, self.date) |
||||||
|
|
||||||
|
|
||||||
|
# ------------------ |
||||||
|
class Paid(models.Model, StatMixin): |
||||||
|
tickets = models.ForeignKey(Banner, related_name='paid_tickets') |
||||||
|
participation = models.ForeignKey(Banner, related_name='paid_participation') |
||||||
|
official = models.ForeignKey(Banner, related_name='paid_official') |
||||||
|
catalog = models.ForeignKey(Banner, related_name='paid_catalog') |
||||||
|
logo = models.ImageField(upload_to='expo-b/paid', blank=True) |
||||||
|
organiser = models.CharField(max_length=100, blank=True) |
||||||
|
public = models.BooleanField(default=True, verbose_name=u'Активная') |
||||||
|
stat_pswd = models.CharField(max_length=16) |
||||||
|
created = models.DateTimeField(auto_now_add=True) |
||||||
|
modified = models.DateTimeField(auto_now=True) |
||||||
|
|
||||||
|
class Meta: |
||||||
|
ordering = ['-public'] |
||||||
|
|
||||||
|
def get_event(self): |
||||||
|
if self.exposition_set.all().exists(): |
||||||
|
return self.exposition_set.all()[0] |
||||||
|
return None |
||||||
|
|
||||||
|
|
||||||
|
class PaidStat(models.Model): |
||||||
|
paid = models.ForeignKey(Paid) |
||||||
|
date = models.DateField(verbose_name=_('Date')) |
||||||
|
page_views = models.PositiveIntegerField(default=0) |
||||||
|
price_views = models.PositiveIntegerField(default=0) |
||||||
|
catalog_views = models.PositiveIntegerField(default=0) |
||||||
|
catalog_clicks = models.PositiveIntegerField(default=0) |
||||||
|
tickets_clicks = models.PositiveIntegerField(default=0) |
||||||
|
participation_clicks = models.PositiveIntegerField(default=0) |
||||||
|
official_clicks = models.PositiveIntegerField(default=0) |
||||||
|
|
||||||
|
|
||||||
|
class Top(models.Model, StatMixin): |
||||||
|
catalog = models.CharField(max_length=16, verbose_name=u'Каталог для топа') |
||||||
|
position = models.PositiveIntegerField(blank=True, default=2, null=True, verbose_name=u'Позиция') |
||||||
|
theme = models.ManyToManyField('theme.Theme', blank=True, null=True, verbose_name=u'Тематики') |
||||||
|
excluded_tags = models.ManyToManyField('theme.Tag', blank=True, null=True, verbose_name=u'Исключить теги') |
||||||
|
country = models.ManyToManyField('country.Country', blank=True, null=True, verbose_name=u'Страны') |
||||||
|
excluded_cities = models.ManyToManyField('city.City', blank=True, null=True, verbose_name=u'Исключить города') |
||||||
|
fr = models.DateField(default=date.today(), verbose_name=u'Начало') |
||||||
|
to = models.DateField(blank=True, null=True, verbose_name=u'Конец') |
||||||
|
stat_pswd = models.CharField(max_length=16) |
||||||
|
|
||||||
|
objects = models.Manager() |
||||||
|
cached = TopCached() |
||||||
|
|
||||||
|
class Meta: |
||||||
|
ordering = ['position'] |
||||||
|
|
||||||
|
|
||||||
|
class TopStat(models.Model): |
||||||
|
date = models.DateField() |
||||||
|
theme = models.ForeignKey('theme.Theme', blank=True, null=True) |
||||||
|
tag = models.ForeignKey('theme.Tag', blank=True, null=True) |
||||||
|
country = models.ForeignKey('country.Country', blank=True, null=True) |
||||||
|
city = models.ForeignKey('city.City', blank=True, null=True) |
||||||
|
views = models.PositiveIntegerField(default=0) |
||||||
|
clicks = models.PositiveIntegerField(default=0) |
||||||
|
|
||||||
|
def generatePassword(length=5): |
||||||
|
""" |
||||||
|
generate random password |
||||||
|
""" |
||||||
|
SYMBOLS = [',', '.', '?', '!', '-', '+', '1', '2', '3', '4', '5', '6', '7', '8', |
||||||
|
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', |
||||||
|
'm', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', |
||||||
|
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', |
||||||
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#'] |
||||||
|
PASSWORD_LENGTH = length |
||||||
|
newPassword = [] |
||||||
|
for i in range(PASSWORD_LENGTH): |
||||||
|
newPassword.append(SYMBOLS[random.randrange(0, len(SYMBOLS))]) |
||||||
|
return ''.join(newPassword) |
||||||
|
|
||||||
|
|
||||||
|
def generate_stat_pass(sender, **kwargs): |
||||||
|
obj = kwargs['instance'] |
||||||
|
if not obj.stat_pswd: |
||||||
|
obj.stat_pswd = generatePassword() |
||||||
|
obj.save() |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
post_save.connect(generate_stat_pass, sender=Banner) |
||||||
|
post_save.connect(generate_stat_pass, sender=Paid) |
||||||
|
post_save.connect(generate_stat_pass, sender=Top) |
||||||
@ -0,0 +1,57 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from django.http import HttpResponseRedirect |
||||||
|
from django.views.generic import TemplateView, CreateView, ListView, UpdateView, DetailView |
||||||
|
from django.views.generic.edit import FormMixin |
||||||
|
from django.forms.util import ErrorList |
||||||
|
from django.conf import settings |
||||||
|
from django.core.urlresolvers import reverse |
||||||
|
from expobanner.models import Banner, Paid |
||||||
|
from expobanner.forms import ClientStatForm |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BannerStat(FormMixin, DetailView): |
||||||
|
model = Banner |
||||||
|
form_class = ClientStatForm |
||||||
|
template_name = 'client/expobanners/banner_stat.html' |
||||||
|
|
||||||
|
def get_success_url(self): |
||||||
|
return reverse('banner_stat_client', kwargs={'pk': self.object.pk}) |
||||||
|
|
||||||
|
def get_context_data(self, **kwargs): |
||||||
|
context = super(BannerStat, self).get_context_data(**kwargs) |
||||||
|
obj = self.object |
||||||
|
cookie_name = obj.get_cookie_name() |
||||||
|
cookie = self.request.session.get(cookie_name) |
||||||
|
if not cookie: |
||||||
|
form = context.get('form') |
||||||
|
# form in context if form invalid called |
||||||
|
if not form: |
||||||
|
context['form'] = self.get_form(self.form_class) |
||||||
|
|
||||||
|
return context |
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs): |
||||||
|
self.object = self.get_object() |
||||||
|
form = self.get_form(self.form_class) |
||||||
|
if form.is_valid(): |
||||||
|
return self.form_valid(form) |
||||||
|
else: |
||||||
|
return self.form_invalid(form) |
||||||
|
|
||||||
|
def form_valid(self, form): |
||||||
|
obj = self.object |
||||||
|
success = form.check_pass(obj) |
||||||
|
if success: |
||||||
|
self.request.session[obj.get_cookie_name()] = 1 |
||||||
|
return HttpResponseRedirect(self.get_success_url()) |
||||||
|
else: |
||||||
|
form.errors['stat_pswd'] = ErrorList([u'Неправильный пароль']) |
||||||
|
return self.form_invalid(form) |
||||||
|
|
||||||
|
class PaidStat(BannerStat): |
||||||
|
model = Paid |
||||||
|
template_name = 'client/expobanners/paid_stat.html' |
||||||
|
|
||||||
|
def get_success_url(self): |
||||||
|
return reverse('paid_stat_client', kwargs={'pk': self.object.pk}) |
||||||
@ -0,0 +1,159 @@ |
|||||||
|
/* |
||||||
|
************************** |
||||||
|
* =COMMON |
||||||
|
************************** |
||||||
|
*/ |
||||||
|
.b-slider { |
||||||
|
position: relative; |
||||||
|
display: block; |
||||||
|
overflow: hidden; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
width: 725px; |
||||||
|
height: 360px; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-list { |
||||||
|
position: absolute; |
||||||
|
display: block; |
||||||
|
overflow: hidden; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
width: 725px; |
||||||
|
height: 360px; |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-item { |
||||||
|
position: absolute; |
||||||
|
z-index: 50; |
||||||
|
float: left; |
||||||
|
overflow: hidden; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
width: 725px; |
||||||
|
height: 360px; |
||||||
|
} |
||||||
|
|
||||||
|
.m-slider-current { |
||||||
|
z-index: 100; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-item__img, |
||||||
|
.b-slider-item__title, |
||||||
|
.b-slider-item__text { |
||||||
|
position: absolute; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-item__img { |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-item__link { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-item__title { |
||||||
|
bottom: 10px; |
||||||
|
left: 10px; |
||||||
|
width: 500px; |
||||||
|
color: #333; |
||||||
|
text-transform: uppercase; |
||||||
|
text-shadow: 0 0 3px #fff, 0 0 2px #fff, 0 0 1px #fff; |
||||||
|
letter-spacing: -5px; |
||||||
|
font-size: 65px; |
||||||
|
font-family: Calibri; |
||||||
|
line-height: 0.8em; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-item__text { |
||||||
|
position: absolute; |
||||||
|
top: 150px; |
||||||
|
left: 300px; |
||||||
|
display: inline-block; |
||||||
|
display: none; |
||||||
|
margin: -10px; |
||||||
|
padding: 10px; |
||||||
|
max-width: 300px; |
||||||
|
border-radius: 10px; |
||||||
|
background: rgba(255, 255, 255, 0.5); |
||||||
|
box-shadow: 0 0 5px #fff; |
||||||
|
color: #555; |
||||||
|
line-height: 1.5em; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
************************** |
||||||
|
* =NAV |
||||||
|
************************** |
||||||
|
*/ |
||||||
|
.b-slider-nav { |
||||||
|
position: absolute; |
||||||
|
width: 100%; |
||||||
|
top: 10px; |
||||||
|
height: 30px; |
||||||
|
left: 0; |
||||||
|
z-index: 500; |
||||||
|
display: block; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
list-style-type: none; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-nav-button { |
||||||
|
display: inline-block; |
||||||
|
margin: 5px; |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
border-radius: 8px; |
||||||
|
background: #ddd; |
||||||
|
color: transparent; |
||||||
|
text-align: center; |
||||||
|
font-weight: bold; |
||||||
|
font-size: 8px; |
||||||
|
line-height: 16px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-nav-button:hover { |
||||||
|
background: #eee; |
||||||
|
} |
||||||
|
|
||||||
|
.m-slider-nav-current_button { |
||||||
|
background: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-nav-prev, |
||||||
|
.b-slider-nav-next { |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
z-index: 500; |
||||||
|
padding-right: 20px; |
||||||
|
padding-left: 20px; |
||||||
|
color: #000; |
||||||
|
text-shadow: 0 0 3px #fff, 0 0 2px #fff, 0 0 1px #fff; |
||||||
|
font-size: 50px; |
||||||
|
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; |
||||||
|
line-height: 360px; |
||||||
|
opacity: 0.5; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-nav-prev:hover, |
||||||
|
.b-slider-nav-next:hover { |
||||||
|
opacity: 0.8; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-nav-prev { |
||||||
|
left: 0; |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.b-slider-nav-next { |
||||||
|
right: 0; |
||||||
|
padding-right: 0; |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
|
||||||
|
$(document).ready(function() { |
||||||
|
$('.b-banner-click').on('click', function(){ |
||||||
|
$.get($(this).data('url')); |
||||||
|
}); |
||||||
|
|
||||||
|
$(".b-banner").on('load', function() { |
||||||
|
$.get($(this).data('view')); |
||||||
|
}); |
||||||
|
}); |
||||||
@ -0,0 +1,71 @@ |
|||||||
|
$.fn.bannersSlider = function(options) { |
||||||
|
$this = this; |
||||||
|
var settings = $.extend( { |
||||||
|
'auto_play': false, |
||||||
|
'effect': 'fade', |
||||||
|
'speed' : 3000 |
||||||
|
}, options); |
||||||
|
|
||||||
|
$this.current = 1; |
||||||
|
$this.old = 1; |
||||||
|
$this.len = $this.find('.b-slider-list li').length; |
||||||
|
|
||||||
|
$this.find('.b-slider-item').hide(); |
||||||
|
$this.find('.m-slider-item-1').show(); |
||||||
|
|
||||||
|
$this.fadeTo = function(new_num) { |
||||||
|
old_num = $this.old; |
||||||
|
if (new_num != old_num) { |
||||||
|
$this.find('.m-slider-item-' + new_num).hide(); |
||||||
|
$this.find('.m-slider-item-' + new_num).fadeIn(1000); |
||||||
|
$this.find('.m-slider-current').fadeOut(1000); |
||||||
|
$this.find('.m-slider-current').removeClass('m-slider-current'); |
||||||
|
$this.find('.m-slider-item-' + new_num).addClass('m-slider-current'); |
||||||
|
|
||||||
|
$this.find('.b-slider-nav-button').removeClass('m-slider-nav-current_button'); |
||||||
|
|
||||||
|
$this.find('.b-slider-nav-button[data-slide=' + new_num + ']').addClass('m-slider-nav-current_button'); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
$this.prev = function() { |
||||||
|
prev = ($this.current != 1) ? $this.current - 1 : $this.len; |
||||||
|
$this.old = $this.current; |
||||||
|
$this.current = prev; |
||||||
|
|
||||||
|
$this.fadeTo(prev); |
||||||
|
}; |
||||||
|
|
||||||
|
$this.next = function() { |
||||||
|
next = ($this.current != $this.len) ? $this.current + 1 : 1; |
||||||
|
$this.old = $this.current; |
||||||
|
$this.current = next; |
||||||
|
|
||||||
|
$this.fadeTo(next); |
||||||
|
}; |
||||||
|
|
||||||
|
$this.children('.b-slider-nav-prev').on('click', function(){ |
||||||
|
$this.prev(); |
||||||
|
}); |
||||||
|
|
||||||
|
$this.children('.b-slider-nav-next').on('click', function(){ |
||||||
|
$this.next(); |
||||||
|
}); |
||||||
|
|
||||||
|
$this.find('.b-slider-nav-button').on('click', function(){ |
||||||
|
to_slide = $(this).data('slide'); |
||||||
|
|
||||||
|
$this.old = $this.current; |
||||||
|
$this.current = to_slide; |
||||||
|
|
||||||
|
$this.fadeTo(to_slide); |
||||||
|
}); |
||||||
|
|
||||||
|
if (settings.auto_play) { |
||||||
|
setInterval(function() { |
||||||
|
$this.next(); |
||||||
|
}, settings.speed); |
||||||
|
} |
||||||
|
|
||||||
|
return $this; |
||||||
|
}; |
||||||
@ -0,0 +1,55 @@ |
|||||||
|
{% if banner.html %} |
||||||
|
{% load banner %} |
||||||
|
<div id='banner_{{ banner.id }}' class='b-banner b-banner-{{ group.slug }} m-banner__html'> |
||||||
|
{% render banner.text %} |
||||||
|
</div> |
||||||
|
{% elif banner.flash %} |
||||||
|
<div id='banner_{{ banner.id }}' class='b-banner b-banner-{{ group.slug }} m-banner__flash'> |
||||||
|
<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' |
||||||
|
codebase='http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0' |
||||||
|
width='{{ banner.group.width }}' height='{{ banner.group.height }}'> |
||||||
|
<param name='movie' value='{{ banner.img.url }}' /> |
||||||
|
<param name='quality' value='high'> |
||||||
|
<param name='play' value='true'> |
||||||
|
<param name='loop' value='true'> |
||||||
|
<param name='wmode' value='transparent'> |
||||||
|
<embed src='{{ banner.img.url }}' |
||||||
|
quality='high' |
||||||
|
bgcolor='#d0f' |
||||||
|
width='{{ banner.group.width }}' |
||||||
|
height='{{ banner.group.height }}' |
||||||
|
name='banner_{{ banner.id }}' |
||||||
|
type='application/x-shockwave-flash' |
||||||
|
play='true' |
||||||
|
loop='true' |
||||||
|
wmode='transparent' |
||||||
|
pluginspage='http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash' |
||||||
|
> |
||||||
|
</embed> |
||||||
|
</object> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script> |
||||||
|
$('#banner_{{ banner.id }}').mousedown(function() { |
||||||
|
// alert('mouse down'); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
{% else %} |
||||||
|
<a href='{{ banner.url }}' id='banner_{{ banner.id }}' class='b-banner b-banner-{{ group.slug }}'> |
||||||
|
<img src='{{ banner.img.url }}' alt='{{ banner.alt }}' title='{{ banner.title }}'> |
||||||
|
</a> |
||||||
|
{% endif %} |
||||||
|
|
||||||
|
<style> |
||||||
|
.b-banner { |
||||||
|
display: block; |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
/*border: 1px solid silver;*/ |
||||||
|
} |
||||||
|
|
||||||
|
.b-banner-{{ group.slug }} { |
||||||
|
width: {{ banner.group.width }}px; |
||||||
|
height: {{ banner.group.height }}px; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
{% load banner %} |
||||||
|
|
||||||
|
<div class="b-banner-group"> |
||||||
|
{% for banner in banners %} |
||||||
|
{% banner_one banner.id %} |
||||||
|
{% endfor %} |
||||||
|
</div> |
||||||
|
|
||||||
|
<style type="text/css"> |
||||||
|
.b-banner-group { |
||||||
|
display: block; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.b-banner { |
||||||
|
display: block; |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
/*border: 1px solid silver;*/ |
||||||
|
} |
||||||
|
|
||||||
|
.b-banner-{{ group.slug }} { |
||||||
|
width: {{ banner.group.width }}px; |
||||||
|
height: {{ banner.group.height }}px; |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
.b-banner-{{ group.slug }} img { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
{% load banner %} |
||||||
|
|
||||||
|
<div class="b-banner-group"> |
||||||
|
{% for banner in banners %} |
||||||
|
{% banner_one banner.id %} |
||||||
|
{% endfor %} |
||||||
|
<script> |
||||||
|
var arr = []; |
||||||
|
{% for banner in banners %} |
||||||
|
arr[{{ forloop.counter }}] = {'id': {{ banner.id }}, 'often': {{ banner.often }}}; |
||||||
|
{% endfor %} |
||||||
|
|
||||||
|
var length = arr.length - 1; |
||||||
|
|
||||||
|
var i = 1; |
||||||
|
var speed = {{ group.speed }}; |
||||||
|
|
||||||
|
$('.b-banner-{{ group.slug }}').hide(); |
||||||
|
$('#banner_' + arr[i]['id']).show(); |
||||||
|
total_speed = speed * arr[i]['often']; |
||||||
|
setInterval(function () { |
||||||
|
if (i < length) i++; else i = 1; |
||||||
|
|
||||||
|
total_speed = speed * arr[i]['often']; |
||||||
|
console.log (total_speed, arr[i]); |
||||||
|
$('.b-banner-{{ group.slug }}').hide(); |
||||||
|
$('#banner_' + arr[i]['id']).show(); |
||||||
|
}, speed); |
||||||
|
</script> |
||||||
|
</div> |
||||||
@ -0,0 +1,74 @@ |
|||||||
|
{% load thumbnail %} |
||||||
|
|
||||||
|
{% if banners %} |
||||||
|
|
||||||
|
<div class="b-slider m-{{ group.slug }}" id="slider-{{ group.slug }}"> |
||||||
|
<ul class='b-slider-list'> |
||||||
|
{% for banner in banners %} |
||||||
|
<li data-url='{{ banner.get_absolute_url }}' |
||||||
|
class=' |
||||||
|
b-slider-item |
||||||
|
m-slider-item-{{ forloop.counter }} |
||||||
|
{% if forloop.counter == 1 %} |
||||||
|
m-slider-current |
||||||
|
{% endif %} |
||||||
|
' |
||||||
|
data-slide='{{ forloop.counter }}' |
||||||
|
> |
||||||
|
|
||||||
|
<a href='{{ banner.get_absolute_url }}' class='b-slider-item__link'> |
||||||
|
{% thumbnail banner.img group.size crop="top" as im %} |
||||||
|
<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" alt="{{ banner.alt }}" title="{{ banner.title }}" class='b-slider-item__img' data-view='{{ banner.image }}'> |
||||||
|
{% endthumbnail %} |
||||||
|
|
||||||
|
<div class="b-slider-item__info_cover"> |
||||||
|
<span class='b-slider-item__title'>{{ banner.title|safe }}</span> |
||||||
|
<span class='b-slider-item__text'>{{ banner.text|safe }}</span> |
||||||
|
</div> |
||||||
|
</a> |
||||||
|
</li> |
||||||
|
{% endfor %} |
||||||
|
</ul> |
||||||
|
|
||||||
|
<ul class="b-slider-nav"> |
||||||
|
{% for banner in banners %} |
||||||
|
<li class="b-slider-nav-button |
||||||
|
{% if forloop.counter == 1 %} |
||||||
|
m-slider-nav-current_button |
||||||
|
{% endif %} |
||||||
|
" data-slide='{{ forloop.counter }}'> |
||||||
|
{{ forloop.counter }} |
||||||
|
</li> |
||||||
|
{% endfor %} |
||||||
|
</ul> |
||||||
|
|
||||||
|
<span data-direction="prev" class='b-slider-nav-prev'>〈 </span> |
||||||
|
<span data-direction="next" class='b-slider-nav-next'> 〉</span> |
||||||
|
|
||||||
|
</div> |
||||||
|
|
||||||
|
<script> |
||||||
|
(function() { |
||||||
|
$('.m-{{ group.slug }}').bannersSlider({'auto_play': {{ group.speed }}, 'speed': {{ group.speed }}}); |
||||||
|
})(); |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
.m-{{ group.slug }} { |
||||||
|
width: {{ group.width }}px; |
||||||
|
height: {{ group.height }}px; |
||||||
|
} |
||||||
|
|
||||||
|
.m-{{ group.slug }} .b-slider-nav-prev, |
||||||
|
.m-{{ group.slug }} .b-slider-nav-next { |
||||||
|
line-height: {{ group.height }}px; |
||||||
|
} |
||||||
|
|
||||||
|
.m-{{ group.slug }} .b-slider-item, |
||||||
|
.m-{{ group.slug }} .b-slider-list { |
||||||
|
width: {{ group.width }}px; |
||||||
|
height: {{ group.height }}px; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
{% endif %} |
||||||
@ -0,0 +1,74 @@ |
|||||||
|
from ..models import Banner |
||||||
|
from ..models import BannerGroup |
||||||
|
from ..models import URL |
||||||
|
|
||||||
|
from django import template |
||||||
|
|
||||||
|
# For render tag |
||||||
|
from django.template import Context |
||||||
|
from django.template import Template |
||||||
|
|
||||||
|
import re |
||||||
|
|
||||||
|
register = template.Library() |
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag(takes_context=True) |
||||||
|
def banner_group(context, group, tpl='group.html'): |
||||||
|
try: |
||||||
|
page_url = context['request'].path_info |
||||||
|
site = context['request'].site |
||||||
|
group = BannerGroup.objects.get(slug=group) |
||||||
|
good_urls = [] |
||||||
|
for url in URL.objects.filter(public=True, sites__in=[site]): |
||||||
|
if url.regex: |
||||||
|
url_re = re.compile(url.url) |
||||||
|
if url_re.findall(page_url): |
||||||
|
good_urls.append(url) |
||||||
|
elif page_url == url.url: |
||||||
|
good_urls.append(url) |
||||||
|
banners = Banner.objects.filter(public=True, group=group, urls__in=good_urls) |
||||||
|
except: |
||||||
|
banners = False |
||||||
|
group = False |
||||||
|
if(banners and group): |
||||||
|
context['banners'] = banners |
||||||
|
context['group'] = group |
||||||
|
|
||||||
|
t = template.loader.get_template(tpl) |
||||||
|
return t.render(template.Context(context)) |
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag(takes_context=True) |
||||||
|
def banner_one(context, banner_id, tpl='banner.html'): |
||||||
|
try: |
||||||
|
page_url = context['request'].path_info |
||||||
|
site = context['request'].site |
||||||
|
good_urls = [] |
||||||
|
for url in URL.objects.filter(public=True, sites__in=[site]): |
||||||
|
if url.regex: |
||||||
|
url_re = re.compile(url.url) |
||||||
|
if url_re.findall(page_url): |
||||||
|
good_urls.append(url) |
||||||
|
elif page_url == url.url: |
||||||
|
good_urls.append(url) |
||||||
|
|
||||||
|
banner = Banner.objects.get(id=banner_id, public=True, urls__in=good_urls) |
||||||
|
except: |
||||||
|
banner = False |
||||||
|
|
||||||
|
context['banner'] = banner |
||||||
|
|
||||||
|
t = template.loader.get_template(tpl) |
||||||
|
return t.render(template.Context(context)) |
||||||
|
|
||||||
|
|
||||||
|
# block render |
||||||
|
@register.simple_tag(takes_context=True) |
||||||
|
def render(context, content): |
||||||
|
try: |
||||||
|
tpl = Template(content) |
||||||
|
content = Context(context) |
||||||
|
return tpl.render(content) |
||||||
|
except: |
||||||
|
return 'Render Error' |
||||||
@ -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,13 @@ |
|||||||
|
from django.conf.urls import url |
||||||
|
from expobanner.stat_views import * |
||||||
|
from . import views |
||||||
|
|
||||||
|
urlpatterns = [ |
||||||
|
url(r'^click/(?P<banner_id>\d{1,4})/$', views.click, name='banner_click'), |
||||||
|
#url(r'^view/(?P<banner_id>\d+)/$', views.view, name='banner_view'), |
||||||
|
# |
||||||
|
url(r'^get-banners/$', views.get_banners), |
||||||
|
url(r'^get-tops/$', views.get_top), |
||||||
|
url(r'^banner/(?P<pk>\d+)/stat/$', BannerStat.as_view(), name='banner_stat_client'), |
||||||
|
url(r'^paid/(?P<pk>\d+)/stat/$', PaidStat.as_view(), name='paid_stat_client'), |
||||||
|
] |
||||||
@ -0,0 +1,73 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
import random |
||||||
|
from django.db import connection |
||||||
|
|
||||||
|
def get_client_ip(request): |
||||||
|
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') |
||||||
|
if x_forwarded_for: |
||||||
|
ip = x_forwarded_for.split(',')[0] |
||||||
|
else: |
||||||
|
ip = request.META.get('REMOTE_ADDR') |
||||||
|
return ip |
||||||
|
|
||||||
|
def get_by_sort(banner_list): |
||||||
|
max_sort = 0 |
||||||
|
for banner in banner_list: |
||||||
|
sort = banner.sort |
||||||
|
if sort > max_sort: |
||||||
|
max_sort = sort |
||||||
|
result = [banner for banner in banner_list if banner.sort == max_sort] |
||||||
|
return result |
||||||
|
|
||||||
|
|
||||||
|
def get_banner_by_params(banners_list, urls, params): |
||||||
|
#print('START. NUMBER of queries = %d'%len(connection.queries)) |
||||||
|
thematic_banners = [] |
||||||
|
url_banners = [] |
||||||
|
|
||||||
|
for banner in banners_list: |
||||||
|
#print('-------------------------') |
||||||
|
#print('number of queries = %d'%len(connection.queries)) |
||||||
|
|
||||||
|
# check by theme |
||||||
|
banner_theme_ids = [str(theme.id) for theme in banner.theme.all()] |
||||||
|
#print('number of queries = %d'%len(connection.queries)) |
||||||
|
|
||||||
|
if banner_theme_ids: |
||||||
|
if params.get('theme'): |
||||||
|
theme = params['theme'] |
||||||
|
if theme in banner_theme_ids: |
||||||
|
thematic_banners.append(banner) |
||||||
|
continue |
||||||
|
# check by country |
||||||
|
banner_country_ids = [str(country.id) for country in banner.country.all()] |
||||||
|
#print('number of queries = %d'%len(connection.queries)) |
||||||
|
if banner_country_ids: |
||||||
|
if params.get('country'): |
||||||
|
|
||||||
|
country = params['country'] |
||||||
|
if country in banner_country_ids: |
||||||
|
thematic_banners.append(banner) |
||||||
|
continue |
||||||
|
|
||||||
|
# check by url |
||||||
|
if urls: |
||||||
|
banner_urls = banner.urls.all() |
||||||
|
print('number of queries = %d'%len(connection.queries)) |
||||||
|
|
||||||
|
if banner_urls: |
||||||
|
|
||||||
|
banner_urls = set(banner_urls) |
||||||
|
common_urls = set(urls).intersection(banner_urls) |
||||||
|
|
||||||
|
if common_urls: |
||||||
|
url_banners.append(banner) |
||||||
|
continue |
||||||
|
print('-------------------------') |
||||||
|
if thematic_banners: |
||||||
|
return random.choice(thematic_banners) |
||||||
|
if url_banners: |
||||||
|
return random.choice(url_banners) |
||||||
|
return None |
||||||
|
|
||||||
|
#print('END. NUMBER of queries = %d'%len(connection.queries)) |
||||||
@ -0,0 +1,100 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
import json |
||||||
|
import re |
||||||
|
from django.http import HttpResponse |
||||||
|
from django.shortcuts import redirect, get_object_or_404 |
||||||
|
from .models import Banner, BannerGroup, URL, Top |
||||||
|
from expobanner.utils import get_by_sort, get_banner_by_params, get_client_ip |
||||||
|
|
||||||
|
|
||||||
|
def click(request, banner_id): |
||||||
|
banner = get_object_or_404(Banner, pk=banner_id) |
||||||
|
banner.log(request, 2) |
||||||
|
return redirect(banner.url) |
||||||
|
|
||||||
|
|
||||||
|
def view(request, banner_id): |
||||||
|
banner = get_object_or_404(Banner, pk=banner_id) |
||||||
|
banner.log(request, 1) |
||||||
|
return redirect(banner.img.url) |
||||||
|
|
||||||
|
def get_banners(request): |
||||||
|
#url = request.GET.get('url', '/') |
||||||
|
url = request.META.get('HTTP_REFERER', '/') |
||||||
|
# get urls by current url |
||||||
|
urls = URL.cached.all() |
||||||
|
good_urls = [] |
||||||
|
for u in urls: |
||||||
|
if u.regex: |
||||||
|
url_re = re.compile(u.url) |
||||||
|
if url_re.findall(url): |
||||||
|
good_urls.append(u) |
||||||
|
elif url == u.url: |
||||||
|
good_urls.append(u) |
||||||
|
# fill parameters dict |
||||||
|
params = {'theme': request.GET.get('theme'), |
||||||
|
'tag': request.GET.get('tag'), |
||||||
|
'country': request.GET.get('country'), |
||||||
|
'city': request.GET.get('city'), |
||||||
|
'ip': get_client_ip(request)} |
||||||
|
|
||||||
|
group_banners = BannerGroup.cached.group_banners() |
||||||
|
result = [] |
||||||
|
# get banners for all groups |
||||||
|
for group, banners in group_banners.iteritems(): |
||||||
|
banner = get_banner_by_params(banners, good_urls, params) |
||||||
|
if banner: |
||||||
|
if banner.js or banner.html: |
||||||
|
text = banner.text |
||||||
|
img = '' |
||||||
|
alt = '' |
||||||
|
is_img = False |
||||||
|
else: |
||||||
|
text = '' |
||||||
|
img = banner.img.url |
||||||
|
alt = banner.alt |
||||||
|
is_img = True |
||||||
|
result.append({'id': group, |
||||||
|
'url': banner.get_click_link(), |
||||||
|
'is_html': banner.html, |
||||||
|
'is_flash': banner.flash, |
||||||
|
'is_img': is_img, |
||||||
|
'is_js': banner.js, |
||||||
|
'img': img, |
||||||
|
'alt': alt, |
||||||
|
'text': text |
||||||
|
}) |
||||||
|
# add view log |
||||||
|
banner.log(request, 1) |
||||||
|
|
||||||
|
return HttpResponse(json.dumps(result, indent=4), content_type='application/json') |
||||||
|
|
||||||
|
def get_top_events(tops, params): |
||||||
|
catalog = params.get('catalog') |
||||||
|
country = params.get('country', '') |
||||||
|
theme = params.get('theme', []) |
||||||
|
good_tops = [] |
||||||
|
for top in tops: |
||||||
|
|
||||||
|
if top.catalog != catalog: |
||||||
|
continue |
||||||
|
country_ids = [str(item.id) for item in top.country.all()] |
||||||
|
if not country in country_ids: |
||||||
|
continue |
||||||
|
|
||||||
|
|
||||||
|
from exposition.models import Exposition |
||||||
|
from django.shortcuts import render_to_response |
||||||
|
from django.template import RequestContext |
||||||
|
def get_top(request): |
||||||
|
params = {'theme': request.GET.get('theme'), |
||||||
|
'tag': request.GET.get('tag'), |
||||||
|
'country': request.GET.get('country'), |
||||||
|
'city': request.GET.get('city'), |
||||||
|
'catalog': request.GET.get('catalog')} |
||||||
|
|
||||||
|
tops = Top.cached.all() |
||||||
|
events = get_top_events(tops, params) |
||||||
|
expos = Exposition.objects.filter(top__isnull=False) |
||||||
|
context = {'objects': expos} |
||||||
|
return render_to_response('client/includes/exposition/expo_top.html', context, context_instance=RequestContext(request)) |
||||||
@ -1,41 +1,97 @@ |
|||||||
|
|
||||||
from accounts.models import User |
from accounts.models import User |
||||||
|
import random |
||||||
|
import string |
||||||
|
|
||||||
|
def random_pass(): |
||||||
|
digits = random.sample(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'), 4) |
||||||
|
chars = random.sample(string.lowercase[:], 4) |
||||||
|
password = chars + digits |
||||||
|
random.shuffle(password) |
||||||
|
return ''.join(password) |
||||||
|
|
||||||
def load_user(details, response, uid, *args, **kwargs): |
|
||||||
if details.get('email'): |
|
||||||
username = details.get('email') |
|
||||||
else: |
|
||||||
username = str(uid) |
|
||||||
|
|
||||||
user = User.objects.safe_get(username=username) |
def load_user(strategy, details, response, uid, *args, **kwargs): |
||||||
|
user = None |
||||||
|
if details.get('email'): |
||||||
|
email = details.get('email') |
||||||
|
user = User.objects.safe_get(email=email) |
||||||
|
|
||||||
return {'user': user, 'is_new': False} |
return {'user': user, 'is_new': False} |
||||||
|
|
||||||
|
from django.contrib.sites.models import Site, RequestSite |
||||||
|
from registration.models import RegistrationProfile |
||||||
|
|
||||||
|
|
||||||
def create_user(strategy, details, response, uid, user=None, *args, **kwargs): |
def create_user(strategy, details, response, uid, user=None, *args, **kwargs): |
||||||
if user: |
if user: |
||||||
return {'user': user, 'is_new': False} |
return {'user': user, 'is_new': False} |
||||||
else: |
else: |
||||||
|
request = strategy.request |
||||||
|
if Site._meta.installed: |
||||||
|
site = Site.objects.get_current() |
||||||
|
else: |
||||||
|
site = RequestSite(request) |
||||||
|
new_user = RegistrationProfile.objects.create_inactive_user(details['first_name'], details['last_name'], details['email'], |
||||||
|
random_pass(), site or 1) |
||||||
|
signals.user_registered.send(sender=User, user=new_user, request=request) |
||||||
|
#user = User.objects.create_social_user(username, details['first_name'], details['last_name']) |
||||||
|
return {'user': new_user, 'is_new': True} |
||||||
|
|
||||||
if details.get('email'): |
|
||||||
|
|
||||||
username = details.get('email') |
|
||||||
|
from django.shortcuts import redirect |
||||||
|
from social.pipeline.partial import partial |
||||||
|
from registration import signals |
||||||
|
|
||||||
|
@partial |
||||||
|
def require_email(strategy, details, user=None, is_new=False, *args, **kwargs): |
||||||
|
if user and user.email: |
||||||
|
return |
||||||
|
elif is_new and not details.get('email'): |
||||||
|
email = strategy.request_data().get('email') |
||||||
|
if email: |
||||||
|
details['email'] = email |
||||||
else: |
else: |
||||||
username = str(uid) |
strategy.request.session['new_email'] = True |
||||||
|
return redirect('acquire_email') |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
user = User.objects.create_social_user(username, details['first_name'], details['last_name']) |
|
||||||
return {'user': user, 'is_new': True} |
|
||||||
|
from django.core import signing |
||||||
|
from django.core.mail import EmailMultiAlternatives |
||||||
|
from django.conf import settings |
||||||
|
from django.core.urlresolvers import reverse |
||||||
|
|
||||||
|
def SendVerificationEmail(strategy, backend, code): |
||||||
""" |
""" |
||||||
if details.get('email'): |
Send an email with an embedded verification code and the necessary details to restore the required session |
||||||
user = User.objects.safe_get(email=details['email']) |
elements to complete the verification and sign-in, regardless of what browser the user completes the |
||||||
if user: |
verification from. |
||||||
return {'user': user, 'is_new': False} |
""" |
||||||
else: |
signature = signing.dumps({"session_key": strategy.session.session_key, "email": code.email}, |
||||||
user = User.objects.create_user(email=details['email'], first_name=details['first_name'], |
key=settings.EMAIL_SECRET_KEY) |
||||||
last_name=details['last_name'], password='1q2w3e4r', is_active=True) |
verifyURL = "{0}?verification_code={1}&signature={2}".format( |
||||||
|
reverse('social:complete', args=(backend.name,)), |
||||||
|
code.code, signature) |
||||||
|
verifyURL = strategy.request.build_absolute_uri(verifyURL) |
||||||
|
|
||||||
return {'user': user, 'is_new': True} |
emailHTML = ''# Include your function that returns an html string here |
||||||
else: |
emailText = """Welcome to Expomap.ru! |
||||||
return None |
In order to login with your new user account, you need to verify your email address with us. |
||||||
""" |
Please click on <a href='{verifyURL}'>this link</a> to continue registration. |
||||||
|
""".format(verifyURL=verifyURL) |
||||||
|
|
||||||
|
kwargs = { |
||||||
|
"subject": "Verify Your Account", |
||||||
|
"body": emailText, |
||||||
|
"from_email": settings.CALLBACK_EMAIL, |
||||||
|
"to": [code.email], |
||||||
|
} |
||||||
|
|
||||||
|
email = EmailMultiAlternatives(**kwargs) |
||||||
|
email.attach_alternative(emailHTML, "text/html") |
||||||
|
email.send() |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
from functools import wraps |
||||||
|
|
||||||
|
from django.template import RequestContext |
||||||
|
from django.shortcuts import render_to_response |
||||||
|
|
||||||
|
|
||||||
|
def render_to(tpl): |
||||||
|
def decorator(func): |
||||||
|
@wraps(func) |
||||||
|
def wrapper(request, *args, **kwargs): |
||||||
|
out = func(request, *args, **kwargs) |
||||||
|
if isinstance(out, dict): |
||||||
|
out = render_to_response(tpl, out, RequestContext(request)) |
||||||
|
return out |
||||||
|
return wrapper |
||||||
|
return decorator |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
|
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-arrow-down"></i>{{ verbose }}</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{% block list_table %} |
||||||
|
<table class="table table-hover"> |
||||||
|
|
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Объект</th> |
||||||
|
<th> </th> |
||||||
|
<th> </th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for item in object_list %} |
||||||
|
<tr> |
||||||
|
<td>{{ item }}</td> |
||||||
|
<td><a href="{{ item.get_admin_url }}">Изменить</a> </td> |
||||||
|
<td><a href="{% url 'expobanner_stat_banner' item.id %}">Статистика</a> </td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
{% endblock %} |
||||||
|
</div> |
||||||
|
{# pagination #} |
||||||
|
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% load static %} |
||||||
|
{% block scripts %} |
||||||
|
<script src="{% static 'js/jquery.dataTables.min.js' %}"></script> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
|
||||||
|
{% block body %} |
||||||
|
<div class="row-fluid sortable"> |
||||||
|
<div class="box span12"> |
||||||
|
<div class="box-header well" data-original-title> |
||||||
|
<h2><i class="icon-align-justify"></i> {{ object }} (Пароль: {{ object.stat_pswd }})</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
<table class="table table-striped table-bordered bootstrap-datatable datatable"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Дата</th> |
||||||
|
<th>Показы</th> |
||||||
|
<th>Клики</th> |
||||||
|
<th>Уникальные показы</th> |
||||||
|
<th>Уникальные клики</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% with stats=object.banner_stat.all %} |
||||||
|
{% for stat in stats %} |
||||||
|
<tr> |
||||||
|
<td>{{ stat.date|date:"Y-m-d" }}</td> |
||||||
|
<td>{{ stat.view }}</td> |
||||||
|
<td>{{ stat.click }}</td> |
||||||
|
<td>{{ stat.unique_view }}</td> |
||||||
|
<td>{{ stat.unique_click }}</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
{% endwith %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
|
||||||
|
{% block body %} |
||||||
|
<div class="row-fluid sortable ui-sortable"> |
||||||
|
<div class="box span6"> |
||||||
|
<div class="box-header well" data-original-title=""> |
||||||
|
<h2><i class="icon-th"></i> Создание</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
<div class="row-fluid"> |
||||||
|
<div class="span4"><h6><a href="{% url 'expobanner-create_url' %}">Урла</a></h6></div> |
||||||
|
<div class="span4"><h6><a href="{% url 'expobanner-create_group' %}">Групы</a></h6></div> |
||||||
|
<div class="span4"><h6><a href="{% url 'expobanner-create_banner' %}">Банера</a></h6></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div><!--/span--> |
||||||
|
|
||||||
|
<div class="box span6"> |
||||||
|
<div class="box-header well" data-original-title=""> |
||||||
|
<h2><i class="icon-th"></i> Список</h2> |
||||||
|
|
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
<div class="row-fluid"> |
||||||
|
<div class="span4"><h6><a href="{% url 'expobanner-list_url' %}">Урлов</a></h6></div> |
||||||
|
<div class="span4"><h6><a href="{% url 'expobanner-list_group' %}">Груп</a></h6></div> |
||||||
|
<div class="span4"><h6><a href="{% url 'expobanner-list_banner' %}">Банеров</a></h6></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div><!--/span--> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,73 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% load static %} |
||||||
|
|
||||||
|
{% block scripts %} |
||||||
|
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/> |
||||||
|
<script src="{% static 'js/select/select2.js' %}"></script> |
||||||
|
<script> |
||||||
|
$(function(){ |
||||||
|
$('#id_fr').datetimepicker({ |
||||||
|
todayHighlight: true, |
||||||
|
format : 'yyyy-mm-dd', |
||||||
|
minView:2 |
||||||
|
}); |
||||||
|
$('#id_to').datetimepicker({ |
||||||
|
todayHighlight: true, |
||||||
|
format : 'yyyy-mm-dd', |
||||||
|
minView:2 |
||||||
|
}); |
||||||
|
$('#id_theme').select2({width: "element"}); |
||||||
|
$('#id_country').select2({width: "element"}); |
||||||
|
/* |
||||||
|
$('#id_tag').select2({ |
||||||
|
placeholder: "Тег", |
||||||
|
width: '200px', |
||||||
|
ajax: { |
||||||
|
url: "/admin/theme/tag/search-without-theme/", |
||||||
|
dataType: "json", |
||||||
|
quietMillis: 200, |
||||||
|
multiple: true, |
||||||
|
|
||||||
|
data: function(term, page){ |
||||||
|
|
||||||
|
return {term: term, |
||||||
|
page: page}; |
||||||
|
}, |
||||||
|
|
||||||
|
results: function (data) { |
||||||
|
return {results: data}; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
*/ |
||||||
|
}) |
||||||
|
</script> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
<form method="post" class="form-horizontal" name="form2" id="form2" enctype="multipart/form-data"> {% csrf_token %} |
||||||
|
<fieldset> |
||||||
|
|
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-pencil"></i>{{ form.verbose }}</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{% for field in form %} |
||||||
|
<div class="control-group {% if field.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{% if field.field.required %}<b>{{ field.label }}:</b>{% else %}{{ field.label }}{% endif %}</label> |
||||||
|
<div class="controls">{{ field }} |
||||||
|
<span class="help-inline">{{ field.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endfor %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</fieldset> |
||||||
|
|
||||||
|
<div class="controls"> |
||||||
|
<input class="btn btn-large btn-primary" type="submit" value="Готово"> |
||||||
|
<input class="btn btn-large" type="reset" value="Отмена"> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,34 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
|
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-arrow-down"></i>{{ verbose }}</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{% block list_table %} |
||||||
|
<table class="table table-hover"> |
||||||
|
|
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Объект</th> |
||||||
|
<th> </th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for item in object_list %} |
||||||
|
<tr> |
||||||
|
<td>{{ item }}</td> |
||||||
|
<td><a href="{{ item.get_admin_url }}">Изменить</a> </td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
{% endblock %} |
||||||
|
</div> |
||||||
|
{# pagination #} |
||||||
|
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,71 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% load static %} |
||||||
|
|
||||||
|
{% block scripts %} |
||||||
|
{# selects #} |
||||||
|
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/> |
||||||
|
<script src="{% static 'js/select/select2.js' %}"></script> |
||||||
|
<script> |
||||||
|
$(function(){ |
||||||
|
$('#id_exposition').select2({ |
||||||
|
placeholder: 'Найти', |
||||||
|
width: 'element', |
||||||
|
ajax: { |
||||||
|
url: '/admin/exposition/search/', |
||||||
|
dataType: "json", |
||||||
|
quietMillis: 200, |
||||||
|
multiple: true, |
||||||
|
|
||||||
|
data: function(term, page, theme){ |
||||||
|
return {term: term, |
||||||
|
page: page}; |
||||||
|
}, |
||||||
|
|
||||||
|
results: function (data) { |
||||||
|
var results = []; |
||||||
|
$.each(data, function(index, item){ |
||||||
|
results.push({ |
||||||
|
id: item.id, |
||||||
|
text: item.label |
||||||
|
}); |
||||||
|
}); |
||||||
|
return {results: results}; |
||||||
|
} |
||||||
|
}, |
||||||
|
initSelection : function(element, callback) { |
||||||
|
var id= $(element).val(); |
||||||
|
var text = $(element).attr('data-init-text'); |
||||||
|
callback({id: id, text:text}); |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
<form method="post" class="form-horizontal" name="form2" id="form2" enctype="multipart/form-data"> {% csrf_token %} |
||||||
|
<fieldset> |
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-pencil"></i>{{ form.verbose }}</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{% for field in form %} |
||||||
|
<div class="control-group {% if field.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{% if field.field.required %}<b>{{ field.label }}:</b>{% else %}{{ field.label }}{% endif %}</label> |
||||||
|
<div class="controls">{{ field }} |
||||||
|
<span class="help-inline">{{ field.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endfor %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</fieldset> |
||||||
|
|
||||||
|
<div class="controls"> |
||||||
|
<input class="btn btn-large btn-primary" type="submit" value="Готово"> |
||||||
|
<input class="btn btn-large" type="reset" value="Отмена"> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,38 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
|
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-arrow-down"></i>Список проплаченых выставок</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{% block list_table %} |
||||||
|
<a class="btn btn-success" href="{% url 'expobanner-create_paid' %}"><i class="icon-plus-sign icon-white"></i> Добавить выставку</a> |
||||||
|
<table class="table table-hover"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Выставка</th> |
||||||
|
<th> </th> |
||||||
|
<th> </th> |
||||||
|
<th> </th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for item in object_list %} |
||||||
|
<tr> |
||||||
|
<td>{{ item }}</td> |
||||||
|
<td><a href="{% url 'expobanner-update_paid' item.paid_new.id %}">Изменить</a> </td> |
||||||
|
<td>{% if item.paid_new.public %}<a href="{% url 'expobanner-paid-turn' item.paid_new.id 'off' %}">отключить</a>{% else %}<a href="{% url 'expobanner-paid-turn' item.paid_new.id 'on' %}">включить</a>{% endif %} </td> |
||||||
|
<td><a href="{% url 'expobanner_stat_paid' item.paid_new.id %}">Статистика</a> </td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
{% endblock %} |
||||||
|
</div> |
||||||
|
{# pagination #} |
||||||
|
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% load static %} |
||||||
|
{% block scripts %} |
||||||
|
<script src="{% static 'js/jquery.dataTables.min.js' %}"></script> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
|
||||||
|
{% block body %} |
||||||
|
<div class="row-fluid sortable"> |
||||||
|
<div class="box span12"> |
||||||
|
<div class="box-header well" data-original-title> |
||||||
|
<h2><i class="icon-align-justify"></i> {{ object.get_event }} (Пароль: {{ object.stat_pswd }})</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
<table class="table table-striped table-bordered bootstrap-datatable datatable"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Дата</th> |
||||||
|
<th>Официальный сайт</th> |
||||||
|
<th>Билеты</th> |
||||||
|
<th>Участие</th> |
||||||
|
<th>Переходы с каталога</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% with stats=object.paidstat_set.all %} |
||||||
|
{% for stat in stats %} |
||||||
|
<tr> |
||||||
|
<td>{{ stat.date|date:"Y-m-d" }}</td> |
||||||
|
<td>{{ stat.official_clicks }}</td> |
||||||
|
<td>{{ stat.tickets_clicks }}</td> |
||||||
|
<td>{{ stat.participation_clicks }}</td> |
||||||
|
<td>{{ stat.catalog_clicks }}</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
{% endwith %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% load static %} |
||||||
|
|
||||||
|
{% block scripts %} |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
<form method="post" class="form-horizontal" name="form2" id="form2" enctype="multipart/form-data"> {% csrf_token %} |
||||||
|
<fieldset> |
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-pencil"></i>{{ exposition }}</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{% for field in form %} |
||||||
|
<div class="control-group {% if field.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{% if field.field.required %}<b>{{ field.label }}:</b>{% else %}{{ field.label }}{% endif %}</label> |
||||||
|
<div class="controls">{{ field }} |
||||||
|
<span class="help-inline">{{ field.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endfor %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</fieldset> |
||||||
|
|
||||||
|
<div class="controls"> |
||||||
|
<input class="btn btn-large btn-primary" type="submit" value="Готово"> |
||||||
|
<input class="btn btn-large" type="reset" value="Отмена"> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,84 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% load static %} |
||||||
|
|
||||||
|
{% block scripts %} |
||||||
|
{# selects #} |
||||||
|
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/> |
||||||
|
<script src="{% static 'js/select/select2.js' %}"></script> |
||||||
|
<script> |
||||||
|
$(function(){ |
||||||
|
$('#id_fr').datetimepicker({ |
||||||
|
todayHighlight: true, |
||||||
|
format : 'yyyy-mm-dd', |
||||||
|
minView:2 |
||||||
|
}); |
||||||
|
$('#id_to').datetimepicker({ |
||||||
|
todayHighlight: true, |
||||||
|
format : 'yyyy-mm-dd', |
||||||
|
minView:2 |
||||||
|
}); |
||||||
|
$('#id_theme').select2({width: "element"}); |
||||||
|
$('#id_country').select2({width: "element"}); |
||||||
|
$('#id_exposition').select2({ |
||||||
|
placeholder: 'Найти', |
||||||
|
width: 'element', |
||||||
|
ajax: { |
||||||
|
url: '/admin/exposition/search/', |
||||||
|
dataType: "json", |
||||||
|
quietMillis: 200, |
||||||
|
multiple: true, |
||||||
|
|
||||||
|
data: function(term, page, theme){ |
||||||
|
return {term: term, |
||||||
|
page: page}; |
||||||
|
}, |
||||||
|
|
||||||
|
results: function (data) { |
||||||
|
var results = []; |
||||||
|
$.each(data, function(index, item){ |
||||||
|
results.push({ |
||||||
|
id: item.id, |
||||||
|
text: item.label |
||||||
|
}); |
||||||
|
}); |
||||||
|
return {results: results}; |
||||||
|
} |
||||||
|
}, |
||||||
|
initSelection : function(element, callback) { |
||||||
|
var id= $(element).val(); |
||||||
|
var text = $(element).attr('data-init-text'); |
||||||
|
callback({id: id, text:text}); |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
</script> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
<form method="post" class="form-horizontal" name="form2" id="form2" enctype="multipart/form-data"> {% csrf_token %} |
||||||
|
<fieldset> |
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-pencil"></i>{{ form.verbose }}</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{% for field in form %} |
||||||
|
<div class="control-group {% if field.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{% if field.field.required %}<b>{{ field.label }}:</b>{% else %}{{ field.label }}{% endif %}</label> |
||||||
|
<div class="controls">{{ field }} |
||||||
|
<span class="help-inline">{{ field.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endfor %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</fieldset> |
||||||
|
|
||||||
|
<div class="controls"> |
||||||
|
<input class="btn btn-large btn-primary" type="submit" value="Готово"> |
||||||
|
<input class="btn btn-large" type="reset" value="Отмена"> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
|
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-arrow-down"></i>Список выставок в топе</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{% block list_table %} |
||||||
|
<a class="btn btn-success" href="{% url 'expobanner-create_top' %}"><i class="icon-plus-sign icon-white"></i> Добавить выставку</a> |
||||||
|
<table class="table table-hover"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Выставка</th> |
||||||
|
<th> </th> |
||||||
|
<th> </th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for item in object_list %} |
||||||
|
<tr> |
||||||
|
<td>{{ item }}</td> |
||||||
|
<td><a href="{% url 'expobanner-update_top' item.top_id %}">Изменить</a> </td> |
||||||
|
<td><a href="{% url 'expobanner_stat_top' item.top_id %}">Статистика</a> </td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
{% endblock %} |
||||||
|
</div> |
||||||
|
{# pagination #} |
||||||
|
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,63 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% load static %} |
||||||
|
{# Displays article form #} |
||||||
|
|
||||||
|
{% block scripts %} |
||||||
|
|
||||||
|
<script src="{% static 'ckeditor/ckeditor/ckeditor.js' %}"></script> |
||||||
|
{# selects #} |
||||||
|
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/> |
||||||
|
<script src="{% static 'js/select/select2.js' %}"></script> |
||||||
|
<script src="{% static 'custom_js/make_select.js' %}"></script> |
||||||
|
{# ajax #} |
||||||
|
<script src="{% static 'custom_js/file_post_ajax.js' %}"></script> |
||||||
|
<script src="{% static 'custom_js/select_tag.js' %}"></script> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
{{ request.LANGUAGE_CODE }} |
||||||
|
<form method="post" class="form-horizontal" > {% csrf_token %} |
||||||
|
<fieldset> |
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-pencil"></i> Основная информация</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{# url/slug #} |
||||||
|
<div class="control-group {% if form.url.errors %}error{% endif %}"> |
||||||
|
<label class="control-label"><b>{{ form.url.label }}:</b></label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.langs }} |
||||||
|
{{ form.url }} |
||||||
|
<span class="help-inline">{{ form.url.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{# title #} |
||||||
|
<div class="control-group {% if form.title.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{{ form.title.label }}:</label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.title }} |
||||||
|
<span class="help-inline">{{ form.title.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{# body #} |
||||||
|
<div class="control-group {% if form.body.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{{ form.body.label }}:</label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.body }} |
||||||
|
<span class="help-inline">{{ form.body.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="controls"> |
||||||
|
|
||||||
|
<input class="btn btn-large btn-primary" type="submit" {% if request.path == '/admin/meta/seo/new/' %} value="Добавить" {% else %} value='Изменить' {% endif %}/> |
||||||
|
<input class="btn btn-large" type="reset" value="Отмена"> |
||||||
|
</div> |
||||||
|
</fieldset> |
||||||
|
</form> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,54 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% block body %} |
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-arrow-down"></i>Список seo-текстов</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
<table class="table table-hover"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
|
||||||
|
<th>Аддрес страници</th> |
||||||
|
<th>Заголовок</th> |
||||||
|
<th> </th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for item in object_list %} |
||||||
|
<tr> |
||||||
|
|
||||||
|
<td><a href = "{{ item.url }}/">{{ item.url }}</a></td> |
||||||
|
<td>{{ item.title }}</td> |
||||||
|
<td class="center sorting_1"> |
||||||
|
<a class="btn-small btn-info" href='{% url "seo_edit" item.id %}'> |
||||||
|
Изменить |
||||||
|
</a> |
||||||
|
</td> |
||||||
|
|
||||||
|
<td> |
||||||
|
<a class="btn-small btn-danger delete" href='{% url "seo_delete" item.id %}'> |
||||||
|
Удалить |
||||||
|
</a> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
<a class="btn btn-success" href='{% url "seo_new" %}'> |
||||||
|
<i class="icon-plus-sign icon-white"></i> Добавить seo-текст </a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="pagination pagination-centered"> |
||||||
|
<ul> |
||||||
|
{% if page_obj.has_previous %} |
||||||
|
<li> <a href="?page={{ page_obj.previous_page_number }}">←</a></li> |
||||||
|
{% endif %} |
||||||
|
|
||||||
|
{% if page_obj.has_next %} |
||||||
|
<li><a href="?page={{ page_obj.next_page_number }}">→</a></li> |
||||||
|
{% endif %} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% block sidebar %}{% endblock %} |
||||||
|
{% block body %} |
||||||
|
<form action="" method="post">{% csrf_token %} |
||||||
|
<div class="controls"> |
||||||
|
<p>Вы точно хотите удалить seo-текст "{{ object.title }}" для страницы <a href = "{{ object.url }}"></a> ?</p> |
||||||
|
<input class="btn btn-large btn-danger delete" type="submit" value="Да" /> |
||||||
|
<a class="btn btn-large btn-primary" href = {% url 'seo_all' %}>Нет</a> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,90 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% load static %} |
||||||
|
{# Displays article form #} |
||||||
|
|
||||||
|
{% block scripts %} |
||||||
|
|
||||||
|
<script src="{% static 'ckeditor/ckeditor/ckeditor.js' %}"></script> |
||||||
|
{# selects #} |
||||||
|
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/> |
||||||
|
<script src="{% static 'js/select/select2.js' %}"></script> |
||||||
|
<script src="{% static 'custom_js/make_select.js' %}"></script> |
||||||
|
{# ajax #} |
||||||
|
<script src="{% static 'custom_js/file_post_ajax.js' %}"></script> |
||||||
|
<script src="{% static 'custom_js/select_tag.js' %}"></script> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block body %} |
||||||
|
|
||||||
|
{# Uses multilang.html template for translated fields #} |
||||||
|
<form method="post" class="form-horizontal" > {% csrf_token %} |
||||||
|
<fieldset> |
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-pencil"></i> Основная информация</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
{# url/slug #} |
||||||
|
{% if request.path == '/admin/page/new/' %} |
||||||
|
<div class="control-group {% if form.url.errors %}error{% endif %}"> |
||||||
|
<label class="control-label"><b>{{ form.url.label }}:</b></label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.langs }} |
||||||
|
{{ form.url }} |
||||||
|
<span class="help-inline">{{ form.url.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
{# h1 #} |
||||||
|
<div class="control-group {% if form.h1.errors %}error{% endif %} "> |
||||||
|
<label class="control-label"><b>{{ form.h1.label }}:</b></label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.h1 }} |
||||||
|
<span class="help-inline">{{ form.h1.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{# title #} |
||||||
|
<div class="control-group {% if form.title.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{{ form.title.label }}:</label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.title }} |
||||||
|
<span class="help-inline">{{ form.title.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{# description #} |
||||||
|
<div class="control-group {% if form.descriptions.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{{ form.descriptions.label }}:</label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.descriptions }} |
||||||
|
<span class="help-inline">{{ form.descriptions.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{# keywords #} |
||||||
|
<div class="control-group {% if form.keywords.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{{ form.keywords.label }}:</label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.keywords }} |
||||||
|
<span class="help-inline">{{ form.keywords.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{# body #} |
||||||
|
<div class="control-group {% if form.body.errors %}error{% endif %}"> |
||||||
|
<label class="control-label">{{ form.body.label }}:</label> |
||||||
|
<div class="controls"> |
||||||
|
{{ form.body }} |
||||||
|
<span class="help-inline">{{ form.body.errors }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="controls"> |
||||||
|
|
||||||
|
<input class="btn btn-large btn-primary" type="submit" {% if request.path == '/admin/page/new/' %} value="Добавить" {% else %} value='Изменить' {% endif %}/> |
||||||
|
<input class="btn btn-large" type="reset" value="Отмена"> |
||||||
|
</div> |
||||||
|
</fieldset> |
||||||
|
</form> |
||||||
|
|
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,58 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% block body %} |
||||||
|
<div class="box span8"> |
||||||
|
<div class="box-header well"> |
||||||
|
<h2><i class="icon-arrow-down"></i>Список страниц</h2> |
||||||
|
</div> |
||||||
|
<div class="box-content"> |
||||||
|
<table class="table table-hover"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
|
||||||
|
<th>Название</th> |
||||||
|
<th>Заголовок</th> |
||||||
|
<th>Адресс</th> |
||||||
|
<th>Создана</th> |
||||||
|
<th> </th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for item in object_list %} |
||||||
|
<tr> |
||||||
|
|
||||||
|
<td>{{ item.title }}</td> |
||||||
|
<td>{{ item.h1 }}</td> |
||||||
|
<td><a href = "/admin/page/{{ item.url }}/">{{ item.url }}</a></td> |
||||||
|
<td> {{ item.created|date:"Y-m-d H:i" }}</td> |
||||||
|
<td class="center sorting_1"> |
||||||
|
<a class="btn-small btn-info" href="/admin/page/edit/{{ item.url }}"> |
||||||
|
Изменить |
||||||
|
</a> |
||||||
|
</td> |
||||||
|
|
||||||
|
<td> |
||||||
|
<a class="btn-small btn-danger delete" href="/admin/page/delete/{{ item.url }}/"> |
||||||
|
Удалить |
||||||
|
</a> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
<a class="btn btn-success" href="/admin/page/new/"> |
||||||
|
<i class="icon-plus-sign icon-white"></i> Добавить страницу </a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="pagination pagination-centered"> |
||||||
|
<ul> |
||||||
|
{% if page_obj.has_previous %} |
||||||
|
<li> <a href="?page={{ page_obj.previous_page_number }}">←</a></li> |
||||||
|
{% endif %} |
||||||
|
|
||||||
|
{% if page_obj.has_next %} |
||||||
|
<li><a href="?page={{ page_obj.next_page_number }}">→</a></li> |
||||||
|
{% endif %} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
{% block sidebar %}{% endblock %} |
||||||
|
{% block body %} |
||||||
|
<form action="" method="post">{% csrf_token %} |
||||||
|
<div class="controls"> |
||||||
|
<p>Вы точно хотите удалить страницу "{{ object }}"?</p> |
||||||
|
<input class="btn btn-large btn-danger delete" type="submit" value="Да" /> |
||||||
|
<a class="btn btn-large btn-primary" href = {% url 'page_list' %}>Нет</a> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
{% extends 'client/blank.html' %} |
||||||
|
{% block main_part %} |
||||||
|
<form method="post" action="{% url "require_email" %}">{% csrf_token %} |
||||||
|
{{ form }} |
||||||
|
<input type="submit" value="Send"> |
||||||
|
</form> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,113 @@ |
|||||||
|
{% extends 'blank.html' %} |
||||||
|
|
||||||
|
{% load static %} |
||||||
|
{% load i18n %} |
||||||
|
{% load template_filters %} |
||||||
|
|
||||||
|
|
||||||
|
{% block main_part %} |
||||||
|
<section class="layout main-part"> |
||||||
|
<div class="layout-wrap"> |
||||||
|
<aside> |
||||||
|
<div class="sbg"></div> |
||||||
|
{% include 'menu.html' %} |
||||||
|
<hr/> |
||||||
|
|
||||||
|
{% include 'client/includes/feedback.html' %} |
||||||
|
<hr /> |
||||||
|
|
||||||
|
{% include 'client/includes/online_consult.html' %} |
||||||
|
|
||||||
|
{% block aside_banner1 %} |
||||||
|
{% if theme_for_filter.id == 27 or theme_for_filter.id == 9 or theme_for_filter.id == 48 %} |
||||||
|
<div class="sbnr"> |
||||||
|
<div class="sbnr-wrap"> |
||||||
|
<a href="/redirect/redirect/11/" target="_blank"> |
||||||
|
<img src="{% static 'client/img/partners/ipsa_.gif' %}" alt="" /> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% include 'client/includes/services.html' %} |
||||||
|
<hr /> |
||||||
|
|
||||||
|
{% include 'client/includes/announces.html' %} |
||||||
|
|
||||||
|
{% block asside_banner2 %} |
||||||
|
|
||||||
|
<!-- task EXPO-145--> |
||||||
|
{% comment %} |
||||||
|
<div class="sbnr"> |
||||||
|
<div class="sbnr-wrap"> |
||||||
|
<a href="/redirect/redirect/11/"> |
||||||
|
<img src="{% static 'client/img/partners/imgo.jpg' %}" alt="" /> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endcomment %} |
||||||
|
|
||||||
|
|
||||||
|
{% endblock %} |
||||||
|
{% include 'client/includes/side_confs.html' %} |
||||||
|
<hr /> |
||||||
|
<div class="s-news-list"> |
||||||
|
{% include 'client/includes/news.html' with news=news_list %} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% block aside_vk %} |
||||||
|
<div class="vk-widget"> |
||||||
|
{% include 'client/includes/social_widjet.html' %} |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
|
</aside> |
||||||
|
|
||||||
|
<div class="mcl"> |
||||||
|
{% with search_form=search_form %} |
||||||
|
{% include 'client/includes/catalog_search.html' %} |
||||||
|
{% endwith %} |
||||||
|
{% block under_search_baner %} |
||||||
|
{% include 'client/includes/banners/under_search.html' %} |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block bread_scrumbs %} |
||||||
|
|
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
<div class="page-title"> |
||||||
|
{% block page_title %} |
||||||
|
|
||||||
|
{% endblock %} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% block page_filter %} |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block page_body %} |
||||||
|
<div class="page-body clearfix"> |
||||||
|
{% block content_list %} |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block paginator %} |
||||||
|
|
||||||
|
|
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block content_footer_banner %} |
||||||
|
{% endblock %} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% block content_text %} |
||||||
|
{% comment %} |
||||||
|
{% with filter=filter %} |
||||||
|
{% include 'includes/event_list_description.html' %} |
||||||
|
{% endwith %} |
||||||
|
{% endcomment %} |
||||||
|
|
||||||
|
{% endblock %} |
||||||
|
{% endblock %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
{% extends 'base_catalog.html' %} |
||||||
|
|
||||||
|
{% block page_title %} |
||||||
|
<div class="page-title"> |
||||||
|
<h1>{{ object }}. Статистика</h1> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block content_list %} |
||||||
|
<div class="m-article recovery-page"> |
||||||
|
{% if form %} |
||||||
|
<form class="pw-form" method="post">{% csrf_token %} |
||||||
|
|
||||||
|
<div> |
||||||
|
<div class="input"> |
||||||
|
<p class="label">{{ form.stat_pswd.label }}</p> |
||||||
|
</div> |
||||||
|
{% if form.errors %} |
||||||
|
{# если есть ошибка #} |
||||||
|
<div class="required err input"> |
||||||
|
{{ form.stat_pswd }} |
||||||
|
</div> |
||||||
|
<div class="error-text"> |
||||||
|
{{ form.errors.stat_pswd.0 }}{# текст ошибки #} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% else %} |
||||||
|
{# ошибки нет #} |
||||||
|
<div class="input"> |
||||||
|
{{ form.stat_pswd }} |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
<div class="input"> |
||||||
|
<button type="submit" class="icon-check submit">Подтвердить</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
</form> |
||||||
|
|
||||||
|
{% else %} |
||||||
|
<table width="100%"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Дата</th> |
||||||
|
<th>Показы</th> |
||||||
|
<th>Клики</th> |
||||||
|
<th>Уникальные показы</th> |
||||||
|
<th>Уникальные клики</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% with stats=object.banner_stat.all %} |
||||||
|
{% for stat in stats %} |
||||||
|
<tr> |
||||||
|
<td>{{ stat.date|date:"Y-m-d" }}</td> |
||||||
|
<td>{{ stat.view }}</td> |
||||||
|
<td>{{ stat.click }}</td> |
||||||
|
<td>{{ stat.unique_view }}</td> |
||||||
|
<td>{{ stat.unique_click }}</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
{% endwith %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
{% extends 'base_catalog.html' %} |
||||||
|
|
||||||
|
{% block page_title %} |
||||||
|
<div class="page-title"> |
||||||
|
<h1>{{ object.get_event }}. Статистика</h1> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block content_list %} |
||||||
|
<div class="m-article recovery-page"> |
||||||
|
{% if form %} |
||||||
|
<form class="pw-form" method="post">{% csrf_token %} |
||||||
|
|
||||||
|
<div> |
||||||
|
<div class="input"> |
||||||
|
<p class="label">{{ form.stat_pswd.label }}</p> |
||||||
|
</div> |
||||||
|
{% if form.errors %} |
||||||
|
{# если есть ошибка #} |
||||||
|
<div class="required err input"> |
||||||
|
{{ form.stat_pswd }} |
||||||
|
</div> |
||||||
|
<div class="error-text"> |
||||||
|
{{ form.errors.stat_pswd.0 }}{# текст ошибки #} |
||||||
|
</div> |
||||||
|
|
||||||
|
{% else %} |
||||||
|
{# ошибки нет #} |
||||||
|
<div class="input"> |
||||||
|
{{ form.stat_pswd }} |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
<div class="input"> |
||||||
|
<button type="submit" class="icon-check submit">Подтвердить</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
</form> |
||||||
|
|
||||||
|
{% else %} |
||||||
|
<table width="100%"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Дата</th> |
||||||
|
<th>Официальный сайт</th> |
||||||
|
<th>Билеты</th> |
||||||
|
<th>Участие</th> |
||||||
|
<th>Переходы с каталога</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% with stats=object.paidstat_set.all %} |
||||||
|
{% for stat in stats %} |
||||||
|
<tr> |
||||||
|
<td>{{ stat.date|date:"Y-m-d" }}</td> |
||||||
|
<td>{{ stat.official_clicks }}</td> |
||||||
|
<td>{{ stat.tickets_clicks }}</td> |
||||||
|
<td>{{ stat.participation_clicks }}</td> |
||||||
|
<td>{{ stat.catalog_clicks }}</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
{% endwith %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
@ -1,219 +0,0 @@ |
|||||||
{% extends 'base_catalog.html' %} |
|
||||||
{% load static %} |
|
||||||
{% load i18n %} |
|
||||||
{% load template_filters %} |
|
||||||
|
|
||||||
|
|
||||||
{% block content_list %} |
|
||||||
|
|
||||||
{% block content_text %} |
|
||||||
{% block page_body %} |
|
||||||
<div class="m-article"> |
|
||||||
<div class="item-wrap event clearfix"> |
|
||||||
<aside> |
|
||||||
{% if object_list.0.expohit %} |
|
||||||
<div class="hit"></div> |
|
||||||
{% endif %} |
|
||||||
<div class="i-pict"> |
|
||||||
{% with obj=object_list.0 %} |
|
||||||
{% include 'client/includes/show_logo.html' %} |
|
||||||
{% endwith %} |
|
||||||
</div> |
|
||||||
<!-- |
|
||||||
<div class="i-rating" title="Рейтинг: 551">551</div> |
|
||||||
--> |
|
||||||
<div class="i-stats"> |
|
||||||
|
|
||||||
{% if object_list.0.visitors %} |
|
||||||
<span class="visitors" title="Посетители">{{ object_list.0.visitors }}</span> |
|
||||||
{% endif %} |
|
||||||
{% if object_list.0.members %} |
|
||||||
<span class="participants" title="Участники">{{ object_list.0.members }}</span> |
|
||||||
{% endif %} |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="i-discount"> |
|
||||||
{% if object_list.0.discount %} |
|
||||||
<a class="discount-button" href="#">{% trans 'Скидка' %} -{{ object_list.0.discount }}%</a> |
|
||||||
|
|
||||||
<div class="dsc-text">{{ object_list.0.discount_description|safe }}</div> |
|
||||||
{% endif %} |
|
||||||
</div> |
|
||||||
</aside> |
|
||||||
|
|
||||||
<div class="i-info"> |
|
||||||
<header> |
|
||||||
<div class="i-title"> |
|
||||||
{% if object_list.0.main_title %} |
|
||||||
{{ object_list.0.main_title|safe }} |
|
||||||
{% else %} |
|
||||||
{{ object_list.0.name|safe }} |
|
||||||
{% endif %} |
|
||||||
</div> |
|
||||||
</header> |
|
||||||
|
|
||||||
<div class="i-date"> |
|
||||||
{% with obj=object_list.0 %} |
|
||||||
{% include 'client/includes/show_date_block.html' %} |
|
||||||
{% endwith %} |
|
||||||
</div> |
|
||||||
{% if object_list.0.place %} |
|
||||||
<div class="i-address"> |
|
||||||
<header> |
|
||||||
<div class="address"> |
|
||||||
{{ object_list.0.place.address.address }} |
|
||||||
</div> |
|
||||||
<div class="show-map"><a class="toggle-map" href="#">{% trans 'Раскрыть карту' %}</a></div> |
|
||||||
</header> |
|
||||||
|
|
||||||
<div class="i-map"> |
|
||||||
<div class="close-map"><a class="toggle-map" href="#">{% trans 'Скрыть карту' %}</a> |
|
||||||
</div> |
|
||||||
<div class="map-canvas" id="map-canvas" |
|
||||||
data-coords="{{ object_list.0.place.address.lat }},{{ exposition.place.address.lng }}"></div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
{% endif %} |
|
||||||
|
|
||||||
|
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<div class="e-price"> |
|
||||||
<div class="sect-title">{% trans 'Стоимость посещения и участия' %}</div> |
|
||||||
<div class="ep-wrap"> |
|
||||||
|
|
||||||
<div class="e-price-wrap"> |
|
||||||
<div class="epr-layout"> |
|
||||||
|
|
||||||
<div class="eprl-col"> |
|
||||||
<div class="epr-title"><span>{% trans 'Для посещения' %}</span></div> |
|
||||||
|
|
||||||
<div class="epr-subtitle">{% trans 'Стоимость билетов' %}</div> |
|
||||||
|
|
||||||
<div class="tp-wrap"> |
|
||||||
|
|
||||||
<ul class="pr-list"> |
|
||||||
{% if object_list.0.price_day %} |
|
||||||
<li> |
|
||||||
<div class="prl-value">{{ object_list.0.price_day }} €</div> |
|
||||||
<div class="prl-descr"><span>{% trans 'на 1 день' %}</span></div> |
|
||||||
</li> |
|
||||||
{% endif %} |
|
||||||
{% if object_list.0.price_all %} |
|
||||||
<li> |
|
||||||
<div class="prl-value">{{ object_list.0.price_all }} €</div> |
|
||||||
<div class="prl-descr"><span>{% trans 'на все дни' %}</span></div> |
|
||||||
</li> |
|
||||||
{% endif %} |
|
||||||
|
|
||||||
</ul> |
|
||||||
|
|
||||||
<div class="tp-descr">{% trans 'Предварительная регистрация' %}</div> |
|
||||||
|
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="tp-wrap"> |
|
||||||
|
|
||||||
<ul class="pr-list gray"> |
|
||||||
{% if object_list.0.price_day_bar %} |
|
||||||
<li> |
|
||||||
<div class="prl-value">{{ object_list.0.price_day_bar }} €</div> |
|
||||||
|
|
||||||
<div class="prl-descr"><span>на 1 день</span></div> |
|
||||||
</li> |
|
||||||
{% endif %} |
|
||||||
{% if object_list.0.price_all_bar %} |
|
||||||
<li> |
|
||||||
<div class="prl-value">{{ object_list.0.price_all_bar }} €</div> |
|
||||||
<div class="prl-descr"><span>{% trans 'на все дни' %}</span></div> |
|
||||||
</li> |
|
||||||
{% endif %} |
|
||||||
|
|
||||||
</ul> |
|
||||||
|
|
||||||
<div class="tp-descr gray">{% trans 'Регистрация на' %} {% trans 'стойке' %}</div> |
|
||||||
|
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="tp-btn-wrap"> |
|
||||||
<div class="tp-btn"> |
|
||||||
<a class="button big orange b-more" href="#">{% trans 'Заказать билет' %}</a> |
|
||||||
</div> |
|
||||||
<div class="tp-categories"> |
|
||||||
<div class="tpc-title">{% trans 'Выставка открыта для' %}:</div> |
|
||||||
<ul> |
|
||||||
{{ object_list.0.get_audience }} |
|
||||||
|
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="eprl-col"> |
|
||||||
<div class="epr-title"><span>{% trans 'Для участия' %}</span></div> |
|
||||||
|
|
||||||
<div class="epr-subtitle">{% trans 'Стоимость аренды 1м²' %}</div> |
|
||||||
|
|
||||||
<ul class="pr-list"> |
|
||||||
{% if object_list.0.max_closed_equipped_area %} |
|
||||||
<li> |
|
||||||
|
|
||||||
<div class="prl-value">{{ object_list.0.max_closed_equipped_area }} €</div> |
|
||||||
<div class="prl-descr"><span>{% trans 'оборудованная площадь' %}</span></div> |
|
||||||
</li> |
|
||||||
{% endif %} |
|
||||||
|
|
||||||
{% if object_list.0.max_closed_area %} |
|
||||||
<li> |
|
||||||
<div class="prl-value">{{ object_list.0.max_closed_area }} €</div> |
|
||||||
<div class="prl-descr"><span>{% trans 'необорудованная площадь' %}</span></div> |
|
||||||
</li> |
|
||||||
{% endif %} |
|
||||||
|
|
||||||
{% if object_list.0.max_open_area %} |
|
||||||
<li> |
|
||||||
<div class="prl-value">{{ object_list.0.max_open_area }} €</div> |
|
||||||
<div class="prl-descr"><span>{% trans 'открытая площадь' %}</span></div> |
|
||||||
</li> |
|
||||||
{% endif %} |
|
||||||
|
|
||||||
</ul> |
|
||||||
|
|
||||||
<a class="button big orange b-more" href="#">{% trans 'Заявка на участие' %}</a> |
|
||||||
|
|
||||||
<div class="epr-conditons"> |
|
||||||
{% if object_list.0.min_stand_size %} |
|
||||||
<p>{% trans 'Минимальный размер стенда' %} — {{ object_list.0.min_stand_size }}м²</p> |
|
||||||
{% endif %} |
|
||||||
{% if object_list.0.registration_payment %} |
|
||||||
<p>{% trans 'Регистрационный взнос' %} — {{ object_list.0.registration_payment }}€</p> |
|
||||||
{% endif %} |
|
||||||
{% if object_list.0.application_deadline %} |
|
||||||
<p>{% trans 'Крайний срок подачи заявки' %} — {{ object_list.0.application_deadline }}</p> |
|
||||||
{% endif %} |
|
||||||
|
|
||||||
</div> |
|
||||||
|
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
</div> |
|
||||||
<div class="ed-back"> |
|
||||||
<a href="/{{ filter|generate_url:'event' }}">{{ object_list.0.name|safe }}</a> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="i-sub-articles"> |
|
||||||
<ul> |
|
||||||
{% for service in object_list.0.get_services %} |
|
||||||
<li><a href="#">{{ service.name }}</a></li> |
|
||||||
{% endfor %} |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
{% endblock %} |
|
||||||
{% endblock %} |
|
||||||
{% endblock %} |
|
||||||
@ -0,0 +1,4 @@ |
|||||||
|
<div class="sbnr"> |
||||||
|
<div class="sbnr-wrap" id="expo_b_aside_1"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
<div class="sbnr"> |
||||||
|
<div class="sbnr-wrap" id="expo_b_aside_2"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
<div class="sbnr"> |
||||||
|
<div class="sbnr-wrap" id="expo_b_aside_3"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
<div class="sbnr"> |
||||||
|
<div class="sbnr-wrap" id="expo_b_aside_4"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
<div id="expo_b_catalog_inner"> |
||||||
|
|
||||||
|
</div> |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
<div id="expo_b_detail_inner"> |
||||||
|
|
||||||
|
</div> |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
<div class="abn" id="expo_b_header"> |
||||||
|
|
||||||
|
</div> |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
<div class="abn" id="expo_b_under_search"> |
||||||
|
|
||||||
|
</div> |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
<div id="expo_top_events"> |
||||||
|
|
||||||
|
</div> |
||||||
|
<script> |
||||||
|
/* НУЖНО ЛИ??? */ |
||||||
|
window.sendData = { |
||||||
|
"theme": [{% for item in themes %}{{ item }}{% endfor %}], |
||||||
|
"country": "{{ country }}", |
||||||
|
"city": "{{ city }}", |
||||||
|
"tag": "{{ tag }}" |
||||||
|
}; |
||||||
|
var url = "/expo-b/get-tops/"; |
||||||
|
</script> |
||||||
@ -0,0 +1,102 @@ |
|||||||
|
{% load static %} |
||||||
|
{% load i18n %} |
||||||
|
{% load template_filters %} |
||||||
|
|
||||||
|
<ul class="cat-list cl-exhibitions"> |
||||||
|
|
||||||
|
{% for obj in objects %} |
||||||
|
<li class="cl-item {% if obj.canceled %}canceled{% endif %}"> |
||||||
|
<div class="cl-item-wrap clearfix"> |
||||||
|
{% if not obj.canceled %} |
||||||
|
<a href="{% if not obj.paid_new_id %}{{ obj.get_permanent_url }}{% else %}{{ obj.get_paid_catalog_url }}{% endif %}"> |
||||||
|
{% if obj.expohit %} |
||||||
|
<div class="hit"></div> |
||||||
|
{% endif %} |
||||||
|
<div class="cli-pict"> |
||||||
|
{% with obj=obj %} |
||||||
|
{% include 'client/includes/show_logo.html' %} |
||||||
|
{% endwith %} |
||||||
|
</div> |
||||||
|
</a> |
||||||
|
|
||||||
|
{% else %} |
||||||
|
<div class="cancel"></div> |
||||||
|
<div class="cli-pict"> |
||||||
|
{% with obj=obj %} |
||||||
|
{% include 'client/includes/show_logo.html' %} |
||||||
|
{% endwith %} |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
<div class="cli-info"> |
||||||
|
<div class="cli-top clearfix"> |
||||||
|
{% if obj.quality_label.ufi.is_set %} |
||||||
|
<div class="cli-approved"> |
||||||
|
<img src="{% static 'client/img/approved-logo.png' %}" alt="" title="Approved Event" /> |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
<header> |
||||||
|
<div class="cli-title"><a href="{% if not obj.paid_new_id %}{{ obj.get_permanent_url }}{% else %}{{ obj.get_paid_catalog_url }}{% endif %}">{{ obj.name|safe }}</a></div> |
||||||
|
</header> |
||||||
|
<div class="cli-descr"> |
||||||
|
{{ obj.main_title|safe }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="cli-bot clearfix"> |
||||||
|
<div class="cli-date"> |
||||||
|
{% with obj=obj %} |
||||||
|
{% include 'client/includes/show_date_block.html' %} |
||||||
|
{% endwith %} |
||||||
|
</div> |
||||||
|
{% if obj.country %} |
||||||
|
<div class="cli-place"> |
||||||
|
<a href="{{ obj.catalog }}country/{{ obj.country.url }}/">{{ obj.country }}</a>, <a href="{{ obj.catalog }}city/{{ obj.city.url }}/">{{ obj.city }}</a> |
||||||
|
{% if obj.place %} |
||||||
|
, <a href="/places/{{ obj.place.url }}/">{{ obj.place }}</a> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="cli-buttons clearfix"> |
||||||
|
<div class="cli-m-buttons"> |
||||||
|
{% include 'client/includes/exposition/services.html' with obj=obj %} |
||||||
|
{% include 'client/includes/calendar_button.html' with obj=obj%} |
||||||
|
<div class="{% if request.user.is_authenticated%}note-wrap{% else %}note-wrap-disabled{% endif %}"> |
||||||
|
{% with note=obj|note_by_user:request.user %} |
||||||
|
<a class="button green icon-note {% if note %}active{% endif %} note-button" href="/expo/add-note/{{ obj.url }}/">{% trans 'заметка' %}</a> |
||||||
|
<div class="note-overlay"> |
||||||
|
<form action=""> |
||||||
|
<textarea name="note_text" class="note-text"> {{ note }}</textarea> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
{% endwith %} |
||||||
|
</div> |
||||||
|
{% if request.user.is_admin %} |
||||||
|
<div class="note-wrap"> |
||||||
|
<a class="button green " href="/admin/exposition/{{ obj.url }}/">{% trans 'изменить' %}</a> |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
<div></div> |
||||||
|
</div> |
||||||
|
<div class="cli-s-buttons"> |
||||||
|
{% include 'client/buttons/booking_button.html' with object=obj %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<footer class="clearfix"> |
||||||
|
<div class="cli-stats"> |
||||||
|
{% if obj.visitors %} |
||||||
|
<span class="visitors" title="Посетители">{{ obj.visitors }}</span> |
||||||
|
{% endif %} |
||||||
|
{% if obj.members %} |
||||||
|
<span class="participants" title="Участники">{{ obj.members }}</span> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
<div class="cli-tags"> |
||||||
|
{% include 'client/includes/exposition/tags.html' with obj=obj %} |
||||||
|
</div> |
||||||
|
</footer> |
||||||
|
</li> |
||||||
|
{% endfor %} |
||||||
|
|
||||||
|
</ul> |
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue