mirror of
https://github.com/Snigdha-OS/snigdhaos-blackbox.git
synced 2025-09-21 03:55:05 +02:00
⏳ @eshanized updated the repository!!!
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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)
|
@@ -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
|
@@ -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")
|
@@ -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
@@ -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 |
@@ -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"
|
@@ -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()
|
@@ -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 ##########
|
@@ -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)
|
@@ -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)
|
@@ -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()
|
@@ -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)
|
@@ -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)
|
@@ -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()
|
@@ -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()
|
@@ -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
|
@@ -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()
|
@@ -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()
|
@@ -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
|
@@ -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
|
@@ -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
|
Reference in New Issue
Block a user