Skip to content

Commit

Permalink
blacklist filters and actions on guilds
Browse files Browse the repository at this point in the history
  • Loading branch information
laggron42 committed Jan 17, 2025
1 parent f6ab1b3 commit 352ee5d
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 46 deletions.
3 changes: 1 addition & 2 deletions admin_panel/bd_models/admin/ball.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
from django.utils.safestring import mark_safe
from django.utils.text import capfirst

from ..models import Ball, BallInstance, Economy, Regime, TradeObject
from ..utils import transform_media
from ..models import Ball, BallInstance, Economy, Regime, TradeObject, transform_media

if TYPE_CHECKING:
from django.db.models import Field, Model
Expand Down
67 changes: 63 additions & 4 deletions admin_panel/bd_models/admin/guild.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,71 @@
from django.contrib import admin
from typing import TYPE_CHECKING

from ..models import GuildConfig
from asgiref.sync import async_to_sync
from django.contrib import admin, messages
from django_admin_action_forms import action_with_form

from admin_panel.webhook import notify_admins

from ..forms import BlacklistActionForm, BlacklistedListFilter
from ..models import BlacklistedGuild, BlacklistHistory, GuildConfig
from ..utils import BlacklistTabular

if TYPE_CHECKING:
from django.db.models import QuerySet
from django.http import HttpRequest


@admin.register(GuildConfig)
class GuildAdmin(admin.ModelAdmin):
list_display = ("guild_id", "spawn_channel", "enabled", "silent")
list_filter = ("enabled", "silent")
list_display = ("guild_id", "spawn_channel", "enabled", "silent", "blacklisted")
list_filter = ("enabled", "silent", BlacklistedListFilter)
show_facets = admin.ShowFacets.NEVER

search_fields = ("guild_id", "spawn_channel")
search_help_text = "Search by guild ID or spawn channel ID"

inlines = (BlacklistTabular,)
actions = ("blacklist_guilds",)

@admin.display(description="Is blacklisted", boolean=True)
def blacklisted(self, obj: GuildConfig):
return BlacklistedGuild.objects.filter(discord_id=obj.guild_id).exists()

@action_with_form(
BlacklistActionForm, description="Blacklist the selected guilds"
) # type: ignore
def blacklist_guilds(
self, request: "HttpRequest", queryset: "QuerySet[GuildConfig]", data: dict
):
reason = (
data["reason"]
+ f"\nDone through the admin panel by {request.user} ({request.user.pk})"
)
blacklists: list[BlacklistedGuild] = []
histories: list[BlacklistHistory] = []
for guild in queryset:
if BlacklistedGuild.objects.filter(discord_id=guild.guild_id).exists():
self.message_user(
request, f"Guild {guild.guild_id} is already blacklisted!", messages.ERROR
)
return
blacklists.append(
BlacklistedGuild(discord_id=guild.guild_id, reason=reason, moderator_id=None)
)
histories.append(
BlacklistHistory(
discord_id=guild.guild_id, reason=reason, moderator_id=0, id_type="guild"
)
)
BlacklistedGuild.objects.bulk_create(blacklists)
BlacklistHistory.objects.bulk_create(histories)

self.message_user(
request,
f"Created blacklist for {queryset.count()} guild{"s" if queryset.count() > 1 else ""}. "
"This will be applied after reloading the bot's cache.",
)
async_to_sync(notify_admins)(
f"{request.user} blacklisted guilds "
f'{", ".join([str(x.guild_id) for x in queryset])} for the reason: {data["reason"]}.'
)
39 changes: 4 additions & 35 deletions admin_panel/bd_models/admin/player.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,22 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING

from asgiref.sync import async_to_sync
from django.contrib import admin, messages
from django.db.models import Exists, OuterRef
from django_admin_action_forms import action_with_form
from nonrelated_inlines.admin import NonrelatedTabularInline

from admin_panel.webhook import notify_admins

from ..forms import BlacklistActionForm
from ..forms import BlacklistActionForm, BlacklistedListFilter
from ..models import BlacklistedID, BlacklistHistory, Player
from ..utils import BlacklistTabular

if TYPE_CHECKING:
from django.db.models import QuerySet
from django.http import HttpRequest


class BlacklistedListFilter(admin.SimpleListFilter):
title = "blacklisted"
parameter_name = "blacklisted"

def lookups(self, request: "HttpRequest", model_admin: PlayerAdmin) -> list[tuple[Any, str]]:
return [(True, "True"), (False, "False")]

def queryset(self, request: "HttpRequest", queryset: "QuerySet[Player]") -> "QuerySet[Player]":
if self.value() is None:
return queryset
return queryset.annotate(
listed=Exists(BlacklistedID.objects.filter(discord_id=OuterRef("discord_id")))
).filter(listed=self.value())


class BlacklistTabular(NonrelatedTabularInline):
model = BlacklistHistory
extra = 0
can_delete = False
verbose_name_plural = "Blacklist history"
fields = ("date", "reason", "moderator_id", "action_type")
readonly_fields = ("date", "moderator_id", "action_type")

def has_add_permission(self, request: "HttpRequest", obj: Any) -> bool: # type: ignore
return False

def get_form_queryset(self, obj: Player):
return BlacklistHistory.objects.filter(discord_id=obj.discord_id)


@admin.register(Player)
class PlayerAdmin(admin.ModelAdmin):
save_on_top = True
Expand Down Expand Up @@ -97,6 +66,6 @@ def blacklist_users(self, request: "HttpRequest", queryset: "QuerySet[Player]",
"This will be applied after reloading the bot's cache.",
)
async_to_sync(notify_admins)(
f"{request.user} blacklisted "
f"{request.user} blacklisted players "
f'{", ".join([str(x.discord_id) for x in queryset])} for the reason: {data["reason"]}.'
)
35 changes: 35 additions & 0 deletions admin_panel/bd_models/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
from typing import TYPE_CHECKING, Any

from django import forms
from django.contrib import admin
from django.db.models import Exists, OuterRef
from django_admin_action_forms import AdminActionForm

from .models import BlacklistedGuild, BlacklistedID, Player

if TYPE_CHECKING:
from django.db.models import QuerySet
from django.http import HttpRequest

from .admin import GuildAdmin, PlayerAdmin
from .models import GuildConfig


class BlacklistActionForm(AdminActionForm):
reason = forms.CharField(label="Reason", required=True)


class BlacklistedListFilter(admin.SimpleListFilter):
title = "blacklisted"
parameter_name = "blacklisted"

def lookups(
self, request: "HttpRequest", model_admin: "PlayerAdmin | GuildAdmin"
) -> list[tuple[Any, str]]:
return [(True, "True"), (False, "False")]

def queryset(
self, request: "HttpRequest", queryset: "QuerySet[Player | GuildConfig]"
) -> "QuerySet[Player | GuildConfig]":
if self.value() is None:
return queryset
if queryset.model == Player:
annotation = Exists(BlacklistedID.objects.filter(discord_id=OuterRef("discord_id")))
else:
annotation = Exists(BlacklistedGuild.objects.filter(discord_id=OuterRef("guild_id")))

return queryset.annotate(listed=annotation).filter(listed=self.value())
6 changes: 5 additions & 1 deletion admin_panel/bd_models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
from django.utils.safestring import SafeText, mark_safe
from django.utils.timezone import now

from .utils import transform_media

def transform_media(path: str) -> str:
return path.replace("/static/uploads/", "").replace(
"/ballsdex/core/image_generator/src/", "default/"
)


def image_display(image_link: str) -> SafeText:
Expand Down
29 changes: 25 additions & 4 deletions admin_panel/bd_models/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
from typing import TYPE_CHECKING

from django.core.paginator import Paginator
from django.db import connection
from django.http import HttpRequest
from django.utils.functional import cached_property
from nonrelated_inlines.admin import NonrelatedTabularInline

from .models import BlacklistHistory, Player

if TYPE_CHECKING:
from .models import GuildConfig


class ApproxCountPaginator(Paginator):
Expand All @@ -23,7 +32,19 @@ def count(self):
return result


def transform_media(path: str) -> str:
return path.replace("/static/uploads/", "").replace(
"/ballsdex/core/image_generator/src/", "default/"
)
class BlacklistTabular(NonrelatedTabularInline):
model = BlacklistHistory
extra = 0
can_delete = False
verbose_name_plural = "Blacklist history"
fields = ("date", "reason", "moderator_id", "action_type")
readonly_fields = ("date", "moderator_id", "action_type")

def has_add_permission(self, request: "HttpRequest", obj: "Player | GuildConfig") -> bool:
return False

def get_form_queryset(self, obj: "Player | GuildConfig"):
if isinstance(obj, Player):
return BlacklistHistory.objects.filter(discord_id=obj.discord_id, id_type="user")
else:
return BlacklistHistory.objects.filter(discord_id=obj.guild_id, id_type="guild")

0 comments on commit 352ee5d

Please sign in to comment.