Skip to content

Commit af4da0c

Browse files
authored
Merge pull request #21 from cs01/cs01/cleanup
2 parents 8cc4fb2 + 4fa5785 commit af4da0c

File tree

9 files changed

+154
-115
lines changed

9 files changed

+154
-115
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## 0.5.0.0
2+
3+
* Update dependencies xtermjs and socketio
4+
* Turn off flask's logging
5+
* Update setup.py to install from pinned dependencies in requirements.tx

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
include README.md LICENSE
1+
include README.md LICENSE requirements.txt
22
recursive-include pyxtermjs *

README.md

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,36 @@ This is a
3232
There are a few ways to install and run.
3333

3434
### Clone & Run Locally
35-
Clone this repository, enter the `pyxtermjs` directory, then run:
35+
Clone this repository, enter the `pyxtermjs` directory.
36+
37+
If you have [nox](https://github.com/theacodes/nox) you can run the following.
38+
```
39+
> nox -s run
40+
```
41+
Nox takes care of setting up a virtual environment and running the right command for you. You can pass arguments to the server like this
3642
```
37-
> python -m venv venv # must be python3.6+
38-
> venv/bin/pip install -r requirements.txt
39-
> venv/bin/python -m pyxtermjs
40-
serving on http://127.0.0.1:5000
43+
> nox -s run -- --debug
4144
```
4245

43-
### Install or Run latest version on PyPI
44-
You can use [pipx](https://github.com/pipxproject/pipx) to try it out.
46+
If you don't have nox, you can run the following from inside a virtual environment.
4547
```
46-
> pipx run pyxtermjs
47-
serving on http://127.0.0.1:5000
48+
> pip install -r requirements.txt
49+
> python -m pyxtermjs
50+
> python -m pyxtermjs --debug
4851
```
4952

50-
You can also and have `pyxtermjs` installed in an isolated environment, yet available on your $PATH with
53+
### Install
54+
You can install with [pipx](https://github.com/pipxproject/pipx) (recommended) or pip.
5155
```
5256
> pipx install pyxtermjs
57+
> pyxtermjs
5358
```
5459

55-
### Run from GitHub source
56-
Use [pipx](https://github.com/pipxproject/pipx) for this as well.
60+
Or you can try run latest version on PyPI
5761
```
58-
> pipx run --spec git+https://github.com/cs01/pyxtermjs.git pyxtermjs
59-
serving on http://127.0.0.1:5000
62+
> pipx run pyxtermjs
6063
```
6164

62-
6365
## API
6466
```
6567
> pyxtermjs --help

noxfile.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
nox.options.reuse_existing_virtualenvs = True
88

99

10+
@nox.session()
11+
def run(session):
12+
session.install(".")
13+
session.run("python", "-m", "pyxtermjs", *session.posargs)
14+
15+
1016
def has_changes():
1117
status = (
1218
subprocess.run(

pyxtermjs/app.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
import struct
1111
import fcntl
1212
import shlex
13+
import logging
14+
import sys
1315

16+
logging.getLogger("werkzeug").setLevel(logging.ERROR)
1417

15-
__version__ = "0.4.0.2"
18+
__version__ = "0.5.0.0"
1619

1720
app = Flask(__name__, template_folder=".", static_folder=".", static_url_path="")
1821
app.config["SECRET_KEY"] = "secret!"
@@ -22,6 +25,7 @@
2225

2326

2427
def set_winsize(fd, row, col, xpix=0, ypix=0):
28+
logging.debug("setting window size with termios")
2529
winsize = struct.pack("HHHH", row, col, xpix, ypix)
2630
fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize)
2731

@@ -49,20 +53,21 @@ def pty_input(data):
4953
terminal.
5054
"""
5155
if app.config["fd"]:
52-
# print("writing to ptd: %s" % data["input"])
53-
os.write(app.config["fd"], data["input"]["key"].encode())
56+
logging.debug("received input from browser: %s" % data["input"])
57+
os.write(app.config["fd"], data["input"].encode())
5458

5559

5660
@socketio.on("resize", namespace="/pty")
5761
def resize(data):
5862
if app.config["fd"]:
63+
logging.debug(f"Resizing window to {data['rows']}x{data['cols']}")
5964
set_winsize(app.config["fd"], data["rows"], data["cols"])
6065

6166

6267
@socketio.on("connect", namespace="/pty")
6368
def connect():
6469
"""new client connected"""
65-
70+
logging.info("new client connected")
6671
if app.config["child_pid"]:
6772
# already started child process, don't start another
6873
return
@@ -81,13 +86,16 @@ def connect():
8186
app.config["child_pid"] = child_pid
8287
set_winsize(fd, 50, 50)
8388
cmd = " ".join(shlex.quote(c) for c in app.config["cmd"])
84-
print("child pid is", child_pid)
85-
print(
89+
# logging/print statements must go after this because... I have no idea why
90+
# but if they come before the background task never starts
91+
socketio.start_background_task(target=read_and_forward_pty_output)
92+
93+
logging.info("child pid is " + child_pid)
94+
logging.info(
8695
f"starting background task with command `{cmd}` to continously read "
8796
"and forward pty output to client"
8897
)
89-
socketio.start_background_task(target=read_and_forward_pty_output)
90-
print("task started")
98+
logging.info("task started")
9199

92100

93101
def main():
@@ -118,8 +126,16 @@ def main():
118126
if args.version:
119127
print(__version__)
120128
exit(0)
121-
print(f"serving on http://127.0.0.1:{args.port}")
122129
app.config["cmd"] = [args.command] + shlex.split(args.cmd_args)
130+
green = "\033[92m"
131+
end = "\033[0m"
132+
log_format = green + "pyxtermjs > " + end + "%(levelname)s (%(funcName)s:%(lineno)s) %(message)s"
133+
logging.basicConfig(
134+
format=log_format,
135+
stream=sys.stdout,
136+
level=logging.DEBUG if args.debug else logging.INFO,
137+
)
138+
logging.info(f"serving on http://127.0.0.1:{args.port}")
123139
socketio.run(app, debug=args.debug, port=args.port, host=args.host)
124140

125141

pyxtermjs/index.html

Lines changed: 82 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,99 @@
11
<html lang="en">
2-
<head>
3-
<meta charset="utf-8">
4-
<title>pyxterm.js</title>
5-
<style>
6-
html {
7-
font-family: arial;
8-
}
9-
</style>
10-
<link rel="stylesheet" href="https://unpkg.com/[email protected]/css/xterm.css" />
11-
</head>
12-
<body>
2+
<head>
3+
<meta charset="utf-8" />
4+
<title>pyxterm.js</title>
5+
<style>
6+
html {
7+
font-family: arial;
8+
}
9+
</style>
10+
<link
11+
rel="stylesheet"
12+
href="https://unpkg.com/[email protected]/css/xterm.css"
13+
/>
14+
</head>
15+
<body>
16+
<span style="font-size: 1.4em">pyxterm.js</span>&nbsp;&nbsp;&nbsp;
17+
<span style="font-size: small"
18+
>status:
19+
<span style="font-size: small" id="status">connecting...</span></span
20+
>
1321

14-
<span style="font-size: 1.4em;">pyxterm.js</span>&nbsp;&nbsp;&nbsp;
15-
<span style="font-size: small;">status: <span style="font-size: small;" id="status">connecting...</span></span>
22+
<div style="width: 100%; height: calc(100% - 50px)" id="terminal"></div>
1623

17-
<div style="width: 100%; height: calc(100% - 50px);" id="terminal"></div>
18-
19-
<p style="text-align: right; font-size: small;">
20-
built by <a href="https://grassfedcode.com">Chad Smith</a> <a href="https://github.com/cs01">GitHub</a>
21-
</p>
22-
<!-- xterm -->
23-
<script src="https://unpkg.com/[email protected]/lib/xterm.js"></script>
24-
<script src="https://unpkg.com/[email protected]/lib/xterm-addon-fit.js"></script>
25-
<script src="https://unpkg.com/[email protected]/lib/xterm-addon-web-links.js"></script>
26-
<script src="https://unpkg.com/[email protected]/lib/xterm-addon-sear
24+
<p style="text-align: right; font-size: small">
25+
built by <a href="https://chadsmith.dev">Chad Smith</a>
26+
<a href="https://github.com/cs01">GitHub</a>
27+
</p>
28+
<!-- xterm -->
29+
<script src="https://unpkg.com/[email protected]/lib/xterm.js"></script>
30+
<script src="https://unpkg.com/[email protected]/lib/xterm-addon-fit.js"></script>
31+
<script src="https://unpkg.com/[email protected]/lib/xterm-addon-web-links.js"></script>
32+
<script src="https://unpkg.com/[email protected]/lib/xterm-addon-sear
2733
ch.js"></script>
28-
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.min.js"></script>
34+
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.min.js"></script>
2935

30-
<script>
31-
const term = new Terminal({
36+
<script>
37+
const term = new Terminal({
3238
cursorBlink: true,
3339
macOptionIsMeta: true,
3440
scrollback: true,
35-
});
36-
// https://github.com/xtermjs/xterm.js/issues/2941
37-
const fit = new FitAddon.FitAddon();
38-
term.loadAddon(fit);
39-
term.loadAddon(new WebLinksAddon.WebLinksAddon());
40-
term.loadAddon(new SearchAddon.SearchAddon());
41-
42-
term.open(document.getElementById('terminal'));
43-
fit.fit()
44-
term.resize(15, 50)
45-
console.log(`size: ${term.cols} columns, ${term.rows} rows`)
46-
fit.fit()
47-
term.write("Welcome to pyxterm.js!\nhttps://github.com/cs01/pyxterm.js\n")
48-
term.onKey((key, ev) => {
49-
console.log("pressed key", key)
50-
console.log("event", ev)
51-
socket.emit("pty-input", {"input": key})
52-
});
53-
54-
const socket = io.connect('/pty');
55-
const status = document.getElementById("status")
56-
57-
socket.on("pty-output", function(data){
58-
console.log("new output", data)
59-
term.write(data.output)
60-
})
41+
});
42+
// https://github.com/xtermjs/xterm.js/issues/2941
43+
const fit = new FitAddon.FitAddon();
44+
term.loadAddon(fit);
45+
term.loadAddon(new WebLinksAddon.WebLinksAddon());
46+
term.loadAddon(new SearchAddon.SearchAddon());
6147

62-
socket.on("connect", () => {
63-
fitToscreen()
64-
status.innerHTML = '<span style="background-color: lightgreen;">connected</span>'
65-
}
66-
)
48+
term.open(document.getElementById("terminal"));
49+
fit.fit();
50+
term.resize(15, 50);
51+
console.log(`size: ${term.cols} columns, ${term.rows} rows`);
52+
fit.fit();
53+
term.writeln("Welcome to pyxterm.js!");
54+
term.writeln("https://github.com/cs01/pyxterm.js");
55+
term.onData((data) => {
56+
console.log("key pressed in browser:", data);
57+
socket.emit("pty-input", { input: data });
58+
});
6759

68-
socket.on("disconnect", () => {
69-
status.innerHTML = '<span style="background-color: #ff8383;">disconnected</span>'
70-
})
60+
const socket = io.connect("/pty");
61+
const status = document.getElementById("status");
7162

72-
function fitToscreen(){
73-
fit.fit()
74-
socket.emit("resize", {"cols": term.cols, "rows": term.rows})
75-
}
63+
socket.on("pty-output", function (data) {
64+
console.log("new output received from server:", data.output);
65+
term.write(data.output);
66+
});
7667

77-
function debounce(func, wait_ms) {
78-
let timeout
79-
return function(...args) {
80-
const context = this
81-
clearTimeout(timeout)
82-
timeout = setTimeout(() => func.apply(context, args), wait_ms)
83-
}
84-
}
68+
socket.on("connect", () => {
69+
fitToscreen();
70+
status.innerHTML =
71+
'<span style="background-color: lightgreen;">connected</span>';
72+
});
8573

86-
const wait_ms = 50;
87-
window.onresize = debounce(fitToscreen, wait_ms)
74+
socket.on("disconnect", () => {
75+
status.innerHTML =
76+
'<span style="background-color: #ff8383;">disconnected</span>';
77+
});
8878

79+
function fitToscreen() {
80+
fit.fit();
81+
const dims = { cols: term.cols, rows: term.rows };
82+
console.log("sending new dimensions to server's pty", dims);
83+
socket.emit("resize", dims);
84+
}
8985

90-
</script>
86+
function debounce(func, wait_ms) {
87+
let timeout;
88+
return function (...args) {
89+
const context = this;
90+
clearTimeout(timeout);
91+
timeout = setTimeout(() => func.apply(context, args), wait_ms);
92+
};
93+
}
9194

92-
</body>
95+
const wait_ms = 50;
96+
window.onresize = debounce(fitToscreen, wait_ms);
97+
</script>
98+
</body>
9399
</html>

requirements.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
flask-socketio==5.1.1

requirements.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
#
2-
# This file is autogenerated by pip-compile
2+
# This file is autogenerated by pip-compile with python 3.8
33
# To update, run:
44
#
5-
# pip-compile
5+
# pip-compile requirements.in
66
#
77
bidict==0.21.2
88
# via python-socketio
9-
click==7.1.2
9+
click==8.0.1
1010
# via flask
11-
flask-socketio==5.0.1
12-
# via pyxtermjs (setup.py)
13-
flask==1.1.2
11+
flask==2.0.1
1412
# via flask-socketio
15-
itsdangerous==1.1.0
13+
flask-socketio==5.1.1
14+
# via -r requirements.in
15+
itsdangerous==2.0.1
1616
# via flask
17-
jinja2==2.11.3
17+
jinja2==3.0.1
1818
# via flask
19-
markupsafe==1.1.1
19+
markupsafe==2.0.1
2020
# via jinja2
21-
python-engineio==4.1.0
21+
python-engineio==4.2.1
2222
# via python-socketio
23-
python-socketio==5.2.1
23+
python-socketio==5.4.0
2424
# via flask-socketio
25-
werkzeug==1.0.1
25+
werkzeug==2.0.1
2626
# via flask

0 commit comments

Comments
 (0)