This commit is contained in:
admin 2024-01-09 21:33:27 +01:00
parent 5a846d328d
commit cdd0e4070d
15 changed files with 864 additions and 0 deletions

15
.gitignore vendored Normal file
View file

@ -0,0 +1,15 @@
config.json
__pycache__/
update/
build/
*.spec
*.bin
*.build
dist
data/config.json
*.dist
*.onefile-build
downloaded_files/
my_app_github/
my_app_gitlab/
data-backup/

3
build.bat Executable file
View file

@ -0,0 +1,3 @@
nuitka3 ./src/main.py --clean-cache=all --onefile --run --output-dir=./build --enable-plugin=tk-inter
:: --clean-cache=all --disable-console --windows-icon-from-ico=./data/icon.ico
pause

2
build.sh Executable file
View file

@ -0,0 +1,2 @@
nuitka3 ./src/main.py --linux-onefile-icon=./data/icon.png --onefile --output-dir=./build --run
#--disable-console --linux-icon=./data/icon.png --output-dir=./build --clean-cache=all #--include-plugin-directory=./src/ --run --disable-console --linux-icon=./data/icon.png --output-dir=./build #--clean-cache=all --recompile-c-only #--windows-icon-from-ico=./data/icon.ico --disable-console --linux-icon=./data/icon.png --onefile --output-dir=./build

34
dwnld.sh Executable file
View file

@ -0,0 +1,34 @@
#!/bin/sh
set -e
display_usage() {
echo "Downloads all of a SourceForge project's files."
echo -e "\nUsage: ./sourceforge-file-download.sh [project name]\n"
}
if [ $# -eq 0 ]
then
display_usage
exit 1
fi
project=$1
echo "Downloading $project's files"
# download all the pages on which direct download links are
# be nice, sleep a second
wget -w 1 -np -m -A download https://sourceforge.net/projects/$project/files/
# find the files (ignore "latest" link, that should be included as another URL already)
find sourceforge.net/ | sed "s#.*${project}/files/##" | grep download$ | grep -v "latest/download" | sed -e "s#^#https://master.dl.sourceforge.net/project/${project}/#" -e "s#/download#?viasf=1#" > urllist
# download each of the extracted URLs, put into $projectname/
while read url; do wget --content-disposition -x -nH --cut-dirs=1 "${url}"; done < urllist
# remove ?viasf=1 suffix
find . -name '*?viasf=1' -print0 | xargs -0 rename --verbose "?viasf=1" ""
# remove temporary files, unless you want to keep them for some reason
rm -ri sourceforge.net/
rm -i urllist

29
install-linux.sh Executable file
View file

@ -0,0 +1,29 @@
#!/bin/bash
# This script installs required dependencies on Linux
# Update package lists and install Python3
sudo apt update -y
sudo apt install python3 -y
# Install Python3 pip
sudo apt install python3-pip -y
# Install GTK4 package
sudo apt install libgtk-4-dev -y
# Install PatchELF for Nuitka (if needed)
sudo apt install patchelf -y
# Install Nuitka
pip3 install nuitka
# Install additional Python packages
pip3 install requests
sudo apt install libgirepository1.0-dev -y
sudo apt install python3-cairo-dev -y
pip3 install PyGObject # Install PyGObject for Gtk support
pip3 install pillow # Install Pillow for image manipulation
pip3 install setuptools # Install setuptools for packaging
# Install ccache for faster re-compiling
sudo apt install ccache -y

13
install-windows.txt Executable file
View file

@ -0,0 +1,13 @@
# install msys2
# update msys2
# install python && pip in msys2
# install GTK4 according to GTK website
# install nuitka (in msys2)
# add python (usually: C:\msys2\bin) to system variable PATH
# restart computer, and if done well you should be able to build and run this app

3
run.bat Normal file
View file

@ -0,0 +1,3 @@
python3 ./src/main.py
:: --clean-cache=all --disable-console --windows-icon-from-ico=./data/icon.ico
pause

1
run.sh Executable file
View file

@ -0,0 +1 @@
python3 ./src/main.py

View file

@ -0,0 +1,29 @@
import requests
from tqdm import tqdm
# not exactly ideal solution
def download_from_sourceforge(api_url, file_path):
response = requests.get(api_url, stream=True)
if response.status_code == 200:
total_size = int(response.headers.get('content-length', 0))
block_size = 1024 # 1 KB
progress_bar = tqdm(total=total_size, unit='B', unit_scale=True)
with open(file_path, 'wb') as file:
for data in response.iter_content(block_size):
progress_bar.update(len(data))
file.write(data)
progress_bar.close()
print("Download completed successfully.")
else:
print(f"Failed to download. Status code: {response.status_code}")
# Example usage with the provided link
sourceforge_api_url = "https://downloads.sourceforge.net/project/sevenzip/7-Zip/19.00/7z1900-x64.exe"
download_path = "7z1900-x64.exe"
download_from_sourceforge(sourceforge_api_url, download_path)

80
src/download_github.py Normal file
View file

@ -0,0 +1,80 @@
import os
import requests
from tqdm import tqdm
def fetch_release_version(url):
try:
response = requests.get(url)
response.raise_for_status()
return response.json()['tag_name']
except requests.exceptions.RequestException as e:
print(f"Error fetching release version: {str(e)}")
return None
def download_from_github(url, destination, progress_bar, version):
# Get the latest release information
api_url = f"{url}/releases/latest"
response = requests.get(api_url)
response.raise_for_status()
release_info = response.json()
latest_version = release_info["tag_name"]
# Check if the latest version is different from the current version
if latest_version != version:
# Get the asset URL for the first asset in the release (you may modify this based on your needs)
asset_url = release_info["assets"][0]["browser_download_url"]
# Download the asset with a progress bar
response = requests.get(asset_url, stream=True)
response.raise_for_status()
# Calculate the total file size for the progress bar
total_size = int(response.headers.get('content-length', 0))
# Create the destination directory if it doesn't exist
os.makedirs(destination, exist_ok=True)
# Define the file path for the downloaded asset
file_path = os.path.join(destination, os.path.basename(asset_url))
with open(file_path, 'wb') as file, tqdm(
desc="Downloading",
total=total_size,
unit="B",
unit_scale=True,
unit_divisor=1024,
disable=not progress_bar,
) as bar:
for data in response.iter_content(chunk_size=1024):
bar.update(len(data))
file.write(data)
print("Download complete.")
return latest_version
else:
print("You already have the latest version.")
return version
def download_from_url(url, destination, progress_bar, version):
if "github.com" in url:
return download_from_github(url, destination, progress_bar, version)
elif "sourceforge.net" in url:
return download_from_sourceforge(url, destination, progress_bar)
elif "gitlab.com" in url:
return download_from_gitlab(url, destination, progress_bar)
elif "gitea.com" in url:
return download_from_gitea(url, destination, progress_bar)
else:
print("Unsupported platform")
return None
#######################
# # Example usage:
# github_url = "https://api.github.com/repos/emoacht/Monitorian"
# destination_folder = "./downloaded_files"
# current_version = "v1.0.0"
# new_version = download_from_github(github_url, destination_folder, True, current_version)
# print(f"Updated to version: {new_version}")

119
src/download_gitlab.py Normal file
View file

@ -0,0 +1,119 @@
import requests
from tqdm import tqdm
import os
import zipfile
def download_release_from_gitlab(api_url, project_id, token, destination, progress_bar, version):
# Get the latest release information
response = requests.get(f"{api_url}/projects/{project_id}/releases", headers={"PRIVATE-TOKEN": token})
response.raise_for_status()
releases = response.json()
# Check if there are any releases
if not releases:
return None
# Assuming releases are sorted by creation date, so the latest release is the first one
latest_release = releases[0]
latest_version = latest_release["tag_name"]
# Check if the latest version is different from the current version
if latest_version != version:
# Get the asset URL for the first asset in the release (you may modify this based on your needs)
asset_url = latest_release["assets"]["sources"][0]["url"]
# Download the asset with a progress bar
response = requests.get(asset_url, stream=True, headers={"PRIVATE-TOKEN": token})
response.raise_for_status()
# Calculate the total file size for the progress bar
total_size = int(response.headers.get('content-length', 0))
# Create the destination directory if it doesn't exist
os.makedirs(destination, exist_ok=True)
# Define the file path for the downloaded asset
file_path = os.path.join(destination, os.path.basename(asset_url))
with open(file_path, 'wb') as file, tqdm(
desc="Downloading",
total=total_size,
unit="B",
unit_scale=True,
unit_divisor=1024,
disable=not progress_bar,
) as bar:
for data in response.iter_content(chunk_size=1024):
bar.update(len(data))
file.write(data)
print("Download complete.")
return latest_version
else:
print("You already have the latest version.")
return version
def download_source_from_gitlab(api_url, project_id, token, destination, progress_bar):
# Construct the source code repository URL based on the project ID
repository_url = f"{api_url}/projects/{project_id}/repository/archive.zip"
# Download the source code as a ZIP file
response = requests.get(repository_url, stream=True, headers={"PRIVATE-TOKEN": token})
response.raise_for_status()
# Create the destination directory if it doesn't exist
os.makedirs(destination, exist_ok=True)
# Define the file path for the downloaded ZIP file
zip_file_path = os.path.join(destination, "source_code.zip")
with open(zip_file_path, 'wb') as file, tqdm(
desc="Downloading Source Code",
unit="B",
unit_scale=True,
unit_divisor=1024,
disable=not progress_bar,
) as bar:
for data in response.iter_content(chunk_size=1024):
bar.update(len(data))
file.write(data)
print("Download complete.")
# Extract the ZIP file
extract_folder = os.path.join(destination, "source_code")
with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:
zip_ref.extractall(extract_folder)
# Remove the ZIP file
os.remove(zip_file_path)
return extract_folder
def download_and_update(api_url, project_id, private_token, destination_folder, progress_bar, current_version):
try:
new_version = download_release_from_gitlab(api_url, project_id, private_token, destination_folder, progress_bar, current_version)
if new_version:
print(f"Updated to version: {new_version}")
else:
print("No releases found. Downloading source code instead.")
source_code_folder = download_source_from_gitlab(api_url, project_id, private_token, destination_folder, progress_bar)
print(f"Source code downloaded to: {source_code_folder}")
except requests.exceptions.HTTPError as e:
if e.response.status_code == 404:
print("No releases found. Downloading source code instead.")
source_code_folder = download_source_from_gitlab(api_url, project_id, private_token, destination_folder, progress_bar)
print(f"Source code downloaded to: {source_code_folder}")
else:
raise # Re-raise the exception if it's not a 404 error
# #######################################
# # Example usage:
# gitlab_api_url = "https://gitlab.com/api/v4"
# project_id = 5774889 # Use the project ID directly
# private_token = "" # No private token needed for public projects
# destination_folder = "./downloaded_files"
# current_version = "v1.0.0"
# download_and_update(gitlab_api_url, project_id, private_token, destination_folder, True, current_version)

71
src/download_main.py Normal file
View file

@ -0,0 +1,71 @@
import os
from tqdm import tqdm # You might need to install this package using pip if not already installed
import json
import json_main
import download_gitlab
import download_github
data_location = "./data/"
# Ensure that the directory structure exists, once again
if not os.path.exists(data_location):
os.makedirs(data_location)
# Check if config.json exists and create it with default values if not
if not os.path.isfile(data_location+"config.json"):
default_data = {
"first_run": "false",
"packages": []
}
with open(data_location+"config.json", "w") as json_file:
json.dump(default_data, json_file, indent=4)
# Placeholder functions for SourceForge and Gitea
def download_from_sourceforge(url, destination, progress_bar, version):
# Placeholder function for downloading from SourceForge
print("Sourceforge not supported yet")
def download_from_gitea(api_url, project_id, token, destination, progress_bar, version):
# Placeholder function for downloading from Gitea
print("Gita not supported, yet")
# Function to install all packages
def install_all_packages(progress_bar, progress_label):
try:
with open(data_location+"config.json", 'r') as file:
data = json.load(file)
packages = data.get("packages", [])
total_packages = len(packages)
for index, package in enumerate(packages, start=1):
app_name, app_data = package.popitem()
source_info = app_data.get("source", {})
source_type = source_info.get("source_type", "")
version = app_data.get("version", "")
try:
progress_label.set_text(f"Downloading {app_name}")
progress_value = index / total_packages/2
progress_bar.set_fraction(progress_value)
if source_type == "github":
download_github.download_from_github(source_info["github_url"], app_name, tqdm, version)
elif source_type == "gitlab":
download_gitlab.download_and_update(source_info["gitlab_api_url"], source_info["project_id"],
source_info["private_token"], app_name, tqdm, version)
# Add other source types as needed
else:
progress_label.set_text(f"Unsupported source type for {app_name}: {source_type}")
print(f"Unsupported source type for {app_name}: {source_type}")
except Exception as e:
progress_label.set_text(f"Error processing {app_name}: {e}")
print(f"Error processing {app_name}: {e}")
except FileNotFoundError:
progress_label.set_text(f"Config file not found.")
print("Config file not found.")
# Check if the script is executed directly
if __name__ == "__main__":
install_all_packages()

212
src/gui_main.py Normal file
View file

@ -0,0 +1,212 @@
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, Gio, GLib, GdkPixbuf
import threading
import download_main
number_of_tabs = 4
class InstallerGUI:
def __init__(self):
self.app = Gtk.Application(application_id="org.example.customizableapp",
flags=Gio.ApplicationFlags.FLAGS_NONE)
self.app.connect("activate", self.activate)
def run(self):
self.app.run()
def activate(self, app):
app_window = MainWindow(application=app)
app_window.present()
class UpdaterGUI(Gtk.Box):
def __init__(self):
super().__init__(orientation=Gtk.Orientation.VERTICAL)
# Create a progress bar and a label
self.progress_bar = Gtk.ProgressBar()
self.progress_label = Gtk.Label()
# # Set up the layout
# logo_path = "./data/icon.png"
# logo_pixbuf = GdkPixbuf.Pixbuf.new_from_file(logo_path)
# logo_image = Gtk.Image.new_from_pixbuf(logo_pixbuf)
# self.append(logo_image)
self.append(self.progress_bar)
self.append(self.progress_label)
# Connect to the "realize" signal to run the function when the widget becomes visible
self.connect("realize", self.on_realize)
def on_realize(self, widget):
# Run the install_all_packages function in a separate thread when the widget becomes visible
threading.Thread(target=self.run_installation).start()
def run_installation(self):
# Pass the progress bar and label to the install_all_packages function
download_main.install_all_packages(self.progress_bar, self.progress_label)
# Glib.idle_add() ?
class CustomizationTab(Gtk.Box):
def __init__(self, button_box):
super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.create_ui(button_box)
def create_ui(self, button_box):
# Add elements for customization tab in the future
# Add back and next buttons at the bottom
self.bottom_buttons(button_box)
def bottom_buttons(self, button_box):
self.append(Gtk.Box(hexpand=True, vexpand=True)) # Expandable empty box to push buttons to the bottom
self.append(button_box)
class MainWindow(Gtk.ApplicationWindow):
def __init__(self, application, **kwargs):
super().__init__(application=application, **kwargs)
# # Set Adwaita theme
# settings = Gtk.Settings.get_default()
# settings.set_property("gtk-application-prefer-dark-theme", True)
# settings.set_property("gtk-theme-name", "Adwaita")
self.set_default_size(600, 400)
self.set_title("Spitfire Installer Nightly")
self.child_names = ["Main", "Customization", "Tab 2", "Tab 3", "Tab 4","UpdaterGUI"]
self.stack = Gtk.Stack(transition_type=Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
self.stack.set_transition_duration(1000) # Set the duration of the transition in milliseconds
# Create a HeaderBar
header_bar = Gtk.HeaderBar()
header_bar.set_show_title_buttons(True)
self.set_titlebar(header_bar)
# First tab
self.add_first_tab()
# Second tab (Customization tab)
button_box = self.create_button_box(0)
self.customization_tab = CustomizationTab(button_box)
self.stack.add_titled(self.customization_tab, "Customization", "Customization")
# Third to Fifth tabs (empty for now)
for i in range(3):
self.add_tab(i + 1)
# Last tab (Installer tab)
self.updater_tab = UpdaterGUI()
self.stack.add_titled(self.updater_tab, "UpdaterGUI", "UpdaterGUI")
self.set_child(self.stack)
self.show()
def create_button_box(self, current_tab):
button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
left_button = Gtk.Button(label="Back")
left_button.connect("clicked", self.on_back_clicked)
right_button = Gtk.Button(label="Next")
right_button.connect("clicked", self.on_next_clicked)
label = Gtk.Label(label=f"{current_tab + 1} / {number_of_tabs}") # Display current tab number
label.set_halign(Gtk.Align.CENTER) # Center-align the label
# Add an empty box to act as a flexible space
button_box.append(Gtk.Box(hexpand=True))
# Add left button, label, and right button to the button box
button_box.append(left_button)
button_box.append(label)
button_box.append(right_button)
return button_box
def add_first_tab(self):
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.stack.add_titled(box, "Main", "Main")
label = Gtk.Label(label=f"\nThis is an experimental (Nightly) build.")
box.append(label)
empty_space = Gtk.Box(vexpand=True)
box.append(empty_space) # Expandable empty box to push buttons to the bottom
skip_button = Gtk.Button(label="Install")
skip_button.connect("clicked", self.on_skip_clicked)
box.append(skip_button) # Use append to add child widgets
customize_button = Gtk.Button(label="Customize")
customize_button.connect("clicked", self.on_next_clicked)
box.append(customize_button) # Use append to add child widget
empty_space = Gtk.Box(vexpand=True)
box.append(empty_space) # Expandable empty box to push buttons to the bottom
def add_tab(self, current_tab):
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.stack.add_titled(box, f"Tab {current_tab + 1}", f"Tab {current_tab + 1}")
# Add back and next buttons at the bottom
self.bottom_buttons(box, current_tab)
def bottom_buttons(self, box, current_tab):
button_box = self.create_button_box(current_tab)
box.append(Gtk.Box(hexpand=True, vexpand=True)) # Expandable empty box to push buttons to the bottom
box.append(button_box)
def on_skip_clicked(self, button):
current_page_name = "UpdaterGUI"
current_page_index = self.child_names.index(current_page_name)
next_page_index = number_of_tabs+1
if next_page_index < len(self.child_names):
next_page_name = self.child_names[next_page_index]
next_page = self.stack.get_child_by_name(next_page_name)
self.stack.set_visible_child(next_page)
def on_next_clicked(self, button):
current_page_name = self.stack.get_visible_child_name()
current_page_index = self.child_names.index(current_page_name)
next_page_index = current_page_index + 1
if next_page_index < len(self.child_names):
next_page_name = self.child_names[next_page_index]
next_page = self.stack.get_child_by_name(next_page_name)
self.stack.set_visible_child(next_page)
def on_back_clicked(self, button):
current_page_name = self.stack.get_visible_child_name()
current_page_index = self.child_names.index(current_page_name)
prev_page_index = current_page_index - 1
if prev_page_index >= 0:
prev_page_name = self.child_names[prev_page_index]
prev_page = self.stack.get_child_by_name(prev_page_name)
self.stack.set_visible_child(prev_page)
def update_logo_and_title(self, page_name):
# Update title label text
self.title_label.set_label(page_name)
# Update logo image based on the page name
logo_path = f"./data/{page_name.lower()}_icon.png" # Assuming you have different icons for each page
logo_pixbuf = GdkPixbuf.Pixbuf.new_from_file(logo_path)
self.logo_and_title_box.get_children()[0].set_from_pixbuf(logo_pixbuf)
# Make the MainWindow class callable as a function
def run_installer():
app = Gtk.Application(application_id="org.example.customizableapp",
flags=Gio.ApplicationFlags.FLAGS_NONE)
app.connect("activate", lambda app: MainWindow(application=app))
app.run()
# # Run the installer when this script is executed directly
# if __name__ == "__main__":
# run_installer()

110
src/json_main.py Normal file
View file

@ -0,0 +1,110 @@
import json
import os
data_location = "./data/config.json"
def save_first_run(var):
with open(data_location, "r") as json_file:
data = json.load(json_file)
data["first_run"] = var
with open(data_location, "w") as json_file:
json.dump(data, json_file, indent=4)
def get_first_run():
with open(data_location, "r") as json_file:
data = json.load(json_file)
return data["first_run"]
# Save variable app to .json file with version, source, and source_type as variables
def save_package(version, app, source_type, source_info, package_type):
try:
with open(data_location, 'r') as file:
data = json.load(file)
except FileNotFoundError:
# If the file doesn't exist, create an empty dictionary
data = {"packages": []}
# Create or update the category for the given app
app_data = {
"version": version,
"source": {
"source_type": source_type,
**source_info
},
"state": "not installed",
"type": package_type
}
data["packages"].append({app: app_data})
with open(data_location, 'w') as file:
json.dump(data, file, indent=2)
# This function will get the package information for the given app.
# If the app is not in .json, return an empty dictionary.
def get_package(app):
try:
with open(data_location, 'r') as file:
data = json.load(file)
for package in data.get("packages", []):
if app in package:
return package[app]
except FileNotFoundError:
return {}
# ######################
# # save package test
# # Example usage:
# # Define source information for GitHub
# github_source_info = {
# "github_url": "https://api.github.com/repos/emoacht/Monitorian"
# }
# # Define source information for GitLab
# gitlab_source_info = {
# "gitlab_api_url": "https://gitlab.com/api/v4",
# "project_id": 5774889,
# "private_token": "" # No private token needed for public projects
# }
# # Define source information for Gitea
# gitea_source_info = {
# # Add gitea-specific information here
# }
# # Define source information for SourceForge
# sourceforge_source_info = {
# # Add sourceforge-specific information here
# }
# # Save package information for GitHub
# save_package("1.0", "my_app_github", "github", github_source_info, "addon")
# # Save package information for GitLab
# save_package("1.0", "my_app_gitlab", "gitlab", gitlab_source_info, "skin")
# # Save package information for Gitea
# save_package("1.0", "my_app_gitea", "gitea", gitea_source_info, "config")
# # Save package information for SourceForge
# save_package("1.0", "my_app_sourceforge", "sourceforge", sourceforge_source_info, "panel")
# #########################
# # get package test
# # Get package information for GitHub
# package_info = get_package("my_app_github")
# # Example of accessing package information
# if package_info:
# print(f"Your package version is: {package_info['version']}")
# print(f"Your package source type is: {package_info['source']['source_type']}")
# print(f"Your package state is: {package_info['state']}")
# print(f"Your package type is: {package_info['type']}")
# else:
# print("Package not found.")

143
src/main.py Normal file
View file

@ -0,0 +1,143 @@
import sys
if sys.platform == 'win32':
import os
import tkinter as tk
from tkinter import ttk
from urllib.request import urlopen
import zipfile
import certifi
import ssl
import subprocess
import tempfile
def get_temp_folder():
# Get the current user's temporary directory
temp_dir = tempfile.gettempdir()
# Create a subdirectory inside the temporary directory
user_temp_folder = os.path.join(temp_dir, 'my_temp_folder')
# Create the directory if it doesn't exist
if not os.path.exists(user_temp_folder):
os.makedirs(user_temp_folder)
return user_temp_folder
def download_file(url, destination, progress_callback=None):
context = ssl.create_default_context(cafile=certifi.where())
with urlopen(url, context=context) as response, open(destination, 'wb') as out_file:
total_size = int(response.headers.get('content-length', 0))
block_size = 1024
current_size = 0
while True:
buffer = response.read(block_size)
if not buffer:
break
out_file.write(buffer)
current_size += len(buffer)
if progress_callback:
progress_callback(current_size, total_size)
def extract_zip(zip_file, extract_path):
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
zip_ref.extractall(extract_path)
def download_gtk_dlls(download_path, dll_url, dll_files, progress_callback=None):
for dll_file in dll_files:
file_url = dll_url + dll_file
# Check if the file already exists, if not, download it
if not os.path.exists(os.path.join(download_path, dll_file)):
download_file(file_url, os.path.join(download_path, dll_file), progress_callback)
# Check if the downloaded file is a zip file, extract it, and remove the zip file
if dll_file.endswith('.zip'):
extract_path = os.path.join(download_path, dll_file.replace('.zip', ''))
extract_zip(os.path.join(download_path, dll_file), extract_path)
os.remove(os.path.join(download_path, dll_file))
def set_path_variable(download_path):
current = subprocess.run("echo %Path%", stdout=subprocess.PIPE, shell=True, text=True)
output_string = str(current.stdout).strip() + ';' + download_path
# Split the output_string into individual elements
elements = output_string.split(';')
# Remove duplicates
unique_elements = list(set(elements))
# Join the unique elements back together
output_string_unique = ';'.join(unique_elements)
# Refresh the system environment variables
subprocess.run("SETX Path " + output_string_unique, shell=True)
print(f"Added PATH: {output_string_unique}")
def main():
# Skips entier program if is a different system than windows
if sys.platform != 'win32':
from gui_main import run_installer
run_installer()
return
# Replace this with the desired download path
download_path = get_temp_folder()
dll_url = 'https://downloads.sourceforge.net/project/spitfire-browser/nightly/components/GTK4/'
# Check if all required files are already present
dll_files = [
'libs.zip'
# Add more files as needed
]
all_files_exist = all(os.path.exists(os.path.join(download_path, filename)) for filename in dll_files)
if not all_files_exist:
# Create a simple GUI window if files are not present
root = tk.Tk()
root.title("Preparing for first start")
root.geometry("300x100")
progress_var = tk.DoubleVar()
progress = ttk.Progressbar(root, variable=progress_var, length=200)
progress.grid(row=0, column=0, padx=20, pady=20)
def update_progress_bar(current_size, total_size):
progress_value = (current_size / total_size) * 100
progress_var.set(progress_value)
root.update_idletasks()
def start_download():
# Download GTK4 DLLs if they are not already present
download_gtk_dlls(download_path, dll_url, dll_files, update_progress_bar)
# Set PATH variable and refresh environment variables
if sys.platform == 'win32':
set_path_variable(download_path)
# Destroy the GUI window
root.destroy()
# Run your main application function
from gui_main import run_installer
run_installer()
# Schedule the start_download function to run after 100 milliseconds
root.after(100, start_download)
# Start the Tkinter event loop
root.mainloop()
else:
# Run installer directly if all files are present
from gui_main import run_installer
run_installer()
if __name__ == "__main__":
main()