108 lines
2.9 KiB
Python
108 lines
2.9 KiB
Python
from websockets.server import serve
|
|
import asyncio
|
|
import os
|
|
import time
|
|
import json
|
|
import random
|
|
import queue
|
|
import functools
|
|
from .parser import Parser, Statement
|
|
from watchdog.events import FileSystemEventHandler
|
|
from watchdog.events import FileModifiedEvent
|
|
from watchdog.observers import Observer
|
|
|
|
class FSEHandler(FileSystemEventHandler):
|
|
def __init__(self, queue, *args, **kwargs):
|
|
self.queue = queue
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def on_modified(self, event):
|
|
self.queue.put("")
|
|
|
|
async def serv(websocket, file, overrides={}):
|
|
message = await websocket.recv()
|
|
lmtime = 0
|
|
epsilon = 0.25 # tweak this to what makes sense. 0.25 seconds makes sense to me.
|
|
q = queue.Queue()
|
|
|
|
# make it read the file initially
|
|
q.put("")
|
|
|
|
# setup the watchdog
|
|
observer = Observer()
|
|
event_handler = FSEHandler(q)
|
|
observer.schedule(event_handler, file)
|
|
observer.start()
|
|
|
|
print("client connected")
|
|
|
|
while True:
|
|
# there are sometimes multiple writes bundled close together -- so
|
|
# debounce them.
|
|
q.get()
|
|
if time.time() - lmtime < epsilon:
|
|
continue
|
|
else:
|
|
lmtime = time.time()
|
|
|
|
parser = Parser(file)
|
|
parser.parse()
|
|
|
|
await websocket.send(
|
|
json.dumps(
|
|
{
|
|
"message": "clear",
|
|
"payload": "none",
|
|
}
|
|
)
|
|
)
|
|
|
|
for line in parser.ast:
|
|
if line["ticker"]:
|
|
await websocket.send(
|
|
json.dumps(
|
|
{
|
|
"message": "ticker",
|
|
"rate": line.commands["ticker"],
|
|
"payload": line.latex,
|
|
}
|
|
)
|
|
)
|
|
|
|
continue
|
|
|
|
# if the line has been assigned an id, make it so
|
|
if line["id"]:
|
|
ident = line.commands["id"]
|
|
print("performing substitution")
|
|
else:
|
|
# else just choose a safe option
|
|
ident = "placeholder" + str(random.randint(1, 100100))
|
|
|
|
if ident in overrides.keys():
|
|
to_send = overrides[ident]
|
|
else:
|
|
to_send = line.latex
|
|
|
|
|
|
await websocket.send(
|
|
json.dumps(
|
|
{
|
|
"message": "expression",
|
|
"id": ident,
|
|
"payload": to_send,
|
|
}
|
|
)
|
|
)
|
|
|
|
async def start_server(file, overrides):
|
|
wrapper = functools.partial(serv, file=file, overrides=overrides)
|
|
async with serve(wrapper, "localhost", 8765):
|
|
await asyncio.Future()
|
|
|
|
def main(file, overrides):
|
|
asyncio.run(start_server(file, overrides))
|
|
|
|
if __name__ == "__main__":
|
|
main("data/testing.desmos")
|