98 lines
3.1 KiB
Python
98 lines
3.1 KiB
Python
import websockets
|
|
import asyncio
|
|
import json
|
|
|
|
from macros import *
|
|
import bot as botPy
|
|
import data
|
|
import posts
|
|
import cmds
|
|
|
|
ws_global = None
|
|
is_connected = False
|
|
|
|
async def send_message(message: str):
|
|
global ws_global
|
|
if ws_global:
|
|
await ws_global.send(message)
|
|
|
|
|
|
async def send_internal_error(e: Exception):
|
|
global ws_global
|
|
if ws_global:
|
|
await ws_global.send(f"json:{{\"error\":\"Internal Python error: {e}\"}}")
|
|
|
|
|
|
async def websocket_client(bot: botPy.Bot):
|
|
global ws_global, is_connected
|
|
port = bot.args["port"]
|
|
async with websockets.connect(f"ws://127.0.0.1:{port}") as ws:
|
|
ws_global = ws
|
|
is_connected = True
|
|
py_print(f"Connected webSocket server on ws://127.0.0.1:{port}")
|
|
|
|
await send_message("[Connection test] Hello from Python!")
|
|
|
|
while True:
|
|
response = await ws.recv()
|
|
if not response.startswith("json:"):
|
|
py_print(f"Received from Rust: {response}")
|
|
await parse_json(response, bot)
|
|
|
|
|
|
async def parse_json(response: str, bot: botPy.Bot):
|
|
if response.startswith("json:"):
|
|
json_str = response[5:]
|
|
try:
|
|
json_response = json.loads(json_str)
|
|
if json_response["value"] not in ["respond_mentions"] or bot.args["dev"]:
|
|
py_print(f"Received from Rust: {response}")
|
|
|
|
result = await json_to_func(json_response, bot)
|
|
await ws_global.ping()
|
|
await send_message(f"json:{json.dumps(result)}")
|
|
except json.JSONDecodeError as e:
|
|
if bot.args["dev"]: py_print(f"failed to parse json: {json_str}\n reason: {e}")
|
|
|
|
|
|
def run_thread(bot: botPy.Bot):
|
|
loop = asyncio.new_event_loop()
|
|
asyncio.set_event_loop(loop)
|
|
loop.run_until_complete(websocket_client(bot))
|
|
|
|
|
|
async def json_to_func(v: dict, bot: botPy.Bot) -> dict:
|
|
if "type" not in v or "value" not in v or not isinstance(v, dict):
|
|
if bot.args["dev"]: py_print("JSON is not a dictionary or does not include \"type\" and \"value\" keys.")
|
|
return
|
|
if v["type"] != "function":
|
|
v_type = v["type"]
|
|
if bot.args["dev"]: py_print(f"Type \"{v_type}\" is not supported.")
|
|
return
|
|
|
|
value_supported = True
|
|
r = False
|
|
|
|
match v["value"]:
|
|
case "update_data_file": r = data .write_data (bot)
|
|
case "respond_mentions": r = await cmds .respond_to_mention(bot)
|
|
case "add_new_posts": r = await posts.add_new_posts (bot, *v["args"])
|
|
case "add_post_url": r = await posts.add_post_url (bot, *v["args"])
|
|
case "remove_post_url": r = data .remove_post (bot, *v["args"])
|
|
case "set_approve_post": r = data .set_approve_post (bot, *v["args"])
|
|
case "set_vote_post": r = data .set_vote_post (bot, *v["args"])
|
|
case "remove_old_posts": r = data .remove_old_posts (bot, *v["args"])
|
|
case "update_cfg": r = await bot .update_cfg_str (*v["args"])
|
|
case "stop_praw": r = await bot .stop ()
|
|
case _: value_supported = False
|
|
|
|
if not value_supported:
|
|
val = v["value"]
|
|
py_print(f"Value \"{val}\" is not supported")
|
|
return {"type": "result", "value": False}
|
|
|
|
return result_json(r)
|
|
|
|
|
|
def result_json(bool: bool) -> dict:
|
|
return {"type": "result", "value": bool} |