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.
490 lines
21 KiB
490 lines
21 KiB
# coding=utf-8
|
|
from django.db import models
|
|
import locale, datetime
|
|
from access.models import User
|
|
from redactor.fields import RedactorField
|
|
from lms.tools import out_date_format, random_int, random_string
|
|
from courses.templates import comment_fabric
|
|
from management.letters import sent_new_feedback
|
|
from storage.models import Storage
|
|
import django.utils.timezone
|
|
from precise_bbcode.fields import BBCodeTextField
|
|
from markdown import markdown
|
|
|
|
MODAL_STATUS = (
|
|
('C', 'Создана'),
|
|
('P', 'Выполняется'),
|
|
('Q', 'На очереди'),
|
|
('F', 'Закончено')
|
|
)
|
|
|
|
|
|
def gen_comment_token(comment):
|
|
# 1 Надпись ID
|
|
# 2 id в системе
|
|
# 3 #
|
|
# 4 5 случайных чисел
|
|
return 'C{0}-{1}'.format(comment.id, random_int(length=5))
|
|
|
|
|
|
def gen_modal_key():
|
|
# Генерация ключа шаблона модуля
|
|
return 'M{0}'.format(random_string())
|
|
|
|
|
|
def gen_modal_journal_key():
|
|
return 'MJ{0}'.format(random_int(length=30))
|
|
|
|
|
|
class NewsletterShell(models.Model):
|
|
name = models.CharField(verbose_name=u'Название шаблона', max_length=255)
|
|
head = models.TextField(verbose_name=u'Заголовок')
|
|
footer = models.TextField(verbose_name=u'Футер')
|
|
|
|
def __unicode__(self):
|
|
return u'%s' % self.name
|
|
|
|
def __str__(self):
|
|
return '%s' % self.name
|
|
|
|
class Meta:
|
|
verbose_name = u'Оболочка рассылки'
|
|
verbose_name_plural = u'Оболочки рассылок'
|
|
|
|
|
|
class Newsletter(models.Model):
|
|
STATUS = (
|
|
('Q', u'На очереди'),
|
|
('W', u'Выполняется'),
|
|
('F', u'Выполнено')
|
|
)
|
|
status = models.CharField(verbose_name=u'Статус', max_length=1, choices=STATUS, default='Q')
|
|
shell = models.ForeignKey(NewsletterShell, verbose_name=u'Оболочка', null=True)
|
|
author = models.ForeignKey(User, verbose_name=u'Инициатор', related_name='newsletter_owner')
|
|
text = models.TextField(verbose_name=u'Текст сообщения')
|
|
recipient = models.ManyToManyField(User, verbose_name=u'Получатели', related_name='newsletter_request')
|
|
date = models.DateTimeField(verbose_name=u'Дата постановки задачи', default=datetime.datetime.now)
|
|
sent_date = models.DateTimeField(verbose_name=u'Дата отправки', default=datetime.datetime.now)
|
|
f_recipient = models.ManyToManyField(User, verbose_name=u'Отправлено', related_name='newsletter_response')
|
|
|
|
def __unicode__(self):
|
|
return u'%s %s %s:%s' % (self.author.get_short_name(), self.get_status_display(), self.date, self.sent_date)
|
|
|
|
def __str__(self):
|
|
return '%s %s %s:%s' % (self.author.get_short_name(), self.get_status_display(), self.date, self.sent_date)
|
|
|
|
class Meta:
|
|
verbose_name = u'Рассылка'
|
|
verbose_name_plural = u'Рассылки'
|
|
|
|
|
|
class News(models.Model):
|
|
public = models.BooleanField(verbose_name='Опубликовать', default=False)
|
|
title = models.CharField(verbose_name='Заголовок', max_length=255)
|
|
icon = models.ImageField(verbose_name=u'Иконка', upload_to='news', blank=True)
|
|
image = models.ImageField(verbose_name='Заголовочное изображение', upload_to='news', blank=True)
|
|
content = RedactorField(verbose_name='Текст')
|
|
author = models.ForeignKey(User, verbose_name='Автор', related_name='author_user')
|
|
public_date = models.DateTimeField(verbose_name='Дата публикации', blank=True)
|
|
create_date = models.DateTimeField(verbose_name='Дата создания', default=django.utils.timezone.now)
|
|
|
|
def __unicode__(self):
|
|
return u'{0}'.format(self.public)
|
|
|
|
def __str__(self):
|
|
return '{0}'.format(self.public)
|
|
|
|
def get_date(self):
|
|
return out_date_format(self.public_date, no_time=True)
|
|
|
|
def save(self, *args, **kwargs):
|
|
if self.public and not self.public_date:
|
|
self.public_date = django.utils.timezone.now()
|
|
super(News, self).save(*args, **kwargs)
|
|
|
|
class Meta:
|
|
verbose_name = 'Новость'
|
|
verbose_name_plural = 'Новости'
|
|
ordering = ['-public_date']
|
|
|
|
|
|
class CommentSawTable(models.Model):
|
|
comment = models.ForeignKey('Comment', verbose_name=u'Комментарий')
|
|
user = models.ForeignKey(User, verbose_name=u'Просмотревший')
|
|
date = models.DateTimeField(verbose_name=u'Время просмотра просмотра', default=datetime.datetime.now)
|
|
|
|
def __unicode__(self):
|
|
return u'%s %s' % (self.user, self.date)
|
|
|
|
def __str__(self):
|
|
return '%s %s' % (self.user, self.date)
|
|
|
|
class Meta:
|
|
verbose_name = u'Журнал просмотра'
|
|
verbose_name_plural = u'Журналы просмотров'
|
|
|
|
|
|
class Comment(models.Model):
|
|
STATUSES = (
|
|
('G', 'Одобрено'),
|
|
('F', 'Отклонено'),
|
|
('A', 'Сообщение от администрации'),
|
|
('T', 'Техническое обращение'),
|
|
('H', 'Домашняя работа студента'),
|
|
('Q', 'Вопрос на форуме'),
|
|
('Q2', 'Ответ на форуме'),
|
|
('S', 'Комментарий')
|
|
)
|
|
token = models.CharField(verbose_name=u'Ключь доступа', max_length=100, default='', editable=False)
|
|
best = models.BooleanField(verbose_name=u'Лучший ответ', default=False)
|
|
rating = models.IntegerField(verbose_name=u'Рейтинг', default=0)
|
|
minus_rating = models.ManyToManyField(User, verbose_name=u'Хейтеры', editable=False, null=True)
|
|
plus_rating = models.ManyToManyField(User, verbose_name=u'Гудеры', editable=False, null=True)
|
|
status = models.CharField(verbose_name=u'Статус сообщения', max_length=2, choices=STATUSES, default='S')
|
|
saw = models.ManyToManyField(User, verbose_name=u'Прочитавшие', blank=True, editable=False)
|
|
response = models.BooleanField(verbose_name=u'Есть ответ от админа', default=False, editable=False)
|
|
response_comment = models.ForeignKey('self', verbose_name=u'Комментарий ответа от админа', blank=True, null=True, related_name='admin_text_response', editable=False)
|
|
closed = models.BooleanField(verbose_name=u'Закрыт', default=False, editable=False)
|
|
parent_id = models.IntegerField(verbose_name=u'ID исходника', default=0, blank=True, editable=False)
|
|
owner = models.ForeignKey(User, verbose_name=u'Автор', related_name='comment_owner')
|
|
text = RedactorField(verbose_name=u'Текст', default='')
|
|
bbtext = BBCodeTextField(verbose_name=u'BB Текст', default='', blank=True)
|
|
markdown = models.TextField(blank=True, default='')
|
|
html_content = models.TextField(editable=False, blank=True, default='')
|
|
date = models.DateTimeField(verbose_name=u'Отправка', default=datetime.datetime.now)
|
|
files = models.ManyToManyField(Storage, verbose_name=u'Прикрепленые файлы', blank=True, editable=False)
|
|
send = models.BooleanField(verbose_name=u'Отправлено', default=False, editable=False)
|
|
replies = models.ManyToManyField('self', verbose_name=u'Ответы', blank=True, null=True, related_name='all_text_response', editable=False)
|
|
answers = models.ManyToManyField('self', verbose_name=u'Форумные ответы', blank=True, null=True, related_name='forum_answers', editable=False)
|
|
|
|
def __unicode__(self):
|
|
return str(self.id)
|
|
|
|
def __str__(self):
|
|
return str(self.id)
|
|
|
|
def get_text(self):
|
|
# Возвращение html текста из bb
|
|
if self.html_content:
|
|
return self.html_content
|
|
|
|
elif self.bbtext.rendered:
|
|
result = self.bbtext.rendered
|
|
# TODO : Кастыль, Настроить приложения, чтобы тег обрабатывался стандартно
|
|
if '[/*]' in result:
|
|
result = str(result).replace('[/*]', '')
|
|
return result
|
|
|
|
elif self.text:
|
|
return self.text
|
|
|
|
def get_root_id(self):
|
|
do = True
|
|
cur = None
|
|
if self.parent_id:
|
|
while do:
|
|
comment = Comment.objects.get(id=self.parent_id)
|
|
if comment.parent_id:
|
|
cur = comment.parent_id
|
|
else:
|
|
return cur
|
|
return cur
|
|
|
|
def plus_rating(self, user):
|
|
# Добавить рейтинг
|
|
# =============
|
|
# Проверить пользователя в хейтерах - удалить его оттуда
|
|
# Проверить пользоветля в гудерах и добавить - если его там нет
|
|
pass
|
|
|
|
def minus_rating(self, user):
|
|
# Отнять рейтинг
|
|
# ============
|
|
# Проверить пользователя в хейтерах - удалить его оттуда
|
|
# Проверить пользоветля в гудерах и добавить - если его там нет
|
|
pass
|
|
|
|
def check_opinion(self, user):
|
|
# Проверить мнение и вернуть состояние голоса
|
|
pass
|
|
|
|
def get_opinion(self, user):
|
|
# Получить цвет мнения
|
|
# ============
|
|
# null = нет мнения
|
|
# True = положительное мнение
|
|
# False = отрицательное мнение
|
|
pass
|
|
|
|
def delete_opinion(self, user):
|
|
# Удалить мнение пользователя
|
|
pass
|
|
|
|
def save(self, *args, **kwargs):
|
|
if not self.status:
|
|
if '<span class="label label-success">Задача принята! </span><br>' in self.text:
|
|
self.status = 'G'
|
|
self.text.replace('<span class="label label-success">Задача принята! </span><br>', '')
|
|
elif '<span class="label label-danger">Отправлено на доработку!</span><br>' in self.text:
|
|
self.status = 'F'
|
|
self.text.replace('<span class="label label-success">Задача принята! </span><br>', '')
|
|
else:
|
|
self.status = 'S'
|
|
|
|
if not self.token:
|
|
self.token = gen_comment_token(self)
|
|
self.html_content = markdown(self.markdown)
|
|
super(Comment, self).save(*args, **kwargs)
|
|
|
|
def get_answered(self):
|
|
return Comment.objects.filter(parent_id=self.id)
|
|
|
|
def set_saw(self, user):
|
|
# Проверить, что прочитан ли комментарий и добавить пользователя в прочитавших
|
|
if not CommentSawTable.objects.filter(user=user, comment=self).exists():
|
|
CommentSawTable.objects.create(user=user, comment=self)
|
|
|
|
def get_replies(self, __type, __user):
|
|
result = []
|
|
for reply in Comment.objects.filter(parent_id=self.id):
|
|
result.append(comment_fabric(reply, __type=__type, __user=__user))
|
|
return result
|
|
|
|
def get_face(self, _type=None, _user=None):
|
|
return comment_fabric(self, __type=_type, __user=_user)
|
|
|
|
def get_RFC_date(self):
|
|
locale.setlocale(locale.LC_TIME, 'en_US')
|
|
return datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
|
|
|
|
class Meta:
|
|
verbose_name = u'Комментарий'
|
|
verbose_name_plural = u'Комментарии'
|
|
ordering = ['id']
|
|
|
|
|
|
class Feedback(models.Model):
|
|
closed = models.BooleanField(verbose_name=u'Взято в работу', default=False)
|
|
name = models.CharField(verbose_name=u'Имя', max_length=255)
|
|
email = models.CharField(verbose_name=u'Email', max_length=255)
|
|
phone = models.CharField(verbose_name=u'Телефон', max_length=255)
|
|
text = models.TextField(verbose_name=u'Текст')
|
|
date = models.DateTimeField(verbose_name=u'Время обращения', default=datetime.datetime.now)
|
|
send = models.BooleanField(verbose_name=u'Отправлено', default=False)
|
|
|
|
def __unicode__(self):
|
|
return u'%s %s' % (self.name, self.closed)
|
|
|
|
def __str__(self):
|
|
return '%s %s' % (self.name, self.closed)
|
|
|
|
def save(self, *args, **kwargs):
|
|
if not self.send:
|
|
for eye in User.objects.filter(in_role='S2'):
|
|
sent_new_feedback(self, eye.email)
|
|
super(Feedback, self).save(*args, **kwargs)
|
|
|
|
class Meta:
|
|
verbose_name = u'Вопрос'
|
|
verbose_name_plural = u'Вопросы'
|
|
|
|
|
|
class FaqTitle(models.Model):
|
|
is_admin = models.BooleanField(verbose_name=u'Только администраторам', default=False)
|
|
is_staff = models.BooleanField(verbose_name=u'Только сотрудникам', default=False)
|
|
title = models.CharField(verbose_name=u'Тема', max_length=255, unique=True)
|
|
icon = models.ImageField(verbose_name=u'Иконка', upload_to='faq', blank=True)
|
|
sort = models.IntegerField(verbose_name=u'Порядок', default=0)
|
|
|
|
def __unicode__(self):
|
|
return u'%s' % self.title
|
|
|
|
def __str__(self):
|
|
return '%s' % self.title
|
|
|
|
def get_face(self):
|
|
return {
|
|
'id': self.id,
|
|
'title': self.title,
|
|
'icon': self.get_image(),
|
|
'is_staff': self.is_staff,
|
|
'is_admin': self.is_admin,
|
|
'answers': [i.get_face() for i in Faq.objects.filter(title=self)]
|
|
}
|
|
|
|
def get_image(self):
|
|
if self.icon:
|
|
return self.icon.url
|
|
else:
|
|
return '/static/img/faq.png'
|
|
|
|
class Meta:
|
|
verbose_name = u'Заголовок FAQ'
|
|
verbose_name_plural = u'Заголовки FAQ'
|
|
ordering = ['sort']
|
|
|
|
|
|
class Faq(models.Model):
|
|
title = models.ForeignKey(FaqTitle, verbose_name=u'Раздел')
|
|
question = models.CharField(verbose_name=u'Вопрос', max_length=255)
|
|
answer = RedactorField(verbose_name=u'Ответ')
|
|
rating = models.IntegerField(verbose_name=u'Рейтинг статьи', default=0)
|
|
comments = models.ManyToManyField(Comment, verbose_name=u'Комментарии', blank=True, null=True, editable=False)
|
|
date = models.DateTimeField(verbose_name=u'Дата создания', default=datetime.datetime.now, editable=False)
|
|
|
|
def __str__(self):
|
|
return '%s %s' % (self.title, self.question)
|
|
|
|
def __unicode__(self):
|
|
return u'%s %s' % (self.title, self.question)
|
|
|
|
def get_face(self):
|
|
return {
|
|
'id': self.id,
|
|
'question': self.question,
|
|
'answer': self.answer,
|
|
'rating': self.rating
|
|
}
|
|
|
|
|
|
class ModalPlace(models.Model):
|
|
public = models.BooleanField(verbose_name=u'В работе', default=True)
|
|
key = models.CharField(verbose_name=u'Ключь места', max_length=255, default=gen_modal_key)
|
|
description = models.TextField(verbose_name=u'Описание', blank=True)
|
|
|
|
def __unicode__(self):
|
|
return u'%s' % self.key
|
|
|
|
def __str__(self):
|
|
return str(self.key)
|
|
|
|
def get_modals(self, user):
|
|
# Получить все модальные окна для этого места
|
|
pass
|
|
|
|
class Meta:
|
|
verbose_name = u'Всплывающие окна / Место вставок'
|
|
verbose_name_plural = u'Всплывающие окна / Места вставки'
|
|
|
|
|
|
class ModalTemplate(models.Model):
|
|
title = models.CharField(verbose_name=u'Заголовок', max_length=255)
|
|
key = models.CharField(verbose_name=u'Ключ Шаблона', max_length=255, default=gen_modal_key)
|
|
place = models.ForeignKey(ModalPlace, verbose_name=u'Место вставки', null=True)
|
|
context = models.TextField(verbose_name=u'Шаблон', help_text=u'{TEXT} - Место вставки текста,'
|
|
u'{TITLE} - Заголовок,'
|
|
u'{KEY} - Ключь окна')
|
|
|
|
def __unicode__(self):
|
|
return u'{0}-{1}'.format(self.title, self.key)
|
|
|
|
def __str__(self):
|
|
return '{0}-{1}'.format(self.title, self.key)
|
|
|
|
def get_title(self):
|
|
return '{0}-{1}'.format(self.title, self.key)
|
|
|
|
def get_modals(self, user):
|
|
# Получить все окна для этого шаблона
|
|
pass
|
|
|
|
class Meta:
|
|
verbose_name = u'Всплывающие окна / Шаблон'
|
|
verbose_name_plural = u'Всплывающие окна / Шаблоны'
|
|
|
|
|
|
class Modal(models.Model):
|
|
template = models.ForeignKey(ModalTemplate, verbose_name=u'Шаблон')
|
|
title = models.CharField(verbose_name=u'Заголовок', max_length=255, blank=True)
|
|
text = models.TextField(verbose_name=u'Содержимое окна', blank=True)
|
|
close = models.BooleanField(verbose_name=u'Закрываемое', default=True)
|
|
views = models.IntegerField(verbose_name=u'Необходимое количество просмотров', default=1)
|
|
closes = models.IntegerField(verbose_name=u'Необходимое количество закрытий', default=1)
|
|
interval = models.IntegerField(verbose_name=u'Интервал показов в часах', default=1)
|
|
show_time = models.DateTimeField(verbose_name=u'Начало показа', default=datetime.datetime.now)
|
|
hide_time = models.DateTimeField(verbose_name=u'Закрытие показов', blank=True, null=True)
|
|
|
|
def __unicode__(self):
|
|
return u'' % self.title
|
|
|
|
def __str__(self):
|
|
return str(self.title)
|
|
|
|
def get_title(self):
|
|
return self.title
|
|
|
|
def get_modals(self, user):
|
|
# Получить все окна для этого конструктора
|
|
pass
|
|
|
|
class Meta:
|
|
verbose_name = u'Всплывающие окна / Конструктор'
|
|
verbose_name_plural = u'Всплывающие окна / Конструкторы'
|
|
|
|
|
|
class ModalTask(models.Model):
|
|
user = models.ManyToManyField(User, verbose_name=u'Пользователи',
|
|
help_text=u'Как пользователь зайдет на сайт - отсюда он будет удален и '
|
|
u'будет создан журнал. ', related_name='task_user', blank=True, editable=False)
|
|
modal = models.ForeignKey(Modal, verbose_name=u'Окно')
|
|
manager = models.ForeignKey(User, verbose_name=u'Поставивший задачу', related_name='task_manager')
|
|
date = models.DateTimeField(verbose_name=u'Постановка задачи', default=datetime.datetime.now)
|
|
status = models.CharField(verbose_name=u'Статус', choices=MODAL_STATUS, default='C', max_length=1)
|
|
|
|
def __str__(self):
|
|
return str(self.modal.get_title())
|
|
|
|
def __unicode__(self):
|
|
return u'%s' % self.modal.get_title()
|
|
|
|
def get_modals(self, user):
|
|
# Получить все окна от этой задачи
|
|
pass
|
|
|
|
def save(self, *args, **kwargs):
|
|
|
|
super(ModalTask, self).save(*args, **kwargs)
|
|
|
|
class Meta:
|
|
verbose_name = u'Всплывающие окна / Задача'
|
|
verbose_name_plural = u'Всплывающие окна / Задачи'
|
|
|
|
|
|
class ModalJournal(models.Model):
|
|
STATUS = (
|
|
('O', 'Открыт'),
|
|
('С', 'Закрыт'),
|
|
('F', 'Закончен')
|
|
)
|
|
key = models.CharField(verbose_name=u'Ключ', max_length=255, default=gen_modal_journal_key)
|
|
status = models.CharField(verbose_name=u'Статус', choices=STATUS, default='O', editable=False, max_length=1)
|
|
user = models.ForeignKey(User, verbose_name=u'Пользователь')
|
|
date = models.DateTimeField(verbose_name=u'Дата показа', default=datetime.datetime.now, editable=False)
|
|
task = models.ForeignKey(ModalTask, verbose_name=u'Задача')
|
|
views = models.IntegerField(verbose_name=u'Необходимое количество просмотров', default=0)
|
|
closes = models.IntegerField(verbose_name=u'Необходимое количество закрытий', default=0)
|
|
|
|
def __unicode__(self):
|
|
return u'%s %s' % (self.user, self.date)
|
|
|
|
def __str__(self):
|
|
return u'%s %s' % (self.user, self.date)
|
|
|
|
def get_content(self, user):
|
|
pass
|
|
|
|
def save(self, *args, **kwargs):
|
|
if self.closes >= self.task.modal.closes:
|
|
self.status = 'F'
|
|
|
|
if self.views >= self.task.modal.views:
|
|
self.status = 'F'
|
|
|
|
if self.date >= self.task.modal.hide_time:
|
|
self.status = 'F'
|
|
|
|
super(ModalJournal, self).save(*args, **kwargs)
|
|
|
|
class Meta:
|
|
verbose_name = u'Всплывающие окна / Журнал'
|
|
verbose_name_plural = u'Всплывающие окна / Журналы'
|
|
|