evennia/evennia/web/admin/comms.py
2021-05-19 20:33:33 +02:00

230 lines
6.2 KiB
Python

"""
This defines how Comm models are displayed in the web admin interface.
"""
from django import forms
from django.contrib import admin
from evennia.comms.models import ChannelDB, Msg
from django.conf import settings
from .attributes import AttributeInline
from .tags import TagInline
class MsgTagInline(TagInline):
"""
Inline display for Msg-tags.
"""
model = Msg.db_tags.through
related_field = "msg"
class MsgForm(forms.ModelForm):
"""
Custom Msg form.
"""
class Meta:
models = Msg
fields = "__all__"
db_header = forms.CharField(
label="Header",
required=False,
widget=forms.Textarea(attrs={"cols": "100", "rows": "2"}),
help_text="Optional header for the message; it could be a title or "
"metadata depending on msg-use."
)
db_lock_storage = forms.CharField(
label="Locks",
required=False,
widget=forms.Textarea(attrs={"cols": "100", "rows": "2"}),
help_text="In-game lock definition string. If not given, defaults will be used. "
"This string should be on the form "
"<i>type:lockfunction(args);type2:lockfunction2(args);...",
)
@admin.register(Msg)
class MsgAdmin(admin.ModelAdmin):
"""
Defines display for Msg objects
"""
list_display = (
"id",
"db_date_created",
"sender",
"receiver",
"start_of_message"
)
list_display_links = ("id", "db_date_created", "start_of_message")
inlines = [MsgTagInline]
form = MsgForm
ordering = ["db_date_created", ]
# readonly_fields = ['db_message', 'db_sender', 'db_receivers', 'db_channels']
search_fields = ["id", "^db_date_created", "^db_message"]
readonly_fields = ["db_date_created"]
save_as = True
save_on_top = True
list_select_related = True
raw_id_fields = (
"db_date_created", "db_sender_accounts",
"db_sender_objects", "db_sender_scripts",
"db_receivers_accounts", "db_receivers_objects",
"db_receivers_scripts", "db_hide_from_accounts",
"db_hide_from_objects")
fieldsets = (
(
None,
{
"fields": (
("db_sender_accounts", "db_sender_objects", "db_sender_scripts", "db_sender_external"),
("db_receivers_accounts", "db_receivers_objects", "db_receivers_scripts", "db_receiver_external"),
("db_hide_from_accounts", "db_hide_from_objects"),
"db_header",
"db_message"
)
},
),
)
def sender(self, obj):
senders = [o for o in obj.senders if o]
if senders:
return senders[0]
sender.help_text = "If multiple, only the first is shown."
def receiver(self, obj):
receivers = [o for o in obj.receivers if o]
if receivers:
return receivers[0]
receiver.help_text = "If multiple, only the first is shown."
def start_of_message(self, obj):
crop_length = 50
if obj.db_message:
msg = obj.db_message
if len(msg) > (crop_length - 5):
msg = msg[:50] + "[...]"
return msg
class ChannelAttributeInline(AttributeInline):
"""
Inline display of Channel Attribute - experimental
"""
model = ChannelDB.db_attributes.through
related_field = "channeldb"
class ChannelTagInline(TagInline):
"""
Inline display of Channel Tags - experimental
"""
model = ChannelDB.db_tags.through
related_field = "channeldb"
class ChannelForm(forms.ModelForm):
"""
Form for accessing channels.
"""
class Meta:
model = ChannelDB
fields = "__all__"
db_lock_storage = forms.CharField(
label="Locks",
required=False,
widget=forms.Textarea(attrs={"cols": "100", "rows": "2"}),
help_text="In-game lock definition string. If not given, defaults will be used. "
"This string should be on the form "
"<i>type:lockfunction(args);type2:lockfunction2(args);...",
)
@admin.register(ChannelDB)
class ChannelAdmin(admin.ModelAdmin):
"""
Defines display for Channel objects
"""
inlines = [ChannelTagInline, ChannelAttributeInline]
form = ChannelForm
list_display = ("id", "db_key", "no_of_subscribers", "db_lock_storage")
list_display_links = ("id", "db_key")
ordering = ["db_key"]
search_fields = ["id", "db_key", "db_tags__db_key"]
save_as = True
save_on_top = True
list_select_related = True
raw_id_fields = ("db_object_subscriptions", "db_account_subscriptions")
fieldsets = (
(
None,
{
"fields": (
("db_key",),
"db_lock_storage",
"db_account_subscriptions",
"db_object_subscriptions",
)
},
),
)
def subscriptions(self, obj):
"""
Helper method to get subs from a channel.
Args:
obj (Channel): The channel to get subs from.
"""
return ", ".join([str(sub) for sub in obj.subscriptions.all()])
def no_of_subscribers(self, obj):
"""
Get number of subs for a a channel .
Args:
obj (Channel): The channel to get subs from.
"""
return sum(1 for sub in obj.subscriptions.all())
def save_model(self, request, obj, form, change):
"""
Model-save hook.
Args:
request (Request): Incoming request.
obj (Object): Database object.
form (Form): Form instance.
change (bool): If this is a change or a new object.
"""
obj.save()
if not change:
# adding a new object
# have to call init with typeclass passed to it
obj.set_class_from_typeclass(typeclass_path=settings.BASE_CHANNEL_TYPECLASS)
obj.at_init()
def response_add(self, request, obj, post_url_continue=None):
from django.http import HttpResponseRedirect
from django.urls import reverse
return HttpResponseRedirect(reverse("admin:comms_channeldb_change", args=[obj.id]))