Major upgrades, much code and docs rewritten.

This commit is contained in:
Leo Vasanko
2023-10-17 21:33:31 +03:00
committed by Leo Vasanko
parent 27b89d6d38
commit bd680e3668
8 changed files with 455 additions and 131 deletions

View File

@@ -1,13 +1,10 @@
import asyncio
from importlib.resources import files
from pathlib import Path
import msgspec
from sanic import Sanic
from sanic.log import logger
from sanic.response import html
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
from . import watching
from .fileio import ROOT, FileServer
@@ -15,6 +12,7 @@ from .protocol import ErrorMsg, FileRange, StatusMsg
app = Sanic("cista")
fileserver = FileServer()
watching.register(app, "/api/watch")
def asend(ws, msg):
return ws.send(msg if isinstance(msg, bytes) else msgspec.json.encode(msg).decode())
@@ -27,22 +25,6 @@ async def start_fileserver(app, _):
async def stop_fileserver(app, _):
await fileserver.stop()
@app.before_server_start
async def start_watcher(app, _):
class Handler(FileSystemEventHandler):
def on_any_event(self, event):
watching.update(Path(event.src_path).relative_to(ROOT))
app.ctx.observer = Observer()
app.ctx.observer.schedule(Handler(), str(ROOT), recursive=True)
app.ctx.observer.start()
@app.after_server_stop
async def stop_watcher(app, _):
app.ctx.observer.stop()
app.ctx.observer.join()
@app.get("/")
async def index_page(request):
index = files("cista").joinpath("static", "index.html").read_text()
@@ -50,16 +32,6 @@ async def index_page(request):
app.static("/files", ROOT, use_content_range=True, stream_large_files=True, directory_view=True)
@app.websocket('/api/watch')
async def watch(request, ws):
try:
q = watching.pubsub[ws] = asyncio.Queue()
await asend(ws, {"root": watching.tree})
while True:
await asend(ws, await q.get())
finally:
del watching.pubsub[ws]
@app.websocket('/api/upload')
async def upload(request, ws):
alink = fileserver.alink
@@ -78,24 +50,28 @@ async def upload(request, ws):
d = f"{len(data)} bytes" if isinstance(data, bytes) else data
raise ValueError(f"Expected {req.end - pos} more bytes, got {d}")
# Report success
res = StatusMsg(status="upload", url=url, req=req)
res = StatusMsg(status="ack", req=req)
await asend(ws, res)
print(res)
await ws.drain()
except Exception as e:
res = ErrorMsg(error=str(e), url=url, req=req)
res = ErrorMsg(error=str(e), req=req)
await asend(ws, res)
logger.exception(repr(res), e)
return
@app.websocket("/ws")
async def ws(request, ws):
while True:
data = await ws.recv()
await ws.send(data)
@app.websocket('/api/download')
async def download(request, ws):
alink = fileserver.alink
url = request.url_for("download")
while True:
req = None
try:
print("Waiting for download command")
text = await ws.recv()
if not isinstance(text, str):
raise ValueError(f"Expected JSON control, got binary len(data) = {len(text)}")
@@ -108,12 +84,14 @@ async def download(request, ws):
await asend(ws, data)
pos += len(data)
# Report success
res = StatusMsg(status="download", url=url, req=req)
res = StatusMsg(status="ack", req=req)
await asend(ws, res)
print(ws, dir(ws))
await ws.drain()
print(res)
except Exception as e:
res = ErrorMsg(error=str(e), url=url, req=req)
res = ErrorMsg(error=str(e), req=req)
await asend(ws, res)
logger.exception(repr(res), e)
return