From fb135ab0e3c3a8e85367797d922cb327985abdf1 Mon Sep 17 00:00:00 2001 From: Jeroen van der Heijden Date: Tue, 3 Dec 2024 16:34:33 +0100 Subject: [PATCH] support room name --- thingsdb/client/client.py | 8 +++++--- thingsdb/room/room.py | 5 ----- thingsdb/room/roombase.py | 42 +++++++++++++++++++++++++-------------- thingsdb/util/cnscope.py | 6 ++---- thingsdb/util/is_name.py | 7 +++++++ thingsdb/version.py | 2 +- 6 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 thingsdb/util/is_name.py diff --git a/thingsdb/client/client.py b/thingsdb/client/client.py index 63b69d3..23b5dfc 100644 --- a/thingsdb/client/client.py +++ b/thingsdb/client/client.py @@ -484,11 +484,12 @@ def _emit( scope = self._scope return self._write_pkg(Proto.REQ_EMIT, [scope, room_id, event, *args]) - def _join(self, *ids: int, scope: Optional[str] = None) -> asyncio.Future: + def _join(self, *ids: Union[int, str], + scope: Optional[str] = None) -> asyncio.Future: """Join one or more rooms. Args: - *ids (int): + *ids (int/str): Room Ids to join. No error is returned in case one of the given room Ids are not found within the collection. Instead, the return value will contain `None` instead of the @@ -512,7 +513,8 @@ def _join(self, *ids: int, scope: Optional[str] = None) -> asyncio.Future: return self._write_pkg(Proto.REQ_JOIN, [scope, *ids]) - def _leave(self, *ids: int, scope: Optional[str] = None) -> asyncio.Future: + def _leave(self, *ids: Union[int, str], + scope: Optional[str] = None) -> asyncio.Future: """Leave one or more rooms. Stop receiving events for the rooms given by one or more ids. It is diff --git a/thingsdb/room/room.py b/thingsdb/room/room.py index 7912ea6..846cc1e 100644 --- a/thingsdb/room/room.py +++ b/thingsdb/room/room.py @@ -1,9 +1,4 @@ -import abc -import asyncio import logging -from typing import Union -from ..client import Client -from ..client.protocol import Proto from .roombase import RoomBase diff --git a/thingsdb/room/roombase.py b/thingsdb/room/roombase.py index fcff225..d4d858f 100644 --- a/thingsdb/room/roombase.py +++ b/thingsdb/room/roombase.py @@ -1,10 +1,10 @@ import abc import asyncio import logging -import functools from typing import Union, Optional from ..client import Client from ..client.protocol import Proto +from ..util.is_name import is_name class RoomBase(abc.ABC): @@ -61,13 +61,19 @@ async def no_join(self, client: Client): self._client = client if isinstance(self._id, str): - code = self._id - id = await client.query(code, scope=self._scope) - if not isinstance(id, int): - raise TypeError( - f'expecting ThingsDB code `{code}` to return with a ' - f'room Id (integer value), ' - f'but got type `{type(id).__name__}`') + if is_name(self._id): + id = await client.query( + "room(name).id();", + name=self._id, + scope=self._scope) + else: + code = self._id + id = await client.query(code, scope=self._scope) + if not isinstance(id, int): + raise TypeError( + f'expecting ThingsDB code `{code}` to return with ' + f'a room Id (integer value), ' + f'but got type `{type(id).__name__}`') else: id = self._id is_room = \ @@ -99,13 +105,19 @@ async def join(self, client: Client, wait: Optional[float] = 60.0): self._client = client if isinstance(self._id, str): - code = self._id - id = await client.query(code, scope=self._scope) - if not isinstance(id, int): - raise TypeError( - f'expecting ThingsDB code `{code}` to return with a ' - f'room Id (integer value), ' - f'but got type `{type(id).__name__}`') + if is_name(self._id): + id = await client.query( + "room(name).id();", + name=self._id, + scope=self._scope) + else: + code = self._id + id = await client.query(code, scope=self._scope) + if not isinstance(id, int): + raise TypeError( + f'expecting ThingsDB code `{code}` to return with ' + f'a room Id (integer value), ' + f'but got type `{type(id).__name__}`') res = await client._join(id, scope=self._scope) if res[0] is None: raise LookupError( diff --git a/thingsdb/util/cnscope.py b/thingsdb/util/cnscope.py index 5cbdfeb..7c95271 100644 --- a/thingsdb/util/cnscope.py +++ b/thingsdb/util/cnscope.py @@ -1,6 +1,4 @@ -import re - -_VALID_NAME = re.compile(r'^[A-Za-z_][0-9A-Za-z_]{0,254}') +from .is_name import is_name def cnscope(scope): @@ -18,7 +16,7 @@ def cnscope(scope): else: name = '' - if _VALID_NAME.match(name): + if is_name(name): return name raise ValueError(f'invalid (collection) scope name: {scope}') diff --git a/thingsdb/util/is_name.py b/thingsdb/util/is_name.py new file mode 100644 index 0000000..e2fb9cf --- /dev/null +++ b/thingsdb/util/is_name.py @@ -0,0 +1,7 @@ +import re + +_VALID_NAME = re.compile(r'^[A-Za-z_][0-9A-Za-z_]{0,254}$') + + +def is_name(s: str) -> bool: + bool(_VALID_NAME.match(s)) diff --git a/thingsdb/version.py b/thingsdb/version.py index 7b344ec..7bb021e 100644 --- a/thingsdb/version.py +++ b/thingsdb/version.py @@ -1 +1 @@ -__version__ = '1.1.2' +__version__ = '1.1.3'