Make more events work (and use an annoying bot to test them)

This commit is contained in:
Joscha 2017-09-02 12:27:38 +00:00
parent 04364c6b3f
commit dfad3241fb
5 changed files with 208 additions and 41 deletions

View file

@ -1,6 +1,7 @@
import asyncio import asyncio
#from controller import Bot #from controller import Bot
from controller import Controller from controller import Controller
from utils import *
@ -13,9 +14,33 @@ class TestBot(Controller):
pm_with_nick=None, pm_with_user_id=None): pm_with_nick=None, pm_with_user_id=None):
await self.room.nick("TestBot") await self.room.nick("TestBot")
async def on_hello(self, user_id, session, room_is_private, version, account=None, async def on_send(self, message):
account_has_access=None, account_email_verified=None): await self.room.send("Hey, a message!", message.message_id)
print(repr(session.user_id), repr(session.session_id), repr(session.name))
async def on_join(self, session):
if session.nick != "":
await self.room.send(f"Hey, a @{mention(session.nick)}!")
else:
await self.room.send("Hey, a lurker!")
async def on_nick(self, session_id, user_id, from_nick, to_nick):
if from_nick != "" and to_nick != "":
if from_nick == to_nick:
await self.room.send(f"You didn't even change your nick, @{mention(to_nick)} :(")
else:
await self.room.send(f"Bye @{mention(from_nick)}, hi @{mention(to_nick)}")
elif from_nick != "":
await self.room.send(f"Bye @{mention(from_nick)}? This message should never appear...")
elif to_nick != "":
await self.room.send(f"Hey, a @{mention(to_nick)}!")
else:
await self.room.send("I have no idea how you did that. This message should never appear...")
async def on_part(self, session):
if session.nick != "":
await self.room.send(f"Bye, you @{mention(session.nick)}!")
else:
await self.room.send("Bye, you lurker!")
if __name__ == "__main__": if __name__ == "__main__":
bot = TestBot("test") bot = TestBot("test")

View file

@ -36,8 +36,8 @@ class Connection:
stopped = True stopped = True
for future in self._pending_responses: for future in self._pending_responses:
future.set_error(ConnectionClosed) #future.set_error(ConnectionClosed)
future.cancel() # TODO: Is this needed? future.cancel()
async def stop(self): async def stop(self):
if not self.stopped and self._ws: if not self.stopped and self._ws:
@ -92,6 +92,16 @@ class Connection:
#c = Connection("wss://euphoria.io/room/test/ws", handle_packet) #c = Connection("wss://euphoria.io/room/test/ws", handle_packet)
#def run(): async def await_future(f):
#loop = asyncio.get_event_loop() await f
#loop.run_until_complete(asyncio.ensure_future(c.run())) print(f.result())
def run():
f = asyncio.Future()
#f.set_result("Hello World!")
f.cancel()
#f.set_result("Hello World!")
loop = asyncio.get_event_loop()
loop.run_until_complete(await_future(f))
#loop.run_until_complete(c.run())

View file

@ -110,7 +110,7 @@ class Controller:
async def on_network(self, ntype, server_id, server_era): async def on_network(self, ntype, server_id, server_era):
pass pass
async def on_nick(self, session_id, user_id, from_name, to_name): async def on_nick(self, session_id, user_id, from_nick, to_nick):
pass pass
async def on_edit_message(self, edit_id, message): async def on_edit_message(self, edit_id, message):

View file

@ -49,6 +49,7 @@ class Room:
async def ping_reply(self, time): async def ping_reply(self, time):
""" """
From api.euphoria.io:
The ping command initiates a client-to-server ping. The server will The ping command initiates a client-to-server ping. The server will
send back a ping-reply with the same timestamp as soon as possible. send back a ping-reply with the same timestamp as soon as possible.
@ -70,6 +71,7 @@ class Room:
""" """
session_id, user_id, from_nick, to_nick = await nick(name) session_id, user_id, from_nick, to_nick = await nick(name)
From api.euphoria.io:
The nick command sets the name you present to the room. This name The nick command sets the name you present to the room. This name
applies to all messages sent during this session, until the nick applies to all messages sent during this session, until the nick
command is called again. command is called again.
@ -79,7 +81,9 @@ class Room:
""" """
data = {"name": name} data = {"name": name}
response = await self._conn.send("nick", data) response = await self._conn.send("nick", data)
self._check_for_errors(response)
session_id = response.get("session_id") session_id = response.get("session_id")
user_id = response.get("id") user_id = response.get("id")
@ -94,7 +98,28 @@ class Room:
pass # TODO pass # TODO
async def send(self, content, parent=None): async def send(self, content, parent=None):
pass # TODO """
From api.euphoria.io:
The send command sends a message to a room. The session must be
successfully joined with the room. This message will be broadcast to
all sessions joined with the room.
If the room is private, then the message content will be encrypted
before it is stored and broadcast to the rest of the room.
The caller of this command will not receive the corresponding
send-event, but will receive the same information in the send-reply.
"""
data = {"content": content}
if parent:
data["parent"] = parent
response = await self._conn.send("send", data)
self._check_for_errors(response)
message = utils.Message.from_dict(response.get("data"))
return message
async def who(self): async def who(self):
pass # TODO pass # TODO
@ -129,16 +154,52 @@ class Room:
self._callbacks["snapshot-event"] = self._handle_snapshot self._callbacks["snapshot-event"] = self._handle_snapshot
async def _handle_packet(self, packet): async def _handle_packet(self, packet):
self._check_for_errors(packet)
ptype = packet.get("type") ptype = packet.get("type")
callback = self._callbacks.get(ptype) callback = self._callbacks.get(ptype)
if callback: if callback:
await callback(packet) try:
await callback(packet)
except asyncio.CancelledError as e:
# TODO: log error
print("HEHEHEHEY, CANCELLEDERROR", e)
pass
def _check_for_errors(self, packet):
# TODO: log throttled
if "error" in packet:
raise utils.ResponseError(response.get("error"))
async def _handle_bounce(self, packet): async def _handle_bounce(self, packet):
pass # TODO """
From api.euphoria.io:
A bounce-event indicates that access to a room is denied.
"""
data = packet.get("data")
await self.controller.on_bounce(
reason=data.get("reason", None),
auth_options=data.get("auth_options", None),
agent_id=data.get("agent_id", None),
ip=data.get("ip", None)
)
async def _handle_disconnect(self, packet): async def _handle_disconnect(self, packet):
pass # TODO """
From api.euphoria.io:
A disconnect-event indicates that the session is being closed. The
client will subsequently be disconnected.
If the disconnect reason is authentication changed, the client should
immediately reconnect.
"""
data = packet.get("data")
await self.controller.on_disconnect(data.get("reason"))
async def _handle_hello(self, packet): async def _handle_hello(self, packet):
""" """
@ -150,10 +211,11 @@ class Room:
data = packet.get("data") data = packet.get("data")
self.session = utils.Session.from_dict(data.get("session")) self.session = utils.Session.from_dict(data.get("session"))
self.account_has_access = data.get("account_has_access")
self.account_email_verified = data.get("account_email_verified")
self.room_is_private = data.get("room_is_private") self.room_is_private = data.get("room_is_private")
self.version = data.get("version") self.version = data.get("version")
self.account = data.get("account", None)
self.account_has_access = data.get("account_has_access", None)
self.account_email_verified = data.get("account_email_verified", None)
await self.controller.on_hello( await self.controller.on_hello(
data.get("id"), data.get("id"),
@ -166,7 +228,18 @@ class Room:
) )
async def _handle_join(self, packet): async def _handle_join(self, packet):
pass # TODO """
From api.euphoria.io:
A join-event indicates a session just joined the room.
"""
data = packet.get("data")
session = utils.Session.from_dict(data)
# update self.listing
self.listing.add(session)
await self.controller.on_join(session)
async def _handle_login(self, packet): async def _handle_login(self, packet):
pass # TODO pass # TODO
@ -178,13 +251,43 @@ class Room:
pass # TODO pass # TODO
async def _handle_nick(self, packet): async def _handle_nick(self, packet):
pass # TODO """
From api.euphoria.io:
nick-event announces a nick change by another session in the room.
"""
data = packet.get("data")
session_id = data.get("session_id")
to_nick = data.get("to")
# update self.listing
session = self.listing.by_sid(session_id)
if session:
session.nick = to_nick
await self.controller.on_nick(
session_id,
data.get("id"),
data.get("from"),
to_nick
)
async def _handle_edit_message(self, packet): async def _handle_edit_message(self, packet):
pass # TODO pass # TODO
async def _handle_part(self, packet): async def _handle_part(self, packet):
pass # TODO """
From api.euphoria.io:
A part-event indicates a session just disconnected from the room.
"""
data = packet.get("data")
session = utils.Session.from_dict(data)
# update self.listing
self.listing.remove(session.session_id)
await self.controller.on_part(session)
async def _handle_ping(self, packet): async def _handle_ping(self, packet):
""" """
@ -205,26 +308,37 @@ class Room:
pass # TODO pass # TODO
async def _handle_send(self, packet): async def _handle_send(self, packet):
pass # TODO """
From api.euphoria.io:
A send-event indicates a message received by the room from another
session.
"""
data = packet.get("data")
message = utils.Message.from_dict(data)
await self.controller.on_send(message)
async def _handle_snapshot(self, packet): async def _handle_snapshot(self, packet):
""" """
From api.euphoria.io:
A snapshot-event indicates that a session has successfully joined a A snapshot-event indicates that a session has successfully joined a
room. It also offers a snapshot of the rooms state and recent history. room. It also offers a snapshot of the rooms state and recent history.
""" """
data = packet.get("data") data = packet.get("data")
for session_data in data.get("listing"): sessions = [utils.Session.from_dict(d) for d in data.get("listing")]
session = utils.Session.from_dict(session_data) messages = [utils.Message.from_dict(d) for d in data.get("log")]
# update self.listing
for session in sessions:
self.listing.add(session) self.listing.add(session)
log = [utils.Message.from_dict(d) for d in data.get("log")] self.session.nick = data.get("nick", None)
self.session.nick = data.get("nick") self.pm_with_nick = data.get("pm_with_nick", None),
self.pm_with_user_id = data.get("pm_with_user_id", None)
self.pm_with_nick = data.get("pm_with_nick"),
self.pm_with_user_id = data.get("pm_with_user_id")
await self.controller.on_connected() await self.controller.on_connected()
@ -232,8 +346,8 @@ class Room:
data.get("identity"), data.get("identity"),
data.get("session_id"), data.get("session_id"),
self.version, self.version,
self.listing, sessions, # listing
log, messages, # log
nick=self.session.nick, nick=self.session.nick,
pm_with_nick=self.pm_with_nick, pm_with_nick=self.pm_with_nick,
pm_with_user_id=self.pm_with_user_id pm_with_user_id=self.pm_with_user_id

View file

@ -1,8 +1,23 @@
import re
__all__ = ["mention", "mention_reduced", "similar", "Session", "Listing", "Message", "Log"]
def mention(nick):
return "".join(c for c in nick if c not in ".!?;&<'\"" and not c.isspace())
def mention_reduced(nick):
return mention(nick).lower()
def similar(nick1, nick2):
return mention_reduced(nick1) == mention_reduced(nick2)
class Session: class Session:
def __init__(self, user_id, name, server_id, server_era, session_id, is_staff=None, def __init__(self, user_id, nick, server_id, server_era, session_id, is_staff=None,
is_manager=None, client_address=None, real_address=None): is_manager=None, client_address=None, real_address=None):
self.user_id = user_id self.user_id = user_id
self.name = name self.nick = nick
self.server_id = server_id self.server_id = server_id
self.server_era = server_era self.server_era = server_era
self.session_id = session_id self.session_id = session_id
@ -19,10 +34,10 @@ class Session:
d.get("server_id"), d.get("server_id"),
d.get("server_era"), d.get("server_era"),
d.get("session_id"), d.get("session_id"),
d.get("is_staff"), d.get("is_staff", None),
d.get("is_manager"), d.get("is_manager", None),
d.get("client_address"), d.get("client_address", None),
d.get("real_address") d.get("real_address", None)
) )
@property @property
@ -86,10 +101,13 @@ class Message():
d.get("time"), d.get("time"),
Session.from_dict(d.get("sender")), Session.from_dict(d.get("sender")),
d.get("content"), d.get("content"),
d.get("parent"), d.get("parent", None),
d.get("previous_edit_id"), d.get("previous_edit_id", None),
d.get("encryption_key"), d.get("encryption_key", None),
d.get("edited"), d.get("edited", None),
d.get("deleted"), d.get("deleted", None),
d.get("truncated") d.get("truncated", None)
) )
class Log:
pass # TODO