Hype-2/pyxterm.py

93 lines
2.4 KiB
Python

#!/usr/bin/env python3
import argparse
from flask import Flask, render_template
from flask_socketio import SocketIO
import pty
import os
import subprocess
import select
import termios
import struct
import fcntl
import shlex
import sys
app = Flask(__name__, template_folder="templates", static_folder=".", static_url_path="")
app.config["SECRET_KEY"] = "secret!"
app.config["fd"] = None
app.config["child_pid"] = None
socketio = SocketIO(app)
def set_winsize(fd, row, col, xpix=0, ypix=0):
winsize = struct.pack("HHHH", row, col, xpix, ypix)
fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize)
def read_and_forward_pty_output():
max_read_bytes = 1024 * 20
while True:
socketio.sleep(0.01)
if app.config["fd"]:
timeout_sec = 0
(data_ready, _, _) = select.select([app.config["fd"]], [], [], timeout_sec)
if data_ready:
output = os.read(app.config["fd"], max_read_bytes).decode(
errors="ignore"
)
socketio.emit("pty-output", {"output": output}, namespace="/pty")
@app.route("/")
def index():
return render_template("pyxterm.html")
@socketio.on("pty-input", namespace="/pty")
def pty_input(data):
if app.config["fd"]:
os.write(app.config["fd"], data["input"].encode())
@socketio.on("resize", namespace="/pty")
def resize(data):
if app.config["fd"]:
set_winsize(app.config["fd"], data["rows"], data["cols"])
@socketio.on("connect", namespace="/pty")
def connect():
if app.config["child_pid"]:
return
(child_pid, fd) = pty.fork()
if child_pid == 0:
subprocess.run(app.config["cmd"])
else:
app.config["fd"] = fd
app.config["child_pid"] = child_pid
set_winsize(fd, 50, 50)
cmd = " ".join(shlex.quote(c) for c in app.config["cmd"])
socketio.start_background_task(target=read_and_forward_pty_output)
def main():
parser = argparse.ArgumentParser(
description=(
),
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"--command", default="bash", help="Command to run in the terminal"
)
parser.add_argument(
"--cmd-args",
default="",
)
args = parser.parse_args()
app.config["cmd"] = [args.command] + shlex.split(args.cmd_args)
green = "\033[92m"
end = "\033[0m"
socketio.run(app, port=5008, host='0.0.0.0')
if __name__ == "__main__":
main()