Log in/out and pm
This commit is contained in:
parent
0d58f61652
commit
135640ca44
4 changed files with 117 additions and 23 deletions
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
## Next version
|
## Next version
|
||||||
|
|
||||||
|
- add login and logout command to room
|
||||||
|
- add pm command to room
|
||||||
- add cookie support
|
- add cookie support
|
||||||
- add !restart to botrulez
|
- add !restart to botrulez
|
||||||
- save (overwrite) `Bot` config file
|
- save (overwrite) `Bot` config file
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,12 @@ class Client:
|
||||||
async def on_edit(self, room: Room, message: LiveMessage) -> None:
|
async def on_edit(self, room: Room, message: LiveMessage) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def on_login(self, room: Room, account_id: str) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_logout(self, room: Room) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
async def on_pm(self,
|
async def on_pm(self,
|
||||||
room: Room,
|
room: Room,
|
||||||
from_id: str,
|
from_id: str,
|
||||||
|
|
|
||||||
118
yaboli/room.py
118
yaboli/room.py
|
|
@ -1,6 +1,6 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Awaitable, Callable, List, Optional, TypeVar
|
from typing import Any, Awaitable, Callable, List, Optional, Tuple, TypeVar
|
||||||
|
|
||||||
from .connection import Connection
|
from .connection import Connection
|
||||||
from .events import Events
|
from .events import Events
|
||||||
|
|
@ -43,6 +43,12 @@ class Room:
|
||||||
"edit" - a message in the room has been modified or deleted
|
"edit" - a message in the room has been modified or deleted
|
||||||
message: LiveMessage
|
message: LiveMessage
|
||||||
|
|
||||||
|
"login" - this session has been logged in from another session
|
||||||
|
account_id: str
|
||||||
|
|
||||||
|
"logout" - this session has been logged out from another session
|
||||||
|
no parameters
|
||||||
|
|
||||||
"pm" - another session initiated a pm with you
|
"pm" - another session initiated a pm with you
|
||||||
from: str - the id of the user inviting the client to chat privately
|
from: str - the id of the user inviting the client to chat privately
|
||||||
from_nick: str - the nick of the inviting user
|
from_nick: str - the nick of the inviting user
|
||||||
|
|
@ -117,9 +123,20 @@ class Room:
|
||||||
|
|
||||||
# Connecting, reconnecting and disconnecting
|
# Connecting, reconnecting and disconnecting
|
||||||
|
|
||||||
def _set_connected(self) -> None:
|
async def _try_set_connected(self) -> None:
|
||||||
packets_received = self._hello_received and self._snapshot_received
|
packets_received = self._hello_received and self._snapshot_received
|
||||||
if packets_received and not self._connected.is_set():
|
if packets_received and not self._connected.is_set():
|
||||||
|
await self._set_nick_if_necessary()
|
||||||
|
self._set_connected()
|
||||||
|
|
||||||
|
async def _set_nick_if_necessary(self) -> None:
|
||||||
|
nick_needs_updating = (self._session is None
|
||||||
|
or self._target_nick != self._session.nick)
|
||||||
|
|
||||||
|
if self._target_nick and nick_needs_updating:
|
||||||
|
await self._nick(self._target_nick)
|
||||||
|
|
||||||
|
def _set_connected(self) -> None:
|
||||||
self._connected_successfully = True
|
self._connected_successfully = True
|
||||||
self._connected.set()
|
self._connected.set()
|
||||||
|
|
||||||
|
|
@ -148,7 +165,7 @@ class Room:
|
||||||
self._account = Account.from_data(data)
|
self._account = Account.from_data(data)
|
||||||
|
|
||||||
self._hello_received = True
|
self._hello_received = True
|
||||||
self._set_connected()
|
await self._try_set_connected()
|
||||||
|
|
||||||
async def _on_snapshot_event(self, packet: Any) -> None:
|
async def _on_snapshot_event(self, packet: Any) -> None:
|
||||||
data = packet["data"]
|
data = packet["data"]
|
||||||
|
|
@ -169,7 +186,7 @@ class Room:
|
||||||
self._events.fire("session", messages)
|
self._events.fire("session", messages)
|
||||||
|
|
||||||
self._snapshot_received = True
|
self._snapshot_received = True
|
||||||
self._set_connected()
|
await self._try_set_connected()
|
||||||
|
|
||||||
async def _on_bounce_event(self, packet: Any) -> None:
|
async def _on_bounce_event(self, packet: Any) -> None:
|
||||||
data = packet["data"]
|
data = packet["data"]
|
||||||
|
|
@ -207,11 +224,6 @@ class Room:
|
||||||
if not self._connected_successfully:
|
if not self._connected_successfully:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
nick_needs_updating = (self._session is None
|
|
||||||
or self._target_nick != self._session.nick)
|
|
||||||
if self._target_nick and nick_needs_updating:
|
|
||||||
await self._nick(self._target_nick)
|
|
||||||
|
|
||||||
self._events.fire("connected")
|
self._events.fire("connected")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -243,14 +255,34 @@ class Room:
|
||||||
session = LiveSession.from_data(self, data)
|
session = LiveSession.from_data(self, data)
|
||||||
self._users = self.users.with_join(session)
|
self._users = self.users.with_join(session)
|
||||||
|
|
||||||
logger.info(f"{session.atmention} joined")
|
logger.info(f"&{self.name}: {session.atmention} joined")
|
||||||
self._events.fire("join", session)
|
self._events.fire("join", session)
|
||||||
|
|
||||||
async def _on_login_event(self, packet: Any) -> None:
|
async def _on_login_event(self, packet: Any) -> None:
|
||||||
pass # TODO implement once cookie support is here
|
"""
|
||||||
|
Just reconnect, see
|
||||||
|
https://github.com/euphoria-io/heim/blob/master/client/lib/stores/chat.js#L275-L276
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = packet["data"]
|
||||||
|
|
||||||
|
account_id = data["account_id"]
|
||||||
|
|
||||||
|
self._events.fire("login", account_id)
|
||||||
|
logger.info(f"&{self.name}: Got logged in to {account_id}, reconnecting")
|
||||||
|
|
||||||
|
await self._connection.reconnect()
|
||||||
|
|
||||||
async def _on_logout_event(self, packet: Any) -> None:
|
async def _on_logout_event(self, packet: Any) -> None:
|
||||||
pass # TODO implement once cookie support is here
|
"""
|
||||||
|
Just reconnect, see
|
||||||
|
https://github.com/euphoria-io/heim/blob/master/client/lib/stores/chat.js#L275-L276
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._events.fire("logout")
|
||||||
|
logger.info(f"&{self.name}: Got logged out, reconnecting")
|
||||||
|
|
||||||
|
await self._connection.reconnect()
|
||||||
|
|
||||||
async def _on_network_event(self, packet: Any) -> None:
|
async def _on_network_event(self, packet: Any) -> None:
|
||||||
data = packet["data"]
|
data = packet["data"]
|
||||||
|
|
@ -264,7 +296,7 @@ class Room:
|
||||||
for user in self.users:
|
for user in self.users:
|
||||||
if user.server_id == server_id and user.server_era == server_era:
|
if user.server_id == server_id and user.server_era == server_era:
|
||||||
users = users.with_part(user)
|
users = users.with_part(user)
|
||||||
logger.info(f"{user.atmention} left")
|
logger.info(f"&{self.name}: {user.atmention} left")
|
||||||
self._events.fire("part", user)
|
self._events.fire("part", user)
|
||||||
|
|
||||||
self._users = users
|
self._users = users
|
||||||
|
|
@ -281,7 +313,7 @@ class Room:
|
||||||
else:
|
else:
|
||||||
await self.who() # recalibrating self._users
|
await self.who() # recalibrating self._users
|
||||||
|
|
||||||
logger.info(f"{atmention(nick_from)} is now called {atmention(nick_to)}")
|
logger.info(f"&{self.name}: {atmention(nick_from)} is now called {atmention(nick_to)}")
|
||||||
self._events.fire("nick", session, nick_from, nick_to)
|
self._events.fire("nick", session, nick_from, nick_to)
|
||||||
|
|
||||||
async def _on_edit_message_event(self, packet: Any) -> None:
|
async def _on_edit_message_event(self, packet: Any) -> None:
|
||||||
|
|
@ -297,7 +329,7 @@ class Room:
|
||||||
session = LiveSession.from_data(self, data)
|
session = LiveSession.from_data(self, data)
|
||||||
self._users = self.users.with_part(session)
|
self._users = self.users.with_part(session)
|
||||||
|
|
||||||
logger.info(f"{session.atmention} left")
|
logger.info(f"&{self.name}: {session.atmention} left")
|
||||||
self._events.fire("part", session)
|
self._events.fire("part", session)
|
||||||
|
|
||||||
async def _on_pm_initiate_event(self, packet: Any) -> None:
|
async def _on_pm_initiate_event(self, packet: Any) -> None:
|
||||||
|
|
@ -374,10 +406,6 @@ class Room:
|
||||||
|
|
||||||
# Functionality
|
# Functionality
|
||||||
|
|
||||||
# These functions require cookie support and are thus not implemented yet:
|
|
||||||
#
|
|
||||||
# login, logout, pm
|
|
||||||
|
|
||||||
def _extract_data(self, packet: Any) -> Any:
|
def _extract_data(self, packet: Any) -> Any:
|
||||||
error = packet.get("error")
|
error = packet.get("error")
|
||||||
if error is not None:
|
if error is not None:
|
||||||
|
|
@ -477,3 +505,55 @@ class Room:
|
||||||
self._users = users
|
self._users = users
|
||||||
|
|
||||||
return self._users
|
return self._users
|
||||||
|
|
||||||
|
async def login(self, email: str, password: str) -> Tuple[bool, str]:
|
||||||
|
"""
|
||||||
|
Since euphoria appears to only support email authentication, this way
|
||||||
|
of logging in is hardcoded here.
|
||||||
|
|
||||||
|
Returns whether the login was successful. If it was, the second
|
||||||
|
parameter is the account id. If it wasn't, the second parameter is the
|
||||||
|
reason why the login failed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
data: Any = {
|
||||||
|
"namespace": "email",
|
||||||
|
"id": email,
|
||||||
|
"password": password,
|
||||||
|
}
|
||||||
|
|
||||||
|
reply = await self._connection.send("login", data)
|
||||||
|
data = self._extract_data(reply)
|
||||||
|
|
||||||
|
success: bool = data["success"]
|
||||||
|
account_id_or_reason = data.get("account_id") or data["reason"]
|
||||||
|
|
||||||
|
if success:
|
||||||
|
logger.info(f"&{self.name}: Logged in as {account_id_or_reason}")
|
||||||
|
else:
|
||||||
|
logger.info(f"&{self.name}: Failed to log in with {email} because {account_id_or_reason}")
|
||||||
|
|
||||||
|
await self._connection.reconnect()
|
||||||
|
|
||||||
|
return success, account_id_or_reason
|
||||||
|
|
||||||
|
async def logout(self) -> None:
|
||||||
|
await self._connection.send("logout", {})
|
||||||
|
|
||||||
|
logger.info(f"&{self.name}: Logged out")
|
||||||
|
|
||||||
|
await self._connection.reconnect()
|
||||||
|
|
||||||
|
async def pm(self, user_id: str) -> Tuple[str, str]:
|
||||||
|
"""
|
||||||
|
Returns the pm_id of the pm and the nick of the person being pinged.
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = {"user_id": user_id}
|
||||||
|
|
||||||
|
reply = await self._connection.send("pm-initiate", data)
|
||||||
|
data = self._extract_data(reply)
|
||||||
|
|
||||||
|
pm_id = data["pm_id"]
|
||||||
|
to_nick = data["to_nick"]
|
||||||
|
return pm_id, to_nick
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import re
|
import re
|
||||||
from typing import TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Optional
|
from typing import (TYPE_CHECKING, Any, Dict, Iterable, Iterator, List,
|
||||||
|
Optional, Tuple)
|
||||||
|
|
||||||
from .util import mention, normalize
|
from .util import mention, normalize
|
||||||
|
|
||||||
|
|
@ -238,7 +239,12 @@ class LiveSession(Session):
|
||||||
|
|
||||||
# Live stuff
|
# Live stuff
|
||||||
|
|
||||||
# TODO pm, once pm support is there.
|
async def pm(self) -> Tuple[str, str]:
|
||||||
|
"""
|
||||||
|
See Room.pm
|
||||||
|
"""
|
||||||
|
|
||||||
|
return await self.room.pm(self.user_id)
|
||||||
|
|
||||||
class LiveSessionListing:
|
class LiveSessionListing:
|
||||||
def __init__(self, room: "Room", sessions: Iterable[LiveSession]) -> None:
|
def __init__(self, room: "Room", sessions: Iterable[LiveSession]) -> None:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue