aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps/api/admin.py
blob: 6d6a9b3bfddb6df2bb1e723ca9090a89fe569bf1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import json
from typing import Optional

from django import urls
from django.contrib import admin
from django.http import HttpRequest
from django.utils.html import format_html

from .models import (
    BotSetting,
    DeletedMessage,
    DocumentationLink,
    Infraction,
    LogEntry,
    MessageDeletionContext,
    Nomination,
    OffTopicChannelName,
    Role,
    Tag,
    User
)


class LogEntryAdmin(admin.ModelAdmin):
    """Allows viewing logs in the Django Admin without allowing edits."""

    actions = None
    list_display = ('timestamp', 'application', 'level', 'message')
    fieldsets = (
        ('Overview', {'fields': ('timestamp', 'application', 'logger_name')}),
        ('Metadata', {'fields': ('level', 'module', 'line')}),
        ('Contents', {'fields': ('message',)})
    )
    list_filter = ('application', 'level', 'timestamp')
    search_fields = ('message',)
    readonly_fields = (
        'application',
        'logger_name',
        'timestamp',
        'level',
        'module',
        'line',
        'message'
    )

    def has_add_permission(self, request: HttpRequest) -> bool:
        """Deny manual LogEntry creation."""
        return False

    def has_delete_permission(self, request: HttpRequest, obj: Optional[LogEntry] = None) -> bool:
        """Deny LogEntry deletion."""
        return False


class DeletedMessageAdmin(admin.ModelAdmin):
    """Admin formatting for the DeletedMessage model."""

    readonly_fields = (
        "id",
        "author",
        "channel_id",
        "content",
        "embed_data",
        "context",
        "view_full_log"
    )

    exclude = ("embeds", "deletion_context")

    search_fields = (
        "id",
        "content",
        "author__name",
        "author__id",
        "deletion_context__actor__name",
        "deletion_context__actor__id"
    )

    @staticmethod
    def embed_data(instance: DeletedMessage) -> Optional[str]:
        """Format embed data in a code block for better readability."""
        if instance.embeds:
            return format_html(
                "<pre><code>{0}</code></pre>",
                json.dumps(instance.embeds, indent=4)
            )

    @staticmethod
    def context(instance: DeletedMessage) -> str:
        """Provide full context info with a link through to context admin view."""
        link = urls.reverse(
            "admin:api_messagedeletioncontext_change",
            args=[instance.deletion_context.id]
        )
        details = (
            f"Deleted by {instance.deletion_context.actor} at "
            f"{instance.deletion_context.creation}"
        )
        return format_html("<a href='{0}'>{1}</a>", link, details)

    @staticmethod
    def view_full_log(instance: DeletedMessage) -> str:
        """Provide a link to the message logs for the relevant context."""
        return format_html(
            "<a href='{0}'>Click to view full context log</a>",
            instance.deletion_context.log_url
        )


class MessageDeletionContextAdmin(admin.ModelAdmin):
    """Admin formatting for the MessageDeletionContext model."""

    readonly_fields = ("actor", "creation", "message_log")

    @staticmethod
    def message_log(instance: MessageDeletionContext) -> str:
        """Provide a formatted link to the message logs for the context."""
        return format_html(
            "<a href='{0}'>Click to see deleted message log</a>",
            instance.log_url
        )


admin.site.register(BotSetting)
admin.site.register(DeletedMessage, DeletedMessageAdmin)
admin.site.register(DocumentationLink)
admin.site.register(Infraction)
admin.site.register(LogEntry, LogEntryAdmin)
admin.site.register(MessageDeletionContext, MessageDeletionContextAdmin)
admin.site.register(Nomination)
admin.site.register(OffTopicChannelName)
admin.site.register(Role)
admin.site.register(Tag)
admin.site.register(User)