Made all unit tests pass
This commit is contained in:
parent
844b04adbb
commit
aa48593a40
10 changed files with 148 additions and 110 deletions
|
|
@ -258,12 +258,12 @@ def prototype_from_object(obj):
|
||||||
aliases = obj.aliases.get(return_list=True)
|
aliases = obj.aliases.get(return_list=True)
|
||||||
if aliases:
|
if aliases:
|
||||||
prot['aliases'] = aliases
|
prot['aliases'] = aliases
|
||||||
tags = [(tag.db_key, tag.db_category, tag.db_data)
|
tags = sorted([(tag.db_key, tag.db_category, tag.db_data)
|
||||||
for tag in obj.tags.all(return_objs=True)]
|
for tag in obj.tags.all(return_objs=True)])
|
||||||
if tags:
|
if tags:
|
||||||
prot['tags'] = tags
|
prot['tags'] = tags
|
||||||
attrs = [(attr.key, attr.value, attr.category, ';'.join(attr.locks.all()))
|
attrs = sorted([(attr.key, attr.value, attr.category, ';'.join(attr.locks.all()))
|
||||||
for attr in obj.attributes.all()]
|
for attr in obj.attributes.all()])
|
||||||
if attrs:
|
if attrs:
|
||||||
prot['attrs'] = attrs
|
prot['attrs'] = attrs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,9 @@ class TestUtils(EvenniaTest):
|
||||||
|
|
||||||
self.assertEqual(obj_prototype,
|
self.assertEqual(obj_prototype,
|
||||||
{'aliases': ['foo'],
|
{'aliases': ['foo'],
|
||||||
'attrs': [('oldtest', 'to_keep', None, ''),
|
'attrs': [('desc', 'changed desc', None, ''),
|
||||||
('test', 'testval', None, ''),
|
('oldtest', 'to_keep', None, ''),
|
||||||
('desc', 'changed desc', None, '')],
|
('test', 'testval', None, '')],
|
||||||
'key': 'Obj',
|
'key': 'Obj',
|
||||||
'home': '#1',
|
'home': '#1',
|
||||||
'location': '#1',
|
'location': '#1',
|
||||||
|
|
@ -213,9 +213,9 @@ class TestUtils(EvenniaTest):
|
||||||
self.assertEqual(count, 1)
|
self.assertEqual(count, 1)
|
||||||
|
|
||||||
new_prot = spawner.prototype_from_object(self.obj1)
|
new_prot = spawner.prototype_from_object(self.obj1)
|
||||||
self.assertEqual({'attrs': [('oldtest', 'to_keep', None, ''),
|
self.assertEqual({'attrs': [('fooattr', 'fooattrval', None, ''),
|
||||||
('fooattr', 'fooattrval', None, ''),
|
|
||||||
('new', 'new_val', None, ''),
|
('new', 'new_val', None, ''),
|
||||||
|
('oldtest', 'to_keep', None, ''),
|
||||||
('test', 'testval_changed', None, '')],
|
('test', 'testval_changed', None, '')],
|
||||||
'home': Something,
|
'home': Something,
|
||||||
'key': 'Obj',
|
'key': 'Obj',
|
||||||
|
|
|
||||||
|
|
@ -1401,7 +1401,7 @@ def create_superuser():
|
||||||
"""
|
"""
|
||||||
print(
|
print(
|
||||||
"\nCreate a superuser below. The superuser is Account #1, the 'owner' "
|
"\nCreate a superuser below. The superuser is Account #1, the 'owner' "
|
||||||
"account of the server.\n")
|
"account of the server. Email is optional and can be empty.\n")
|
||||||
django.core.management.call_command("createsuperuser", interactive=True)
|
django.core.management.call_command("createsuperuser", interactive=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,20 +114,20 @@ class TestTelnet(TwistedTestCase):
|
||||||
self.assertEqual(self.proto.protocol_flags['SCREENWIDTH'], {0: DEFAULT_WIDTH})
|
self.assertEqual(self.proto.protocol_flags['SCREENWIDTH'], {0: DEFAULT_WIDTH})
|
||||||
self.assertEqual(self.proto.protocol_flags['SCREENHEIGHT'], {0: DEFAULT_HEIGHT})
|
self.assertEqual(self.proto.protocol_flags['SCREENHEIGHT'], {0: DEFAULT_HEIGHT})
|
||||||
self.proto.dataReceived(IAC + WILL + NAWS)
|
self.proto.dataReceived(IAC + WILL + NAWS)
|
||||||
self.proto.dataReceived([IAC, SB, NAWS, '', 'x', '', 'd', IAC, SE])
|
self.proto.dataReceived(b"".join([IAC, SB, NAWS, b'', b'x', b'', b'd', IAC, SE]))
|
||||||
self.assertEqual(self.proto.protocol_flags['SCREENWIDTH'][0], 120)
|
self.assertEqual(self.proto.protocol_flags['SCREENWIDTH'][0], 78)
|
||||||
self.assertEqual(self.proto.protocol_flags['SCREENHEIGHT'][0], 100)
|
self.assertEqual(self.proto.protocol_flags['SCREENHEIGHT'][0], 45)
|
||||||
self.assertEqual(self.proto.handshakes, 6)
|
self.assertEqual(self.proto.handshakes, 6)
|
||||||
# test ttype
|
# test ttype
|
||||||
self.assertTrue(self.proto.protocol_flags["FORCEDENDLINE"])
|
self.assertTrue(self.proto.protocol_flags["FORCEDENDLINE"])
|
||||||
self.assertFalse(self.proto.protocol_flags["TTYPE"])
|
self.assertFalse(self.proto.protocol_flags["TTYPE"])
|
||||||
self.assertTrue(self.proto.protocol_flags["ANSI"])
|
self.assertTrue(self.proto.protocol_flags["ANSI"])
|
||||||
self.proto.dataReceived(IAC + WILL + TTYPE)
|
self.proto.dataReceived(IAC + WILL + TTYPE)
|
||||||
self.proto.dataReceived([IAC, SB, TTYPE, IS, "MUDLET", IAC, SE])
|
self.proto.dataReceived(b"".join([IAC, SB, TTYPE, IS, b"MUDLET", IAC, SE]))
|
||||||
self.assertTrue(self.proto.protocol_flags["XTERM256"])
|
self.assertTrue(self.proto.protocol_flags["XTERM256"])
|
||||||
self.assertEqual(self.proto.protocol_flags["CLIENTNAME"], "MUDLET")
|
self.assertEqual(self.proto.protocol_flags["CLIENTNAME"], "MUDLET")
|
||||||
self.proto.dataReceived([IAC, SB, TTYPE, IS, "XTERM", IAC, SE])
|
self.proto.dataReceived(b"".join([IAC, SB, TTYPE, IS, b"XTERM", IAC, SE]))
|
||||||
self.proto.dataReceived([IAC, SB, TTYPE, IS, "MTTS 137", IAC, SE])
|
self.proto.dataReceived(b"".join([IAC, SB, TTYPE, IS, b"MTTS 137", IAC, SE]))
|
||||||
self.assertEqual(self.proto.handshakes, 5)
|
self.assertEqual(self.proto.handshakes, 5)
|
||||||
# test mccp
|
# test mccp
|
||||||
self.proto.dataReceived(IAC + DONT + MCCP)
|
self.proto.dataReceived(IAC + DONT + MCCP)
|
||||||
|
|
@ -138,7 +138,7 @@ class TestTelnet(TwistedTestCase):
|
||||||
self.assertEqual(self.proto.handshakes, 3)
|
self.assertEqual(self.proto.handshakes, 3)
|
||||||
# test oob
|
# test oob
|
||||||
self.proto.dataReceived(IAC + DO + MSDP)
|
self.proto.dataReceived(IAC + DO + MSDP)
|
||||||
self.proto.dataReceived([IAC, SB, MSDP, MSDP_VAR, "LIST", MSDP_VAL, "COMMANDS", IAC, SE])
|
self.proto.dataReceived(b"".join([IAC, SB, MSDP, MSDP_VAR, b"LIST", MSDP_VAL, b"COMMANDS", IAC, SE]))
|
||||||
self.assertTrue(self.proto.protocol_flags['OOB'])
|
self.assertTrue(self.proto.protocol_flags['OOB'])
|
||||||
self.assertEqual(self.proto.handshakes, 2)
|
self.assertEqual(self.proto.handshakes, 2)
|
||||||
# test mxp
|
# test mxp
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,25 @@ from evennia.utils.test_resources import EvenniaTest
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class TestAttributes(EvenniaTest):
|
||||||
|
def test_attrhandler(self):
|
||||||
|
key = 'testattr'
|
||||||
|
value = 'test attr value '
|
||||||
|
self.obj1.attributes.add(key, value)
|
||||||
|
self.assertEqual(self.obj1.attributes.get(key), value)
|
||||||
|
self.obj1.db.testattr = value
|
||||||
|
self.assertEqual(self.obj1.db.testattr, value)
|
||||||
|
|
||||||
|
def test_weird_text_save(self):
|
||||||
|
"test 'weird' text type (different in py2 vs py3)"
|
||||||
|
from django.utils.safestring import SafeText
|
||||||
|
key = 'test attr 2'
|
||||||
|
value = SafeText('test attr value 2')
|
||||||
|
self.obj1.attributes.add(key, value)
|
||||||
|
self.assertEqual(self.obj1.attributes.get(key), value)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestTypedObjectManager(EvenniaTest):
|
class TestTypedObjectManager(EvenniaTest):
|
||||||
def _manager(self, methodname, *args, **kwargs):
|
def _manager(self, methodname, *args, **kwargs):
|
||||||
return list(getattr(self.obj1.__class__.objects, methodname)(*args, **kwargs))
|
return list(getattr(self.obj1.__class__.objects, methodname)(*args, **kwargs))
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ except ImportError:
|
||||||
from pickle import dumps, loads
|
from pickle import dumps, loads
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.utils.safestring import SafeString, SafeBytes
|
||||||
from evennia.utils.utils import to_str, uses_database, is_iter
|
from evennia.utils.utils import to_str, uses_database, is_iter
|
||||||
from evennia.utils import logger
|
from evennia.utils import logger
|
||||||
|
|
||||||
|
|
@ -521,7 +522,7 @@ def to_pickle(data):
|
||||||
def process_item(item):
|
def process_item(item):
|
||||||
"""Recursive processor and identification of data"""
|
"""Recursive processor and identification of data"""
|
||||||
dtype = type(item)
|
dtype = type(item)
|
||||||
if dtype in (str, int, float, bool):
|
if dtype in (str, int, float, bool, bytes, SafeString, SafeBytes):
|
||||||
return item
|
return item
|
||||||
elif dtype == tuple:
|
elif dtype == tuple:
|
||||||
return tuple(process_item(val) for val in item)
|
return tuple(process_item(val) for val in item)
|
||||||
|
|
@ -573,7 +574,7 @@ def from_pickle(data, db_obj=None):
|
||||||
def process_item(item):
|
def process_item(item):
|
||||||
"""Recursive processor and identification of data"""
|
"""Recursive processor and identification of data"""
|
||||||
dtype = type(item)
|
dtype = type(item)
|
||||||
if dtype in (str, int, float, bool):
|
if dtype in (str, int, float, bool, bytes, SafeString, SafeBytes):
|
||||||
return item
|
return item
|
||||||
elif _IS_PACKED_DBOBJ(item):
|
elif _IS_PACKED_DBOBJ(item):
|
||||||
# this must be checked before tuple
|
# this must be checked before tuple
|
||||||
|
|
@ -602,7 +603,7 @@ def from_pickle(data, db_obj=None):
|
||||||
def process_tree(item, parent):
|
def process_tree(item, parent):
|
||||||
"""Recursive processor, building a parent-tree from iterable data"""
|
"""Recursive processor, building a parent-tree from iterable data"""
|
||||||
dtype = type(item)
|
dtype = type(item)
|
||||||
if dtype in (str, int, float, bool):
|
if dtype in (str, int, float, bool, bytes, SafeString, SafeBytes):
|
||||||
return item
|
return item
|
||||||
elif _IS_PACKED_DBOBJ(item):
|
elif _IS_PACKED_DBOBJ(item):
|
||||||
# this must be checked before tuple
|
# this must be checked before tuple
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,10 @@ class TestEvForm(TestCase):
|
||||||
def test_form(self):
|
def test_form(self):
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
form1 = evform._test()
|
form1 = evform._test()
|
||||||
print("len(form1): {}".format(len(form1)))
|
|
||||||
form2 = evform._test()
|
form2 = evform._test()
|
||||||
print("len(form2): {}".format(len(form2)))
|
|
||||||
|
|
||||||
self.assertEqual(form1, form2)
|
self.assertEqual(form1, form2)
|
||||||
|
|
||||||
# self.assertEqual(form, "")
|
# self.assertEqual(form1, "")
|
||||||
# '.------------------------------------------------.\n'
|
# '.------------------------------------------------.\n'
|
||||||
# '| |\n'
|
# '| |\n'
|
||||||
# '| Name: \x1b[0m\x1b[1m\x1b[32mTom\x1b[1m\x1b[32m \x1b'
|
# '| Name: \x1b[0m\x1b[1m\x1b[32mTom\x1b[1m\x1b[32m \x1b'
|
||||||
|
|
|
||||||
|
|
@ -140,10 +140,12 @@ class CharacterForm(ObjectForm):
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fields pertaining to configurable attributes on the Character object.
|
# Fields pertaining to configurable attributes on the Character object.
|
||||||
desc = forms.CharField(label='Description', max_length=2048, required=False,
|
desc = forms.CharField(
|
||||||
|
label='Description', max_length=2048, required=False,
|
||||||
widget=forms.Textarea(attrs={'rows': 3}),
|
widget=forms.Textarea(attrs={'rows': 3}),
|
||||||
help_text="A brief description of your character.")
|
help_text="A brief description of your character.")
|
||||||
|
|
||||||
|
|
||||||
class CharacterUpdateForm(CharacterForm):
|
class CharacterUpdateForm(CharacterForm):
|
||||||
"""
|
"""
|
||||||
This is a Django form for updating Evennia Character objects.
|
This is a Django form for updating Evennia Character objects.
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,22 @@
|
||||||
|
"""
|
||||||
|
This file contains the generic, assorted views that don't fall under one of the other applications.
|
||||||
|
Views are django's way of processing e.g. html templates on the fly.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This file contains the generic, assorted views that don't fall under one of
|
|
||||||
the other applications. Views are django's way of processing e.g. html
|
|
||||||
templates on the fly.
|
|
||||||
|
|
||||||
"""
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.contrib.admin.sites import site
|
from django.contrib.admin.sites import site
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth import authenticate
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib.admin.views.decorators import staff_member_required
|
from django.contrib.admin.views.decorators import staff_member_required
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db.models.functions import Lower
|
from django.db.models.functions import Lower
|
||||||
from django.http import HttpResponseBadRequest, HttpResponseRedirect, Http404
|
from django.http import HttpResponseBadRequest, HttpResponseRedirect
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.views.generic import View, TemplateView, ListView, DetailView, FormView
|
from django.views.generic import TemplateView, ListView, DetailView
|
||||||
from django.views.generic.base import RedirectView
|
from django.views.generic.base import RedirectView
|
||||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||||
|
|
||||||
|
|
@ -26,15 +24,15 @@ from evennia import SESSION_HANDLER
|
||||||
from evennia.help.models import HelpEntry
|
from evennia.help.models import HelpEntry
|
||||||
from evennia.objects.models import ObjectDB
|
from evennia.objects.models import ObjectDB
|
||||||
from evennia.accounts.models import AccountDB
|
from evennia.accounts.models import AccountDB
|
||||||
from evennia.utils import class_from_module, logger
|
from evennia.utils import class_from_module
|
||||||
from evennia.utils.logger import tail_log_file
|
from evennia.utils.logger import tail_log_file
|
||||||
from evennia.web.website.forms import *
|
from evennia.web.website import forms as website_forms
|
||||||
|
|
||||||
from django.contrib.auth import login
|
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
|
||||||
_BASE_CHAR_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS
|
_BASE_CHAR_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS
|
||||||
|
|
||||||
|
|
||||||
def _gamestats():
|
def _gamestats():
|
||||||
# Some misc. configurable stuff.
|
# Some misc. configurable stuff.
|
||||||
# TODO: Move this to either SQL or settings.py based configuration.
|
# TODO: Move this to either SQL or settings.py based configuration.
|
||||||
|
|
@ -49,8 +47,10 @@ def _gamestats():
|
||||||
# nsess = len(AccountDB.objects.get_connected_accounts()) or "no one"
|
# nsess = len(AccountDB.objects.get_connected_accounts()) or "no one"
|
||||||
|
|
||||||
nobjs = ObjectDB.objects.all().count()
|
nobjs = ObjectDB.objects.all().count()
|
||||||
nrooms = ObjectDB.objects.filter(db_location__isnull=True).exclude(db_typeclass_path=_BASE_CHAR_TYPECLASS).count()
|
nrooms = ObjectDB.objects.filter(
|
||||||
nexits = ObjectDB.objects.filter(db_location__isnull=False, db_destination__isnull=False).count()
|
db_location__isnull=True).exclude(db_typeclass_path=_BASE_CHAR_TYPECLASS).count()
|
||||||
|
nexits = ObjectDB.objects.filter(
|
||||||
|
db_location__isnull=False, db_destination__isnull=False).count()
|
||||||
nchars = ObjectDB.objects.filter(db_typeclass_path=_BASE_CHAR_TYPECLASS).count()
|
nchars = ObjectDB.objects.filter(db_typeclass_path=_BASE_CHAR_TYPECLASS).count()
|
||||||
nothers = nobjs - nrooms - nchars - nexits
|
nothers = nobjs - nrooms - nchars - nexits
|
||||||
|
|
||||||
|
|
@ -99,6 +99,7 @@ def admin_wrapper(request):
|
||||||
"""
|
"""
|
||||||
return staff_member_required(site.index)(request)
|
return staff_member_required(site.index)(request)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Class-based views
|
# Class-based views
|
||||||
#
|
#
|
||||||
|
|
@ -237,6 +238,7 @@ class EvenniaDeleteView(DeleteView, TypeclassMixin):
|
||||||
# Makes sure the page has a sensible title.
|
# Makes sure the page has a sensible title.
|
||||||
return 'Delete %s' % self.typeclass._meta.verbose_name.title()
|
return 'Delete %s' % self.typeclass._meta.verbose_name.title()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Object views
|
# Object views
|
||||||
#
|
#
|
||||||
|
|
@ -336,7 +338,8 @@ class ObjectDetailView(EvenniaDetailView):
|
||||||
|
|
||||||
# Check if this object was requested in a valid manner
|
# Check if this object was requested in a valid manner
|
||||||
if slugify(obj.name) != self.kwargs.get(self.slug_url_kwarg):
|
if slugify(obj.name) != self.kwargs.get(self.slug_url_kwarg):
|
||||||
raise HttpResponseBadRequest(u"No %(verbose_name)s found matching the query" %
|
raise HttpResponseBadRequest(
|
||||||
|
u"No %(verbose_name)s found matching the query" %
|
||||||
{'verbose_name': queryset.model._meta.verbose_name})
|
{'verbose_name': queryset.model._meta.verbose_name})
|
||||||
|
|
||||||
# Check if the requestor account has permissions to access object
|
# Check if the requestor account has permissions to access object
|
||||||
|
|
@ -430,7 +433,8 @@ class ObjectUpdateView(LoginRequiredMixin, ObjectDetailView, EvenniaUpdateView):
|
||||||
object detail page so the user can see their changes reflected.
|
object detail page so the user can see their changes reflected.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.success_url: return self.success_url
|
if self.success_url:
|
||||||
|
return self.success_url
|
||||||
return self.object.web_get_detail_url()
|
return self.object.web_get_detail_url()
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
|
@ -448,10 +452,10 @@ class ObjectUpdateView(LoginRequiredMixin, ObjectDetailView, EvenniaUpdateView):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
|
|
||||||
# Get attributes
|
# Get attributes
|
||||||
data = {k:getattr(obj.db, k, '') for k in self.form_class.base_fields}
|
data = {k: getattr(obj.db, k, '') for k in self.form_class.base_fields}
|
||||||
|
|
||||||
# Get model fields
|
# Get model fields
|
||||||
data.update({k:getattr(obj, k, '') for k in self.form_class.Meta.fields})
|
data.update({k: getattr(obj, k, '') for k in self.form_class.Meta.fields})
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
@ -471,17 +475,18 @@ class ObjectUpdateView(LoginRequiredMixin, ObjectDetailView, EvenniaUpdateView):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Get the attributes after they've been cleaned and validated
|
# Get the attributes after they've been cleaned and validated
|
||||||
data = {k:v for k,v in form.cleaned_data.items() if k not in self.form_class.Meta.fields}
|
data = {k: v for k, v in form.cleaned_data.items() if k not in self.form_class.Meta.fields}
|
||||||
|
|
||||||
# Update the object attributes
|
# Update the object attributes
|
||||||
for key, value in data.items():
|
for key, value in data.items():
|
||||||
setattr(self.object.db, key, value)
|
self.object.attributes.add(key, value)
|
||||||
messages.success(self.request, "Successfully updated '%s' for %s." % (key, self.object))
|
messages.success(self.request, "Successfully updated '%s' for %s." % (key, self.object))
|
||||||
|
|
||||||
# Do not return super().form_valid; we don't want to update the model
|
# Do not return super().form_valid; we don't want to update the model
|
||||||
# instance, just its attributes.
|
# instance, just its attributes.
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
return HttpResponseRedirect(self.get_success_url())
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Account views
|
# Account views
|
||||||
#
|
#
|
||||||
|
|
@ -496,7 +501,7 @@ class AccountMixin(TypeclassMixin):
|
||||||
"""
|
"""
|
||||||
# -- Django constructs --
|
# -- Django constructs --
|
||||||
model = class_from_module(settings.BASE_ACCOUNT_TYPECLASS)
|
model = class_from_module(settings.BASE_ACCOUNT_TYPECLASS)
|
||||||
form_class = AccountForm
|
form_class = website_forms.AccountForm
|
||||||
|
|
||||||
|
|
||||||
class AccountCreateView(AccountMixin, EvenniaCreateView):
|
class AccountCreateView(AccountMixin, EvenniaCreateView):
|
||||||
|
|
@ -537,11 +542,13 @@ class AccountCreateView(AccountMixin, EvenniaCreateView):
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
# Inform user of success
|
# Inform user of success
|
||||||
messages.success(self.request, "Your account '%s' was successfully created! You may log in using it now." % account.name)
|
messages.success(self.request, "Your account '%s' was successfully created! "
|
||||||
|
"You may log in using it now." % account.name)
|
||||||
|
|
||||||
# Redirect the user to the login page
|
# Redirect the user to the login page
|
||||||
return HttpResponseRedirect(self.success_url)
|
return HttpResponseRedirect(self.success_url)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Character views
|
# Character views
|
||||||
#
|
#
|
||||||
|
|
@ -556,7 +563,7 @@ class CharacterMixin(TypeclassMixin):
|
||||||
"""
|
"""
|
||||||
# -- Django constructs --
|
# -- Django constructs --
|
||||||
model = class_from_module(settings.BASE_CHARACTER_TYPECLASS)
|
model = class_from_module(settings.BASE_CHARACTER_TYPECLASS)
|
||||||
form_class = CharacterForm
|
form_class = website_forms.CharacterForm
|
||||||
success_url = reverse_lazy('character-manage')
|
success_url = reverse_lazy('character-manage')
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
|
@ -608,7 +615,8 @@ class CharacterListView(LoginRequiredMixin, CharacterMixin, ListView):
|
||||||
|
|
||||||
# Return a queryset consisting of characters the user is allowed to
|
# Return a queryset consisting of characters the user is allowed to
|
||||||
# see.
|
# see.
|
||||||
ids = [obj.id for obj in self.typeclass.objects.all() if obj.access(account, self.access_type)]
|
ids = [obj.id for obj in self.typeclass.objects.all()
|
||||||
|
if obj.access(account, self.access_type)]
|
||||||
|
|
||||||
return self.typeclass.objects.filter(id__in=ids).order_by(Lower('db_key'))
|
return self.typeclass.objects.filter(id__in=ids).order_by(Lower('db_key'))
|
||||||
|
|
||||||
|
|
@ -637,7 +645,7 @@ class CharacterPuppetView(LoginRequiredMixin, CharacterMixin, RedirectView, Obje
|
||||||
char = self.get_object()
|
char = self.get_object()
|
||||||
|
|
||||||
# Get the page the user came from
|
# Get the page the user came from
|
||||||
next = self.request.GET.get('next', self.success_url)
|
next_page = self.request.GET.get('next', self.success_url)
|
||||||
|
|
||||||
if char:
|
if char:
|
||||||
# If the account owns the char, store the ID of the char in the
|
# If the account owns the char, store the ID of the char in the
|
||||||
|
|
@ -650,7 +658,7 @@ class CharacterPuppetView(LoginRequiredMixin, CharacterMixin, RedirectView, Obje
|
||||||
self.request.session['puppet'] = None
|
self.request.session['puppet'] = None
|
||||||
messages.error(self.request, "You cannot become '%s'." % char)
|
messages.error(self.request, "You cannot become '%s'." % char)
|
||||||
|
|
||||||
return next
|
return next_page
|
||||||
|
|
||||||
|
|
||||||
class CharacterManageView(LoginRequiredMixin, CharacterMixin, ListView):
|
class CharacterManageView(LoginRequiredMixin, CharacterMixin, ListView):
|
||||||
|
|
@ -674,7 +682,7 @@ class CharacterUpdateView(CharacterMixin, ObjectUpdateView):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# -- Django constructs --
|
# -- Django constructs --
|
||||||
form_class = CharacterUpdateForm
|
form_class = website_forms.CharacterUpdateForm
|
||||||
template_name = 'website/character_form.html'
|
template_name = 'website/character_form.html'
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -705,7 +713,8 @@ class CharacterDetailView(CharacterMixin, ObjectDetailView):
|
||||||
|
|
||||||
# Return a queryset consisting of characters the user is allowed to
|
# Return a queryset consisting of characters the user is allowed to
|
||||||
# see.
|
# see.
|
||||||
ids = [obj.id for obj in self.typeclass.objects.all() if obj.access(account, self.access_type)]
|
ids = [obj.id for obj in self.typeclass.objects.all()
|
||||||
|
if obj.access(account, self.access_type)]
|
||||||
|
|
||||||
return self.typeclass.objects.filter(id__in=ids).order_by(Lower('db_key'))
|
return self.typeclass.objects.filter(id__in=ids).order_by(Lower('db_key'))
|
||||||
|
|
||||||
|
|
@ -746,7 +755,6 @@ class CharacterCreateView(CharacterMixin, ObjectCreateView):
|
||||||
self.attributes = {k: form.cleaned_data[k] for k in form.cleaned_data.keys()}
|
self.attributes = {k: form.cleaned_data[k] for k in form.cleaned_data.keys()}
|
||||||
charname = self.attributes.pop('db_key')
|
charname = self.attributes.pop('db_key')
|
||||||
description = self.attributes.pop('desc')
|
description = self.attributes.pop('desc')
|
||||||
|
|
||||||
# Create a character
|
# Create a character
|
||||||
character, errors = self.typeclass.create(charname, account, description=description)
|
character, errors = self.typeclass.create(charname, account, description=description)
|
||||||
|
|
||||||
|
|
@ -756,7 +764,7 @@ class CharacterCreateView(CharacterMixin, ObjectCreateView):
|
||||||
|
|
||||||
if character:
|
if character:
|
||||||
# Assign attributes from form
|
# Assign attributes from form
|
||||||
for key,value in self.attributes.items():
|
for key, value in self.attributes.items():
|
||||||
setattr(character.db, key, value)
|
setattr(character.db, key, value)
|
||||||
|
|
||||||
# Return the user to the character management page, unless overridden
|
# Return the user to the character management page, unless overridden
|
||||||
|
|
@ -768,6 +776,7 @@ class CharacterCreateView(CharacterMixin, ObjectCreateView):
|
||||||
messages.error(self.request, "Your character could not be created.")
|
messages.error(self.request, "Your character could not be created.")
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Channel views
|
# Channel views
|
||||||
#
|
#
|
||||||
|
|
@ -881,12 +890,14 @@ class ChannelDetailView(ChannelMixin, ObjectDetailView):
|
||||||
context = super(ChannelDetailView, self).get_context_data(**kwargs)
|
context = super(ChannelDetailView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
# Get the filename this Channel is recording to
|
# Get the filename this Channel is recording to
|
||||||
filename = self.object.attributes.get("log_file", default="channel_%s.log" % self.object.key)
|
filename = self.object.attributes.get(
|
||||||
|
"log_file", default="channel_%s.log" % self.object.key)
|
||||||
|
|
||||||
# Split log entries so we can filter by time
|
# Split log entries so we can filter by time
|
||||||
bucket = []
|
bucket = []
|
||||||
for log in (x.strip() for x in tail_log_file(filename, 0, self.max_num_lines)):
|
for log in (x.strip() for x in tail_log_file(filename, 0, self.max_num_lines)):
|
||||||
if not log: continue
|
if not log:
|
||||||
|
continue
|
||||||
time, msg = log.split(' [-] ')
|
time, msg = log.split(' [-] ')
|
||||||
time_key = time.split(':')[0]
|
time_key = time.split(':')[0]
|
||||||
|
|
||||||
|
|
@ -904,7 +915,6 @@ class ChannelDetailView(ChannelMixin, ObjectDetailView):
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
"""
|
"""
|
||||||
Override of Django hook that retrieves an object by slugified channel
|
Override of Django hook that retrieves an object by slugified channel
|
||||||
|
|
@ -924,7 +934,8 @@ class ChannelDetailView(ChannelMixin, ObjectDetailView):
|
||||||
|
|
||||||
# Check if this object was requested in a valid manner
|
# Check if this object was requested in a valid manner
|
||||||
if not obj:
|
if not obj:
|
||||||
raise HttpResponseBadRequest(u"No %(verbose_name)s found matching the query" %
|
raise HttpResponseBadRequest(
|
||||||
|
u"No %(verbose_name)s found matching the query" %
|
||||||
{'verbose_name': queryset.model._meta.verbose_name})
|
{'verbose_name': queryset.model._meta.verbose_name})
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
@ -976,6 +987,7 @@ class HelpMixin(TypeclassMixin):
|
||||||
|
|
||||||
return filtered
|
return filtered
|
||||||
|
|
||||||
|
|
||||||
class HelpListView(HelpMixin, ListView):
|
class HelpListView(HelpMixin, ListView):
|
||||||
"""
|
"""
|
||||||
Returns a list of help entries that can be viewed by a user, authenticated
|
Returns a list of help entries that can be viewed by a user, authenticated
|
||||||
|
|
@ -989,6 +1001,7 @@ class HelpListView(HelpMixin, ListView):
|
||||||
# -- Evennia constructs --
|
# -- Evennia constructs --
|
||||||
page_title = "Help Index"
|
page_title = "Help Index"
|
||||||
|
|
||||||
|
|
||||||
class HelpDetailView(HelpMixin, EvenniaDetailView):
|
class HelpDetailView(HelpMixin, EvenniaDetailView):
|
||||||
"""
|
"""
|
||||||
Returns the detail page for a given help entry.
|
Returns the detail page for a given help entry.
|
||||||
|
|
@ -1012,7 +1025,8 @@ class HelpDetailView(HelpMixin, EvenniaDetailView):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
|
|
||||||
# Get queryset and filter out non-related categories
|
# Get queryset and filter out non-related categories
|
||||||
queryset = self.get_queryset().filter(db_help_category=obj.db_help_category).order_by(Lower('db_key'))
|
queryset = self.get_queryset().filter(
|
||||||
|
db_help_category=obj.db_help_category).order_by(Lower('db_key'))
|
||||||
context['topic_list'] = queryset
|
context['topic_list'] = queryset
|
||||||
|
|
||||||
# Find the index position of the given obj in the queryset
|
# Find the index position of the given obj in the queryset
|
||||||
|
|
@ -1025,12 +1039,14 @@ class HelpDetailView(HelpMixin, EvenniaDetailView):
|
||||||
try:
|
try:
|
||||||
assert i+1 <= len(objs) and objs[i+1] is not obj
|
assert i+1 <= len(objs) and objs[i+1] is not obj
|
||||||
context['topic_next'] = objs[i+1]
|
context['topic_next'] = objs[i+1]
|
||||||
except: context['topic_next'] = None
|
except:
|
||||||
|
context['topic_next'] = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
assert i-1 >= 0 and objs[i-1] is not obj
|
assert i-1 >= 0 and objs[i-1] is not obj
|
||||||
context['topic_previous'] = objs[i-1]
|
context['topic_previous'] = objs[i-1]
|
||||||
except: context['topic_previous'] = None
|
except:
|
||||||
|
context['topic_previous'] = None
|
||||||
|
|
||||||
# Format the help entry using HTML instead of newlines
|
# Format the help entry using HTML instead of newlines
|
||||||
text = obj.db_entrytext
|
text = obj.db_entrytext
|
||||||
|
|
@ -1057,11 +1073,14 @@ class HelpDetailView(HelpMixin, EvenniaDetailView):
|
||||||
# Find the object in the queryset
|
# Find the object in the queryset
|
||||||
category = slugify(self.kwargs.get('category', ''))
|
category = slugify(self.kwargs.get('category', ''))
|
||||||
topic = slugify(self.kwargs.get('topic', ''))
|
topic = slugify(self.kwargs.get('topic', ''))
|
||||||
obj = next((x for x in queryset if slugify(x.db_help_category)==category and slugify(x.db_key)==topic), None)
|
obj = next((x for x in queryset
|
||||||
|
if slugify(x.db_help_category) == category and
|
||||||
|
slugify(x.db_key) == topic), None)
|
||||||
|
|
||||||
# Check if this object was requested in a valid manner
|
# Check if this object was requested in a valid manner
|
||||||
if not obj:
|
if not obj:
|
||||||
raise HttpResponseBadRequest(u"No %(verbose_name)s found matching the query" %
|
raise HttpResponseBadRequest(
|
||||||
|
u"No %(verbose_name)s found matching the query" %
|
||||||
{'verbose_name': queryset.model._meta.verbose_name})
|
{'verbose_name': queryset.model._meta.verbose_name})
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue