コード例 #1
0
class NoticeReadTracker(models.Model):
    """
    Save per user notice read tracking
    """
    user = models.ForeignKey(get_user_model_path(), blank=False, null=False)
    notice = models.ForeignKey(Notice, blank=True, null=True)
    time_stamp = models.DateTimeField(auto_now=True)

    objects = NoticeReadTrackerManager()

    class Meta(object):
        verbose_name = _('Notice read tracker')
        verbose_name_plural = _('Notice read trackers')
        unique_together = ('user', 'notice')
コード例 #2
0
class Profile(NoticeappProfile):
    """
    Profile class that can be used if you doesn't have
    your site profile.
    """
    user = AutoOneToOneField(get_user_model_path(),
                             related_name='noticeapp_profile',
                             verbose_name=_('User'))

    class Meta(object):
        verbose_name = _('Profile')
        verbose_name_plural = _('Profiles')

    def get_absolute_url(self):
        return reverse(
            'noticeapp:user',
            kwargs={'username': getattr(self.user, get_username_field())})
コード例 #3
0
class PollAnswerUser(models.Model):
    poll_answer = models.ForeignKey(PollAnswer,
                                    related_name='users',
                                    verbose_name=_('Poll answer'))
    user = models.ForeignKey(get_user_model_path(),
                             related_name='poll_answers',
                             verbose_name=_('User'))
    timestamp = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = _('Poll answer user')
        verbose_name_plural = _('Polls answers users')
        unique_together = ((
            'poll_answer',
            'user',
        ), )

    def __str__(self):
        return '%s - %s' % (self.poll_answer.course, self.user)
コード例 #4
0
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from noticeapp.compat import get_image_field_full_name, get_user_model_path, get_user_frozen_models


AUTH_USER = get_user_model_path()


class Migration(SchemaMigration):

    def forwards(self, orm):

        # Deleting field 'Attachment.hash'
        db.delete_column('noticeapp_attachment', 'hash')

        # Deleting field 'Attachment.content_type'
        db.delete_column('noticeapp_attachment', 'content_type')

        # Deleting field 'Attachment.path'
        db.delete_column('noticeapp_attachment', 'path')

        # Deleting field 'Attachment.name'
        db.delete_column('noticeapp_attachment', 'name')


    def backwards(self, orm):

        # Adding field 'Attachment.hash'
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from noticeapp.compat import get_image_field_full_name, get_user_model_path, get_user_frozen_models


AUTH_USER = get_user_model_path()


class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding unique constraint on 'CourseReadTracker', fields ['course', 'user']
        db.create_unique('noticeapp_coursereadtracker', ['course_id', 'user_id'])

        # Adding unique constraint on 'NoticeReadTracker', fields ['user', 'notice']
        db.create_unique('noticeapp_noticereadtracker', ['user_id', 'notice_id'])


    def backwards(self, orm):
        # Removing unique constraint on 'NoticeReadTracker', fields ['user', 'notice']
        db.delete_unique('noticeapp_noticereadtracker', ['user_id', 'notice_id'])

        # Removing unique constraint on 'CourseReadTracker', fields ['course', 'user']
        db.delete_unique('noticeapp_coursereadtracker', ['course_id', 'user_id'])


    models = {
        'auth.group': {
コード例 #6
0
class Notice(models.Model):
    category = models.ForeignKey(Category,
                                 related_name='notices',
                                 verbose_name=_('Category'))
    parent = models.ForeignKey('self',
                               related_name='child_notices',
                               verbose_name=_('Parent notice'),
                               blank=True,
                               null=True)
    name = models.CharField(_('Name'), max_length=80)
    position = models.IntegerField(_('Position'), blank=True, default=0)
    description = models.TextField(_('Description'), blank=True)
    moderators = models.ManyToManyField(get_user_model_path(),
                                        blank=True,
                                        null=True,
                                        verbose_name=_('Moderators'))
    updated = models.DateTimeField(_('Updated'), blank=True, null=True)
    post_count = models.IntegerField(_('Post count'), blank=True, default=0)
    course_count = models.IntegerField(_('Course count'),
                                       blank=True,
                                       default=0)
    hidden = models.BooleanField(_('Hidden'),
                                 blank=False,
                                 null=False,
                                 default=False)
    readed_by = models.ManyToManyField(get_user_model_path(),
                                       through='NoticeReadTracker',
                                       related_name='readed_notices')
    headline = models.TextField(_('Headline'), blank=True, null=True)

    class Meta(object):
        ordering = ['position']
        verbose_name = _('Notice')
        verbose_name_plural = _('Notices')

    def __str__(self):
        return self.name

    def update_counters(self):
        posts = Post.objects.filter(course__notice_id=self.id)
        self.post_count = posts.count()
        self.course_count = Course.objects.filter(notice=self).count()
        try:
            last_post = posts.order_by('-created', '-id')[0]
            self.updated = last_post.updated or last_post.created
        except IndexError:
            pass

        self.save()

    def get_absolute_url(self):
        return reverse('noticeapp:notice', kwargs={'pk': self.id})

    @property
    def posts(self):
        return Post.objects.filter(course__notice=self).select_related()

    @property
    def last_post(self):
        try:
            return self.posts.order_by('-created', '-id')[0]
        except IndexError:
            return None

    def get_parents(self):
        """
        Used in templates for breadcrumb building
        """
        parents = [self.category]
        parent = self.parent
        while parent is not None:
            parents.insert(1, parent)
            parent = parent.parent
        return parents
コード例 #7
0
class Post(RenderableItem):
    course = models.ForeignKey(Course,
                               related_name='posts',
                               verbose_name=_('Course'))
    user = models.ForeignKey(get_user_model_path(),
                             related_name='posts',
                             verbose_name=_('User'))
    created = models.DateTimeField(_('Created'), blank=True, db_index=True)
    updated = models.DateTimeField(_('Updated'), blank=True, null=True)
    user_ip = models.IPAddressField(_('User IP'),
                                    blank=True,
                                    default='0.0.0.0')
    on_moderation = models.BooleanField(_('On moderation'), default=False)

    class Meta(object):
        ordering = ['created']
        verbose_name = _('Post')
        verbose_name_plural = _('Posts')

    def summary(self):
        limit = 50
        tail = len(self.body) > limit and '...' or ''
        return self.body[:limit] + tail

    def __str__(self):
        return self.summary()

    def save(self, *args, **kwargs):
        created_at = tznow()
        if self.created is None:
            self.created = created_at
        self.render()

        new = self.pk is None

        course_changed = False
        old_post = None
        if not new:
            old_post = Post.objects.get(pk=self.pk)
            if old_post.course != self.course:
                course_changed = True

        super(Post, self).save(*args, **kwargs)

        # If post is course head and moderated, moderate course too
        if self.course.head == self and not self.on_moderation and self.course.on_moderation:
            self.course.on_moderation = False

        self.course.update_counters()
        self.course.notice.update_counters()

        if course_changed:
            old_post.course.update_counters()
            old_post.course.notice.update_counters()

    def get_absolute_url(self):
        return reverse('noticeapp:post', kwargs={'pk': self.id})

    def delete(self, *args, **kwargs):
        self_id = self.id
        head_post_id = self.course.posts.order_by('created', 'id')[0].id

        if self_id == head_post_id:
            self.course.delete()
        else:
            super(Post, self).delete(*args, **kwargs)
            self.course.update_counters()
            self.course.notice.update_counters()

    def get_parents(self):
        """
        Used in templates for breadcrumb building
        """
        return self.course.notice.category, self.course.notice, self.course,
コード例 #8
0
class Course(models.Model):
    POLL_TYPE_NONE = 0
    POLL_TYPE_SINGLE = 1
    POLL_TYPE_MULTIPLE = 2

    POLL_TYPE_CHOICES = (
        (POLL_TYPE_NONE, _('None')),
        (POLL_TYPE_SINGLE, _('Single answer')),
        (POLL_TYPE_MULTIPLE, _('Multiple answers')),
    )

    notice = models.ForeignKey(Notice,
                               related_name='courses',
                               verbose_name=_('Notice'))
    name = models.CharField(_('Subject'), max_length=255)
    created = models.DateTimeField(_('Created'), null=True)
    updated = models.DateTimeField(_('Updated'), null=True)
    user = models.ForeignKey(get_user_model_path(),
                             verbose_name=_('User'),
                             related_name='notice_user')
    views = models.IntegerField(_('Views count'), blank=True, default=0)
    sticky = models.BooleanField(_('Sticky'), blank=True, default=False)
    closed = models.BooleanField(_('Closed'), blank=True, default=False)
    subscribers = models.ManyToManyField(get_user_model_path(),
                                         related_name='subscriptions',
                                         verbose_name=_('Subscribers'),
                                         blank=True)
    post_count = models.IntegerField(_('Post count'), blank=True, default=0)
    readed_by = models.ManyToManyField(get_user_model_path(),
                                       through='CourseReadTracker',
                                       related_name='readed_courses')
    on_moderation = models.BooleanField(_('On moderation'), default=False)
    poll_type = models.IntegerField(_('Poll type'),
                                    choices=POLL_TYPE_CHOICES,
                                    default=POLL_TYPE_NONE)
    poll_question = models.TextField(_('Poll question'), blank=True, null=True)

    class Meta(object):
        ordering = ['-created']
        verbose_name = _('Course')
        verbose_name_plural = _('Courses')

    def __str__(self):
        return self.name

    @property
    def head(self):
        """
        Get first post and cache it for request
        """
        if not hasattr(self, "_head"):
            self._head = self.posts.all().order_by('created', 'id')
        if not len(self._head):
            return None
        return self._head[0]

    @property
    def last_post(self):
        if not getattr(self, '_last_post', None):
            self._last_post = self.posts.order_by(
                '-created', '-id').select_related('user')[0]
        return self._last_post

    def get_absolute_url(self):
        return reverse('noticeapp:course', kwargs={'pk': self.id})

    def save(self, *args, **kwargs):
        if self.id is None:
            self.created = tznow()
            self.updated = tznow()

        notice_changed = False
        old_course = None
        if self.id is not None:
            old_course = Course.objects.get(id=self.id)
            if self.notice != old_course.notice:
                notice_changed = True

        super(Course, self).save(*args, **kwargs)

        if notice_changed:
            old_course.notice.update_counters()
            self.notice.update_counters()

    def delete(self, using=None):
        super(Course, self).delete(using)
        self.notice.update_counters()

    def update_counters(self):
        self.post_count = self.posts.count()
        last_post = Post.objects.filter(course_id=self.id).order_by(
            '-created', '-id')[0]
        self.updated = last_post.updated or last_post.created
        self.save()

    def get_parents(self):
        """
        Used in templates for breadcrumb building
        """
        parents = self.notice.get_parents()
        parents.append(self.notice)
        return parents

    def poll_votes(self):
        if self.poll_type != self.POLL_TYPE_NONE:
            return PollAnswerUser.objects.filter(
                poll_answer__course=self).count()
        else:
            return None