commit
3a8ee32218
123 changed files with 5045 additions and 605 deletions
@ -1,12 +1,13 @@ |
||||
# -*- coding: utf-8 -*- |
||||
from django.conf.urls import patterns, url |
||||
from admin import UserListView |
||||
from admin import UserListView, EditUser |
||||
|
||||
urlpatterns = patterns('', |
||||
#url(r'^registration/$', 'accounts.admin.registration'), |
||||
#url(r'^create_admin/$', 'accounts.admin.create_admin'), |
||||
#url(r'^create_md5user/$', 'accounts.admin.create_md5'), |
||||
url(r'^change/(.*)/$', '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'^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 |
||||
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} |
||||
|
||||
from django.contrib.sites.models import Site, RequestSite |
||||
from registration.models import RegistrationProfile |
||||
|
||||
|
||||
def create_user(strategy, details, response, uid, user=None, *args, **kwargs): |
||||
if user: |
||||
return {'user': user, 'is_new': False} |
||||
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: |
||||
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'): |
||||
user = User.objects.safe_get(email=details['email']) |
||||
if user: |
||||
return {'user': user, 'is_new': False} |
||||
else: |
||||
user = User.objects.create_user(email=details['email'], first_name=details['first_name'], |
||||
last_name=details['last_name'], password='1q2w3e4r', is_active=True) |
||||
Send an email with an embedded verification code and the necessary details to restore the required session |
||||
elements to complete the verification and sign-in, regardless of what browser the user completes the |
||||
verification from. |
||||
""" |
||||
signature = signing.dumps({"session_key": strategy.session.session_key, "email": code.email}, |
||||
key=settings.EMAIL_SECRET_KEY) |
||||
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} |
||||
else: |
||||
return None |
||||
""" |
||||
emailHTML = ''# Include your function that returns an html string here |
||||
emailText = """Welcome to Expomap.ru! |
||||
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