Run black. Resolve circular import issues in components contrib.

This commit is contained in:
Griatch 2024-02-25 19:03:11 +01:00
parent 577f66c3ec
commit e5d07603ca
49 changed files with 202 additions and 122 deletions

View file

@ -198,7 +198,12 @@ def _init(portal_mode=False):
from .comms.models import ChannelDB, Msg from .comms.models import ChannelDB, Msg
from .locks import lockfuncs from .locks import lockfuncs
from .objects.models import ObjectDB from .objects.models import ObjectDB
from .objects.objects import DefaultCharacter, DefaultExit, DefaultObject, DefaultRoom from .objects.objects import (
DefaultCharacter,
DefaultExit,
DefaultObject,
DefaultRoom,
)
from .prototypes.spawner import spawn from .prototypes.spawner import spawn
from .scripts.models import ScriptDB from .scripts.models import ScriptDB
from .scripts.monitorhandler import MONITOR_HANDLER from .scripts.monitorhandler import MONITOR_HANDLER

View file

@ -15,13 +15,14 @@ import time
import typing import typing
from random import getrandbits from random import getrandbits
import evennia
from django.conf import settings from django.conf import settings
from django.contrib.auth import authenticate, password_validation from django.contrib.auth import authenticate, password_validation
from django.core.exceptions import ImproperlyConfigured, ValidationError from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.utils import timezone from django.utils import timezone
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import evennia
from evennia.accounts.manager import AccountManager from evennia.accounts.manager import AccountManager
from evennia.accounts.models import AccountDB from evennia.accounts.models import AccountDB
from evennia.commands.cmdsethandler import CmdSetHandler from evennia.commands.cmdsethandler import CmdSetHandler
@ -40,7 +41,13 @@ from evennia.typeclasses.attributes import ModelAttributeBackend, NickHandler
from evennia.typeclasses.models import TypeclassBase from evennia.typeclasses.models import TypeclassBase
from evennia.utils import class_from_module, create, logger from evennia.utils import class_from_module, create, logger
from evennia.utils.optionhandler import OptionHandler from evennia.utils.optionhandler import OptionHandler
from evennia.utils.utils import is_iter, lazy_property, make_iter, to_str, variable_from_module from evennia.utils.utils import (
is_iter,
lazy_property,
make_iter,
to_str,
variable_from_module,
)
__all__ = ("DefaultAccount", "DefaultGuest") __all__ = ("DefaultAccount", "DefaultGuest")

View file

@ -40,8 +40,8 @@ from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks, returnValue from twisted.internet.defer import inlineCallbacks, returnValue
from twisted.internet.task import deferLater from twisted.internet.task import deferLater
from evennia.commands.command import InterruptCommand
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet
from evennia.commands.command import InterruptCommand
from evennia.utils import logger, utils from evennia.utils import logger, utils
from evennia.utils.utils import string_suggestions from evennia.utils.utils import string_suggestions

View file

@ -10,7 +10,7 @@ from django.db.models import Max, Min, Q
import evennia import evennia
from evennia import InterruptCommand from evennia import InterruptCommand
from evennia.commands.cmdhandler import get_and_merge_cmdsets, generate_cmdset_providers from evennia.commands.cmdhandler import generate_cmdset_providers, get_and_merge_cmdsets
from evennia.locks.lockhandler import LockException from evennia.locks.lockhandler import LockException
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.prototypes import menus as olc_menus from evennia.prototypes import menus as olc_menus

View file

@ -13,9 +13,10 @@ import time
import traceback import traceback
import django import django
import evennia
import twisted import twisted
from django.conf import settings from django.conf import settings
import evennia
from evennia.accounts.models import AccountDB from evennia.accounts.models import AccountDB
from evennia.scripts.taskhandler import TaskHandlerTask from evennia.scripts.taskhandler import TaskHandlerTask
from evennia.utils import gametime, logger, search, utils from evennia.utils import gametime, logger, search, utils

View file

@ -14,10 +14,13 @@ main test suite started with
import datetime import datetime
from unittest.mock import MagicMock, Mock, patch from unittest.mock import MagicMock, Mock, patch
import evennia
from anything import Anything from anything import Anything
from django.conf import settings from django.conf import settings
from django.test import override_settings from django.test import override_settings
from parameterized import parameterized
from twisted.internet import task
import evennia
from evennia import ( from evennia import (
DefaultCharacter, DefaultCharacter,
DefaultExit, DefaultExit,
@ -29,7 +32,14 @@ from evennia import (
from evennia.commands import cmdparser from evennia.commands import cmdparser
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet
from evennia.commands.command import Command, InterruptCommand from evennia.commands.command import Command, InterruptCommand
from evennia.commands.default import account, admin, batchprocess, building, comms, general from evennia.commands.default import (
account,
admin,
batchprocess,
building,
comms,
general,
)
from evennia.commands.default import help as help_module from evennia.commands.default import help as help_module
from evennia.commands.default import syscommands, system, unloggedin from evennia.commands.default import syscommands, system, unloggedin
from evennia.commands.default.cmdset_character import CharacterCmdSet from evennia.commands.default.cmdset_character import CharacterCmdSet
@ -38,8 +48,6 @@ from evennia.prototypes import prototypes as protlib
from evennia.utils import create, gametime, utils from evennia.utils import create, gametime, utils
from evennia.utils.test_resources import BaseEvenniaCommandTest # noqa from evennia.utils.test_resources import BaseEvenniaCommandTest # noqa
from evennia.utils.test_resources import BaseEvenniaTest, EvenniaCommandTest from evennia.utils.test_resources import BaseEvenniaTest, EvenniaCommandTest
from parameterized import parameterized
from twisted.internet import task
# ------------------------------------------------------------ # ------------------------------------------------------------
# Command testing # Command testing
@ -1645,8 +1653,9 @@ class TestBuilding(BaseEvenniaCommandTest):
self.call( self.call(
building.CmdTeleport(), building.CmdTeleport(),
"Obj = Room2", "Obj = Room2",
"Obj(#{}) is leaving Room(#{}), heading for Room2(#{}).|Teleported Obj -> Room2." "Obj(#{}) is leaving Room(#{}), heading for Room2(#{}).|Teleported Obj -> Room2.".format(
.format(oid, rid, rid2), oid, rid, rid2
),
) )
self.call(building.CmdTeleport(), "NotFound = Room", "Could not find 'NotFound'.") self.call(building.CmdTeleport(), "NotFound = Room", "Could not find 'NotFound'.")
self.call( self.call(
@ -1768,8 +1777,7 @@ class TestBuilding(BaseEvenniaCommandTest):
self.call( self.call(
building.CmdSpawn(), building.CmdSpawn(),
"{'prototype_key':'GOBLIN', 'typeclass':'evennia.objects.objects.DefaultCharacter', " "{'prototype_key':'GOBLIN', 'typeclass':'evennia.objects.objects.DefaultCharacter', "
"'key':'goblin', 'location':'%s'}" "'key':'goblin', 'location':'%s'}" % spawnLoc.dbref,
% spawnLoc.dbref,
"Spawned goblin", "Spawned goblin",
) )
goblin = get_object(self, "goblin") goblin = get_object(self, "goblin")
@ -1817,8 +1825,7 @@ class TestBuilding(BaseEvenniaCommandTest):
self.call( self.call(
building.CmdSpawn(), building.CmdSpawn(),
"/noloc {'prototype_parent':'TESTBALL', 'key': 'Ball', 'prototype_key': 'foo'," "/noloc {'prototype_parent':'TESTBALL', 'key': 'Ball', 'prototype_key': 'foo',"
" 'location':'%s'}" " 'location':'%s'}" % spawnLoc.dbref,
% spawnLoc.dbref,
"Spawned Ball", "Spawned Ball",
) )
ball = get_object(self, "Ball") ball = get_object(self, "Ball")

View file

@ -6,8 +6,9 @@ import datetime
import re import re
from codecs import lookup as codecs_lookup from codecs import lookup as codecs_lookup
import evennia
from django.conf import settings from django.conf import settings
import evennia
from evennia.commands.cmdhandler import CMD_LOGINSTART from evennia.commands.cmdhandler import CMD_LOGINSTART
from evennia.comms.models import ChannelDB from evennia.comms.models import ChannelDB
from evennia.utils import class_from_module, create, gametime, logger, utils from evennia.utils import class_from_module, create, gametime, logger, utils

View file

@ -13,7 +13,7 @@ from evennia.comms.managers import ChannelManager
from evennia.comms.models import ChannelDB from evennia.comms.models import ChannelDB
from evennia.typeclasses.models import TypeclassBase from evennia.typeclasses.models import TypeclassBase
from evennia.utils import create, logger from evennia.utils import create, logger
from evennia.utils.utils import make_iter, inherits_from from evennia.utils.utils import inherits_from, make_iter
class DefaultChannel(ChannelDB, metaclass=TypeclassBase): class DefaultChannel(ChannelDB, metaclass=TypeclassBase):

View file

@ -126,6 +126,7 @@ from inspect import getfullargspec
from textwrap import dedent from textwrap import dedent
from django.conf import settings from django.conf import settings
from evennia import CmdSet, Command from evennia import CmdSet, Command
from evennia.commands import cmdhandler from evennia.commands import cmdhandler
from evennia.utils.ansi import strip_ansi from evennia.utils.ansi import strip_ansi

View file

@ -7,16 +7,8 @@ This helps writing isolated code and reusing it over multiple objects.
See the docs for more information. See the docs for more information.
""" """
from evennia.contrib.base_systems.components import exceptions from . import exceptions # noqa
from evennia.contrib.base_systems.components.listing import COMPONENT_LISTING, get_component_class from .component import Component # noqa
from evennia.contrib.base_systems.components.component import Component from .dbfield import DBField, NDBField, TagField # noqa
from evennia.contrib.base_systems.components.dbfield import ( from .holder import ComponentHolderMixin, ComponentProperty # noqa
DBField, from .listing import COMPONENT_LISTING, get_component_class # noqa
NDBField,
TagField
)
from evennia.contrib.base_systems.components.holder import (
ComponentHolderMixin,
ComponentProperty,
)

View file

@ -5,7 +5,9 @@ This file contains the base class to inherit for creating new components.
""" """
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet
from evennia.contrib.base_systems.components import COMPONENT_LISTING, exceptions
from . import exceptions
from .listing import COMPONENT_LISTING
class BaseComponent(type): class BaseComponent(type):
@ -13,6 +15,7 @@ class BaseComponent(type):
This is the metaclass for components, This is the metaclass for components,
responsible for registering components to the listing. responsible for registering components to the listing.
""" """
@classmethod @classmethod
def __new__(cls, *args): def __new__(cls, *args):
""" """
@ -45,7 +48,7 @@ class Component(metaclass=BaseComponent):
Each Component must supply the name, it is used as a slot name but also part of the attribute key. Each Component must supply the name, it is used as a slot name but also part of the attribute key.
""" """
__slots__ = ('host',) __slots__ = ("host",)
name = "" name = ""
slot = None slot = None

View file

@ -8,7 +8,7 @@ import typing
from evennia.typeclasses.attributes import AttributeProperty, NAttributeProperty from evennia.typeclasses.attributes import AttributeProperty, NAttributeProperty
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from evennia.contrib.base_systems.components import Component from .components import Component
class DBField(AttributeProperty): class DBField(AttributeProperty):
@ -21,7 +21,7 @@ class DBField(AttributeProperty):
def __init__(self, default=None, autocreate=False, **kwargs): def __init__(self, default=None, autocreate=False, **kwargs):
super().__init__(default=default, autocreate=autocreate, **kwargs) super().__init__(default=default, autocreate=autocreate, **kwargs)
def __set_name__(self, owner: 'Component', name): def __set_name__(self, owner: "Component", name):
""" """
Called when descriptor is first assigned to the class. Called when descriptor is first assigned to the class.
@ -61,7 +61,7 @@ class NDBField(NAttributeProperty):
It uses NAttributeProperty under the hood but prefixes the key with the component name. It uses NAttributeProperty under the hood but prefixes the key with the component name.
""" """
def __set_name__(self, owner: 'Component', name): def __set_name__(self, owner: "Component", name):
""" """
Called when descriptor is first assigned to the class. Called when descriptor is first assigned to the class.
@ -108,7 +108,7 @@ class TagField:
self._default = default self._default = default
self._enforce_single = enforce_single self._enforce_single = enforce_single
def __set_name__(self, owner: 'Component', name): def __set_name__(self, owner: "Component", name):
""" """
Called when TagField is first assigned to the class. Called when TagField is first assigned to the class.
It is called with the component class and the name of the field. It is called with the component class and the name of the field.

View file

@ -4,8 +4,9 @@ Components - ChrisLR 2022
This file contains the classes that allow a typeclass to use components. This file contains the classes that allow a typeclass to use components.
""" """
from evennia.contrib.base_systems import components from . import exceptions, signals
from evennia.contrib.base_systems.components import signals, exceptions, get_component_class from .component import Component
from .listing import get_component_class
class ComponentProperty: class ComponentProperty:
@ -62,7 +63,7 @@ class ComponentHandler:
self.host = host self.host = host
self._loaded_components = {} self._loaded_components = {}
def add(self, component: components.Component): def add(self, component: Component):
""" """
Method to add a Component to a host. Method to add a Component to a host.
It caches the loaded component and appends its name to the host's component name list. It caches the loaded component and appends its name to the host's component name list.
@ -92,11 +93,11 @@ class ComponentHandler:
name (str): The name of the component class to add. name (str): The name of the component class to add.
""" """
component_class = components.get_component_class(name) component_class = get_component_class(name)
component_instance = component_class.default_create(self.host) component_instance = component_class.default_create(self.host)
self.add(component_instance) self.add(component_instance)
def remove(self, component: components.Component): def remove(self, component: Component):
""" """
Method to remove a component instance from a host. Method to remove a component instance from a host.
It removes the component from the cache and listing. It removes the component from the cache and listing.
@ -109,9 +110,7 @@ class ComponentHandler:
name = component.name name = component.name
slot_name = component.get_component_slot() slot_name = component.get_component_slot()
if not self.has(slot_name): if not self.has(slot_name):
message = ( message = f"Cannot remove {name} from {self.host.name} as it is not registered."
f"Cannot remove {name} from {self.host.name} as it is not registered."
)
raise exceptions.ComponentIsNotRegistered(message) raise exceptions.ComponentIsNotRegistered(message)
for field in component.get_fields(): for field in component.get_fields():
@ -142,7 +141,7 @@ class ComponentHandler:
self.remove(instance) self.remove(instance)
def get(self, name: str) -> components.Component | None: def get(self, name: str) -> Component | None:
return self._loaded_components.get(name) return self._loaded_components.get(name)
def has(self, name: str) -> bool: def has(self, name: str) -> bool:
@ -167,7 +166,7 @@ class ComponentHandler:
return return
for component_name in component_names: for component_name in component_names:
component = components.get_component_class(component_name) component = get_component_class(component_name)
if component: if component:
component_instance = component.load(self.host) component_instance = component.load(self.host)
self._set_component(component_instance) self._set_component(component_instance)
@ -213,6 +212,7 @@ class ComponentHolderMixin:
All registered components are initialized on the typeclass. All registered components are initialized on the typeclass.
They will be of None value if not present in the class components or runtime components. They will be of None value if not present in the class components or runtime components.
""" """
def at_init(self): def at_init(self):
""" """
Method that initializes the ComponentHandler. Method that initializes the ComponentHandler.
@ -241,7 +241,7 @@ class ComponentHolderMixin:
setattr(self, "_signal_handler", signals.SignalsHandler(self)) setattr(self, "_signal_handler", signals.SignalsHandler(self))
class_components = self._get_class_components() class_components = self._get_class_components()
for component_name, values in class_components: for component_name, values in class_components:
component_class = components.get_component_class(component_name) component_class = get_component_class(component_name)
component = component_class.create(self, **values) component = component_class.create(self, **values)
self.components.add(component) self.components.add(component)

View file

@ -1,4 +1,4 @@
from evennia.contrib.base_systems.components import exceptions from . import exceptions
COMPONENT_LISTING = {} COMPONENT_LISTING = {}
@ -13,7 +13,7 @@ def get_component_class(name):
if component_class is None: if component_class is None:
message = ( message = (
f"Component with name {name} has not been found. " f"Component with name {name} has not been found. "
f"Make sure it has been imported before being used." "Make sure it has been imported before being used."
) )
raise exceptions.ComponentDoesNotExist(message) raise exceptions.ComponentDoesNotExist(message)

View file

@ -1,18 +1,13 @@
from evennia.contrib.base_systems.components import (
Component,
DBField,
TagField,
signals,
)
from evennia.contrib.base_systems.components.holder import (
ComponentHolderMixin,
ComponentProperty,
)
from evennia.contrib.base_systems.components.signals import as_listener
from evennia.objects.objects import DefaultCharacter from evennia.objects.objects import DefaultCharacter
from evennia.utils import create from evennia.utils import create
from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTest from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTest
from . import signals
from .component import Component
from .dbfield import DBField, TagField
from .holder import ComponentHolderMixin, ComponentProperty
from .signals import as_listener
class ComponentTestA(Component): class ComponentTestA(Component):
name = "test_a" name = "test_a"
@ -22,12 +17,12 @@ class ComponentTestA(Component):
class ShadowedComponentTestA(ComponentTestA): class ShadowedComponentTestA(ComponentTestA):
name = "shadowed_test_a" name = "shadowed_test_a"
slot = 'ic_a' slot = "ic_a"
class InheritedComponentTestA(ComponentTestA): class InheritedComponentTestA(ComponentTestA):
name = "inherited_test_a" name = "inherited_test_a"
slot = 'ic_a' slot = "ic_a"
my_other_int = DBField(default=2) my_other_int = DBField(default=2)
@ -68,7 +63,7 @@ class ShadowedCharacterMixin:
class CharacterMixinWithComponents: class CharacterMixinWithComponents:
ic_a = ComponentProperty("inherited_test_a", my_other_int=33) ic_a = ComponentProperty("inherited_test_a", my_other_int=33)
test_d = ComponentProperty('test_d') test_d = ComponentProperty("test_d")
class CharacterWithComponents( class CharacterWithComponents(
@ -247,9 +242,13 @@ class TestComponents(EvenniaTest):
test_b = self.char1.components.get("test_b") test_b = self.char1.components.get("test_b")
test_b.default_single_tag = "second value" test_b.default_single_tag = "second value"
self.assertTrue(self.char1.tags.has(key="second value", category="test_b::default_single_tag")) self.assertTrue(
self.char1.tags.has(key="second value", category="test_b::default_single_tag")
)
self.assertTrue(test_b.default_single_tag == "second value") self.assertTrue(test_b.default_single_tag == "second value")
self.assertFalse(self.char1.tags.has(key="first_value", category="test_b::default_single_tag")) self.assertFalse(
self.char1.tags.has(key="first_value", category="test_b::default_single_tag")
)
def test_component_tags_support_multiple_values_by_default(self): def test_component_tags_support_multiple_values_by_default(self):
test_b = self.char1.components.get("test_b") test_b = self.char1.components.get("test_b")
@ -257,9 +256,12 @@ class TestComponents(EvenniaTest):
test_b.multiple_tags = "second value" test_b.multiple_tags = "second value"
test_b.multiple_tags = "third value" test_b.multiple_tags = "third value"
self.assertTrue(all( self.assertTrue(
val in test_b.multiple_tags for val in ("first value", "second value", "third value") all(
)) val in test_b.multiple_tags
for val in ("first value", "second value", "third value")
)
)
self.assertTrue(self.char1.tags.has(key="first value", category="test_b::multiple_tags")) self.assertTrue(self.char1.tags.has(key="first value", category="test_b::multiple_tags"))
self.assertTrue(self.char1.tags.has(key="second value", category="test_b::multiple_tags")) self.assertTrue(self.char1.tags.has(key="second value", category="test_b::multiple_tags"))
self.assertTrue(self.char1.tags.has(key="third value", category="test_b::multiple_tags")) self.assertTrue(self.char1.tags.has(key="third value", category="test_b::multiple_tags"))

View file

@ -33,6 +33,7 @@ the module given by settings.CONNECTION_SCREEN_MODULE.
""" """
from django.conf import settings from django.conf import settings
from evennia.accounts.models import AccountDB from evennia.accounts.models import AccountDB
from evennia.commands.cmdhandler import CMD_LOGINSTART from evennia.commands.cmdhandler import CMD_LOGINSTART
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet

View file

@ -14,6 +14,7 @@ except ImportError:
import json import json
import mock import mock
from django.test import override_settings
from mock import MagicMock, Mock from mock import MagicMock, Mock
from twisted.internet.base import DelayedCall from twisted.internet.base import DelayedCall
from twisted.test import proto_helpers from twisted.test import proto_helpers
@ -22,11 +23,12 @@ import evennia
from evennia.server.portal.portalsessionhandler import PortalSessionHandler from evennia.server.portal.portalsessionhandler import PortalSessionHandler
from evennia.server.portal.service import EvenniaPortalService from evennia.server.portal.service import EvenniaPortalService
from evennia.utils.test_resources import BaseEvenniaTest from evennia.utils.test_resources import BaseEvenniaTest
from django.test import override_settings
class TestGodotWebSocketClient(BaseEvenniaTest): class TestGodotWebSocketClient(BaseEvenniaTest):
@override_settings(GODOT_CLIENT_WEBSOCKET_CLIENT_INTERFACE="127.0.0.1", GODOT_CLIENT_WEBSOCKET_PORT='8988') @override_settings(
GODOT_CLIENT_WEBSOCKET_CLIENT_INTERFACE="127.0.0.1", GODOT_CLIENT_WEBSOCKET_PORT="8988"
)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.portal = EvenniaPortalService() self.portal = EvenniaPortalService()
@ -34,7 +36,9 @@ class TestGodotWebSocketClient(BaseEvenniaTest):
self.amp_server_factory = AMPServerFactory(self.portal) self.amp_server_factory = AMPServerFactory(self.portal)
self.amp_server = self.amp_server_factory.buildProtocol("127.0.0.1") self.amp_server = self.amp_server_factory.buildProtocol("127.0.0.1")
start_plugin_services(self.portal) start_plugin_services(self.portal)
godot_ws_service = next(srv for srv in self.portal.services if srv.name.startswith('GodotWebSocket')) godot_ws_service = next(
srv for srv in self.portal.services if srv.name.startswith("GodotWebSocket")
)
factory = godot_ws_service.args[1] factory = godot_ws_service.args[1]
self.proto = factory.protocol() self.proto = factory.protocol()
@ -61,11 +65,15 @@ class TestGodotWebSocketClient(BaseEvenniaTest):
self.proto.sessionhandler.data_in.assert_called_with(self.proto, logged_in=[[], {}]) self.proto.sessionhandler.data_in.assert_called_with(self.proto, logged_in=[[], {}])
msg = json.dumps(["text", ("|rRed Text|n",), {}]).encode() msg = json.dumps(["text", ("|rRed Text|n",), {}]).encode()
self.proto.onMessage(msg, isBinary=False) self.proto.onMessage(msg, isBinary=False)
self.proto.sessionhandler.data_in.assert_called_with(self.proto, text=[["|rRed Text|n"], {}]) self.proto.sessionhandler.data_in.assert_called_with(
self.proto, text=[["|rRed Text|n"], {}]
)
@mock.patch("evennia.server.portal.portalsessionhandler.reactor", new=MagicMock()) @mock.patch("evennia.server.portal.portalsessionhandler.reactor", new=MagicMock())
def test_data_out(self): def test_data_out(self):
self.proto.onOpen() self.proto.onOpen()
self.proto.sendLine = MagicMock() self.proto.sendLine = MagicMock()
self.proto.sessionhandler.data_out(self.proto, text=[["|rRed Text|n"], {}]) self.proto.sessionhandler.data_out(self.proto, text=[["|rRed Text|n"], {}])
self.proto.sendLine.assert_called_with(json.dumps(["text", ["[color=#ff0000]Red Text[/color]"], {}])) self.proto.sendLine.assert_called_with(
json.dumps(["text", ["[color=#ff0000]Red Text[/color]"], {}])
)

View file

@ -21,9 +21,14 @@ called automatically when a new user connects.
""" """
from django.conf import settings from django.conf import settings
from evennia import CmdSet, Command, syscmdkeys from evennia import CmdSet, Command, syscmdkeys
from evennia.utils.evmenu import EvMenu from evennia.utils.evmenu import EvMenu
from evennia.utils.utils import callables_from_module, class_from_module, random_string_from_module from evennia.utils.utils import (
callables_from_module,
class_from_module,
random_string_from_module,
)
_CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE _CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
_GUEST_ENABLED = settings.GUEST_ENABLED _GUEST_ENABLED = settings.GUEST_ENABLED

View file

@ -333,13 +333,13 @@ class WildernessScript(DefaultScript):
# we will need to do special handling if the old room is a different location # we will need to do special handling if the old room is a different location
# check that here, so we only need to do it once # check that here, so we only need to do it once
if self == getattr(old_room, 'wilderness', None): if self == getattr(old_room, "wilderness", None):
# it is our own room # it is our own room
from_outside = False from_outside = False
else: else:
# it's from another wilderness, or no wilderness # it's from another wilderness, or no wilderness
from_outside = True from_outside = True
# check if we have a room at the new coordinates already # check if we have a room at the new coordinates already
room = self.db.rooms.get(new_coordinates) room = self.db.rooms.get(new_coordinates)

View file

@ -18,8 +18,9 @@ Use `evennia xyzgrid help` for usage help.
from os.path import join as pathjoin from os.path import join as pathjoin
import evennia
from django.conf import settings from django.conf import settings
import evennia
from evennia.contrib.grid.xyzgrid.xyzgrid import get_xyzgrid from evennia.contrib.grid.xyzgrid.xyzgrid import get_xyzgrid
from evennia.utils import ansi from evennia.utils import ansi

View file

@ -7,9 +7,10 @@ from random import randint
from unittest import mock from unittest import mock
from django.test import TestCase from django.test import TestCase
from evennia.utils.test_resources import BaseEvenniaCommandTest, BaseEvenniaTest
from parameterized import parameterized from parameterized import parameterized
from evennia.utils.test_resources import BaseEvenniaCommandTest, BaseEvenniaTest
from . import commands, xymap, xymap_legend, xyzgrid, xyzroom from . import commands, xymap, xymap_legend, xyzgrid, xyzroom
MAP1 = """ MAP1 = """

View file

@ -9,6 +9,7 @@ used as stand-alone XYZ-coordinate-aware rooms.
from django.conf import settings from django.conf import settings
from django.db.models import Q from django.db.models import Q
from evennia.objects.manager import ObjectManager from evennia.objects.manager import ObjectManager
from evennia.objects.objects import DefaultExit, DefaultRoom from evennia.objects.objects import DefaultExit, DefaultRoom

View file

@ -5,9 +5,10 @@ Unit tests for the LLM Client and npc.
from anything import Something from anything import Something
from django.test import override_settings from django.test import override_settings
from mock import Mock, patch
from evennia.utils.create import create_object from evennia.utils.create import create_object
from evennia.utils.test_resources import BaseEvenniaTestCase from evennia.utils.test_resources import BaseEvenniaTestCase
from mock import Mock, patch
from .llm_npc import LLMNPC from .llm_npc import LLMNPC

View file

@ -154,12 +154,18 @@ from string import punctuation
import inflect import inflect
from django.conf import settings from django.conf import settings
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet
from evennia.commands.command import Command from evennia.commands.command import Command
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.objects.objects import DefaultCharacter, DefaultObject from evennia.objects.objects import DefaultCharacter, DefaultObject
from evennia.utils import ansi, logger from evennia.utils import ansi, logger
from evennia.utils.utils import iter_to_str, lazy_property, make_iter, variable_from_module from evennia.utils.utils import (
iter_to_str,
lazy_property,
make_iter,
variable_from_module,
)
_INFLECT = inflect.engine() _INFLECT = inflect.engine()

View file

@ -5,6 +5,7 @@ Tests for RP system
import time import time
from anything import Anything from anything import Anything
from evennia import DefaultObject, create_object, default_cmds from evennia import DefaultObject, create_object, default_cmds
from evennia.commands.default.tests import BaseEvenniaCommandTest from evennia.commands.default.tests import BaseEvenniaCommandTest
from evennia.utils.test_resources import BaseEvenniaTest from evennia.utils.test_resources import BaseEvenniaTest

View file

@ -3,6 +3,7 @@ EvAdventure character generation.
""" """
from django.conf import settings from django.conf import settings
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.prototypes.spawner import spawn from evennia.prototypes.spawner import spawn
from evennia.utils.create import create_object from evennia.utils.create import create_object

View file

@ -3,13 +3,14 @@ Test tutorial_world/mob
""" """
from evennia.commands.default.tests import BaseEvenniaCommandTest
from evennia.utils.create import create_object
from evennia.utils.test_resources import BaseEvenniaTest, mockdeferLater, mockdelay
from mock import patch from mock import patch
from twisted.internet.base import DelayedCall from twisted.internet.base import DelayedCall
from twisted.trial.unittest import TestCase as TwistedTestCase from twisted.trial.unittest import TestCase as TwistedTestCase
from evennia.commands.default.tests import BaseEvenniaCommandTest
from evennia.utils.create import create_object
from evennia.utils.test_resources import BaseEvenniaTest, mockdeferLater, mockdelay
from . import mob from . import mob
from . import objects as tutobjects from . import objects as tutobjects
from . import rooms as tutrooms from . import rooms as tutrooms

View file

@ -6,6 +6,7 @@ import re
from django.conf import settings from django.conf import settings
from django.db.models import Q from django.db.models import Q
from django.db.models.fields import exceptions from django.db.models.fields import exceptions
from evennia.server import signals from evennia.server import signals
from evennia.typeclasses.managers import TypeclassManager, TypedObjectManager from evennia.typeclasses.managers import TypeclassManager, TypedObjectManager
from evennia.utils.utils import ( from evennia.utils.utils import (

View file

@ -11,10 +11,11 @@ import time
import typing import typing
from collections import defaultdict from collections import defaultdict
import evennia
import inflect import inflect
from django.conf import settings from django.conf import settings
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import evennia
from evennia.commands import cmdset from evennia.commands import cmdset
from evennia.commands.cmdsethandler import CmdSetHandler from evennia.commands.cmdsethandler import CmdSetHandler
from evennia.objects.manager import ObjectManager from evennia.objects.manager import ObjectManager

View file

@ -5,13 +5,14 @@ Module containing the task handler for Evennia deferred tasks, persistent or not
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pickle import PickleError from pickle import PickleError
from evennia.server.models import ServerConfig
from evennia.utils.dbserialize import dbserialize, dbunserialize
from evennia.utils.logger import log_err
from twisted.internet import reactor from twisted.internet import reactor
from twisted.internet.defer import CancelledError as DefCancelledError from twisted.internet.defer import CancelledError as DefCancelledError
from twisted.internet.task import deferLater from twisted.internet.task import deferLater
from evennia.server.models import ServerConfig
from evennia.utils.dbserialize import dbserialize, dbunserialize
from evennia.utils.logger import log_err
TASK_HANDLER = None TASK_HANDLER = None

View file

@ -6,6 +6,8 @@ Unit tests for the scripts package
from collections import defaultdict from collections import defaultdict
from unittest import TestCase, mock from unittest import TestCase, mock
from parameterized import parameterized
from evennia import DefaultScript from evennia import DefaultScript
from evennia.objects.objects import DefaultObject from evennia.objects.objects import DefaultObject
from evennia.scripts.manager import ScriptDBManager from evennia.scripts.manager import ScriptDBManager
@ -17,7 +19,6 @@ from evennia.scripts.tickerhandler import TickerHandler
from evennia.utils.create import create_script from evennia.utils.create import create_script
from evennia.utils.dbserialize import dbserialize from evennia.utils.dbserialize import dbserialize
from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTest from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTest
from parameterized import parameterized
class TestScript(BaseEvenniaTest): class TestScript(BaseEvenniaTest):

View file

@ -9,9 +9,10 @@ Everything starts at handle_setup()
import time import time
import evennia
from django.conf import settings from django.conf import settings
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import evennia
from evennia.accounts.models import AccountDB from evennia.accounts.models import AccountDB
from evennia.server.models import ServerConfig from evennia.server.models import ServerConfig
from evennia.utils import create, logger from evennia.utils import create, logger

View file

@ -425,7 +425,7 @@ def _on_monitor_change(**kwargs):
# the object as "db_value" with a separate "category" field. # the object as "db_value" with a separate "category" field.
if hasattr(obj, "db_category") and obj.db_category != None: if hasattr(obj, "db_category") and obj.db_category != None:
category = obj.db_category category = obj.db_category
fieldname = fieldname.replace("[{}]".format(obj.db_category), '') fieldname = fieldname.replace("[{}]".format(obj.db_category), "")
# the session may be None if the char quits and someone # the session may be None if the char quits and someone
# else then edits the object # else then edits the object
@ -435,9 +435,9 @@ def _on_monitor_change(**kwargs):
outputfunc_name: { outputfunc_name: {
"name": name, "name": name,
**({"category": category} if category is not None else {}), **({"category": category} if category is not None else {}),
"value": _GA(obj, fieldname) "value": _GA(obj, fieldname),
}
} }
}
session.msg(**callsign) session.msg(**callsign)

View file

@ -7,14 +7,15 @@ Sessionhandler for portal sessions.
import time import time
from collections import deque, namedtuple from collections import deque, namedtuple
import evennia
from django.conf import settings from django.conf import settings
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from twisted.internet import reactor
import evennia
from evennia.server.portal.amp import PCONN, PCONNSYNC, PDISCONN, PDISCONNALL from evennia.server.portal.amp import PCONN, PCONNSYNC, PDISCONN, PDISCONNALL
from evennia.server.sessionhandler import SessionHandler from evennia.server.sessionhandler import SessionHandler
from evennia.utils.logger import log_trace from evennia.utils.logger import log_trace
from evennia.utils.utils import class_from_module from evennia.utils.utils import class_from_module
from twisted.internet import reactor
# module import # module import
_MOD_IMPORT = None _MOD_IMPORT = None

View file

@ -34,9 +34,6 @@ except ImportError:
raise ImportError(_SSH_IMPORT_ERROR) raise ImportError(_SSH_IMPORT_ERROR)
from django.conf import settings from django.conf import settings
from evennia.accounts.models import AccountDB
from evennia.utils import ansi
from evennia.utils.utils import class_from_module, to_str
from twisted.conch import interfaces as iconch from twisted.conch import interfaces as iconch
from twisted.conch.insults import insults from twisted.conch.insults import insults
from twisted.conch.manhole import Manhole, recvline from twisted.conch.manhole import Manhole, recvline
@ -46,6 +43,10 @@ from twisted.conch.ssh.userauth import SSHUserAuthServer
from twisted.internet import defer, protocol from twisted.internet import defer, protocol
from twisted.python import components from twisted.python import components
from evennia.accounts.models import AccountDB
from evennia.utils import ansi
from evennia.utils.utils import class_from_module, to_str
_RE_N = re.compile(r"\|n$") _RE_N = re.compile(r"\|n$")
_RE_SCREENREADER_REGEX = re.compile( _RE_SCREENREADER_REGEX = re.compile(
r"%s" % settings.SCREENREADER_REGEX_STRIP, re.DOTALL + re.MULTILINE r"%s" % settings.SCREENREADER_REGEX_STRIP, re.DOTALL + re.MULTILINE

View file

@ -24,13 +24,14 @@ import time
from django.conf import settings from django.conf import settings
from django.utils.functional import Promise from django.utils.functional import Promise
from twisted.internet.task import LoopingCall
from twisted.web import resource, server
from evennia.server import session from evennia.server import session
from evennia.utils import utils from evennia.utils import utils
from evennia.utils.ansi import parse_ansi from evennia.utils.ansi import parse_ansi
from evennia.utils.text2html import parse_html from evennia.utils.text2html import parse_html
from evennia.utils.utils import class_from_module, ip_from_request, to_bytes from evennia.utils.utils import class_from_module, ip_from_request, to_bytes
from twisted.internet.task import LoopingCall
from twisted.web import resource, server
_CLIENT_SESSIONS = utils.mod_import(settings.SESSION_ENGINE).SessionStore _CLIENT_SESSIONS = utils.mod_import(settings.SESSION_ENGINE).SessionStore
_RE_SCREENREADER_REGEX = re.compile( _RE_SCREENREADER_REGEX = re.compile(
@ -362,7 +363,7 @@ class AjaxWebClient(resource.Resource):
sess.client = self sess.client = self
sess.init_session("ajax/comet", remote_addr, self.sessionhandler) sess.init_session("ajax/comet", remote_addr, self.sessionhandler)
sess.csessid = session_id+page_id sess.csessid = session_id + page_id
sess.browserstr = browserstr sess.browserstr = browserstr
csession = _CLIENT_SESSIONS(session_key=session_id) csession = _CLIENT_SESSIONS(session_key=session_id)
uid = csession and csession.get("webclient_authenticated_uid", False) uid = csession and csession.get("webclient_authenticated_uid", False)

View file

@ -10,10 +10,15 @@ import time
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
from evennia.commands.cmdsethandler import CmdSetHandler from evennia.commands.cmdsethandler import CmdSetHandler
from evennia.comms.models import ChannelDB from evennia.comms.models import ChannelDB
from evennia.scripts.monitorhandler import MONITOR_HANDLER from evennia.scripts.monitorhandler import MONITOR_HANDLER
from evennia.typeclasses.attributes import AttributeHandler, DbHolder, InMemoryAttributeBackend from evennia.typeclasses.attributes import (
AttributeHandler,
DbHolder,
InMemoryAttributeBackend,
)
from evennia.utils import logger from evennia.utils import logger
from evennia.utils.utils import class_from_module, lazy_property, make_iter from evennia.utils.utils import class_from_module, lazy_property, make_iter

View file

@ -7,19 +7,20 @@ import time
import traceback import traceback
import django import django
import evennia
from django.conf import settings from django.conf import settings
from django.db import connection from django.db import connection
from django.db.utils import OperationalError from django.db.utils import OperationalError
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from evennia.utils import logger
from evennia.utils.utils import get_evennia_version, make_iter, mod_import
from twisted.application import internet from twisted.application import internet
from twisted.application.service import MultiService from twisted.application.service import MultiService
from twisted.internet import defer, reactor from twisted.internet import defer, reactor
from twisted.internet.defer import Deferred from twisted.internet.defer import Deferred
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
import evennia
from evennia.utils import logger
from evennia.utils.utils import get_evennia_version, make_iter, mod_import
_SA = object.__setattr__ _SA = object.__setattr__

View file

@ -15,9 +15,10 @@ There are two similar but separate stores of sessions:
import time import time
from codecs import decode as codecs_decode from codecs import decode as codecs_decode
import evennia
from django.conf import settings from django.conf import settings
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import evennia
from evennia.commands.cmdhandler import CMD_LOGINSTART from evennia.commands.cmdhandler import CMD_LOGINSTART
from evennia.server.portal import amp from evennia.server.portal import amp
from evennia.server.signals import ( from evennia.server.signals import (
@ -27,7 +28,13 @@ from evennia.server.signals import (
SIGNAL_ACCOUNT_POST_LOGOUT, SIGNAL_ACCOUNT_POST_LOGOUT,
) )
from evennia.utils.logger import log_trace from evennia.utils.logger import log_trace
from evennia.utils.utils import callables_from_module, class_from_module, delay, is_iter, make_iter from evennia.utils.utils import (
callables_from_module,
class_from_module,
delay,
is_iter,
make_iter,
)
_FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED = settings.FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED _FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED = settings.FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED
_BROADCAST_SERVER_RESTART_MESSAGES = settings.BROADCAST_SERVER_RESTART_MESSAGES _BROADCAST_SERVER_RESTART_MESSAGES = settings.BROADCAST_SERVER_RESTART_MESSAGES

View file

@ -8,6 +8,7 @@ import unittest
from django.test import TestCase from django.test import TestCase
from django.test.runner import DiscoverRunner from django.test.runner import DiscoverRunner
from evennia.server.throttle import Throttle from evennia.server.throttle import Throttle
from evennia.utils.test_resources import BaseEvenniaTest from evennia.utils.test_resources import BaseEvenniaTest

View file

@ -4,10 +4,11 @@ Test the main server component
""" """
from unittest import TestCase from unittest import TestCase
import evennia
from django.test import override_settings from django.test import override_settings
from mock import DEFAULT, MagicMock, call, patch from mock import DEFAULT, MagicMock, call, patch
import evennia
@patch("evennia.server.service.LoopingCall", new=MagicMock()) @patch("evennia.server.service.LoopingCall", new=MagicMock())
class TestServer(TestCase): class TestServer(TestCase):

View file

@ -38,4 +38,3 @@ class EvenniaUsernameAvailabilityValidator:
raise ValidationError( raise ValidationError(
_("Sorry, that username is already taken."), code="evennia_username_taken" _("Sorry, that username is already taken."), code="evennia_username_taken"
) )

View file

@ -13,6 +13,7 @@ from collections import defaultdict
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from evennia.locks.lockfuncs import perm as perm_lockfunc from evennia.locks.lockfuncs import perm as perm_lockfunc
from evennia.utils.utils import make_iter, to_str from evennia.utils.utils import make_iter, to_str

View file

@ -286,13 +286,13 @@ from evennia.utils.evtable import EvColumn, EvTable
from evennia.utils.utils import ( from evennia.utils.utils import (
crop, crop,
dedent, dedent,
inherits_from,
is_iter, is_iter,
m_len, m_len,
make_iter, make_iter,
mod_import, mod_import,
pad, pad,
to_str, to_str,
inherits_from,
) )
# read from protocol NAWS later? # read from protocol NAWS later?
@ -1209,10 +1209,12 @@ class EvMenu:
# check if the caller is using a screenreader # check if the caller is using a screenreader
screenreader_mode = False screenreader_mode = False
if sessions := getattr(self.caller, 'sessions', None): if sessions := getattr(self.caller, "sessions", None):
screenreader_mode = any(sess.protocol_flags.get("SCREENREADER") for sess in sessions.all()) screenreader_mode = any(
sess.protocol_flags.get("SCREENREADER") for sess in sessions.all()
)
# the caller doesn't have a session; check it directly # the caller doesn't have a session; check it directly
elif hasattr(self.caller, 'protocol_flags'): elif hasattr(self.caller, "protocol_flags"):
screenreader_mode = self.caller.protocol_flags.get("SCREENREADER") screenreader_mode = self.caller.protocol_flags.get("SCREENREADER")
ncols = 1 if screenreader_mode else _MAX_TEXT_WIDTH // table_width_max ncols = 1 if screenreader_mode else _MAX_TEXT_WIDTH // table_width_max

View file

@ -36,11 +36,12 @@ the `caller.msg()` construct every time the page is updated.
---- ----
""" """
import evennia
from django.conf import settings from django.conf import settings
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import evennia
from evennia.commands import cmdhandler from evennia.commands import cmdhandler
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet
from evennia.commands.command import Command from evennia.commands.command import Command

View file

@ -26,21 +26,27 @@ import re
import sys import sys
import types import types
import evennia
from django.conf import settings from django.conf import settings
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
from mock import MagicMock, Mock, patch
from twisted.internet.defer import Deferred
import evennia
from evennia import settings_default from evennia import settings_default
from evennia.accounts.accounts import DefaultAccount from evennia.accounts.accounts import DefaultAccount
from evennia.commands.command import InterruptCommand from evennia.commands.command import InterruptCommand
from evennia.commands.default.muxcommand import MuxCommand from evennia.commands.default.muxcommand import MuxCommand
from evennia.objects.objects import DefaultCharacter, DefaultExit, DefaultObject, DefaultRoom from evennia.objects.objects import (
DefaultCharacter,
DefaultExit,
DefaultObject,
DefaultRoom,
)
from evennia.scripts.scripts import DefaultScript from evennia.scripts.scripts import DefaultScript
from evennia.server.serversession import ServerSession from evennia.server.serversession import ServerSession
from evennia.utils import ansi, create from evennia.utils import ansi, create
from evennia.utils.idmapper.models import flush_cache from evennia.utils.idmapper.models import flush_cache
from evennia.utils.utils import all_from_module, to_str from evennia.utils.utils import all_from_module, to_str
from mock import MagicMock, Mock, patch
from twisted.internet.defer import Deferred
_RE_STRIP_EVMENU = re.compile(r"^\+|-+\+|\+-+|--+|\|(?:\s|$)", re.MULTILINE) _RE_STRIP_EVMENU = re.compile(r"^\+|-+\+|\+-+|--+|\|(?:\s|$)", re.MULTILINE)

View file

@ -10,10 +10,11 @@ from ast import literal_eval
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
from evennia.utils import funcparser, test_resources
from parameterized import parameterized from parameterized import parameterized
from simpleeval import simple_eval from simpleeval import simple_eval
from evennia.utils import funcparser, test_resources
def _test_callable(*args, **kwargs): def _test_callable(*args, **kwargs):
kwargs.pop("funcparser", None) kwargs.pop("funcparser", None)

View file

@ -28,7 +28,6 @@ from os.path import join as osjoin
from string import punctuation from string import punctuation
from unicodedata import east_asian_width from unicodedata import east_asian_width
import evennia
from django.apps import apps from django.apps import apps
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError as DjangoValidationError from django.core.exceptions import ValidationError as DjangoValidationError
@ -36,12 +35,14 @@ from django.core.validators import validate_email as django_validate_email
from django.utils import timezone from django.utils import timezone
from django.utils.html import strip_tags from django.utils.html import strip_tags
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from evennia.utils import logger
from simpleeval import simple_eval from simpleeval import simple_eval
from twisted.internet import reactor, threads from twisted.internet import reactor, threads
from twisted.internet.defer import returnValue # noqa - used as import target from twisted.internet.defer import returnValue # noqa - used as import target
from twisted.internet.task import deferLater from twisted.internet.task import deferLater
import evennia
from evennia.utils import logger
_MULTIMATCH_TEMPLATE = settings.SEARCH_MULTIMATCH_TEMPLATE _MULTIMATCH_TEMPLATE = settings.SEARCH_MULTIMATCH_TEMPLATE
_EVENNIA_DIR = settings.EVENNIA_DIR _EVENNIA_DIR = settings.EVENNIA_DIR
_GAME_DIR = settings.GAME_DIR _GAME_DIR = settings.GAME_DIR

View file

@ -1,7 +1,7 @@
from django.contrib.auth import authenticate, login from django.contrib.auth import authenticate, login
from evennia.accounts.models import AccountDB from evennia.accounts.models import AccountDB
from evennia.utils import logger, ip_from_request from evennia.utils import ip_from_request, logger
class OriginIpMiddleware: class OriginIpMiddleware: