Add last unread function

This commit is contained in:
Skia
2017-01-29 00:16:41 +01:00
parent 4cc57c183e
commit 254126fd79
14 changed files with 229 additions and 36 deletions

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
from django.utils.timezone import utc
import datetime
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('forum', '0003_forum_owner_club'),
]
operations = [
migrations.CreateModel(
name='ForumUserInfo',
fields=[
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
('last_read_date', models.DateTimeField(verbose_name='last read date', default=datetime.datetime(1999, 1, 1, 0, 0, tzinfo=utc))),
('user', models.OneToOneField(related_name='_forum_infos', to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('forum', '0004_forumuserinfo'),
]
operations = [
migrations.AddField(
model_name='forumuserinfo',
name='read_messages',
field=models.ManyToManyField(to='forum.ForumMessage', related_name='readers', verbose_name='read messages'),
),
]

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('forum', '0005_forumuserinfo_read_messages'),
]
operations = [
migrations.RemoveField(
model_name='forumuserinfo',
name='read_messages',
),
migrations.AddField(
model_name='forummessage',
name='readers',
field=models.ManyToManyField(to=settings.AUTH_USER_MODEL, related_name='read_messages', verbose_name='readers'),
),
]

View File

@ -7,6 +7,9 @@ from django.db import IntegrityError, transaction
from django.core.urlresolvers import reverse
from django.utils import timezone
from datetime import datetime
import pytz
from core.models import User, MetaGroup, Group, SithFile
from club.models import Club
@ -136,10 +139,14 @@ class ForumMessage(models.Model):
title = models.CharField(_("title"), default="", max_length=64, blank=True)
message = models.TextField(_("message"), default="")
date = models.DateTimeField(_('date'), default=timezone.now)
readers = models.ManyToManyField(User, related_name="read_messages", verbose_name=_("readers"))
class Meta:
ordering = ['id']
def __str__(self):
return "%s" % (self.title)
def is_owned_by(self, user):
return self.topic.is_owned_by(user) or user.id == self.author.id
@ -150,5 +157,14 @@ class ForumMessage(models.Model):
return user.can_view(self.topic)
def get_absolute_url(self):
return self.topic.get_absolute_url()
return self.topic.get_absolute_url() + "#first_unread"
def mark_as_read(self, user):
self.readers.add(user)
class ForumUserInfo(models.Model):
user = models.OneToOneField(User, related_name="_forum_infos")
last_read_date = models.DateTimeField(_('last read date'), default=datetime(year=settings.SITH_SCHOOL_START_YEAR,
month=1, day=1, tzinfo=pytz.UTC))
# read_messages = models.ManyToManyField(ForumMessage, related_name="readers", verbose_name=_("read messages"))

View File

@ -1,6 +1,9 @@
{% extends "core/base.jinja" %}
{% from 'forum/macros.jinja' import display_forum %}
{% from 'core/macros.jinja' import user_profile_link %}
{% from 'forum/macros.jinja' import display_forum, display_topic %}
{% block title %}
{{ forum }}
{% endblock %}
{% block content %}
<div>
@ -21,34 +24,7 @@
{{ display_forum(f, user) }}
{% endfor %}
{% for t in topics %}
<div class="topic">
<div class="ib w_medium">
<a class="ib w_big" href="{{ url('forum:view_topic', topic_id=t.id) }}">
<h5>{{ t.title }}</h5>
<p>{{ t.description }}</p>
</a>
{% if user.is_owner(t) %}
<div class="ib" style="text-align: center;">
<a href="{{ url('forum:edit_topic', topic_id=t.id) }}">Edit</a>
</div>
{% endif %}
</div>
<div class="ib w_medium">
<div class="ib w_medium">
<div class="ib w_medium" style="text-align: center;">
{{ user_profile_link(t.author) }}
</div>
<div class="ib w_medium" style="text-align: center;">
{{ t.messages.count() }}
</div>
</div>
<div class="ib w_medium" style="text-align: center;">
{% set last_msg = t.messages.order_by('id').last() %}
{{ user_profile_link(last_msg.author) }} <br/>
{{ last_msg.date|date(DATETIME_FORMAT) }} {{ last_msg.date|time(DATETIME_FORMAT) }}
</div>
</div>
</div>
{{ display_topic(t, user) }}
{% endfor %}
{% endblock %}

View File

@ -0,0 +1,24 @@
{% extends "core/base.jinja" %}
{% from 'forum/macros.jinja' import display_topic %}
{% block title %}
{% trans %}Last unread messages{% endtrans %}
{% endblock %}
{% block content %}
<p>
<a href="{{ url('forum:main') }}">Forum</a> >
</p>
<h3>{% trans %}Forum{% endtrans %}</h3>
<h4>{% trans %}Last unread messages{% endtrans %}</h4>
<p>
<a class="ib" href="{{ url('forum:mark_all_as_read') }}">{% trans %}Mark all as read{% endtrans %}</a>
<a class="ib" href="{{ url('forum:last_unread') }}">{% trans %}Refresh{% endtrans %}</a>
</p>
{% for t in forumtopic_list %}
{{ display_topic(t, user, True) }}
{% endfor %}
{% endblock %}

View File

@ -1,3 +1,5 @@
{% from 'core/macros.jinja' import user_profile_link %}
{% macro display_forum(forum, user) %}
<div class="forum {% if forum.is_category %}category{% endif %}">
<div class="ib w_big">
@ -35,4 +37,38 @@
</div>
{% endmacro %}
{% macro display_topic(topic, user, first_unread=False) %}
<div class="topic">
<div class="ib w_medium">
{% if first_unread %}
<a class="ib w_big" href="{{ url('forum:view_topic', topic_id=topic.id) }}#first_unread">
{% else %}
<a class="ib w_big" href="{{ url('forum:view_topic', topic_id=topic.id) }}">
{% endif %}
<h5>{{ topic.title }}</h5>
<p>{{ topic.description }}</p>
</a>
{% if user.is_owner(topic) %}
<div class="ib" style="text-align: center;">
<a href="{{ url('forum:edit_topic', topic_id=topic.id) }}">{% trans %}Edit{% endtrans %}</a>
</div>
{% endif %}
</div>
<div class="ib w_medium">
<div class="ib w_medium">
<div class="ib w_medium" style="text-align: center;">
{{ user_profile_link(topic.author) }}
</div>
<div class="ib w_medium" style="text-align: center;">
{{ topic.messages.count() }}
</div>
</div>
<div class="ib w_medium" style="text-align: center;">
{% set last_msg = topic.messages.order_by('id').last() %}
{{ user_profile_link(last_msg.author) }} <br/>
{{ last_msg.date|date(DATETIME_FORMAT) }} {{ last_msg.date|time(DATETIME_FORMAT) }}
</div>
</div>
</div>
{% endmacro %}

View File

@ -2,16 +2,25 @@
{% from 'core/macros.jinja' import user_profile_link %}
{% from 'forum/macros.jinja' import display_forum %}
{% block title %}
{% trans %}Forum{% endtrans %}
{% endblock %}
{% block content %}
<p>
<a href="{{ url('forum:main') }}">Forum</a> >
</p>
<h3>{% trans %}Forum{% endtrans %}</h3>
<p>
{% if user.is_in_group(settings.SITH_GROUP_FORUM_ADMIN_ID) or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %}
<a href="{{ url('forum:new_forum') }}">New forum</a>
{% endif %}
<a class="ib" href="{{ url('forum:last_unread') }}">{% trans %}View last unread messages{% endtrans %}</a>
<a class="ib" href="{{ url('forum:mark_all_as_read') }}">{% trans %}Mark all as read{% endtrans %}</a>
<a class="ib" href="{{ url('forum:main') }}">{% trans %}Refresh{% endtrans %}</a>
</p>
{% if user.is_in_group(settings.SITH_GROUP_FORUM_ADMIN_ID) or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %}
<p>
<a href="{{ url('forum:new_forum') }}">{% trans %}New forum{% endtrans %}</a>
</p>
{% endif %}
{% for f in forum_list %}
<div style="padding: 4px; margin: 4px">
{{ display_forum(f, user) }}

View File

@ -1,6 +1,10 @@
{% extends "core/base.jinja" %}
{% from 'core/macros.jinja' import user_profile_link %}
{% block title %}
{{ topic }}
{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css" media="all">
@ -32,8 +36,16 @@
<h3>{{ topic.title }}</h3>
<p>{{ topic.description }}</p>
<p><a href="{{ url('forum:new_message', topic_id=topic.id) }}">Reply</a></p>
{% set unread = False %}
{% for m in topic.messages.all() %}
{% if m.id == first_unread_message_id %}
<div class="message unread" id="first_unread">
{% set unread = True %}
{% elif unread %}
<div class="message unread">
{% else %}
<div class="message">
{% endif %}
<div class="msg_author">
{% if m.author.profile_pict %}
<img src="{{ m.author.profile_pict.get_download_url() }}" alt="{% trans %}Profile{% endtrans %}" id="picture" />
@ -64,6 +76,7 @@
</div>
</div>
</div>
{# m.mark_as_read(user) or "" #}
{% endfor %}
{% endblock %}

View File

@ -5,6 +5,8 @@ from forum.views import *
urlpatterns = [
url(r'^$', ForumMainView.as_view(), name='main'),
url(r'^new_forum$', ForumCreateView.as_view(), name='new_forum'),
url(r'^mark_all_as_read$', ForumMarkAllAsRead.as_view(), name='mark_all_as_read'),
url(r'^last_unread$', ForumLastUnread.as_view(), name='last_unread'),
url(r'^(?P<forum_id>[0-9]+)$', ForumDetailView.as_view(), name='view_forum'),
url(r'^(?P<forum_id>[0-9]+)/edit$', ForumEditView.as_view(), name='edit_forum'),
url(r'^(?P<forum_id>[0-9]+)/delete$', ForumDeleteView.as_view(), name='delete_forum'),

View File

@ -16,6 +16,29 @@ class ForumMainView(CanViewMixin, ListView):
queryset = Forum.objects.filter(parent=None)
template_name = "forum/main.jinja"
class ForumMarkAllAsRead(RedirectView):
permanent = False
url = reverse_lazy('forum:last_unread')
def get(self, request, *args, **kwargs):
try:
fi = request.user.forum_infos
fi.last_read_date = timezone.now()
fi.save()
except: pass
return super(ForumMarkAllAsRead, self).get(request, *args, **kwargs)
class ForumLastUnread(ListView):
model = ForumTopic
template_name = "forum/last_unread.jinja"
def get_queryset(self):
l = ForumMessage.objects.exclude(readers=self.request.user).filter(
date__gt=self.request.user.forum_infos.last_read_date).values_list('topic') # TODO try to do better
return self.model.objects.filter(id__in=l).annotate(models.Max('messages__date')).order_by('-messages__date__max')
# return self.model.objects.exclude(messages__readers=self.request.user).distinct().annotate(
# models.Max('messages__date')).order_by('-messages__date__max')
class ForumCreateView(CanCreateMixin, CreateView):
model = Forum
fields = ['name', 'parent', 'owner_club', 'is_category', 'edit_groups', 'view_groups']
@ -95,6 +118,15 @@ class ForumTopicDetailView(CanViewMixin, DetailView):
template_name = "forum/topic.jinja"
context_object_name = "topic"
def get_context_data(self, **kwargs):
kwargs = super(ForumTopicDetailView, self).get_context_data(**kwargs)
msg = self.object.messages.exclude(readers=self.request.user).order_by('id').first()
try:
kwargs['first_unread_message_id'] = msg.id
except:
kwargs['first_unread_message_id'] = -1
return kwargs
class ForumMessageEditView(CanEditMixin, UpdateView):
model = ForumMessage
fields = ['title', 'message']