Clean up Connection and add logging

This commit is contained in:
Joscha 2017-03-28 13:40:06 +00:00
parent 3b3ce99625
commit aee8e5c118

View file

@ -1,10 +1,13 @@
import json import json
import logging
import time import time
import threading import threading
import websocket import websocket
from websocket import WebSocketException as WSException from websocket import WebSocketException as WSException
from . import callbacks from .callbacks import Callbacks
logger = logging.getLogger(__name__)
class Connection(): class Connection():
""" """
@ -24,15 +27,13 @@ class Connection():
def __init__(self, room, url_format=None): def __init__(self, room, url_format=None):
""" """
room - name of the room to connect to room - name of the room to connect to
url_format - url the bot will connect to, where the room name is represented by {}
""" """
self.room = room self.room = room
if not url_format: self._url_format = url_format or ROOM_FORMAT
url_format = self.ROOM_FORMAT
self._url = url_format.format(self.room)
self._stopping = False self._stopping = False
@ -46,8 +47,9 @@ class Connection():
""" """
_connect(tries, delay) -> bool _connect(tries, delay) -> bool
tries - maximum number of retries delay - delay between retries (in seconds)
-1 -> retry indefinitely tries - maximum number of retries
-1 -> retry indefinitely
Returns True on success, False on failure. Returns True on success, False on failure.
@ -56,48 +58,62 @@ class Connection():
while tries != 0: while tries != 0:
try: try:
url = self._url_format.format(self.room)
logger.log("Connecting to url: {!r}".format(url))
logger.debug("{} {} left".format(
tries-1 if tries>0 else "infinite",
"tries" if tries!=1 else "try" # proper english :D
))
self._ws = websocket.create_connection( self._ws = websocket.create_connection(
self._url, url,
enable_multithread=True enable_multithread=True
) )
self._callbacks.call("connect")
return True
except WSException: except WSException:
if tries > 0: if tries > 0:
tries -= 1 tries -= 1
if tries != 0: if tries != 0:
logger.log("Connection failed. Retrying in {} seconds.".format(delay))
time.sleep(delay) time.sleep(delay)
else:
logger.debug("Connected")
self._callbacks.call("connect")
return True
return False return False
def disconnect(self): def disconnect(self):
""" """
disconnect() -> None disconnect() -> None
Reconnect to the room. Disconnect from the room.
WARNING: To completely disconnect, use stop(). This will cause the connection to reconnect.
To completely disconnect, use stop().
""" """
if self._ws: if self._ws:
self._ws.close() self._ws.close()
self._ws = None self._ws = None
logger.debug("Disconnected")
self._callbacks.call("disconnect") self._callbacks.call("disconnect")
def launch(self): def launch(self):
""" """
launch() -> Thread launch() -> Thread
Connect to the room and spawn a new thread running run. Connect to the room and spawn a new thread.
""" """
if self._connect(tries=1): if self._connect(tries=1):
self._thread = threading.Thread(target=self._run, self._thread = threading.Thread(target=self._run,
name="{}-{}".format(self.room, int(time.time()))) name="{}-{}".format(self.room, int(time.time())))
logger.debug("Launching new thread: {}".format(self._thread.name))
self._thread.start() self._thread.start()
return self._thread return self._thread
else: else:
logger.debug("Room probably doesn't exist.");
self.stop() self.stop()
def _run(self): def _run(self):
@ -107,6 +123,7 @@ class Connection():
Receive messages. Receive messages.
""" """
logger.debug("Running")
while not self._stopping: while not self._stopping:
try: try:
self._handle_json(self._ws.recv()) self._handle_json(self._ws.recv())
@ -123,6 +140,7 @@ class Connection():
Joins the thread launched by self.launch(). Joins the thread launched by self.launch().
""" """
logger.debug("Stopping")
self._stopping = True self._stopping = True
self.disconnect() self.disconnect()
@ -131,6 +149,28 @@ class Connection():
if self._thread and self._thread != threading.current_thread(): if self._thread and self._thread != threading.current_thread():
self._thread.join() self._thread.join()
def switch_to(self, new_room):
"""
switch_to(new_room) -> bool
Returns True on success, False on failure.
Attempts to connect to new_room.
"""
old_room = self.room
logger.info("Switching to &{} from &{}".format(old_room, new_room))
self.room = new_room
self.disconnect()
if not self._connect(tries=1):
logger.info("Could not connect to &{}: Connecting to ${} again.".format(new_room, old_room))
self.room = old_room
self._connect()
return False
return True
def next_id(self): def next_id(self):
""" """
next_id() -> id next_id() -> id
@ -184,22 +224,20 @@ class Connection():
Handle incoming packets Handle incoming packets
""" """
if "data" in packet: ptype = packet.get("type")
data = packet["data"] logger.debug("Handling packet of type {}.".format(ptype))
else:
data = None
if "error" in packet: data = packet.get("data")
error = packet["error"] error = packet.get("error")
else: if error:
error = None logger.debug("Error in packet: {!r}".format(error))
self._callbacks.call(packet["type"], data, error)
if "id" in packet: if "id" in packet:
self._id_callbacks.call(packet["id"], data, error) self._id_callbacks.call(packet["id"], data, error)
self._id_callbacks.remove(packet["id"]) self._id_callbacks.remove(packet["id"])
self._callbacks.call(packet["type"], data, error)
def _send_json(self, data): def _send_json(self, data):
""" """
_send_json(data) -> None _send_json(data) -> None