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
|
||||
|
||||
- add login and logout command to room
|
||||
- add pm command to room
|
||||
- add cookie support
|
||||
- add !restart to botrulez
|
||||
- save (overwrite) `Bot` config file
|
||||
|
|
|
|||
|
|
@ -152,6 +152,12 @@ class Client:
|
|||
async def on_edit(self, room: Room, message: LiveMessage) -> None:
|
||||
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,
|
||||
room: Room,
|
||||
from_id: str,
|
||||
|
|
|
|||
118
yaboli/room.py
118
yaboli/room.py
|
|
@ -1,6 +1,6 @@
|
|||
import asyncio
|
||||
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 .events import Events
|
||||
|
|
@ -43,6 +43,12 @@ class Room:
|
|||
"edit" - a message in the room has been modified or deleted
|
||||
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
|
||||
from: str - the id of the user inviting the client to chat privately
|
||||
from_nick: str - the nick of the inviting user
|
||||
|
|
@ -117,9 +123,20 @@ class Room:
|
|||
|
||||
# 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
|
||||
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.set()
|
||||
|
||||
|
|
@ -148,7 +165,7 @@ class Room:
|
|||
self._account = Account.from_data(data)
|
||||
|
||||
self._hello_received = True
|
||||
self._set_connected()
|
||||
await self._try_set_connected()
|
||||
|
||||
async def _on_snapshot_event(self, packet: Any) -> None:
|
||||
data = packet["data"]
|
||||
|
|
@ -169,7 +186,7 @@ class Room:
|
|||
self._events.fire("session", messages)
|
||||
|
||||
self._snapshot_received = True
|
||||
self._set_connected()
|
||||
await self._try_set_connected()
|
||||
|
||||
async def _on_bounce_event(self, packet: Any) -> None:
|
||||
data = packet["data"]
|
||||
|
|
@ -207,11 +224,6 @@ class Room:
|
|||
if not self._connected_successfully:
|
||||
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")
|
||||
return True
|
||||
|
||||
|
|
@ -243,14 +255,34 @@ class Room:
|
|||
session = LiveSession.from_data(self, data)
|
||||
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)
|
||||
|
||||
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:
|
||||
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:
|
||||
data = packet["data"]
|
||||
|
|
@ -264,7 +296,7 @@ class Room:
|
|||
for user in self.users:
|
||||
if user.server_id == server_id and user.server_era == server_era:
|
||||
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._users = users
|
||||
|
|
@ -281,7 +313,7 @@ class Room:
|
|||
else:
|
||||
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)
|
||||
|
||||
async def _on_edit_message_event(self, packet: Any) -> None:
|
||||
|
|
@ -297,7 +329,7 @@ class Room:
|
|||
session = LiveSession.from_data(self, data)
|
||||
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)
|
||||
|
||||
async def _on_pm_initiate_event(self, packet: Any) -> None:
|
||||
|
|
@ -374,10 +406,6 @@ class Room:
|
|||
|
||||
# Functionality
|
||||
|
||||
# These functions require cookie support and are thus not implemented yet:
|
||||
#
|
||||
# login, logout, pm
|
||||
|
||||
def _extract_data(self, packet: Any) -> Any:
|
||||
error = packet.get("error")
|
||||
if error is not None:
|
||||
|
|
@ -477,3 +505,55 @@ class Room:
|
|||
self._users = 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
|
||||
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
|
||||
|
||||
|
|
@ -238,7 +239,12 @@ class LiveSession(Session):
|
|||
|
||||
# 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:
|
||||
def __init__(self, room: "Room", sessions: Iterable[LiveSession]) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue