Ready to run.

This commit is contained in:
retoor 2024-12-29 16:51:03 +01:00
parent 79d4e850da
commit 8b212187d1
5 changed files with 144 additions and 133 deletions

View File

@ -1,7 +1,7 @@
BIN = ./.venv/bin/ BIN = ./.venv/bin/
PYTHON = ./.venv/bin/python PYTHON = ./.venv/bin/python
PIP = ./.venv/bin/pip PIP = ./.venv/bin/pip
APP_NAME=boeh APP_NAME=rwebgui
all: install build all: install build
@ -24,5 +24,5 @@ build:
$(PYTHON) -m build $(PYTHON) -m build
run: run:
$(BIN)$(APP_NAME) --port=3028 $(BIN)$(APP_NAME).serve --port=3080

View File

@ -1,8 +1,10 @@
from nio import AsyncClient, RoomMessageText
import random import random
from nio import AsyncClient, RoomMessageText
class BooeehBot: class BooeehBot:
def generate_boeh(self): def generate_boeh(self):
boeh = "b" boeh = "b"
for _ in range(random.randint(1, 10)): for _ in range(random.randint(1, 10)):
@ -10,9 +12,9 @@ class BooeehBot:
for _ in range(random.randint(1, 5)): for _ in range(random.randint(1, 5)):
boeh += "e" boeh += "e"
for _ in range(random.randint(1, 3)): for _ in range(random.randint(1, 3)):
boeh += "e" boeh += "e"
return boeh return boeh
def __init__(self, url, username, password): def __init__(self, url, username, password):
self.url = url self.url = url
self.username = username self.username = username

View File

@ -1,16 +1,17 @@
from rwebgui.app import Application
from aiohttp import web
import asyncio import asyncio
from concurrent.futures import ThreadPoolExecutor as Executor from concurrent.futures import ThreadPoolExecutor as Executor
from aiohttp import web
from rwebgui.app import Application
def main(): def main():
app = Application() app = Application()
executor = Executor(max_workers=20) executor = Executor(max_workers=20)
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.set_default_executor(executor) loop.set_default_executor(executor)
web.run_app(app, loop=loop,port=3080) web.run_app(app, loop=loop, port=3080)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1,59 +1,63 @@
import asyncio
import json
import pathlib import pathlib
from aiohttp import web import time
import uuid import uuid
from app.app import Application as BaseApplication
from aiohttp import web
from app.app import Application as BaseApplication
from rwebgui.component import Component from rwebgui.component import Component
import traceback
import time
import asyncio
import json
class EvalBox(Component): class EvalBox(Component):
async def on_change(self, value): async def on_change(self, value):
try: try:
if value and value.strip().endswith("="): if value and value.strip().endswith("="):
value = value.strip()[:-1] value = value.strip()[:-1]
try: try:
result = eval(value) result = eval(value)
value = value + "= " + str(result) value = value + "= " + str(result)
await self.set_attr("value",value) await self.set_attr("value", value)
except: except:
pass pass
except AttributeError as ex: except AttributeError:
print(value) print(value)
return value return value
class Button(Component): class Button(Component):
async def on_click(self, event): async def on_click(self, event):
component = self.app.search component = self.app.search
await component.set_attr("value","Woeiii") await component.set_attr("value", "Woeiii")
class Button1(Component): class Button1(Component):
async def on_click(self,event): async def on_click(self, event):
field = self.app.search field = self.app.search
await field.toggle() await field.toggle()
value = await field.get_style("display","block") value = await field.get_style("display", "block")
await self.set_attr("innerText", value) await self.set_attr("innerText", value)
class RandomString(Component): class RandomString(Component):
async def task_random(self): async def task_random(self):
import random import random
rand_bytes = [random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(15)] rand_bytes = [random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(15)]
random_data = "".join(rand_bytes) random_data = "".join(rand_bytes)
while True: while True:
remember = random_data[0] remember = random_data[0]
random_data = random_data[1:] + remember random_data = random_data[1:] + remember
await self.set_attr("innerHTML",random_data) await self.set_attr("innerHTML", random_data)
await asyncio.sleep(0.01) await asyncio.sleep(0.01)
class Counter(Component): class Counter(Component):
async def task_test(self): async def task_test(self):
@ -61,8 +65,6 @@ class Counter(Component):
await asyncio.sleep(10) await asyncio.sleep(10)
print("Slow task") print("Slow task")
async def task_increment(self): async def task_increment(self):
if not self.value: if not self.value:
self.value = 0 self.value = 0
@ -72,41 +74,46 @@ class Counter(Component):
except: except:
self.value = 0 self.value = 0
self.value += 1 self.value += 1
await self.set_attr("value",self.value) await self.set_attr("value", self.value)
await asyncio.sleep(1) await asyncio.sleep(1)
class GPT(Component): class GPT(Component):
class Children: class Children:
prompt = Component prompt = Component
answer = Component answer = Component
class submit(Component): class submit(Component):
async def trigger(self, id_, event, data): async def trigger(self, id_, event, data):
print("GOGOG",event,data) print("GOGOG", event, data)
return await super().trigger(id_, event, data) return await super().trigger(id_, event, data)
async def on_click(self,data):
from xmlrpc.client import ServerProxy async def on_click(self, data):
from xmlrpc.client import ServerProxy
client = ServerProxy("https://api.molodetz.nl/rpc") client = ServerProxy("https://api.molodetz.nl/rpc")
prompt = await self.app.prompt.get_attr("value") prompt = await self.app.prompt.get_attr("value")
print(prompt) print(prompt)
exit(0) exit(0)
await self.answer.set_attr("value",client.gpt4o(prompt)) await self.answer.set_attr("value", client.gpt4o(prompt))
return {"event_id":data['event_id'],"success":True} return {"event_id": data["event_id"], "success": True}
class SpeedMeter(Component): class SpeedMeter(Component):
def __init__(self, app, id_, description=None, ws = None): def __init__(self, app, id_, description=None, ws=None):
self.time_start = time.time() self.time_start = time.time()
self.bytes_received = 0 self.bytes_received = 0
super().__init__(app, id_, description, ws) super().__init__(app, id_, description, ws)
async def task_update(self): async def task_update(self):
while True: while True:
bytes_received = self.bytes_received bytes_received = self.bytes_received
self.bytes_received = 0 self.bytes_received = 0
await self.set_attr("value","{} kb/s".format(bytes_received / 1000)) await self.set_attr("value", f"{bytes_received / 1000} kb/s")
await asyncio.sleep(1) await asyncio.sleep(1)
async def trigger(self, id_, event, data): async def trigger(self, id_, event, data):
@ -116,7 +123,7 @@ class SpeedMeter(Component):
class App(Component): class App(Component):
class Children: class Children:
eval_box = EvalBox eval_box = EvalBox
search = Component search = Component
@ -142,31 +149,29 @@ class Application(BaseApplication):
self.location_static = self.location.joinpath("static") self.location_static = self.location.joinpath("static")
self.template_path = self.location.joinpath("templates") self.template_path = self.location.joinpath("templates")
super().__init__(template_path=self.template_path) super().__init__(template_path=self.template_path)
self.router.add_static('/static', self.location_static) self.router.add_static("/static", self.location_static)
self.router.add_get("/", self.index_handler) self.router.add_get("/", self.index_handler)
self.router.add_get("/ws/{uuid}", self.websocket_handler) self.router.add_get("/ws/{uuid}", self.websocket_handler)
async def websocket_handler(self, request): async def websocket_handler(self, request):
# Extract the UUID from the route # Extract the UUID from the route
uuid_value = request.match_info['uuid'] uuid_value = request.match_info["uuid"]
# Validate if it's a valid UUID # Validate if it's a valid UUID
try: try:
uuid_obj = uuid.UUID(uuid_value) uuid_obj = uuid.UUID(uuid_value)
except ValueError: except ValueError:
return web.Response(text="Invalid UUID", status=400) return web.Response(text="Invalid UUID", status=400)
# Upgrade the connection to WebSocket # Upgrade the connection to WebSocket
ws = web.WebSocketResponse() ws = web.WebSocketResponse()
await ws.prepare(request) await ws.prepare(request)
print(f"WebSocket connection established with UUID: {uuid_obj}") print(f"WebSocket connection established with UUID: {uuid_obj}")
component = App(self, "app", ws=ws) component = App(self, "app", ws=ws)
await component.service() await component.service()
return ws return ws
async def index_handler(self, request): async def index_handler(self, request):
return await self.render_template("index.html",request,{}) return await self.render_template("index.html", request, {})

View File

@ -1,54 +1,55 @@
import uuid import asyncio
import json
import time import time
import aiohttp import uuid
import asyncio
from aiohttp import web from aiohttp import web
class Component: class Component:
@classmethod @classmethod
def define(cls): def define(cls):
return cls return cls
def __init__(self,app, id_, description=None,ws: web.WebSocketResponse=None): def __init__(self, app, id_, description=None, ws: web.WebSocketResponse = None):
self.id = id_ self.id = id_
self.ws = ws self.ws = ws
self.app = app self.app = app
self.description = description self.description = description
self.children = [] self.children = []
self._callbacks = {} self._callbacks = {}
self.value = None self.value = None
self._running = False self._running = False
if not hasattr(self,"Children"): if not hasattr(self, "Children"):
return return
for name in dir(self.Children): for name in dir(self.Children):
if name.startswith("__"): if name.startswith("__"):
continue continue
obj = getattr(self.Children, name) obj = getattr(self.Children, name)
instance = obj(app=self.app,id_=name,ws=ws ) instance = obj(app=self.app, id_=name, ws=ws)
self.add_child(instance) self.add_child(instance)
instance.app = self instance.app = self
instance.ws = self.ws instance.ws = self.ws
setattr(self, name, instance) setattr(self, name, instance)
@classmethod @classmethod
def from_json(cls, json): def from_json(cls, json):
obj = cls(None, None) obj = cls(None, None)
obj.__dict__ = json obj.__dict__ = json
return obj return obj
@classmethod @classmethod
def to_json(cls): def to_json(cls):
obj = cls.__dict__ .copy() obj = cls.__dict__.copy()
return obj return obj
@classmethod @classmethod
def clone(cls): def clone(cls):
return cls.from_json(cls.to_json()) return cls.from_json(cls.to_json())
@property @property
def running(self): def running(self):
if not hasattr(self.app, "_running"): if not hasattr(self.app, "_running"):
@ -57,21 +58,25 @@ class Component:
@property @property
def tasks(self): def tasks(self):
tasks_ = [getattr(self, name) for name in dir(self) if name.startswith("task_") and hasattr(self, name)] tasks_ = [
getattr(self, name)
for name in dir(self)
if name.startswith("task_") and hasattr(self, name)
]
for child in self.children: for child in self.children:
tasks_ += child.tasks#.extend(await child.get_tasks()) tasks_ += child.tasks # .extend(await child.get_tasks())
return tasks_ return tasks_
async def communicate(self, event_id=None): async def communicate(self, event_id=None):
async for msg in self.ws: async for msg in self.ws:
if msg.type == web.WSMsgType.TEXT: if msg.type == web.WSMsgType.TEXT:
# Echo the message back to the client # Echo the message back to the client
#print(f"Received message: {msg.data}") # print(f"Received message: {msg.data}")
data = msg.json() data = msg.json()
if not event_id: if not event_id:
pass pass
#return data # return data
else: else:
if data.get("event_id") == event_id: if data.get("event_id") == event_id:
return data return data
@ -80,55 +85,55 @@ class Component:
def callbacks(self): def callbacks(self):
return hasattr(self.app, "callbacks") and self.app.callbacks or self._callbacks return hasattr(self.app, "callbacks") and self.app.callbacks or self._callbacks
async def trigger(self, id_, event, data):
async def trigger(self,id_, event,data):
if self.id == id_: if self.id == id_:
method_name = "on_"+event method_name = "on_" + event
if hasattr(self, method_name): if hasattr(self, method_name):
method = getattr(self, method_name) method = getattr(self, method_name)
await method(data) await method(data)
print("JAAJ") print("JAAJ")
for child in self.children: for child in self.children:
await child.trigger(id_,event,data) await child.trigger(id_, event, data)
async def register_callback(self, event_id, callback): async def register_callback(self, event_id, callback):
self.callbacks[event_id] = callback self.callbacks[event_id] = callback
async def call(self, method, args=None,id_=None, callback=True): async def call(self, method, args=None, id_=None, callback=True):
while not self.running: while not self.running:
await asyncio.sleep(0.1) await asyncio.sleep(0.1)
if not args: if not args:
args= [] args = []
event_id = str(uuid.uuid4()) event_id = str(uuid.uuid4())
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
future = loop.create_future() future = loop.create_future()
self.callbacks[event_id] = lambda data: future.set_result(data) self.callbacks[event_id] = lambda data: future.set_result(data)
await self.ws.send_json({ await self.ws.send_json(
"event_id": event_id, {
"event": "call", "event_id": event_id,
"id": id_ and id_ or self.id, "event": "call",
"method": method, "id": id_ and id_ or self.id,
"args": args, "method": method,
"callback": callback "args": args,
}) "callback": callback,
}
)
if callback: if callback:
response = await self.communicate(event_id=event_id) response = await self.communicate(event_id=event_id)
return response['result'] return response["result"]
#print("GLUKT") # print("GLUKT")
#return response['result'] # return response['result']
return True
#return await future
return True
# return await future
async def get_attr(self, key, default=None): async def get_attr(self, key, default=None):
result = await self.call("getAttr", [self.id, key],True) result = await self.call("getAttr", [self.id, key], True)
return result or default return result or default
async def set_attr(self, key, value): async def set_attr(self, key, value):
result = await self.call("setAttr", [self.id,key,value],callback=False) result = await self.call("setAttr", [self.id, key, value], callback=False)
return result return result
async def get(self, id_): async def get(self, id_):
if self.id == id_: if self.id == id_:
@ -139,16 +144,16 @@ class Component:
return child return child
async def set_data(self, key, value): async def set_data(self, key, value):
result = await self.call("setData", [self.id, key,value], callback=False) result = await self.call("setData", [self.id, key, value], callback=False)
return result return result
async def get_data(self, key, default=None): async def get_data(self, key, default=None):
result = await self.call("getData", [self.id,key], default,True) result = await self.call("getData", [self.id, key], default, True)
return result or default return result or default
async def set_style(self, key, value): async def set_style(self, key, value):
result = await self.call("setStyle", [self.id, key,value], callback=False) result = await self.call("setStyle", [self.id, key, value], callback=False)
return result return result
async def toggle(self): async def toggle(self):
value = await self.get_style("display", "block") value = await self.get_style("display", "block")
@ -160,13 +165,10 @@ class Component:
await self.set_style("display", value) await self.set_style("display", value)
async def get_style(self, key, default=None): async def get_style(self, key, default=None):
result = await self.call("getStyle", [self.id,key], default) result = await self.call("getStyle", [self.id, key], default)
return result or default return result or default
async def on_keyup(self, event):
async def on_keyup(self,event):
value = await self.get_attr("value") value = await self.get_attr("value")
if self.value != value: if self.value != value:
if hasattr(self, "on_change"): if hasattr(self, "on_change"):
@ -174,11 +176,10 @@ class Component:
self.value = value self.value = value
return self.value return self.value
async def get_tasks(self): async def get_tasks(self):
tasks = self.tasks tasks = self.tasks
for child in self.children: for child in self.children:
tasks += child.tasks#.extend(await child.get_tasks()) tasks += child.tasks # .extend(await child.get_tasks())
return tasks return tasks
async def set_running(self): async def set_running(self):
@ -197,42 +198,44 @@ class Component:
async for msg in self.ws: async for msg in self.ws:
if msg.type == web.WSMsgType.TEXT: if msg.type == web.WSMsgType.TEXT:
# Echo the message back to the client # Echo the message back to the client
#print(f"Received message: {msg.data}") # print(f"Received message: {msg.data}")
data = msg.json() data = msg.json()
response = {"event_id":data['event_id'],"success":True} response = {"event_id": data["event_id"], "success": True}
response['time_start'] = time.time() response["time_start"] = time.time()
if self.callbacks.get(data['event_id']): if self.callbacks.get(data["event_id"]):
self.callbacks[data['event_id']](data['result']) self.callbacks[data["event_id"]](data["result"])
elif data.get('data') and not data['data'].get('id'): elif data.get("data") and not data["data"].get("id"):
response['handled'] = False response["handled"] = False
elif data.get('data'): elif data.get("data"):
response['handled'] = True response["handled"] = True
response['data'] = await self.trigger(data['data']['id'], data['event'],data['data']) response["data"] = await self.trigger(
response['cancel'] = True data["data"]["id"], data["event"], data["data"]
)
response["cancel"] = True
response['time_end'] = time.time() response["time_end"] = time.time()
response['time_duration'] = response['time_end'] - response['time_start'] response["time_duration"] = (
await self.ws.send_json(response) response["time_end"] - response["time_start"]
)
#await ws.send_str(f"Echo: {msg.data}") await self.ws.send_json(response)
# await ws.send_str(f"Echo: {msg.data}")
elif msg.type == web.WSMsgType.ERROR: elif msg.type == web.WSMsgType.ERROR:
print(f"WebSocket error: {self.ws.exception()}") print(f"WebSocket error: {self.ws.exception()}")
except Exception as ex: except Exception as ex:
print(ex) print(ex)
pass pass
#async def the_task(): # async def the_task():
# while True: # while True:
# time.sleep(1) # time.sleep(1)
#while True: # while True:
tasks.append(events) tasks.append(events)
await asyncio.gather(*[task() for task in tasks]) await asyncio.gather(*[task() for task in tasks])
#await asyncio.create_task(asyncio.gather(*[task() for task in tasks])) # await asyncio.create_task(asyncio.gather(*[task() for task in tasks]))
#await tasks() # await tasks()
print("AFTERR") print("AFTERR")
def add_child(self, child): def add_child(self, child):
child.app = self.app child.app = self.app
child.ws = self.ws child.ws = self.ws