mirror of
https://github.com/paradoxxxzero/butterfly.git
synced 2026-06-06 12:29:40 +00:00
Major improvements. Now with a much better css stylable terminal
This commit is contained in:
@@ -33,22 +33,15 @@ class File(Route):
|
||||
class TermWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
|
||||
def pty(self):
|
||||
pid, fd = pty.fork()
|
||||
if pid == 0:
|
||||
self.pid, self.fd = pty.fork()
|
||||
if self.pid == 0:
|
||||
# Child
|
||||
try:
|
||||
fd_list = [int(i) for i in os.listdir('/proc/self/fd')]
|
||||
except OSError:
|
||||
fd_list = range(256)
|
||||
# Close all file descriptors other than
|
||||
# stdin, stdout, and stderr (0, 1, 2)
|
||||
for i in [i for i in fd_list if i > 2]:
|
||||
try:
|
||||
os.close(i)
|
||||
except OSError:
|
||||
pass
|
||||
os.closerange(3, 256)
|
||||
except:
|
||||
pass
|
||||
env = os.environ
|
||||
env["TERM"] = "xterm"
|
||||
env["TERM"] = "xterm-256color"
|
||||
env["COLORTERM"] = "wsterm"
|
||||
command = os.getenv('SHELL')
|
||||
env["SHELL"] = command
|
||||
@@ -57,39 +50,35 @@ class TermWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
os.path.dirname(__file__), '..', 'bin')), env["PATH"])
|
||||
p = Popen(command, env=env)
|
||||
p.wait()
|
||||
self.log.info('Exiting...')
|
||||
sys.exit(0)
|
||||
else:
|
||||
self.pid = pid
|
||||
self.fd = fd
|
||||
self.log.debug('Adding handler')
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)
|
||||
fcntl.fcntl(self.fd, fcntl.F_SETFL, os.O_NONBLOCK)
|
||||
|
||||
# Set the size of the terminal window:
|
||||
s = struct.pack("HHHH", 80, 80, 0, 0)
|
||||
fcntl.ioctl(fd, termios.TIOCSWINSZ, s)
|
||||
fcntl.ioctl(self.fd, termios.TIOCSWINSZ, s)
|
||||
|
||||
def utf8_error(e):
|
||||
self.log.error(e)
|
||||
|
||||
self.reader = io.open(
|
||||
fd,
|
||||
'rt',
|
||||
buffering=1024,
|
||||
newline="",
|
||||
encoding='UTF-8',
|
||||
closefd=False,
|
||||
errors='handle_special'
|
||||
)
|
||||
self.writer = io.open(
|
||||
fd,
|
||||
'wt',
|
||||
buffering=1024,
|
||||
newline="",
|
||||
encoding='UTF-8',
|
||||
self.fd,
|
||||
'rb',
|
||||
buffering=0,
|
||||
closefd=False
|
||||
)
|
||||
ioloop.add_handler(fd, self.shell, ioloop.READ)
|
||||
self.writer = io.open(
|
||||
self.fd,
|
||||
'wt',
|
||||
encoding='utf-8',
|
||||
closefd=False
|
||||
)
|
||||
ioloop.add_handler(self.fd, self.shell, ioloop.READ | ioloop.ERROR)
|
||||
|
||||
def open(self):
|
||||
self.log.info('Websocket opened')
|
||||
self.set_nodelay(True)
|
||||
self.pty()
|
||||
|
||||
def on_message(self, message):
|
||||
@@ -107,18 +96,24 @@ class TermWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
|
||||
def shell(self, fd, events):
|
||||
if events & ioloop.READ:
|
||||
self.log.info('shell %d: %d' % (fd, events))
|
||||
try:
|
||||
read = self.reader.read()
|
||||
except IOError:
|
||||
self.log.info('READ>%r' % read)
|
||||
self.write_message('Exited')
|
||||
self.write_message('DIE')
|
||||
return
|
||||
|
||||
self.log.info('READ>%r' % read)
|
||||
self.write_message(read)
|
||||
self.write_message(read.decode('utf-8', 'replace'))
|
||||
|
||||
if events & ioloop.ERROR:
|
||||
self.log.info('Closing due to ioloop fd handler error')
|
||||
# Terminated
|
||||
self.close()
|
||||
|
||||
def on_close(self):
|
||||
if self.pid == 0:
|
||||
return
|
||||
self.writer.write('')
|
||||
self.writer.flush()
|
||||
os.close(self.fd)
|
||||
|
||||
@@ -7,8 +7,9 @@ $ ->
|
||||
ws.onopen = ->
|
||||
console.log "WebSocket open", arguments
|
||||
term = new Terminal(
|
||||
visualBell: true
|
||||
screenKeys: true
|
||||
visualBell: true
|
||||
screenKeys: true
|
||||
scrollback: -1
|
||||
)
|
||||
term.on "data", (data) ->
|
||||
ws.send 'SH|' + data
|
||||
@@ -25,15 +26,17 @@ $ ->
|
||||
if term
|
||||
term.destroy()
|
||||
console.log "WebSocket closed", arguments
|
||||
open('','_self').close()
|
||||
|
||||
ws.onerror = -> console.log "WebSocket error", arguments
|
||||
ws.onmessage = (event) ->
|
||||
# setTimeout (term.write event.data), 1
|
||||
term.write event.data
|
||||
|
||||
$(window).resize ->
|
||||
$main = $('main')
|
||||
$termtest = $('<div>').addClass('terminal')
|
||||
$test = $('<div>').css(display: 'inline-block').text('0123456789')
|
||||
$test = $('<div>').css(display: 'inline').text('0123456789')
|
||||
$termtest.append($test)
|
||||
|
||||
$main.append($termtest)
|
||||
@@ -42,7 +45,7 @@ $ ->
|
||||
$termtest.remove()
|
||||
w = $main.outerWidth()
|
||||
h = $main.outerHeight()
|
||||
cols = Math.floor(w / ew)
|
||||
rows = Math.floor(h / eh)
|
||||
cols = Math.floor(w / ew) - 1
|
||||
rows = Math.floor(h / eh) - 1
|
||||
term.resize cols, rows
|
||||
ws.send "RS|#{cols},#{rows}"
|
||||
|
||||
@@ -11,7 +11,8 @@ $(function() {
|
||||
console.log("WebSocket open", arguments);
|
||||
term = new Terminal({
|
||||
visualBell: true,
|
||||
screenKeys: true
|
||||
screenKeys: true,
|
||||
scrollback: -1
|
||||
});
|
||||
term.on("data", function(data) {
|
||||
return ws.send('SH|' + data);
|
||||
@@ -27,7 +28,8 @@ $(function() {
|
||||
if (term) {
|
||||
term.destroy();
|
||||
}
|
||||
return console.log("WebSocket closed", arguments);
|
||||
console.log("WebSocket closed", arguments);
|
||||
return open('', '_self').close();
|
||||
};
|
||||
ws.onerror = function() {
|
||||
return console.log("WebSocket error", arguments);
|
||||
@@ -40,7 +42,7 @@ $(function() {
|
||||
$main = $('main');
|
||||
$termtest = $('<div>').addClass('terminal');
|
||||
$test = $('<div>').css({
|
||||
display: 'inline-block'
|
||||
display: 'inline'
|
||||
}).text('0123456789');
|
||||
$termtest.append($test);
|
||||
$main.append($termtest);
|
||||
@@ -49,8 +51,8 @@ $(function() {
|
||||
$termtest.remove();
|
||||
w = $main.outerWidth();
|
||||
h = $main.outerHeight();
|
||||
cols = Math.floor(w / ew);
|
||||
rows = Math.floor(h / eh);
|
||||
cols = Math.floor(w / ew) - 1;
|
||||
rows = Math.floor(h / eh) - 1;
|
||||
term.resize(cols, rows);
|
||||
return ws.send("RS|" + cols + "," + rows);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
$bg: #110f13
|
||||
$fg: #f4ead5
|
||||
|
||||
$shadow: 6px
|
||||
$shadow-alpha: .5
|
||||
|
||||
|
||||
html, body
|
||||
height: 100%
|
||||
|
||||
@@ -19,11 +23,72 @@ body
|
||||
outline: none
|
||||
background-color: $bg
|
||||
color: $fg
|
||||
/* text-shadow: 0 0 10px
|
||||
span
|
||||
/* text-shadow: 0 0 10px
|
||||
text-shadow: 0 0 $shadow rgba($fg, $shadow-alpha)
|
||||
|
||||
.cursor
|
||||
box-shadow: 0 0 $shadow rgba($fg, $shadow-alpha)
|
||||
|
||||
/* Terminal styles
|
||||
.bold
|
||||
font-weight: bold
|
||||
|
||||
.underline
|
||||
text-decoration: underline
|
||||
|
||||
.blink
|
||||
text-decoration: blink
|
||||
|
||||
.invisible
|
||||
visibility: hidden
|
||||
|
||||
.reverse-video, .cursor
|
||||
color: $bg
|
||||
background-color: $fg
|
||||
|
||||
=termcolor($i, $color)
|
||||
.bg-color-#{$i}
|
||||
background-color: $color
|
||||
&.reverse-video, .cursor
|
||||
color: $color !important
|
||||
|
||||
.fg-color-#{$i}
|
||||
color: $color
|
||||
&.reverse-video, .cursor
|
||||
background-color: $color !important
|
||||
|
||||
text-shadow: 0 0 $shadow rgba($color, $shadow-alpha)
|
||||
|
||||
|
||||
.terminal-cursor
|
||||
color: $bg
|
||||
background-color: $fg
|
||||
+termcolor(0, #2e3436)
|
||||
+termcolor(1, #cc0000)
|
||||
+termcolor(2, #4e9a06)
|
||||
+termcolor(3, #c4a000)
|
||||
+termcolor(4, #3465a4)
|
||||
+termcolor(5, #75507b)
|
||||
+termcolor(6, #06989a)
|
||||
+termcolor(7, #d3d7cf)
|
||||
+termcolor(8, #555753)
|
||||
+termcolor(9, #ef2929)
|
||||
+termcolor(10, #8ae234)
|
||||
+termcolor(11, #fce94f)
|
||||
+termcolor(12, #729fcf)
|
||||
+termcolor(13, #ad7fa8)
|
||||
+termcolor(14, #34e2e2)
|
||||
+termcolor(15, #eeeeec)
|
||||
|
||||
$st: 00, 95, 135, 175, 215, 255
|
||||
|
||||
@for $i from 0 through 215
|
||||
$r: nth($st, 1 + floor(($i / 36) % 6))
|
||||
$g: nth($st, 1 + floor(($i / 6) % 6))
|
||||
$b: nth($st, 1 + $i % 6)
|
||||
+termcolor($i + 16, rgb($r, $g, $b))
|
||||
|
||||
@for $i from 0 through 23
|
||||
$l: 8 + $i * 10
|
||||
+termcolor($i + 232, rgb($l, $l, $l))
|
||||
|
||||
|
||||
/* ??
|
||||
+termcolor(256, $bg)
|
||||
+termcolor(257, $fg)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user