Source code for oioioi.forum.admin

from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils import timezone
from django.utils.safestring import mark_safe
from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy

from oioioi.base import admin
from oioioi.base.utils import make_html_link
from oioioi.contests.admin import contest_site
from oioioi.contests.utils import is_contest_admin
from oioioi.forum.models import Ban, Category, Forum, Post, Thread

[docs]def string_concat(*strings): """https://docs.djangoproject.com/en/3.2/releases/1.11/#deprecated-features-1-11""" return format_lazy('{}' * len(strings), *strings)
[docs]def make_list_elem(elem, text=None): if not text: text = elem.name return '<li>%s</li>' % make_html_link(elem.get_admin_url(), text)
[docs]def get_permission(self, request): try: _f = request.contest.forum return is_contest_admin(request) except Forum.DoesNotExist: return False
[docs]class ForumAdmin(admin.ModelAdmin):
[docs] fields = ( 'visible', 'lock_date', 'unlock_date', 'categories', 'add_category', 'posts_admin', 'bans', )
[docs] readonly_fields = ('categories', 'add_category', 'posts_admin', 'bans')
[docs] def categories(self, obj): slist = [ make_list_elem(c) for c in obj.category_set.prefetch_related( 'thread_set', 'thread_set__post_set' ).all() ] ret = "".join(slist) if not ret: ret = string_concat('<li>', _("Empty forum"), '</li>') return mark_safe('<ul>%s</ul>' % ret)
[docs] categories.short_description = _("Categories")
[docs] def add_category(self, obj): return make_html_link( reverse( 'oioioiadmin:forum_category_add', ), '+', )
add_category.short_description = _("Add category")
[docs] def posts_admin(self, obj): return make_html_link( reverse( 'oioioiadmin:forum_post_changelist', ), _("Posts admin view"), )
posts_admin.short_description = _("Posts")
[docs] def bans(self, obj): return make_html_link( reverse( 'oioioiadmin:forum_ban_changelist', ), _("Bans"), )
bans.short_description = _("Bans")
[docs] def has_add_permission(self, request): return False
[docs] def has_change_permission(self, request, obj=None): return get_permission(self, request)
[docs] def has_delete_permission(self, request, obj=None): return False
[docs] def response_change(self, request, obj): # Never redirect to the list of forums. Just re-display the edit # view. if '_popup' not in request.POST: return HttpResponseRedirect(request.get_full_path()) return super(ForumAdmin, self).response_change(request, obj)
[docs] def get_queryset(self, request): # each qs filters forum/categories/threads/posts connected with # this particular contest qs = super(ForumAdmin, self).get_queryset(request) qs = qs.filter(contest=request.contest) return qs
[docs]class CategoryAdmin(admin.ModelAdmin):
[docs] fields = ( 'name', 'threads', )
[docs] readonly_fields = ('threads',)
[docs] def threads(self, obj): slist = [ make_list_elem(t) for t in obj.thread_set.prefetch_related('post_set').all() ] ret = "".join(slist) if not ret: ret = string_concat('<li>', _("Empty category"), '</li>') return mark_safe('<ul>%s</ul>' % ret)
[docs] threads.short_description = _("Threads")
[docs] def save_model(self, request, obj, form, change): obj.forum = request.contest.forum obj.save()
[docs] def has_add_permission(self, request): return get_permission(self, request)
[docs] def has_change_permission(self, request, obj=None): return get_permission(self, request)
[docs] def has_delete_permission(self, request, obj=None): return get_permission(self, request)
[docs] def response_add(self, request, obj, post_url_continue=None): if '_popup' not in request.POST: return HttpResponseRedirect( reverse( 'oioioiadmin:forum_forum_change', args=(request.contest.forum.id,) ) ) return super(CategoryAdmin, self).response_add(request, obj, post_url_continue)
[docs] def response_change(self, request, obj): if '_popup' not in request.POST: return HttpResponseRedirect(request.get_full_path()) return super(CategoryAdmin, self).response_change(request, obj)
[docs] def response_delete(self, request): if 'came_from' in request.GET or not self.has_change_permission(request): return super(CategoryAdmin, self).response_delete(request) return HttpResponseRedirect( reverse('oioioiadmin:forum_forum_change', args=(request.contest.forum.id,)) )
[docs] def get_queryset(self, request): qs = super(CategoryAdmin, self).get_queryset(request) qs = qs.filter(forum=request.contest.forum) return qs
[docs]class ThreadAdmin(admin.ModelAdmin):
[docs] fields = ['name', 'category', 'count_posts', 'count_reported', 'posts']
[docs] readonly_fields = ('count_posts', 'count_reported', 'posts')
[docs] def get_post_descr(self, post): localtime = timezone.localtime(post.add_date) return '#%(id)s. %(author)s: %(date)s' % { 'id': post.id, 'author': post.author, 'date': localtime.strftime('%Y-%m-%d %H:%M:%S'), }
[docs] def posts(self, obj): slist = [ make_list_elem(p, self.get_post_descr(p)) for p in obj.post_set.select_related('author').all() ] ret = "".join(slist) if not ret: ret = string_concat('<li>', _("Empty thread"), '</li>') return mark_safe('<ul>%s</ul>' % ret)
[docs] posts.short_description = _("Posts")
[docs] def has_add_permission(self, request): return False
[docs] def has_change_permission(self, request, obj=None): return get_permission(self, request)
[docs] def has_delete_permission(self, request, obj=None): return get_permission(self, request)
[docs] def response_add(self, request, obj, post_url_continue=None): if '_popup' not in request.POST: return HttpResponseRedirect( reverse( 'oioioiadmin:forum_forum_change', args=(request.contest.forum.id,) ) ) return super(ThreadAdmin, self).response_add(request, obj, post_url_continue)
[docs] def response_change(self, request, obj): if '_popup' not in request.POST: return HttpResponseRedirect(request.get_full_path()) return super(ThreadAdmin, self).response_change(request, obj)
[docs] def response_delete(self, request): if 'came_from' in request.GET or not self.has_change_permission(request): return super(ThreadAdmin, self).response_delete(request) return HttpResponseRedirect( reverse('oioioiadmin:forum_forum_change', args=(request.contest.forum.id,)) )
[docs] def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == 'category': kwargs['queryset'] = Category.objects.filter(forum=request.contest.forum) return super(ThreadAdmin, self).formfield_for_foreignkey( db_field, request, **kwargs )
[docs] def get_queryset(self, request): qs = super(ThreadAdmin, self).get_queryset(request) qs = qs.filter(category__forum=request.contest.forum) return qs
[docs]class PostAdmin(admin.ModelAdmin):
[docs] list_display = [ 'id', 'author', 'thread_link', 'content', 'reported', 'approved', 'hidden', ]
[docs] list_filter = ['reported', 'approved', 'hidden', 'thread']
[docs] actions = [ 'hide_action', 'unreport_action', 'approve_action', 'revoke_approval_action', ]
[docs] fields = ['content', 'thread', 'author', 'reported', 'approved', 'hidden']
[docs] readonly_fields = ['author']
[docs] thread_link.short_description = _("Thread")
[docs] def has_add_permission(self, request): return False
[docs] def has_change_permission(self, request, obj=None): return get_permission(self, request)
[docs] def has_delete_permission(self, request, obj=None): return get_permission(self, request)
[docs] def response_change(self, request, obj): if '_popup' not in request.POST: return HttpResponseRedirect(request.get_full_path()) return super(PostAdmin, self).response_change(request, obj)
[docs] def response_delete(self, request): if 'came_from' in request.GET or not self.has_change_permission(request): return super(PostAdmin, self).response_delete(request) return HttpResponseRedirect( reverse('oioioiadmin:forum_forum_change', args=(request.contest.forum.id,)) )
[docs] def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == 'thread': kwargs['queryset'] = Thread.objects.filter( category__forum=request.contest.forum ) return super(PostAdmin, self).formfield_for_foreignkey( db_field, request, **kwargs )
[docs] def hide_action(self, request, queryset): queryset.update(hidden=True) counter = queryset.count() self.message_user( request, ngettext_lazy( "One post has been hidden.", "%(counter)d posts have been hidden.", counter, ) % {'counter': counter}, )
hide_action.short_description = _("Hide selected posts")
[docs] def unreport_action(self, request, queryset): queryset.update(reported=False) counter = queryset.count() self.message_user( request, ngettext_lazy( "\"Reported\" status removed from one post.", "\"Reported\" status removed from %(counter)d posts.", counter, ) % {'counter': counter}, )
unreport_action.short_description = _("Dismiss reports for selected posts")
[docs] def approve_action(self, request, queryset): queryset.update(approved=True, reported=False) counter = queryset.count() self.message_user( request, ngettext_lazy( "One post was approved.", "%(counter)d posts were approved.", counter ) % {'counter': counter}, )
approve_action.short_description = _("Approve selected posts")
[docs] def revoke_approval_action(self, request, queryset): queryset.update(approved=False) counter = queryset.count() self.message_user( request, ngettext_lazy( "\"Approved\" status removed from one post.", "\"Approved\" status removed from %(counter)d posts.", counter, ) % {'counter': counter}, )
revoke_approval_action.short_description = _("Revoke approval of selected posts")
[docs] def get_queryset(self, request): qs = super(PostAdmin, self).get_queryset(request) qs = qs.filter(thread__category__forum=request.contest.forum) return qs
[docs]class BanAdmin(admin.ModelAdmin):
[docs] list_display = ['user', 'admin', 'created_at']
[docs] fields = ['user', 'admin', 'created_at', 'reason']
[docs] readonly_fields = ['user', 'admin', 'created_at']
[docs] def has_add_permission(self, request): return False
[docs] def has_change_permission(self, request, obj=None): return get_permission(self, request)
[docs] def has_delete_permission(self, request, obj=None): return get_permission(self, request)
[docs] def get_queryset(self, request): qs = super(BanAdmin, self).get_queryset(request) qs = qs.filter(forum=request.contest.forum) return qs
contest_site.contest_register(Ban, BanAdmin) contest_site.contest_register(Forum, ForumAdmin) contest_site.contest_register(Category, CategoryAdmin) contest_site.contest_register(Thread, ThreadAdmin) contest_site.contest_register(Post, PostAdmin)