From 421a15a05fa992d85c8acac1aec517aa7de26297 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Tue, 4 Feb 2014 16:23:36 +0100 Subject: [PATCH] Make it work on android and perhaps in IOS --- butterfly/__init__.py | 2 +- butterfly/routes.py | 11 ++-- butterfly/static/coffees/main.coffee | 72 ++++++++++++++++++++++++- butterfly/static/javascripts/main.js | 79 +++++++++++++++++++++++++++- butterfly/static/javascripts/term.js | 2 +- 5 files changed, 157 insertions(+), 9 deletions(-) diff --git a/butterfly/__init__.py b/butterfly/__init__.py index 527b70a..3d49696 100644 --- a/butterfly/__init__.py +++ b/butterfly/__init__.py @@ -14,7 +14,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -__version__ = '1.0.5' +__version__ = '1.0.6' import os diff --git a/butterfly/routes.py b/butterfly/routes.py index 16a39b4..450fc6f 100644 --- a/butterfly/routes.py +++ b/butterfly/routes.py @@ -64,15 +64,15 @@ class TermWebSocket(Route, tornado.websocket.WebSocketHandler): try: os.chdir(self.path or self.pw.pw_dir) except: - self.log.warning('chdir failed', exc_info=True) + pass env = os.environ if self.is_local and os.getuid() == 0: try: env = self.socket_opener_environ except: - self.log.warning('getting local environment failed', - exc_info=True) + pass + env["TERM"] = "xterm-256color" env["COLORTERM"] = "butterfly" @@ -95,7 +95,10 @@ class TermWebSocket(Route, tornado.websocket.WebSocketHandler): self.uid == self.pw.pw_uid): # If user is not the same, get a password prompt # (setuid to daemon user before su) - os.setuid(2) + try: + os.setuid(2) + except PermissionError: + pass args = ['butterfly', '-p'] if tornado.options.options.command: diff --git a/butterfly/static/coffees/main.coffee b/butterfly/static/coffees/main.coffee index 56545ab..8e2096e 100644 --- a/butterfly/static/coffees/main.coffee +++ b/butterfly/static/coffees/main.coffee @@ -1,12 +1,82 @@ +try + document.createEvent("TouchEvent") + virtual_input = true +catch e + virtual_input = false + term = ws = null cols = rows = null quit = false + +if virtual_input + ctrl = false + alt = false + first = true + virtual_input = document.createElement 'input' + virtual_input.type = 'password' + virtual_input.style.position = 'fixed' + virtual_input.style.top = 0 + virtual_input.style.left = 0 + virtual_input.style.border = 'none' + virtual_input.style.outline = 'none' + virtual_input.style.opacity = 0 + virtual_input.value = '0' + document.body.appendChild virtual_input + + virtual_input.addEventListener 'blur', -> + setTimeout((=> @focus()), 10) + + addEventListener 'click', -> + virtual_input.focus() + + addEventListener 'touchstart', (e) -> + if e.touches.length == 1 + ctrl = true + else if e.touches.length == 2 + ctrl = false + alt = true + else if e.touches.length == 3 + ctrl = true + alt = true + + virtual_input.addEventListener 'keydown', (e) -> + term.keyDown(e) + return true + + virtual_input.addEventListener 'input', (e) -> + len = @value.length + + if len == 0 + e.keyCode = 8 + term.keyDown e + @value = '0' + return true + + e.keyCode = @value.charAt(1).charCodeAt(0) + + if (ctrl or alt) and not first + e.keyCode = @value.charAt(1).charCodeAt(0) + e.ctrlKey = ctrl + e.altKey = alt + if e.keyCode >= 97 && e.keyCode <= 122 + e.keyCode -= 32 + term.keyDown e + @value = '0' + ctrl = alt = false + return true + + term.keyPress e + first = false + @value = '0' + true + $ = document.querySelectorAll.bind(document) ws_url = 'ws://' + document.location.host + '/ws' + location.pathname ws = new WebSocket ws_url ws.onopen = -> console.log "WebSocket open", arguments + term = new Terminal( visualBell: 100 screenKeys: true @@ -31,7 +101,7 @@ ws.onclose = -> open('','_self').close() ws.onerror = -> console.log "WebSocket error", arguments -ws.onmessage = (event) -> +ws.onmessage = (e) -> term.write event.data addEventListener 'beforeunload', -> diff --git a/butterfly/static/javascripts/main.js b/butterfly/static/javascripts/main.js index 5ae8842..047acf3 100644 --- a/butterfly/static/javascripts/main.js +++ b/butterfly/static/javascripts/main.js @@ -1,5 +1,13 @@ // Generated by CoffeeScript 1.6.3 -var $, cols, quit, resize, rows, term, ws, ws_url; +var $, alt, cols, ctrl, e, first, quit, resize, rows, term, virtual_input, ws, ws_url; + +try { + document.createEvent("TouchEvent"); + virtual_input = true; +} catch (_error) { + e = _error; + virtual_input = false; +} term = ws = null; @@ -7,6 +15,73 @@ cols = rows = null; quit = false; +if (virtual_input) { + ctrl = false; + alt = false; + first = true; + virtual_input = document.createElement('input'); + virtual_input.type = 'password'; + virtual_input.style.position = 'fixed'; + virtual_input.style.top = 0; + virtual_input.style.left = 0; + virtual_input.style.border = 'none'; + virtual_input.style.outline = 'none'; + virtual_input.style.opacity = 0; + virtual_input.value = '0'; + document.body.appendChild(virtual_input); + virtual_input.addEventListener('blur', function() { + var _this = this; + return setTimeout((function() { + return _this.focus(); + }), 10); + }); + addEventListener('click', function() { + return virtual_input.focus(); + }); + addEventListener('touchstart', function(e) { + if (e.touches.length === 1) { + return ctrl = true; + } else if (e.touches.length === 2) { + ctrl = false; + return alt = true; + } else if (e.touches.length === 3) { + ctrl = true; + return alt = true; + } + }); + virtual_input.addEventListener('keydown', function(e) { + term.keyDown(e); + return true; + }); + virtual_input.addEventListener('input', function(e) { + var len; + len = this.value.length; + if (len === 0) { + e.keyCode = 8; + term.keyDown(e); + this.value = '0'; + return true; + } + e.keyCode = this.value.charAt(1).charCodeAt(0); + if ((ctrl || alt) && !first) { + e.keyCode = this.value.charAt(1).charCodeAt(0); + e.ctrlKey = ctrl; + e.altKey = alt; + if (e.keyCode >= 97 && e.keyCode <= 122) { + e.keyCode -= 32; + } + term.keyDown(e); + this.value = '0'; + ctrl = alt = false; + return true; + } + term.keyPress(e); + first = false; + this.value = '0'; + return true; + }); +} + $ = document.querySelectorAll.bind(document); ws_url = 'ws://' + document.location.host + '/ws' + location.pathname; @@ -44,7 +119,7 @@ ws.onerror = function() { return console.log("WebSocket error", arguments); }; -ws.onmessage = function(event) { +ws.onmessage = function(e) { return term.write(event.data); }; diff --git a/butterfly/static/javascripts/term.js b/butterfly/static/javascripts/term.js index bcf1da0..74b39ab 160000 --- a/butterfly/static/javascripts/term.js +++ b/butterfly/static/javascripts/term.js @@ -1 +1 @@ -Subproject commit bcf1da07d13208f8eebcac6e5dece4a141d57035 +Subproject commit 74b39ab476af3b208efad8adc1180ac0b070cd96