From 72438cf8c38be26a547f8af80985994aec44533d Mon Sep 17 00:00:00 2001 From: Dom Hynes Date: Sat, 23 Jul 2022 22:29:44 +1000 Subject: [PATCH 1/2] added piio support --- meleeuploader/forms.py | 97 +++++++++++++++++++++++++++++++++++++++- meleeuploader/workers.py | 62 +++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/meleeuploader/forms.py b/meleeuploader/forms.py index e0bac88..6e25f94 100755 --- a/meleeuploader/forms.py +++ b/meleeuploader/forms.py @@ -159,6 +159,31 @@ def __button_action(self, data=None): else: 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): @@ -330,6 +355,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 +439,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 +707,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 +745,54 @@ 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), + data.get("player1_sponsor"), + data.get("player2_sponsor"), + ) + + 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 @@ -992,7 +1084,7 @@ def __update_chars(self, chars): self._p1char.load_form(dict(selected=p1)) self._p2char.load_form(dict(selected=p2)) - def __handle_players(self, p1_name, p2_name): + def __handle_players(self, p1_name, p2_name, p1_sponsor, p2_sponsor): if all( ( p1_name != "", @@ -1011,6 +1103,9 @@ def __handle_players(self, p1_name, p2_name): self._p1.value = p1_name self._p2.value = p2_name + self._p1_sponsor.value = p1_sponsor if p1_sponsor else "" + self._p2_sponsor.value = p2_sponsor if p2_sponsor else "" + def __sa_update(self, data): if consts.stop_updates and not consts.submitted: return diff --git a/meleeuploader/workers.py b/meleeuploader/workers.py index 311321c..c7a6655 100644 --- a/meleeuploader/workers.py +++ b/meleeuploader/workers.py @@ -130,6 +130,68 @@ def get_update(self): 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) + + player1 = raw_data["data"]["scoreboard"]["teams"]['1']['players'][0] + player2 = raw_data["data"]["scoreboard"]["teams"]['2']['players'][0] + + indexedTeams = {} + for team in raw_data["data"]["dbEntries"]["team"]: + indexedTeams[team['_id']] = team + + data = { + "player1": player1["name"], + "player2": player2["name"], + "round": raw_data["data"]["scoreboard"]["fields"]["round"]["value"], + } + + if (len(player1["team"])): + data["player1_sponsor"] = indexedTeams[player1["team"][0]]["name"] + if (len(player2["team"])): + data["player2_sponsor"] = indexedTeams[player2["team"][0]]["name"] + + 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): From 768047d581dd9937fc94cc1d8c0e37fbd0d7601f Mon Sep 17 00:00:00 2001 From: Dom Hynes Date: Sun, 24 Jul 2022 17:48:37 +1000 Subject: [PATCH 2/2] piio support handles teams + teams properly --- meleeuploader/forms.py | 25 +++++++------------ meleeuploader/workers.py | 52 ++++++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/meleeuploader/forms.py b/meleeuploader/forms.py index 6e25f94..fae6835 100755 --- a/meleeuploader/forms.py +++ b/meleeuploader/forms.py @@ -159,18 +159,14 @@ def __button_action(self, data=None): else: 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.form.lineEdit.setPlaceholderText("localhost") + self._pi_port.form.lineEdit.setPlaceholderText("80") self._pi_host.value = "localhost" self._pi_port.value = "80" @@ -180,7 +176,9 @@ def __init__(self): 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) + self.parent._MeleeUploader__hook_pi( + self._pi_host.value, self._pi_port.value + ) else: self.warning("You must provide a URL") @@ -714,7 +712,7 @@ def __show_piio_form(self): self._piio_thread.quit() self._piio_worker = None return - + self._piiowin = PiioInput() self._piiowin.parent = self self._piiowin.show() @@ -764,10 +762,8 @@ def __handle_piio_update(self, data): suffix = "" self.__handle_players( - data.get("player1", self._p1.value), + data.get("player1", self._p1.value), data.get("player2", self._p2.value), - data.get("player1_sponsor"), - data.get("player2_sponsor"), ) try: @@ -1084,7 +1080,7 @@ def __update_chars(self, chars): self._p1char.load_form(dict(selected=p1)) self._p2char.load_form(dict(selected=p2)) - def __handle_players(self, p1_name, p2_name, p1_sponsor, p2_sponsor): + def __handle_players(self, p1_name, p2_name): if all( ( p1_name != "", @@ -1103,9 +1099,6 @@ def __handle_players(self, p1_name, p2_name, p1_sponsor, p2_sponsor): self._p1.value = p1_name self._p2.value = p2_name - self._p1_sponsor.value = p1_sponsor if p1_sponsor else "" - self._p2_sponsor.value = p2_sponsor if p2_sponsor else "" - def __sa_update(self, data): if consts.stop_updates and not consts.submitted: return diff --git a/meleeuploader/workers.py b/meleeuploader/workers.py index c7a6655..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) @@ -130,6 +132,7 @@ def get_update(self): def send_update(self): self.sig.emit(self.data) + class PiioWorker(QObject): sig = pyqtSignal(object) data = None @@ -142,10 +145,10 @@ def startws(self): try: print("Hooking into Piio...") self.ws = websocket.WebSocketApp( - url=self.addr, - on_message=self.get_update, + url=self.addr, + on_message=self.get_update, on_error=self.on_error, - on_open=self.on_open_ws + on_open=self.on_open_ws, ) self.ws.run_forever() except: @@ -155,7 +158,6 @@ def on_open_ws(self, ws): print("piio connection open") self.ws.send('{"type":"subscribe","data":"scoreboard"}') - def closews(self): self.ws.close() @@ -165,23 +167,42 @@ def on_error(self, ws, error): def get_update(self, ws, message): raw_data = json.loads(message) - player1 = raw_data["data"]["scoreboard"]["teams"]['1']['players'][0] - player2 = raw_data["data"]["scoreboard"]["teams"]['2']['players'][0] - indexedTeams = {} for team in raw_data["data"]["dbEntries"]["team"]: - indexedTeams[team['_id']] = team + indexedTeams[team["_id"]] = team data = { - "player1": player1["name"], - "player2": player2["name"], "round": raw_data["data"]["scoreboard"]["fields"]["round"]["value"], } - if (len(player1["team"])): - data["player1_sponsor"] = indexedTeams[player1["team"][0]]["name"] - if (len(player2["team"])): - data["player2_sponsor"] = indexedTeams[player2["team"][0]]["name"] + 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() @@ -193,6 +214,7 @@ def stop(self): def send_update(self): self.sig.emit(self.data) + class WriteWorker(QObject): textWritten = pyqtSignal(str)