diff --git a/bigbashview/usr/lib/python3/dist-packages/bbv/globaldata.py b/bigbashview/usr/lib/python3/dist-packages/bbv/globaldata.py index 51f7618..6d9ed20 100644 --- a/bigbashview/usr/lib/python3/dist-packages/bbv/globaldata.py +++ b/bigbashview/usr/lib/python3/dist-packages/bbv/globaldata.py @@ -19,12 +19,11 @@ import os APP_NAME = "BigBashView" -APP_VERSION = "3.6.6" +APP_VERSION = "3.6.8" PROGDIR = os.path.dirname(os.path.realpath(__file__)) ICON = os.sep.join((PROGDIR, "img", "icone.png")) LOGO = os.sep.join((PROGDIR, "img", "logo.png")) TITLE = None ROOT_FILE = False - -def ADDRESS(): return '127.0.0.1' -def PORT(): return 9000 +ADDRESS = '127.0.0.1' +PORT = 19000 diff --git a/bigbashview/usr/lib/python3/dist-packages/bbv/main.py b/bigbashview/usr/lib/python3/dist-packages/bbv/main.py index e62923a..e362767 100644 --- a/bigbashview/usr/lib/python3/dist-packages/bbv/main.py +++ b/bigbashview/usr/lib/python3/dist-packages/bbv/main.py @@ -3,7 +3,7 @@ # Copyright (C) 2008 Wilson Pinto Júnior # Copyright (C) 2011 Thomaz de Oliveira dos Reis # Copyright (C) 2009 Bruno Goncalves Araujo -# Copyright (C) 2019 Elton Fabrício Ferreira +# Copyright (C) 2022 Elton Fabrício Ferreira # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,148 +17,144 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - +import argparse import sys import os -import getopt - from bbv import globaldata from bbv.server.bbv2server import run_server -class Main: - width = 0 - height = 0 - toolkit = "auto" - url = "/" - window_state = None - color = None +class Main: + """Start bbv""" def __init__(self): - try: - opts, args = getopt.gnu_getopt(sys.argv[1:], 'hs:vn:w:i:c:t:', ['help', 'size=', 'version', "name=", - 'window_state=', 'icon=', 'color=', 'toolkit=']) - except getopt.error as msg: - print(msg) - print('For help use -h or --help') - sys.exit(2) - - if args: - self.url = args[0] - - for o, a in opts: - if o in ('-h', '--help'): - self.help() - - elif o in ('-v', '--version'): - print(globaldata.APP_NAME, globaldata.APP_VERSION) - sys.exit() - - elif o in ('-s', '--size'): - args = a.split('x') - - if len(args) != 2: - self.help() - - for i in args: - if not i.isdigit(): - self.help() - - self.width, self.height = args - - # Window Size - self.width = int(self.width) - self.height = int(self.height) - - elif o in ('-t', '--toolkit'): - if a in ("gtk", "qt"): - self.toolkit = a - - elif o in ('-w', '--window_state'): - if a in ("maximized", "maximizedTop", "fullscreen", "fixed", - "fixedTop", "frameless", "framelessTop"): - self.window_state = a - - elif o in ('-i', '--icon'): - if os.path.exists(a): - globaldata.ICON = a - - elif o in ('-c', '--color'): - if a in ('black', 'none'): - self.color = a + def formatter(prog): + return argparse.RawTextHelpFormatter( + prog, + max_help_position=100, + width=None) + + parser = argparse.ArgumentParser( + prog='bigbashview', + description=''' + ____ _ ____ _ __ ___ + | _ \\(_) | _ \\ | |\\ \\ / (_) + | |_) |_ __ _| |_) | __ _ ___| |_\\ \\ / / _ _____ __ + | _ <| |/ _` | _ < / _` / __| '_ \\ \\/ / | |/ _ \\ \\ /\\ / / + | |_) | | (_| | |_) | (_| \\__ \\ | | \\ / | | __/\\ V V / + |____/|_|\\__, |____/ \\__,_|___/_| |_|\\/ |_|\\___| \\_/\\_/ + __/ | + |___/ - elif o in ('-n', '--name'): - globaldata.TITLE = a + BigBashView is a script to run Bash+HTML in a Desktop WebView. + ''', + epilog=''' + PlainText Extension: .txt Text Content + -------------------------------------------------------- + HTML Extensions: .html |.htm HTML Content + -------------------------------------------------------- + Executable Extensions: .sh |.run Shell Script + .sh.html|.sh.htm Html Markup + .sh.php PHP Script + .sh.py Python Script + .sh.lua Lua Script + .sh.rb Ruby Script + .sh.pl Perl Script + .sh.lisp Lisp Script + .sh.jl Julia Script + -------------------------------------------------------- + Note: All executable files must have the shebang''', + formatter_class=formatter) + + parser.add_argument('url', default='/', nargs='?', help='URL/File') + parser.add_argument( + '-v', '--version', + action='version', version=f'%(prog)s {globaldata.APP_VERSION}', + help='BigBashView Version') + parser.add_argument( + '-c', '--color', default=None, + help='Background Color: "black" or "none"') + parser.add_argument( + '-i', '--icon', default=globaldata.ICON, + help='Window Icon: /path/to/image') + parser.add_argument('-n', '--name', help='Window Title: "Title"') + parser.add_argument( + '-s', '--size', default='0x0', + help='Window Size: [width]x[height](800x600)') + parser.add_argument( + '-t', '--toolkit', + default='auto', + help='Rendering by QtWebEngine or WebKitGTK2: qt or gtk') + parser.add_argument( + '-w', '--window_state', default=None, + help='''Window state: fullscreen, maximized, maximizedTop, + fixed, fixedTop, frameless, framelessTop''') + + args = parser.parse_args() + self.url = args.url + globaldata.TITLE = args.name + geom = args.size.split('x') + try: + width, height = geom + self.width = int(width) + self.height = int(height) + except Exception: + parser.print_help() + sys.exit(1) + + if os.path.exists(args.icon): + globaldata.ICON = args.icon + + if args.color in ['black', 'none', None]: + self.color = args.color + else: + parser.print_help() + sys.exit(1) + + if args.toolkit in ['auto', 'qt', 'gtk']: + self.toolkit = args.toolkit + else: + parser.print_help() + sys.exit(1) + + if args.window_state in [ + 'fullscreen', 'maximized', + 'maximizedTop', 'fixed', + 'fixedTop', 'frameless', + 'framelessTop', None + ]: + self.window_state = args.window_state + else: + parser.print_help() + sys.exit(1) # construct window if self.toolkit == "auto": try: from bbv.ui import qt - has_qt = True + self.toolkit = 'qt' except ImportError as e: print(e) - has_qt = False - - try: - from bbv.ui import gtk - has_gtk = True - except ImportError as e: - print(e) - has_gtk = False - - if not has_qt and not has_gtk: - print(('bbv needs WebKitGtk2 or PySide2 ' - 'to run. Please install ' - 'the latest stable version'), file=sys.stderr) - sys.exit(1) + self.toolkit = 'gtk' - elif has_qt: - os.environ['QTWEBENGINE_CHROMIUM_FLAGS'] = '--disable-logging --disable-gpu --no-sandbox --single-process --disable-gpu-compositing --autoplay-policy=no-user-gesture-required --font-render-hinting=none' - os.environ['QT_QUICK_BACKEND'] = 'software' - os.environ['QT_XCB_GL_INTEGRATION'] = 'none' - os.environ['QSG_RENDER_LOOP'] = 'basic' - os.environ['QTWEBENGINE_DISABLE_SANDBOX'] = '1' - self.window = qt.Window() - - elif has_gtk: - os.environ['GDK_BACKEND'] = 'x11' - os.environ['WEBKIT_FORCE_SANDBOX'] = '0' - self.window = gtk.Window() - if globaldata.TITLE: - self.window.set_role(globaldata.TITLE) - - elif self.toolkit == "gtk": + if self.toolkit == "gtk": try: from bbv.ui import gtk - has_gtk = True except ImportError as e: print(e) - has_gtk = False - - if not has_gtk: - print(('bbv needs WebKitGtk2 ' - 'to run. Please install ' - 'the latest stable version'), file=sys.stderr) - + print('Please install WebKitGtk2') sys.exit(1) os.environ['GDK_BACKEND'] = 'x11' os.environ['WEBKIT_FORCE_SANDBOX'] = '0' self.window = gtk.Window() if globaldata.TITLE: - self.window.set_role(globaldata.TITLE) + self.window.set_wmclass(globaldata.TITLE, globaldata.TITLE) - elif self.toolkit == "qt": + if self.toolkit == "qt": try: from bbv.ui import qt - has_qt = True except ImportError as e: print(e) - has_qt = False - - if not has_qt: - print(('bbv needs PySide2 ' - 'to run. Please install ' - 'the latest stable version'), file=sys.stderr) - + print('Please install PySide6') sys.exit(1) os.environ['QTWEBENGINE_CHROMIUM_FLAGS'] = '--disable-logging --disable-gpu --no-sandbox --single-process --disable-gpu-compositing --autoplay-policy=no-user-gesture-required --font-render-hinting=none' os.environ['QT_QUICK_BACKEND'] = 'software' @@ -167,75 +163,16 @@ def __init__(self): os.environ['QTWEBENGINE_DISABLE_SANDBOX'] = '1' self.window = qt.Window() - @staticmethod - def help(): - helper = r''' - ____ _ ____ _ __ ___ - | _ \(_) | _ \ | |\ \ / (_) - | |_) |_ __ _| |_) | __ _ ___| |_\ \ / / _ _____ __ - | _ <| |/ _` | _ < / _` / __| '_ \ \/ / | |/ _ \ \ /\ / / - | |_) | | (_| | |_) | (_| \__ \ | | \ / | | __/\ V V / - |____/|_|\__, |____/ \__,_|___/_| |_|\/ |_|\___| \_/\_/ - __/ | - |___/ - -~$bigbashview options arguments URL -================================================================== -Options Arguments Descriptions ------------------------------------------------------------------- --s|--size= widthxheight Window size ------------------------------------------------------------------- --t|--toolkit= gtk Rendering by WebKitGTK2 - qt Rendering by QtWebEngine ------------------------------------------------------------------- --w|--window_state= fullscreen Open window in fullscreen - maximized Open maximized window - maximizedTop Open maximized window - and keep window on top - fixed Open window in fixed size - fixedTop Open window in fixed size - and keep window on top - frameless Open window frameless - framelessTop Open window frameless - and keep window on top ------------------------------------------------------------------- --i|--icon= /path/to/image Window icon ------------------------------------------------------------------- --n|--name= AppName Window title ------------------------------------------------------------------- --c|--color= black Black background - none Transparent background ------------------------------------------------------------------- --h|--help BigBashView help --v|--version BigBashView version -================================================================== -PlainText Extension: .txt Text Content ------------------------------------------------------------------- -HTML Extensions: .html |.htm HTML Content ------------------------------------------------------------------- -Executable Extensions: .sh |.run Shell Script - .sh.html|.sh.htm Html Markup - .sh.php PHP Script - .sh.py Python Script - .sh.lua Lua Script - .sh.rb Ruby Script - .sh.pl Perl Script - .sh.lisp Lisp Script - .sh.jl Julia Script ------------------------------------------------------------------- -*Note: All executable files must have the shebang* - ''' - print(helper) - sys.exit() - def run(self, start_server=True): server = run_server() if start_server else None if self.url.find('://') == -1: if not self.url.startswith('/'): self.url = '/'+self.url - self.url = "http://%s:%s%s" % (globaldata.ADDRESS(), - globaldata.PORT(), self.url) + self.url = "http://%s:%s%s" % ( + globaldata.ADDRESS, + globaldata.PORT, + self.url) self.window.set_size(self.width, self.height, self.window_state) self.window.style(self.color) diff --git a/bigbashview/usr/lib/python3/dist-packages/bbv/server/bbv2server.py b/bigbashview/usr/lib/python3/dist-packages/bbv/server/bbv2server.py index 828e184..bc1ae28 100644 --- a/bigbashview/usr/lib/python3/dist-packages/bbv/server/bbv2server.py +++ b/bigbashview/usr/lib/python3/dist-packages/bbv/server/bbv2server.py @@ -15,7 +15,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - +from bbv import globaldata import web import sys import socket @@ -24,7 +24,6 @@ from . import views import os -from bbv import globaldata class Server(threading.Thread): def _get_subclasses(self, classes=None): @@ -55,8 +54,8 @@ def get_classes(self): def run(self): """ Run the webserver """ - ip = globaldata.ADDRESS() - port = globaldata.PORT() + ip = globaldata.ADDRESS + port = globaldata.PORT sys.argv = [sys.argv[0], ''] sys.argv[1] = ':'.join((ip, str(port))) @@ -66,9 +65,9 @@ def run(self): self.app.run() def stop(self): - print('Waiting for server to shutdown...') os.kill(os.getpid(), 15) + def run_server(ip='127.0.0.1', background=True): soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) for port in range(19000, 19100): @@ -82,8 +81,8 @@ def run_server(ip='127.0.0.1', background=True): raise socket.error(e) print('Port %d already in use, trying next one' % port) - globaldata.ADDRESS = lambda: ip - globaldata.PORT = lambda: port + globaldata.ADDRESS = ip + globaldata.PORT = port server = Server() @@ -108,5 +107,6 @@ def run_server(ip='127.0.0.1', background=True): return server + if __name__ == "__main__": run_server(background=False) diff --git a/bigbashview/usr/lib/python3/dist-packages/bbv/server/html.py b/bigbashview/usr/lib/python3/dist-packages/bbv/server/html.py new file mode 100644 index 0000000..34526e2 --- /dev/null +++ b/bigbashview/usr/lib/python3/dist-packages/bbv/server/html.py @@ -0,0 +1,537 @@ +import os +from bbv.globaldata import LOGO, APP_VERSION + +HTML = ''' + + + Welcome to BigBashView + + + +
+
+
+
+
+

BigBashView

+

%s

+

+
+
+
+ Hostname + %s
+
+
+ Desktop Environment + %s
+
+
+
+ +
+ + +''' % (LOGO, APP_VERSION, os.uname()[1], os.environ.get('XDG_CURRENT_DESKTOP')) diff --git a/bigbashview/usr/lib/python3/dist-packages/bbv/server/views.py b/bigbashview/usr/lib/python3/dist-packages/bbv/server/views.py index eb33e0a..88426c1 100644 --- a/bigbashview/usr/lib/python3/dist-packages/bbv/server/views.py +++ b/bigbashview/usr/lib/python3/dist-packages/bbv/server/views.py @@ -19,13 +19,13 @@ from urllib.parse import parse_qs from urllib.parse import unquote +from .utils import get_env_for_shell, to_s +from .html import HTML +from bbv import globaldata import subprocess import os import web -from .utils import get_env_for_shell -from .utils import to_s -from bbv import globaldata class url_handler(object): __url__ = '/' @@ -59,12 +59,14 @@ def _get_set_default_options(self, options): def called(self, options, content, query): raise NotImplementedError + class favicon_handler(url_handler): __url__ = '/favicon.ico' def called(self, options, content, query): return + class content_handler(url_handler): __url__ = '/content(.*)' @@ -76,21 +78,32 @@ def called(self, options, content, query): with open(content, 'rb') as arq: return arq.read() + class execute_handler(url_handler): __url__ = '/execute(.*)' def _execute(self, command, extra_env={}): env = os.environ.copy() - env['bbv_ip'] = str(globaldata.ADDRESS()) - env['bbv_port'] = str(globaldata.PORT()) + env['bbv_ip'] = str(globaldata.ADDRESS) + env['bbv_port'] = str(globaldata.PORT) env.update(extra_env) if not globaldata.ROOT_FILE: - po = subprocess.Popen(command, - stdin=None, stdout=subprocess.PIPE, shell=True, env=env) + po = subprocess.Popen( + command, + stdin=None, + stdout=subprocess.PIPE, + shell=True, + env=env + ) else: - po = subprocess.Popen('/bin/bash {}'.format(command), - stdin=None, stdout=subprocess.PIPE, shell=True, env=env) + po = subprocess.Popen( + '/bin/bash {}'.format(command), + stdin=None, + stdout=subprocess.PIPE, + shell=True, + env=env + ) return po.communicate() @@ -101,6 +114,7 @@ def called(self, options, content, query): os.kill(os.getpid(), 15) return stdout + class default_handler(url_handler): __url__ = '(.*)' @@ -108,572 +122,6 @@ def called(self, options, content, query): if content not in ("", "/"): return self.bbv_compat_mode(options, content, query) else: - HTML = ''' - - Welcome to BigBashView - - - -
-
-
-
-
-

BigBashView

-

%s

-

-
-
-
- Hostname - %s
- -
-
- Desktop Environment - %s
- -
-
- -
- -
- - - ''' % (globaldata.LOGO, globaldata.APP_VERSION, os.uname()[1], os.environ.get('XDG_CURRENT_DESKTOP')) return HTML def parse_and_call(self, qs, name): @@ -681,9 +129,9 @@ def parse_and_call(self, qs, name): return url_handler.parse_and_call(self, qs, name) def bbv_compat_mode(self, options, content, query): - execute_ext = ('.sh','.sh.html','.sh.htm','.sh.php', - '.sh.py','.sh.lua','.sh.rb','.sh.pl', - '.sh.lisp','.sh.jl','.run') + execute_ext = ('.sh', '.sh.html', '.sh.htm', '.sh.php', + '.sh.py', '.sh.lua', '.sh.rb', '.sh.pl', + '.sh.lisp', '.sh.jl', '.run') content_ext = ('.htm', '.html') content_plain_ext = ('.txt') content_css_ext = ('.css') @@ -700,7 +148,7 @@ def bbv_compat_mode(self, options, content, query): try: import stat os.chmod(content, os.stat(content).st_mode | stat.S_IEXEC) - except: + except Exception: globaldata.ROOT_FILE = True if content.endswith(content_plain_ext): web.header('Content-Type', 'text/plain; charset=UTF-8') diff --git a/bigbashview/usr/lib/python3/dist-packages/bbv/ui/gtk.py b/bigbashview/usr/lib/python3/dist-packages/bbv/ui/gtk.py index 749fd00..4f099fe 100644 --- a/bigbashview/usr/lib/python3/dist-packages/bbv/ui/gtk.py +++ b/bigbashview/usr/lib/python3/dist-packages/bbv/ui/gtk.py @@ -14,16 +14,15 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . - +# along with this program. If not, see import os import gi gi.require_version('Gtk', '3.0') gi.require_version('WebKit2', '4.1') from gi.repository import Gtk, WebKit2, Gdk - from bbv.globaldata import ICON, TITLE + class Window(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) @@ -37,7 +36,10 @@ def __init__(self): self.webview.connect("notify::title", self.title_changed) self.webview.connect("load-changed", self.add_script) self.webview.connect("close", self.close_window) - self.webview.get_settings().set_property("enable-developer-extras",True) + self.webview.get_settings().set_property( + "enable-developer-extras", + True + ) self.connect("destroy", Gtk.main_quit) self.connect("key-press-event", self.key) @@ -54,7 +56,7 @@ def add_script(self, webview, event): fetch("/execute$"+run); }; ''' - if event.FINISHED: + if event == WebKit2.LoadEvent.FINISHED: self.webview.run_javascript(script) def viewer(self, window_state): @@ -91,8 +93,9 @@ def close_window(webview): def title_changed(self, webview, title): title = self.webview.get_title() - os.system('''xprop -id "$(xprop -root '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)" \ - -f WM_CLASS 8s -set WM_CLASS "%s"''' % title) + os.system(''' + xprop -id "$(xprop -root '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)" \ + -f WM_CLASS 8s -set WM_CLASS "%s" ''' % title) self.set_title(title) def load_url(self, url): @@ -114,7 +117,10 @@ def set_size(self, width, height, window_state): def style(self, colorful): if colorful == 'black': - self.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 1)) + self.override_background_color( + Gtk.StateFlags.NORMAL, + Gdk.RGBA(0, 0, 0, 1) + ) self.webview.set_background_color(Gdk.RGBA(0, 0, 0, 1)) elif colorful == 'none': @@ -122,7 +128,10 @@ def style(self, colorful): visual = screen.get_rgba_visual() if visual is not None and screen.is_composited(): self.set_visual(visual) - self.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 0)) + self.override_background_color( + Gtk.StateFlags.NORMAL, + Gdk.RGBA(0, 0, 0, 0) + ) self.webview.set_background_color(Gdk.RGBA(0, 0, 0, 0)) elif os.environ.get('XDG_CURRENT_DESKTOP') == 'KDE': @@ -133,14 +142,16 @@ def style(self, colorful): r = float(int(r)/255) g = float(int(g)/255) b = float(int(b)/255) - self.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(r, g, b, 1)) + self.override_background_color( + Gtk.StateFlags.NORMAL, + Gdk.RGBA(r, g, b, 1) + ) self.webview.set_background_color(Gdk.RGBA(r, g, b, 1)) else: - color = Gtk.Window().get_style_context().get_background_color(Gtk.StateFlags.NORMAL) + color = self.get_style_context().get_background_color(Gtk.StateFlags.NORMAL) self.override_background_color(Gtk.StateFlags.NORMAL, color) self.webview.set_background_color(color) - else: - color = Gtk.Window().get_style_context().get_background_color(Gtk.StateFlags.NORMAL) + color = self.get_style_context().get_background_color(Gtk.StateFlags.NORMAL) self.override_background_color(Gtk.StateFlags.NORMAL, color) self.webview.set_background_color(color) diff --git a/bigbashview/usr/lib/python3/dist-packages/bbv/ui/qt.py b/bigbashview/usr/lib/python3/dist-packages/bbv/ui/qt.py index 254d929..b945922 100644 --- a/bigbashview/usr/lib/python3/dist-packages/bbv/ui/qt.py +++ b/bigbashview/usr/lib/python3/dist-packages/bbv/ui/qt.py @@ -105,7 +105,6 @@ def add_script(self, event): fetch('/execute$'+run, { signal: controller.signal }); }; ''' - if event: self.web.page().runJavaScript(script) @@ -139,8 +138,9 @@ def close_window(self): self.app.quit() def title_changed(self, title): - os.system('''xprop -id "$(xprop -root '\t$0' _NET_ACTIVE_WINDOW | cut -f2)" \ - -f WM_CLASS 8s -set WM_CLASS "%s"''' % title) + os.system(''' + xprop -id "$(xprop -root '\t$0' _NET_ACTIVE_WINDOW | cut -f2)" \ + -f WM_CLASS 8s -set WM_CLASS "%s"''' % title) self.setWindowTitle(title) def icon_changed(self, icon): @@ -185,6 +185,5 @@ def style(self, colorful): self.web.page().setBackgroundColor(QColor.fromRgbF(r, g, b, 1)) else: self.web.page().setBackgroundColor(QColor.fromRgbF(0, 0, 0, 0)) - else: self.web.page().setBackgroundColor(QColor.fromRgbF(0, 0, 0, 0))