-
- - You cannot delete the root article. -
- - - - - - Go back - -From 6ab05d33b750afe069f399b801ebd424b5d98a15 Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Sun, 20 Oct 2019 05:14:49 +1000 Subject: Set default example.com dev site to pythondiscord.local:8000 --- manage.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/manage.py b/manage.py index d2996488..dc4aef08 100755 --- a/manage.py +++ b/manage.py @@ -112,6 +112,19 @@ class SiteManager: print("Database could not be found, exiting.") sys.exit(1) + @staticmethod + def set_dev_site_name() -> None: + """Set the development site domain in admin from default example.""" + # import Site model now after django setup + from django.contrib.sites.models import Site + query = Site.objects.filter(id=1) + site = query.get() + if site.domain == "example.com": + query.update( + domain="pythondiscord.local:8000", + name="pythondiscord.local:8000" + ) + def prepare_server(self) -> None: """Perform preparation tasks before running the server.""" django.setup() @@ -125,6 +138,7 @@ class SiteManager: call_command("collectstatic", interactive=False, clear=True, verbosity=self.verbosity) if self.debug: + self.set_dev_site_name() self.create_superuser() def run_server(self) -> None: -- cgit v1.2.3 From e2956b87289a37747cb5431ad3a08dc202a2bcba Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Sun, 20 Oct 2019 05:37:15 +1000 Subject: Set newest-first sorting for message deletion models, add log_url property. --- pydis_site/apps/api/models/bot/deleted_message.py | 4 ++-- pydis_site/apps/api/models/bot/message_deletion_context.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pydis_site/apps/api/models/bot/deleted_message.py b/pydis_site/apps/api/models/bot/deleted_message.py index 1eb4516e..50b70d8c 100644 --- a/pydis_site/apps/api/models/bot/deleted_message.py +++ b/pydis_site/apps/api/models/bot/deleted_message.py @@ -14,6 +14,6 @@ class DeletedMessage(Message): ) class Meta: - """Sets the default ordering for list views to oldest first.""" + """Sets the default ordering for list views to newest first.""" - ordering = ["id"] + ordering = ("-id",) diff --git a/pydis_site/apps/api/models/bot/message_deletion_context.py b/pydis_site/apps/api/models/bot/message_deletion_context.py index 44a0c8ae..02a15ca0 100644 --- a/pydis_site/apps/api/models/bot/message_deletion_context.py +++ b/pydis_site/apps/api/models/bot/message_deletion_context.py @@ -1,3 +1,4 @@ +from django.contrib.sites.models import Site from django.db import models from pydis_site.apps.api.models.bot.user import User @@ -28,3 +29,14 @@ class MessageDeletionContext(ModelReprMixin, models.Model): # the deletion context does not take place in the future. help_text="When this deletion took place." ) + + @property + def log_url(self) -> str: + """Create the url for the deleted message logs.""" + domain = Site.objects.get_current().domain + return f"http://staff.{domain}/bot/logs/{self.id}/" + + class Meta: + """Set the ordering for list views to newest first.""" + + ordering = ("-creation",) -- cgit v1.2.3 From f590d2bc5960cafede1e596d67028052f2fad5b2 Mon Sep 17 00:00:00 2001 From: scragly <29337040+scragly@users.noreply.github.com> Date: Sun, 20 Oct 2019 05:39:11 +1000 Subject: Add message log links, improved formatting to message deletion admin pages. --- pydis_site/apps/api/admin.py | 82 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 7 deletions(-) diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index 059f52eb..6d6a9b3b 100644 --- a/pydis_site/apps/api/admin.py +++ b/pydis_site/apps/api/admin.py @@ -1,7 +1,10 @@ +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, @@ -44,21 +47,86 @@ class LogEntryAdmin(admin.ModelAdmin): """Deny manual LogEntry creation.""" return False - def has_delete_permission( - self, - request: HttpRequest, - obj: Optional[LogEntry] = None - ) -> bool: + 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( + "
{0}
",
+ 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("{1}", link, details)
+
+ @staticmethod
+ def view_full_log(instance: DeletedMessage) -> str:
+ """Provide a link to the message logs for the relevant context."""
+ return format_html(
+ "Click to view full context log",
+ 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(
+ "Click to see deleted message log",
+ instance.log_url
+ )
+
+
admin.site.register(BotSetting)
-admin.site.register(DeletedMessage)
+admin.site.register(DeletedMessage, DeletedMessageAdmin)
admin.site.register(DocumentationLink)
admin.site.register(Infraction)
admin.site.register(LogEntry, LogEntryAdmin)
-admin.site.register(MessageDeletionContext)
+admin.site.register(MessageDeletionContext, MessageDeletionContextAdmin)
admin.site.register(Nomination)
admin.site.register(OffTopicChannelName)
admin.site.register(Role)
--
cgit v1.2.3
From 618610fe367b0c8d6175d251c276c2e37db8aa52 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Oct 2019 05:43:21 +1000
Subject: Order roles by positioning, add filters and search to api user admin
page.
---
pydis_site/apps/api/admin.py | 45 ++++++++++++++++++++++++++++++++--
pydis_site/apps/api/models/bot/role.py | 5 ++++
2 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index 6d6a9b3b..65cc0a6c 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -1,8 +1,9 @@
import json
-from typing import Optional
+from typing import Optional, Tuple
from django import urls
from django.contrib import admin
+from django.db.models.query import QuerySet
from django.http import HttpRequest
from django.utils.html import format_html
@@ -121,6 +122,46 @@ class MessageDeletionContextAdmin(admin.ModelAdmin):
)
+class StaffRolesFilter(admin.SimpleListFilter):
+ """Filter options for Staff Roles."""
+
+ title = "Staff Role"
+ parameter_name = "staff_role"
+
+ @staticmethod
+ def lookups(*_) -> Tuple[Tuple[str, str], ...]:
+ """Available filter options."""
+ return (
+ ("Owners", "Owners"),
+ ("Admins", "Admins"),
+ ("Moderators", "Moderators"),
+ ("Core Developers", "Core Developers"),
+ ("Helpers", "Helpers"),
+ )
+
+ def queryset(self, request: HttpRequest, queryset: QuerySet) -> Optional[QuerySet]:
+ """Returned data filter based on selected option."""
+ value = self.value()
+ if value:
+ return queryset.filter(roles__name=value)
+
+
+class UserAdmin(admin.ModelAdmin):
+ """Admin formatting for the User model."""
+
+ search_fields = ("name", "id", "roles__name", "roles__id")
+ list_filter = ("in_guild", StaffRolesFilter)
+ exclude = ("name", "discriminator")
+ readonly_fields = (
+ "__str__",
+ "id",
+ "avatar_hash",
+ "top_role",
+ "roles",
+ "in_guild",
+ )
+
+
admin.site.register(BotSetting)
admin.site.register(DeletedMessage, DeletedMessageAdmin)
admin.site.register(DocumentationLink)
@@ -131,4 +172,4 @@ admin.site.register(Nomination)
admin.site.register(OffTopicChannelName)
admin.site.register(Role)
admin.site.register(Tag)
-admin.site.register(User)
+admin.site.register(User, UserAdmin)
diff --git a/pydis_site/apps/api/models/bot/role.py b/pydis_site/apps/api/models/bot/role.py
index 58bbf8b4..b95740da 100644
--- a/pydis_site/apps/api/models/bot/role.py
+++ b/pydis_site/apps/api/models/bot/role.py
@@ -65,3 +65,8 @@ class Role(ModelReprMixin, models.Model):
def __le__(self, other: Role) -> bool:
"""Compares the roles based on their position in the role hierarchy of the guild."""
return self.position <= other.position
+
+ class Meta:
+ """Set role ordering from highest to lowest position."""
+
+ ordering = ("-position",)
--
cgit v1.2.3
From 0021d4a2906021351203ffabc73d6e02ecf400c4 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Oct 2019 06:21:13 +1000
Subject: Improve infractions admin list and page, add search and filters.
---
pydis_site/apps/api/admin.py | 46 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index 65cc0a6c..74b9413b 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -122,6 +122,50 @@ class MessageDeletionContextAdmin(admin.ModelAdmin):
)
+class InfractionAdmin(admin.ModelAdmin):
+ """Admin formatting for the Infraction model."""
+
+ fields = (
+ "user",
+ "actor",
+ "type",
+ "reason",
+ "inserted_at",
+ "expires_at",
+ "active",
+ "hidden"
+ )
+ readonly_fields = (
+ "user",
+ "actor",
+ "type",
+ "inserted_at"
+ )
+ list_display = (
+ "type",
+ "user",
+ "actor",
+ "inserted_at",
+ "expires_at",
+ "reason",
+ "active",
+ )
+ search_fields = (
+ "id",
+ "user__name",
+ "user__id",
+ "actor__name",
+ "actor__id",
+ "reason",
+ "type"
+ )
+ list_filter = (
+ "type",
+ "hidden",
+ "active"
+ )
+
+
class StaffRolesFilter(admin.SimpleListFilter):
"""Filter options for Staff Roles."""
@@ -165,7 +209,7 @@ class UserAdmin(admin.ModelAdmin):
admin.site.register(BotSetting)
admin.site.register(DeletedMessage, DeletedMessageAdmin)
admin.site.register(DocumentationLink)
-admin.site.register(Infraction)
+admin.site.register(Infraction, InfractionAdmin)
admin.site.register(LogEntry, LogEntryAdmin)
admin.site.register(MessageDeletionContext, MessageDeletionContextAdmin)
admin.site.register(Nomination)
--
cgit v1.2.3
From 1c41c8a1aa07d7a716561c7594f769db7aa58cf5 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Oct 2019 06:33:35 +1000
Subject: Improve nominations admin list and page, add search and filter by
active.
---
pydis_site/apps/api/admin.py | 39 +++++++++++++++++++++++++++-
pydis_site/apps/api/models/bot/nomination.py | 5 ++++
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index 74b9413b..55a9d655 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -166,6 +166,43 @@ class InfractionAdmin(admin.ModelAdmin):
)
+class NominationAdmin(admin.ModelAdmin):
+ """Admin formatting for the Nomination model."""
+
+ list_display = (
+ "user",
+ "active",
+ "reason",
+ "actor",
+ "inserted_at",
+ "ended_at"
+ )
+ fields = (
+ "user",
+ "active",
+ "actor",
+ "reason",
+ "inserted_at",
+ "ended_at",
+ "end_reason"
+ )
+ readonly_fields = (
+ "user",
+ "active",
+ "actor",
+ "inserted_at",
+ "ended_at"
+ )
+ search_fields = (
+ "actor__name",
+ "actor__id",
+ "user__name",
+ "user__id",
+ "reason"
+ )
+ list_filter = ("active",)
+
+
class StaffRolesFilter(admin.SimpleListFilter):
"""Filter options for Staff Roles."""
@@ -212,7 +249,7 @@ admin.site.register(DocumentationLink)
admin.site.register(Infraction, InfractionAdmin)
admin.site.register(LogEntry, LogEntryAdmin)
admin.site.register(MessageDeletionContext, MessageDeletionContextAdmin)
-admin.site.register(Nomination)
+admin.site.register(Nomination, NominationAdmin)
admin.site.register(OffTopicChannelName)
admin.site.register(Role)
admin.site.register(Tag)
diff --git a/pydis_site/apps/api/models/bot/nomination.py b/pydis_site/apps/api/models/bot/nomination.py
index cd9951aa..a0ba42a3 100644
--- a/pydis_site/apps/api/models/bot/nomination.py
+++ b/pydis_site/apps/api/models/bot/nomination.py
@@ -44,3 +44,8 @@ class Nomination(ModelReprMixin, models.Model):
"""Representation that makes the target and state of the nomination immediately evident."""
status = "active" if self.active else "ended"
return f"Nomination of {self.user} ({status})"
+
+ class Meta:
+ """Set the ordering of nominations to most recent first."""
+
+ ordering = ("-inserted_at",)
--
cgit v1.2.3
From 77da3336a248a5a01fe1f83493e0424dbd261cd2 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Oct 2019 06:37:55 +1000
Subject: Add search field to off topic admin page.
---
pydis_site/apps/api/admin.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index 55a9d655..fe0e3235 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -203,6 +203,12 @@ class NominationAdmin(admin.ModelAdmin):
list_filter = ("active",)
+class OffTopicChannelNameAdmin(admin.ModelAdmin):
+ """Admin formatting for the OffTopicChannelName model."""
+
+ search_fields = ("name",)
+
+
class StaffRolesFilter(admin.SimpleListFilter):
"""Filter options for Staff Roles."""
@@ -250,7 +256,7 @@ admin.site.register(Infraction, InfractionAdmin)
admin.site.register(LogEntry, LogEntryAdmin)
admin.site.register(MessageDeletionContext, MessageDeletionContextAdmin)
admin.site.register(Nomination, NominationAdmin)
-admin.site.register(OffTopicChannelName)
+admin.site.register(OffTopicChannelName, OffTopicChannelNameAdmin)
admin.site.register(Role)
admin.site.register(Tag)
admin.site.register(User, UserAdmin)
--
cgit v1.2.3
From 72f156fda828a7e28605d0fe07bd990d05f61925 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Oct 2019 07:18:42 +1000
Subject: Show role colour style and add hex value, link perms to calc page,
add role search.
---
pydis_site/apps/api/admin.py | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index fe0e3235..237d68a4 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -209,6 +209,38 @@ class OffTopicChannelNameAdmin(admin.ModelAdmin):
search_fields = ("name",)
+class RoleAdmin(admin.ModelAdmin):
+ """Admin formatting for the Role model."""
+
+ exclude = ("permissions", "colour")
+ readonly_fields = (
+ "name",
+ "id",
+ "colour_with_preview",
+ "permissions_with_calc_link",
+ "position"
+ )
+ search_fields = ("name", "id")
+
+ def colour_with_preview(self, instance: Role) -> str:
+ """Show colour value in both int and hex, in bolded and coloured style."""
+ return format_html(
+ "{1} / #{0}",
+ f"{instance.colour:06x}",
+ instance.colour
+ )
+
+ def permissions_with_calc_link(self, instance: Role) -> str:
+ """Show permissions with link to API permissions calculator page."""
+ return format_html(
+ "{0}",
+ instance.permissions
+ )
+
+ colour_with_preview.short_description = "Colour"
+ permissions_with_calc_link.short_description = "Permissions"
+
+
class StaffRolesFilter(admin.SimpleListFilter):
"""Filter options for Staff Roles."""
@@ -257,6 +289,6 @@ admin.site.register(LogEntry, LogEntryAdmin)
admin.site.register(MessageDeletionContext, MessageDeletionContextAdmin)
admin.site.register(Nomination, NominationAdmin)
admin.site.register(OffTopicChannelName, OffTopicChannelNameAdmin)
-admin.site.register(Role)
+admin.site.register(Role, RoleAdmin)
admin.site.register(Tag)
admin.site.register(User, UserAdmin)
--
cgit v1.2.3
From e19d34b06f6485d2809b600547ae5b672c31fe7e Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Oct 2019 07:50:00 +1000
Subject: Add tag search and rendered preview.
---
pydis_site/apps/api/admin.py | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index 237d68a4..010541a6 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -82,7 +82,8 @@ class DeletedMessageAdmin(admin.ModelAdmin):
"""Format embed data in a code block for better readability."""
if instance.embeds:
return format_html(
- "{0}
",
+ ""
+ "{0}
",
json.dumps(instance.embeds, indent=4)
)
@@ -241,6 +242,29 @@ class RoleAdmin(admin.ModelAdmin):
permissions_with_calc_link.short_description = "Permissions"
+class TagAdmin(admin.ModelAdmin):
+ """Admin formatting for the Tag model."""
+
+ fields = ("title", "embed", "preview")
+ readonly_fields = ("preview",)
+ search_fields = ("title", "embed")
+
+ @staticmethod
+ def preview(instance: Tag) -> Optional[str]:
+ """Render tag markdown contents to preview actual appearance."""
+ if instance.embed:
+ import markdown
+ return format_html(
+ markdown.markdown(
+ instance.embed["description"],
+ extensions=[
+ "markdown.extensions.nl2br",
+ "markdown.extensions.extra"
+ ]
+ )
+ )
+
+
class StaffRolesFilter(admin.SimpleListFilter):
"""Filter options for Staff Roles."""
@@ -290,5 +314,5 @@ admin.site.register(MessageDeletionContext, MessageDeletionContextAdmin)
admin.site.register(Nomination, NominationAdmin)
admin.site.register(OffTopicChannelName, OffTopicChannelNameAdmin)
admin.site.register(Role, RoleAdmin)
-admin.site.register(Tag)
+admin.site.register(Tag, TagAdmin)
admin.site.register(User, UserAdmin)
--
cgit v1.2.3
From b6d01478bab4a2706202d44f117498ca676c00df Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Oct 2019 08:51:28 +1000
Subject: Adjust deleted message test to account for new ordering of newest
created first.
---
pydis_site/apps/staff/tests/test_logs_view.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pydis_site/apps/staff/tests/test_logs_view.py b/pydis_site/apps/staff/tests/test_logs_view.py
index 32cb6bbf..5036363b 100644
--- a/pydis_site/apps/staff/tests/test_logs_view.py
+++ b/pydis_site/apps/staff/tests/test_logs_view.py
@@ -132,7 +132,7 @@ class TestLogsView(TestCase):
response = self.client.get(url)
self.assertIn("messages", response.context)
self.assertListEqual(
- [self.deleted_message_one, self.deleted_message_two],
+ [self.deleted_message_two, self.deleted_message_one],
list(response.context["deletion_context"].deletedmessage_set.all())
)
--
cgit v1.2.3
From 56c6c85ad973a3b594d72215cdfb2d3b6c19d741 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Oct 2019 09:29:58 +1000
Subject: Add new test for deleted message context log_url.
---
.../api/models/bot/message_deletion_context.py | 5 ++---
pydis_site/apps/api/tests/test_deleted_messages.py | 22 ++++++++++++++++++++++
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/pydis_site/apps/api/models/bot/message_deletion_context.py b/pydis_site/apps/api/models/bot/message_deletion_context.py
index 02a15ca0..fde9b0a6 100644
--- a/pydis_site/apps/api/models/bot/message_deletion_context.py
+++ b/pydis_site/apps/api/models/bot/message_deletion_context.py
@@ -1,5 +1,5 @@
-from django.contrib.sites.models import Site
from django.db import models
+from django_hosts.resolvers import reverse
from pydis_site.apps.api.models.bot.user import User
from pydis_site.apps.api.models.utils import ModelReprMixin
@@ -33,8 +33,7 @@ class MessageDeletionContext(ModelReprMixin, models.Model):
@property
def log_url(self) -> str:
"""Create the url for the deleted message logs."""
- domain = Site.objects.get_current().domain
- return f"http://staff.{domain}/bot/logs/{self.id}/"
+ return reverse('logs', host="staff", args=(self.id,))
class Meta:
"""Set the ordering for list views to newest first."""
diff --git a/pydis_site/apps/api/tests/test_deleted_messages.py b/pydis_site/apps/api/tests/test_deleted_messages.py
index d1e9f2f5..ccccdda4 100644
--- a/pydis_site/apps/api/tests/test_deleted_messages.py
+++ b/pydis_site/apps/api/tests/test_deleted_messages.py
@@ -1,5 +1,6 @@
from datetime import datetime
+from django.utils import timezone
from django_hosts.resolvers import reverse
from .base import APISubdomainTestCase
@@ -75,3 +76,24 @@ class DeletedMessagesWithActorTests(APISubdomainTestCase):
self.assertEqual(response.status_code, 201)
[context] = MessageDeletionContext.objects.all()
self.assertEqual(context.actor.id, self.actor.id)
+
+
+class DeletedMessagesLogURLTests(APISubdomainTestCase):
+ @classmethod
+ def setUpTestData(cls): # noqa
+ cls.author = cls.actor = User.objects.create(
+ id=324888,
+ name='Black Knight',
+ discriminator=1975,
+ avatar_hash=None
+ )
+
+ cls.deletion_context = MessageDeletionContext.objects.create(
+ actor=cls.actor,
+ creation=timezone.now()
+ )
+
+ def test_valid_log_url(self):
+ expected_url = reverse('logs', host="staff", args=(1,))
+ [context] = MessageDeletionContext.objects.all()
+ self.assertEqual(context.log_url, expected_url)
--
cgit v1.2.3
From 49e7243f6527140dbdb29a2f1dd994839f248dba Mon Sep 17 00:00:00 2001
From: Eivind Teig "
"{0}
",
- json.dumps(instance.embeds, indent=4)
+ json.dumps(message.embeds, indent=4)
)
+ embed_data.short_description = "Embeds"
+
@staticmethod
- def context(instance: DeletedMessage) -> str:
+ def context(message: 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]
+ args=[message.deletion_context.id]
)
details = (
- f"Deleted by {instance.deletion_context.actor} at "
- f"{instance.deletion_context.creation}"
+ f"Deleted by {message.deletion_context.actor} at "
+ f"{message.deletion_context.creation}"
)
return format_html("{1}", link, details)
@staticmethod
- def view_full_log(instance: DeletedMessage) -> str:
+ def view_full_log(message: DeletedMessage) -> str:
"""Provide a link to the message logs for the relevant context."""
return format_html(
"Click to view full context log",
- instance.deletion_context.log_url
+ message.deletion_context.log_url
)
+ def has_add_permission(self, *args) -> bool:
+ """Prevent adding from django admin."""
+ return False
+
+ def has_change_permission(self, *args) -> bool:
+ """Prevent editing from django admin."""
+ return False
+
+
+class DeletedMessageInline(admin.TabularInline):
+ """Tabular Inline Admin model for Deleted Message to be viewed within Context."""
+
+ model = DeletedMessage
+
@admin.register(MessageDeletionContext)
class MessageDeletionContextAdmin(admin.ModelAdmin):
"""Admin formatting for the MessageDeletionContext model."""
- readonly_fields = ("actor", "creation", "message_log")
+ fields = ("actor", "creation")
+ list_display = ("id", "creation", "actor")
+ inlines = (DeletedMessageInline,)
- @staticmethod
- def message_log(instance: MessageDeletionContext) -> str:
- """Provide a formatted link to the message logs for the context."""
- return format_html(
- "Click to see deleted message log",
- instance.log_url
- )
-
-
-@admin.register(Infraction)
-class InfractionAdmin(admin.ModelAdmin):
- """Admin formatting for the Infraction model."""
+ def has_add_permission(self, *args) -> bool:
+ """Prevent adding from django admin."""
+ return False
- fields = (
- "user",
- "actor",
- "type",
- "reason",
- "inserted_at",
- "expires_at",
- "active",
- "hidden"
- )
- readonly_fields = (
- "user",
- "actor",
- "type",
- "inserted_at"
- )
- list_display = (
- "type",
- "user",
- "actor",
- "inserted_at",
- "expires_at",
- "reason",
- "active",
- )
- search_fields = (
- "id",
- "user__name",
- "user__id",
- "actor__name",
- "actor__id",
- "reason",
- "type"
- )
- list_filter = (
- "type",
- "hidden",
- "active"
- )
+ def has_change_permission(self, *args) -> bool:
+ """Prevent editing from django admin."""
+ return False
class NominationActorFilter(admin.SimpleListFilter):
@@ -179,7 +194,7 @@ class NominationActorFilter(admin.SimpleListFilter):
title = "Actor"
parameter_name = "actor"
- def lookups(self, request: HttpRequest, model_admin: NominationAdmin) -> Iterable[Tuple[int, str]]:
+ def lookups(self, request: HttpRequest, model: NominationAdmin) -> Iterable[Tuple[int, str]]:
"""Selectable values for viewer to filter by."""
actor_ids = Nomination.objects.order_by().values_list("actor").distinct()
actors = User.objects.filter(id__in=actor_ids)
@@ -322,7 +337,7 @@ class UserTopRoleFilter(admin.SimpleListFilter):
title = "Role"
parameter_name = "role"
- def lookups(self, request: HttpRequest, model_admin: UserAdmin) -> Iterable[Tuple[str, str]]:
+ def lookups(self, request: HttpRequest, model: UserAdmin) -> Iterable[Tuple[str, str]]:
"""Selectable values for viewer to filter by."""
roles = Role.objects.all()
return ((r.name, r.name) for r in roles)
diff --git a/pydis_site/apps/api/models/bot/message.py b/pydis_site/apps/api/models/bot/message.py
index f6ae55a5..ff06de21 100644
--- a/pydis_site/apps/api/models/bot/message.py
+++ b/pydis_site/apps/api/models/bot/message.py
@@ -21,7 +21,8 @@ class Message(ModelReprMixin, models.Model):
limit_value=0,
message="Message IDs cannot be negative."
),
- )
+ ),
+ verbose_name="ID"
)
author = models.ForeignKey(
User,
@@ -38,7 +39,8 @@ class Message(ModelReprMixin, models.Model):
limit_value=0,
message="Channel IDs cannot be negative."
),
- )
+ ),
+ verbose_name="Channel ID"
)
content = models.CharField(
max_length=2_000,
--
cgit v1.2.3
From c6e80a97bb9e40dc404e274d6ebc419b410a2b66 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Fri, 18 Sep 2020 15:16:00 +1000
Subject: Add DocumentationLink and BotSetting Admin models.
---
pydis_site/apps/api/admin.py | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index ca97512f..7b571005 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -27,6 +27,28 @@ admin.site.site_header = "Python Discord | Administration"
admin.site.site_title = "Python Discord"
+@admin.register(BotSetting)
+class BotSettingAdmin(admin.ModelAdmin):
+ """Admin formatting for the BotSetting model."""
+
+ fields = ("name", "data")
+ list_display = ("name",)
+
+ def has_add_permission(self, *args) -> bool:
+ """Prevent adding from django admin."""
+ return False
+
+
+@admin.register(DocumentationLink)
+class DocumentationLinkAdmin(admin.ModelAdmin):
+ """Admin formatting for the DocumentationLink model."""
+
+ fields = ("package", "base_url", "inventory_url")
+ list_display = ("package", "base_url", "inventory_url")
+ list_editable = ("base_url", "inventory_url")
+ search_fields = ("package",)
+
+
@admin.register(Infraction)
class InfractionAdmin(admin.ModelAdmin):
"""Admin formatting for the Infraction model."""
@@ -71,6 +93,10 @@ class InfractionAdmin(admin.ModelAdmin):
"active"
)
+ def has_add_permission(self, *args) -> bool:
+ """Prevent adding from django admin."""
+ return False
+
@admin.register(LogEntry)
class LogEntryAdmin(admin.ModelAdmin):
@@ -124,6 +150,8 @@ class DeletedMessageAdmin(admin.ModelAdmin):
"deletion_context__actor__id"
)
+ list_display = ("id", "author", "channel_id")
+
def embed_data(self, message: DeletedMessage) -> Optional[str]:
"""Format embed data in a code block for better readability."""
if message.embeds:
@@ -389,7 +417,3 @@ class UserAdmin(admin.ModelAdmin):
def has_change_permission(self, *args) -> bool:
"""Prevent editing from django admin."""
return False
-
-
-admin.site.register(BotSetting)
-admin.site.register(DocumentationLink)
--
cgit v1.2.3
From 8af9e190f69484efb5fe3b5910a9125738e0ee84 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Fri, 18 Sep 2020 15:22:48 +1000
Subject: Declutter Infraction admin list, add actor list filter.
---
pydis_site/apps/api/admin.py | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index 7b571005..ff9afc46 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -49,6 +49,25 @@ class DocumentationLinkAdmin(admin.ModelAdmin):
search_fields = ("package",)
+class InfractionActorFilter(admin.SimpleListFilter):
+ """Actor Filter for Infraction Admin list page."""
+
+ title = "Actor"
+ parameter_name = "actor"
+
+ def lookups(self, request: HttpRequest, model: NominationAdmin) -> Iterable[Tuple[int, str]]:
+ """Selectable values for viewer to filter by."""
+ actor_ids = Infraction.objects.order_by().values_list("actor").distinct()
+ actors = User.objects.filter(id__in=actor_ids)
+ return ((a.id, a.username) for a in actors)
+
+ def queryset(self, request: HttpRequest, queryset: QuerySet) -> Optional[QuerySet]:
+ """Query to filter the list of Users against."""
+ if not self.value():
+ return
+ return queryset.filter(actor__id=self.value())
+
+
@admin.register(Infraction)
class InfractionAdmin(admin.ModelAdmin):
"""Admin formatting for the Infraction model."""
@@ -67,16 +86,16 @@ class InfractionAdmin(admin.ModelAdmin):
"user",
"actor",
"type",
- "inserted_at"
+ "inserted_at",
+ "active",
+ "hidden"
)
list_display = (
"type",
+ "active",
"user",
- "actor",
"inserted_at",
- "expires_at",
"reason",
- "active",
)
search_fields = (
"id",
@@ -90,7 +109,8 @@ class InfractionAdmin(admin.ModelAdmin):
list_filter = (
"type",
"hidden",
- "active"
+ "active",
+ InfractionActorFilter
)
def has_add_permission(self, *args) -> bool:
--
cgit v1.2.3
From 2c4b3451b3349d098ceebce774b08946b5e378d5 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Fri, 18 Sep 2020 15:24:54 +1000
Subject: Don't allow expiry to be editable, due to pending bot tasks unsyncing
---
pydis_site/apps/api/admin.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index ff9afc46..6267b7a8 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -87,6 +87,7 @@ class InfractionAdmin(admin.ModelAdmin):
"actor",
"type",
"inserted_at",
+ "expires_at",
"active",
"hidden"
)
--
cgit v1.2.3
From 8edeb88f92b8ed48f2f383c2245416486f8e99cc Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sat, 19 Sep 2020 01:23:58 +1000
Subject: Remove noqa from DeletedMessagesLogURLTests setup.
---
pydis_site/apps/api/tests/test_deleted_messages.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pydis_site/apps/api/tests/test_deleted_messages.py b/pydis_site/apps/api/tests/test_deleted_messages.py
index 287c1737..448f1186 100644
--- a/pydis_site/apps/api/tests/test_deleted_messages.py
+++ b/pydis_site/apps/api/tests/test_deleted_messages.py
@@ -81,7 +81,7 @@ class DeletedMessagesWithActorTests(APISubdomainTestCase):
class DeletedMessagesLogURLTests(APISubdomainTestCase):
@classmethod
- def setUpTestData(cls): # noqa
+ def setUpTestData(cls):
cls.author = cls.actor = User.objects.create(
id=324888,
name='Black Knight',
--
cgit v1.2.3
From 520ea636a3b22beb3fb153dea5e6dd0dd6f809f4 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sat, 19 Sep 2020 02:23:01 +1000
Subject: Update user model in DeletedMessagesLogURLTests.
`avatar_hash` is no longer a field stored in the database.
---
pydis_site/apps/api/tests/test_deleted_messages.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/pydis_site/apps/api/tests/test_deleted_messages.py b/pydis_site/apps/api/tests/test_deleted_messages.py
index 448f1186..40450844 100644
--- a/pydis_site/apps/api/tests/test_deleted_messages.py
+++ b/pydis_site/apps/api/tests/test_deleted_messages.py
@@ -86,7 +86,6 @@ class DeletedMessagesLogURLTests(APISubdomainTestCase):
id=324888,
name='Black Knight',
discriminator=1975,
- avatar_hash=None
)
cls.deletion_context = MessageDeletionContext.objects.create(
--
cgit v1.2.3
From 394d1ca151ad28be431eff8f25dde5707eeb0d47 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Sep 2020 00:04:20 +1000
Subject: Test username property formatting for user model.
---
pydis_site/apps/api/tests/test_users.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py
index 4c0f6e27..a02fce8a 100644
--- a/pydis_site/apps/api/tests/test_users.py
+++ b/pydis_site/apps/api/tests/test_users.py
@@ -143,7 +143,7 @@ class UserModelTests(APISubdomainTestCase):
cls.user_with_roles = User.objects.create(
id=1,
name="Test User with two roles",
- discriminator=1111,
+ discriminator=1,
in_guild=True,
)
cls.user_with_roles.roles.extend([cls.role_bottom.id, cls.role_top.id])
@@ -166,3 +166,7 @@ class UserModelTests(APISubdomainTestCase):
top_role = self.user_without_roles.top_role
self.assertIsInstance(top_role, Role)
self.assertEqual(top_role.id, self.developers_role.id)
+
+ def test_correct_username_formatting(self):
+ """Tests the username property with both name and discriminator formatted together."""
+ self.assertEqual(self.user_with_roles.username, "Test User with two roles#0001")
--
cgit v1.2.3
From dafca0fee8ac618ee9aab5ce8a1d7c34aafc3a05 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Sep 2020 02:06:11 +1000
Subject: Change UserTopRoleFilter to UserRoleFilter.
Filter checks for general role membership instead of only those who have the selected role as top role. Noticed during development that we'd not be able to filter to show all Helpers otherwise, as some Helpers have different top roles such as Core Dev that wouldn't give immediately obvious behaviour to user expectations.
---
pydis_site/apps/api/admin.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index 6267b7a8..733a056d 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -380,7 +380,7 @@ class RoleAdmin(admin.ModelAdmin):
return False
-class UserTopRoleFilter(admin.SimpleListFilter):
+class UserRoleFilter(admin.SimpleListFilter):
"""List Filter for User list Admin page."""
title = "Role"
@@ -426,7 +426,7 @@ class UserAdmin(admin.ModelAdmin):
all_roles_coloured.short_description = "All Roles"
search_fields = ("name", "id", "roles")
- list_filter = (UserTopRoleFilter, "in_guild")
+ list_filter = (UserRoleFilter, "in_guild")
list_display = ("username", "top_role_coloured", "in_guild")
fields = ("username", "id", "in_guild", "all_roles_coloured")
sortable_by = ("username",)
--
cgit v1.2.3
From 715dd46aa68358cdd2abee07b018ee08e54da8d9 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Sep 2020 05:02:48 +1000
Subject: Allow Nomination end_reason to have a blank value for validation.
Without `blank=True`, admin page editable forms could not be saved if no content was in the end_reason input.
---
pydis_site/apps/api/models/bot/nomination.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pydis_site/apps/api/models/bot/nomination.py b/pydis_site/apps/api/models/bot/nomination.py
index 54f56c98..11b9e36e 100644
--- a/pydis_site/apps/api/models/bot/nomination.py
+++ b/pydis_site/apps/api/models/bot/nomination.py
@@ -34,7 +34,8 @@ class Nomination(ModelReprMixin, models.Model):
)
end_reason = models.TextField(
help_text="Why the nomination was ended.",
- default=""
+ default="",
+ blank=True
)
ended_at = models.DateTimeField(
auto_now_add=False,
--
cgit v1.2.3
From d39eeb9b7e936f264abcfbb998453179ef8556f5 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Sep 2020 06:27:16 +1000
Subject: Change Infraction admin to use fieldsets for better grouping of info.
---
pydis_site/apps/api/admin.py | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index 733a056d..c3f1179e 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -72,15 +72,11 @@ class InfractionActorFilter(admin.SimpleListFilter):
class InfractionAdmin(admin.ModelAdmin):
"""Admin formatting for the Infraction model."""
- fields = (
- "user",
- "actor",
- "type",
- "reason",
- "inserted_at",
- "expires_at",
- "active",
- "hidden"
+ fieldsets = (
+ ("Members", {"fields": ("user", "actor")}),
+ ("Action", {"fields": ("type", "hidden", "active")}),
+ ("Dates", {"fields": ("inserted_at", "expires_at")}),
+ ("Reason", {"fields": ("reason",)}),
)
readonly_fields = (
"user",
--
cgit v1.2.3
From 9344d8ac63df05d67a79fbeacc7a8c31acf86853 Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Sep 2020 06:35:38 +1000
Subject: Change documentation link model to order by package.
---
pydis_site/apps/api/models/bot/documentation_link.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pydis_site/apps/api/models/bot/documentation_link.py b/pydis_site/apps/api/models/bot/documentation_link.py
index 5a46460b..2a0ce751 100644
--- a/pydis_site/apps/api/models/bot/documentation_link.py
+++ b/pydis_site/apps/api/models/bot/documentation_link.py
@@ -24,3 +24,8 @@ class DocumentationLink(ModelReprMixin, models.Model):
def __str__(self):
"""Returns the package and URL for the current documentation link, for display purposes."""
return f"{self.package} - {self.base_url}"
+
+ class Meta:
+ """Defines the meta options for the documentation link model."""
+
+ ordering = ['package']
--
cgit v1.2.3
From 1916074a704fc6f4b8595b8afb5463436b60961a Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Sep 2020 06:36:30 +1000
Subject: Add migrations for nomination and doc link model changes.
---
.../apps/api/migrations/0064_auto_20200919_1900.py | 76 ++++++++++++++++++++++
.../apps/api/migrations/0065_auto_20200919_2033.py | 17 +++++
2 files changed, 93 insertions(+)
create mode 100644 pydis_site/apps/api/migrations/0064_auto_20200919_1900.py
create mode 100644 pydis_site/apps/api/migrations/0065_auto_20200919_2033.py
diff --git a/pydis_site/apps/api/migrations/0064_auto_20200919_1900.py b/pydis_site/apps/api/migrations/0064_auto_20200919_1900.py
new file mode 100644
index 00000000..0080eb42
--- /dev/null
+++ b/pydis_site/apps/api/migrations/0064_auto_20200919_1900.py
@@ -0,0 +1,76 @@
+# Generated by Django 3.0.9 on 2020-09-19 19:00
+
+import django.core.validators
+from django.db import migrations, models
+import pydis_site.apps.api.models.bot.offensive_message
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0063_Allow_blank_or_null_for_nomination_reason'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='deletedmessage',
+ options={'ordering': ('-id',)},
+ ),
+ migrations.AlterModelOptions(
+ name='messagedeletioncontext',
+ options={'ordering': ('-creation',)},
+ ),
+ migrations.AlterModelOptions(
+ name='nomination',
+ options={'ordering': ('-inserted_at',)},
+ ),
+ migrations.AlterModelOptions(
+ name='role',
+ options={'ordering': ('-position',)},
+ ),
+ migrations.AlterField(
+ model_name='deletedmessage',
+ name='channel_id',
+ field=models.BigIntegerField(help_text='The channel ID that this message was sent in, taken from Discord.', validators=[django.core.validators.MinValueValidator(limit_value=0, message='Channel IDs cannot be negative.')], verbose_name='Channel ID'),
+ ),
+ migrations.AlterField(
+ model_name='deletedmessage',
+ name='id',
+ field=models.BigIntegerField(help_text='The message ID as taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='Message IDs cannot be negative.')], verbose_name='ID'),
+ ),
+ migrations.AlterField(
+ model_name='nomination',
+ name='end_reason',
+ field=models.TextField(blank=True, default='', help_text='Why the nomination was ended.'),
+ ),
+ migrations.AlterField(
+ model_name='offensivemessage',
+ name='channel_id',
+ field=models.BigIntegerField(help_text='The channel ID that the message was sent in, taken from Discord.', validators=[django.core.validators.MinValueValidator(limit_value=0, message='Channel IDs cannot be negative.')], verbose_name='Channel ID'),
+ ),
+ migrations.AlterField(
+ model_name='offensivemessage',
+ name='delete_date',
+ field=models.DateTimeField(help_text='The date on which the message will be auto-deleted.', validators=[pydis_site.apps.api.models.bot.offensive_message.future_date_validator], verbose_name='To Be Deleted'),
+ ),
+ migrations.AlterField(
+ model_name='offensivemessage',
+ name='id',
+ field=models.BigIntegerField(help_text='The message ID as taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='Message IDs cannot be negative.')], verbose_name='Message ID'),
+ ),
+ migrations.AlterField(
+ model_name='role',
+ name='id',
+ field=models.BigIntegerField(help_text='The role ID, taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='Role IDs cannot be negative.')], verbose_name='ID'),
+ ),
+ migrations.AlterField(
+ model_name='user',
+ name='id',
+ field=models.BigIntegerField(help_text='The ID of this user, taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='User IDs cannot be negative.')], verbose_name='ID'),
+ ),
+ migrations.AlterField(
+ model_name='user',
+ name='in_guild',
+ field=models.BooleanField(default=True, help_text='Whether this user is in our server.', verbose_name='In Guild'),
+ ),
+ ]
diff --git a/pydis_site/apps/api/migrations/0065_auto_20200919_2033.py b/pydis_site/apps/api/migrations/0065_auto_20200919_2033.py
new file mode 100644
index 00000000..89bc4e02
--- /dev/null
+++ b/pydis_site/apps/api/migrations/0065_auto_20200919_2033.py
@@ -0,0 +1,17 @@
+# Generated by Django 3.0.9 on 2020-09-19 20:33
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0064_auto_20200919_1900'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='documentationlink',
+ options={'ordering': ['package']},
+ ),
+ ]
--
cgit v1.2.3
From a105de702d2f64a66acfc2f06a3b994cd46a5c3e Mon Sep 17 00:00:00 2001
From: scragly <29337040+scragly@users.noreply.github.com>
Date: Sun, 20 Sep 2020 07:06:40 +1000
Subject: Remove delete permission for bot settings admin.
I'm unable to see any cases where this would be wanted, and instead accidental deletion would result in the system possibly breaking, as we are unable to add the setting again to replace it if it got removed.
The name has also set to read only in item view, to prevent renames, effectively doing the same thing as deleting it.
---
pydis_site/apps/api/admin.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py
index c3f1179e..5093e605 100644
--- a/pydis_site/apps/api/admin.py
+++ b/pydis_site/apps/api/admin.py
@@ -33,11 +33,16 @@ class BotSettingAdmin(admin.ModelAdmin):
fields = ("name", "data")
list_display = ("name",)
+ readonly_fields = ("name",)
def has_add_permission(self, *args) -> bool:
"""Prevent adding from django admin."""
return False
+ def has_delete_permission(self, *args) -> bool:
+ """Prevent deleting from django admin."""
+ return False
+
@admin.register(DocumentationLink)
class DocumentationLinkAdmin(admin.ModelAdmin):
--
cgit v1.2.3
From 9a98122a2544fc943b05015b156769ce2a53d0b6 Mon Sep 17 00:00:00 2001
From: Den4200 "+l(u.message+"",!0)+"";throw u}}var d={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:u,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:u,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:u,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};d.bullet=/(?:[*+-]|\d+\.)/,d.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,d.item=c(d.item,"gm")(/bull/g,d.bullet)(),d.list=c(d.list)(/bull/g,d.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+d.def.source+")")(),d.blockquote=c(d.blockquote)("def",d.def)(),d._tag="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b",d.html=c(d.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/
'+(n?e:l(e,!0))+"\n
\n":""+(n?e:l(e,!0))+"\n
"},o.prototype.blockquote=function(e){return"\n"+e+"\n"},o.prototype.html=function(e){return e},o.prototype.heading=function(e,t,n){return"
"+e+"
\n"},o.prototype.table=function(e,t){return""+e+"
"},o.prototype.br=function(){return this.options.xhtml?"- Please create the root article. This article will be available at the root of your wiki, - so consider creating a landing page here. -
-- Please note that, to begin with, this article may only be modified by wiki administrators. - Once it's been created, you may edit the permissions and set up plugins, metadata, and so on. -
- - -{% endblock %} diff --git a/pydis_site/templates/wiki/delete.html b/pydis_site/templates/wiki/delete.html deleted file mode 100644 index bb7a7966..00000000 --- a/pydis_site/templates/wiki/delete.html +++ /dev/null @@ -1,90 +0,0 @@ -{% extends "wiki/base.html" %} -{% load static %} -{% load wiki_tags %} - -{% block wiki_pagetitle %}Delete Article{% endblock %} - -{% block wiki_contents %} -Please confirm that you would like to delete this article.
- - - {% endif %} - {% endif %} -{% endblock %} diff --git a/pydis_site/templates/wiki/deleted.html b/pydis_site/templates/wiki/deleted.html deleted file mode 100644 index cdde2c47..00000000 --- a/pydis_site/templates/wiki/deleted.html +++ /dev/null @@ -1,62 +0,0 @@ -{% extends "wiki/base.html" %} -{% load wiki_tags %} - -{% block wiki_pagetitle %}Article deleted{% endblock %} - -{% block wiki_contents %} - - - {% if not article.current_revision.locked or article|can_delete:user %} -- To restore this article and any child articles, click the restore button below. -
- - - - - Restore - - {% endif %} - - {% if article|can_moderate:user %} -- To permanently remove this article and any child articles, click the purge button below. This will - allow you to free up the slugs assigned to these articles, so that they may be used for other - articles. -
-- Please note: This action cannot be undone. -
- - - {% endif %} - -{% endblock %} diff --git a/pydis_site/templates/wiki/deleted_list.html b/pydis_site/templates/wiki/deleted_list.html deleted file mode 100644 index 1a8d203c..00000000 --- a/pydis_site/templates/wiki/deleted_list.html +++ /dev/null @@ -1,45 +0,0 @@ -{% extends "wiki/base.html" %} -{% load wiki_tags %} - -{% block wiki_pagetitle %}Deleted Articles{% endblock %} - -{% block wiki_contents %} -Page Title | -Date Deleted | -Restore Article | -
---|---|---|
- {{ article }} - | -- {{article.modified}} - | -- - - - - Restore - - | -
- No deleted articles to display. -
- {% endif %} -{% endblock %} diff --git a/pydis_site/templates/wiki/dir.html b/pydis_site/templates/wiki/dir.html deleted file mode 100644 index 5a30de7b..00000000 --- a/pydis_site/templates/wiki/dir.html +++ /dev/null @@ -1,103 +0,0 @@ -{% extends "wiki/article.html" %} -{% load humanize %} -{% load i18n %} -{% load wiki_extra %} -{% load wiki_tags %} - -{% block wiki_pagetitle %}Listing articles in {{ article.current_revision.title }}{% endblock %} - -{% block wiki_contents_tab %} - {% url 'wiki:dir' urlpath.path as self_url %} - - - -- {% with paginator.object_list.count as cnt %} - {% blocktrans with urlpath.path as path and cnt|pluralize:_("article,articles") as articles_plur and cnt|pluralize:_("is,are") as articles_plur_verb trimmed %} - Browsing /{{ path }}. There {{ articles_plur_verb }} {{ cnt }} {{ articles_plur }} in this level. - {% endblocktrans %} - {% endwith %} -
- - {% include "wiki/includes/pagination.html" %} - -Title | -Slug | -Last modified | -
---|---|---|
- {{ urlpath.article.current_revision.title }} - - - - - - - - {% if urlpath.article.current_revision.deleted %} - - - - {% endif %} - - {% if urlpath.article.current_revision.locked %} - - - - {% endif %} - | - -- {{ urlpath.slug }} - | - -- {{ urlpath.article.current_revision.created|naturaltime }} - | -
- There are no articles at this level - | -
Article Preview
-- {{ field.help_text|safe }} -
- {% endif %} -
- {% for error in field.errors %}
- {{ error }}
- {% endfor %}
-
- {{ field.help_text|safe }} -
- {% endif %} -
- {% for error in field.errors %}
- {{ error }}
- {% endfor %}
-
- {{ field.help_text|safe }} -
- {% endif %} -
- {% for error in field.errors %}
- {{ error }}
- {% endfor %}
-
- {{ field.help_text|safe }} -
- {% endif %} -
- {% for error in field.errors %}
- {{ error }}
- {% endfor %}
-
- {{ field.help_text|safe }} -
- {% endif %} -
- {% for error in field.errors %}
- {{ error }}
- {% endfor %}
-
- {{ field.help_text|safe }} -
- {% endif %} -
- {% for error in field.errors %}
- {{ error }}
- {% endfor %}
-
- Click each revision to see a list of edited lines. Click the Preview - button to see how the article looked at this stage. At the bottom of - this page, you can change to a particular revision or merge an old - revision with the current one. -
- - {% include "wiki/includes/pagination.html" %} - - - - - -{% endblock %} diff --git a/pydis_site/templates/wiki/includes/article_menu.html b/pydis_site/templates/wiki/includes/article_menu.html deleted file mode 100644 index 966e8120..00000000 --- a/pydis_site/templates/wiki/includes/article_menu.html +++ /dev/null @@ -1,78 +0,0 @@ -{% load wiki_tags %} - -{% if article|can_write:user %} - {% with selected_tab as selected %} - - {% endwith %} -{% endif %} diff --git a/pydis_site/templates/wiki/includes/breadcrumbs.html b/pydis_site/templates/wiki/includes/breadcrumbs.html deleted file mode 100644 index 1b268e11..00000000 --- a/pydis_site/templates/wiki/includes/breadcrumbs.html +++ /dev/null @@ -1,95 +0,0 @@ -{% load wiki_tags %} - -{% if urlpath and article %} - -{% endif %} diff --git a/pydis_site/templates/wiki/includes/editor.html b/pydis_site/templates/wiki/includes/editor.html deleted file mode 100644 index 6eb6cd45..00000000 --- a/pydis_site/templates/wiki/includes/editor.html +++ /dev/null @@ -1,4 +0,0 @@ -{% load wiki_tags %} -{% include "wiki/includes/editormedia.html" %} - -{% wiki_form form %} diff --git a/pydis_site/templates/wiki/includes/editor_sidebar.html b/pydis_site/templates/wiki/includes/editor_sidebar.html deleted file mode 100644 index 45ac87a1..00000000 --- a/pydis_site/templates/wiki/includes/editor_sidebar.html +++ /dev/null @@ -1,38 +0,0 @@ -{% load static %} - -- {% if plugin.sidebar.icon_class %} - - {% if plugin.sidebar.icon_class == "fa-picture-o" %} - - {% else %} - - {% endif %} - - {% endif %} - - {{ plugin.sidebar.headline }} -
- -The following images are available for this article. Copy the markdown tag to directly refer to an image from the article text.
- -- - - - - Back to edit page - -
- - {% include "wiki/includes/pagination.html" %} - -{{ revision.get_filename|default:_("No filename") }} | -Tag | -Updated | -Size | -|||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- |
-
-
- [image:{{ image.id }}]
- |
-
- - {% include "wiki/includes/revision_info.html" %} - | - -
- {{ revision.get_size|filesizeformat }} {{ revision.width }}x{{ revision.height }} pixels - |
- |||||||||||
- History - | -||||||||||||||
-
|
-
- Purge image: Completely remove image file and all revisions -
- -s.
-{% endcomment %}{% with image.current_revision.imagerevision as revision %}{% spaceless %}
-
- {% empty %}
-
- {% endif %}
-
-
- Upload an image to replace the current one. -
- - -- Images are local to the article, and may only be used in the article they are - uploaded to. Images may be replaced by clicking the upload button next to it - above, but note that image revisions are kept and can be found on the - Manage Images page. -
- -
- To make use of images in an article, use the image
wiki tag in
- your Markdown. These tags take some arguments for customisation, and you can
- also include a caption on the next line, indented by four spaces. Note that
- the align
and size
options are optional.
-
- Syntax: [image:ID align:x size:y]
-
- The ID to use is the image ID shown next to the image in the list above. - You can click on the insert button if you'd like to insert an image into the - editor without manually typing the tag. -
- -- [image:1 align:left size:orig] - Python Discord logo -- -
Insert Image
-
- Type in something from another wiki page's title and auto-complete will help you create a tag for your wiki link. Tags for links look like this:
-
[Title of link](wiki:ArticleSlug)- -{# We do this to prevent accidental form submission - this isn't _really_ a form #} - - -
- You can link to another website simply by inserting an address example.com or http://example.com or by using the markdown syntax:
-
[Clickable text](http://example.com)- -{% addtoblock "js" %} - {% comment %} - So, for whatever reason, bulmahead doesn't have a LICENSE file. There is one in - the package.json, but that isn't a standard most projects adhere to - so I've - declined to include it within the project directly. - - The package.json states MIT - but there is no prose or license - text available for the project itself. - {% endcomment %} - - - - - -{% endaddtoblock %} diff --git a/pydis_site/templates/wiki/preview_inline.html b/pydis_site/templates/wiki/preview_inline.html deleted file mode 100644 index a01c963a..00000000 --- a/pydis_site/templates/wiki/preview_inline.html +++ /dev/null @@ -1,73 +0,0 @@ -{% extends "wiki/base.html" %} -{% load sekizai_tags %} -{% load static %} -{% load wiki_tags %} - -{# We make these empty so they don't appear in the preview #} -{% block site_navbar %}{% endblock %} -{% block site_footer %}{% endblock %} -{% block wiki_breadcrumbs %}{% endblock %} - -{% block wiki_body %} - {% if revision %} -
Restoring to this revision will mark the article as deleted.
-Title | -Last modified | -
---|---|
- No articles were found for that search query. - | -
This article is currently locked for editing.
- {% endif %} - --{{ article.current_revision.content }} --{% endblock %} -- cgit v1.2.3 From d6954d6be692592bf08409fc9745ee6273beb7c1 Mon Sep 17 00:00:00 2001 From: Leon Sandøy