From 37ecac009df72b72200aacc3ecb41620b5f83872 Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Mon, 25 Sep 2023 00:32:06 -0300 Subject: [PATCH 01/18] Add the ability to PATCH discord nicknames and roles. --- evennia/accounts/bots.py | 3 ++ evennia/commands/default/comms.py | 6 ++++ evennia/server/portal/discord.py | 57 +++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index 0f5a2cbddd..6fae561d38 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -637,6 +637,9 @@ class DiscordBot(Bot): # send outputfunc channel(msg, discord channel) super().msg(channel=(strip_ansi(message.strip()), dc_chan)) + def change_nickname(self, new_nickname, guild_id, user_id, **kwargs): + super().msg(nickname=(new_nickname, guild_id, user_id)) + def direct_msg(self, message, sender, **kwargs): """ Called when the Discord bot receives a direct message on Discord. diff --git a/evennia/commands/default/comms.py b/evennia/commands/default/comms.py index 8a1762d784..63d83285f1 100644 --- a/evennia/commands/default/comms.py +++ b/evennia/commands/default/comms.py @@ -1942,6 +1942,7 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS): "list", "remove", "start", + "nickname", ) locks = "cmd:serversetting(DISCORD_ENABLED) and pperm(Developer)" help_category = "Comms" @@ -1981,6 +1982,11 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS): self.msg("Starting the Discord bot session.") return + if "nickname" in self.switches: + discord_bot.change_nickname("Test", 541788744471281700, 124523120668311552) + self.msg(f"Changed username") + return + if "guild" in self.switches: discord_bot.db.tag_guild = not discord_bot.db.tag_guild self.msg( diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index 38f387f04f..8126d8cd66 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -375,6 +375,39 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): d.addCallback(cbResponse) + def _patch_json(self, url, data, **kwargs): + """ + Post JSON data to a REST API endpoint + + Args: + url (str) - The API path which is being posted to + data (dict) - Content to be sent + """ + url = f"{DISCORD_API_BASE_URL}/{url}" + body = FileBodyProducer(BytesIO(json.dumps(data).encode("utf-8"))) + d = _AGENT.request( + b"PATCH", + url.encode("utf-8"), + Headers( + { + "User-Agent": [DISCORD_USER_AGENT], + "Authorization": [f"Bot {DISCORD_BOT_TOKEN}"], + "Content-Type": ["application/json"], + } + ), + body, + ) + + def cbResponse(response): + if response.code == 200: + d = readBody(response) + d.addCallback(self.post_response) + return d + elif should_retry(response.code): + delay(300, self._post_json, url, data, **kwargs) + + d.addCallback(cbResponse) + def post_response(self, body, **kwargs): """ Process the response from sending a POST request @@ -483,10 +516,30 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ - data = {"content": text} + data = {"nick": text} data.update(kwargs) self._post_json(f"channels/{channel_id}/messages", data) + def send_nickname(self, text, guild_id, user_id, **kwargs): + """ + Changes a user's nickname on a Discord server. + + Use with session.msg(nickname=(new_nickname, guild_id, user_id)) + """ + + data = {"nick": text} + self._patch_json(f"guilds/{guild_id}/members/{user_id}", data) + + def send_roles(self, current_roles, role, guild_id, user_id, **kwargs): + """ + Assign the user a role on a Discord server. + Use with session.msg(roles=(current_roles, role, guild_id, user_id)) + """ + + data = {"roles": current_roles.append(role)} + data.update(kwargs) + self._post_json(f"guilds/{guild_id}/members/{user_id}", data) + def send_default(self, *args, **kwargs): """ Ignore other outputfuncs @@ -552,4 +605,4 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): # send the data for any other action types on to the bot as-is for optional server-side handling keywords = {"type": action_type} keywords.update(data["d"]) - self.sessionhandler.data_in(self, bot_data_in=("", keywords)) + self.sessionhandler.data_in(self, bot_data_in=("", keywords)) \ No newline at end of file From dbcd947b832fc2fd77e3070e1ab5a7a13acaec94 Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Mon, 25 Sep 2023 00:44:25 -0300 Subject: [PATCH 02/18] Fix having renamed a property on send_channel. --- evennia/server/portal/discord.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index 8126d8cd66..df4d721a5c 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -516,7 +516,7 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ - data = {"nick": text} + data = {"content": text} data.update(kwargs) self._post_json(f"channels/{channel_id}/messages", data) From a9b1417806b6dcec77ffe5a1e64764803f69a8f5 Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Mon, 25 Sep 2023 00:44:25 -0300 Subject: [PATCH 03/18] Remove _patch_json and modify _post_json to support an optional patch argument. --- evennia/server/portal/discord.py | 47 ++------------------------------ 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index df4d721a5c..751057f375 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -352,41 +352,9 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ url = f"{DISCORD_API_BASE_URL}/{url}" body = FileBodyProducer(BytesIO(json.dumps(data).encode("utf-8"))) + is_patch_request = kwargs.pop('patch', False) d = _AGENT.request( - b"POST", - url.encode("utf-8"), - Headers( - { - "User-Agent": [DISCORD_USER_AGENT], - "Authorization": [f"Bot {DISCORD_BOT_TOKEN}"], - "Content-Type": ["application/json"], - } - ), - body, - ) - - def cbResponse(response): - if response.code == 200: - d = readBody(response) - d.addCallback(self.post_response) - return d - elif should_retry(response.code): - delay(300, self._post_json, url, data, **kwargs) - - d.addCallback(cbResponse) - - def _patch_json(self, url, data, **kwargs): - """ - Post JSON data to a REST API endpoint - - Args: - url (str) - The API path which is being posted to - data (dict) - Content to be sent - """ - url = f"{DISCORD_API_BASE_URL}/{url}" - body = FileBodyProducer(BytesIO(json.dumps(data).encode("utf-8"))) - d = _AGENT.request( - b"PATCH", + b"PATCH" if is_patch_request else b"POST", url.encode("utf-8"), Headers( { @@ -528,17 +496,8 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ data = {"nick": text} - self._patch_json(f"guilds/{guild_id}/members/{user_id}", data) - - def send_roles(self, current_roles, role, guild_id, user_id, **kwargs): - """ - Assign the user a role on a Discord server. - Use with session.msg(roles=(current_roles, role, guild_id, user_id)) - """ - - data = {"roles": current_roles.append(role)} data.update(kwargs) - self._post_json(f"guilds/{guild_id}/members/{user_id}", data) + self._post_json(f"guilds/{guild_id}/members/{user_id}", data, patch=True) def send_default(self, *args, **kwargs): """ From 911323b721733b829c3ffb080a6fc4cf838cbeec Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Mon, 25 Sep 2023 01:20:46 -0300 Subject: [PATCH 04/18] Documentation. --- evennia/accounts/bots.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index 6fae561d38..65ca1b650f 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -638,6 +638,15 @@ class DiscordBot(Bot): super().msg(channel=(strip_ansi(message.strip()), dc_chan)) def change_nickname(self, new_nickname, guild_id, user_id, **kwargs): + """ + Changes a given user's nickname on the given guild the bot is in. + + Args: + new_nickname (str) - The user's new nickname. + guild_id (int) - The guild the nickname will be changed in. + user_id (int) - The Discord ID of the user who's nickname will be changed. + + """ super().msg(nickname=(new_nickname, guild_id, user_id)) def direct_msg(self, message, sender, **kwargs): From 3532fffca44d885968106411f1497d0fcbabdfac Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Mon, 25 Sep 2023 01:22:24 -0300 Subject: [PATCH 05/18] Remove testing switch from discord2chan. --- evennia/commands/default/comms.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/evennia/commands/default/comms.py b/evennia/commands/default/comms.py index 63d83285f1..8a1762d784 100644 --- a/evennia/commands/default/comms.py +++ b/evennia/commands/default/comms.py @@ -1942,7 +1942,6 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS): "list", "remove", "start", - "nickname", ) locks = "cmd:serversetting(DISCORD_ENABLED) and pperm(Developer)" help_category = "Comms" @@ -1982,11 +1981,6 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS): self.msg("Starting the Discord bot session.") return - if "nickname" in self.switches: - discord_bot.change_nickname("Test", 541788744471281700, 124523120668311552) - self.msg(f"Changed username") - return - if "guild" in self.switches: discord_bot.db.tag_guild = not discord_bot.db.tag_guild self.msg( From 61083ed9b52d5156ddd130fa9c0950e3ccde9566 Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Mon, 2 Oct 2023 02:27:15 -0300 Subject: [PATCH 06/18] Add outputfunc to add roles through the bot. --- evennia/accounts/bots.py | 4 ++++ evennia/server/portal/discord.py | 22 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index 65ca1b650f..e593daaa71 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -649,6 +649,10 @@ class DiscordBot(Bot): """ super().msg(nickname=(new_nickname, guild_id, user_id)) + def assign_role(self, role_id, guild_id, user_id, **kwargs): + + pass + def direct_msg(self, message, sender, **kwargs): """ Called when the Discord bot receives a direct message on Discord. diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index 751057f375..b7df76e037 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -352,9 +352,19 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ url = f"{DISCORD_API_BASE_URL}/{url}" body = FileBodyProducer(BytesIO(json.dumps(data).encode("utf-8"))) - is_patch_request = kwargs.pop('patch', False) + is_patch_request = kwargs.pop("patch", False) + is_put_request = kwargs.pop("put", False) + request_type = "POST" + + if is_patch_request: + request_type = b"PATCH" + elif is_put_request: + request_type = b"PUT" + else: + request_type = b"POST" + d = _AGENT.request( - b"PATCH" if is_patch_request else b"POST", + request_type, url.encode("utf-8"), Headers( { @@ -371,6 +381,9 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): d = readBody(response) d.addCallback(self.post_response) return d + elif response.code == 204: + d = readBody(response) + d.addCallback(self.post_response) elif should_retry(response.code): delay(300, self._post_json, url, data, **kwargs) @@ -499,6 +512,11 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): data.update(kwargs) self._post_json(f"guilds/{guild_id}/members/{user_id}", data, patch=True) + def send_role(self, role_id, guild_id, user_id, **kwargs): + + data = kwargs + self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", put=True) + def send_default(self, *args, **kwargs): """ Ignore other outputfuncs From 58bfd143d2f92a9f2451499ad957e5a7f91c41ee Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Mon, 2 Oct 2023 02:29:51 -0300 Subject: [PATCH 07/18] Finish the assign role system through the bot. --- evennia/accounts/bots.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index e593daaa71..c881664982 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -650,8 +650,16 @@ class DiscordBot(Bot): super().msg(nickname=(new_nickname, guild_id, user_id)) def assign_role(self, role_id, guild_id, user_id, **kwargs): + """ + Assigns a user the role on the given guild the bot is in. - pass + Args: + role_id (int) - The Discord role's ID. + guild_id (int) - The guild the role will be assigned in. + user_id (int) - The user the given role will be assigned to. + """ + + super().msg(role=(role_id, guild_id, user_id)) def direct_msg(self, message, sender, **kwargs): """ From e89ae5b090588b2fc240cc7d964e823ab6907ffb Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Mon, 2 Oct 2023 02:40:55 -0300 Subject: [PATCH 08/18] Fix small typo on role assignment function. --- evennia/server/portal/discord.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index b7df76e037..3a7633b213 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -515,7 +515,7 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): def send_role(self, role_id, guild_id, user_id, **kwargs): data = kwargs - self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", put=True) + self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, put=True) def send_default(self, *args, **kwargs): """ From 2562d65a4d7478fde8dce26d53237bdfdadd27ec Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Tue, 3 Oct 2023 15:53:52 -0300 Subject: [PATCH 09/18] Change handling of different request types and callback for 204 requests (nickname change). --- evennia/server/portal/discord.py | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index 3a7633b213..17108fc581 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -352,16 +352,7 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ url = f"{DISCORD_API_BASE_URL}/{url}" body = FileBodyProducer(BytesIO(json.dumps(data).encode("utf-8"))) - is_patch_request = kwargs.pop("patch", False) - is_put_request = kwargs.pop("put", False) - request_type = "POST" - - if is_patch_request: - request_type = b"PATCH" - elif is_put_request: - request_type = b"PUT" - else: - request_type = b"POST" + request_type = kwargs.pop("type", b"POST") d = _AGENT.request( request_type, @@ -377,13 +368,11 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): ) def cbResponse(response): - if response.code == 200: + logger.log_info(response.code) + if response.code == 200 or response.code == 204: d = readBody(response) d.addCallback(self.post_response) return d - elif response.code == 204: - d = readBody(response) - d.addCallback(self.post_response) elif should_retry(response.code): delay(300, self._post_json, url, data, **kwargs) @@ -510,12 +499,12 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): data = {"nick": text} data.update(kwargs) - self._post_json(f"guilds/{guild_id}/members/{user_id}", data, patch=True) + self._post_json(f"guilds/{guild_id}/members/{user_id}", data, type=b"PATCH") def send_role(self, role_id, guild_id, user_id, **kwargs): data = kwargs - self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, put=True) + self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, type=b"PUT") def send_default(self, *args, **kwargs): """ From 3eface6def3145dfc54be0df4675ac248e1745b3 Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Tue, 3 Oct 2023 18:51:16 -0300 Subject: [PATCH 10/18] Change byte handling to only one place. --- evennia/server/portal/discord.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index 17108fc581..7bc4a50d37 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -352,10 +352,10 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ url = f"{DISCORD_API_BASE_URL}/{url}" body = FileBodyProducer(BytesIO(json.dumps(data).encode("utf-8"))) - request_type = kwargs.pop("type", b"POST") + request_type = kwargs.pop("type", "POST") d = _AGENT.request( - request_type, + request_type.encode("utf-8"), url.encode("utf-8"), Headers( { @@ -499,12 +499,12 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): data = {"nick": text} data.update(kwargs) - self._post_json(f"guilds/{guild_id}/members/{user_id}", data, type=b"PATCH") + self._post_json(f"guilds/{guild_id}/members/{user_id}", data, type="PATCH") def send_role(self, role_id, guild_id, user_id, **kwargs): data = kwargs - self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, type=b"PUT") + self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, type="PUT") def send_default(self, *args, **kwargs): """ From d57a3550bcf184ddfa4d9523406fc9ab5c215d1d Mon Sep 17 00:00:00 2001 From: nate2s Date: Sat, 23 Sep 2023 19:28:18 -0400 Subject: [PATCH 11/18] fix return_appearance typo --- evennia/objects/objects.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 4dc15ce729..ffd9e21655 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -212,7 +212,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): objects = ObjectManager() - # populated by `return_apperance` + # populated by `return_appearance` appearance_template = """ {header} |c{name}|n @@ -1201,7 +1201,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): self.at_access(result, accessing_obj, access_type, **kwargs) return result - # name and return_apperance hooks + # name and return_appearance hooks def get_display_name(self, looker=None, **kwargs): """ @@ -2111,7 +2111,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): Notes: This method shouldn't add extra coloring to the names beyond what is already given by the .get_display_name() (and the .name field) already. - Per-type coloring can be applied in `return_apperance`. + Per-type coloring can be applied in `return_appearance`. """ # a mapping {'exits': [...], 'characters': [...], 'things': [...]} From e28f9dd3c4cd5822d8f6a0050a8703948a48280c Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 1 Oct 2023 10:41:58 +0200 Subject: [PATCH 12/18] Prepping unit test for later fixes --- evennia/scripts/manager.py | 1 - evennia/scripts/tests.py | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/evennia/scripts/manager.py b/evennia/scripts/manager.py index b0a57df162..c42866aa9e 100644 --- a/evennia/scripts/manager.py +++ b/evennia/scripts/manager.py @@ -4,7 +4,6 @@ The custom manager for Scripts. from django.conf import settings from django.db.models import Q - from evennia.server import signals from evennia.typeclasses.managers import TypeclassManager, TypedObjectManager from evennia.utils.utils import class_from_module, dbid_to_obj, make_iter diff --git a/evennia/scripts/tests.py b/evennia/scripts/tests.py index bd1d245a25..eb5f205d13 100644 --- a/evennia/scripts/tests.py +++ b/evennia/scripts/tests.py @@ -78,26 +78,28 @@ class TestScriptHandler(BaseEvenniaTest): def setUp(self): self.obj, self.errors = DefaultObject.create("test_object") + self.obj.scripts.add(TestingListIntervalScript) def tearDown(self): self.obj.delete() def test_start(self): "Check that ScriptHandler start function works correctly" - self.obj.scripts.add(TestingListIntervalScript) self.num = self.obj.scripts.start(self.obj.scripts.all()[0].key) - self.assertTrue(self.num == 1) + self.assertEqual(self.num, 1) def test_list_script_intervals(self): "Checks that Scripthandler __str__ function lists script intervals correctly" - self.obj.scripts.add(TestingListIntervalScript) self.str = str(self.obj.scripts) self.assertTrue("None/1" in self.str) self.assertTrue("1 repeats" in self.str) + def test_get_all_scripts(self): + "Checks that Scripthandler get_all returns correct number of scripts" + self.assertEqual([script.key for script in self.obj.scripts.all()], ["interval_test"]) + def test_get_script(self): "Checks that Scripthandler get function returns correct script" - self.obj.scripts.add(TestingListIntervalScript) script = self.obj.scripts.get("interval_test") self.assertTrue(bool(script)) From 26a804ca1f1081fdccae50c5f4ebf54dd429e973 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 1 Oct 2023 10:49:42 +0200 Subject: [PATCH 13/18] Fixes in SubscriptionHandler; return subs ordered by pk. --- evennia/comms/comms.py | 3 +-- evennia/comms/models.py | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/evennia/comms/comms.py b/evennia/comms/comms.py index 9791e5a930..7e370b23f1 100644 --- a/evennia/comms/comms.py +++ b/evennia/comms/comms.py @@ -7,7 +7,6 @@ import re from django.contrib.contenttypes.models import ContentType from django.urls import reverse from django.utils.text import slugify - from evennia.comms.managers import ChannelManager from evennia.comms.models import ChannelDB from evennia.typeclasses.models import TypeclassBase @@ -188,7 +187,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase): # display listening subscribers in bold string = ", ".join( [ - account.key if account not in listening else "|w%s|n" % account.key + account.key if account not in listening else f"|w{account.key}|n" for account in subs ] ) diff --git a/evennia/comms/models.py b/evennia/comms/models.py index ec6037f23f..80dfa69d79 100644 --- a/evennia/comms/models.py +++ b/evennia/comms/models.py @@ -21,7 +21,6 @@ necessary to easily be able to delete connections on the fly). from django.conf import settings from django.db import models from django.utils import timezone - from evennia.comms import managers from evennia.locks.lockhandler import LockHandler from evennia.typeclasses.models import TypedObject @@ -104,8 +103,10 @@ class Msg(SharedMemoryModel): null=True, blank=True, db_index=True, - help_text="Identifier for single external sender, for use with senders " - "not represented by a regular database model.", + help_text=( + "Identifier for single external sender, for use with senders " + "not represented by a regular database model." + ), ) db_receivers_accounts = models.ManyToManyField( @@ -137,8 +138,10 @@ class Msg(SharedMemoryModel): null=True, blank=True, db_index=True, - help_text="Identifier for single external receiver, for use with recievers " - "not represented by a regular database model.", + help_text=( + "Identifier for single external receiver, for use with recievers " + "not represented by a regular database model." + ), ) # header could be used for meta-info about the message if your system needs @@ -167,8 +170,10 @@ class Msg(SharedMemoryModel): db_tags = models.ManyToManyField( Tag, blank=True, - help_text="tags on this message. Tags are simple string markers to " - "identify, group and alias messages.", + help_text=( + "tags on this message. Tags are simple string markers to " + "identify, group and alias messages." + ), ) # Database manager @@ -518,7 +523,7 @@ class TempMsg: # ------------------------------------------------------------ -class SubscriptionHandler(object): +class SubscriptionHandler: """ This handler manages subscriptions to the channel and hides away which type of entity is @@ -540,13 +545,13 @@ class SubscriptionHandler(object): def _recache(self): self._cache = { account: True - for account in self.obj.db_account_subscriptions.all() + for account in self.obj.db_account_subscriptions.all().order_by("pk") if hasattr(account, "pk") and account.pk } self._cache.update( { obj: True - for obj in self.obj.db_object_subscriptions.all() + for obj in self.obj.db_object_subscriptions.all().order_by("pk") if hasattr(obj, "pk") and obj.pk } ) From 4d153d1971a9244702eb41eaa2bc05a065f99cad Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Tue, 3 Oct 2023 15:53:52 -0300 Subject: [PATCH 14/18] Change handling of different request types and callback for 204 requests (nickname change). --- evennia/server/portal/discord.py | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index 3a7633b213..17108fc581 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -352,16 +352,7 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ url = f"{DISCORD_API_BASE_URL}/{url}" body = FileBodyProducer(BytesIO(json.dumps(data).encode("utf-8"))) - is_patch_request = kwargs.pop("patch", False) - is_put_request = kwargs.pop("put", False) - request_type = "POST" - - if is_patch_request: - request_type = b"PATCH" - elif is_put_request: - request_type = b"PUT" - else: - request_type = b"POST" + request_type = kwargs.pop("type", b"POST") d = _AGENT.request( request_type, @@ -377,13 +368,11 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): ) def cbResponse(response): - if response.code == 200: + logger.log_info(response.code) + if response.code == 200 or response.code == 204: d = readBody(response) d.addCallback(self.post_response) return d - elif response.code == 204: - d = readBody(response) - d.addCallback(self.post_response) elif should_retry(response.code): delay(300, self._post_json, url, data, **kwargs) @@ -510,12 +499,12 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): data = {"nick": text} data.update(kwargs) - self._post_json(f"guilds/{guild_id}/members/{user_id}", data, patch=True) + self._post_json(f"guilds/{guild_id}/members/{user_id}", data, type=b"PATCH") def send_role(self, role_id, guild_id, user_id, **kwargs): data = kwargs - self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, put=True) + self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, type=b"PUT") def send_default(self, *args, **kwargs): """ From d0446d5de1f31bd792c58059eef49738bf0fb741 Mon Sep 17 00:00:00 2001 From: Johnny Voruz Date: Sat, 23 Sep 2023 16:48:49 -0500 Subject: [PATCH 15/18] Index.html template split up into new widgitized templates found in evennia\web\templates\website\homepage --- .../website/homepage/accounts-widget.html | 14 ++ .../homepage/database-stats-widget.html | 13 ++ .../website/homepage/evennia-widget.html | 12 ++ .../website/homepage/main-content.html | 62 ++++++++ .../homepage/recently-connected-widget.html | 11 ++ evennia/web/templates/website/index.html | 132 +++--------------- 6 files changed, 131 insertions(+), 113 deletions(-) create mode 100644 evennia/web/templates/website/homepage/accounts-widget.html create mode 100644 evennia/web/templates/website/homepage/database-stats-widget.html create mode 100644 evennia/web/templates/website/homepage/evennia-widget.html create mode 100644 evennia/web/templates/website/homepage/main-content.html create mode 100644 evennia/web/templates/website/homepage/recently-connected-widget.html diff --git a/evennia/web/templates/website/homepage/accounts-widget.html b/evennia/web/templates/website/homepage/accounts-widget.html new file mode 100644 index 0000000000..9e6e13ad99 --- /dev/null +++ b/evennia/web/templates/website/homepage/accounts-widget.html @@ -0,0 +1,14 @@ +
+

Accounts

+ +
+

+ There's currently {{num_accounts_connected}} connected out of a total of {{num_accounts_registered}} + account{{num_accounts_registered|pluralize}} registered. +

+

+ Of these, {{num_accounts_registered_recent}} were created this week, and {{num_accounts_connected_recent}} + have connected within the last seven days. +

+
+
\ No newline at end of file diff --git a/evennia/web/templates/website/homepage/database-stats-widget.html b/evennia/web/templates/website/homepage/database-stats-widget.html new file mode 100644 index 0000000000..747bef56d2 --- /dev/null +++ b/evennia/web/templates/website/homepage/database-stats-widget.html @@ -0,0 +1,13 @@ +
+

Database Stats

+ +
+
    +
  • {{num_accounts_registered}} account{{num_accounts_registered|pluralize}} (+ + {{num_characters}} character{{num_characters|pluralize}}) +
  • +
  • {{num_rooms}} room{{num_rooms|pluralize}} (+ {{num_exits}} exits)
  • +
  • {{num_others}} other objects
  • +
+
+
\ No newline at end of file diff --git a/evennia/web/templates/website/homepage/evennia-widget.html b/evennia/web/templates/website/homepage/evennia-widget.html new file mode 100644 index 0000000000..a4772d71bb --- /dev/null +++ b/evennia/web/templates/website/homepage/evennia-widget.html @@ -0,0 +1,12 @@ +
+

Evennia

+ +
+

Evennia is an open-source MUD/MU*-creation framework built in + Python, using + Twisted and + Django.
+ Create the text-based multiplayer-game of your dreams - as + simple or as complex as you like.

+
+
\ No newline at end of file diff --git a/evennia/web/templates/website/homepage/main-content.html b/evennia/web/templates/website/homepage/main-content.html new file mode 100644 index 0000000000..72c9208177 --- /dev/null +++ b/evennia/web/templates/website/homepage/main-content.html @@ -0,0 +1,62 @@ +

Welcome to Evennia!

+ +
+ +

The Python MUD/MU* creation system.

+ +

+ You are looking at the start of your game's website, generated out of + the box by Evennia.
It can be expanded into a full-fledged home for your game. +

+ +{% if webclient_enabled %} + +

Play in the browser!

+ +{% endif %} +{% if telnet_enabled %} +

+ Telnet: {{ server_hostname }}, port + {% for port in telnet_ports %} + {% if not forloop.first and forloop.last %} or + {% elif forloop.counter != 1 %}, + {% endif %} + {{ port }} + {% endfor %} +

+{% endif %} +{% if telnet_ssl_enabled %} +

+ Telnet (SSL): {{ server_hostname }}, port + {% for port in telnet_ssl_ports %} + {% if not forloop.first and forloop.last %} or + {% elif forloop.counter != 1 %}, + {% endif %} + {{ port }} + {% endfor %} +

+{% endif %} +{% if ssh_enabled %} +

+ SSH: {{ server_hostname }}, port + {% for port in ssh_ports %} + {% if not forloop.first and forloop.last %} or + {% elif forloop.counter != 1 %}, + {% endif %} + {{ port }} + {% endfor %} +

+{% endif %} +

+ For more info, see the Evennia homepage or check + out our extensive online documentation. +

+

+ Don't hesitate asking questions to the Evennia community!
Drop a message + in the Evennia forums + or come say hi in the Discord support channel. +

+

+ Evennia is Open source and can be found on GitHub. + If you find bugs, please report them to the Issue tracker. +

\ No newline at end of file diff --git a/evennia/web/templates/website/homepage/recently-connected-widget.html b/evennia/web/templates/website/homepage/recently-connected-widget.html new file mode 100644 index 0000000000..4ee1552bc0 --- /dev/null +++ b/evennia/web/templates/website/homepage/recently-connected-widget.html @@ -0,0 +1,11 @@ +
+

Recently Connected

+ +
+
    + {% for account in accounts_connected_recent %} +
  • {{account.username}}—{{account.last_login|timesince}} ago
  • + {% endfor %} +
+
+
\ No newline at end of file diff --git a/evennia/web/templates/website/index.html b/evennia/web/templates/website/index.html index 365f473a4d..49a9479d62 100644 --- a/evennia/web/templates/website/index.html +++ b/evennia/web/templates/website/index.html @@ -7,138 +7,44 @@ {% block content %}
-
-
-
+
+
+
-

Welcome to Evennia!

+ {% include "website/homepage/main-content.html" %} -
- -

- The Python MUD/MU* creation system. -

-

- You are looking at the start of your game's website, generated out of - the box by Evennia.
It can be expanded into a full-fledged home for your game. -

- {% if webclient_enabled %} -

- Play in the browser! -

- {% endif %} - {% if telnet_enabled %} -

- Telnet: {{ server_hostname }}, port - {% for port in telnet_ports %} - {% if not forloop.first and forloop.last %} or - {% elif forloop.counter != 1 %}, - {% endif %} - {{ port }} - {% endfor %} -

- {% endif %} - {% if telnet_ssl_enabled %} -

- Telnet (SSL): {{ server_hostname }}, port - {% for port in telnet_ssl_ports %} - {% if not forloop.first and forloop.last %} or - {% elif forloop.counter != 1 %}, - {% endif %} - {{ port }} - {% endfor %} -

- {% endif %} - {% if ssh_enabled %} -

- SSH: {{ server_hostname }}, port - {% for port in ssh_ports %} - {% if not forloop.first and forloop.last %} or - {% elif forloop.counter != 1 %}, - {% endif %} - {{ port }} - {% endfor %} -

- {% endif %} -

- For more info, see the Evennia homepage or check - out our extensive online documentation. -

-

- Don't hesitate asking questions to the Evennia community!
Drop a message - in the Evennia forums - or come say hi in the Discord support channel. -

-

- Evennia is Open source and can be found on GitHub. - If you find bugs, please report them to the Issue tracker. -

-
+
+
-
-
+
-
-
-

Accounts

+
+ + {% include "website/homepage/accounts-widget.html" %} -
-

- There's currently {{num_accounts_connected}} connected out of a total of {{num_accounts_registered}} account{{num_accounts_registered|pluralize}} registered. -

-

- Of these, {{num_accounts_registered_recent}} were created this week, and {{num_accounts_connected_recent}} have connected within the last seven days. -

-
-
-
-
-

Recently Connected

+
+ + {% include "website/homepage/recently-connected-widget.html" %} -
-
    - {% for account in accounts_connected_recent %} -
  • {{account.username}}—{{account.last_login|timesince}} ago
  • - {% endfor %} -
-
-
-
-
-

Database Stats

+
+ + {% include "website/homepage/database-stats-widget.html" %} -
-
    -
  • {{num_accounts_registered}} account{{num_accounts_registered|pluralize}} (+ {{num_characters}} character{{num_characters|pluralize}})
  • -
  • {{num_rooms}} room{{num_rooms|pluralize}} (+ {{num_exits}} exits)
  • -
  • {{num_others}} other objects
  • -
-
-
-
-
-

Evennia

+
+ + {% include "website/homepage/evennia-widget.html" %} -
-

Evennia is an open-source MUD/MU*-creation framework built in - Python, using - Twisted and - Django.
- Create the text-based multiplayer-game of your dreams - as - simple or as complex as you like.

-
-
{% endblock %} From 4258281a8829dd0b768ce06be733906739fcc340 Mon Sep 17 00:00:00 2001 From: Griatch Date: Mon, 2 Oct 2023 20:56:10 +0200 Subject: [PATCH 16/18] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffe4452125..379cf0a706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - [Feature][issue3273]: Allow passing `text_kwargs` kwarg to `EvMore.msg` in order to expand the outputfunc used for every evmore page. +- [Feature][pull3278]: Refactor home page into multiple sub-parts for easier + overriding and composition (johnnyvoruz) - [Fix][pull3267]: Missing recache step in ObjectSessionHandler (InspectorCaracal) - [Fix][pull3270]: Evennia is its own MSSP family now, so we should return that instead of 'Custom' (InspectorCaracal) @@ -17,6 +19,7 @@ [pull3267]: https://github.com/evennia/evennia/pull/3267 [pull3270]: https://github.com/evennia/evennia/pull/3270 [pull3274]: https://github.com/evennia/evennia/pull/3274 +[pull3278]: https://github.com/evennia/evennia/pull/3278 [issue3272]: https://github.com/evennia/evennia/issues/3272 [issue3273]: https://github.com/evennia/evennia/issues/3273 From 4e2eaf7a46c348f0be8511c25054555205611fb9 Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Tue, 3 Oct 2023 18:51:16 -0300 Subject: [PATCH 17/18] Change byte handling to only one place. --- evennia/server/portal/discord.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index 17108fc581..7bc4a50d37 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -352,10 +352,10 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): """ url = f"{DISCORD_API_BASE_URL}/{url}" body = FileBodyProducer(BytesIO(json.dumps(data).encode("utf-8"))) - request_type = kwargs.pop("type", b"POST") + request_type = kwargs.pop("type", "POST") d = _AGENT.request( - request_type, + request_type.encode("utf-8"), url.encode("utf-8"), Headers( { @@ -499,12 +499,12 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): data = {"nick": text} data.update(kwargs) - self._post_json(f"guilds/{guild_id}/members/{user_id}", data, type=b"PATCH") + self._post_json(f"guilds/{guild_id}/members/{user_id}", data, type="PATCH") def send_role(self, role_id, guild_id, user_id, **kwargs): data = kwargs - self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, type=b"PUT") + self._post_json(f"guilds/{guild_id}/members/{user_id}/roles/{role_id}", data, type="PUT") def send_default(self, *args, **kwargs): """ From 926a265a903c57d9dca8efde79dd48de60a3219e Mon Sep 17 00:00:00 2001 From: holl0wstar Date: Fri, 6 Oct 2023 17:00:09 -0300 Subject: [PATCH 18/18] Remove leftover log debug. --- evennia/server/portal/discord.py | 1 - 1 file changed, 1 deletion(-) diff --git a/evennia/server/portal/discord.py b/evennia/server/portal/discord.py index 7bc4a50d37..babae8a495 100644 --- a/evennia/server/portal/discord.py +++ b/evennia/server/portal/discord.py @@ -368,7 +368,6 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS): ) def cbResponse(response): - logger.log_info(response.code) if response.code == 200 or response.code == 204: d = readBody(response) d.addCallback(self.post_response)