From eec9e57dd2ba7a06a4bdbd678fadfe119d16b6ce Mon Sep 17 00:00:00 2001 From: Anand Chitipothu Date: Fri, 7 May 2021 16:48:52 +0530 Subject: [PATCH] fix: fixed thumbnail generation from livecode Due to the recent changes to livecode, the code to generate svg from code got broken. Fixed that now. --- community/lms/doctype/lms_sketch/livecode.py | 79 +++++++++++++++++--- 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/community/lms/doctype/lms_sketch/livecode.py b/community/lms/doctype/lms_sketch/livecode.py index 512f48ec..e0cf2312 100644 --- a/community/lms/doctype/lms_sketch/livecode.py +++ b/community/lms/doctype/lms_sketch/livecode.py @@ -4,23 +4,82 @@ import websocket import json from .svg import SVG -def livecode_to_svg(livecode_ws_url, code, *, timeout=1): +# Files to pass to livecode server +# The same code is part of livecode-canvas.js +# TODO: generate livecode-canvas.js from this file +START = ''' +import sketch +code = open("main.py").read() +env = dict(sketch.__dict__) +exec(code, env) +''' + +SKETCH = ''' +import json + +def sendmsg(msgtype, function, args): + """Sends a message to the frontend. + + The frontend will receive the specified message whenever + this function is called. The frontend can decide to some + action on each of these messages. + """ + msg = dict(msgtype=msgtype, function=function, args=args) + print("--MSG--", json.dumps(msg)) + +def _draw(func, **kwargs): + sendmsg(msgtype="draw", function=func, args=kwargs) + +def circle(x, y, d): + """Draws a circle of diameter d with center (x, y). + """ + _draw("circle", x=x, y=y, d=d) + +def line(x1, y1, x2, y2): + """Draws a line from point (x1, y1) to point (x2, y2). + """ + _draw("line", x1=x1, y1=y1, x2=x2, y2=y2) + +def rect(x, y, w, h): + """Draws a rectangle on the canvas. + + Parameters + ---------- + x: x coordinate of the top-left corner of the rectangle + y: y coordinate of the top-left corner of the rectangle + w: width of the rectangle + h: height of the rectangle + """ + _draw("rect", x=x, y=y, w=w, h=h) + +def clear(): + _draw("clear") + +# clear the canvas on start +clear() +''' + +def livecode_to_svg(livecode_ws_url, code, *, timeout=3): """Renders the code as svg. """ - print("livecode_to_svg") ws = websocket.WebSocket() ws.settimeout(timeout) ws.connect(livecode_ws_url) msg = { "msgtype": "exec", - "runtime": "python-canvas", - "code": code + "runtime": "python", + "code": code, + "files": [ + {"filename": "start.py", "contents": START}, + {"filename": "sketch.py", "contents": SKETCH}, + ], + "command": ["python", "start.py"] } ws.send(json.dumps(msg)) messages = _read_messages(ws) - commands = [m['cmd'] for m in messages if m['msgtype'] == 'draw'] + commands = [m for m in messages if m['msgtype'] == 'draw'] img = draw_image(commands) return img.tostring() @@ -32,17 +91,19 @@ def _read_messages(ws): if not msg: break messages.append(json.loads(msg)) - except websocket.WebSocketTimeoutException: + except websocket.WebSocketTimeoutException as e: + print("Error:", e) pass return messages def draw_image(commands): img = SVG(width=300, height=300, viewBox="0 0 300 300", fill='none', stroke='black') for c in commands: + args = c['args'] if c['function'] == 'circle': - img.circle(cx=c['x'], cy=c['y'], r=c['d']/2) + img.circle(cx=args['x'], cy=args['y'], r=args['d']/2) elif c['function'] == 'line': - img.line(x1=c['x1'], y1=c['y1'], x2=c['x2'], y2=c['y2']) + img.line(x1=args['x1'], y1=args['y1'], x2=args['x2'], y2=args['y2']) elif c['function'] == 'rect': - img.rect(x=c['x'], y=c['y'], width=c['w'], height=c['h']) + img.rect(x=args['x'], y=args['y'], width=args['w'], height=args['h']) return img