Skip to content

Commit

Permalink
Use wetty as terminal backend.
Browse files Browse the repository at this point in the history
  • Loading branch information
manateelazycat committed Jan 27, 2020
1 parent 0f5d9dd commit ac3ceba
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 68 deletions.
42 changes: 23 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ EAF is extensible, you can develop any PyQt application and integrate it into Em

| Terminal Emulator | RSS Reader |
| :--------: | :------: |
| <img src="./screenshot/terminal.png" width="400"> | <img src="./screenshot/rss_reader.gif" width="400"> |
| <img src="./screenshot/terminal.gif" width="400"> | <img src="./screenshot/rss_reader.gif" width="400"> |
| | |

## Install EAF
Expand Down Expand Up @@ -62,28 +62,32 @@ If you use [use-package](https://github.com/jwiegley/use-package), a sample conf
sudo pip3 install dbus-python python-xlib pyqt5 pyqtwebengine pymupdf grip qrcode feedparser
```

3. Compile ```qtermwidget-git``` use the following command:
```Elisp
git clone https://github.com/lxqt/qtermwidget.git --depth=1
mkdir build && cd build
cmake .. -DQTERMWIDGET_BUILD_PYTHON_BINDING=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=/usr
make
sudo make install
3. Install and config ```wetty```:
```Bash
# Install wetty
sudo yarn global add wetty

# Make wetty login with public key
ssh-keygen
cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys

# You need add below in .bashrc if you are Chinese
echo 'export LANG=zh_CN.UTF-8' >> ~/.bashrc
```

Package info:

| Package | Package Repo | Classification | Package Description |
| :-------- | :---- | :------ | :------ |
| dbus-python | pip3 | Core | DBus IPC to communicate python with elisp |
| python-xlib | pip3 | Core | Stick app window into Emacs frame |
| pyqt5 | pip3 | Core | GUI library required for applications |
| pyqtwebengine | pip3 | Core | Browser: QtWebEngine for browser application |
| pymupdf | pip3 | Application | PDF Viewer: Rendering engine |
| grip | pip3 | Application | Markdown Previewer: Markdown render server |
| qrcode | pip3 | Application | File Transfer: Render QR code pointing local files |
| feedparser | pip3 | Application | RSS Reader: feed parser |
| qtermwidget-git | compile from source | Application | Terminal: QTermWidget, PyQt5 terminal emulator |
| Package | Package Repo | Classification | Package Description |
| :-------- | :---- | :------ | :------ |
| dbus-python | pip3 | Core | DBus IPC to communicate python with elisp |
| python-xlib | pip3 | Core | Stick app window into Emacs frame |
| pyqt5 | pip3 | Core | GUI library required for applications |
| pyqtwebengine | pip3 | Core | Browser: QtWebEngine for browser application |
| pymupdf | pip3 | Application | PDF Viewer: Rendering engine |
| grip | pip3 | Application | Markdown Previewer: Markdown render server |
| qrcode | pip3 | Application | File Transfer: Render QR code pointing local files |
| feedparser | pip3 | Application | RSS Reader: feed parser |
| wetty | yarn | Application | Terminal: Share SSH over Web |


## Launch EAF Applications
Expand Down
16 changes: 2 additions & 14 deletions app/file-sender/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
from PyQt5.QtGui import QColor, QFont
from PyQt5.QtWidgets import QWidget, QLabel, QVBoxLayout
from core.buffer import Buffer
from core.utils import get_free_port
import http.server as BaseHTTPServer
import os
import qrcode
import shutil
import socket
import sys
import threading

Expand Down Expand Up @@ -130,24 +130,12 @@ def get_local_ip(self):
print("Network is unreachable")
sys.exit()

def get_free_port(self):
"""
Determines a free port using sockets.
"""
free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
free_socket.bind(('0.0.0.0', 0))
free_socket.listen(5)
port = free_socket.getsockname()[1]
free_socket.close()

return port

def start_server(self, filename):
global local_file_path

local_file_path = filename

self.port = self.get_free_port()
self.port = get_free_port()
self.local_ip = self.get_local_ip()
self.set_address("http://{0}:{1}/{2}".format(self.local_ip, self.port, filename))

Expand Down
17 changes: 2 additions & 15 deletions app/markdown-previewer/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QColor
from core.browser import BrowserBuffer
from core.utils import PostGui
from core.utils import PostGui, get_free_port
import os
import socket
import subprocess
import threading

Expand All @@ -33,7 +32,7 @@ def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict):
BrowserBuffer.__init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, False, QColor(255, 255, 255, 255))

# Get free port to render markdown.
self.port = self.get_free_port()
self.port = get_free_port()
self.url = url

# Start markdown render process.
Expand All @@ -46,18 +45,6 @@ def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict):
timer = threading.Timer(2, self.load_markdown_server)
timer.start()

def get_free_port(self):
"""
Determines a free port using sockets.
"""
free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
free_socket.bind(('0.0.0.0', 0))
free_socket.listen(5)
port = free_socket.getsockname()[1]
free_socket.close()

return port

@PostGui()
def load_markdown_server(self):
self.buffer_widget.setUrl(QUrl("http://localhost:{0}".format(self.port)))
Expand Down
54 changes: 36 additions & 18 deletions app/terminal/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,48 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from PyQt5.QtGui import QColor, QFont
from core.buffer import Buffer
import QTermWidget
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QColor
from core.browser import BrowserBuffer
from core.utils import PostGui, get_free_port
import os
import subprocess
import signal
import threading
import getpass

class AppBuffer(Buffer):
class AppBuffer(BrowserBuffer):
def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict):
Buffer.__init__(self, buffer_id, url, arguments, emacs_var_dict, True, QColor(0, 0, 0, 255))
BrowserBuffer.__init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, False, QColor(255, 255, 255, 255))

self.add_widget(QTermWidget.QTermWidget())
# Get free port to render markdown.
self.port = get_free_port()
self.url = url

self.buffer_widget.setTerminalFont(QFont('Source Code Pro', 14))
self.buffer_widget.setColorScheme('Linux')
# Start wetty process.
self.background_process = subprocess.Popen(
"wetty -p {0} --base / --sshuser {1} --sshauth publickey -c bash".format(self.port, getpass.getuser()),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True)

self.buffer_widget.finished.connect(self.request_close_buffer)
# Add timer make load markdown preview link after grip process start finish.
threading.Timer(1, self.load_wetty_server).start()

def get_key_event_widgets(self):
return self.buffer_widget.children()
self.reset_default_zoom()

def fake_key_event_filter(self, event_string):
if event_string == "RET":
self.buffer_widget.sendText("\n")
@PostGui()
def load_wetty_server(self):
self.buffer_widget.setUrl(QUrl("http://localhost:{0}".format(self.port)))

def zoom_out(self):
self.buffer_widget.zoomOut()
paths = os.path.split(self.url)
if len(paths) > 0:
self.change_title(paths[-1])

def zoom_in(self):
self.buffer_widget.zoomIn()
def handle_destroy(self):
os.killpg(os.getpgid(self.background_process.pid), signal.SIGTERM)

self.before_destroy_hook.emit()

if self.buffer_widget is not None:
self.buffer_widget.destroy()
13 changes: 13 additions & 0 deletions core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from PyQt5 import QtCore
import functools
import os
import socket

class PostGui(QtCore.QObject):

Expand Down Expand Up @@ -59,3 +60,15 @@ def touch(path):

with open(path, 'a'):
os.utime(path)

def get_free_port():
"""
Determines a free port using sockets.
"""
free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
free_socket.bind(('0.0.0.0', 0))
free_socket.listen(5)
port = free_socket.getsockname()[1]
free_socket.close()

return port
5 changes: 3 additions & 2 deletions eaf.el
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
;; Copyright (C) 2018, Andy Stewart, all rights reserved.
;; Created: 2018-06-15 14:10:12
;; Version: 0.5
;; Last-Updated: Tue Jan 14 00:36:40 2020 (-0500)
;; Last-Updated: Wed Jan 22 23:11:57 2020 (-0500)
;; By: Mingde (Matthew) Zeng
;; URL: http://www.emacswiki.org/emacs/download/eaf.el
;; Keywords:
Expand Down Expand Up @@ -1062,7 +1062,8 @@ This function works best if paired with a fuzzy search package."
(history (completing-read "[EAF/browser] Search || URL || History: " history-list))
(history-url (when (string-match "[^\s]+$" history)
(match-string 0 history))))
(if (string-match "^\\(https?://\\)?[a-z0-9]+\\([-.][a-z0-9]+\\)*.+\\..+[a-z0-9.]\\{2,5\\}\\(:[0-9]{1,5}\\)?\\(/.*\\)?$" history-url)
(if (and history-url
(string-match "^\\(https?://\\)?[a-z0-9]+\\([-.][a-z0-9]+\\)*.+\\..+[a-z0-9.]\\{2,5\\}\\(:[0-9]{1,5}\\)?\\(/.*\\)?$" history-url))
(eaf-open-browser history-url)
(eaf-open-browser history))))))

Expand Down
Binary file added screenshot/terminal.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed screenshot/terminal.png
Binary file not shown.

0 comments on commit ac3ceba

Please sign in to comment.