← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands-website/internal_forum into lp:widelands-website

 

kaputtnik has proposed merging lp:~widelands-dev/widelands-website/internal_forum into lp:widelands-website.

Commit message:
Add possibility to have forums for internal discussions. Those Forums are hidden to normal users.
Make pybb.Moderator superfluous by applying a group to a forum.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1804295 in Widelands Website: "Add a moderator forum"
  https://bugs.launchpad.net/widelands-website/+bug/1804295

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands-website/internal_forum/+merge/360917

Changes:

Table pybb.Category:
- add a boolean column 'internal': If enabled, all subforums below this Category aren't visible to normal users
- add permission 'can access internal': Each user which has this permission can enter internal forums and add topics and posts. This permission can also be applied to a group, so each user in this group can enter the internal forums.

Internal Forums are shown if a logged in user has the permisssion 'can access internal':
- In the navigation Forums dropdown box with a different coloring
- In the forums overview

Internal Forums and posts are excluded from:
- The search
- The feeds
- E-Mailing for users which have notification setting 'Forum new topic' enabled. Users with permission 'can access internal' AND enabled notification setting 'Forum new topic' will receive an email for a new topic.


Table pybb.Forum:
- add a foreign key to django.admin.auth.group: Each Forum can be assigned to a group with administrative permissions. This makes the table pybb.Moderator superfluous. Removing it is planned for a follow up branch.

This makes it possible to have each forum a different moderator group, if wanted. It is recommended to give a moderator group the permission 'Can access internal'.


admin/auth/group:
- The list shows now all users which are in this group, including a link to admin/auth/user/username

admin/auth/user:
- The users list shows now if the user is in a group (the groups name) or has a permission of any kind. Showing all permissions in this list is too much, so this is only shown as 'has perm.'.


I will setup the alpha site for testing, not sure when i get around to do so.


To get this in:
1. There is an old issue derived from branch: https://bazaar.launchpad.net/~widelands-dev/widelands-website/trunk/revision/323
This removed the column post_count from both tables pybb.Forum and pybb.Topic but the migration did only removed the column from pybb.Topic, leaving post_count in pybb.Forum. So our database contain this column and will through an error if one wants to create a new forum. To fix this run  in the mysql console:
alter table pybb_forum drop column post_count;
2. merge the branch
3. run python manage.py migrate

Then one with appropriate permissions (at least the superuser) should be able to:
1. Create an internal category
2. Create a Forum inside this category
3. Apply permission 'Can access internal' to the existing group 'Forum Admin'
4. Check if all wanted users are in the group 'Forum Admin'. Remember superusers do not need to be added, because they have all permissions by default.
5. Apply the group 'Forum Admin' to each forum

-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands-website/internal_forum into lp:widelands-website.
=== modified file 'mainpage/admin.py'
--- mainpage/admin.py	2017-12-03 11:43:47 +0000
+++ mainpage/admin.py	2018-12-14 08:49:33 +0000
@@ -4,9 +4,52 @@
 """Get acces to additional models which are not set by Django by default.
 
 So Djangos orm is used when changing things, e.g. delete a permission.
-
 """
 
 from django.contrib import admin
 from django.contrib.auth.models import Permission
 admin.site.register(Permission)
+
+
+# Adjusted from: https://www.djangosnippets.org/snippets/1650/
+"""Displays the users which are in a group to /admin/auth/group.
+Displays groups and permissions to admin/auth/user."""
+
+from django.contrib.auth.models import User, Group
+from django.contrib.auth.admin import UserAdmin, GroupAdmin
+from django.core.urlresolvers import reverse
+
+
+def roles(self):
+    # Groups
+    text = [x.name for x in self.groups.all()]
+    # Permissions
+    if self.user_permissions.count():
+        text += ['has perm.']
+    value = ', '.join(text)
+    return value
+roles.short_description = u'Groups/Permissions'
+
+
+def persons(self):
+    return ', '.join(['<a href="%s">%s</a>' % (reverse('admin:auth_user_change', args=(x.id,)), x.username) for x in self.user_set.all().order_by('username')])
+persons.allow_tags = True
+
+
+class GroupAdmin(GroupAdmin):
+    list_display = ['name', persons]
+    list_display_links = ['name']
+
+
+admin.site.unregister(Group)
+admin.site.register(Group, GroupAdmin)
+
+
+class UserAdmin(UserAdmin):
+    list_display = ('username', 'email', 'date_joined', 'last_login',
+                    'is_active', 'is_staff', roles)
+    ordering = ('-date_joined',)
+
+
+admin.site.unregister(User)
+admin.site.register(User, UserAdmin)

=== modified file 'mainpage/templatetags/wl_extras.py'
--- mainpage/templatetags/wl_extras.py	2018-05-12 19:04:14 +0000
+++ mainpage/templatetags/wl_extras.py	2018-12-14 08:49:33 +0000
@@ -23,21 +23,6 @@
     return settings.LOGO_FILE
 
 
-@register.inclusion_tag('mainpage/forum_navigation.html')
-def forum_navigation():
-    """Makes the forum list available to the navigation.
-
-    Ordering:
-    1.: value of 'Position' in pybb.Category
-    2.: value of 'Position' of pybb.Forum.
-
-    """
-
-    from pybb.models import Category
-    categories = Category.objects.all()
-    return {'categories': categories}
-
-
 @register.filter
 def get_model_name(object):
     """Returns the name of an objects model."""

=== modified file 'pybb/admin.py'
--- pybb/admin.py	2018-10-03 09:01:09 +0000
+++ pybb/admin.py	2018-12-14 08:49:33 +0000
@@ -32,13 +32,13 @@
 
 
 class ForumAdmin(admin.ModelAdmin):
-    list_display = ['name', 'category', 'position', 'topic_count']
+    list_display = ['name', 'category', 'position', 'topic_count', 'moderator_group']
     list_per_page = 20
     ordering = ['category__position', 'position']
     search_fields = ['name', 'category__name']
     fieldsets = (
         (None, {
-            'fields': ('category', 'name', 'updated')
+            'fields': ('category', 'name', 'updated', 'moderator_group',)
         }
         ),
         (_('Additional options'), {

=== modified file 'pybb/feeds.py'
--- pybb/feeds.py	2018-11-15 18:30:45 +0000
+++ pybb/feeds.py	2018-12-14 08:49:33 +0000
@@ -56,10 +56,15 @@
     title_template = 'pybb/feeds/posts_title.html'
     description_template = 'pybb/feeds/posts_description.html'
 
-    all_objects = Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(hidden=False)
+    all_objects = Post.objects.exclude(
+        topic__forum__category__internal=True).exclude(
+        topic__in=Post.hidden_topics.all()).filter(hidden=False)
 
     def items_for_object(self, obj):
-        return Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(hidden=False, topic__forum=obj).order_by('-created')[:15]
+        # Latest posts for forum 'xy' 
+        return Post.objects.exclude(
+            topic__in=Post.hidden_topics.all()).filter(
+            hidden=False, topic__forum=obj).order_by('-created')[:15]
 
 # Validated through http://validator.w3.org/feed/
 
@@ -70,7 +75,11 @@
     title_template = 'pybb/feeds/topics_title.html'
     description_template = 'pybb/feeds/topics_description.html'
 
-    all_objects = Topic.objects.exclude(posts__hidden=True)
+    all_objects = Topic.objects.exclude(
+        forum__category__internal=True).exclude(posts__hidden=True)
 
     def items_for_object(self, item):
-        return Topic.objects.exclude(posts__hidden=True).filter(forum=item).order_by('-created')[:15]
+        # Latest topics on forum 'xy'
+        return Topic.objects.exclude(
+            forum__category__internal=True).exclude(
+            posts__hidden=True).filter(forum=item).order_by('-created')[:15]

=== added file 'pybb/migrations/0004_auto_20181209_1334.py'
--- pybb/migrations/0004_auto_20181209_1334.py	1970-01-01 00:00:00 +0000
+++ pybb/migrations/0004_auto_20181209_1334.py	2018-12-14 08:49:33 +0000
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.12 on 2018-12-09 13:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('auth', '0008_alter_user_username_max_length'),
+        ('pybb', '0003_remove_post_user_ip'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='category',
+            options={'ordering': ['position'], 'permissions': (('can_access_internal', 'Can access Internal Forums'),), 'verbose_name': 'Category', 'verbose_name_plural': 'Categories'},
+        ),
+        migrations.AddField(
+            model_name='category',
+            name='internal',
+            field=models.BooleanField(default=False, help_text='If set, this category is only visible for special users.', verbose_name='Internal Category'),
+        ),
+        migrations.AddField(
+            model_name='forum',
+            name='moderator_group',
+            field=models.ForeignKey(blank=True, default=None, help_text=b'Users in this Group will have administrative permissions in this Forum.', null=True, on_delete=django.db.models.deletion.CASCADE, to='auth.Group'),
+        ),
+    ]

=== modified file 'pybb/models.py'
--- pybb/models.py	2018-11-22 13:34:30 +0000
+++ pybb/models.py	2018-12-14 08:49:33 +0000
@@ -5,6 +5,7 @@
 
 from django.db import models
 from django.contrib.auth.models import User
+from django.contrib.auth.models import Group
 from django.urls import reverse
 from django.utils.html import strip_tags
 from django.utils.translation import ugettext_lazy as _
@@ -16,7 +17,6 @@
 
 from django.conf import settings
 from notification.models import send
-from django.contrib.auth.models import User
 from check_input.models import SuspiciousInput
 
 
@@ -31,15 +31,35 @@
     ('bbcode', 'bbcode'),
 )
 
+class PybbExcludeInternal(models.Manager):
+    def get_queryset(self):
+        return super(PybbExcludeInternal, self).get_queryset().exclude(internal=True)
+
 
 class Category(models.Model):
+    """The base model of pybb.
+    
+    If 'internal' is set to True, the category is only visible for superusers and
+    users which have the permission 'can_access_internal'.
+    """
+    
     name = models.CharField(_('Name'), max_length=80)
     position = models.IntegerField(_('Position'), blank=True, default=0)
+    internal = models.BooleanField(
+        default=False,
+        verbose_name=_('Internal Category'),
+        help_text=_('If set, this category is only visible for special users.')
+        )
+
+    objects = models.Manager()
+    exclude_internal = PybbExcludeInternal()
 
     class Meta:
         ordering = ['position']
         verbose_name = _('Category')
         verbose_name_plural = _('Categories')
+        # See also pybb/views
+        permissions = (("can_access_internal", "Can access Internal Forums"),)
 
     def __unicode__(self):
         return self.name
@@ -68,6 +88,14 @@
     moderators = models.ManyToManyField(
         User, blank=True, verbose_name=_('Moderators'))
     updated = models.DateTimeField(_('Updated'), null=True)
+    moderator_group = models.ForeignKey(
+        Group,
+        on_delete=models.CASCADE,
+        blank=True,
+        null=True,
+        default=None,
+        help_text='Users in this Group will have administrative permissions in this Forum.',
+    )
 
     class Meta:
         ordering = ['position']
@@ -96,6 +124,7 @@
         # This has better performance than using the posts manager hidden_topics
         # We search only for the last 10 topics
         topics = self.topics.order_by('-updated')[:10]
+        posts = []
         for topic in topics:
             if topic.is_hidden:
                 continue

=== modified file 'pybb/search_indexes.py'
--- pybb/search_indexes.py	2017-09-17 15:52:45 +0000
+++ pybb/search_indexes.py	2018-12-14 08:49:33 +0000
@@ -30,7 +30,7 @@
 
     def index_queryset(self, using=None):
         """Do not index hidden topics."""
-        return self.get_model().objects.exclude(posts__hidden=True)
+        return self.get_model().objects.filter(forum__category__internal=False).exclude(posts__hidden=True)
 
     def get_updated_field(self):
         return 'updated'
@@ -52,7 +52,7 @@
 
     def index_queryset(self, using=None):
         """Do not index hidden posts."""
-        return self.get_model().objects.exclude(hidden=True)
+        return self.get_model().objects.filter(topic__forum__category__internal=False).exclude(hidden=True)
 
     def get_updated_field(self):
         return 'created'

=== modified file 'pybb/templatetags/pybb_extras.py'
--- pybb/templatetags/pybb_extras.py	2018-11-13 18:34:10 +0000
+++ pybb/templatetags/pybb_extras.py	2018-12-14 08:49:33 +0000
@@ -12,9 +12,10 @@
 from django.utils.translation import ugettext as _
 from django.utils import dateformat
 
-from pybb.models import Post, Forum, Topic, Read, PrivateMessage
+from pybb.models import Post, Forum, Topic, Read, Category
 from pybb.unread import cache_unreads
 from pybb import settings as pybb_settings
+import pybb.views
 
 register = template.Library()
 
@@ -77,14 +78,13 @@
             'paginator': paginator,
             'label': label,
             }
-import time
 
 
 @register.inclusion_tag('pybb/last_posts.html', takes_context=True)
 def pybb_last_posts(context, number=8):
-
-    last_posts = Post.objects.filter(hidden=False).order_by(
-        '-created').select_related()[:45]
+    last_posts = Post.objects.filter(
+        hidden=False, topic__forum__category__internal=False).order_by(
+        '-created')[:45]
 
     check = []
     answer = []
@@ -156,10 +156,20 @@
 
 
 @register.filter
-def pybb_moderated_by(topic, user):
-    """Check if user is moderator of topic's forum."""
-
-    return user.is_superuser or user in topic.forum.moderators.all()
+def pybb_moderated_by(instance, user):
+    """Check if user is superuser or moderator in this forum."""
+    try:
+        if isinstance(instance, Forum):
+            return user.is_superuser or user in instance.moderator_group.user_set.all()
+        if isinstance(instance, Topic):
+            return user.is_superuser or user in instance.forum.moderator_group.user_set.all()
+        if isinstance(instance, Post):
+            return user.is_superuser or user in instance.topic.forum.moderator_group.user_set.all()
+    except:
+        pass
+    
+    return False
+    
 
 
 @register.filter
@@ -170,7 +180,7 @@
         return True
     if post.user == user:
         return True
-    if user in post.topic.forum.moderators.all():
+    if user in post.topic.forum.moderator_group.user_set.all():
         return True
     return False
 
@@ -196,15 +206,6 @@
 
 @register.filter
 @stringfilter
-def pybb_cut_string(value, arg):
-    if len(value) > arg:
-        return value[0:arg - 3] + '...'
-    else:
-        return value
-
-
-@register.filter
-@stringfilter
 def pybb_output_bbcode(post):
     """
     post = post.replace('[b]', '<span class="bold">')
@@ -250,6 +251,30 @@
     re_tag = re.compile(r'@@@AUTOJOIN-(\d+)@@@')
     return re_tag.sub(render_autojoin_message, body)
 
+
+@register.inclusion_tag('mainpage/forum_navigation.html', takes_context=True)
+def forum_navigation(context):
+    """Makes the forum list available to the navigation.
+
+    Ordering:
+    1.: value of 'Position' in pybb.Category
+    2.: value of 'Position' of pybb.Forum.
+
+    """
+
+    from pybb.models import Forum
+    
+    forums = Forum.objects.all()
+    
+    if context.request.user.is_superuser or pybb.views.allowed_for(context.request.user):
+        pass
+    else:
+        # Don't show internal forums
+        forums = forums.filter(category__internal=False)
+
+    return {'forums': forums.order_by('category', 'position')}
+
+
 """
 Spielwiese, Playground, Cour de récréati ;)
 """

=== modified file 'pybb/views.py'
--- pybb/views.py	2018-11-16 18:56:07 +0000
+++ pybb/views.py	2018-12-14 08:49:33 +0000
@@ -11,7 +11,8 @@
 from django.db import connection
 from django.utils import translation
 from django.shortcuts import render, redirect
-
+from django.db.models import Q
+from django.http import Http404
 
 from pybb.util import render_to, paged, build_form, quote_text, ajax, urlize
 from pybb.models import Category, Forum, Topic, Post, PrivateMessage, Attachment,\
@@ -19,6 +20,7 @@
 from pybb.forms import AddPostForm, EditPostForm, UserSearchForm
 from pybb import settings as pybb_settings
 from pybb.orm import load_related
+from pybb.templatetags.pybb_extras import pybb_moderated_by
 
 from check_input.models import SuspiciousInput
 
@@ -27,16 +29,31 @@
 except ImportError:
     notification = None
 
+# The permission string derived from pybb.models.category
+INTERNAL_PERM='pybb.can_access_internal'
+
+def allowed_for(user):
+    """Check if a user has the permission to enter internal Forums."""
+    
+    return user.has_perm(INTERNAL_PERM)
+
 
 def index_ctx(request):
-    cats = Category.objects.all().select_related()
+    if allowed_for(request.user):
+        cats = Category.objects.all().select_related()
+    else:
+        cats = Category.exclude_internal.all().select_related()
 
     return {'cats': cats }
 index = render_to('pybb/index.html')(index_ctx)
 
 
 def show_category_ctx(request, category_id):
+    
     category = get_object_or_404(Category, pk=category_id)
+    
+    if category.internal and not allowed_for(request.user):
+        raise Http404
 
     return {'category': category }
 show_category = render_to('pybb/category.html')(show_category_ctx)
@@ -45,8 +62,10 @@
 def show_forum_ctx(request, forum_id):
     forum = get_object_or_404(Forum, pk=forum_id)
 
-    moderator = (request.user.is_superuser or
-                 request.user in forum.moderators.all())
+    if forum.category.internal and not allowed_for(request.user):
+        raise Http404
+
+    user_is_mod = pybb_moderated_by(forum, request.user)
 
     topics = forum.topics.order_by(
         '-sticky', '-updated').select_related()
@@ -54,7 +73,7 @@
     return {'forum': forum,
             'topics': topics,
             'page_size': pybb_settings.FORUM_PAGE_SIZE,
-            'moderator': moderator,
+            'user_is_mod': user_is_mod,
             }
 show_forum = render_to('pybb/forum.html')(show_forum_ctx)
 
@@ -64,6 +83,10 @@
         topic = Topic.objects.select_related().get(pk=topic_id)
     except Topic.DoesNotExist:
         raise Http404()
+
+    if topic.forum.category.internal and not allowed_for(request.user):
+        raise Http404
+
     topic.views += 1
     topic.save()
 
@@ -81,17 +104,15 @@
         initial = {'markup': 'markdown'}
     form = AddPostForm(topic=topic, initial=initial)
 
-    moderator = (request.user.is_superuser or
-                 request.user in topic.forum.moderators.all())
+    user_is_mod = pybb_moderated_by(topic, request.user)
     subscribed = (request.user.is_authenticated and
                   request.user in topic.subscribers.all())
 
-
     is_spam = False
     if topic.is_hidden:
             is_spam = topic.posts.first().is_spam()
 
-    if moderator:
+    if user_is_mod:
         posts = topic.posts.select_related()
     else:
         posts = topic.posts.exclude(hidden=True).select_related()
@@ -110,7 +131,7 @@
             'last_post': last_post,
             'first_post': first_post,
             'form': form,
-            'moderator': moderator,
+            'user_is_mod': user_is_mod,
             'subscribed': subscribed,
             'posts': posts,
             'page_size': pybb_settings.TOPIC_PAGE_SIZE,
@@ -166,8 +187,25 @@
         if notification:
             if not topic:
                 # Inform subscribers of a new topic
-                subscribers = notification.get_observers_for('forum_new_topic',
+                if post.topic.forum.category.internal:
+                    # Inform only users which have the permission to enter the
+                    # internal forum and superusers. Those users have to:
+                    # - enable 'forum_new_topic' in the notification settings, or
+                    # - subscribe to an existing topic
+                    subscribers = User.objects.filter(
+                        Q(groups__permissions__codename=INTERNAL_PERM) |
+                        Q(user_permissions__codename=INTERNAL_PERM)
+                        ).exclude(username=request.user.username)
+                    superusers = User.objects.filter(
+                        is_superuser=True).exclude(
+                        username=request.user.username)
+                    # Combine the querysets, excluding double entrys.
+                    subscribers = subscribers.union(superusers)
+                else:
+                    # Inform normal users
+                    subscribers = notification.get_observers_for('forum_new_topic',
                                                              excl_user=request.user)
+
                 notification.send(subscribers, 'forum_new_topic',
                                   {'topic': post.topic,
                                    'post': post,
@@ -242,7 +280,6 @@
 
 @login_required
 def stick_topic(request, topic_id):
-    from pybb.templatetags.pybb_extras import pybb_moderated_by
 
     topic = get_object_or_404(Topic, pk=topic_id)
     if pybb_moderated_by(topic, request.user):
@@ -254,7 +291,6 @@
 
 @login_required
 def unstick_topic(request, topic_id):
-    from pybb.templatetags.pybb_extras import pybb_moderated_by
 
     topic = get_object_or_404(Topic, pk=topic_id)
     if pybb_moderated_by(topic, request.user):
@@ -270,8 +306,7 @@
     last_post = post.topic.posts.order_by('-created')[0]
 
     allowed = False
-    if request.user.is_superuser or\
-            request.user in post.topic.forum.moderators.all() or \
+    if pybb_moderated_by(post, request.user) or \
             (post.user == request.user and post == last_post):
         allowed = True
 
@@ -297,8 +332,6 @@
 
 @login_required
 def close_topic(request, topic_id):
-    from pybb.templatetags.pybb_extras import pybb_moderated_by
-
     topic = get_object_or_404(Topic, pk=topic_id)
     if pybb_moderated_by(topic, request.user):
         if not topic.closed:
@@ -309,7 +342,6 @@
 
 @login_required
 def open_topic(request, topic_id):
-    from pybb.templatetags.pybb_extras import pybb_moderated_by
 
     topic = get_object_or_404(Topic, pk=topic_id)
     if pybb_moderated_by(topic, request.user):
@@ -393,4 +425,4 @@
         first_post.hidden = True
     first_post.save()
     
-    return redirect(topic)
\ No newline at end of file
+    return redirect(topic)

=== modified file 'templates/header.html'
--- templates/header.html	2018-11-30 08:18:02 +0000
+++ templates/header.html	2018-12-14 08:49:33 +0000
@@ -40,7 +40,7 @@
 			<br />
 			<a href="{% url 'scheduling_find' %}?next={{ request.path|iriencode }}" title="Show other users playtimes">Playtimes</a>
 			<br />
-			<a href="{% url 'auth_logout' %}?next={{ request.path|iriencode }}">Logout</a>
+			<a href="{% url 'auth_logout' %}?next=/">Logout</a>
 		{% else %}
 			<a href="{% url 'auth_login' %}?next={{ request.path|iriencode }}">Login/Register</a>
 		{% endif %}

=== modified file 'templates/mainpage/forum_navigation.html'
--- templates/mainpage/forum_navigation.html	2016-12-15 19:20:36 +0000
+++ templates/mainpage/forum_navigation.html	2018-12-14 08:49:33 +0000
@@ -1,12 +1,15 @@
 {% comment %}
 Showing the forum navigation ordered by category position and forum position
 {% endcomment %}
-
 <ul>
-{% for category in categories %}
-	{% for forum in category.forums.all %}
+{% for forum in forums %}
+	{% if forum.category.internal %}
+		<li>
+			<a href="{% url 'pybb_forum' forum.id %}" style="color: rgba(254, 234, 138, 1);">{{ forum.name }}</a>
+		</li>
+	{% else %}
 		<li><a href="{% url 'pybb_forum' forum.id %}">{{ forum.name }}</a></li>
-	{% endfor %}
+	{% endif %}
 {% endfor %}
 </ul>
 

=== modified file 'templates/navigation.html'
--- templates/navigation.html	2018-05-27 09:25:54 +0000
+++ templates/navigation.html	2018-12-14 08:49:33 +0000
@@ -2,7 +2,7 @@
    vim:ft=htmldjango
 {% endcomment %}
 
-{% load wl_extras %}
+{% load pybb_extras %}
 
 <script type="text/javascript">
 	/* Enable dropdown menus on touch devices */

=== modified file 'templates/pybb/forum.html'
--- templates/pybb/forum.html	2018-11-22 11:08:51 +0000
+++ templates/pybb/forum.html	2018-12-14 08:49:33 +0000
@@ -76,7 +76,7 @@
 				<span class="small">on {{ topic.last_post.created|custom_date:user }}</span>
 				{% endif %}
 			</td>
-			{% elif moderator %}
+			{% elif user_is_mod %}
 				<td colspan="4" class="center errormessage">Hidden Topic: <a href="{{ topic.get_absolute_url }}">{{ topic.name }}</a></td>
 			{% endif %}
 		</tr>

=== modified file 'templates/pybb/inlines/post.html'
--- templates/pybb/inlines/post.html	2018-11-22 11:08:51 +0000
+++ templates/pybb/inlines/post.html	2018-12-14 08:49:33 +0000
@@ -94,13 +94,13 @@
                   </a>
                   {% endifnotequal %}
                   {% endif %}
-                  {% if moderator or post|pybb_posted_by:user %}
+                  {% if user_is_mod or post|pybb_posted_by:user %}
                   <a href="{% url 'pybb_edit_post' post.id %}">
                     <img src="{% static 'forum/img/en/edit.png' %}" height="25" alt ="{% trans "Edit" %}" />
                   </a>
                   {% endif %}
-                  {% if moderator or post|pybb_equal_to:last_post %}
-                  {% if moderator or post.user|pybb_equal_to:user %}
+                  {% if user_is_mod or post|pybb_equal_to:last_post %}
+                  {% if user_is_mod or post.user|pybb_equal_to:user %}
                   <a href="{% url 'pybb_delete_post' post.id %}">
                      <img src="{% static 'forum/img/en/delete.png' %}" height="25" alt ="{% trans "Delete" %}" />
                   </a>

=== modified file 'templates/pybb/last_posts.html'
--- templates/pybb/last_posts.html	2018-09-07 20:34:55 +0000
+++ templates/pybb/last_posts.html	2018-12-14 08:49:33 +0000
@@ -11,7 +11,7 @@
 			{% for post in posts %}
 				<li>
 					{{ post.topic.forum.name }}<br />
-					<a href="{{ post.get_absolute_url }}" title="{{ post.topic.name }}">{{ post.topic.name|pybb_cut_string:30 }}</a><br />
+					<a href="{{ post.get_absolute_url }}" title="{{ post.topic.name }}">{{ post.topic.name|truncatechars:30 }}</a><br />
 					by {{ post.user|user_link }} {{ post.created|minutes }} ago
 				</li>
 			{% endfor %}

=== modified file 'templates/pybb/topic.html'
--- templates/pybb/topic.html	2018-11-22 11:08:51 +0000
+++ templates/pybb/topic.html	2018-12-14 08:49:33 +0000
@@ -32,12 +32,12 @@
 		</div>
 	{% if topic.is_hidden %}
 		<p>This topic is hidden. It is either waiting for a review or was hidden by a moderator.</p>
-		{% if posts.0.is_spam and moderator %}
+		{% if posts.0.is_spam and user_is_mod %}
 			<p>This topic's first post is possible spam. Toggle the visibility to show the post. If it is indeed spam, consider deleting the user:</p>
 			<p>To delete the user, go to the <a href="/admin/auth/user/{{posts.0.user.pk}}/change/">admin user-page for the post's author</a></p>
 		{% endif %}
 		<div class="posRight">
-		{% if moderator %}
+		{% if user_is_mod %}
 			<a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}">
 				<img src="{% static 'forum/img/topic_show.png' %}" alt ="" class="middle" />
 				<span class="middle">{% trans "Toggle Visibility" %}</span>
@@ -45,7 +45,7 @@
 		{% endif %}
 	{% else %}
 		<div class="posRight">
-		{% if moderator %}
+		{% if user_is_mod %}
 			<a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}">
 				<img src="{% static 'forum/img/topic_hide.png' %}" alt ="" class="middle" />
 				<span class="middle">{% trans "Toggle Visibility" %}</span>
@@ -157,12 +157,12 @@
 							<img src="{% static 'forum/img/quote.png' %}" alt ="" class="middle" />
 							<span class="middle">{% trans "Quote" %}</span>
 						</button>
-						{% if moderator or post|pybb_posted_by:user %}
+						{% if user_is_mod or post|pybb_posted_by:user %}
 							<button onclick="window.location.href='{% url 'pybb_edit_post' post.id %}';">
 								<img src="{% static 'forum/img/edit.png' %}" alt ="" class="middle" />
 								<span class="middle">{% trans "Edit" %}</span>
 							</button>
-							{% if moderator or post|pybb_equal_to:last_post %}
+							{% if user_is_mod or post|pybb_equal_to:last_post %}
 							<button onclick="window.location.href='{% url 'pybb_delete_post' post.id %}';">
 								<img src="{% static 'forum/img/delete.png' %}" alt ="" class="middle" />
 								<span class="middle">{% trans "Delete" %}</span>
@@ -242,12 +242,12 @@
 							<img src="{% static 'forum/img/quote.png' %}" alt ="" class="middle" />
 							<span class="middle">{% trans "Quote" %}</span>
 						</a>
-						{% if moderator or post|pybb_posted_by:user %}
+						{% if user_is_mod or post|pybb_posted_by:user %}
 							<a class="button" href="{% url 'pybb_edit_post' post.id %}">
 								<img src="{% static 'forum/img/edit.png' %}" alt ="" class="middle" />
 								<span class="middle">{% trans "Edit" %}</span>
 							</a>
-							{% if moderator or post|pybb_equal_to:last_post %}
+							{% if user_is_mod or post|pybb_equal_to:last_post %}
 							<a class="button" href="{% url 'pybb_delete_post' post.id %}">
 								<img src="{% static 'forum/img/delete.png' %}" alt ="" class="middle" />
 								<span class="middle">{% trans "Delete" %}</span>
@@ -268,7 +268,7 @@
 			</table>
 
 			<div class="posRight">
-			{% if moderator %}
+			{% if user_is_mod %}
 			<a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}">
 					<img src="{% static 'forum/img/topic_hide.png' %}" alt ="" class="middle" />
 					<span class="middle">{% trans "Toggle Visibility" %}</span>

=== modified file 'wlprofile/admin.py'
--- wlprofile/admin.py	2017-09-30 11:46:11 +0000
+++ wlprofile/admin.py	2018-12-14 08:49:33 +0000
@@ -39,18 +39,3 @@
     )
 
 admin.site.register(Profile, ProfileAdmin)
-
-
-class CustomUserAdmin(UserAdmin):
-    """Partly overwritten admin page for django auth.user.
-
-    Replaces in users list: 'first_name' with 'date_joined' and
-    'last_name' with 'is_active'. Added column: 'last_login'.
-
-    """
-    list_display = ('username', 'email', 'date_joined', 'last_login',
-                    'is_active', 'is_staff')
-    ordering = ('-date_joined',)
-
-admin.site.unregister(User)
-admin.site.register(User, CustomUserAdmin)


Follow ups