#!/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()