#!/usr/bin/python
#
# Author: ncmprhnsbl
#
# This gtkdialog script opens a window with some options to obtain and update various applications
# for Porteus Linux, it is a gui for update-*-live scripts
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Vte', '2.91')
from gi.repository import Gtk, Vte, GLib
from os import getenv, getuid, path, environ
from subprocess import run, Popen
from platform import machine
## Make sure we're in X
display = getenv('DISPLAY')
if display == None:
print("This program requires an X session!")
quit()
## prompt root password(gui psu) and re-execute? probly a bit dirty..
## using subprocess rather than os.system() to be script agnostic..
user = getuid()
if user != 0:
print("You must be root to run this!")
this_script = path.abspath(__file__)
run(['psu', this_script])
quit()
class GtkBrowserUpdate(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title = "Porteus Module Centre", border_width = 5, default_height = 480, default_width = 650, icon_name = "cdr")
self.vb = Gtk.Box(spacing = 5, orientation = Gtk.Orientation.VERTICAL)
self.l_header_txt = Gtk.Label()
self.l_header_txt.set_markup("Choose a Module to Install or to Update")
self.vb.pack_start(self.l_header_txt, False, False, 5)
self.vb.pack_start(Gtk.Separator(), False, False, 5)
self.scrolledwindow = Gtk.ScrolledWindow(hexpand = True, vexpand = True)
self.vb.pack_start(self.scrolledwindow, True, True, 5)
self.vb_inner = Gtk.Box(spacing = 5, orientation = Gtk.Orientation.VERTICAL)
self.vb_inner_br = Gtk.Box(spacing = 5, orientation = Gtk.Orientation.VERTICAL)
self.br_txt = Gtk.Label()
self.br_txt.set_markup("\tNetwork:")
self.br_txt.set_halign(Gtk.Align.START)
self.vb_inner_br.pack_start(self.br_txt, False, False, 5)
self.fb_br = Gtk.FlowBox(max_children_per_line = 5, row_spacing = 25, homogeneous = True)
self.add_button("Firefox", "Mozilla's web browser", "firefox", self.fb_br)
if machine() == "x86_64":
self.add_button("Chrome", "Google's web browser", "chrome", self.fb_br)
self.add_button("Palemoon", "Lightweight web browser based on older Firefox", "palemoon", self.fb_br)
self.add_button("Opera", "Chromium based web browser", "opera", self.fb_br)
self.add_button("Chromium-gost", "Chromium based web browser for Russian banking", "chromium-gost", self.fb_br)
self.add_button("Vivaldi", "Chromium based web browser", "vivaldi", self.fb_br)
self.add_button("AnyDesk", "Remote Desktop Access", "anydesk", self.fb_br)
self.add_button("RustDesk", "Remote Desktop Access", "rustdesk", self.fb_br)
self.add_button("Remmina", "Remote Desktop Access", "remmina", self.fb_br)
self.add_button("Chromium", "The open source web browser with google elements removed", "chromium", self.fb_br)
self.add_button("Netsurf", "Very lightweight Web Browser", "netsurf", self.fb_br)
self.add_button("YouTube-download", "(Console)Download Videos from the Web", "youtube-dl", self.fb_br)
self.vb_inner_br.pack_start(self.fb_br, False, False, 5)
self.vb_inner_grph = Gtk.Box(spacing = 5, orientation = Gtk.Orientation.VERTICAL)
self.l_grph_txt = Gtk.Label()
self.l_grph_txt.set_markup("\tGraphics:")
self.l_grph_txt.set_halign(Gtk.Align.START)
self.vb_inner_grph.pack_start(self.l_grph_txt, False, False, 5)
self.fb_grph = Gtk.FlowBox(max_children_per_line = 5, row_spacing = 25, homogeneous = True)
self.add_button("Gimp", "Gnu Image Manipulation Program", "gimp", self.fb_grph)
self.vb_inner_grph.pack_start(self.fb_grph, False, False, 5)
self.vb_inner_offce = Gtk.Box(spacing = 5, orientation = Gtk.Orientation.VERTICAL)
self.l_offce_txt = Gtk.Label()
self.l_offce_txt.set_markup("\tOffice:")
self.l_offce_txt.set_halign(Gtk.Align.START)
self.vb_inner_offce.pack_start(self.l_offce_txt, False, False, 5)
self.fb_offce = Gtk.FlowBox(max_children_per_line = 5, row_spacing = 25, homogeneous = True)
if machine() == "x86_64":
self.add_button("Libre Office", "Office Suite", "libreoffice", self.fb_offce)
self.add_button("OnlyOffice", "Office Suite", "onlyoffice", self.fb_offce)
self.add_button("WPS Office", "Office Suite", "wps-office", self.fb_offce)
self.add_button("Printing", "Printing Tools", "printing", self.fb_offce)
self.add_button("Printing Extra", "Printing Tools", "printing", self.fb_offce)
self.add_button("Thunderbird", "Mozilla's email client", "thunderbird", self.fb_offce)
self.vb_inner_offce.pack_start(self.fb_offce, False, False, 5)
if machine() == "x86_64":
self.vb_inner_virt = Gtk.Box(spacing = 5, orientation = Gtk.Orientation.VERTICAL)
self.l_virt_txt = Gtk.Label()
self.l_virt_txt.set_markup("\tVirtual Machine:")
self.l_virt_txt.set_halign(Gtk.Align.START)
self.vb_inner_virt.pack_start(self.l_virt_txt, False, False, 5)
self.fb_virt = Gtk.FlowBox(max_children_per_line = 5, row_spacing = 25, homogeneous = True)
self.add_button("VirtualBox", "Virtual Computer", "vbox", self.fb_virt)
self.vb_inner_virt.pack_start(self.fb_virt, False, False, 5)
self.vb_inner.pack_start(self.vb_inner_br, True, True, 5)
self.vb_inner.pack_start(self.vb_inner_grph, True, True, 5)
self.vb_inner.pack_start(self.vb_inner_offce, True, True, 5)
if machine() == "x86_64":
self.vb_inner.pack_start(self.vb_inner_virt, True, True, 5)
self.scrolledwindow.add(self.vb_inner)
self.vb.pack_start(Gtk.Separator(), False, False, 10)
self.hb_bottom = Gtk.Box(spacing = 5, homogeneous = False)
self.cancel_button = Gtk.Button.new_with_label("Close")
self.cancel_button.connect("clicked", self.on_cancel_clicked)
self.hb_bottom.pack_end(self.cancel_button, False, False, 2)
lynx_img = Gtk.Image.new_from_icon_name("browser", Gtk.IconSize.BUTTON)
help_img = Gtk.Image.new_from_icon_name("help-about", Gtk.IconSize.BUTTON)
file_img = Gtk.Image.new_from_icon_name("cdr", Gtk.IconSize.BUTTON)
self.lynx_button = Gtk.Button.new_with_label("Run Lynx")
self.lynx_button.set_image(lynx_img)
self.lynx_button.set_always_show_image(True)
self.lynx_button.connect("clicked", self.on_lynx_clicked)
self.hb_bottom.pack_end(self.lynx_button, False, False, 2)
self.help_button = Gtk.Button.new_with_label("Help")
self.help_button.set_image(help_img)
self.help_button.set_always_show_image(True)
self.help_button.connect("clicked", self.on_help_clicked)
self.hb_bottom.pack_end(self.help_button, False, False, 2)
self.file_button = Gtk.Button.new_with_label("File")
self.file_button.set_image(file_img)
self.file_button.set_always_show_image(True)
self.file_button.connect("clicked", self.on_file_clicked)
self.hb_bottom.pack_end(self.file_button, False, False, 2)
self.vb.pack_start(self.hb_bottom, False, False, 5)
self.add(self.vb)
self.help_button.grab_focus()
def add_button(self, button_text, tooltip, option, fb):
button = Gtk.Button.new_with_label(button_text)
button.set_tooltip_text(tooltip)
button.set_relief(Gtk.ReliefStyle.NONE)
Gtk.Widget.set_focus_on_click(button, False)
button.connect("clicked", self.on_button_clicked, button_text, option)
fb.add(button)
def on_button_clicked(self, button, *data):
gterm = GtkTerminal(self, "Updating " + data[0], data[1])
gterm.run()
gterm.destroy()
def on_cancel_clicked(self, button):
Gtk.main_quit()
def on_lynx_clicked(self, button):
Popen(['su', '--login', environ["USER"], 'vterm', '/usr/bin/lynx'], stdin=None, stdout=None, stderr=None, close_fds=True)
def on_help_clicked(self, button):
help_dialog = HelpDialog(self)
help_dialog.run()
help_dialog.destroy()
def on_file_clicked(self, button):
Popen(['dbus-run-session', '/opt/porteus-scripts/xorg/fmanager', '/tmp'], stdin=None, stdout=None, stderr=None, close_fds=True)
class GtkTerminal(Gtk.Dialog):
def __init__(self, parent, header_txt, option):
Gtk.Dialog.__init__(self, "Porteus Terminal", parent, 0)
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
self.set_default_size(450, 550)
self.vb = self.get_content_area()
self.l_header_txt = Gtk.Label()
self.l_header_txt.set_markup("" + header_txt + "")
self.vb.add(self.l_header_txt)
self.terminal = Vte.Terminal()
self.pty = Vte.Pty.new_sync(Vte.PtyFlags.DEFAULT)
self.terminal.set_pty(self.pty)
self.pty.spawn_async(None, ['/opt/porteus-scripts/update', option], None, GLib.SpawnFlags.DO_NOT_REAP_CHILD, None, None, -1, None, self.ready)
self.scrolledwindow = Gtk.ScrolledWindow()
self.scrolledwindow.add(self.terminal)
self.vb.pack_start(self.scrolledwindow, True, True, 5)
self.show_all()
def ready(self, pty, task):
# print('ready')
None
class HelpDialog(Gtk.Dialog):
def __init__(self, parent):
Gtk.Dialog.__init__(self, "Help", parent, 0)
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
self.set_default_size(550, 500)
self.help_header_txt = "Porteus Module Centre Help"
self.help_txt = "Porteus Module Centre is to help you get or update selected software. \nChoose by \
clicking a button and follow the y/n prompts in the terminal window that opens. Some option offer a choice, either to download a premade \
module from our server or to build it from official packages. \
\n\nIf you choose the latter, for Firefox, Chrome, Chromium, or Opera you can choose your preferred language and \
set a custom homepage (the default homepage is the Porteus forum: https://forum.porteus.org).\
\n\nAt the end, the chosen module(s) can be found in /tmp directory. Multiple modules can be chosen (one at a time).\
\n\nThe Run Lynx button launches a terminal with the included Lynx text based Web browser.\
\n\nYou can use the File button below to open a Privileged (Root user) Filemanager or you can use the normal (Guest user) Filemanager, \
to move the module to your porteus modules directory or somewhere else outside the live filesystem to survive reboot. Don\'t forget \
to activate it (double click). The last activated browser will become the icon visible on the toolbar."
self.l_header_txt = Gtk.Label()
self.l_header_txt.set_markup(self.help_header_txt)
self.vb = self.get_content_area()
self.vb.add(self.l_header_txt)
self.scrolledwindow = Gtk.ScrolledWindow(hexpand = True, vexpand = True)
self.vb.pack_start(self.scrolledwindow, True, True, 5)
self.textview = Gtk.TextView(border_width = 20, editable = False, wrap_mode = Gtk.WrapMode.WORD, justification = Gtk.Justification.FILL, cursor_visible = False)
self.textbuffer = self.textview.get_buffer()
self.textbuffer.set_text(self.help_txt)
self.scrolledwindow.add(self.textview)
self.show_all()
win = GtkBrowserUpdate()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()