@eshanized updated the repository!!!

This commit is contained in:
Eshan Roy (Eshanized)
2024-04-19 09:03:31 +05:30
parent d1b9436026
commit 3845ba4135
26 changed files with 0 additions and 9706 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,523 +0,0 @@
# =================================================================
# = Author: Cameron Percival =
# =================================================================
import os
import sys
import shutil
import psutil
import datetime
# import time
import subprocess
import threading # noqa
import gi
# import configparser
gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gtk # noqa
# =====================================================
# Create log file
# =====================================================
log_dir = "/var/log/snigdhaos/"
aai_log_dir = "/var/log/snigdhaos/aai/"
def create_log(self):
print("Making log in /var/log/snigdhaos")
now = datetime.datetime.now()
time = now.strftime("%Y-%m-%d-%H-%M-%S")
destination = aai_log_dir + "aai-log-" + time
command = "sudo pacman -Q > " + destination
subprocess.call(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
# GLib.idle_add(show_in_app_notification, self, "Log file created")
# =====================================================
# GLOBAL FUNCTIONS
# =====================================================
def _get_position(lists, value):
data = [string for string in lists if value in string]
position = lists.index(data[0])
return position
# =====================================================
# PERMISSIONS
# =====================================================
def permissions(dst):
try:
groups = subprocess.run(
["sh", "-c", "id " + sudo_username],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
for x in groups.stdout.decode().split(" "):
if "gid" in x:
g = x.split("(")[1]
group = g.replace(")", "").strip()
subprocess.call(["chown", "-R", sudo_username + ":" + group, dst], shell=False)
except Exception as e:
print(e)
#######ANYTHING UNDER THIS LINE IS CURRENTLY UNUSED!
sudo_username = os.getlogin()
home = "/home/" + str(sudo_username)
sddm_default = "/etc/sddm.conf"
sddm_default_original = "/usr/local/share/snigdhaos/sddm/sddm.conf"
sddm_default_d1 = "/etc/sddm.conf"
sddm_default_d2 = "/etc/sddm.conf.d/kde_settings.conf"
sddm_default_d2_dir = "/etc/sddm.conf.d/"
sddm_default_d_sddm_original_1 = "/usr/local/share/snigdhaos/sddm.conf.d/sddm.conf"
sddm_default_d_sddm_original_2 = (
"/usr/local/share/snigdhaos/sddm.conf.d/kde_settings.conf"
)
if os.path.exists("/etc/sddm.conf.d/kde_settings.conf"):
sddm_conf = "/etc/sddm.conf.d/kde_settings.conf"
else:
sddm_conf = "/etc/sddm.conf"
snigdhaos_mirrorlist = "/etc/pacman.d/snigdhaos-mirrorlist"
snigdhaos_mirrorlist_original = "/usr/local/share/snigdhaos/snigdhaos-mirrorlist"
pacman = "/etc/pacman.conf"
oblogout_conf = "/etc/oblogout.conf"
# oblogout_conf = home + "/oblogout.conf"
gtk3_settings = home + "/.config/gtk-3.0/settings.ini"
gtk2_settings = home + "/.gtkrc-2.0"
grub_theme_conf = "/boot/grub/themes/snigdhaos-grub-theme/theme.txt"
xfce_config = home + "/.config/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml"
slimlock_conf = "/etc/slim.conf"
termite_config = home + "/.config/termite/config"
neofetch_config = home + "/.config/neofetch/config.conf"
lightdm_conf = "/etc/lightdm/lightdm.conf"
bd = ".att_backups"
config = home + "/.config/archlinux-tweak-tool/settings.ini"
config_dir = home + "/.config/archlinux-tweak-tool/"
polybar = home + "/.config/polybar/"
desktop = ""
autostart = home + "/.config/autostart/"
zsh_config = home + "/.zshrc"
account_list = ["Standard", "Administrator"]
i3wm_config = home + "/.config/i3/config"
awesome_config = home + "/.config/awesome/rc.lua"
qtile_config = home + "/.config/qtile/config.py"
arepo = "[snigdhaos-core]\n\
SigLevel = Required DatabaseOptional\n\
Include = /etc/pacman.d/snigdhaos-mirrorlist"
a3drepo = "[snigdhaos-extra]\n\
SigLevel = Required DatabaseOptional\n\
Include = /etc/pacman.d/snigdhaos-mirrorlist"
# =====================================================
# NOTIFICATIONS
# =====================================================
def show_in_app_notification(self, message):
if self.timeout_id is not None:
GLib.source_remove(self.timeout_id)
self.timeout_id = None
self.notification_label.set_markup(
'<span foreground="white">' + message + "</span>"
)
self.notification_revealer.set_reveal_child(True)
self.timeout_id = GLib.timeout_add(3000, timeOut, self)
def timeOut(self):
close_in_app_notification(self)
def close_in_app_notification(self):
self.notification_revealer.set_reveal_child(False)
GLib.source_remove(self.timeout_id)
self.timeout_id = None
# =====================================================
# PERMISSIONS
# =====================================================
def test(dst):
for root, dirs, filesr in os.walk(dst):
# print(root)
for folder in dirs:
pass
# print(dst + "/" + folder)
for file in filesr:
pass
# print(dst + "/" + folder + "/" + file)
for file in filesr:
pass
# print(dst + "/" + file)
# =====================================================
# COPY FUNCTION
# =====================================================
def copy_func(src, dst, isdir=False):
if isdir:
subprocess.run(["cp", "-Rp", src, dst], shell=False)
else:
subprocess.run(["cp", "-p", src, dst], shell=False)
# permissions(dst)
# =====================================================
# SOURCE
# =====================================================
def source_shell(self):
process = subprocess.run(["sh", "-c", 'echo "$SHELL"'], stdout=subprocess.PIPE)
output = process.stdout.decode().strip()
print(output)
if output == "/bin/bash":
subprocess.run(
[
"bash",
"-c",
"su - " + sudo_username + ' -c "source ' + home + '/.bashrc"',
],
stdout=subprocess.PIPE,
)
elif output == "/bin/zsh":
subprocess.run(
["zsh", "-c", "su - " + sudo_username + ' -c "source ' + home + '/.zshrc"'],
stdout=subprocess.PIPE,
)
def run_as_user(script):
subprocess.call(["su - " + sudo_username + " -c " + script], shell=False)
# =====================================================
# MESSAGEBOX
# =====================================================
def MessageBox(self, title, message):
md2 = Gtk.MessageDialog(
parent=self,
flags=0,
message_type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK,
text=title,
)
md2.format_secondary_markup(message)
md2.run()
md2.destroy()
# =====================================================
# CONVERT COLOR
# =====================================================
def rgb_to_hex(rgb):
if "rgb" in rgb:
rgb = rgb.replace("rgb(", "").replace(")", "")
vals = rgb.split(",")
return "#{0:02x}{1:02x}{2:02x}".format(
clamp(int(vals[0])), clamp(int(vals[1])), clamp(int(vals[2]))
)
return rgb
def clamp(x):
return max(0, min(x, 255))
# =====================================================
# GLOBAL FUNCTIONS
# =====================================================
def _get_variable(lists, value):
data = [string for string in lists if value in string]
if len(data) >= 1:
data1 = [string for string in data if "#" in string]
for i in data1:
if i[:4].find("#") != -1:
data.remove(i)
if data:
data_clean = [data[0].strip("\n").replace(" ", "")][0].split("=")
return data_clean
# Check value exists
def check_value(list, value):
data = [string for string in list if value in string]
if len(data) >= 1:
data1 = [string for string in data if "#" in string]
for i in data1:
if i[:4].find("#") != -1:
data.remove(i)
return data
def check_backups(now):
if not os.path.exists(home + "/" + bd + "/Backup-" + now.strftime("%Y-%m-%d %H")):
os.makedirs(home + "/" + bd + "/Backup-" + now.strftime("%Y-%m-%d %H"), 0o777)
permissions(home + "/" + bd + "/Backup-" + now.strftime("%Y-%m-%d %H"))
# =====================================================
# Check if File Exists
# =====================================================
def file_check(file):
if os.path.isfile(file):
return True
return False
def path_check(path):
if os.path.isdir(path):
return True
return False
# =====================================================
# GTK3 CONF
# =====================================================
def gtk_check_value(my_list, value):
data = [string for string in my_list if value in string]
if len(data) >= 1:
data1 = [string for string in data if "#" in string]
for i in data1:
if i[:4].find("#") != -1:
data.remove(i)
return data
def gtk_get_position(my_list, value):
data = [string for string in my_list if value in string]
position = my_list.index(data[0])
return position
# =====================================================
# OBLOGOUT CONF
# =====================================================
# Get shortcuts index
def get_shortcuts(conflist):
sortcuts = _get_variable(conflist, "shortcuts")
shortcuts_index = _get_position(conflist, sortcuts[0])
return int(shortcuts_index)
# Get commands index
def get_commands(conflist):
commands = _get_variable(conflist, "commands")
commands_index = _get_position(conflist, commands[0])
return int(commands_index)
# =====================================================
# LIGHTDM CONF
# =====================================================
def check_lightdm_value(list, value):
data = [string for string in list if value in string]
# if len(data) >= 1:
# data1 = [string for string in data if "#" in string]
return data
# =====================================================
# SDDM CONF
# =====================================================
def check_sddm_value(list, value):
data = [string for string in list if value in string]
return data
# =====================================================
# HBLOCK CONF
# =====================================================
def hblock_get_state(self):
lines = int(
subprocess.check_output("wc -l /etc/hosts", shell=True).strip().split()[0]
)
if os.path.exists("/usr/local/bin/hblock") and lines > 100:
return True
self.firstrun = False
return False
def do_pulse(data, prog):
prog.pulse()
return True
# =====================================================
# UBLOCK ORIGIN
# =====================================================
def ublock_get_state(self):
if os.path.exists(
"/usr/lib/firefox/browser/extensions/uBlock0@raymondhill.net.xpi"
):
return True
return False
def set_firefox_ublock(self, toggle, state):
GLib.idle_add(toggle.set_sensitive, False)
GLib.idle_add(self.label7.set_text, "Run..")
GLib.idle_add(self.progress.set_fraction, 0.2)
timeout_id = None
timeout_id = GLib.timeout_add(100, do_pulse, None, self.progress)
try:
install_ublock = "pacman -S firefox-ublock-origin --needed --noconfirm"
uninstall_ublock = "pacman -Rs firefox-ublock-origin --noconfirm"
if state:
GLib.idle_add(self.label7.set_text, "Installing ublock Origin...")
subprocess.call(
install_ublock.split(" "),
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
else:
GLib.idle_add(self.label7.set_text, "Removing ublock Origin...")
subprocess.call(
uninstall_ublock.split(" "),
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
GLib.idle_add(self.label7.set_text, "Complete")
GLib.source_remove(timeout_id)
timeout_id = None
GLib.idle_add(self.progress.set_fraction, 0)
GLib.idle_add(toggle.set_sensitive, True)
if state:
GLib.idle_add(self.label7.set_text, "uBlock Origin installed")
else:
GLib.idle_add(self.label7.set_text, "uBlock Origin removed")
except Exception as e:
MessageBox(self, "ERROR!!", str(e))
print(e)
# =====================================================
# ALACRITTY
# =====================================================
def install_alacritty(self):
install = "pacman -S alacritty --needed --noconfirm"
if os.path.exists("/usr/bin/alacritty"):
pass
else:
subprocess.call(
install.split(" "),
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
def copytree(self, src, dst, symlinks=False, ignore=None): # noqa
if not os.path.exists(dst):
os.makedirs(dst)
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.exists(d):
try:
shutil.rmtree(d)
except Exception as e:
print(e)
os.unlink(d)
if os.path.isdir(s):
try:
shutil.copytree(s, d, symlinks, ignore)
except Exception as e:
print(e)
print("ERROR2")
self.ecode = 1
else:
try:
shutil.copy2(s, d)
except: # noqa
print("ERROR3")
self.ecode = 1
# =====================================================
# CHECK RUNNING PROCESS
# =====================================================
def checkIfProcessRunning(processName):
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(attrs=["pid", "name", "create_time"])
if processName == pinfo["pid"]:
return True
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
return False
def restart_program():
python = sys.executable
os.execl(python, python, *sys.argv)

View File

@@ -1,19 +0,0 @@
# This class is to encapsulate package metadata, taken from the yaml files stored inside the blackbox github repository
class Package(object):
def __init__(
self,
name,
description,
category,
subcategory,
subcategory_description,
version,
):
self.name = name
self.description = description
self.category = category
self.subcategory = subcategory
self.subcategory_description = subcategory_description
self.version = version

View File

@@ -1,132 +0,0 @@
# This class is used to process configuration data for the app
import os
import Functions as fn
from string import Template
base_dir = os.path.dirname(os.path.realpath(__file__))
# a default configuration file if one doesn't exist is copied over from /usr/share/blackbox/defaults to $HOME/.config
default_file = "%s/defaults/blackbox.yaml" % base_dir
class Settings(object):
def __init__(self, display_versions, display_package_progress):
self.display_versions = display_versions
self.display_package_progress = display_package_progress
def write_config_file(self):
try:
content = []
with open(fn.config_file, "r", encoding="UTF-8") as f:
contents = f.readlines()
if len(contents) > 0:
self.read(contents)
conf_settings = {}
conf_settings["Display Package Versions"] = self.display_versions
conf_settings[
"Display Package Progress"
] = self.display_package_progress
index = 0
for line in contents:
if line.startswith("- name:"):
if (
line.strip("- name: ")
.strip()
.strip('"')
.strip("\n")
.strip()
== "Display Package Versions"
):
index = contents.index(line)
index += 2
if contents[index].startswith(" enabled: "):
del contents[index]
contents.insert(
index,
" enabled: %s\n"
% conf_settings["Display Package Versions"],
)
if (
line.strip("- name: ")
.strip()
.strip('"')
.strip("\n")
.strip()
== "Display Package Progress"
):
index += 4
if contents[index].startswith(" enabled: "):
del contents[index]
contents.insert(
index,
" enabled: %s\n"
% conf_settings["Display Package Progress"],
)
if len(contents) > 0:
with open(fn.config_file, "w", encoding="UTF-8") as f:
f.writelines(contents)
fn.permissions(fn.config_dir)
except Exception as e:
fn.logger.error("Exception in write_config_file(): %s" % e)
def read_config_file(self):
try:
if os.path.exists(fn.config_file):
contents = []
with open(fn.config_file, "r", encoding="UTF-8") as f:
contents = f.readlines()
# file is empty, string replace template file
if len(contents) == 0:
fn.shutil.copy(default_file, fn.config_file)
fn.permissions(fn.config_dir)
else:
return self.read(contents)
else:
# config file doesn't exist, string replace template file
fn.shutil.copy(default_file, fn.config_file)
fn.permissions(fn.config_dir)
with open(fn.config_file, "r", encoding="UTF-8") as f:
contents = f.readlines()
return self.read(contents)
except Exception as e:
print("Exception in read_config_file(): %s" % e)
def read(self, contents):
setting_name = None
setting_value_enabled = None
conf_settings = {}
for line in contents:
if line.startswith("- name:"):
setting_name = (
line.strip("- name: ").strip().strip('"').strip("\n").strip()
)
elif line.startswith(" enabled: "):
setting_value_enabled = (
line.strip(" enabled: ").strip().strip('"').strip("\n").strip()
)
if setting_value_enabled == "False":
conf_settings[setting_name] = False
else:
conf_settings[setting_name] = True
if len(conf_settings) > 0:
return conf_settings
else:
print("[ERROR] Failed to read settings into memory")

View File

@@ -1,61 +0,0 @@
frame#awesome * {
padding-left: 20px;
padding-right: 20px;
padding-bottom: 20px;
padding-top: 10px;
border-color: transparent;
}
box#vbox {
padding-right: 20px;
}
#sidebar label {
font-size: 14px;
font-weight: 500;
padding-left: 15px;
padding-right: 15px;
}
label#title {
font-size: 20px;
font-weight: 600;
}
label#lbl_package_version {
color: white;
background-color: #5481e5;
border: 3px solid #5481e5;
border-radius: 100px;
font-size: 80%;
font-weight: bold;
padding-left: 5px;
padding-right: 5px;
}
infobar#infobar_info {
background-color: #5481e5;
color: white;
}
infobar#infobar_error {
background-color: #9d261d;
color: white;
}
infobar#infobar_warning {
background-color: #ffcc00;
color: black;
}
modelbutton#modelbtn_popover{
padding-left: 0;
padding-right: 0;
padding-top: 1px;
padding-bottom: 1px;
}
modelbutton#modelbtn_popover:hover{
font-weight: bold;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +0,0 @@
- name: "Display Package Versions"
description: "Show package version labels alongside the package description <True/False>"
enabled: False
- name: "Display Package Progress"
description: "Show the package install/uninstall progress window <True/False>"
enabled: False
- name: "Debug Logging"
description: "Enable debug logging for more verbose app logging <True/False>"
enabled: False

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -1,34 +0,0 @@
#!/bin/bash
######################################################################################################################
sudo pacman -S wget --noconfirm --needed
echo "Getting the Snigdha OS keys from the Snigdha PS repo - report if link is broken"
sudo wget https://github.com/arcolinux/arcolinux_repo/raw/main/x86_64/arcolinux-keyring-20251209-3-any.pkg.tar.zst -O /tmp/arcolinux-keyring-20251209-3-any.pkg.tar.zst
sudo pacman -U --noconfirm --needed /tmp/arcolinux-keyring-20251209-3-any.pkg.tar.zst
echo "Getting the latest arcolinux mirrors file - report if link is broken"
sudo wget https://github.com/arcolinux/arcolinux_repo/raw/main/x86_64/arcolinux-mirrorlist-git-23.06-01-any.pkg.tar.zst -O /tmp/arcolinux-mirrorlist-git-23.06-01-any.pkg.tar.zst
sudo pacman -U --noconfirm --needed /tmp/arcolinux-mirrorlist-git-23.06-01-any.pkg.tar.zst
######################################################################################################################
if grep -q snigdhaos-core /etc/pacman.conf; then
echo "Snigdha OS repos are already in /etc/pacman.conf"
else
echo '
[snigdhaos-core]
SigLevel = PackageRequired DatabaseNever
Include = /etc/pacman.d/snigdhaos-mirrorlist
[snigdhaos-extra]
SigLevel = PackageRequired DatabaseNever
Include = /etc/pacman.d/snigdhaos-mirrorlist' | sudo tee --append /etc/pacman.conf
fi
echo "DONE - UPDATE NOW"

View File

@@ -1,192 +0,0 @@
# This class stores static information about the app, and is displayed in the about dialog
import os
import gi
from gi.repository import Gtk, Gdk, GdkPixbuf, Pango, GLib
gi.require_version("Gtk", "3.0")
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
# base_dir = os.path.dirname(os.path.realpath(__file__))
class AboutDialog(Gtk.Dialog):
def __init__(self):
Gtk.Dialog.__init__(self)
app_name = "BlackBox"
app_title = "About BlackBox"
app_main_description = "%s - %s" % (app_name, "Software Installer Remover")
app_secondary_message = "Install or remove software from your ArcoLinux system"
app_secondary_description = "Report issues to make it even better"
app_version = "pkgversion-pkgrelease"
app_discord = "https://discord.gg/stBhS4taje"
app_website = "https://arcolinux.info"
app_github = "https://github.com/Snigdha-OS/blackbox"
app_authors = []
app_authors.append(("Cameron Percival", None))
app_authors.append(("Fennec", None))
app_authors.append(("Erik Dubois", None))
pixbuf = GdkPixbuf.Pixbuf().new_from_file_at_size(
os.path.join(base_dir, "images/blackbox.png"), 100, 100
)
app_image = Gtk.Image().new_from_pixbuf(pixbuf)
self.set_resizable(False)
self.set_size_request(560, 350)
self.set_icon_from_file(os.path.join(base_dir, "images/blackbox.png"))
self.set_border_width(10)
headerbar = Gtk.HeaderBar()
headerbar.set_show_close_button(True)
headerbar.set_title(app_title)
self.set_titlebar(headerbar)
btn_about_close = Gtk.Button(label="OK")
btn_about_close.connect("clicked", self.on_response, "response")
stack = Gtk.Stack()
stack.set_transition_type(Gtk.StackTransitionType.SLIDE_UP_DOWN)
stack.set_transition_duration(350)
stack.set_hhomogeneous(False)
stack.set_vhomogeneous(False)
stack_switcher = Gtk.StackSwitcher()
stack_switcher.set_orientation(Gtk.Orientation.HORIZONTAL)
stack_switcher.set_stack(stack)
stack_switcher.set_homogeneous(True)
lbl_main_description = Gtk.Label(xalign=0, yalign=0)
lbl_main_description.set_markup(
"<b> %s</b>" % app_main_description
)
lbl_secondary_message = Gtk.Label(xalign=0, yalign=0)
lbl_secondary_message.set_text(
" %s" % app_secondary_message
)
lbl_secondary_description = Gtk.Label(xalign=0, yalign=0)
lbl_secondary_description.set_text(
" %s" % app_secondary_description
)
lbl_version = Gtk.Label(xalign=0, yalign=0)
lbl_version.set_markup(
" <b>Version:</b> %s" % app_version
)
ivbox_about = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
ivbox_about.pack_start(app_image, True, True, 0)
ivbox_about.pack_start(lbl_main_description, True, True, 0)
ivbox_about.pack_start(lbl_version, True, True, 0)
ivbox_about.pack_start(lbl_secondary_message, True, True, 0)
ivbox_about.pack_start(lbl_secondary_description, True, True, 0)
stack.add_titled(ivbox_about, "About BlackBox", "About")
grid_support = Gtk.Grid()
lbl_padding1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding1.set_text(" ")
grid_support.attach(lbl_padding1, 0, 1, 1, 1)
lbl_support_title = Gtk.Label(xalign=0, yalign=0)
lbl_support_title.set_markup("<b>Discord </b>")
lbl_support_value = Gtk.Label(xalign=0, yalign=0)
lbl_support_value.set_markup("<a href='%s'>%s</a>" % (app_discord, app_discord))
lbl_website_title = Gtk.Label(xalign=0, yalign=0)
lbl_website_title.set_markup("<b>ArcoLinux website </b>")
lbl_website_value = Gtk.Label(xalign=0, yalign=0)
lbl_website_value.set_markup("<a href='%s'>%s</a>" % (app_website, app_website))
lbl_github_title = Gtk.Label(xalign=0, yalign=0)
lbl_github_title.set_markup("<b>GitHub </b>")
lbl_github_value = Gtk.Label(xalign=0, yalign=0)
lbl_github_value.set_markup("<a href='%s'>%s</a>" % (app_github, app_github))
grid_support.attach(lbl_support_title, 0, 2, 1, 1)
grid_support.attach_next_to(
lbl_support_value, lbl_support_title, Gtk.PositionType.RIGHT, 20, 1
)
grid_support.attach(lbl_website_title, 0, 3, 1, 1)
grid_support.attach_next_to(
lbl_website_value, lbl_website_title, Gtk.PositionType.RIGHT, 20, 1
)
grid_support.attach(lbl_github_title, 0, 4, 1, 1)
grid_support.attach_next_to(
lbl_github_value, lbl_github_title, Gtk.PositionType.RIGHT, 20, 1
)
stack.add_titled(grid_support, "Support", "Support")
box_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
box_outer.set_border_width(10)
lbl_padding2 = Gtk.Label(xalign=0, yalign=0)
lbl_padding2.set_text(" ")
lbl_padding3 = Gtk.Label(xalign=0, yalign=0)
lbl_padding3.set_text(" ")
lbl_authors_title = Gtk.Label(xalign=0, yalign=0)
lbl_authors_title.set_text(
"The following people have contributed to the development of %s" % app_name
)
listbox = Gtk.ListBox()
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
box_outer.pack_start(lbl_authors_title, True, True, 0)
box_outer.pack_start(listbox, True, True, 0)
treestore_authors = Gtk.TreeStore(str, str)
for item in app_authors:
treestore_authors.append(None, list(item))
treeview_authors = Gtk.TreeView(model=treestore_authors)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(None, renderer, text=0)
treeview_authors.append_column(column)
path = Gtk.TreePath.new_from_indices([0])
selection = treeview_authors.get_selection()
selection.select_path(path)
treeview_authors.expand_all()
treeview_authors.columns_autosize()
row_authors = Gtk.ListBoxRow()
vbox_authors = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
row_authors.add(vbox_authors)
vbox_authors.pack_start(treeview_authors, True, True, 0)
listbox.add(row_authors)
stack.add_titled(box_outer, "Authors", "Authors")
self.connect("response", self.on_response)
self.vbox.add(stack_switcher)
self.vbox.add(stack)
self.show_all()
def on_response(self, dialog, response):
self.hide()
self.destroy()

View File

@@ -1,523 +0,0 @@
# =================================================================
# = Author: Cameron Percival =
# =================================================================
from socket import TIPC_ADDR_NAME
from urllib.parse import scheme_chars
import Functions as fn
class AppFrameGUI:
def build_ui_frame(self, Gtk, vbox_stack, category, packages_list):
try:
# Lets set some variables that we know we will need later
# hboxes and items to make the page look sensible
cat_name = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
seperator = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
lbl1 = Gtk.Label(xalign=0)
lbl1.set_text(category)
lbl1.set_name("title")
hseparator = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
seperator.pack_start(hseparator, True, True, 0)
cat_name.pack_start(lbl1, False, False, 0)
# Stack for the different subcategories - I like crossfade as a transition, but you choose
stack = Gtk.Stack()
stack.set_transition_type(Gtk.StackTransitionType.SLIDE_UP_DOWN)
stack.set_transition_duration(350)
stack.set_hhomogeneous(False)
stack.set_vhomogeneous(False)
# Stack needs a stack switcher to allow the user to make different choices
stack_switcher = Gtk.StackSwitcher()
stack_switcher.set_orientation(Gtk.Orientation.HORIZONTAL)
stack_switcher.set_stack(stack)
stack_switcher.set_homogeneous(True)
# We will need a vbox later for storing the stack and stack switcher together at the end
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
# create scroller for when/if these items go "off the page"
scrolled_switch = Gtk.ScrolledWindow()
scrolled_switch.add(stack_switcher)
# These lists will ensure that we can keep track of the individual windows and their names
# stack of vboxes
vbox_stacks = []
# name of each vbox - derived from the sub category name
vbox_stacknames = []
sep_text = " "
subcats = {}
# index for the grid
index = 0
"""
Store a list of unique sub-categories
e.g.
category --> applications
sub category --> Accessories
sub category --> Conky
"""
sub_catlabels = []
# store unique subcategory names into a dictionary
for package in packages_list:
subcats[package.subcategory] = package
# we now iterate across the dictionary keys
# each Stack has an associated subcategory
for subcat in subcats.keys():
vbox_stacks.append(
Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
)
# for the sub-cat page title
sub_catlabels.append(Gtk.Label(xalign=0))
vbox_stacknames.append(subcat)
# iterate across a list of packages
for package in packages_list:
if package.subcategory == subcat:
page = vbox_stacks.pop()
if len(sub_catlabels) > 0:
lbl_title = sub_catlabels.pop()
lbl_desc = Gtk.Label(xalign=0)
lbl_desc.set_markup(
"Description: <i><b>"
+ package.subcategory_description
+ "</b></i>"
)
lbl_title.set_markup("<b>" + package.subcategory + "</b>")
lbl_padding_page1 = Gtk.Label(xalign=0)
lbl_padding_page1.set_text("")
page.pack_start(lbl_title, False, False, 0)
page.pack_start(lbl_desc, False, False, 0)
page.pack_start(lbl_padding_page1, False, False, 0)
grid = Gtk.Grid()
grid.insert_row(index)
lbl_sep1 = Gtk.Label(xalign=0, yalign=0)
lbl_sep1.set_text(sep_text)
grid.attach(lbl_sep1, 0, index, 1, 1)
lbl_package = Gtk.Label(xalign=0, yalign=0) # was in for loop
lbl_package.set_markup("<b>%s</b>" % package.name)
###### switch widget starts ######
# construct new switch
switch = Gtk.Switch()
switch.set_valign(Gtk.Align.CENTER)
"""
Changed to use signal state-set for switch widget.
set_state(boolean) allows the switch state to be enabled/disabled.
When a pkg install/uninstall fails, the switch widget is enabled/disabled inside a thread.
Changing the switch using set_active(bool), and using the signal notify::active
caused a never-ending loop which would call app_toggle.
"""
switch.set_state(fn.query_pkg(package.name))
switch.connect(
"state-set",
self.app_toggle,
package,
)
# add switch widget to grid
# attach_next_to(child, sibling, side, width, height)
grid.attach_next_to(
switch, lbl_sep1, Gtk.PositionType.LEFT, 1, 1
)
# add space seperator next to switch
lbl_sep_switch = Gtk.Label(xalign=0, yalign=0)
lbl_sep_switch.set_text(sep_text)
grid.attach_next_to(
lbl_sep_switch, switch, Gtk.PositionType.LEFT, 1, 1
)
###### switch widget ends ######
###### pkg name label widget starts ######
lbl_sep_package1 = Gtk.Label(xalign=0, yalign=0)
lbl_sep_package1.set_text(sep_text)
# add space seperator next to switch for extra padding
grid.attach_next_to(
lbl_sep_package1, switch, Gtk.PositionType.RIGHT, 1, 1
)
lbl_sep_package2 = Gtk.Label(xalign=0, yalign=0)
lbl_sep_package2.set_text(sep_text)
# add pkg name label widget to grid
grid.attach_next_to(
lbl_package, lbl_sep_package1, Gtk.PositionType.RIGHT, 1, 1
)
###### pkg name label widget ends
###### pkg desc label widget starts ######
lbl_sep_package_desc = Gtk.Label(xalign=0, yalign=0)
lbl_sep_package_desc.set_text(sep_text)
# add space seperator next to pkg name for extra padding
grid.attach_next_to(
lbl_sep_package_desc,
lbl_package,
Gtk.PositionType.RIGHT,
1,
1,
)
lbl_package_desc = Gtk.Label(xalign=0, yalign=0)
lbl_package_desc.set_text(package.description)
# add pkg desc label widget to grid
grid.attach_next_to(
lbl_package_desc,
lbl_sep_package_desc,
Gtk.PositionType.RIGHT,
1,
1,
)
###### pkg desc label widget ends
##### add pkg version label widget starts #####
if self.display_versions is True:
lbl_package_version = Gtk.Label(xalign=0, yalign=0)
lbl_package_version.set_text(package.version)
lbl_package_version.set_name("lbl_package_version")
lbl_sep_package_version = Gtk.Label(xalign=0, yalign=0)
lbl_sep_package_version.set_text(sep_text)
grid.attach_next_to(
lbl_sep_package_version,
lbl_package_desc,
Gtk.PositionType.RIGHT,
1,
1,
)
grid.attach_next_to(
lbl_package_version,
lbl_sep_package_version,
Gtk.PositionType.RIGHT,
1,
1,
)
##### pkg version ends #####
# make the page scrollable
grid_sc = Gtk.ScrolledWindow()
# hide the horizontal scrollbar showing on each grid row if the window width is resized
grid_sc.set_policy(
Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC
)
grid_sc.add(grid)
grid_sc.set_propagate_natural_height(True)
# pack the grid to the page.
page.pack_start(grid_sc, True, True, 0)
# save the page - put it back (now populated)
"""
UI note.
To remove the extra padding around the switch buttons
Comment out the references to grid_sc
Then just have page.pack_start(grid,True, True, 0)
"""
vbox_stacks.append(page)
# reset the things that we need to.
# packages.clear()
grid = Gtk.Grid()
index += 1
# Now we pack the stack
item_num = 0
for item in vbox_stacks:
stack.add_titled(
item,
"stack" + str(item_num),
vbox_stacknames[item_num],
)
item_num += 1
# Place the stack switcher and the stack together into a vbox
vbox.pack_start(scrolled_switch, False, False, 0)
scrolled_window = Gtk.ScrolledWindow()
scrolled_window.set_propagate_natural_height(True)
scrolled_window.add(stack)
vbox.pack_start(scrolled_window, True, True, 0)
# Stuff the vbox with the title and seperator to create the page
vbox_stack.pack_start(cat_name, False, False, 0)
vbox_stack.pack_start(seperator, False, False, 0)
vbox_stack.pack_start(vbox, False, False, 0)
except Exception as e:
fn.logger.error("Exception in App_Frame_GUI.GUI(): %s" % e)
########## PREVIOUS GUI CODE START ##########
"""
def GUI(self, Gtk, vboxStack1, category, package_file):
try:
# Lets set some variables that we know we will need later
# hboxes and items to make the page look sensible
cat_name = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
seperator = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
lbl1 = Gtk.Label(xalign=0)
lbl1.set_text(category)
lbl1.set_name("title")
hseparator = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
seperator.pack_start(hseparator, True, True, 0)
cat_name.pack_start(lbl1, False, False, 0)
# Stack for the different subcategories - I like crossfade as a transition, but you choose
stack = Gtk.Stack()
stack.set_transition_type(Gtk.StackTransitionType.SLIDE_UP_DOWN)
stack.set_transition_duration(350)
stack.set_hhomogeneous(False)
stack.set_vhomogeneous(False)
# Stack needs a stack switcher to allow the user to make different choices
stack_switcher = Gtk.StackSwitcher()
stack_switcher.set_orientation(Gtk.Orientation.HORIZONTAL)
stack_switcher.set_stack(stack)
stack_switcher.set_homogeneous(True)
# We will need a vbox later for storing the stack and stack switcher together at the end
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
# create scroller for when/if these items go "off the page"
scrolledSwitch = Gtk.ScrolledWindow()
scrolledSwitch.add(stack_switcher)
# These lists will ensure that we can keep track of the individual windows and their names
# stack of vboxes
vboxStacks = []
# name of each vbox - derived from the sub category name
vboxStackNames = []
# page variables - reset these when making multiple subcategories:
# List of packages for any given subcategory
packages = []
# labels:
name = ""
description = ""
# Lets start by reading in the package list and saving it as a file
with open(package_file, "r") as f:
content = f.readlines()
# f.close()
# Add a line to the end of content to force the page to be packed.
content.append(
"pack now"
) # Really, this can be any string, as long as it doesn't match the if statement below.
# Now lets read the file, and use some logic to drive what goes where
# Optomised for runspeed: the line most commonly activated appears first.
for line in content:
# this line will handle code in the yaml that we simply don't need or care about
# MAINTENANCE; if the structure of the .yaml file ever changes, this WILL likely need to be updated
if line.startswith(" packages:"):
continue
elif line.startswith(" - "):
# add the package to the packages list
package = line.strip(" - ")
packages.append(package)
# TODO: Add list and function to obtain package description from pacman and store it (maybe? Maybe the yaml file has what we need?)
elif line.startswith(" description: "):
# Set the label text for the description line
description = (
line.strip(" description: ").strip().strip('"').strip("\n")
)
else:
# We will only hit here for category changes, or to pack the page, or if the yaml is changed.
# Yaml changes are handled in the first if statement.
# Pack page;
if len(packages) > 0:
# Pack the page
# Packing list:
# vbox to pack into - pop it off the
page = vboxStacks.pop()
# grid it
grid = Gtk.Grid()
# Subcat
lblName = Gtk.Label(xalign=0)
lblName.set_markup("<b>" + name + "</b>")
page.pack_start(lblName, False, False, 0)
# description
lblDesc = Gtk.Label(xalign=0)
lblDesc.set_markup("Description: <i>" + description + "</i>")
page.pack_start(lblDesc, False, False, 0)
# packages
sep_text = " "
for i in range(len(packages)):
grid.insert_row(i)
# hbox_pkg = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
lblSep1 = Gtk.Label(xalign=0, yalign=0)
lblSep1.set_text(sep_text)
grid.attach(lblSep1, 0, i, 1, 1)
lblPkg = Gtk.Label(xalign=0, yalign=0) # was in for loop
lblPkg.set_markup("<b>%s</b>" % packages[i].strip()) # was in for loop
# hbox_pkg.pack_start(lblPkg, False, False, 100)
###### switch widget starts ######
# construct new switch
switch = Gtk.Switch()
switch.set_active(Functions.query_pkg(packages[i]))
switch.connect(
"notify::active",
self.app_toggle,
packages[i],
Gtk,
vboxStack1,
Functions,
category,
)
# add switch widget to grid
# attach_next_to(child, sibling, side, width, height)
grid.attach_next_to(
switch, lblSep1, Gtk.PositionType.LEFT, 1, 1
)
# add space seperator next to switch
lblSepSwitch = Gtk.Label(xalign=0, yalign=0)
lblSepSwitch.set_text(sep_text)
grid.attach_next_to(
lblSepSwitch, switch, Gtk.PositionType.LEFT, 1, 1
)
###### switch widget ends ######
###### pkg name label widget starts ######
lblSepPkg1 = Gtk.Label(xalign=0, yalign=0)
lblSepPkg1.set_text(sep_text)
# add space seperator next to switch for extra padding
grid.attach_next_to(
lblSepPkg1, switch, Gtk.PositionType.RIGHT, 1, 1
)
lblSepPkg2 = Gtk.Label(xalign=0, yalign=0)
lblSepPkg2.set_text(sep_text)
# add pkg name label widget to grid
grid.attach_next_to(
lblPkg, lblSepPkg1, Gtk.PositionType.RIGHT, 1, 1
)
###### pkg name label widget ends
###### pkg desc label widget starts ######
lblSepPkgDesc = Gtk.Label(xalign=0, yalign=0)
lblSepPkgDesc.set_text(sep_text)
# add space seperator next to pkg name for extra padding
grid.attach_next_to(
lblSepPkgDesc, lblPkg, Gtk.PositionType.RIGHT, 1, 1
)
lblPkgDesc = Gtk.Label(xalign=0, yalign=0)
lblPkgDesc.set_text(Functions.obtain_pkg_description(packages[i]))
# add pkg desc label widget to grid
grid.attach_next_to(
lblPkgDesc, lblSepPkgDesc, Gtk.PositionType.RIGHT, 1, 1
)
###### pkg desc label widget ends
# make the page scrollable
grid_sc = Gtk.ScrolledWindow()
grid_sc.add(grid)
grid_sc.set_propagate_natural_height(True)
# pack the grid to the page.
page.pack_start(grid_sc, False, False, 0)
# save the page - put it back (now populated)
vboxStacks.append(page)
# reset the things that we need to.
packages.clear()
grid = Gtk.Grid()
# category change
if line.startswith("- name: "):
# Generate the vboxStack item and name for use later (and in packing)
name = line.strip("- name: ").strip().strip('"')
vboxStackNames.append(name)
vboxStacks.append(
Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
)
# Now we pack the stack
item_num = 0
for item in vboxStacks:
stack.add_titled(item, "stack" + str(item_num), vboxStackNames[item_num])
item_num += 1
# Place the stack switcher and the stack together into a vbox
vbox.pack_start(scrolledSwitch, False, False, 0)
vbox.pack_start(stack, True, True, 0)
# Stuff the vbox with the title and seperator to create the page
vboxStack1.pack_start(cat_name, False, False, 0)
vboxStack1.pack_start(seperator, False, False, 0)
vboxStack1.pack_start(vbox, False, False, 0)
except Exception as e:
print("Exception in App_Frame_GUI.GUI(): %s" % e)
"""
########## PREVIOUS GUI CODE END ##########

View File

@@ -1,726 +0,0 @@
# =================================================================
# = Author: Cameron Percival =
# =================================================================
# ============Functions============
import Functions as fn
from ui.AppFrameGUI import AppFrameGUI
from multiprocessing import cpu_count
from queue import Queue
from threading import Thread
base_dir = fn.os.path.abspath(fn.os.path.join(fn.os.path.dirname(__file__), ".."))
# base_dir = fn.os.path.dirname(fn.os.path.realpath(__file__))
class GUI_Worker(Thread):
def __init__(self, queue):
Thread.__init__(self)
self.queue = queue
def run(self):
while True:
# pull what we need from the queue so we can process properly.
items = self.queue.get()
try:
# make sure we have the required number of items on the queue
if items is not None:
# self, Gtk, vboxStack1, category, package_file = items
self, Gtk, vbox_stack, category, packages = items
AppFrameGUI.build_ui_frame(
self,
Gtk,
vbox_stack,
category,
packages,
)
except Exception as e:
fn.logger.error("Exception in GUI_Worker(): %s" % e)
finally:
if items is None:
fn.logger.debug("Stopping GUI Worker thread")
self.queue.task_done()
return False
self.queue.task_done()
class GUI:
def setup_gui_search(
self,
Gtk,
Gdk,
GdkPixbuf,
base_dir,
os,
Pango,
search_results,
search_term,
settings,
):
try:
# remove previous vbox
if self.search_activated == False:
self.remove(self.vbox)
else:
self.remove(self.vbox_search)
# lets quickly create the latest installed list.
fn.get_current_installed()
# =======================================================
# HeaderBar
# =======================================================
setup_headerbar(self, Gtk, settings)
# =======================================================
# App Notifications
# =======================================================
hbox0 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
self.notification_revealer = Gtk.Revealer()
self.notification_revealer.set_reveal_child(False)
self.notification_label = Gtk.Label()
pb_panel = GdkPixbuf.Pixbuf().new_from_file(base_dir + "/images/panel.png")
panel = Gtk.Image().new_from_pixbuf(pb_panel)
overlay_frame = Gtk.Overlay()
overlay_frame.add(panel)
overlay_frame.add_overlay(self.notification_label)
self.notification_revealer.add(overlay_frame)
hbox0.pack_start(self.notification_revealer, True, False, 0)
# ==========================================================
# CONTAINER
# ==========================================================
self.vbox_search = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
vbox1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
self.vbox_search.pack_start(hbox, True, True, 0)
self.add(self.vbox_search)
# ==========================================================
# PREP WORK
# ==========================================================
# This section sets up the tabs, and the array for dealing with the tab content
# ==========================================================
# GENERATE STACK
# ==========================================================
stack = Gtk.Stack()
# stack.set_transition_type(Gtk.StackTransitionType.SLIDE_UP_DOWN)
stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
stack.set_transition_duration(350)
vbox_stack = []
stack_item = 0
# Max Threads
"""
Fatal Python error: Segmentation fault
This error happens randomly, due to the for loop iteration on the cpu_count
old code: for x in range(cpu_count()):
"""
# spawn only 1 GUI_Worker threads, as any number greater causes a Segmentation fault
search_worker = GUI_Worker(self.queue)
search_worker.name = "thread_GUI_search_worker"
# Set the worker to be True to allow processing, and avoid Blocking
# search_worker.daemon = True
search_worker.start()
# This code section might look a little weird. It is because it was
# derived from another function before this version was required.
for category in search_results:
# NOTE: IF the yaml file name standard changes, be sure to update this, or weirdness will follow.
# subcategory = search_results[category][0].subcategory
vbox_stack.append(
Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
)
stack.add_titled(
vbox_stack[stack_item],
str("stack" + str(len(vbox_stack))),
category,
)
# subcategory_desc = search_results[category][0].subcategory_description
search_res_lst = search_results[category]
# Multithreading!
self.queue.put(
(
self,
Gtk,
vbox_stack[stack_item],
category,
search_res_lst,
)
)
stack_item += 1
# send a signal that no further items are to be put on the queue
self.queue.put(None)
# safety to ensure that we finish threading before we continue on.
self.queue.join()
fn.logger.debug("GUI Worker thread completed")
stack_switcher = Gtk.StackSidebar()
stack_switcher.set_name("sidebar")
stack_switcher.set_stack(stack)
# =====================================================
# LOGO
# =====================================================
ivbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
pixbuf = GdkPixbuf.Pixbuf().new_from_file_at_size(
os.path.join(base_dir, "images/blackbox.png"), 45, 45
)
image = Gtk.Image().new_from_pixbuf(pixbuf)
# remove the focus on startup from search entry
ivbox.set_property("can-focus", True)
Gtk.Window.grab_focus(ivbox)
# =====================================================
# RECACHE BUTTON
# =====================================================
btn_recache = Gtk.Button(label="Recache Applications")
btn_recache.connect("clicked", self.recache_clicked)
# btnReCache.set_property("has-tooltip", True)
# btnReCache.connect("query-tooltip", self.tooltip_callback,
# "Refresh the application cache")
# =====================================================
# REPOS
# =====================================================
# if not (
# fn.check_package_installed("arcolinux-keyring")
# or fn.check_package_installed("arcolinux-mirrorlist-git")
# ):
# self.btnRepos = Gtk.Button(label="Add ArcoLinux Repo")
# self.btnRepos._value = 1
# else:
# self.btnRepos = Gtk.Button(label="Remove ArcoLinux Repo")
# self.btnRepos._value = 2
#
# self.btnRepos.set_size_request(100, 30)
# self.btnRepos.connect("clicked", self.on_repos_clicked)
# =====================================================
# QUIT BUTTON
# =====================================================
btn_quit_app = Gtk.Button(label="Quit")
btn_quit_app.set_size_request(100, 30)
btn_quit_app.connect("clicked", self.on_close, "delete-event")
btn_context = btn_quit_app.get_style_context()
btn_context.add_class("destructive-action")
# =====================================================
# SEARCH BOX
# =====================================================
self.searchentry = Gtk.SearchEntry()
self.searchentry.set_text(search_term)
self.searchentry.connect("activate", self.on_search_activated)
self.searchentry.connect("icon-release", self.on_search_cleared)
iv_searchbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
# =====================================================
# PACKS
# =====================================================
# hbox1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=2)
# hbox2 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=2)
# hbox3 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=2)
# hbox3.pack_start(btnReCache, False, False, 0)
iv_searchbox.pack_start(self.searchentry, False, False, 0)
ivbox.pack_start(image, False, False, 0)
ivbox.pack_start(iv_searchbox, False, False, 0)
ivbox.pack_start(stack_switcher, True, True, 0)
ivbox.pack_start(btn_quit_app, False, False, 0)
vbox1.pack_start(hbox0, False, False, 0)
vbox1.pack_start(stack, True, True, 0)
hbox.pack_start(ivbox, False, True, 0)
hbox.pack_start(vbox1, True, True, 0)
stack.set_hhomogeneous(False)
stack.set_vhomogeneous(False)
self.show_all()
except Exception as err:
fn.logger.error("Exception in GUISearch(): %s" % err)
def setup_gui(self, Gtk, Gdk, GdkPixbuf, base_dir, os, Pango, settings): # noqa
try:
# reset back to main box
if self.search_activated:
# remove the search vbox
self.remove(self.vbox_search)
self.show_all()
# lets quickly create the latest installed list.
fn.get_current_installed()
# =======================================================
# HeaderBar
# =======================================================
setup_headerbar(self, Gtk, settings)
# =======================================================
# App Notifications
# =======================================================
hbox0 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
self.notification_revealer = Gtk.Revealer()
self.notification_revealer.set_reveal_child(False)
self.notification_label = Gtk.Label()
pb_panel = GdkPixbuf.Pixbuf().new_from_file(base_dir + "/images/panel.png")
panel = Gtk.Image().new_from_pixbuf(pb_panel)
overlay_frame = Gtk.Overlay()
overlay_frame.add(panel)
overlay_frame.add_overlay(self.notification_label)
self.notification_revealer.add(overlay_frame)
hbox0.pack_start(self.notification_revealer, True, False, 0)
# ==========================================================
# CONTAINER
# ==========================================================
self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
vbox1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
self.vbox.pack_start(hbox, True, True, 0)
self.add(self.vbox)
# ==========================================================
# PREP WORK
# ==========================================================
# This section sets up the tabs, and the array for dealing with the tab content
"""
yaml_files_unsorted = []
path = base_dir + "/yaml/"
for file in os.listdir(path):
if file.endswith(".yaml"):
yaml_files_unsorted.append(file)
else:
print(
"Unsupported configuration file type. Please contact Arcolinux Support."
)
# Need to sort the list (Or do we? I choose to)
yaml_files = sorted(yaml_files_unsorted)
"""
# Check github for updated files
# fn.check_github(yaml_files)
# ==========================================================
# GENERATE STACK
# ==========================================================
stack = Gtk.Stack()
# stack.set_transition_type(Gtk.StackTransitionType.SLIDE_UP_DOWN)
stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
stack.set_transition_duration(350)
vbox_stack = []
stack_item = 0
# Max Threads
"""
Fatal Python error: Segmentation fault
This error happens randomly, due to the for loop iteration on the cpu_count
old code: for x in range(cpu_count()):
"""
# spawn only 1 GUI_Worker threads, as any number greater causes a Segmentation fault
worker = GUI_Worker(self.queue)
worker.name = "thread_GUI_Worker"
# Set the worker to be True to allow processing, and avoid Blocking
# worker.daemon = True
worker.start()
for category in self.packages:
# NOTE: IF the yaml file name standard changes, be sure to update this, or weirdness will follow.
# this is the side stack listing all categories
vbox_stack.append(
Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
)
stack.add_titled(
vbox_stack[stack_item],
str("stack" + str(len(vbox_stack))),
category,
)
packages_lst = self.packages[category]
# Multithreading!
self.queue.put(
(
self,
Gtk,
vbox_stack[stack_item],
category,
packages_lst,
)
)
stack_item += 1
# send a signal that no further items are to be put on the queue
self.queue.put(None)
# safety to ensure that we finish threading before we continue on.
self.queue.join()
fn.logger.debug("GUI Worker thread completed")
stack_switcher = Gtk.StackSidebar()
stack_switcher.set_name("sidebar")
stack_switcher.set_stack(stack)
# =====================================================
# LOGO
# =====================================================
ivbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
pixbuf = GdkPixbuf.Pixbuf().new_from_file_at_size(
os.path.join(base_dir, "images/blackbox.png"), 45, 45
)
image = Gtk.Image().new_from_pixbuf(pixbuf)
# remove the focus on startup from search entry
ivbox.set_property("can-focus", True)
Gtk.Window.grab_focus(ivbox)
# =====================================================
# RECACHE BUTTON
# =====================================================
# btnReCache = Gtk.Button(label="Recache Applications")
# btnReCache.connect("clicked", self.recache_clicked)
# btnReCache.set_property("has-tooltip", True)
# btnReCache.connect("query-tooltip", self.tooltip_callback,
# "Refresh the application cache")
# =====================================================
# REPOS
# =====================================================
# =====================================================
# QUIT BUTTON
# =====================================================
btn_quit_app = Gtk.Button(label="Quit")
btn_quit_app.set_size_request(100, 30)
btn_quit_app.connect("clicked", self.on_close, "delete-event")
btn_context = btn_quit_app.get_style_context()
btn_context.add_class("destructive-action")
# =====================================================
# SEARCH BOX
# =====================================================
self.searchentry = Gtk.SearchEntry()
self.searchentry.set_placeholder_text("Search...")
self.searchentry.connect("activate", self.on_search_activated)
self.searchentry.connect("icon-release", self.on_search_cleared)
ivsearchbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
ivsearchbox.pack_start(self.searchentry, False, False, 0)
ivbox.pack_start(image, False, False, 0)
ivbox.pack_start(ivsearchbox, False, False, 0)
ivbox.pack_start(stack_switcher, True, True, 0)
ivbox.pack_start(btn_quit_app, False, False, 0)
vbox1.pack_start(hbox0, False, False, 0)
vbox1.pack_start(stack, True, True, 0)
hbox.pack_start(ivbox, False, True, 0)
hbox.pack_start(vbox1, True, True, 0)
stack.set_hhomogeneous(False)
stack.set_vhomogeneous(False)
if self.search_activated:
self.show_all()
except Exception as e:
fn.logger.error("Exception in GUI(): %s" % e)
# setup headerbar including popover settings
def setup_headerbar(self, Gtk, settings):
try:
header_bar_title = "BlackBox"
headerbar = Gtk.HeaderBar()
headerbar.set_title(header_bar_title)
headerbar.set_show_close_button(True)
self.set_titlebar(headerbar)
toolbutton = Gtk.ToolButton()
# icon-name open-menu-symbolic / open-menu-symbolic.symbolic
toolbutton.set_icon_name("open-menu-symbolic")
toolbutton.connect("clicked", self.on_settings_clicked)
headerbar.pack_end(toolbutton)
self.popover = Gtk.Popover()
self.popover.set_relative_to(toolbutton)
vbox = Gtk.Box(spacing=0, orientation=Gtk.Orientation.VERTICAL)
vbox.set_border_width(15)
# switches
# switch to display package versions
self.switch_package_version = Gtk.Switch()
if settings != None:
if settings["Display Package Versions"]:
self.display_versions = settings["Display Package Versions"]
if self.display_versions == True:
self.switch_package_version.set_active(True)
else:
self.switch_package_version.set_active(False)
self.switch_package_version.connect("notify::active", self.version_toggle)
# switch to import snigdhaos keyring
self.switch_snigdhaos_keyring = Gtk.Switch()
if (
fn.check_package_installed("snigdhaos-keyring") is False
or fn.verify_snigdhaos_pacman_conf() is False
):
self.switch_snigdhaos_keyring.set_state(False)
else:
self.switch_snigdhaos_keyring.set_state(True)
self.switch_snigdhaos_keyring.connect("state-set", self.snigdhaos_keyring_toggle)
# switch to import snigdhaos mirrorlist
self.switch_snigdhaos_mirrorlist = Gtk.Switch()
if (
fn.check_package_installed("snigdhaos-mirrorlist") is False
or fn.verify_snigdhaos_pacman_conf() is False
):
self.switch_snigdhaos_mirrorlist.set_state(False)
else:
self.switch_snigdhaos_mirrorlist.set_state(True)
self.switch_snigdhaos_mirrorlist.connect("state-set", self.snigdhaos_mirrorlist_toggle)
# switch to display package progress window
self.switch_package_progress = Gtk.Switch()
if settings != None:
if settings["Display Package Progress"]:
self.display_package_progress = settings["Display Package Progress"]
if self.display_package_progress == True:
self.switch_package_progress.set_active(True)
else:
self.switch_package_progress.set_active(False)
self.switch_package_progress.connect(
"notify::active", self.package_progress_toggle
)
# modalbuttons
# button to open the pacman log monitoring dialog
self.modelbtn_pacmanlog = Gtk.ModelButton()
self.modelbtn_pacmanlog.connect("clicked", self.on_pacman_log_clicked)
self.modelbtn_pacmanlog.set_name("modelbtn_popover")
self.modelbtn_pacmanlog.props.centered = False
self.modelbtn_pacmanlog.props.text = "Open Pacman Log File"
# button to display installed packages window
modelbtn_packages_export = Gtk.ModelButton()
modelbtn_packages_export.connect("clicked", self.on_packages_export_clicked)
modelbtn_packages_export.set_name("modelbtn_popover")
modelbtn_packages_export.props.centered = False
modelbtn_packages_export.props.text = "Show Installed Packages"
# button to display import packages window
modelbtn_packages_import = Gtk.ModelButton()
modelbtn_packages_import.connect("clicked", self.on_packages_import_clicked)
modelbtn_packages_import.set_name("modelbtn_popover")
modelbtn_packages_import.props.centered = False
modelbtn_packages_import.props.text = "Import Packages"
# button to show about dialog
modelbtn_about_app = Gtk.ModelButton()
modelbtn_about_app.connect("clicked", self.on_about_app_clicked)
modelbtn_about_app.set_name("modelbtn_popover")
modelbtn_about_app.props.centered = False
modelbtn_about_app.props.text = "About BlackBox"
# button to show iso package lists window
modelbtn_iso_packages_list = Gtk.ModelButton()
modelbtn_iso_packages_list.connect(
"clicked", self.on_arcolinux_iso_packages_clicked
)
modelbtn_iso_packages_list.set_name("modelbtn_popover")
modelbtn_iso_packages_list.props.centered = False
modelbtn_iso_packages_list.props.text = "Explore ArcoLinux ISO Packages"
# button to show package search window
modelbtn_package_search = Gtk.ModelButton()
modelbtn_package_search.connect("clicked", self.on_package_search_clicked)
modelbtn_package_search.set_name("modelbtn_popover")
modelbtn_package_search.props.centered = False
modelbtn_package_search.props.text = "Open Package Search"
# grid for the switch options
grid_switches = Gtk.Grid()
grid_switches.set_row_homogeneous(True)
lbl_package_version = Gtk.Label(xalign=0)
lbl_package_version.set_text("Display Package Versions")
lbl_package_version_padding = Gtk.Label(xalign=0)
lbl_package_version_padding.set_text(" ")
lbl_package_progress = Gtk.Label(xalign=0)
lbl_package_progress.set_text("Display Package Progress")
lbl_package_progress_padding = Gtk.Label(xalign=0)
lbl_package_progress_padding.set_text(" ")
lbl_arco_keyring = Gtk.Label(xalign=0)
lbl_arco_keyring.set_text("Import ArcoLinux Keyring")
lbl_arco_keyring_padding = Gtk.Label(xalign=0)
lbl_arco_keyring_padding.set_text(" ")
lbl_arco_mirrorlist = Gtk.Label(xalign=0)
lbl_arco_mirrorlist.set_text("Import ArcoLinux Mirrorlist")
lbl_arco_mirrorlist_padding = Gtk.Label(xalign=0)
lbl_arco_mirrorlist_padding.set_text(" ")
grid_switches.attach(lbl_package_version, 0, 1, 1, 1)
grid_switches.attach_next_to(
lbl_package_version_padding,
lbl_package_version,
Gtk.PositionType.RIGHT,
1,
1,
)
grid_switches.attach_next_to(
self.switch_package_version,
lbl_package_version_padding,
Gtk.PositionType.RIGHT,
1,
1,
)
grid_switches.attach(lbl_package_progress, 0, 2, 1, 1)
grid_switches.attach_next_to(
lbl_package_progress_padding,
lbl_package_progress,
Gtk.PositionType.RIGHT,
1,
1,
)
grid_switches.attach_next_to(
self.switch_package_progress,
lbl_package_progress_padding,
Gtk.PositionType.RIGHT,
1,
1,
)
grid_switches.attach(lbl_arco_keyring, 0, 3, 1, 1)
grid_switches.attach_next_to(
lbl_arco_keyring_padding,
lbl_arco_keyring,
Gtk.PositionType.RIGHT,
1,
1,
)
grid_switches.attach_next_to(
self.switch_arco_keyring,
lbl_arco_keyring_padding,
Gtk.PositionType.RIGHT,
1,
1,
)
grid_switches.attach(lbl_arco_mirrorlist, 0, 4, 1, 1)
grid_switches.attach_next_to(
lbl_arco_mirrorlist_padding,
lbl_arco_mirrorlist,
Gtk.PositionType.RIGHT,
1,
1,
)
grid_switches.attach_next_to(
self.switch_arco_mirrorlist,
lbl_arco_mirrorlist_padding,
Gtk.PositionType.RIGHT,
1,
1,
)
vbox_buttons = Gtk.Box(spacing=1, orientation=Gtk.Orientation.VERTICAL)
vbox_buttons.pack_start(self.modelbtn_pacmanlog, False, True, 0)
vbox_buttons.pack_start(modelbtn_packages_export, False, True, 0)
vbox_buttons.pack_start(modelbtn_packages_import, False, True, 0)
vbox_buttons.pack_start(modelbtn_iso_packages_list, False, True, 0)
vbox_buttons.pack_start(modelbtn_package_search, False, True, 0)
vbox_buttons.pack_start(modelbtn_about_app, False, True, 0)
vbox.pack_start(grid_switches, False, False, 0)
vbox.pack_start(vbox_buttons, False, False, 0)
self.popover.add(vbox)
self.popover.set_position(Gtk.PositionType.BOTTOM)
except Exception as e:
fn.logger.error("Exception in setup_headerbar(): %s" % e)

View File

@@ -1,429 +0,0 @@
# This class is used to create a window showing a list of packages available for a given ArcoLinux ISO
import os
import gi
import requests
import Functions as fn
from ui.MessageDialog import MessageDialog
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
arcolinux_isos = [
"arcolinuxs-xanmod-iso",
"arcolinuxs-zen-iso",
"arcolinuxs-lts-iso",
"arcolinuxs-iso",
"arcolinuxl-iso",
"arcolinuxd-iso",
]
arcolinuxb_isos = [
"arco-sway",
"arco-plasma",
"arco-hyprland",
"arco-chadwm",
"arco-dusk",
"arco-dwm",
"arco-berry",
"arco-hypr",
"arco-enlightenment",
"arco-xtended",
"arco-pantheon",
"arco-awesome",
"arco-bspwm",
"arco-cinnamon",
"arco-budgie",
"arco-cutefish",
"arco-cwm",
"arco-deepin",
"arco-gnome",
"arco-fvwm3",
"arco-herbstluftwm",
"arco-i3",
"arco-icewm",
"arco-jwm",
"arco-leftwm",
"arco-lxqt",
"arco-mate",
"arco-openbox",
"arco-qtile",
"arco-spectrwm",
"arco-ukui",
"arco-wmderland",
"arco-xfce",
"arco-xmonad",
]
github_arcolinux_packagelist = "https://raw.githubusercontent.com/${ARCOLINUX}/${ISO}/master/archiso/packages.x86_64"
headers = {"Content-Type": "text/plain;charset=UTF-8"}
class ISOPackagesWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
headerbar = Gtk.HeaderBar()
headerbar.set_title("ArcoLinux ISO Package Explorer")
headerbar.set_show_close_button(True)
# remove the focus on startup from search entry
headerbar.set_property("can-focus", True)
Gtk.Window.grab_focus(headerbar)
self.set_resizable(True)
self.set_size_request(500, 600)
self.set_border_width(10)
self.set_titlebar(headerbar)
self.set_icon_from_file(os.path.join(base_dir, "images/blackbox.png"))
self.treeview_loaded = False
self.build_gui()
def get_packagelist(self):
try:
# make request to get the package list from github
url = None
self.package_list = []
if "-iso" in self.selected_iso:
url = github_arcolinux_packagelist.replace(
"${ARCOLINUX}", "arcolinux"
).replace("${ISO}", self.selected_iso)
github_arcolinux = [
"https://github.com/arcolinux/",
self.selected_iso,
"/blob/master/archiso/packages.x86_64",
]
self.github_source = "".join(github_arcolinux)
else:
url = github_arcolinux_packagelist.replace(
"${ARCOLINUX}", "arcolinuxb"
).replace("${ISO}", self.selected_iso)
github_arcolinuxb = [
"https://github.com/arcolinuxb/",
self.selected_iso,
"/blob/master/archiso/packages.x86_64",
]
self.github_source = "".join(github_arcolinuxb)
r = requests.get(url, headers=headers, allow_redirects=True)
# read the package list ignore any commented lines
if r.status_code == 200:
if len(r.text) > 0:
for line in r.text.splitlines():
if "#" not in line.strip() and len(line.strip()) > 0:
self.package_list.append((line.strip(), None))
else:
fn.logger.error("Request for %s returned %s" % (url, r.status_code))
message_dialog = MessageDialog(
"Error",
"Request failed",
"Failed to request package list",
"Request for %s returned status code = %s" % (url, r.status_code),
"error",
True,
)
message_dialog.show_all()
message_dialog.run()
message_dialog.hide()
message_dialog.destroy()
except Exception as e:
message_dialog = MessageDialog(
"Error",
"Request failed",
"Failed to request package list",
e,
"error",
True,
)
message_dialog.show_all()
message_dialog.run()
message_dialog.hide()
message_dialog.destroy()
def on_combo_iso_changed(self, combo):
try:
iso = combo.get_active_text()
if iso is not None:
self.selected_iso = iso
self.get_packagelist()
if len(self.package_list) > 0:
lbl_github_source_title = Gtk.Label(xalign=0, yalign=0)
lbl_github_source_title.set_markup("<b>Package list source</b>")
lbl_github_source_value = Gtk.Label(xalign=0, yalign=0)
lbl_github_source_value.set_markup(
"<a href='%s'>%s</a>" % (self.github_source, self.github_source)
)
lbl_package_count_title = Gtk.Label(xalign=0, yalign=0)
lbl_package_count_title.set_markup("<b>Activated packages</b>")
lbl_package_count_value = Gtk.Label(xalign=0, yalign=0)
lbl_package_count_value.set_text(str(len(self.package_list)))
self.filename = "%s/blackbox-exports/%s-%s-packages.x86_64.txt" % (
fn.home,
self.selected_iso,
fn.datetime.now().strftime("%Y-%m-%d"),
)
lbl_export_desc_title = Gtk.Label(xalign=0, yalign=0)
lbl_export_desc_title.set_markup("<b>Export destination</b>")
lbl_export_desc_value = Gtk.Label(xalign=0, yalign=0)
lbl_export_desc_value.set_text(self.filename)
if self.treeview_loaded is True:
self.vbox_package_data.destroy()
search_entry = Gtk.SearchEntry()
search_entry.set_placeholder_text("Search...")
search_entry.set_size_request(450, 0)
grid_package_data = Gtk.Grid()
treestore_packages_explorer = Gtk.TreeStore(str, str)
for item in sorted(self.package_list):
treestore_packages_explorer.append(None, list(item))
treeview_packages_explorer = Gtk.TreeView()
treeview_packages_explorer.set_search_entry(search_entry)
treeview_packages_explorer.set_model(treestore_packages_explorer)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Packages", renderer, text=0)
treeview_packages_explorer.append_column(column)
path = Gtk.TreePath.new_from_indices([0])
selection = treeview_packages_explorer.get_selection()
selection.select_path(path)
treeview_packages_explorer.expand_all()
treeview_packages_explorer.columns_autosize()
scrolled_window = Gtk.ScrolledWindow()
scrolled_window.set_vexpand(True)
scrolled_window.set_hexpand(True)
scrolled_window.add(treeview_packages_explorer)
grid_treeview = Gtk.Grid()
grid_treeview.set_column_homogeneous(True)
self.vbox_package_data = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
self.vbox_package_data.pack_start(
lbl_github_source_title, False, True, 1
)
self.vbox_package_data.pack_start(
lbl_github_source_value, False, True, 1
)
self.vbox_package_data.pack_start(
lbl_package_count_title, False, True, 1
)
self.vbox_package_data.pack_start(
lbl_package_count_value, False, True, 1
)
self.vbox_package_data.pack_start(
lbl_export_desc_title, False, True, 1
)
self.vbox_package_data.pack_start(
lbl_export_desc_value, False, True, 1
)
lbl_padding_search_entry1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding_search_entry1.set_text("")
lbl_padding_search_entry2 = Gtk.Label(xalign=0, yalign=0)
lbl_padding_search_entry2.set_text("")
grid_search_entry = Gtk.Grid()
grid_search_entry.attach(lbl_padding_search_entry1, 0, 1, 1, 1)
grid_search_entry.attach(search_entry, 0, 2, 1, 1)
grid_search_entry.attach(lbl_padding_search_entry2, 0, 3, 1, 1)
self.vbox_package_data.pack_start(
grid_search_entry, False, False, 1
)
self.vbox_package_data.pack_start(scrolled_window, False, True, 1)
self.vbox_combo.pack_start(self.vbox_package_data, False, True, 1)
self.show_all()
self.treeview_loaded = True
except Exception as e:
fn.logger.error("Exception in on_combo_iso_changed(): %s" % e)
def on_iso_package_list_export(self, widget):
# export the package list to a file inside $HOME/blackbox-exports
fn.logger.debug("Exporting ArcoLinux ISO package list")
try:
if self.filename is not None:
with open(self.filename, "w", encoding="utf-8") as f:
f.write(
"# Created by BlackBox on %s\n"
% fn.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
f.write("# %s\n" % self.github_source)
for line in sorted(self.package_list):
f.write("%s\n" % line[0])
if os.path.exists(self.filename):
message_dialog = MessageDialog(
"Info",
"Package export complete",
"Package list exported to %s" % self.filename,
"",
"info",
False,
)
message_dialog.show_all()
message_dialog.run()
message_dialog.hide()
else:
message_dialog = MessageDialog(
"Error",
"Package export failed",
"Package list export failed",
"",
"error",
False,
)
message_dialog.show_all()
message_dialog.run()
message_dialog.hide()
# file is created by root, update the permissions to the sudo username
fn.permissions(self.filename)
else:
message_dialog = MessageDialog(
"Warning",
"Select an ISO",
"An ArcoLinux ISO needs to be selected before exporting",
"",
"warning",
False,
)
message_dialog.show_all()
message_dialog.run()
message_dialog.hide()
except Exception as e:
fn.logger.error("Exception in on_iso_package_list_export(): %s" % e)
def on_close(self, widget):
self.hide()
self.destroy()
def populate_combo_iso(self):
for arco_iso in arcolinux_isos:
self.combo_iso.append_text(arco_iso)
for arco_isob in sorted(arcolinuxb_isos):
self.combo_iso.append_text(arco_isob)
def build_gui(self):
try:
lbl_select_iso = Gtk.Label(xalign=0, yalign=0)
lbl_select_iso.set_markup("<b>Select ArcoLinux ISO</b>")
lbl_padding1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding1.set_text("")
lbl_padding2 = Gtk.Label(xalign=0, yalign=0)
lbl_padding2.set_text("")
self.combo_iso = Gtk.ComboBoxText()
self.combo_iso.set_wrap_width(3)
self.combo_iso.set_entry_text_column(0)
self.combo_iso.connect("changed", self.on_combo_iso_changed)
self.populate_combo_iso()
self.filename = None
grid_top = Gtk.Grid()
grid_top.attach(lbl_select_iso, 0, 1, 1, 1)
grid_top.attach_next_to(
lbl_padding1, lbl_select_iso, Gtk.PositionType.BOTTOM, 1, 1
)
grid_top.attach(self.combo_iso, 0, 2, 1, 1)
grid_top.attach(lbl_padding2, 0, 3, 1, 1)
btn_ok = Gtk.Button(label="OK")
btn_ok.set_size_request(100, 30)
btn_ok.connect("clicked", self.on_close)
btn_ok.set_halign(Gtk.Align.END)
btn_export = Gtk.Button(label="Export")
btn_export.set_size_request(100, 30)
btn_export.connect("clicked", self.on_iso_package_list_export)
btn_export.set_halign(Gtk.Align.END)
grid_bottom = Gtk.Grid()
grid_bottom.attach(btn_ok, 0, 1, 1, 1)
lbl_padding3 = Gtk.Label(xalign=0, yalign=0)
lbl_padding3.set_text(" ")
grid_bottom.attach_next_to(
lbl_padding3, btn_ok, Gtk.PositionType.RIGHT, 1, 1
)
grid_bottom.attach_next_to(
btn_export, lbl_padding3, Gtk.PositionType.RIGHT, 1, 1
)
grid_bottom.set_halign(Gtk.Align.END)
vbox_bottom = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
lbl_padding_bottom = Gtk.Label(xalign=0, yalign=0)
lbl_padding_bottom.set_text("")
vbox_bottom.pack_start(lbl_padding_bottom, False, True, 0)
vbox_bottom.pack_start(grid_bottom, False, True, 0)
self.vbox_combo = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
self.vbox_combo.pack_start(grid_top, False, True, 0)
self.vbox_combo.pack_end(vbox_bottom, False, True, 0)
self.add(self.vbox_combo)
self.show_all()
except Exception as e:
fn.logger.error("Exception in build_gui(): %s" % e)

View File

@@ -1,118 +0,0 @@
# This class is used to create a modal dialog window showing detailed information about an event
import os
import gi
import Functions as fn
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
# base_dir = os.path.dirname(os.path.realpath(__file__))
class MessageDialog(Gtk.Dialog):
# message_type is a string, either one of "info", "warning", "error" to show which infobar to display
# extended argument when set to true shows a textview inside the dialog
# extended argument when set to false only shows a standard dialog
def __init__(
self, title, subtitle, first_msg, secondary_msg, message_type, extended
):
Gtk.Dialog.__init__(self)
headerbar = Gtk.HeaderBar()
headerbar.set_title(title)
headerbar.set_show_close_button(True)
self.set_resizable(True)
self.set_border_width(10)
self.set_titlebar(headerbar)
btn_ok = Gtk.Button(label="OK")
btn_ok.set_size_request(100, 30)
btn_ok.connect("clicked", on_message_dialog_ok_response, self)
btn_ok.set_halign(Gtk.Align.END)
self.set_icon_from_file(os.path.join(base_dir, "images/blackbox.png"))
infobar = Gtk.InfoBar()
if message_type == "info":
infobar.set_name("infobar_info")
if message_type == "error":
infobar.set_name("infobar_error")
if message_type == "warning":
infobar.set_name("infobar_warning")
lbl_title_message = Gtk.Label(xalign=0, yalign=0)
lbl_title_message.set_markup("<b>%s</b>" % subtitle)
content = infobar.get_content_area()
content.add(lbl_title_message)
infobar.set_revealed(True)
lbl_padding1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding1.set_text("")
lbl_padding2 = Gtk.Label(xalign=0, yalign=0)
lbl_padding2.set_text("")
grid_message = Gtk.Grid()
grid_message.attach(infobar, 0, 0, 1, 1)
grid_message.attach(lbl_padding1, 0, 1, 1, 1)
if extended is True:
scrolled_window = Gtk.ScrolledWindow()
textview = Gtk.TextView()
textview.set_property("editable", False)
textview.set_property("monospace", True)
textview.set_border_width(10)
textview.set_vexpand(True)
textview.set_hexpand(True)
msg_buffer = textview.get_buffer()
msg_buffer.insert(
msg_buffer.get_end_iter(),
"Event timestamp = %s\n"
% fn.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
)
msg_buffer.insert(msg_buffer.get_end_iter(), "%s\n" % first_msg)
msg_buffer.insert(msg_buffer.get_end_iter(), "%s\n" % secondary_msg)
# move focus away from the textview, to hide the cursor at load
headerbar.set_property("can-focus", True)
Gtk.Window.grab_focus(headerbar)
scrolled_window.add(textview)
grid_message.attach(scrolled_window, 0, 2, 1, 1)
grid_message.attach(lbl_padding2, 0, 3, 1, 1)
self.set_default_size(800, 600)
else:
# do not display textview
lbl_first_message = Gtk.Label(xalign=0, yalign=0)
lbl_first_message.set_text(first_msg)
lbl_second_message = Gtk.Label(xalign=0, yalign=0)
lbl_second_message.set_markup("<b>%s</b>" % secondary_msg)
grid_message.attach(lbl_first_message, 0, 2, 1, 1)
grid_message.attach(lbl_second_message, 0, 3, 1, 1)
self.set_default_size(600, 100)
self.set_resizable(False)
vbox_close = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
vbox_close.pack_start(btn_ok, True, True, 1)
self.vbox.add(grid_message)
self.vbox.add(vbox_close)
def on_message_dialog_ok_response(self, widget):
# widget.hide()
widget.destroy()

View File

@@ -1,283 +0,0 @@
# This class is used to create a modal dialog window to display currently installed packages
import os
import gi
import Functions as fn
from ui.MessageDialog import MessageDialog
from queue import Queue
from gi.repository import Gtk, Gdk, GdkPixbuf, Pango, GLib
gi.require_version("Gtk", "3.0")
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
# base_dir = os.path.dirname(os.path.realpath(__file__))
class PackageListDialog(Gtk.Dialog):
def __init__(self):
Gtk.Dialog.__init__(self)
# Create a queue for storing package list exports to display inside PackageListDialog
self.pkg_export_queue = Queue()
self.filename = "%s/packages-x86_64.txt" % (fn.export_dir,)
self.set_resizable(True)
self.set_size_request(1050, 700)
self.set_modal(True)
self.set_border_width(10)
self.set_icon_from_file(os.path.join(base_dir, "images/blackbox.png"))
self.connect("delete-event", self.on_close)
self.installed_packages_list = None
self.headerbar = Gtk.HeaderBar()
self.headerbar.set_title("Loading please wait ..")
self.headerbar.set_show_close_button(True)
self.set_titlebar(self.headerbar)
self.grid_packageslst = Gtk.Grid()
self.grid_packageslst.set_column_homogeneous(True)
self.lbl_info = Gtk.Label(xalign=0, yalign=0)
self.lbl_info.set_text("Export destination %s" % self.filename)
# get a list of installed packages on the system
self.pacman_export_cmd = ["pacman", "-Qien"]
fn.Thread(
target=fn.get_installed_package_data,
args=(self,),
daemon=True,
).start()
fn.Thread(target=self.check_queue, daemon=True).start()
def setup_gui(self):
if len(self.installed_packages_list) > 0:
self.set_title(
"Showing %s installed packages" % len(self.installed_packages_list)
)
search_entry = Gtk.SearchEntry()
search_entry.set_placeholder_text("Search...")
# remove the focus on startup from search entry
self.headerbar.set_property("can-focus", True)
Gtk.Window.grab_focus(self.headerbar)
treestore_packages = Gtk.TreeStore(str, str, str, str, str)
for item in sorted(self.installed_packages_list):
treestore_packages.append(None, list(item))
treeview_packages = Gtk.TreeView()
treeview_packages.set_search_entry(search_entry)
treeview_packages.set_model(treestore_packages)
for i, col_title in enumerate(
[
"Name",
"Installed Version",
"Latest Version",
"Installed Size",
"Installed Date",
]
):
renderer = Gtk.CellRendererText()
col = Gtk.TreeViewColumn(col_title, renderer, text=i)
treeview_packages.append_column(col)
# allow sorting by installed date
col_installed_date = treeview_packages.get_column(4)
col_installed_date.set_sort_column_id(4)
treestore_packages.set_sort_func(4, self.compare_install_date, None)
path = Gtk.TreePath.new_from_indices([0])
selection = treeview_packages.get_selection()
selection.select_path(path)
treeview_packages.expand_all()
treeview_packages.columns_autosize()
scrolled_window = Gtk.ScrolledWindow()
scrolled_window.set_vexpand(True)
scrolled_window.set_hexpand(True)
self.grid_packageslst.attach(scrolled_window, 0, 0, 8, 10)
lbl_padding1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding1.set_text("")
self.grid_packageslst.attach_next_to(
lbl_padding1, scrolled_window, Gtk.PositionType.BOTTOM, 1, 1
)
btn_dialog_export = Gtk.Button(label="Export")
btn_dialog_export.connect("clicked", self.on_dialog_export_clicked)
btn_dialog_export.set_size_request(100, 30)
btn_dialog_export.set_halign(Gtk.Align.END)
btn_dialog_export_close = Gtk.Button(label="Close")
btn_dialog_export_close.connect("clicked", self.on_close, "delete-event")
btn_dialog_export_close.set_size_request(100, 30)
btn_dialog_export_close.set_halign(Gtk.Align.END)
scrolled_window.add(treeview_packages)
grid_btn = Gtk.Grid()
grid_btn.attach(btn_dialog_export, 0, 1, 1, 1)
lbl_padding2 = Gtk.Label(xalign=0, yalign=0)
lbl_padding2.set_text(" ")
grid_btn.attach_next_to(
lbl_padding2, btn_dialog_export, Gtk.PositionType.RIGHT, 1, 1
)
grid_btn.attach_next_to(
btn_dialog_export_close, lbl_padding2, Gtk.PositionType.RIGHT, 1, 1
)
grid_btn.set_halign(Gtk.Align.END)
vbox_btn = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
vbox_btn.pack_start(grid_btn, True, True, 1)
lbl_padding3 = Gtk.Label(xalign=0, yalign=0)
lbl_padding3.set_text("")
self.vbox.add(search_entry)
self.vbox.add(lbl_padding3)
self.vbox.add(self.grid_packageslst)
self.vbox.add(self.lbl_info)
self.vbox.add(vbox_btn)
self.show_all()
def check_queue(self):
while True:
self.installed_packages_list = self.pkg_export_queue.get()
if self.installed_packages_list is not None:
break
self.pkg_export_queue.task_done()
GLib.idle_add(self.setup_gui, priority=GLib.PRIORITY_DEFAULT)
def on_close(self, dialog, event):
self.hide()
self.destroy()
def on_dialog_export_clicked(self, dialog):
try:
if not os.path.exists(fn.export_dir):
fn.makedirs(fn.export_dir)
fn.permissions(fn.export_dir)
with open(self.filename, "w", encoding="utf-8") as f:
f.write(
"# This file was auto-generated by BlackBox on %s at %s\n"
% (
fn.datetime.today().date(),
fn.datetime.now().strftime("%H:%M:%S"),
)
)
f.write(
"# Exported explicitly installed packages using %s\n"
% " ".join(self.pacman_export_cmd)
)
for package in sorted(self.installed_packages_list):
f.write("%s\n" % (package[0]))
if os.path.exists(self.filename):
fn.logger.info("Export completed")
# fix permissions, file is owned by root
fn.permissions(self.filename)
message_dialog = MessageDialog(
"Info",
"Package export complete",
"Package list exported to %s" % self.filename,
"",
"info",
False,
)
message_dialog.show_all()
message_dialog.run()
message_dialog.hide()
message_dialog.destroy()
else:
fn.logger.error("Export failed")
message_dialog = MessageDialog(
"Error",
"Package export failed",
"Failed to export package list to %s." % self.filename,
"",
"error",
False,
)
message_dialog.show_all()
message_dialog.run()
message_dialog.hide()
message_dialog.destroy()
except Exception as e:
fn.logger.error("Exception in on_dialog_export_clicked(): %s" % e)
# noqa: any locales other than en_GB.UTF-8 / en_US.UTF-8 are untested
def compare_install_date(self, model, row1, row2, user_data):
try:
sort_column, _ = model.get_sort_column_id()
str_value1 = model.get_value(row1, sort_column)
str_value2 = model.get_value(row2, sort_column)
datetime_value1 = None
datetime_value2 = None
# convert string into datetime object, check if time format is 12H format with AM/PM
if str_value1.lower().find("am") > 0 or str_value1.lower().find("pm") > 0:
# 12H format
datetime_value1 = fn.datetime.strptime(
str_value1, "%a %d %b %Y %I:%M:%S %p %Z"
).replace(tzinfo=None)
datetime_value2 = fn.datetime.strptime(
str_value2, "%a %d %b %Y %I:%M:%S %p %Z"
).replace(tzinfo=None)
else:
# 24H format
datetime_value1 = fn.datetime.strptime(
str_value1, "%a %d %b %Y %H:%M:%S %Z"
).replace(tzinfo=None)
datetime_value2 = fn.datetime.strptime(
str_value2, "%a %d %b %Y %H:%M:%S %Z"
).replace(tzinfo=None)
if datetime_value1 is not None and datetime_value2 is not None:
if datetime_value1 < datetime_value2:
return -1
elif datetime_value1 == datetime_value2:
return 0
else:
return 1
except ValueError as ve:
# fn.logger.error("ValueError in compare_install_date: %s" % ve)
# compare fails due to the format of the datetime string, which hasn't been tested
pass
except Exception as e:
fn.logger.error("Exception in compare_install_date: %s" % e)

View File

@@ -1,543 +0,0 @@
# This class is used to create a window for package name searches and to display package information
import os
import gi
import Functions as fn
from ui.MessageDialog import MessageDialog
from gi.repository import Gtk, Gdk, GdkPixbuf, Pango, GLib
gi.require_version("Gtk", "3.0")
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
class PackageSearchWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.headerbar = Gtk.HeaderBar()
self.headerbar.set_title("Package Search")
self.headerbar.set_show_close_button(True)
# remove the focus on startup from search entry
self.headerbar.set_property("can-focus", True)
Gtk.Window.grab_focus(self.headerbar)
self.set_resizable(True)
self.set_size_request(700, 500)
self.set_border_width(10)
self.set_titlebar(self.headerbar)
self.set_icon_from_file(os.path.join(base_dir, "images/blackbox.png"))
self.search_package_activated = False
self.build_gui()
def build_gui(self):
self.stack = Gtk.Stack()
self.stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
self.stack.set_transition_duration(350)
self.stack.set_hhomogeneous(False)
self.stack.set_vhomogeneous(False)
stack_switcher = Gtk.StackSwitcher()
stack_switcher.set_orientation(Gtk.Orientation.HORIZONTAL)
stack_switcher.set_stack(self.stack)
stack_switcher.set_homogeneous(True)
searchentry = Gtk.SearchEntry()
searchentry.set_placeholder_text("Search using package name...")
searchentry.set_size_request(400, 0)
searchentry.connect("activate", self.on_search_package_activated)
searchentry.connect("icon-release", self.on_search_package_cleared)
btn_ok = Gtk.Button(label="OK")
btn_ok.set_size_request(100, 30)
btn_ok.connect("clicked", self.on_close)
btn_ok.set_halign(Gtk.Align.END)
grid_bottom = Gtk.Grid()
grid_bottom.attach(btn_ok, 0, 1, 1, 1)
grid_bottom.set_halign(Gtk.Align.END)
vbox_bottom = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
lbl_padding_bottom = Gtk.Label(xalign=0, yalign=0)
lbl_padding_bottom.set_text("")
vbox_bottom.pack_start(lbl_padding_bottom, False, True, 0)
vbox_bottom.pack_start(grid_bottom, False, True, 0)
self.stack.add_titled(searchentry, "Package Search", "Package Search")
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
vbox.set_border_width(10)
vbox.pack_start(stack_switcher, False, False, 0)
vbox.pack_start(self.stack, False, False, 0)
vbox.pack_end(vbox_bottom, False, True, 0)
self.add(vbox)
self.show_all()
thread_pacman_sync_file_db = fn.threading.Thread(
name="thread_pacman_sync_file_db",
target=fn.sync_file_db,
daemon=True,
)
thread_pacman_sync_file_db.start()
def on_close(self, widget):
self.hide()
self.destroy()
def on_search_package_activated(self, searchentry):
if searchentry.get_text_length() == 0 and self.search_package_activated:
self.search_package_activated = False
self.stack.get_child_by_name("Package Information").destroy()
self.stack.get_child_by_name("Package Files").destroy()
Gtk.Window.grab_focus(self.headerbar)
else:
self.perform_search(searchentry)
def on_search_package_cleared(self, searchentry, icon_pos, event):
searchentry.set_placeholder_text("Search using package name...")
if self.search_package_activated is True:
self.search_package_activated = False
self.stack.get_child_by_name("Package Information").destroy()
self.stack.get_child_by_name("Package Files").destroy()
Gtk.Window.grab_focus(self.headerbar)
def perform_search(self, searchentry):
try:
if (
len(searchentry.get_text().rstrip().lstrip()) > 0
and not searchentry.get_text().isspace()
):
term = searchentry.get_text().rstrip().lstrip()
if len(term) > 0:
fn.logger.info("Searching pacman file database")
package_metadata = fn.get_package_information(term)
if package_metadata is not None:
# package information
if self.search_package_activated is True:
self.stack.get_child_by_name(
"Package Information"
).destroy()
self.stack.get_child_by_name("Package Files").destroy()
box_outer = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=5
)
listbox = Gtk.ListBox()
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
box_outer.pack_start(listbox, True, True, 0)
# package name
row_package_title = Gtk.ListBoxRow()
vbox_package_title = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_title.add(vbox_package_title)
lbl_package_name_title = Gtk.Label(xalign=0)
lbl_package_name_title.set_markup("<b>Package Name</b>")
lbl_package_name_value = Gtk.Label(xalign=0)
lbl_package_name_value.set_text(package_metadata["name"])
vbox_package_title.pack_start(
lbl_package_name_title, True, True, 0
)
vbox_package_title.pack_start(
lbl_package_name_value, True, True, 0
)
listbox.add(row_package_title)
# repository
row_package_repo = Gtk.ListBoxRow()
vbox_package_repo = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_repo.add(vbox_package_repo)
lbl_package_repo_title = Gtk.Label(xalign=0)
lbl_package_repo_title.set_markup("<b>Repository</b>")
lbl_package_repo_value = Gtk.Label(xalign=0)
lbl_package_repo_value.set_text(package_metadata["repository"])
vbox_package_repo.pack_start(
lbl_package_repo_title, True, True, 0
)
vbox_package_repo.pack_start(
lbl_package_repo_value, True, True, 0
)
listbox.add(row_package_repo)
# description
row_package_description = Gtk.ListBoxRow()
vbox_package_description = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_description.add(vbox_package_description)
lbl_package_description_title = Gtk.Label(xalign=0)
lbl_package_description_title.set_markup("<b>Description</b>")
lbl_package_description_value = Gtk.Label(xalign=0)
lbl_package_description_value.set_text(
package_metadata["description"]
)
vbox_package_description.pack_start(
lbl_package_description_title, True, True, 0
)
vbox_package_description.pack_start(
lbl_package_description_value, True, True, 0
)
listbox.add(row_package_description)
# arch
row_package_arch = Gtk.ListBoxRow()
vbox_package_arch = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_arch.add(vbox_package_arch)
lbl_package_arch_title = Gtk.Label(xalign=0)
lbl_package_arch_title.set_markup("<b>Architecture</b>")
lbl_package_arch_value = Gtk.Label(xalign=0)
lbl_package_arch_value.set_text(package_metadata["arch"])
vbox_package_arch.pack_start(
lbl_package_arch_title, True, True, 0
)
vbox_package_arch.pack_start(
lbl_package_arch_value, True, True, 0
)
listbox.add(row_package_arch)
# url
row_package_url = Gtk.ListBoxRow()
vbox_package_url = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_url.add(vbox_package_url)
lbl_package_url_title = Gtk.Label(xalign=0)
lbl_package_url_title.set_markup("<b>URL</b>")
lbl_package_url_value = Gtk.Label(xalign=0)
lbl_package_url_value.set_markup(
"<a href='%s'>%s</a>"
% (package_metadata["url"], package_metadata["url"])
)
vbox_package_url.pack_start(
lbl_package_url_title, True, True, 0
)
vbox_package_url.pack_start(
lbl_package_url_value, True, True, 0
)
listbox.add(row_package_url)
# download size
row_package_size = Gtk.ListBoxRow()
vbox_package_size = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_size.add(vbox_package_size)
lbl_package_size_title = Gtk.Label(xalign=0)
lbl_package_size_title.set_markup("<b>Download size</b>")
lbl_package_size_value = Gtk.Label(xalign=0)
lbl_package_size_value.set_text(
package_metadata["download_size"]
)
vbox_package_size.pack_start(
lbl_package_size_title, True, True, 0
)
vbox_package_size.pack_start(
lbl_package_size_value, True, True, 0
)
listbox.add(row_package_size)
# installed size
row_package_installed_size = Gtk.ListBoxRow()
vbox_package_installed_size = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_installed_size.add(vbox_package_installed_size)
lbl_package_installed_size_title = Gtk.Label(xalign=0)
lbl_package_installed_size_title.set_markup(
"<b>Installed size</b>"
)
lbl_package_installed_size_value = Gtk.Label(xalign=0)
lbl_package_installed_size_value.set_text(
package_metadata["installed_size"]
)
vbox_package_installed_size.pack_start(
lbl_package_installed_size_title, True, True, 0
)
vbox_package_installed_size.pack_start(
lbl_package_installed_size_value, True, True, 0
)
listbox.add(row_package_installed_size)
# build date
row_package_build_date = Gtk.ListBoxRow()
vbox_package_build_date = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_build_date.add(vbox_package_build_date)
lbl_package_build_date_title = Gtk.Label(xalign=0)
lbl_package_build_date_title.set_markup("<b>Build date</b>")
lbl_package_build_date_value = Gtk.Label(xalign=0)
lbl_package_build_date_value.set_text(
package_metadata["build_date"]
)
vbox_package_build_date.pack_start(
lbl_package_build_date_title, True, True, 0
)
vbox_package_build_date.pack_start(
lbl_package_build_date_value, True, True, 0
)
listbox.add(row_package_build_date)
# packager
row_package_maintainer = Gtk.ListBoxRow()
vbox_package_maintainer = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_maintainer.add(vbox_package_maintainer)
lbl_package_maintainer_title = Gtk.Label(xalign=0)
lbl_package_maintainer_title.set_markup("<b>Packager</b>")
lbl_package_maintainer_value = Gtk.Label(xalign=0)
lbl_package_maintainer_value.set_text(
package_metadata["packager"]
)
vbox_package_maintainer.pack_start(
lbl_package_maintainer_title, True, True, 0
)
vbox_package_maintainer.pack_start(
lbl_package_maintainer_value, True, True, 0
)
listbox.add(row_package_maintainer)
# depends on
expander_depends_on = Gtk.Expander()
expander_depends_on.set_expanded(True)
expander_depends_on.set_use_markup(True)
expander_depends_on.set_resize_toplevel(True)
expander_depends_on.set_label("<b>Depends on</b>")
row_package_depends_on = Gtk.ListBoxRow()
expander_depends_on.add(row_package_depends_on)
vbox_package_depends_on = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_depends_on.add(vbox_package_depends_on)
if len(package_metadata["depends_on"]) > 0:
treestore_depends = Gtk.TreeStore(str, str)
for item in package_metadata["depends_on"]:
treestore_depends.append(None, list(item))
treeview_depends = Gtk.TreeView(model=treestore_depends)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Package", renderer, text=0)
treeview_depends.append_column(column)
vbox_package_depends_on.pack_start(
treeview_depends, True, True, 0
)
else:
lbl_package_depends_value = Gtk.Label(xalign=0, yalign=0)
lbl_package_depends_value.set_text("None")
vbox_package_depends_on.pack_start(
lbl_package_depends_value, True, True, 0
)
listbox.add(expander_depends_on)
# conflicts with
expander_conflicts_with = Gtk.Expander()
expander_conflicts_with.set_use_markup(True)
expander_conflicts_with.set_expanded(True)
expander_conflicts_with.set_resize_toplevel(True)
expander_conflicts_with.set_label("<b>Conflicts with</b>")
row_package_conflicts_with = Gtk.ListBoxRow()
expander_conflicts_with.add(row_package_conflicts_with)
vbox_package_conflicts_with = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_conflicts_with.add(vbox_package_conflicts_with)
if len(package_metadata["conflicts_with"]) > 0:
treestore_conflicts = Gtk.TreeStore(str, str)
for item in package_metadata["conflicts_with"]:
treestore_conflicts.append(None, list(item))
treeview_conflicts = Gtk.TreeView(model=treestore_conflicts)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Package", renderer, text=0)
treeview_conflicts.append_column(column)
vbox_package_conflicts_with.pack_start(
treeview_conflicts, True, True, 0
)
else:
lbl_package_conflicts_with_value = Gtk.Label(
xalign=0, yalign=0
)
lbl_package_conflicts_with_value.set_text("None")
vbox_package_conflicts_with.pack_start(
lbl_package_conflicts_with_value, True, True, 0
)
listbox.add(expander_conflicts_with)
checkbtn_installed = Gtk.CheckButton(label="Installed")
checkbtn_installed.set_active(False)
checkbtn_installed.set_sensitive(False)
# is the package installed
installed = fn.check_package_installed(term)
if installed is True:
checkbtn_installed.set_active(True)
# box_outer.pack_start(checkbtn_installed, True, True, 0)
scrolled_window_package_info = Gtk.ScrolledWindow()
scrolled_window_package_info.set_propagate_natural_height(True)
scrolled_window_package_info.add(box_outer)
vbox_package_info = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
lbl_padding_vbox = Gtk.Label(xalign=0, yalign=0)
lbl_padding_vbox.set_text("")
vbox_package_info.pack_start(
scrolled_window_package_info, True, True, 0
)
vbox_package_info.pack_start(lbl_padding_vbox, True, True, 0)
vbox_package_info.pack_start(checkbtn_installed, True, True, 0)
self.stack.add_titled(
vbox_package_info,
"Package Information",
"Package Information",
)
# package files
package_files = fn.get_package_files(term)
if package_files is not None:
lbl_package_title = Gtk.Label(xalign=0, yalign=0)
lbl_package_title.set_markup("<b>Package</b>")
lbl_package_title_value = Gtk.Label(xalign=0, yalign=0)
lbl_package_title_value.set_text(package_metadata["name"])
treestore_filelist = Gtk.TreeStore(str, str)
for file in package_files:
treestore_filelist.append(None, list(file))
treeview_files = Gtk.TreeView(model=treestore_filelist)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Files", renderer, text=0)
treeview_files.append_column(column)
vbox_package_files = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
vbox_package_files.pack_start(
lbl_package_title, True, True, 0
)
vbox_package_files.pack_start(
lbl_package_title_value, True, True, 0
)
lbl_padding_package_files = Gtk.Label(xalign=0, yalign=0)
lbl_padding_package_files.set_text("")
vbox_package_files.pack_start(
lbl_padding_package_files, True, True, 0
)
scrolled_window_package_files = Gtk.ScrolledWindow()
scrolled_window_package_files.set_propagate_natural_height(
True
)
scrolled_window_package_files.add(treeview_files)
vbox_package_files.pack_start(
scrolled_window_package_files, True, True, 0
)
self.stack.add_titled(
vbox_package_files,
"Package Files",
"Package Files",
)
self.search_package_activated = True
self.show_all()
else:
message_dialog = MessageDialog(
"Info",
"Search returned 0 results",
"Failed to find package name",
"Are the correct pacman mirrorlists configured ?\nOr try to search again using the exact package name",
"info",
False,
)
message_dialog.show_all()
message_dialog.run()
message_dialog.hide()
except Exception as e:
fn.logger.error("Exception in perform_search(): %s" % e)

View File

@@ -1,228 +0,0 @@
# ============================================================
# Authors: Brad Heffernan - Erik Dubois - Cameron Percival
# ============================================================
import os
import gi
import Functions as fn
from queue import Queue
from ui.MessageDialog import MessageDialog
from gi.repository import Gtk, Gdk, GdkPixbuf, Pango, GLib
gi.require_version("Gtk", "3.0")
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
class PackagesImportDialog(Gtk.Dialog):
"""create a gui"""
def __init__(self, package_file, packages_list, logfile):
Gtk.Dialog.__init__(self)
# Create a queue for storing package import messages from pacman
self.pkg_import_queue = Queue()
# Create a queue for storing package install errors
self.pkg_err_queue = Queue()
# Create a queue for storing package install status
self.pkg_status_queue = Queue()
self.package_file = package_file
self.packages_list = packages_list
self.logfile = logfile
self.stop_thread = False
self.set_resizable(True)
self.set_border_width(10)
self.set_size_request(800, 700)
self.set_modal(True)
headerbar = Gtk.HeaderBar()
headerbar.set_title("Import packages")
headerbar.set_show_close_button(True)
self.set_titlebar(headerbar)
self.set_icon_from_file(os.path.join(base_dir, "images/blackbox.png"))
hbox_title = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
lbl_packages_title = Gtk.Label(xalign=0)
lbl_packages_title.set_name("title")
lbl_packages_title.set_text("Packages")
hbox_title.pack_start(lbl_packages_title, False, False, 0)
hbox_title_install = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
label_install_title = Gtk.Label(xalign=0)
label_install_title.set_markup("<b> Install Packages</b>")
hbox_title_install.pack_start(label_install_title, False, False, 0)
hbox_sep = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
hsep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
hbox_sep.pack_start(hsep, True, True, 0)
frame_install = Gtk.Frame(label="")
frame_install_label = frame_install.get_label_widget()
frame_install_label.set_markup("<b>Install Packages</b>")
hbox_install = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
label_install_desc = Gtk.Label(xalign=0, yalign=0)
label_install_desc.set_markup(
f""
f" <b>WARNING: Proceed with caution this will install packages onto your system!</b>\n"
f" <b>Packages from the AUR are not supported </b>\n"
f" <b>This also performs a full system upgrade</b>\n\n"
f" - A list of packages are sourced from <b>{self.package_file}</b>\n"
f" - To ignore a package, add a # in front of the package name\n"
f" - Log file: {self.logfile}\n"
f" - <b>A reboot is recommended when core Linux packages are installed</b>\n"
)
self.scrolled_window = Gtk.ScrolledWindow()
self.textview = Gtk.TextView()
self.textview.set_name("textview_log")
self.textview.set_property("editable", False)
self.textview.set_property("monospace", True)
self.textview.set_border_width(10)
self.textview.set_vexpand(True)
self.textview.set_hexpand(True)
msg_buffer = self.textview.get_buffer()
msg_buffer.insert(
msg_buffer.get_end_iter(),
"\n Click Yes to confirm install of the following packages:\n\n",
)
lbl_title_message = Gtk.Label(xalign=0, yalign=0)
lbl_title_message.set_markup(
"There are <b>%s</b> packages to install, proceed ?"
% len(self.packages_list)
)
lbl_padding1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding1.set_text("")
lbl_padding2 = Gtk.Label(xalign=0, yalign=0)
lbl_padding2.set_text("")
self.infobar = Gtk.InfoBar()
content = self.infobar.get_content_area()
content.add(lbl_title_message)
self.infobar.set_revealed(True)
for package in sorted(self.packages_list):
msg_buffer.insert(msg_buffer.get_end_iter(), " - %s\n" % package)
# move focus away from the textview, to hide the cursor at load
headerbar.set_property("can-focus", True)
Gtk.Window.grab_focus(headerbar)
self.scrolled_window.add(self.textview)
self.button_yes = self.add_button("Yes", Gtk.ResponseType.OK)
self.button_yes.set_size_request(100, 30)
btn_yes_context = self.button_yes.get_style_context()
btn_yes_context.add_class("destructive-action")
self.button_no = self.add_button("Close", Gtk.ResponseType.CANCEL)
self.button_no.set_size_request(100, 30)
self.connect("response", self.on_response)
vbox_log_dir = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
btn_open_log_dir = Gtk.Button(label="Open log directory")
btn_open_log_dir.connect("clicked", self.on_open_log_dir_clicked)
btn_open_log_dir.set_size_request(100, 30)
vbox_log_dir.pack_start(btn_open_log_dir, False, False, 0)
grid_message = Gtk.Grid()
grid_message.attach(label_install_desc, 0, 0, 1, 1)
grid_message.attach(self.infobar, 0, 1, 1, 1)
grid_message.attach(lbl_padding1, 0, 2, 1, 1)
grid_message.attach(self.scrolled_window, 0, 3, 1, 1)
grid_message.attach(lbl_padding2, 0, 4, 1, 1)
grid_message.attach(vbox_log_dir, 0, 5, 1, 1)
self.vbox.add(grid_message)
def on_open_log_dir_clicked(self, widget):
fn.open_log_dir()
def display_progress(self):
self.textview.destroy()
self.infobar.destroy()
self.button_yes.destroy()
self.label_package_status = Gtk.Label(xalign=0, yalign=0)
self.label_package_count = Gtk.Label(xalign=0, yalign=0)
label_warning_close = Gtk.Label(xalign=0, yalign=0)
label_warning_close.set_markup(
"<b>Do not close this window during package installation</b>"
)
self.textview = Gtk.TextView()
self.textview.set_name("textview_log")
self.textview.set_property("editable", False)
self.textview.set_property("monospace", True)
self.textview.set_border_width(10)
self.textview.set_vexpand(True)
self.textview.set_hexpand(True)
self.scrolled_window.add(self.textview)
self.msg_buffer = self.textview.get_buffer()
self.vbox.add(label_warning_close)
self.vbox.add(self.label_package_status)
self.vbox.add(self.label_package_count)
fn.Thread(
target=fn.monitor_package_import,
args=(self,),
daemon=True,
).start()
self.show_all()
fn.logger.info("Installing packages")
event = "%s [INFO]: Installing packages\n" % fn.datetime.now().strftime(
"%Y-%m-%d-%H-%M-%S"
)
fn.logger.info("Log file = %s" % self.logfile)
self.pkg_import_queue.put(event)
# debug install, overrride packages_list
# self.packages_list = ["cheese", "firefox", "blackbox-dev-git", "blackbox-git"]
# starts 2 threads one to install the packages, and another to check install status
fn.Thread(
target=fn.import_packages,
args=(self,),
daemon=True,
).start()
fn.Thread(target=fn.log_package_status, args=(self,), daemon=True).start()
def on_response(self, dialog, response):
if response in (Gtk.ResponseType.OK, Gtk.ResponseType.YES):
self.stop_thread = False
self.display_progress()
else:
self.stop_thread = True
dialog.hide()
dialog.destroy()

View File

@@ -1,71 +0,0 @@
# This class is used to create a window to monitor the pacman log file inside /var/log/pacman.log
import os
import gi
import Functions as fn
from gi.repository import Gtk, Gdk, GdkPixbuf, Pango, GLib
gi.require_version("Gtk", "3.0")
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
# base_dir = os.path.dirname(os.path.realpath(__file__))
class PacmanLogWindow(Gtk.Window):
def __init__(self, textview_pacmanlog, btn_pacmanlog):
Gtk.Window.__init__(self)
self.start_logtimer = True
self.textview_pacmanlog = textview_pacmanlog
self.btn_pacmanlog = btn_pacmanlog
headerbar = Gtk.HeaderBar()
headerbar.set_show_close_button(True)
self.set_titlebar(headerbar)
self.set_title("BlackBox - Pacman log file viewer")
self.set_default_size(800, 600)
self.set_resizable(True)
self.set_border_width(10)
self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.set_icon_from_file(os.path.join(base_dir, "images/blackbox.png"))
self.connect("delete-event", self.on_close)
btn_pacmanlog_ok = Gtk.Button(label="OK")
btn_pacmanlog_ok.connect("clicked", self.on_response, "response")
btn_pacmanlog_ok.set_size_request(100, 30)
btn_pacmanlog_ok.set_halign(Gtk.Align.END)
pacmanlog_scrolledwindow = Gtk.ScrolledWindow()
pacmanlog_scrolledwindow.set_size_request(750, 500)
pacmanlog_scrolledwindow.add(self.textview_pacmanlog)
lbl_padding1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding1.set_text("")
vbox_pacmanlog = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
vbox_pacmanlog.pack_start(pacmanlog_scrolledwindow, True, True, 0)
vbox_pacmanlog.pack_start(lbl_padding1, False, False, 0)
vbox_pacmanlog.pack_start(btn_pacmanlog_ok, False, False, 0)
self.add(vbox_pacmanlog)
def on_close(self, widget, data):
fn.logger.debug("Closing pacman log monitoring window")
self.start_logtimer = False
self.btn_pacmanlog.set_sensitive(True)
self.hide()
self.destroy()
def on_response(self, widget, response):
# stop updating the textview
fn.logger.debug("Closing pacman log monitoring dialog")
self.start_logtimer = False
self.btn_pacmanlog.set_sensitive(True)
# self.remove(self)
self.hide()
self.destroy()

View File

@@ -1,87 +0,0 @@
from gi.repository import Gtk, GLib
import gi
# Since a system can have multiple versions
# of GTK + installed, we want to make
# sure that we are importing GTK + 3.
gi.require_version("Gtk", "3.0")
class ProgressBarWindow(Gtk.Window):
new_value = 0.0
def __init__(self):
Gtk.Window.__init__(self, title="Progress Bar")
self.set_border_width(10)
vbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
self.add(vbox)
# Create a ProgressBar
self.progressbar = Gtk.ProgressBar()
vbox.pack_start(self.progressbar, True, True, 0)
# Create CheckButton with labels "Show text",
# "Activity mode", "Right to Left" respectively
# button = Gtk.CheckButton(label="Show text")
# button.connect("toggled", self.on_show_text_toggled)
# vbox.pack_start(button, True, True, 0)
# button = Gtk.CheckButton(label="Activity mode")
# button.connect("toggled", self.on_activity_mode_toggled)
# vbox.pack_start(button, True, True, 0)
# button = Gtk.CheckButton(label="Right to Left")
# button.connect("toggled", self.on_right_to_left_toggled)
# vbox.pack_start(button, True, True, 0)
# self.timeout_id = GLib.timeout_add(5000, self.on_timeout, None)
self.activity_mode = False
def set_text(self, text):
self.progressbar.set_text(text)
self.progressbar.set_show_text(True)
def reset_timer(self):
new_value = 0.0
self.progressbar.set_fraction(new_value)
def on_activity_mode_toggled(self, button):
self.activity_mode = button.get_active()
if self.activity_mode:
self.progressbar.pulse()
else:
self.progressbar.set_fraction(0.0)
def on_right_to_left_toggled(self, button):
value = button.get_active()
self.progressbar.set_inverted(value)
def update(self, fraction):
new_value = self.progressbar.get_fraction() + fraction
self.progressbar.set_fraction(new_value)
if new_value >= 1.0:
return False
return True
def get_complete(self):
if self.progressbar.get_fraction() >= 1.0:
return True
return False
def on_timeout(self, user_data=0.01):
"""
Update value on the progress bar
"""
if self.activity_mode:
self.progressbar.pulse()
else:
new_value = self.progressbar.get_fraction() + user_data
if new_value > 1:
new_value = 0.0
return False
self.progressbar.set_fraction(new_value)
return True

View File

@@ -1,400 +0,0 @@
# This class is used to create a modal dialog window showing progress of a package install/uninstall and general package information
import os
import gi
import Functions as fn
from ui.MessageDialog import MessageDialog
from gi.repository import Gtk, Gdk, GdkPixbuf, Pango, GLib
gi.require_version("Gtk", "3.0")
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
# base_dir = os.path.dirname(os.path.realpath(__file__))
class ProgressDialog(Gtk.Dialog):
def __init__(self, action, package, command, package_metadata):
Gtk.Dialog.__init__(self)
self.package_found = True
# this gets package information using pacman -Si or pacman -Qi whichever returns output
# package_metadata = fn.get_package_information(pkg.name)
# if a mirrorlist isn't configured properly, pacman will not be able to query its repository
# so the following is a condition to make sure the data returned isn't an error
if type(package_metadata) is dict:
package_progress_dialog_headerbar = Gtk.HeaderBar()
package_progress_dialog_headerbar.set_show_close_button(True)
self.set_titlebar(package_progress_dialog_headerbar)
self.connect("delete-event", package_progress_dialog_on_close, self, action)
if action == "install":
self.set_title("BlackBox - installing package %s" % package.name)
elif action == "uninstall":
self.set_title("BlackBox - removing package %s" % package.name)
self.btn_package_progress_close = Gtk.Button(label="OK")
self.btn_package_progress_close.connect(
"clicked",
on_package_progress_close_response,
self,
)
self.btn_package_progress_close.set_sensitive(False)
self.btn_package_progress_close.set_size_request(100, 30)
self.btn_package_progress_close.set_halign(Gtk.Align.END)
self.set_resizable(True)
self.set_size_request(850, 700)
self.set_modal(True)
self.set_border_width(10)
self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.set_icon_from_file(os.path.join(base_dir, "images/blackbox.png"))
lbl_pacman_action_title = Gtk.Label(xalign=0, yalign=0)
lbl_pacman_action_title.set_text("Running command:")
lbl_pacman_action_value = Gtk.Label(xalign=0, yalign=0)
lbl_pacman_action_value.set_markup("<b>%s</b>" % command)
stack = Gtk.Stack()
stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
stack.set_transition_duration(350)
stack.set_hhomogeneous(False)
stack.set_vhomogeneous(False)
stack_switcher = Gtk.StackSwitcher()
stack_switcher.set_orientation(Gtk.Orientation.HORIZONTAL)
stack_switcher.set_stack(stack)
stack_switcher.set_homogeneous(True)
package_progress_grid = Gtk.Grid()
self.infobar = Gtk.InfoBar()
self.infobar.set_name("infobar_info")
content = self.infobar.get_content_area()
content.add(lbl_pacman_action_title)
content.add(lbl_pacman_action_value)
self.infobar.set_revealed(True)
lbl_padding_header1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding_header1.set_text("")
package_progress_grid.attach(lbl_padding_header1, 0, 1, 1, 1)
package_progress_grid.attach(self.infobar, 0, 2, 1, 1)
package_progress_grid.set_property("can-focus", True)
Gtk.Window.grab_focus(package_progress_grid)
lbl_padding1 = Gtk.Label(xalign=0, yalign=0)
lbl_padding1.set_text("")
lbl_padding2 = Gtk.Label(xalign=0, yalign=0)
lbl_padding2.set_text("")
lbl_padding2.set_halign(Gtk.Align.END)
package_progress_grid.attach(lbl_padding1, 0, 3, 1, 1)
package_progress_scrolled_window = Gtk.ScrolledWindow()
self.package_progress_textview = Gtk.TextView()
self.package_progress_textview.set_property("editable", False)
self.package_progress_textview.set_property("monospace", True)
self.package_progress_textview.set_border_width(10)
self.package_progress_textview.set_vexpand(True)
self.package_progress_textview.set_hexpand(True)
buffer = self.package_progress_textview.get_buffer()
self.package_progress_textview.set_buffer(buffer)
package_progress_scrolled_window.set_size_request(700, 430)
package_progress_scrolled_window.add(self.package_progress_textview)
package_progress_grid.attach(package_progress_scrolled_window, 0, 4, 1, 1)
vbox_close = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
vbox_close.pack_start(lbl_padding2, True, True, 0)
vbox_close.pack_start(self.btn_package_progress_close, True, True, 0)
stack.add_titled(package_progress_grid, "Progress", "Package Progress")
# package information
box_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
listbox = Gtk.ListBox()
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
box_outer.pack_start(listbox, True, True, 0)
# package name
row_package_title = Gtk.ListBoxRow()
vbox_package_title = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_title.add(vbox_package_title)
lbl_package_name_title = Gtk.Label(xalign=0)
lbl_package_name_title.set_markup("<b>Package Name</b>")
lbl_package_name_value = Gtk.Label(xalign=0)
lbl_package_name_value.set_text(package_metadata["name"])
vbox_package_title.pack_start(lbl_package_name_title, True, True, 0)
vbox_package_title.pack_start(lbl_package_name_value, True, True, 0)
listbox.add(row_package_title)
# repository
row_package_repo = Gtk.ListBoxRow()
vbox_package_repo = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
row_package_repo.add(vbox_package_repo)
lbl_package_repo_title = Gtk.Label(xalign=0)
lbl_package_repo_title.set_markup("<b>Repository</b>")
lbl_package_repo_value = Gtk.Label(xalign=0)
lbl_package_repo_value.set_text(package_metadata["repository"])
vbox_package_repo.pack_start(lbl_package_repo_title, True, True, 0)
vbox_package_repo.pack_start(lbl_package_repo_value, True, True, 0)
listbox.add(row_package_repo)
# description
row_package_description = Gtk.ListBoxRow()
vbox_package_description = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_description.add(vbox_package_description)
lbl_package_description_title = Gtk.Label(xalign=0)
lbl_package_description_title.set_markup("<b>Description</b>")
lbl_package_description_value = Gtk.Label(xalign=0)
lbl_package_description_value.set_text(package_metadata["description"])
vbox_package_description.pack_start(
lbl_package_description_title, True, True, 0
)
vbox_package_description.pack_start(
lbl_package_description_value, True, True, 0
)
listbox.add(row_package_description)
# arch
row_package_arch = Gtk.ListBoxRow()
vbox_package_arch = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
row_package_arch.add(vbox_package_arch)
lbl_package_arch_title = Gtk.Label(xalign=0)
lbl_package_arch_title.set_markup("<b>Architecture</b>")
lbl_package_arch_value = Gtk.Label(xalign=0)
lbl_package_arch_value.set_text(package_metadata["arch"])
vbox_package_arch.pack_start(lbl_package_arch_title, True, True, 0)
vbox_package_arch.pack_start(lbl_package_arch_value, True, True, 0)
listbox.add(row_package_arch)
# url
row_package_url = Gtk.ListBoxRow()
vbox_package_url = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
row_package_url.add(vbox_package_url)
lbl_package_url_title = Gtk.Label(xalign=0)
lbl_package_url_title.set_markup("<b>URL</b>")
lbl_package_url_value = Gtk.Label(xalign=0)
lbl_package_url_value.set_markup(
"<a href='%s'>%s</a>"
% (package_metadata["url"], package_metadata["url"])
)
vbox_package_url.pack_start(lbl_package_url_title, True, True, 0)
vbox_package_url.pack_start(lbl_package_url_value, True, True, 0)
listbox.add(row_package_url)
# download size
row_package_size = Gtk.ListBoxRow()
vbox_package_size = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
row_package_size.add(vbox_package_size)
lbl_package_size_title = Gtk.Label(xalign=0)
lbl_package_size_title.set_markup("<b>Download size</b>")
lbl_package_size_value = Gtk.Label(xalign=0)
lbl_package_size_value.set_text(package_metadata["download_size"])
vbox_package_size.pack_start(lbl_package_size_title, True, True, 0)
vbox_package_size.pack_start(lbl_package_size_value, True, True, 0)
listbox.add(row_package_size)
# installed size
row_package_installed_size = Gtk.ListBoxRow()
vbox_package_installed_size = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_installed_size.add(vbox_package_installed_size)
lbl_package_installed_size_title = Gtk.Label(xalign=0)
lbl_package_installed_size_title.set_markup("<b>Installed size</b>")
lbl_package_installed_size_value = Gtk.Label(xalign=0)
lbl_package_installed_size_value.set_text(
package_metadata["installed_size"]
)
vbox_package_installed_size.pack_start(
lbl_package_installed_size_title, True, True, 0
)
vbox_package_installed_size.pack_start(
lbl_package_installed_size_value, True, True, 0
)
listbox.add(row_package_installed_size)
# build date
row_package_build_date = Gtk.ListBoxRow()
vbox_package_build_date = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_build_date.add(vbox_package_build_date)
lbl_package_build_date_title = Gtk.Label(xalign=0)
lbl_package_build_date_title.set_markup("<b>Build date</b>")
lbl_package_build_date_value = Gtk.Label(xalign=0)
lbl_package_build_date_value.set_text(package_metadata["build_date"])
vbox_package_build_date.pack_start(
lbl_package_build_date_title, True, True, 0
)
vbox_package_build_date.pack_start(
lbl_package_build_date_value, True, True, 0
)
listbox.add(row_package_build_date)
# packager
row_package_maintainer = Gtk.ListBoxRow()
vbox_package_maintainer = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_maintainer.add(vbox_package_maintainer)
lbl_package_maintainer_title = Gtk.Label(xalign=0)
lbl_package_maintainer_title.set_markup("<b>Packager</b>")
lbl_package_maintainer_value = Gtk.Label(xalign=0)
lbl_package_maintainer_value.set_text(package_metadata["packager"])
vbox_package_maintainer.pack_start(
lbl_package_maintainer_title, True, True, 0
)
vbox_package_maintainer.pack_start(
lbl_package_maintainer_value, True, True, 0
)
listbox.add(row_package_maintainer)
# depends on
expander_depends_on = Gtk.Expander()
expander_depends_on.set_use_markup(True)
expander_depends_on.set_resize_toplevel(True)
expander_depends_on.set_label("<b>Depends on</b>")
row_package_depends_on = Gtk.ListBoxRow()
expander_depends_on.add(row_package_depends_on)
vbox_package_depends_on = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_depends_on.add(vbox_package_depends_on)
if len(package_metadata["depends_on"]) > 0:
treestore_depends = Gtk.TreeStore(str, str)
for item in package_metadata["depends_on"]:
treestore_depends.append(None, list(item))
treeview_depends = Gtk.TreeView(model=treestore_depends)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Package", renderer, text=0)
treeview_depends.append_column(column)
vbox_package_depends_on.pack_start(treeview_depends, True, True, 0)
else:
lbl_package_depends_value = Gtk.Label(xalign=0, yalign=0)
lbl_package_depends_value.set_text("None")
vbox_package_depends_on.pack_start(
lbl_package_depends_value, True, True, 0
)
listbox.add(expander_depends_on)
# conflicts with
expander_conflicts_with = Gtk.Expander()
expander_conflicts_with.set_use_markup(True)
expander_conflicts_with.set_resize_toplevel(True)
expander_conflicts_with.set_label("<b>Conflicts with</b>")
row_package_conflicts_with = Gtk.ListBoxRow()
expander_conflicts_with.add(row_package_conflicts_with)
vbox_package_conflicts_with = Gtk.Box(
orientation=Gtk.Orientation.VERTICAL, spacing=0
)
row_package_conflicts_with.add(vbox_package_conflicts_with)
if len(package_metadata["conflicts_with"]) > 0:
treestore_conflicts = Gtk.TreeStore(str, str)
for item in package_metadata["conflicts_with"]:
treestore_conflicts.append(None, list(item))
treeview_conflicts = Gtk.TreeView(model=treestore_conflicts)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Package", renderer, text=0)
treeview_conflicts.append_column(column)
vbox_package_conflicts_with.pack_start(
treeview_conflicts, True, True, 0
)
else:
lbl_package_conflicts_with_value = Gtk.Label(xalign=0, yalign=0)
lbl_package_conflicts_with_value.set_text("None")
vbox_package_conflicts_with.pack_start(
lbl_package_conflicts_with_value, True, True, 0
)
listbox.add(expander_conflicts_with)
package_metadata_scrolled_window = Gtk.ScrolledWindow()
package_metadata_scrolled_window.add(box_outer)
stack.add_titled(
package_metadata_scrolled_window, "Package Information", "Information"
)
self.vbox.add(stack_switcher)
self.vbox.add(stack)
self.vbox.add(vbox_close)
def on_package_progress_close_response(self, widget):
self.pkg_dialog_closed = True
fn.logger.debug("Closing package progress dialog")
widget.hide()
widget.destroy()
def package_progress_dialog_on_close(widget, data, self, action):
self.pkg_dialog_closed = True
fn.logger.debug("Closing package progress dialog")
widget.hide()
widget.destroy()

View File

@@ -1,30 +0,0 @@
import gi
from Functions import os
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf, Gdk # noqa
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
# base_dir = os.path.dirname(os.path.realpath(__file__))
class SplashScreen(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, Gtk.WindowType.POPUP, title="")
self.set_decorated(False)
self.set_resizable(False)
self.set_size_request(600, 400)
self.set_position(Gtk.WindowPosition.CENTER)
main_vbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=1)
self.add(main_vbox)
self.image = Gtk.Image()
pimage = GdkPixbuf.Pixbuf().new_from_file_at_size(
base_dir + "/images/splash.png", 600, 400
)
self.image.set_from_pixbuf(pimage)
main_vbox.pack_start(self.image, True, True, 0)
self.show_all()

View File

@@ -1,227 +0,0 @@
- name: "Fuzzer"
description: "Fuzzer"
critical: false
hidden: false
selected: false
expanded: true
packages:
- 0d1n
- abuse-ssl-bypass-waf
- aflplusplus
- aggroargs
- ajpfuzzer
- astra
- atlas
- atscan
- backfuzz
- bbscan
- bfuzz
- bing-lfi-rfi
- birp
- bluebox-ng
- boofuzz
- browser-fuzzer
- brutexss
- bss
- bt_audit
- bunny
- burpsuite
- cantoolz
- capfuzz
- cecster
- chipsec
- choronzon
- cirt-fuzzer
- cisco-auditing-tool
- cmsfuzz
- conscan
- cookie-cadger
- crackql
- crlf-injector
- dalfox
- darkbing
- dharma
- dhcpig
- dizzy
- domato
- doona
- dotdotpwn
- dpscan
- dr-checker
- drozer
- easyfuzzer
- faradaysec
- fdsploit
- feroxbuster
- ffuf
- fhttp
- filebuster
- filefuzz
- fimap
- firewalk
- flyr
- fockcache
- frisbeelite
- ftester
- ftp-fuzz
- fuddly
- fusil
- fuzzball2
- fuzzdb
- fuzzdiff
- fuzzowski
- fuzztalk
- gloom
- goofuzz
- grammarinator
- graphql-path-enum
- graphqlmap
- grr
- hexorbase
- hodor
- homepwn
- honggfuzz
- http-fuzz
- httpforge
- hwk
- ifuzz
- ikeprober
- inguma
- injectus
- isip
- jbrofuzz
- jok3r
- joomlavs
- jsql-injection
- kitty-framework
- krbrelayx
- leviathan
- lfi-autopwn
- lfi-fuzzploit
- lfi-scanner
- lfi-sploiter
- lfimap
- liffy
- littleblackbox
- log4j-bypass
- log4j-scan
- logmepwn
- lorsrf
- maligno
- malybuzz
- manul
- mdk3
- mdk4
- melkor
- metasploit
- mitm6
- mongoaudit
- network-app-stress-tester
- netzob
- nikto
- nili
- nimbostratus
- notspikefile
- nsoq
- nullscan
- oat
- ohrwurm
- openvas-scanner
- oscanner
- owtf
- pappy-proxy
- parampampam
- peach
- peach-fuzz
- pentbox
- pmcma
- portmanteau
- powerfuzzer
- pret
- profuzz
- pulsar
- pureblood
- pyersinia
- pyjfuzz
- pytbull
- qark
- radamsa
- rapidscan
- ratproxy
- responder
- restler-fuzzer
- s3-fuzzer
- samesame
- sandsifter
- sb0x
- scout2
- sfuzz
- shortfuzzy
- skipfish
- sloth-fuzzer
- smartphone-pentest-framework
- smbexec
- smod
- smtp-fuzz
- smtptx
- sn00p
- snmp-fuzzer
- soapui
- socketfuzz
- spaf
- spartan
- spiderpig-pdffuzzer
- spike-fuzzer
- sploitego
- sps
- sqlbrute
- sqlmap
- sqlninja
- sshfuzz
- ssrfmap
- stews
- sulley
- taof
- tcpcontrol-fuzzer
- tcpjunk
- termineter
- tftp-fuzz
- thefuzz
- tlsfuzzer
- trinity
- udp-hunter
- udsim
- umap
- unifuzzer
- uniofuzz
- uniscan
- upnp-pentest-toolkit
- uppwn
- vane
- vbscan
- viproy-voipkit
- vsaudit
- vulscan
- w13scan
- w3af
- wafninja
- wafpass
- wapiti
- webscarab
- webshag
- websploit
- webxploiter
- weirdaal
- wfuzz
- witchxtool
- wpscan
- wsfuzzer
- xspear
- xss-freak
- xsser
- xsss
- xssscan
- xsssniper
- yawast
- zaproxy
- zzuf

View File

@@ -1,664 +0,0 @@
- name: "WebApp"
description: "WebApp"
critical: false
hidden: false
selected: false
expanded: true
packages:
- 0d1n
- 0trace
- a2sv
- adenum
- adminpagefinder
- admsnmp
- allthevhosts
- amass
- androidsniffer
- anti-xss
- anubis
- apache-users
- apachetomcatscanner
- apnbf
- appmon
- arjun
- arp-scan
- asp-audit
- assetfinder
- atear
- athena-ssl-scanner
- atscan
- atstaketools
- attk
- autorecon
- aws-extender-cli
- aws-iam-privesc
- awsbucketdump
- badkarma
- badministration
- barmie
- basedomainname
- bashscan
- bbscan
- belati
- billcipher
- bing-lfi-rfi
- bingoo
- birp
- blackbox-scanner
- bleah
- blindy
- blue-hydra
- bluebox-ng
- bluelog
- bluescan
- bluto
- botb
- braa
- brakeman
- bss
- btscanner
- burpsuite
- c5scan
- cameradar
- camscan
- canari
- cangibrina
- cansina
- cantoolz
- cariddi
- casefile
- cecster
- cent
- cero
- changeme
- chaosmap
- check-weak-dh-ssh
- checksec
- chipsec
- chiron
- cipherscan
- cisco-auditing-tool
- cisco-scanner
- cisco-torch
- ciscos
- clair
- clairvoyance
- climber
- cloudflare-enum
- cloudmare
- cloudsploit
- cloudunflare
- cms-few
- cmsfuzz
- cmsmap
- cmsscan
- cmsscanner
- comission
- complemento
- configpush
- conscan
- cookie-cadger
- corscanner
- corstest
- corsy
- cpfinder
- crackmapexec
- creepy
- crlfuzz
- ct-exposer
- cvechecker
- cybercrowl
- cyberscan
- d-tect
- dark-dork-searcher
- darkbing
- darkdump
- darkscrape
- datasploit
- davscan
- davtest
- dawnscanner
- dbusmap
- dcrawl
- deblaze
- delldrac
- dependency-check
- dhcpig
- dirb
- dirble
- dirbuster
- dirbuster-ng
- dirhunt
- dirscanner
- dirscraper
- dirsearch
- dirstalk
- dive
- dmitry
- dnmap
- dns2geoip
- dnsa
- dnsbf
- dnsbrute
- dnscan
- dnsenum
- dnsgoblin
- dnspredict
- dnsspider
- dnstwist
- dnswalk
- dockerscan
- dontgo403
- dorkbot
- dorkme
- dpscan
- driftnet
- dripper
- droopescan
- drozer
- drupal-module-enum
- drupalscan
- drupwn
- dsfs
- dsjs
- dsss
- dsxs
- dvcs-ripper
- easyda
- eazy
- eigrp-tools
- enteletaor
- enum-shares
- enum4linux
- enum4linux-ng
- enumerate-iam
- enumiax
- eos
- eternal-scanner
- evine
- extended-ssrf-search
- faradaysec
- fernmelder
- feroxbuster
- fgscanner
- fhttp
- fi6s
- fierce
- find-dns
- firewalk
- flashscanner
- flunym0us
- forkingportscanner
- fortiscan
- fping
- fs-nyarl
- fscan
- fsnoop
- ftp-scanner
- ftp-spider
- ftpmap
- ftpscout
- gatecrasher
- gcpbucketbrute
- gethsploit
- gggooglescan
- ghost-phisher
- git-dump
- git-dumper
- gitdorker
- gitrob
- gittools
- gloom
- gobuster
- goofuzz
- goohak
- goop-dump
- gospider
- gpredict
- grabbb
- graphinder
- graphql-cop
- grepforrfi
- grype
- gtp-scan
- gwcheck
- h2buster
- h2t
- habu
- hackredis
- hakku
- hakrawler
- halberd
- hasere
- hbad
- heartleech
- hellraiser
- hexorbase
- hikpwn
- homepwn
- hookshot
- hoppy
- host-extract
- hostbox-ssh
- hsecscan
- htcap
- http-enum
- http2smugl
- httpforge
- httpgrep
- httprobe
- httpsscanner
- httpx
- hwk
- iaxscan
- icmpquery
- idswakeup
- iis-shortname-scanner
- ike-scan
- ikeprobe
- ilo4-toolbox
- infip
- inguma
- injectus
- inurlbr
- ipscan
- iptv
- ipv6toolkit
- ircsnapshot
- isme
- jaadas
- jaeles
- jira-scan
- jok3r
- joomlascan
- joomlavs
- juumla
- kadimus
- kalibrate-rtl
- katana-framework
- katana-pd
- kiterunner
- knock
- knxmap
- konan
- krbrelayx
- kube-hunter
- kubesploit
- kubestriker
- kubolt
- laf
- ldapdomaindump
- ldapenum
- leaklooker
- letmefuckit-scanner
- leviathan
- lfi-scanner
- lfisuite
- lightbulb
- linenum
- linikatz
- linux-smart-enumeration
- list-urls
- littleblackbox
- locasploit
- log4j-bypass
- log4j-scan
- logmepwn
- loki-scanner
- lorsrf
- lotophagi
- lte-cell-scanner
- lulzbuster
- lunar
- lynis
- magescan
- maligno
- maltego
- manspider
- mantra
- maryam
- massbleed
- masscan
- meg
- metasploit
- mingsweeper
- miranda-upnp
- mitm6
- modscan
- mongoaudit
- mooscan
- morxtraversal
- mptcp-abuse
- mqtt-pwn
- msmailprobe
- mssqlscan
- multiscanner
- mwebfp
- naabu
- nbname
- nbtenum
- nbtool
- nbtscan
- netbios-share-scanner
- netexec
- netreconn
- netscan
- netscan2
- nettacker
- netz
- nextnet
- nikto
- nili
- nmap
- nmbscan
- nosqlattack
- nosqli
- nray
- nsdtool
- nsec3map
- nsoq
- ntlm-challenger
- ntlm-scanner
- ntlmrecon
- nuclei
- nuclei-templates
- nullinux
- nullscan
- o-saft
- ocs
- okadminfinder
- onesixtyone
- onetwopunch
- onionscan
- onionsearch
- opendoor
- openscap
- openvas-scanner
- owasp-bywaf
- owtf
- pagodo
- paketto
- panhunt
- pappy-proxy
- parameth
- paranoic
- passhunt
- pbscan
- pcredz
- peass
- pentbox
- pentestly
- phonia
- php-malware-finder
- pinkerton
- plcscan
- pmap
- pnscan
- poison
- postenum
- pown
- ppfuzz
- ppmap
- ppscan
- prads
- praeda
- pret
- propecia
- prowler
- proxmark
- proxmark3
- proxybroker2
- proxycheck
- proxyp
- proxyscan
- ptf
- pureblood
- puredns
- pwncat
- pwndora
- pyersinia
- pyfiscan
- pyssltest
- pytbull
- pythem
- python-api-dnsdumpster
- python-shodan
- python2-api-dnsdumpster
- python2-ldapdomaindump
- python2-shodan
- qark
- quickrecon
- raccoon
- ranger-scanner
- rapidscan
- ratproxy
- rawr
- rbac-lookup
- rdp-cipher-checker
- rdp-sec-check
- reconscan
- recsech
- red-hawk
- redfang
- relay-scanner
- responder
- retire
- revipd
- rext
- ripdc
- rlogin-scanner
- routerhunter
- rpctools
- rpdscan
- rtlizer
- rtlsdr-scanner
- rustbuster
- rustscan
- s3scanner
- sambascan
- sandcastle
- sandmap
- sandy
- sb0x
- scamper
- scanless
- scanqli
- scanssh
- scap-security-guide
- scap-workbench
- scout2
- scoutsuite
- scrape-dns
- scrapy
- sctpscan
- sdn-toolkit
- sdnpwn
- seat
- second-order
- secscan
- see-surf
- shareenum
- sharesniffer
- shocker
- shortfuzzy
- shuffledns
- silk
- simple-lan-scan
- sipscan
- sipshock
- sitadel
- skipfish
- slurp-scanner
- smap-scanner
- smartphone-pentest-framework
- smbcrunch
- smbexec
- smbmap
- smbspider
- smbsr
- smod
- smtp-test
- smtp-user-enum
- smtp-vrfy
- smtptx
- smuggler
- smuggler-py
- sn00p
- sn1per
- snallygaster
- snmpattack
- snmpenum
- snmpscan
- snoopbrute
- snscan
- snyk
- spade
- sparta
- spiga
- spipscan
- sploitego
- sprayhound
- sprayingtoolkit
- sqlivulscan
- ssdp-scanner
- ssh-audit
- ssh-user-enum
- sshprank
- sshscan
- ssl-hostname-resolver
- sslcaudit
- ssllabs-scan
- sslmap
- sslscan
- sslscan2
- sslyze
- ssrfmap
- stacs
- stews
- sticky-keys-hunter
- stig-viewer
- storm-ring
- striker
- strutscan
- subbrute
- subdomainer
- subjack
- sublist3r
- subover
- subscraper
- superscan
- svn-extractor
- swarm
- synscan
- sysdig
- tachyon-scanner
- tactical-exploitation
- taipan
- takeover
- testssl.sh
- tfsec
- thc-ipv6
- thc-smartbrute
- thcrut
- tiger
- tlsenum
- tlspretense
- tlssled
- tlsx
- topera
- torcrawl
- traxss
- trivy
- typo3scan
- ubiquiti-probing
- udork
- udp-hunter
- udsim
- umap
- unicornscan
- uniscan
- unix-privesc-check
- upnp-pentest-toolkit
- upnpscan
- uptux
- urldigger
- uw-loveimap
- uw-udpscan
- uw-zone
- v3n0m
- vais
- vane
- vanguard
- vault-scanner
- vbrute
- vbscan
- vcsmap
- vhostscan
- videosnarf
- viproy-voipkit
- visql
- vsaudit
- vscan
- vsvbp
- vulmap
- vulnerabilities-spider
- vulnx
- vuls
- vulscan
- w13scan
- w3af
- wafw00f
- waldo
- wapiti
- wascan
- wcvs
- webanalyze
- webborer
- webenum
- webhunter
- webpwn3r
- webrute
- webscarab
- webshag
- websploit
- webtech
- webxploiter
- weirdaal
- whatwaf
- whitewidow
- wifiscanmap
- wig
- winfo
- witchxtool
- wnmap
- wolpertinger
- wordpresscan
- wpintel
- wpscan
- wpseku
- wpsik
- wups
- x-scan
- x8
- xcname
- xpire-crossdomain-scanner
- xsrfprobe
- xss-freak
- xsscon
- xsspy
- xsss
- xssscan
- xsstracer
- xsstrike
- xssya
- xwaf
- yaaf
- yasat
- yasuo
- yawast
- ycrawler
- yersinia
- zackattack
- zeus
- zmap
- paranoic

View File

@@ -1,444 +0,0 @@
- name: "WebApp"
description: "WebApp"
critical: false
hidden: false
selected: false
expanded: true
packages:
- 0d1n
- abuse-ssl-bypass-waf
- adfind
- adminpagefinder
- albatar
- allthevhosts
- anti-xss
- apachetomcatscanner
- arachni
- archivebox
- arjun
- asp-audit
- astra
- atlas
- atscan
- aws-extender-cli
- backcookie
- badministration
- bbqsql
- bbscan
- belati
- bfac
- bing-lfi-rfi
- bitdump
- blindelephant
- blisqy
- brakeman
- brute-force
- brutemap
- brutexss
- bsqlbf
- bsqlinjector
- burpsuite
- c5scan
- cangibrina
- cansina
- cent
- chankro
- cintruder
- cjexploiter
- clairvoyance
- cloudget
- cms-explorer
- cms-few
- cmseek
- cmsfuzz
- cmsmap
- cmsscan
- cmsscanner
- comission
- commentor
- commix
- conscan
- corscanner
- corstest
- corsy
- cpfinder
- crabstick
- crackql
- crawlic
- crlf-injector
- crlfuzz
- csrftester
- cybercrowl
- d-tect
- dalfox
- darkbing
- darkd0rk3r
- darkdump
- darkjumper
- darkmysqli
- darkscrape
- davscan
- dawnscanner
- dcrawl
- detectem
- dff-scanner
- dirb
- dirble
- dirbuster
- dirbuster-ng
- directorytraversalscan
- dirhunt
- dirscanner
- dirscraper
- dirsearch
- dirstalk
- docem
- domi-owned
- dontgo403
- doork
- dorknet
- dpscan
- droopescan
- drupal-module-enum
- drupalscan
- drupwn
- dsfs
- dsjs
- dsss
- dsstore-crawler
- dsxs
- dumb0
- easyfuzzer
- eazy
- eos
- epicwebhoneypot
- evine
- extended-ssrf-search
- eyewitness
- facebot
- facebrute
- fbht
- fdsploit
- feroxbuster
- ffuf
- fhttp
- filebuster
- filegps
- fingerprinter
- flashscanner
- flask-session-cookie-manager2
- flask-session-cookie-manager3
- flask-unsign
- flunym0us
- fockcache
- fuxploider
- gau
- ghauri
- ghost-py
- git-dumper
- gitdump
- gittools
- gobuster
- golismero
- goop-dump
- gopherus
- gospider
- gowitness
- grabber
- graphinder
- graphql-cop
- graphql-path-enum
- graphqlmap
- graphw00f
- gwtenum
- h2buster
- h2csmuggler
- h2t
- hakku
- hakrawler
- halberd
- hetty
- hookshot
- host-extract
- htcap
- http2smugl
- httpforge
- httpgrep
- httppwnly
- httpx
- hyperfox
- identywaf
- imagejs
- injectus
- interactsh-client
- inurlbr
- ipsourcebypass
- isr-form
- jaeles
- jaidam
- jast
- jboss-autopwn
- jdeserialize
- jexboss
- jira-scan
- jok3r
- jomplug
- jooforce
- joomlascan
- joomlavs
- joomscan
- jsearch
- jshell
- jsonbee
- jsparser
- jsql-injection
- jstillery
- juumla
- jwt-hack
- kadimus
- katana-pd
- keye
- kiterunner
- kolkata
- konan
- kubolt
- laf
- laudanum
- lbmap
- letmefuckit-scanner
- leviathan
- lfi-exploiter
- lfi-fuzzploit
- lfi-image-helper
- lfi-scanner
- lfi-sploiter
- lfifreak
- lfimap
- lfisuite
- liffy
- lightbulb
- linkfinder
- list-urls
- log4j-bypass
- log4j-scan
- lorsrf
- lulzbuster
- magescan
- mando.me
- mantra
- maryam
- meg
- metoscan
- monsoon
- mooscan
- morxtraversal
- mosquito
- multiinjector
- mwebfp
- nikto
- nosqli
- nosqli-user-pass-enum
- nosqlmap
- novahot
- nuclei
- okadminfinder
- onionsearch
- opendoor
- otori
- owasp-bywaf
- owtf
- pappy-proxy
- parameth
- parampampam
- paranoic
- paros
- payloadmask
- pblind
- peepingtom
- photon
- php-findsock-shell
- php-malware-finder
- php-vulnerability-hunter
- phpggc
- phpsploit
- pinkerton
- pixload
- plecost
- plown
- poly
- poracle
- pown
- ppfuzz
- ppmap
- proxenet
- pureblood
- pwndrop
- pyfiscan
- pythem
- python-arsenic
- python-jsbeautifier
- python-witnessme
- python2-jsbeautifier
- rabid
- rapidscan
- ratproxy
- rawr
- recsech
- red-hawk
- remot3d
- restler-fuzzer
- richsploit
- riwifshell
- ruler
- rustbuster
- rww-attack
- sawef
- scanqli
- scrapy
- scrying
- second-order
- secretfinder
- secscan
- see-surf
- serializationdumper
- shellinabox
- shortfuzzy
- shuffledns
- sitadel
- sitediff
- sjet
- skipfish
- smplshllctrlr
- smuggler
- smuggler-py
- snallygaster
- snare
- snuck
- sourcemapper
- spaf
- sparty
- spiga
- spike-proxy
- spipscan
- sprayingtoolkit
- sqid
- sqlbrute
- sqldict
- sqlivulscan
- sqlmap
- sqlninja
- sqlping
- sqlpowerinjector
- sqlsus
- ssrf-sheriff
- ssrfmap
- stews
- striker
- subjs
- swarm
- swftools
- taipan
- themole
- tidos-framework
- tinfoleak
- tinfoleak2
- tomcatwardeployer
- torcrawl
- tplmap
- typo3scan
- uatester
- ufonet
- uncaptcha2
- uniscan
- uppwn
- urlcrazy
- urldigger
- urlextractor
- v3n0m
- vane
- vanguard
- vbscan
- vega
- visql
- vsvbp
- vulnerabilities-spider
- vulnx
- w13scan
- w3af
- wafninja
- wafp
- wafpass
- wafw00f
- wapiti
- wascan
- waybackpack
- wcvs
- web-soul
- webacoo
- webanalyze
- webborer
- webenum
- webexploitationtool
- webhandler
- webhunter
- webkiller
- webpwn3r
- webrute
- webscarab
- webshag
- webshells
- webslayer
- webspa
- webtech
- webxploiter
- weevely
- weirdaal
- wfuzz
- whatwaf
- whatweb
- whichcdn
- whitewidow
- wig
- witchxtool
- wmat
- wordbrutepress
- wordpress-exploit-framework
- wordpresscan
- wpbf
- wpbrute-rpc
- wpbullet
- wpforce
- wpintel
- wpscan
- wpseku
- ws-attacker
- wsfuzzer
- wssip
- wuzz
- x8
- xmlrpc-bruteforcer
- xspear
- xsrfprobe
- xss-freak
- xsscon
- xsscrapy
- xsser
- xssless
- xsspy
- xsss
- xssscan
- xsssniper
- xsstrike
- xssya
- xwaf
- xxeinjector
- xxexploiter
- xxxpwn
- xxxpwn-smart
- yaaf
- yasuo
- yawast
- ycrawler
- yinjector
- ysoserial
- zaproxy