Merge pull request #1 from ReK42/main
Add `use_community_slug` option to support disabling the slug suffix
This commit is contained in:
@@ -10,6 +10,10 @@ parent_room: ''
|
||||
# leave blank to generate an acronym of your community name during initialization
|
||||
community_slug: ''
|
||||
|
||||
# use_community_slug
|
||||
# whether to use the community slug as a suffix for room aliases
|
||||
use_community_slug: true
|
||||
|
||||
# sleep time between actions. you can drop this to 0 if your bot has no
|
||||
# ratelimits imposed on its homeserver, otherwise you may want to increase this
|
||||
# to avoid errors.
|
||||
|
||||
+13
-5
@@ -71,6 +71,7 @@ class Config(BaseProxyConfig):
|
||||
helper.copy("welcome_sleep")
|
||||
helper.copy("parent_room")
|
||||
helper.copy("community_slug")
|
||||
helper.copy("use_community_slug")
|
||||
helper.copy("track_users")
|
||||
helper.copy("warn_threshold_days")
|
||||
helper.copy("kick_threshold_days")
|
||||
@@ -178,7 +179,9 @@ class CommunityBot(Plugin):
|
||||
Returns:
|
||||
tuple: (is_valid, list_of_conflicting_aliases)
|
||||
"""
|
||||
if not self.config.get("community_slug", ""):
|
||||
if self.config.get("use_community_slug", True) and not self.config.get(
|
||||
"community_slug", ""
|
||||
):
|
||||
if evt:
|
||||
await evt.respond(
|
||||
"Error: No community slug configured. Please run initialize command first."
|
||||
@@ -187,7 +190,11 @@ class CommunityBot(Plugin):
|
||||
|
||||
server = self.client.parse_user_id(self.client.mxid)[1]
|
||||
return await room_utils.validate_room_aliases(
|
||||
self.client, room_names, self.config.get("community_slug", ""), server
|
||||
self.client,
|
||||
room_names,
|
||||
self.config.get("community_slug", ""),
|
||||
self.config.get("use_community_slug", True),
|
||||
server,
|
||||
)
|
||||
|
||||
async def get_moderators_and_above(self) -> list[str]:
|
||||
@@ -1980,7 +1987,7 @@ class CommunityBot(Plugin):
|
||||
return
|
||||
|
||||
# Check if community slug is configured
|
||||
if not self.config["community_slug"]:
|
||||
if self.config["use_community_slug"] and not self.config["community_slug"]:
|
||||
await evt.reply(
|
||||
"No community slug configured. Please run initialize command first."
|
||||
)
|
||||
@@ -2186,7 +2193,7 @@ class CommunityBot(Plugin):
|
||||
aliases_to_transfer = await self.remove_room_aliases(room_id, evt)
|
||||
|
||||
# Check if community slug is configured
|
||||
if not self.config["community_slug"]:
|
||||
if self.config["use_community_slug"] and not self.config["community_slug"]:
|
||||
await evt.respond(
|
||||
"No community slug configured. Please run initialize command first."
|
||||
)
|
||||
@@ -3124,7 +3131,7 @@ class CommunityBot(Plugin):
|
||||
|
||||
try:
|
||||
# Generate community slug if not already set
|
||||
if not self.config["community_slug"]:
|
||||
if self.config["use_community_slug"] and not self.config["community_slug"]:
|
||||
community_slug = self.generate_community_slug(community_name)
|
||||
self.config["community_slug"] = community_slug
|
||||
self.log.info(f"Generated community slug: {community_slug}")
|
||||
@@ -3307,6 +3314,7 @@ class CommunityBot(Plugin):
|
||||
await evt.respond(
|
||||
f"Community space initialized successfully!<br /><br />"
|
||||
f"Community Slug: {self.config['community_slug']}<br />"
|
||||
f"Use Community Slug: {self.config['use_community_slug']}"
|
||||
f"Room Version: {self.config['room_version']}<br />"
|
||||
f"Space: <a href='https://matrix.to/#/{space_alias}'>{space_alias}</a><br />"
|
||||
f"Moderators Room: <a href='https://matrix.to/#/{mod_room_alias}'>{mod_room_alias}</a><br />"
|
||||
|
||||
@@ -99,6 +99,14 @@ class ConfigManager:
|
||||
"""
|
||||
return self.config.get("community_slug")
|
||||
|
||||
def get_use_community_slug(self) -> Optional[str]:
|
||||
"""Get the community slug suffix setting.
|
||||
|
||||
Returns:
|
||||
bool: Whether to use the community slug as a room suffix
|
||||
"""
|
||||
return self.config.get("use_community_slug")
|
||||
|
||||
def get_parent_room(self) -> Optional[str]:
|
||||
"""Get the parent room ID.
|
||||
|
||||
@@ -201,7 +209,12 @@ class ConfigManager:
|
||||
Returns:
|
||||
List[str]: List of missing required configuration keys
|
||||
"""
|
||||
required_configs = ["parent_room", "room_version", "community_slug"]
|
||||
required_configs = [
|
||||
"parent_room",
|
||||
"room_version",
|
||||
"community_slug",
|
||||
"use_community_slug",
|
||||
]
|
||||
|
||||
missing = []
|
||||
for config_key in required_configs:
|
||||
@@ -231,6 +244,7 @@ class ConfigManager:
|
||||
return {
|
||||
"room_version": self.get_room_version(),
|
||||
"community_slug": self.get_community_slug(),
|
||||
"use_community_slug": self.get_use_community_slug(),
|
||||
"invitees": self.get_invitees(),
|
||||
"invite_power_level": self.get_invite_power_level(),
|
||||
"encrypt": self.is_encryption_enabled(),
|
||||
|
||||
@@ -38,7 +38,7 @@ async def validate_room_creation_params(
|
||||
sanitized_name = re.sub(r"[^a-zA-Z0-9]", "", roomname).lower()
|
||||
|
||||
# Check if community slug is configured
|
||||
if not config.get("community_slug", ""):
|
||||
if config.get("use_community_slug", True) and not config.get("community_slug", ""):
|
||||
error_msg = "No community slug configured. Please run initialize command first."
|
||||
return sanitized_name, force_encryption, force_unencryption, error_msg, roomname
|
||||
|
||||
@@ -63,7 +63,10 @@ async def prepare_room_creation_data(
|
||||
Tuple of (alias_localpart, server, room_invitees, parent_room)
|
||||
"""
|
||||
# Create alias with community slug
|
||||
if config.get("use_community_slug", True):
|
||||
alias_localpart = f"{sanitized_name}-{config.get('community_slug', '')}"
|
||||
else:
|
||||
alias_localpart = sanitized_name
|
||||
|
||||
# Get server and invitees
|
||||
server = client.parse_user_id(client.mxid)[1]
|
||||
|
||||
@@ -31,7 +31,11 @@ async def validate_room_alias(client, alias_localpart: str, server: str) -> bool
|
||||
|
||||
|
||||
async def validate_room_aliases(
|
||||
client, room_names: list[str], community_slug: str, server: str
|
||||
client,
|
||||
room_names: list[str],
|
||||
community_slug: str,
|
||||
use_community_slug: bool,
|
||||
server: str,
|
||||
) -> Tuple[bool, List[str]]:
|
||||
"""Validate that all room aliases are available.
|
||||
|
||||
@@ -39,12 +43,13 @@ async def validate_room_aliases(
|
||||
client: Matrix client instance
|
||||
room_names: List of room names to validate
|
||||
community_slug: The community slug to append
|
||||
use_community_slug: Whether to append a community slug
|
||||
server: The server domain
|
||||
|
||||
Returns:
|
||||
tuple: (is_valid, list_of_conflicting_aliases)
|
||||
"""
|
||||
if not community_slug:
|
||||
if use_community_slug and not community_slug:
|
||||
return False, []
|
||||
|
||||
conflicting_aliases = []
|
||||
@@ -54,7 +59,10 @@ async def validate_room_aliases(
|
||||
from .message_utils import sanitize_room_name
|
||||
|
||||
sanitized_name = sanitize_room_name(room_name)
|
||||
if use_community_slug:
|
||||
alias_localpart = f"{sanitized_name}-{community_slug}"
|
||||
else:
|
||||
alias_localpart = sanitized_name
|
||||
|
||||
# Check if alias is available
|
||||
is_available = await validate_room_alias(client, alias_localpart, server)
|
||||
|
||||
@@ -67,6 +67,9 @@ plugin_config:
|
||||
# leave blank to generate an acronym of your community name during initialization
|
||||
community_slug: ''
|
||||
|
||||
# use_community_slug
|
||||
# whether to use the community slug as a suffix for room aliases
|
||||
use_community_slug: true
|
||||
|
||||
# sleep time between actions. you can drop this to 0 if your bot has no
|
||||
# ratelimits imposed on its homeserver, otherwise you may want to increase this
|
||||
|
||||
@@ -46,24 +46,41 @@ class TestRoomUtils:
|
||||
assert result == True
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_room_aliases_no_slug(self):
|
||||
async def test_validate_room_aliases_slug_not_required_with_no_slug(self):
|
||||
"""Test alias validation without community slug."""
|
||||
client = Mock()
|
||||
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "", "example.com")
|
||||
assert result == (False, [])
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "", False, "example.com")
|
||||
assert result == (True, [])
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_room_aliases_success(self):
|
||||
async def test_validate_room_aliases_slug_not_required_with_slug(self):
|
||||
"""Test successful alias validation."""
|
||||
client = Mock()
|
||||
client.resolve_room_alias = AsyncMock(side_effect=MNotFound("Room not found", 404))
|
||||
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "test", "example.com")
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "test", False, "example.com")
|
||||
assert result == (True, [])
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_room_aliases_conflicts(self):
|
||||
async def test_validate_room_aliases_slug_required_with_no_slug(self):
|
||||
"""Test alias validation without community slug."""
|
||||
client = Mock()
|
||||
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "", True, "example.com")
|
||||
assert result == (False, [])
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_room_aliases_slug_required_with_slug(self):
|
||||
"""Test successful alias validation."""
|
||||
client = Mock()
|
||||
client.resolve_room_alias = AsyncMock(side_effect=MNotFound("Room not found", 404))
|
||||
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "test", True, "example.com")
|
||||
assert result == (True, [])
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_room_aliases_conflicts_slug_not_required(self):
|
||||
"""Test alias validation with conflicts."""
|
||||
client = Mock()
|
||||
|
||||
@@ -75,7 +92,23 @@ class TestRoomUtils:
|
||||
|
||||
client.resolve_room_alias = AsyncMock(side_effect=resolve_side_effect)
|
||||
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "test", "example.com")
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "", False, "example.com")
|
||||
assert result == (False, ["#room1:example.com"])
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_room_aliases_conflicts_slug_required(self):
|
||||
"""Test alias validation with conflicts."""
|
||||
client = Mock()
|
||||
|
||||
def resolve_side_effect(alias):
|
||||
if "room1" in alias:
|
||||
return {"room_id": "!room1:example.com"} # Exists
|
||||
else:
|
||||
raise MNotFound() # Doesn't exist
|
||||
|
||||
client.resolve_room_alias = AsyncMock(side_effect=resolve_side_effect)
|
||||
|
||||
result = await validate_room_aliases(client, ["room1", "room2"], "test", True, "example.com")
|
||||
assert result == (False, ["#room1-test:example.com"])
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Reference in New Issue
Block a user