added permissions check

This commit is contained in:
Faraphel 2022-06-08 14:39:43 +02:00
parent 2f7f0ad5bf
commit 8d6141703b
9 changed files with 150 additions and 31 deletions

View file

@ -1,6 +1,10 @@
{
"name": "English",
"translation": {
"INSTALLER_TITLE": "MKWF-Install"
"INSTALLER_TITLE": "MKWF-Install",
"LANGUAGE_SELECTION": "Language",
"TRACK_CONFIGURATION": "Track Configuration",
"ADVANCED_CONFIGURATION": "Advanced",
"HELP": "Help"
}
}

View file

@ -1,6 +1,10 @@
{
"name": "Français",
"translation": {
"INSTALLER_TITLE": "MKWF-Install",
"LANGUAGE_SELECTION": "Langue",
"TRACK_CONFIGURATION": "Configuration des courses",
"ADVANCED_CONFIGURATION": "Avancée",
"HELP": "Aide"
}
}

View file

@ -1,3 +1,8 @@
from source.gui import install
import sys
install.Window().mainloop()
# this allows every variable to be accessible from other files, useful for the plugins
self = sys.modules[__name__]
self.window = install.Window()
self.window.run()

View file

@ -1,10 +1,22 @@
from source import event
import tkinter
import sys
@event.on("source.gui.install.Window.__init__")
def test_button(master):
tkinter.Button(master, text="test des plugins", command=lambda: print("test")).grid(
@event.on("source.gui.install.Window.run_after")
def test_button():
"""
Test function for the plugins
:return:
"""
# get the main window from the main module
window = sys.modules["__main__"].window
# get the install button from the main window
window.button_install.config(text="installation plugins")
# add a custom button on the main window
tkinter.Button(window, text="test des plugins", command=lambda: print("test")).grid(
row=10, column=1, sticky="nsew"
)
print("I have been called")
)

View file

@ -1,6 +1,6 @@
from cx_Freeze import setup, Executable
import sys
import json
import source
include_files = [
"./LICENSE",
@ -25,7 +25,7 @@ options = {
setup(
options=options,
name='MKWF-Install',
version="0.12",
version=".".join(source.__version__),
url='https://github.com/Faraphel/MKWF-Install',
license='Apache-2.0',
author='Faraphel',

View file

@ -0,0 +1,12 @@
__version__ = (0, 12, 0)
__author__ = 'Faraphel'
discord_url = "https://discord.gg/HEYW5v8ZCd"
github_wiki_url = "https://github.com/Faraphel/MKWF-Install/wiki/help"
Ko = 1_000
Mo = 1_000 * Ko
Go = 1_000 * Mo
minimum_space_available = 15*Go

View file

@ -2,11 +2,11 @@ from types import FunctionType
from pathlib import Path
import sys
# using this self variable allow us to keep the events in the whole module
self = sys.modules[__name__]
self.events = {}
# register the function to the event
def on(event_name: str):
"""
Register the function to be called when the event is called.
@ -23,7 +23,6 @@ def on(event_name: str):
return decorator
# register all the events at the end of the function
def register(func: FunctionType):
"""
Register the function as an event.
@ -39,7 +38,6 @@ def register(func: FunctionType):
return wrapper
# call all the events of the event_name
def call_event(event_name: str, *args, **kwargs) -> None:
"""
Call all the events associated with the event_name.
@ -47,9 +45,13 @@ def call_event(event_name: str, *args, **kwargs) -> None:
:return:
"""
for func in self.events.get(event_name, []):
func(*args, **kwargs)
func()
# execute all scripts in the ./plugins/ directory that don't start with an underscore
for file in Path("./plugins/").rglob("[!_]*.py"):
exec(file.read_text(encoding="utf8"), globals())
def initialise_plugins() -> None:
"""
Execute all the scripts in the ./plugins/ directory that don't start with an underscore.
:return:
"""
for file in Path("./plugins/").rglob("[!_]*.py"):
exec(file.read_text(encoding="utf8"), globals())

View file

@ -1,16 +1,20 @@
import shutil
import tkinter
from pathlib import Path
import json
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox
import webbrowser
from source.translation import translate as _
from source import event
from source import *
import os
# Main window for the installer
class Window(tkinter.Tk):
@event.register
def __init__(self):
super().__init__()
@ -38,6 +42,22 @@ class Window(tkinter.Tk):
self.progress_bar = ProgressBar(self)
self.progress_bar.grid(row=5, column=1, sticky="nsew")
def run(self) -> None:
"""
Run the installer
"""
event.initialise_plugins()
self.after(0, self.run_after)
self.mainloop()
@event.register
def run_after(self) -> None:
"""
Run after the installer has been initialised, can be used to add plugins
:return:
"""
return None
# Menu bar
class Menu(tkinter.Menu):
@ -54,7 +74,7 @@ class Menu(tkinter.Menu):
def __init__(self, master: tkinter.Menu):
super().__init__(master, tearoff=False)
master.add_cascade(label="Language", menu=self)
master.add_cascade(label=_("LANGUAGE_SELECTION"), menu=self)
for file in Path("./assets/language/").iterdir():
self.add_command(label=json.loads(file.read_text(encoding="utf8"))["name"])
@ -64,7 +84,7 @@ class Menu(tkinter.Menu):
def __init__(self, master: tkinter.Menu):
super().__init__(master, tearoff=False)
master.add_cascade(label="Track Configuration", menu=self)
master.add_cascade(label=_("TRACK_CONFIGURATION"), menu=self)
self.add_command(label="Change configuration")
# Advanced menu
@ -72,7 +92,7 @@ class Menu(tkinter.Menu):
def __init__(self, master: tkinter.Menu):
super().__init__(master, tearoff=False)
master.add_cascade(label="Advanced", menu=self)
master.add_cascade(label=_("ADVANCED_CONFIGURATION"), menu=self)
self.add_command(label="Debug mode")
# Help menu
@ -81,8 +101,8 @@ class Menu(tkinter.Menu):
super().__init__(master, tearoff=False)
master.add_cascade(label="Help", menu=self)
self.add_command(label="Discord")
self.add_command(label="Github Wiki")
self.add_command(label="Discord", command=lambda: webbrowser.open(discord_url))
self.add_command(label="Github Wiki", command=lambda: webbrowser.open(github_wiki_url))
# Select game frame
@ -93,7 +113,35 @@ class SourceGame(ttk.LabelFrame):
self.entry = ttk.Entry(self, width=50)
self.entry.grid(row=1, column=1, sticky="nsew")
ttk.Button(self, text="...", width=2).grid(row=1, column=2, sticky="nsew")
self.button = ttk.Button(self, text="...", width=2, command=self.select)
self.button.grid(row=1, column=2, sticky="nsew")
def select(self) -> None:
"""
Select the source game
:return:
"""
path = Path(tkinter.filedialog.askopenfilename(
title=_("SELECT_SOURCE_GAME"),
filetypes=[(_("WII GAMES"), "*.iso *.wbfs *.dol")],
))
# if the user didn't select any file, return None
if not path.exists():
messagebox.showerror(_("ERROR"), _("ERROR_INVALID_SOURCE_GAME"))
return
self.set_path(path)
def set_path(self, path: Path) -> None:
"""
Set the source game path
:param path:
:return:
"""
self.entry.delete(0, tkinter.END)
self.entry.insert(0, str(path.absolute()))
self.master.destination_game.set_path(path.parent / "MKWF.iso")
# Select game destination frame
@ -104,7 +152,29 @@ class DestinationGame(ttk.LabelFrame):
self.entry = ttk.Entry(self, width=50)
self.entry.grid(row=1, column=1, sticky="nsew")
ttk.Button(self, text="...", width=2).grid(row=1, column=2, sticky="nsew")
self.button = ttk.Button(self, text="...", width=2, command=self.select)
self.button.grid(row=1, column=2, sticky="nsew")
def select(self) -> None:
"""
Select the source game
:return:
"""
path = Path(tkinter.filedialog.asksaveasfilename(
title=_("SELECT_DESTINATION_GAME"),
filetypes=[(_("WII GAMES"), "*.iso *.wbfs *.dol")],
))
path.parent.mkdir(mode=0o777, parents=True, exist_ok=True)
self.set_path(path)
def set_path(self, path: Path):
if not os.access(path.parent, os.W_OK):
messagebox.showwarning(_("WARNING"), _("WARNING_DESTINATION_GAME_NOT_WRITABLE"))
self.entry.delete(0, tkinter.END)
self.entry.insert(0, str(path.absolute()))
# Install button
@ -113,18 +183,23 @@ class ButtonInstall(ttk.Button):
super().__init__(master, text="Install", command=self.install)
def install(self):
...
# get space remaining on the C: drive
if shutil.disk_usage(".").free < minimum_space_available:
if not messagebox.askokcancel(_("WARNING"), _("WARNING_NOT_ENOUGH_SPACE_CONTINUE")): return
# Progress bar
class ProgressBar(ttk.Frame):
class ProgressBar(ttk.LabelFrame):
def __init__(self, master: tkinter.Tk):
super().__init__(master)
self.progress_bar = ttk.Progressbar(self)
# make the element fill the whole frame
self.columnconfigure(1, weight=1)
self.progress_bar = ttk.Progressbar(self, orient="horizontal")
self.progress_bar.grid(row=1, column=1, sticky="nsew")
self.description = tkinter.Label(self, text="test")
self.description = ttk.Label(self, text="no process running", anchor="center", font=("TkDefaultFont", 10))
self.description.grid(row=2, column=1, sticky="nsew")

View file

@ -5,5 +5,10 @@ from pathlib import Path
language_data = json.loads(Path("./assets/language/en.json").read_text(encoding="utf8"))
def translate(*text):
def translate(*text) -> str:
"""
Translate a text to the loaded language.
:param text: list of text to translate
:return: translated text
"""
return "".join([language_data["translation"].get(word, word) for word in text])