diff --git a/chatom/backend.py b/chatom/backend.py
index 9cc0673..8174eaa 100644
--- a/chatom/backend.py
+++ b/chatom/backend.py
@@ -1,24 +1,46 @@
from typing import Literal, Union
DISCORD = "discord"
+EMAIL = "email"
+IRC = "irc"
+MATRIX = "matrix"
MATTERMOST = "mattermost"
MESSENGER = "messenger"
SLACK = "slack"
+SYMPHONY = "symphony"
TEAMS = "teams"
TELEGRAM = "telegram"
WHATSAPP = "whatsapp"
ZULIP = "zulip"
-Backend = Union[
+BACKEND = Union[
Literal[DISCORD],
+ Literal[EMAIL],
+ Literal[IRC],
+ Literal[MATRIX],
Literal[MATTERMOST],
Literal[MESSENGER],
Literal[SLACK],
+ Literal[SYMPHONY],
Literal[TEAMS],
Literal[TELEGRAM],
Literal[WHATSAPP],
Literal[ZULIP],
str,
]
+ALL_BACKENDS = [
+ DISCORD,
+ EMAIL,
+ IRC,
+ MATRIX,
+ MATTERMOST,
+ MESSENGER,
+ SLACK,
+ SYMPHONY,
+ TEAMS,
+ TELEGRAM,
+ WHATSAPP,
+ ZULIP,
+]
-__all__ = ("Backend", "DISCORD", "MATTERMOST", "MESSENGER", "SLACK", "TEAMS", "TELEGRAM", "WHATSAPP", "ZULIP")
+__all__ = ("BACKEND", "DISCORD", "MATTERMOST", "MESSENGER", "SLACK", "SYMPHONY", "TEAMS", "TELEGRAM", "WHATSAPP", "ZULIP")
diff --git a/chatom/format/__init__.py b/chatom/format/__init__.py
index d17f147..534827e 100644
--- a/chatom/format/__init__.py
+++ b/chatom/format/__init__.py
@@ -1,3 +1,4 @@
from .message import *
from .table import *
from .text import *
+from .variant import *
diff --git a/chatom/mention.py b/chatom/mention.py
index e69de29..a5a0171 100644
--- a/chatom/mention.py
+++ b/chatom/mention.py
@@ -0,0 +1,42 @@
+from .backend import BACKEND
+from .user import User
+
+
+def mention_user(user: User, backend: BACKEND) -> str:
+ """Generate a mention string for a user based on the backend platform.
+
+ Args:
+ user (User): The user to mention.
+ backend (BACKEND): The backend platform.
+
+ Returns:
+ str: The formatted mention string.
+ """
+ match backend:
+ case "discord":
+ return f"<@!{user.id}>"
+ case "email":
+ return f"{user.name}" if user.email else user.name
+ case "irc":
+ return f"{user.handle}" if user.handle else user.name
+ case "matrix":
+ return f"@{user.handle}:matrix.org" if user.handle else user.name
+ case "mattermost":
+ return f"@{user.handle}" if user.handle else user.name
+ case "messenger":
+ return f"@{user.name}"
+ case "slack":
+ return f"<@{user.id}>"
+ case "teams":
+ return f"{user.name}"
+ case "telegram":
+ return f"@{user.handle}" if user.handle else user.name
+ case "symphony":
+ return f"@{user.name}"
+ case "whatsapp":
+ return f"@{user.name}"
+ case "zulip":
+ return f"@**{user.name}**"
+ case _:
+ # Fallback to full name if no specific format is defined
+ return user.name
diff --git a/chatom/tests/test_backend.py b/chatom/tests/test_backend.py
new file mode 100644
index 0000000..84864da
--- /dev/null
+++ b/chatom/tests/test_backend.py
@@ -0,0 +1,10 @@
+from typing import Literal
+
+
+class TestBackend:
+ def test_all_backends_listed(self):
+ from chatom.backend import ALL_BACKENDS, BACKEND
+
+ # Ensure that ALL_BACKENDS actually has all backends
+ for backend in ALL_BACKENDS:
+ assert Literal[backend] in BACKEND.__args__
diff --git a/chatom/tests/test_mention.py b/chatom/tests/test_mention.py
new file mode 100644
index 0000000..a0fea6a
--- /dev/null
+++ b/chatom/tests/test_mention.py
@@ -0,0 +1,32 @@
+import pytest
+
+from chatom.mention import mention_user
+from chatom.user import User
+
+
+class TestMention:
+ @pytest.mark.parametrize(
+ "user,backend,expected",
+ [
+ (User(handle="jane_doe", id="456", name="Jane Doe"), "discord", "<@!456>"),
+ (User(handle="", id="789", name="Alice"), "email", "Alice"),
+ (User(handle="", id="101", name="Bob", email="bob@example.com"), "email", "Bob"),
+ (User(handle="charlie", id="112", name="Charlie"), "irc", "charlie"),
+ (User(handle="", id="131", name="David"), "irc", "David"),
+ (User(handle="eve", id="415", name="Eve"), "matrix", "@eve:matrix.org"),
+ (User(handle="charlie", id="112", name="Charlie"), "mattermost", "@charlie"),
+ (User(handle="", id="131", name="David"), "mattermost", "David"),
+ (User(handle="eve", id="415", name="Eve"), "messenger", "@Eve"),
+ (User(handle="john_doe", id="123", name="John Doe"), "slack", "<@123>"),
+ (User(handle="frank", id="161", name="Frank"), "symphony", "@Frank"),
+ (User(handle="eve", id="415", name="Eve"), "teams", "Eve"),
+ (User(handle="alice", id="789", name="Alice"), "telegram", "@alice"),
+ (User(handle="", id="101", name="Bob"), "telegram", "Bob"),
+ (User(handle="grace", id="718", name="Grace"), "whatsapp", "@Grace"),
+ (User(handle="heidi", id="192", name="Heidi"), "zulip", "@**Heidi**"),
+ (User(handle="ivan", id="202", name="Ivan"), "unknown", "Ivan"),
+ ],
+ )
+ def test_mention(self, user, backend, expected):
+ result = mention_user(user, backend)
+ assert result == expected
diff --git a/chatom/user.py b/chatom/user.py
index 2cfd110..4f3d102 100644
--- a/chatom/user.py
+++ b/chatom/user.py
@@ -4,7 +4,7 @@
class User(BaseModel):
- user: str = Field(
+ handle: str = Field(
description="The username of the author of the message.",
)
email: str = Field(
@@ -15,3 +15,7 @@ class User(BaseModel):
default="",
description="uid of the author, for mentions",
)
+ name: str = Field(
+ default="",
+ description="The display name of the author of the message.",
+ )
diff --git a/pyproject.toml b/pyproject.toml
index 76f6bab..bd5b37a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,7 +9,7 @@ description = "Minimum viable chat components"
readme = "README.md"
license = { text = "Apache-2.0" }
version = "0.1.0"
-requires-python = ">=3.9"
+requires-python = ">=3.10"
keywords = [
"chat",
"chatbot",
@@ -27,7 +27,6 @@ classifiers = [
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",