# encoding=utf-8
import random
import re
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
import datetime
from django.db.models import SET_NULL
from lms.regex import check_email
from lms.settings import STATIC_ROOT, DOMAIN
from lms.tools import random_string, random_int, out_date_format, get_client_ip
import os
from management.letters import sent_registration
from storage.models import Storage
import django.utils.timezone
from django.core.files.base import File
from django.utils.deconstruct import deconstructible
from uuid import uuid4
ROLE = (
('U', u'Студент школы'),
('T', u'Преподаватель'),
('M', u'Менеджер'),
('S', u'Руководитель'),
('S2', u'Куратор'),
('A', u'Администратор'),
('Ts', u'Тестовый пользователь'),
('F', u'Пользователь свободного счета')
)
@deconstructible
class PathAndRename(object):
def __init__(self, sub_path):
self.path = sub_path
def __call__(self, instance, filename):
ext = filename.split('.')[-1]
# set filename as random string
filename = '{}.{}'.format(uuid4().hex, ext)
# return the whole path to the file
return os.path.join(self.path, filename)
path_and_rename = PathAndRename("personal_files")
def insert_in_system(user, sent_letter=True):
if sent_letter:
sent_registration(user)
user.subscription = Subscription.objects.create(owner=user)
user.interactive_key = gen_interactive_key(user)
user.save()
def random_avatar():
ava_dir = os.path.join(STATIC_ROOT, 'img/avs')
files = os.listdir(ava_dir)
return os.path.join(ava_dir, random.choice(files))
class UserManager(BaseUserManager):
def create_user(self, email, password=None, sent_letter=True):
if not email:
raise ValueError(u"Пользователь должен иметь email")
if not check_email(email):
raise ValueError(u"Email введен не верно")
user = self.model(email=email)
user.set_password(password)
user.token = random_string(length=10, postfix=user.get_email())
user.save(using=self._db)
insert_in_system(user, sent_letter=sent_letter)
return user
def create_superuser(self, email, password):
user = self.create_user(email, password=password)
user.is_admin = True
user.is_active = True
user.superuser = True
user.is_staff = True
user.token = random_string(length=10, postfix=user.get_email())
user.save(using=self._db)
return user
def __unicode__(self):
return u'%s %s' % (self.get_short_name(), self.email)
def get_activate_time():
return datetime.datetime.now() + datetime.timedelta(days=7)
def gen_interactive_key(user):
# 1 Надпись ID
# 2 id в системе
# 3 #
# 4 5 случайных чисел
return 'ID{0}-{1}'.format(user.id, random_int(length=5))
class User(AbstractBaseUser):
STATUS_CHOICES = (
('ON', 'on-line'),
('OFF', 'off-line')
)
REG_STATUS = (
('1', 'Пароль'),
('2', 'О себе'),
('3', 'Фото'),
('4', 'Закончена')
)
PRIVATE = (
('A', 'Всему интернету'),
('U', 'Только пользователям системы'),
('L', 'По прямой ссылке'),
('B', 'Только мне')
)
SOURCE = (
('S', 'Органично'),
('B', 'Привлечен')
)
#sync = models.BooleanField(verbose_name=u'Синхронизирован', default=False)
#sync_date = models.DateTimeField(verbose_name=u'Дата постановки на синхронизацию', blank=True, null=True)
block = models.BooleanField(verbose_name=u'Заблокировать', default=False)
refer = models.CharField(verbose_name=u'Источник', max_length=1, choices=SOURCE, default='S', null=True)
refer_source = models.CharField(verbose_name=u'Источник пользователя', blank=True, max_length=255, default='')
traf_source = models.ForeignKey('TrafHistory', verbose_name=u'Обращение', blank=True, null=True)
private = models.CharField(verbose_name=u'Приватность профиля', max_length=1, choices=PRIVATE, default='A')
customer = models.BooleanField(verbose_name=u'Покупатель', default=False)
interactive_key = models.CharField(verbose_name=u'Интерактивый ключ', max_length=255, blank=True)
deactivate = models.BooleanField(verbose_name=u'Не давать новых студентов', default=False)
delay = models.BooleanField(verbose_name=u'Могут быть задержки', default=False, help_text=u'Если возможны задержки с проверками')
delay_description = models.TextField(verbose_name=u'Повод просрочки', blank=True)
delay_date = models.DateTimeField(verbose_name=u'Задержка до. Не включая этот день.', blank=True, default=django.utils.timezone.now, null=True)
email = models.EmailField(verbose_name='email', max_length=255, blank=True, db_index=True, unique=True,
help_text=u'Будьте аккуратны. Менять почту можно. Но только если очень нужно.')
changed_email = models.EmailField(verbose_name=u'Ящик на замену', blank=True, null=True)
phone = models.CharField(verbose_name=u'Телефон', max_length=255, default='', blank=True)
back_phone = models.CharField(verbose_name=u'Предидущий телефон', max_length=255, default='', blank=True)
status = models.CharField(max_length=9, choices=STATUS_CHOICES, default='ON')
in_role = models.CharField(verbose_name=u'Роль', choices=ROLE, max_length=2, default='U')
unique_role = models.CharField(verbose_name=u'Уникальная роль', max_length=255, blank=True, default='')
city = models.CharField(verbose_name=u'Город', max_length=255, default='', blank=True)
b_day = models.DateField(verbose_name=u'День рождения', null=True, blank=True)
token = models.CharField(max_length=255, default='', blank=True)
activate_time = models.DateTimeField(verbose_name=u"Активировать до", default=get_activate_time)
reg_status = models.CharField(verbose_name=u'Статус регистрации', choices=REG_STATUS, max_length=1, default='1')
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False, editable=False)
is_staff = models.BooleanField(default=False, editable=False)
objects = UserManager()
avatar = models.CharField(verbose_name=u"Ключ аватара", max_length=255, blank=True, default='')
in_avatar = models.ImageField(verbose_name=u'Наш аватар', blank=True, null=True, editable=False, upload_to='in_ava')
fname = models.CharField(verbose_name=u"Фамилия", max_length=255, blank=True, default='')
name = models.CharField(verbose_name=u"Имя", max_length=255, blank=True, default='')
oname = models.CharField(verbose_name=u"Отчество", max_length=255, blank=True, default='')
#
skype = models.CharField(max_length=300, blank=True, default='')
facebook = models.CharField(default='', max_length=255, blank=True)
vk = models.CharField(max_length=255, default='', blank=True)
linkedin = models.CharField(max_length=255, default='', blank=True)
odnoklassniki = models.CharField(max_length=255, default='', blank=True)
#
last_time = models.DateTimeField(verbose_name=u'Последняя активность', default=datetime.datetime.now)
date_joined = models.DateTimeField(default=datetime.datetime.now)
last_ip = models.ForeignKey('UserRequest', verbose_name=u'Последний IP', blank=True, null=True, related_name='user_last_ip', on_delete=SET_NULL)
USERNAME_FIELD = 'email'
def save(self, *args, **kwargs):
if self.in_role in ['A', 'S2'] and not self.is_admin:
self.is_admin = True
self.is_staff = True
if self.in_role in ['M']:
self.is_staff = True
if not self.interactive_key:
self.interactive_key = gen_interactive_key(self)
super(User, self).save(*args, **kwargs)
def get_ip_len(self):
UserRequest.objects.filter(user=self).count()
def set_request_data(self, request):
ip = get_client_ip(request)
try:
_request = UserRequest.objects.get(ip=ip, user=self)
except UserRequest.DoesNotExist:
_request = UserRequest.objects.create(ip=ip, user=self)
_request.new_count(request)
self.last_ip = _request
self.save()
def get_ip(self):
return self.last_ip.ip if self.last_ip else None
def get_activation_url(self):
return u'{3}/access/activate/?step=1&token={0}&email={1}'.format(self.token, self.email, self.reg_status, DOMAIN)
def _set_to_sync(self):
self.sync = False
self.sync_date = datetime.datetime.now()
self.save()
def _set_synced(self):
self.sync = True
self.sync_date = None
self.save()
def change_token(self):
self.token = random_string(length=10, postfix=self.email)
self.save()
def get_status_point(self):
return {'title': self.get_status_display(),
'color': 'green' if self.status == 'ON' else 'red',
'point': 'glyphicon glyphicon-ok-sign' if self.status == 'ON' else 'glyphicon glyphicon-remove-sign'}
def get_full_data(self):
return self.full_data()
def full_data(self):
return 'Имя: {0} - Телефон: {1} - Почта: {2}'.format(self.get_full_name(), self.get_phone(), self.email)
def get_name(self):
if self.name:
return self.name
else:
return 'Без имени'
def get_face(self):
return {'full_name': self.get_full_name(),
'short_name': self.get_short_name(),
'name': self.name if self.name else '',
'fname': self.fname if self.fname else '',
'oname': self.oname if self.oname else '',
'email': self.email,
'phone': self.get_phone(),
'ava': self.get_image_url(),
'date_joined': out_date_format(self.date_joined),
'status': self.get_status_point(),
'id': self.id,
'interactive_key': self.interactive_key,
'is_staff': self.is_staff or self.is_admin,
'role': self.unique_role if self.unique_role else self.get_in_role_display(),
'is_unique_role': bool(self.unique_role),
'profile': self.get_profile()}
def get_username(self):
return self.get_short_name()
def get_image_url(self, type_in=None):
try:
image = Storage.objects.get(key=self.avatar)
except Storage.DoesNotExist:
if not self.in_avatar:
self.in_avatar.save('ava', File(open(random_avatar(), 'rb')), save=True)
return '{0}/{1}'.format(DOMAIN, self.in_avatar.url)
else:
try:
image = image.get_url(type_in)
except IOError:
if not self.in_avatar:
self.in_avatar.save('ava', File(open(random_avatar(), 'rb')), save=True)
return '{0}/{1}'.format(DOMAIN, self.in_avatar.url)
return image
def clean_image(self):
self.avatar = ''
self.save()
def get_phone(self):
return self.phone
def get_back_phone(self):
return self.back_phone
def get_email(self):
return self.email
def get_full_name(self):
result = u""
# Если есть фамилия пишем: Фамилия Имя Отчество
if self.fname:
result += u"%s" % self.fname
if self.name:
result += u" %s" % self.name
if self.oname:
result += u" %s" % self.oname
if result:
return result
else:
return self.email
def get_short_name(self):
result = u""
# Если есть фамилия пишем: Фамилия И.О.
if self.fname:
result += u"%s" % self.fname
if self.name:
result += u" %s." % self.name[0].upper()
if self.oname:
result += u" %s." % self.oname[0].upper()
# Если нет фамилии пишем: Имя Отчество
elif not self.fname and self.name:
if self.name:
result += u"%s" % self.name
if self.oname:
result += u" %s" % self.oname
if result:
return result
else:
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
def check_subscription(self, right):
return Subscription.objects.get_or_create(owner=self)[0].check_right(right)
def get_profile(self):
return u'{0}/{1}'.format(DOMAIN, self.interactive_key)
def __unicode__(self): return u'%s:%s' % (self.id, self.get_short_name())
def __str__(self): return '%s:%s' % (self.id, self.get_short_name())
def name_to_html(self, user):
if user == self:
return u"Вы"
else:
return u"%s" \
% (self.id, self.get_short_name())
def check_phone(self, _type='actual'): # actual = self.phone, back = self.back_phone
phone = self.phone if _type == 'actual' else self.back_phone
return bool(len(''.join([n for n in phone if n in [str(x) for x in range(0,10)]])) > 9)
def clean_phone(self, _type='actual'):
return ''.join([n for n in self.phone if n in [str(x) for x in range(0,10)]]) if self.check_phone() else ''
class Meta:
verbose_name = u"Пользователя"
verbose_name_plural = u"Пользователи"
class UserRequest(models.Model):
# Информация о сессиях пользователей при авторизации
ip = models.CharField(verbose_name=u'IP', max_length=255)
user = models.ForeignKey(User, verbose_name=u'Пользователь')
count = models.IntegerField(verbose_name=u'Количество использований', default=0)
date = models.DateTimeField(verbose_name=u'Дата', default=datetime.datetime.now)
def __str__(self):
return self.ip
def new_count(self, request):
self.count += 1
UserRequestData.objects.create(row=self, data=request)
self.save()
class Meta:
verbose_name = u'Данные сессии при авторизации'
verbose_name_plural = u'Данные сессий при авторизации'
class UserRequestData(models.Model):
# Содержимое сессии пользователя
row = models.ForeignKey(UserRequest, verbose_name=u'Запрос')
data = models.TextField(verbose_name=u'Данные')
date = models.DateTimeField(verbose_name=u'Дата', default=datetime.datetime.now)
def __str__(self):
return str(self.row)
class Meta:
verbose_name = u'Данные запроса'
verbose_name_plural = u'Данные запроса'
class Subscription(models.Model):
# Подписки
owner = models.OneToOneField(User, verbose_name=u"Владелец", unique=True, related_name='rights_owner')
news = models.BooleanField(verbose_name=u"Подписка на новости", default=True)
teacher = models.BooleanField(verbose_name=u'Ответы преподователя', default=True)
new_comments = models.BooleanField(verbose_name=u'Ответы на комментарии', default=True)
send_sms = models.BooleanField(verbose_name=u'Отправлять sms', default=False)
courses = models.BooleanField(verbose_name=u'Новые курсы', default=True)
def __str__(self): return "%s: %s" % (self.id, self.owner)
def __unicode__(self): return u"%s: %s" % (self.id, self.owner)
def check_right(self, right):
# Проверка указанного права для пользователя
return self.right_map(right)
def set_right(self, right, value):
# Установка права
if right == 'news':
self.news = value
elif right == 'teacher':
self.teacher = value
elif right == 'send_sms':
self.send_sms = value
elif right == 'courses':
self.courses = value
elif right == 'new_comments':
self.new_comments = value
self.save()
def set_default_values(self):
# Установка дефолтных значений
for field in self._meta.fields:
if field.has_default:
self.set_right(field.name, field.default)
def right_map(self, right):
# Карта проверки прав
__right_map = {
'news': self.news,
'teacher': self.teacher,
'send_sms': self.send_sms,
'courses': self.courses,
'new_comments': self.new_comments
}
if right in __right_map:
return __right_map[right]
else:
return __right_map
class Meta:
verbose_name = u"Подписка"
verbose_name_plural = u"Подписки"
class ActionJ(models.Model):
ACTION_TYPE = (
('B', 'b-default'),
('P', 'b-primary'),
('S', 'b-success'),
('I', 'b-info'),
('W', 'b-warning'),
('D', 'b-danger')
)
student = models.ForeignKey(User, verbose_name=u'Студент')
a_type = models.CharField(verbose_name=u'Тип события', choices=ACTION_TYPE, max_length=1, default='B')
place = models.CharField(verbose_name=u'Место создания события', max_length=100)
date = models.DateTimeField(verbose_name=u'Время создания', default=django.utils.timezone.now)
text = models.TextField(verbose_name=u'Текст сообщения')
def __str__(self):
return '%s %s %s' % (self.get_a_type_display(), self.place, self.date)
def __unicode__(self):
return u'%s %s %s' % (self.get_a_type_display(), self.place, self.date)
class Meta:
verbose_name = u'Журнал активности'
verbose_name_plural = u'Журналы активностей'
class TrafSource(models.Model):
on = models.BooleanField(verbose_name=u'Ативен', default=True)
url = models.URLField(verbose_name=u'Источник трафика')
token = models.CharField(verbose_name=u'Токен доступа', max_length=255, editable=False)
token_start = models.DateTimeField(verbose_name=u'Точка отсчета жизни токена', editable=False, null=True)
live_time = models.IntegerField(verbose_name=u'Время жизни токена', blank=True, help_text=u'Указывается в часах. пустое поле - пожизненно', null=True)
date_start = models.DateTimeField(verbose_name=u'Дата запуска источника', default=datetime.datetime.now)
def __str__(self):
return '%s' % self.url
def __unicode__(self):
return u'%s' % self.url
def save(self, *args, **kwargs):
if not self.token:
self.token = random_string(length=20)
self.token_start = datetime.datetime.now()
super(TrafSource, self).save(*args, **kwargs)
class Meta:
verbose_name = u'Источник трафика'
verbose_name_plural = u'Источники трафика'
class TrafTokenHistory(models.Model):
token = models.CharField(verbose_name=u'Токен', max_length=255, editable=False)
live_time = models.IntegerField(verbose_name=u'Время жизни', help_text=u'В часах', editable=False)
date_start = models.DateTimeField(verbose_name=u'Дата установки токена', editable=False)
date_end = models.DateTimeField(verbose_name=u'Дата отключения', editable=False)
source = models.ForeignKey(TrafSource, verbose_name=u'Использующий источник', editable=False)
def __str__(self):
return '%s %s:%s %s' % (self.token, self.date_start, self.date_end, self.sources)
def __unicode__(self):
return u'%s %s:%s %s' % (self.token, self.date_start, self.date_end, self.sources)
class Meta:
verbose_name = u'История смены токена'
verbose_name_plural = u'Истории смены токенов'
class TrafHistory(models.Model):
TRAF_ACTION = (
('G', 'Получение данных'),
('D', 'Запись данных'),
('C', 'Создание пользователя'),
('O', 'Создание счета')
)
action = models.CharField(verbose_name=u'Действие', choices=TRAF_ACTION, max_length=1)
source = models.ForeignKey(TrafSource, verbose_name=u'Источник запроса')
token = models.CharField(verbose_name=u'Используемый токен', max_length=255, null=True)
data = models.TextField(verbose_name=u'Данные в запросе')
result = models.BooleanField(verbose_name=u'Результат запроса', default=False)
result_description = models.CharField(verbose_name=u'Описание результата', max_length=255, blank=True)
date = models.DateTimeField(verbose_name=u'Дата обращения', default=datetime.datetime.now)
def __str__(self):
return '%s %s %s' % (self.source, self.action, self.result)
def __unicode__(self):
return u'%s %s %s' % (self.source, self.action, self.result)
class Meta:
verbose_name = u'Обращение источника'
verbose_name_plural = u'Обращения источников'
class Document(models.Model):
DOC_STATUS = (
('W', u'На оформлении'),
('F', u'Оформлен')
)
title = models.CharField(verbose_name=u'Заголовок', max_length=255)
status = models.CharField(verbose_name=u'Статус', choices=DOC_STATUS, default='W', editable=False, max_length=1)
user = models.ForeignKey(User, verbose_name=u'Пользователь')
date = models.DateField(verbose_name=u'Дата заключения', default=datetime.datetime.now)
file = models.FileField(verbose_name=u'Скан', upload_to='documents', null=True, blank=True)
in_date = models.DateTimeField(verbose_name=u'Дата добавления', default=datetime.datetime.now, editable=False)
def __str__(self):
return u'%s %s' % (self.title, self.date)
def __unicode__(self):
return u'%s %s' % (self.title, self.date)
def save(self, *args, **kwargs):
if self.file and self.status != 'F':
self.status = 'F'
elif not self.file and self.status != 'W':
self.status = 'W'
super(Document, self).save(*args, **kwargs)
class Meta:
verbose_name = u'Документ'
verbose_name_plural = u'Документы'
class Questionnaire(models.Model):
GENDER = (
('M', 'Мужчина'),
('W', 'Женщина')
)
EXP = (
('1', 'Только начинаю'),
('2', 'Да, менее года'),
('3', 'Да, 1-2 года'),
('4', 'Да, более 2 лет')
)
AIM = (
('1', 'Да, в офисе'),
('2', 'Да, свой проект'),
('3', 'Да, на фрилансе'),
('4', 'Нет, изучаю для себя')
)
AGE = (
('1', 'до 18'),
('2', '18-25'),
('3', '25-30'),
('4', '30-40'),
('5', 'больше 40')
)
FULLY = (
('1', 'Флаги'),
('2', 'Свободный ответ'),
('3', 'Завершено')
)
fully = models.CharField(verbose_name=u'Стадия', max_length=1, choices=FULLY, default=1) # Завершенность заполения
steps = models.IntegerField(verbose_name=u'Количество показов', default=0, help_text=u'Количество показов для заполнения')
user = models.ForeignKey(User, verbose_name=u'Пользователь')
male = models.CharField(verbose_name=u'Пол', choices=GENDER, max_length=1, null=True, blank=True)
city = models.CharField(verbose_name=u'Город', max_length=255, null=True, blank=True)
experience = models.CharField(verbose_name=u'Опыт', max_length=1, choices=EXP, null=True, blank=True)
aim = models.CharField(verbose_name=u'Цель обучения', max_length=1, choices=AIM, null=True, blank=True)
age = models.CharField(verbose_name=u'Возраст', max_length=1, choices=AGE, null=True, blank=True)
description = models.TextField(verbose_name=u'Свободны ответ', blank=True)
def __str__(self):
return u'%s %s' % (self.user, self.get_fully_display())
def __unicode__(self):
return u'%s %s' % (self.user, self.get_fully_display())
class Meta:
verbose_name = u'Акета'
verbose_name_plural = u'Анкеты'
#class UserSync(models.Model):
# user = models.ForeignKey(User, verbose_name=u'Синхронизируемый')
# date = models.DateTimeField(verbose_name=u'Дата начала', default=datetime.datetime.now)
# data = models.TextField(verbose_name=u'Сырые данные', blank=True, default='')
# f_date = models.DateTimeField(verbose_name=u'Дата завершения процеса', blank=True, null=True)
# source = models.CharField(verbose_name=u'Источник синхронизации', max_length=255)
# dist = models.CharField(verbose_name=u'Получатель синхронизации', max_length=255)
# result = models.BooleanField(verbose_name=u'Результат синхронизации', default=False)
# def __str__(self):
# return '%s %s %s' % (self.user, self.f_date, self.result)
# def __unicode__(self):
# return u'%s %s %s' % (self.user, self.f_date, self.result)
# def good_sync(self):
# self.f_date = datetime.datetime.now()
# self.result = True
# self.save()
# self.user._set_synced()
# def fail_sync(self):
# self.f_date = datetime.datetime.now()
# self.result = False
# self.save()
# class Meta:
# verbose_name = u'Задача синхронизации'
# verbose_name_plural = u'Задачи синхронизации'