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