2024-04-08 17:08:24 -06:00
|
|
|
const pyodidePromise = import("https://cdn.jsdelivr.net/npm/pyodide@0.25.1/pyodide.mjs")
|
2024-04-01 16:46:45 -06:00
|
|
|
|
|
|
|
const HOME = "/home/web_user"
|
|
|
|
|
|
|
|
async function createInstance() {
|
|
|
|
let instance = await pyodide.loadPyodide()
|
|
|
|
instance.runPython("import sys")
|
|
|
|
self.postMessage({type: "loaded"})
|
|
|
|
return instance
|
|
|
|
}
|
|
|
|
const initialized = createInstance()
|
|
|
|
|
|
|
|
class Buffer {
|
|
|
|
constructor() {
|
|
|
|
this.buf = []
|
|
|
|
}
|
|
|
|
|
|
|
|
write(s) {
|
|
|
|
this.buf.push(s)
|
|
|
|
}
|
|
|
|
|
|
|
|
value() {
|
|
|
|
return this.buf.join("")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function handleMessage(event) {
|
|
|
|
let data = event.data
|
|
|
|
|
|
|
|
let instance = await initialized
|
|
|
|
let fs = instance._module.FS
|
|
|
|
|
|
|
|
let ret = {
|
|
|
|
result: null,
|
|
|
|
answer: null,
|
|
|
|
stdout: null,
|
|
|
|
stderr: null,
|
|
|
|
traceback: null,
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (data.type) {
|
|
|
|
case "nop":
|
|
|
|
// You might want to do nothing in order to display to the user that a run can now be handled
|
|
|
|
break
|
|
|
|
case "run":
|
|
|
|
let sys = instance.globals.get("sys")
|
|
|
|
sys.stdout = new Buffer()
|
|
|
|
sys.stderr = new Buffer()
|
|
|
|
instance.globals.set("setanswer", (s) => {ret.answer = s})
|
|
|
|
|
|
|
|
try {
|
|
|
|
ret.result = await instance.runPythonAsync(data.code)
|
|
|
|
} catch (err) {
|
|
|
|
ret.traceback = err
|
|
|
|
}
|
|
|
|
ret.stdout = sys.stdout.value()
|
|
|
|
ret.stderr = sys.stderr.value()
|
|
|
|
break
|
|
|
|
case "wget":
|
|
|
|
let url = data.url
|
|
|
|
let dir = data.directory || fs.cwd()
|
|
|
|
let filename = url.split("/").pop()
|
|
|
|
let path = dir + "/" + filename
|
|
|
|
|
|
|
|
if (fs.analyzePath(path).exists) {
|
|
|
|
fs.unlink(path)
|
|
|
|
}
|
|
|
|
fs.createLazyFile(dir, filename, url, true, false)
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
ret.result = "Unknown message type: " + data.type
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if (data.channel) {
|
|
|
|
data.channel.postMessage(ret)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.addEventListener("message", e => handleMessage(e))
|