diff --git a/meleeuploader/forms.py b/meleeuploader/forms.py index e0bac88..fae6835 100755 --- a/meleeuploader/forms.py +++ b/meleeuploader/forms.py @@ -160,6 +160,29 @@ def __button_action(self, data=None): self.warning("You must provide a URL") +class PiioInput(BaseWidget): + def __init__(self): + super(PiioInput, self).__init__("Piio") + self._pi_host = ControlText("Piio Host") + self._pi_port = ControlText("Piio Port") + self._pi_host.form.lineEdit.setPlaceholderText("localhost") + self._pi_port.form.lineEdit.setPlaceholderText("80") + + self._pi_host.value = "localhost" + self._pi_port.value = "80" + + self._button = ControlButton("Submit") + self._button.value = self.__button_action + + def __button_action(self, data=None): + if self._pi_host.value and self._pi_port.value: + self.parent._MeleeUploader__hook_pi( + self._pi_host.value, self._pi_port.value + ) + else: + self.warning("You must provide a URL") + + class YouTubeSelector(BaseWidget): def __init__(self): super(YouTubeSelector, self).__init__("YouTube Account Selector") @@ -330,6 +353,7 @@ def __init__(self): {"Toggle SA Hook": self.__show_sa_form}, {"Toggle SC Hook": self.__show_sc_form}, {"Toggle Streameta Hook": self.__show_sm_form}, + {"Toggle Piio Hook": self.__show_piio_form}, {"About": self.__about_info}, ], "Save/Clear": [ @@ -413,6 +437,12 @@ def __init__(self): self._smf = ControlText() self._smf.value = "" + # Piio + self._piio_worker = None + self._piio_thread = None + self._pi_add = ControlText() + self._pi_add.value = "" + # Define the mapping of the form values json to form fields self._form_fields = { "ename": self._ename, @@ -675,6 +705,18 @@ def __show_sm_form(self): self._smwin.parent = self self._smwin.show() + def __show_piio_form(self): + if self._piio_worker: + self._piio_worker.stop() + print("Unhooked from Piio") + self._piio_thread.quit() + self._piio_worker = None + return + + self._piiowin = PiioInput() + self._piiowin.parent = self + self._piiowin.show() + def __hook_sa(self, host, port): self._sawin.close() self.warning( @@ -701,6 +743,52 @@ def __hook_obs(self, host, port, password, stopUpdates): self._obst.started.connect(self._obs.startobs) self._obst.start() + def __hook_pi(self, host, port): + self._piiowin.close() + self.warning( + "Please make sure piio is open", + title="MeleeUploader", + ) + self._piio_worker = workers.PiioWorker(host, port) + self._piio_thread = QtCore.QThread() + self._piio_worker.moveToThread(self._piio_thread) + self._piio_worker.sig.connect(self.__handle_piio_update) + self._piio_thread.started.connect(self._piio_worker.startws) + self._piio_thread.start() + + def __handle_piio_update(self, data): + prefix = "" + mtype = "" + suffix = "" + + self.__handle_players( + data.get("player1", self._p1.value), + data.get("player2", self._p2.value), + ) + + try: + match = data.get("round", None) + if match: + for t in consts.match_types: + if t.lower() in match.lower(): + mtype = t + prefix = "" + suffix = "" + if not match.find(t): + sections = match.split(t) + suffix = sections[1].strip() + if match.find(t) == -1 and match.find(t.lower()) >= 0: + pass + else: + sections = match.split(t) + prefix = sections[0].strip() + suffix = sections[1].strip() + self._mtype.value = mtype + self._mprefix.value = prefix + self._msuffix.value = suffix + except Exception as e: + print(e) + def __handle_obs(self, recording): if recording: # timestamps for the description will use this as 00:00 diff --git a/meleeuploader/workers.py b/meleeuploader/workers.py index 311321c..3bbf10d 100644 --- a/meleeuploader/workers.py +++ b/meleeuploader/workers.py @@ -1,13 +1,15 @@ #!/usr/bin/env python3 import json +import re from time import sleep import requests import websocket -from .obswebsocket import obsws, events from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot +from .obswebsocket import events, obsws + class SAWorker(QObject): sig = pyqtSignal(object) @@ -131,6 +133,88 @@ def send_update(self): self.sig.emit(self.data) +class PiioWorker(QObject): + sig = pyqtSignal(object) + data = None + + def __init__(self, host, port): + super().__init__() + self.addr = f"ws://{host}:{port}" + + def startws(self): + try: + print("Hooking into Piio...") + self.ws = websocket.WebSocketApp( + url=self.addr, + on_message=self.get_update, + on_error=self.on_error, + on_open=self.on_open_ws, + ) + self.ws.run_forever() + except: + print("Failed to hook into Piio") + + def on_open_ws(self, ws): + print("piio connection open") + self.ws.send('{"type":"subscribe","data":"scoreboard"}') + + def closews(self): + self.ws.close() + + def on_error(self, ws, error): + print(error) + + def get_update(self, ws, message): + raw_data = json.loads(message) + + indexedTeams = {} + for team in raw_data["data"]["dbEntries"]["team"]: + indexedTeams[team["_id"]] = team + + data = { + "round": raw_data["data"]["scoreboard"]["fields"]["round"]["value"], + } + + try: + for index, team in raw_data["data"]["scoreboard"]["teams"].items(): + names = [] + for player in team["players"]: + name = player["name"] + teams_no_regex = [] + + for team_id in player["team"]: + team = indexedTeams[team_id] + + if team["regex"]: + name = re.sub(team["regex"], team["prefix"], name) + else: + teams_no_regex.append(team) + + if teams_no_regex: + delimiter = teams_no_regex[-1]["delimiter"] + team_names = map(lambda t: t["prefix"], teams_no_regex) + whole_prefix = " ".join(team_names) + delimiter + name = whole_prefix + name + + names.append(name) + + data[f"player{index}"] = " & ".join(names) + + except Exception as e: + print(e) + raise e + + self.data = data + self.send_update() + + def stop(self): + self.ws.close() + + @pyqtSlot() + def send_update(self): + self.sig.emit(self.data) + + class WriteWorker(QObject): textWritten = pyqtSignal(str)