builder_peppermint_void/builder/peppermint/pmostools/peptools/kumo.py
2025-04-25 12:38:42 +00:00

353 lines
11 KiB
Python
Executable File

"""
* Author: "PepDebian(peppermintosteam@proton.me)
*
* License: SPDX-License-Identifier: GPL-3.0-or-later
*
* This is for the Kumo SSB Gui
"""
import os
import re
from urllib.parse import urljoin
from tkinter import filedialog
import sqlite3
import tkinter as tk
import requests
import ttkbootstrap as ttk
import bsconf
# setup the window
pwin = bsconf.bbstyle
pwin.resizable(False, False)
WINDOW_HEIGHT = 380
WINDOW_WIDTH = 640
pwin.title('Peppermint Kumo (SSB Manager)')
# Set the user paths used
gusr = os.environ.get('USER')
spath = "/home/" + gusr + "/.local/share/pmostools/peptools"
dpath = "/home/" + gusr + "/.local/share/applications/"
ipath = "/home/" + gusr + "/Pictures/"
# Set the window icon
pwin.tk.call('wm', 'iconphoto', pwin,
tk.PhotoImage(
file=spath + '/images/kumosm.png'))
# Set the database connection string
dcon = sqlite3.connect(spath + '/welval.db')
pcur = dcon.cursor()
# Create the table if not exists
pcur.execute(""" CREATE TABLE IF NOT EXISTS kumoapp (id integer PRIMARY
KEY AUTOINCREMENT, ssbname text, lnk text);"""
)
import os
import subprocess
def determine_browser():
"""Verifica o navegador padrão no sistema ou retorna um valor alternativo"""
try:
# Tenta detectar o navegador padrão do sistema com 'xdg-settings'
browser = subprocess.check_output(['xdg-settings', 'get', 'default-web-browser']).decode('utf-8').strip()
# Verifica se o comando foi bem-sucedido e retorna o navegador
if browser:
print(f"Navegador padrão detectado: {browser}")
return "xdg-open" # O comando 'xdg-open' serve para abrir URLs no navegador padrão
except subprocess.CalledProcessError as e:
print("Erro ao tentar detectar o navegador padrão:", e)
# Caso não consiga detectar o navegador, retorna 'xdg-open' como fallback
print("Nenhum navegador padrão detectado. Usando 'xdg-open'.")
return "xdg-open"
def download_favicon(url, output_folder=ipath, request_timeout=3):
"""
This function will try a regex to find and locate the favicon
of a website.Depending on the website it may not find the favicon.
the goals is to try and stay within the python stndard library
"""
# Send a GET request to the website
response = requests.get(url, timeout=request_timeout)
response.raise_for_status() # Raise an error for bad responses
# Use a regular expression to find the favicon URL in the HTML
match = re.search(
r'<link[^>]*?rel=["\']?icon["\']?[^>]*?href=["\'](.*?)["\']',
response.text,
re.IGNORECASE
)
if match:
favicon_url = match.group(1)
favicon_url = urljoin(url, favicon_url)
# Download the favicon
response = requests.get(favicon_url,timeout=request_timeout, stream=True)
response.raise_for_status()
if not os.path.exists(output_folder):
os.makedirs(output_folder)
filename = os.path.join(output_folder,
os.path.basename(favicon_url)
)
with open(filename, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
return filename
return None
def delete_ssb():
""" Delete the ssb that is selected """
get_name = cmbo.get()
link_address = """ DELETE FROM kumoapp WHERE ssbname = ? """
pcur.execute(link_address, (get_name,))
dcon.commit()
runaddr_value.delete('1.0', tk.END)
for dfile in os.listdir(dpath):
if dfile.startswith(get_name) and dfile.endswith('.desktop'):
del_path = os.path.join(dpath, dfile)
os.remove(del_path)
pwin.destroy()
os.system('python3 refresh.py')
def center_screen():
"""Gets the coordinates of the center of the screen"""
screen_width = pwin.winfo_screenwidth()
screen_height = pwin.winfo_screenheight()
x_cordinate = (screen_width // 2) - (WINDOW_WIDTH // 2)
y_cordinate = (screen_height // 2) - (WINDOW_HEIGHT // 2)
pwin.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}+{x_cordinate}+{y_cordinate}")
def update_ui():
"""Reorganiza os componentes para uma melhor apresentação"""
# Ajuste as posições, margens, etc., se necessário para garantir um layout mais agradável
pwin.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
def make_desktop_file():
# Obter valores das entradas
get_name = ssb_value.get("1.0", 'end-1c').strip()
get_url = urladdr_value.get("1.0", 'end-1c').strip()
get_local = cmbomenu.get()
get_icon = icon_value.get("1.0", 'end-1c').strip()
write_path = dpath + get_name + '.desktop'
# Obter a categoria reversa
selected_category_key = categories_reverse.get(get_local, 'Applications') # Defina um valor padrão
# Determinar o comando do navegador
command = determine_browser()
if not command:
print("No suitable browser found. .desktop file not created")
return
# Usar o comando de execução adequado sem o '&'
exec_command = f'xdg-open "{get_url}"'
# Definir o conteúdo do arquivo .desktop
app_content = f"""
[Desktop Entry]
Version=1.0
Name={get_name}
Exec={exec_command}
Icon={get_icon}
Categories={selected_category_key}
Type=Application
Terminal=false
"""
# Verificar se o diretório de destino existe, criar se não
folder = os.path.dirname(write_path)
if not os.path.exists(folder):
os.makedirs(folder)
# Criar e escrever no arquivo .desktop
with open(write_path, 'w') as app:
app.write(app_content)
# Tornar o arquivo executável
os.chmod(write_path, 0o755)
print(f"Desktop file created at {write_path}")
def add_new_ssb():
""" Add new ssb """
make_desktop_file()
ssb_name = ssb_value.get("1.0", 'end-1c')
ssb_address = urladdr_value.get("1.0", 'end-1c')
sql_insert = """ INSERT INTO kumoapp(ssbname,lnk) VALUES(?,?);"""
pcur.execute(sql_insert, (ssb_name, ssb_address,))
dcon.commit()
ssb_value.delete('1.0', tk.END)
urladdr_value.delete('1.0', tk.END)
pwin.destroy()
os.system('python3 ' + spath + '/refresh.py')
pwin.destroy()
os.system('python3 refresh.py')
def fill_dropdown():
""" set the combobox value """
cursor = dcon.execute('SELECT ssbname FROM kumoapp')
result = [row[0] for row in cursor.fetchall()]
return result
def fill_url_address():
""" get the url of the ssb and run the it in min"""
get_name = cmbo.get()
link_address = """ SELECT lnk FROM kumoapp WHERE ssbname = ? """
pcur.execute(link_address, (get_name,))
use_address = pcur.fetchone()
runaddr_value.delete('1.0', tk.END)
runaddr_value.insert("end-1c", use_address)
def run_url_address():
"""Run the browser with the appropriate profile and address."""
command = determine_browser()
if command:
os.system(command)
else:
print("There no suitebable browser installed!")
def select_icon():
"""
Select the icon to be used for the SSB in the system
The starting folder is the home pictures folder
"""
ssb_address = urladdr_value.get("1.0", 'end-1c')
output_filename = download_favicon(ssb_address)
initial_dir = ipath
file_path = filedialog.askopenfilename(
title="Select Icon",
initialdir=initial_dir,
filetypes=[("Icon files", "*.ico"), ("Icon files", "*.png"),
("Icon files", "*.gif"), ("Icon files", "*.ppm"),
("Icon files", "*.pgm")]
)
if file_path:
icon_value.delete(1.0, tk.END)
icon_value.insert(tk.END, file_path)
elif output_filename:
icon_value.delete(1.0, tk.END)
icon_value.insert(tk.END, output_filename)
else:
icon_value.delete(1.0, tk.END)
icon_value.insert(tk.END, "No icon selected")
### Create SSB side objects used
### Title
new_label = ttk.Label(pwin, text="Create new SSBs",
bootstyle="dark",
font=("Helvetica", 14)
)
new_label.place(x=10, y=20)
ssb_label = ttk.Label(pwin, text="Give the ssb a name:")
ssb_label.place(x=10, y=55)
ssb_value = tk.Text(pwin, height=1, width=25)
ssb_value.place(x=10, y=80)
lblcmbomenu = ttk.Label(pwin, text="Menu Location:")
lblcmbomenu.place(x=10, y=113)
categories = { 'AudioVideo' : 'AudioVideo', 'Audio':'Audio', 'Video':'Video',
'Development':'Development', 'Education':'Education',
'Game':'Game', 'Graphics':'Graphics', 'Network':'Internet',
'Office':'Office', 'Settings':'Settings','System':'System',
'Utility':'Utility'
}
categories_reverse = {value: key for key, value in categories.items()}
cmbomenu = ttk.Combobox(pwin)
cmbomenu.place(x=10, y=135)
cmbomenu['values'] = list(categories.values())
icon_default_text = 'Set the icon with the "Icon" button'
icon_value = tk.Text(pwin, height=1, width=32)
icon_value.insert(tk.END, icon_default_text)
icon_value.place(x=10, y=280)
icon_button = ttk.Button(pwin, text="Icon", width=7, cursor="hand2",
bootstyle="danger", command=select_icon
)
icon_button.place(x=90, y=324)
url_default_text = "example: https://www.example.com"
urladdr_label = ttk.Label(pwin, text="Enter the Url:")
urladdr_label.place(x=10, y=172)
urladdr_value = tk.Text(pwin, height=3, width=32)
urladdr_value.insert(tk.END, url_default_text)
urladdr_value.place(x=10, y=200)
btnsv = ttk.Button(
pwin,
text="Save",
cursor="hand2",
bootstyle="danger",
width=5,
command=add_new_ssb
)
btnsv.place(x=10, y=324)
### The Separator for the window
separator = ttk.Separator(pwin, orient='vertical')
separator.place(relx=.495, rely=0, relheight=1)
### Manage SSBs side)
manage_label = ttk.Label(pwin, text="Manage SSBs",
bootstyle="dark",
font=("Helvetica", 14)
)
manage_label.place(x=330, y=20)
lblcmbo = ttk.Label(pwin, text="Select SSB to Manage:")
lblcmbo.place(x=330, y=55)
cmbo = ttk.Combobox(pwin)
cmbo.place(x=330, y=80)
cmbo['values'] = fill_dropdown()
runaddr_label = ttk.Label(pwin, text="Url Address:")
runaddr_label.place(x=330, y=125)
runaddr_value = tk.Text(pwin, height=4, width=32)
runaddr_value.place(x=330, y=150)
btnrun = ttk.Button(
pwin,
text="Run",
cursor="hand2",
bootstyle="danger",
width=7,
command=run_url_address
)
btnrun.place(x=330, y=324)
btndelete = ttk.Button(
pwin,
text="Delete",
cursor="hand2",
bootstyle="danger",
width=7,
command=delete_ssb
)
btndelete.place(x=430, y=324)
def set_state(event):
"""
Function that managse the state of the buttons and the Url address
for the Manage SSBs section, this is an event function
"""
selected_value = cmbo.get()
if selected_value == "":
btndelete["state"] = "disabled"
btnrun["state"] = "disabled"
else:
btndelete["state"] = "normal"
btnrun["state"] = "normal"
fill_url_address()
cmbo.bind("<<ComboboxSelected>>", set_state)
set_state(None)
center_screen()
pwin.mainloop()