origin commit(完成installer)

This commit is contained in:
cxykevin 2024-05-03 09:08:46 +08:00
parent 1208fec3e1
commit 52d28f42d2
17 changed files with 893 additions and 0 deletions

107
.gitignore vendored Normal file
View File

@ -0,0 +1,107 @@
# download files
debug_utils
software
################# python config ##################
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
.idea/
# celery beat schedule file
celerybeat-schedule
workspace.xml
# SageMath parsed files
*.sage.py
.idea/workspace.xml
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/

15
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python 调试",
"type": "debugpy",
"request": "launch",
"program": "main.py",
"console": "integratedTerminal"
}
]
}

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"python.analysis.typeCheckingMode": "off",
"python.analysis.autoImportCompletions": true
}

21
lang/zh_cn.toml Normal file
View File

@ -0,0 +1,21 @@
UnsupportedSystem = "当前操作系统不受支持"
PermissionDeniedLinux = "在 linux 操作系统系统下,请使用 root 权限进行安装"
PermissionDeniedWin = "权限不足,请以管理员身份运行此程序"
InstallWelcome = "欢迎安装 PEInjector"
InstallInfo = "PEinjector 是增强 WindowsPE 的一个工具和平台"
DownloadInstallTitle = "下载必要文件"
DownloadInstall = "在开始之前,我们需要下载一些依赖文件\n如果您的网络状况不佳请手动下载 peinjector 和 ventoy 并解压到 software 文件夹"
StartInstall = "开始安装"
InstallVtoy = "安装 Ventoy"
InstallVtoyTitle = "安装 Ventoy"
InstallVtoyInfo = "请在打开的 ventoy 安装程序手动完成安装\n若安装完毕请点击 “扫描” 按钮并选择您安装完毕的U盘\n若您找不到您的U盘请尝试点击 “显示所有设备”\n如果你在使用 arm 架构的设备或软件无法打开,请手动运行以下程序:\n Windows: software\\ventoy\\altexe\\你的架构对应程序.exe\n Linux: software/ventoy/altexe/你的架构对应程序\n注请确保磁盘已经挂载。本版本ventoy已精简与原版兼容"
ScanVtoy = "扫描"
RestartVtoy = "重启安装程序"
ChooseVtoyDevice = "选择设备"
ShowAllDevices = "显示所有设备"
InstallIjTitle = "安装 PEinjector"
InstallIjInfo = "PEinjector主程序正在安装中请稍等"
FinishInstall = "完成安装"
InstallFinishTitle = "安装已完成"
InstallFinishInfo = "PEinjector已经安装到您的设备\n点击下方按钮关闭程序并重新启动以管理 PEinjector"
InstallFinishBtn = "关闭"

64
lib/downloader.py Normal file
View File

@ -0,0 +1,64 @@
import time
import os
import shutil
import requests
import py7zr
from threading import Thread
from logger.logger import *
CHUNKSIZE = 1024
class Download_Theard(Thread):
def __init__(self, url, to, progress_callback, onfinish):
self.url = url
self.to = to
self.progress_callback = progress_callback
self.onfinish = onfinish
Thread.__init__(self, daemon=True)
def run(self):
while 1:
try:
info("[downloader]download "+self.url)
self.progress_callback(0)
r = requests.get(self.url, stream=True)
if (r.status_code >= 300):
raise Exception
total = int(r.headers.get('content-length', 0))
now_file = 0
with open(self.to, 'wb') as fp:
for item in r.iter_content(CHUNKSIZE):
fp.write(item)
now_file += len(item)
self.progress_callback(now_file/total*0.9)
self.progress_callback(0.9)
info("[downloader]unzip "+self.url)
with py7zr.SevenZipFile(self.to, mode='r') as z:
z.extractall(path="software")
self.progress_callback(1)
self.onfinish()
return
except:
pass
def download_files(files, onfisish, anim_list):
threads = []
finishnum = 0
finishmax = len(files)
def anim_check(*args):
onfisish() # run in main thread
return -1
def progfinish():
nonlocal finishnum, finishmax
finishnum += 1
if (finishnum == finishmax):
anim_list.anim.append(anim_check)
for i in files:
threads.append(Download_Theard(
i["from"], i["to"], i["progbar"], progfinish))
threads[-1].start()

112
lib/get_disk.py Normal file
View File

@ -0,0 +1,112 @@
import platform
import os
import subprocess
import sys
from ui.lang import l
from logger.logger import *
if platform.system() == 'Linux':
def find_hub_disk():
info("[getdisk]get hub disk")
output = subprocess.check_output(
['mount', '-v']).decode(sys.getdefaultencoding())
for line in output.split('\n'):
if not line:
continue
mount_point_l = line.split(" ")
disk_id = mount_point_l[0]
mount_to = mount_point_l[2]
if len(disk_id) <= len("/dev/sd") or (disk_id[:len("/dev/sd")] != "/dev/sd" and (disk_id[:len("/dev/sd")] != "/dev/lo") and (disk_id[:len("/dev/sd")] != "/dev/nv")):
continue
if (mount_to == "/" or mount_to == "/boot"):
continue
if (os.path.exists(mount_to + "/PEinjector")):
return (0, mount_to, disk_id)
return (2, "")
def find_vtoy_disk():
vtoylist = []
info("[getdisk]get vtoy disk")
output = subprocess.check_output(
['mount', '-v']).decode(sys.getdefaultencoding())
for line in output.split('\n'):
if not line:
continue
mount_point_l = line.split(" ")
disk_id = mount_point_l[0]
mount_to = mount_point_l[2]
if len(disk_id) <= len("/dev/sd") or (disk_id[:len("/dev/sd")] != "/dev/sd" and (disk_id[:len("/dev/sd")] != "/dev/lo") and (disk_id[:len("/dev/sd")] != "/dev/nv")):
continue
if (mount_to == "/" or mount_to == "/boot"):
continue
if os.path.exists(mount_to + "/ventoy"):
vtoylist.append((disk_id, mount_to))
continue
output2 = subprocess.check_output(
['blkid', '-o', 'value', '-s', 'LABEL', disk_id]).decode(sys.getdefaultencoding())
output2 = output2.replace('\n', "")
if (output2 == ""):
continue
if (output2 == "Ventoy" or output2 == "ventoy"):
vtoylist.append((disk_id, mount_to))
return vtoylist
def find_all_disk():
vtoylist = []
info("[getdisk]get all disk")
output = subprocess.check_output(
['mount', '-v']).decode(sys.getdefaultencoding())
for line in output.split('\n'):
if not line:
continue
mount_point_l = line.split(" ")
disk_id = mount_point_l[0]
mount_to = mount_point_l[2]
if len(disk_id) <= len("/dev/sd") or (disk_id[:len("/dev/sd")] != "/dev/sd" and (disk_id[:len("/dev/sd")] != "/dev/lo") and (disk_id[:len("/dev/sd")] != "/dev/nv")):
continue
if (mount_to == "/" or mount_to == "/boot"):
continue
vtoylist.append((disk_id, mount_to))
return vtoylist
elif platform.system() == 'Windows':
def find_hub_disk():
info("[getdisk]get hub disk")
for i in "CDEFGHIJKABLMNOPQRSTUVWYZ":
this_disk = i+":"
if os.path.exists(this_disk + "/PEinjector"):
return (0, this_disk, this_disk)
return (2, "")
def find_vtoy_disk():
vtoylist = []
info("[getdisk]get vtoy disk")
for i in "CDEFGHIJKABLMNOPQRSTUVWYZ":
this_disk = i+":"
if not os.path.exists(this_disk):
continue
if os.path.exists(this_disk + "/ventoy"):
vtoylist.append((this_disk, this_disk))
with os.popen("wmic logicaldisk" +
f" where name=\"{this_disk}\" get volumename", 'r', 1) as file:
output2 = file.read()
output2 = (output2.replace("\n", "")
.replace("VolumeName", "")
.lstrip()
.rstrip())
if (output2 == "Ventoy"):
vtoylist.append((this_disk, this_disk))
return vtoylist
def find_all_disk():
vtoylist = []
info("[getdisk]get all disk")
for i in "CDEFGHIJKABLMNOPQRSTUVWYZ":
this_disk = i+":"
if (os.path.exists(this_disk)):
vtoylist.append((this_disk, this_disk))
return vtoylist
else:
def find_hub_disk():
info("[getdisk]get hub disk")
return (1, l("UnsupportedSystem"))

60
lib/install_pkg.py Normal file
View File

@ -0,0 +1,60 @@
import time
import os
import shutil
from threading import Thread
from logger.logger import *
class PKG_Theard(Thread):
def __init__(self, disks, barcallback, donecallback):
self.disks = disks
self.barcallback = barcallback
self.donecallback = donecallback
Thread.__init__(self, daemon=True)
def run(self):
DISK = self.disks
info(f"[install]install to {DISK}")
self.barcallback(0)
if not os.path.exists(DISK+"/PEinjector"):
os.mkdir(DISK+"/PEinjector")
time.sleep(0.1)
self.barcallback(0.1)
info("[install]install main file")
if os.path.exists(DISK+"/PEinjector/PEinjector.7z"):
os.remove(DISK+"/PEinjector/PEinjector.7z")
time.sleep(0.1)
self.barcallback(0.2)
shutil.copyfile("software/peinjector/dist/PEinjector.7z",
DISK+"/PEinjector/PEinjector.7z")
time.sleep(0.1)
self.barcallback(0.4)
time.sleep(0.1)
info("[install]write info")
if not os.path.exists(DISK+"/PEinjector/disable.txt"):
with open(DISK+"/PEinjector/disable.txt", "w") as file:
pass
self.barcallback(0.5)
time.sleep(0.1)
shutil.copyfile("software/peinjector/version",
DISK+"/PEinjector/VERSION")
if not os.path.exists(DISK+"/PEinjector/install"):
os.mkdir(DISK+"/PEinjector/install")
self.barcallback(0.6)
if not os.path.exists(DISK+"/PEinjector/package"):
os.mkdir(DISK+"/PEinjector/package")
ns = 0
for i in os.listdir("software/peinjector/package"):
if os.path.exists(DISK+"/PEinjector/package/"+i):
shutil.rmtree(DISK+"/PEinjector/package/"+i)
shutil.copytree("software/peinjector/package/" +
i, DISK+"/PEinjector/package/"+i)
ns += 1
info(
f"[install]install pkg {ns}/{len(os.listdir('software/peinjector/package'))}")
self.barcallback(
0.6+ns/len(os.listdir("software/peinjector/package"))*0.4)
time.sleep(0.1)
info("[install]install finish")
self.barcallback(1)
self.donecallback()

11
lib/open_ventoy.py Normal file
View File

@ -0,0 +1,11 @@
import os
import platform
def run():
if (platform.system() == 'Linux'):
os.system("chmod +x ./software/ventoy/VentoyGUI.x86_64")
os.system(
"cd software/ventoy;./VentoyGUI.x86_64 2> ../../logger/vtoylog.log&")
if (platform.system() == 'Windows'):
os.system("cd software\\ventoy && start Ventoy2Disk.exe")

3
logger/config.py Normal file
View File

@ -0,0 +1,3 @@
LOGPATH = "logger/log.log"
LOGLEVEL = "debug"
OUTPUT_COLORFUL = True

55
logger/logger.py Normal file
View File

@ -0,0 +1,55 @@
# ------ cxykevin log moudle ------
# This moudle is not a part of this project.
# This file is CopyNone.
import logging
from logger import config
import sys
levels = {
"debug": logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARN,
'err': logging.ERROR
}
def init() -> None:
logging.basicConfig(filename=config.LOGPATH,
format='[%(asctime)s][%(levelname)s] %(message)s',
level=levels[config.LOGLEVEL])
def info(msg: str) -> None:
if (20 >= levels[config.LOGLEVEL]):
sys.stdout.write(
("[\033[34mINFO\033[0m]" if config.OUTPUT_COLORFUL else "[INFO]") + msg + "\n")
logging.info(msg)
def warn(msg: str) -> None:
if (30 >= levels[config.LOGLEVEL]):
sys.stdout.write(
("[\033[33mWARNING\033[0m]" if config.OUTPUT_COLORFUL else "[WARNING]") + msg + "\n")
logging.warn(msg)
def err(msg: str) -> None:
if (40 >= levels[config.LOGLEVEL]):
sys.stdout.write(
("[\033[31mERROR\033[0m]" if config.OUTPUT_COLORFUL else "[ERROR]") + msg + "\n")
logging.error(msg)
def break_err(msg: str) -> None:
if (40 >= levels[config.LOGLEVEL]):
sys.stdout.write(
("[\033[31mERROR\033[0m]" if config.OUTPUT_COLORFUL else "[ERROR]") + msg + "\n")
logging.error(msg)
def print(*args, end="\n") -> None:
msg = ' '.join(map(str, args))
if (10 >= levels[config.LOGLEVEL]):
sys.stdout.write(msg + end)
logging.debug(msg)

3
main.py Normal file
View File

@ -0,0 +1,3 @@
from ui import win
if __name__ == "__main__":
win.main()

BIN
res/icon.pack Normal file

Binary file not shown.

10
res/installer_file.json Normal file
View File

@ -0,0 +1,10 @@
[
{
"name": "peinjector",
"source": "http://git.hmtsai.cn/cxykevin/PEinjector_Hub_Files/raw/branch/master/peinjector.7z"
},
{
"name": "ventoy",
"source": "http://git.hmtsai.cn/cxykevin/PEinjector_Hub_Files/raw/branch/master/ventoy.7z"
}
]

299
ui/installer.py Normal file
View File

@ -0,0 +1,299 @@
import json
import os
from turtle import bgcolor
from magictk import mtk, color_tmpl
from magictk import fontconfig
from ui.lang import l
from lib import open_ventoy
from lib import get_disk
from lib import install_pkg
from lib import downloader
from logger.logger import *
now_frame = None
master: mtk.Frame = None
def show_first_page():
global now_frame, master
first_page = mtk.Frame(master,)
mtk.Frame(first_page, w=10000).pack(fill="both", expand=True)
mtk.Label(first_page, text=l("InstallWelcome"),
anchor='center', font=(fontconfig.getfont(), 22), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["primary_text"]).pack(fill='x')
mtk.Label(first_page, text="\n"+l("InstallInfo"),
anchor='center', font=(fontconfig.getfont(), 12), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["secondary_text"]).pack(fill='x')
mtk.Frame(first_page, height=30).pack()
buttonlist = mtk.Frame(first_page)
def install_callback(*args):
change_page_download()
mtk.ButtonFill(buttonlist, text=l("StartInstall"),
w=110, color_type="primary", func=install_callback).pack(side="left")
mtk.Frame(buttonlist, height=10).pack(side="left")
buttonlist.pack()
mtk.Frame(first_page, w=10000).pack(fill="both", expand=True)
first_page.pack(fill="both", expand=True)
now_frame = first_page
def change_page_download():
global now_frame, master
now_frame.pack_forget()
instvtoy_page = mtk.Frame(master,)
mtk.Frame(instvtoy_page, w=10000).pack(fill="both", expand=True)
mtk.Label(instvtoy_page, text="0/3 "+l("DownloadInstallTitle"),
anchor='center', font=(fontconfig.getfont(), 22), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["primary_text"]).pack(fill='x')
mtk.Label(instvtoy_page, text="\n"+l("DownloadInstall"),
anchor='center', font=(fontconfig.getfont(), 12), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["secondary_text"]).pack(fill='x')
mtk.Frame(instvtoy_page, height=30).pack()
prog_frame = mtk.Frame(instvtoy_page)
with open("res/installer_file.json", 'r') as file:
files = json.load(file)
download_l = []
if not (os.path.exists("software")):
os.mkdir("software")
if not (os.path.exists("software"+os.sep+"cache")):
os.mkdir("software"+os.sep+"cache")
funclst = []
for i in files:
def runf():
sframe = mtk.Frame(prog_frame, height=10)
progps = mtk.Label(
sframe, background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["secondary_text"], text=" 0%", width=6, font=(fontconfig.getfont(), 10))
progps.pack(side="left")
progbar = mtk.ProgressBar(sframe, w=300)
progbar.pack(side="left", anchor='w')
proglabel = mtk.Label(
sframe, background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["secondary_text"], text=" "+i["name"], width=18, font=(fontconfig.getfont(), 10))
proglabel.pack(side="left")
sframe.pack(side="top")
def progcallback(prog):
progbar.set_progress(prog)
progstr = str(int(prog*100))
outstr = " "*(3-len(progstr))+progstr+"%"
def setproganim(*args):
progps.configure(text=outstr)
return -1
prog_frame.root.anim.append(setproganim)
funclst.append(progcallback)
download_l.append({
"from": i["source"],
"to": "software"+os.sep+"cache"+os.sep+i["name"]+".7z",
"progbar": funclst[-1]
})
runf()
def nextpage_callback(*args):
change_page_installvtoy()
open_ventoy.run()
buttonlist = mtk.Frame(instvtoy_page, height=30)
btns = mtk.ButtonFill(buttonlist, text=l("InstallVtoy"),
w=120, color_type="primary", func=nextpage_callback)
def callbacks():
btns.pack(side="left")
downloader.download_files(download_l, callbacks, prog_frame.root)
prog_frame.pack(fill='x', anchor="center")
mtk.Frame(instvtoy_page, height=30).pack()
buttonlist.pack()
mtk.Frame(instvtoy_page, w=10000).pack(fill="both", expand=True)
instvtoy_page.pack(fill="both", expand=True)
now_frame = instvtoy_page
def change_page_installvtoy():
global now_frame, master
now_frame.pack_forget()
instvtoy_page = mtk.Frame(master,)
mtk.Frame(instvtoy_page, w=10000).pack(fill="both", expand=True)
mtk.Label(instvtoy_page, text="1/3 "+l("InstallVtoyTitle"),
anchor='center', font=(fontconfig.getfont(), 22), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["primary_text"]).pack(fill='x')
mtk.Label(instvtoy_page, text="\n"+l("InstallVtoyInfo"),
anchor='center', font=(fontconfig.getfont(), 12), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["secondary_text"]).pack(fill='x')
mtk.Frame(instvtoy_page, height=30).pack()
buttonlist = mtk.Frame(instvtoy_page)
scan_obj_list = mtk.Frame(instvtoy_page, height=30)
added_list = False
selects = mtk.Select(scan_obj_list, text=l(
"ChooseVtoyDevice"), items=[], w=380)
devmenu = []
def finishvtoy_callback(*args):
if (selects.get() == -1):
return
info(f"[installer]choose disk info:{str(devmenu[selects.get()])}")
global devinfo
devinfo = devmenu[selects.get()]
change_page_installing()
def install_callback(*args):
nonlocal added_list, selects, devmenu
def show_all_dev(*args):
nonlocal devmenu
devmenu = get_disk.find_all_disk()
selects.change_menu([f"{i[0]} [{i[1]}]" for i in devmenu])
if (added_list == False):
mtk.ButtonLight(scan_obj_list, func=show_all_dev, text=l("ShowAllDevices"), w=100, color_type="info").pack(
side="left")
selects.pack(side="left")
mtk.Button(scan_obj_list, func=finishvtoy_callback, iconname="circle-check", iconsize=16, w=32).pack(
side="left")
added_list = True
devmenu = get_disk.find_vtoy_disk()
selects.change_menu([f"{i[0]} [{i[1]}]" for i in devmenu])
def restart_callback(*args):
open_ventoy.run()
mtk.ButtonFill(buttonlist, text=l("ScanVtoy"),
w=80, color_type="primary", func=install_callback).pack(side="left")
mtk.ButtonLight(buttonlist, text=l("RestartVtoy"),
w=120, color_type="primary", func=restart_callback).pack(side="left")
mtk.Frame(buttonlist, height=10).pack(side="left")
buttonlist.pack()
scan_obj_list.pack()
mtk.Frame(instvtoy_page, w=10000).pack(fill="both", expand=True)
instvtoy_page.pack(fill="both", expand=True)
now_frame = instvtoy_page
def change_page_installing():
global now_frame, master, devinfo
devpath = devinfo[1]
now_frame.pack_forget()
installinjector_page = mtk.Frame(master,)
mtk.Frame(installinjector_page, w=10000).pack(fill="both", expand=True)
mtk.Label(installinjector_page, text="2/3 "+l("InstallIjTitle"),
anchor='center', font=(fontconfig.getfont(), 22), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["primary_text"]).pack(fill='x')
mtk.Label(installinjector_page, text="\n"+l("InstallIjInfo"),
anchor='center', font=(fontconfig.getfont(), 12), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["secondary_text"]).pack(fill='x')
mtk.Frame(installinjector_page, height=30).pack()
prog_frame = mtk.Frame(installinjector_page, height=10)
progbar = mtk.ProgressBar(prog_frame, w=300)
progbar.pack()
prog_frame.pack(fill='x')
def barcallback(prog):
progbar.set_progress(prog)
finishbutton_frame = mtk.Frame(installinjector_page, height=30)
def finishbtncallback(*args):
change_page_finish()
finishbtn = mtk.ButtonFill(finishbutton_frame, text=l(
"FinishInstall"), w=120, color_type="success", func=finishbtncallback)
closeid = False
def anim_pick(*args):
nonlocal closeid
if (closeid == True):
closeid = False
finishbtn.pack()
return -1
prog_frame.root.anim.append(anim_pick)
def finishcallback():
nonlocal closeid
closeid = True
finishbutton_frame.pack(fill="both", expand=True)
mtk.Frame(installinjector_page, w=10000).pack(fill="both", expand=True)
installinjector_page.pack(fill="both", expand=True)
theards = install_pkg.PKG_Theard(devpath, barcallback, finishcallback)
theards.start()
now_frame = installinjector_page
def change_page_installing():
global now_frame, master, devinfo
devpath = devinfo[1]
now_frame.pack_forget()
installinjector_page = mtk.Frame(master,)
mtk.Frame(installinjector_page, w=10000).pack(fill="both", expand=True)
mtk.Label(installinjector_page, text="2/3 "+l("InstallIjTitle"),
anchor='center', font=(fontconfig.getfont(), 22), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["primary_text"]).pack(fill='x')
mtk.Label(installinjector_page, text="\n"+l("InstallIjInfo"),
anchor='center', font=(fontconfig.getfont(), 12), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["secondary_text"]).pack(fill='x')
mtk.Frame(installinjector_page, height=30).pack()
prog_frame = mtk.Frame(installinjector_page, height=10)
progbar = mtk.ProgressBar(prog_frame, w=300)
progbar.pack()
prog_frame.pack(fill='x')
def barcallback(prog):
progbar.set_progress(prog)
finishbutton_frame = mtk.Frame(installinjector_page, height=30)
def finishbtncallback(*args):
change_page_finish()
finishbtn = mtk.ButtonFill(finishbutton_frame, text=l(
"FinishInstall"), w=120, color_type="success", func=finishbtncallback)
closeid = False
def anim_pick(*args):
nonlocal closeid
if (closeid == True):
closeid = False
finishbtn.pack()
return -1
prog_frame.root.anim.append(anim_pick)
def finishcallback():
nonlocal closeid
closeid = True
mtk.Frame(installinjector_page, height=30).pack()
finishbutton_frame.pack(fill="both", expand=True)
mtk.Frame(installinjector_page, w=10000).pack(fill="both", expand=True)
installinjector_page.pack(fill="both", expand=True)
theards = install_pkg.PKG_Theard(devpath, barcallback, finishcallback)
theards.start()
now_frame = installinjector_page
def change_page_finish():
global now_frame, master
now_frame.pack_forget()
finish_page = mtk.Frame(master,)
mtk.Frame(finish_page, w=10000).pack(fill="both", expand=True)
mtk.Label(finish_page, text="3/3 "+l("InstallFinishTitle"),
anchor='center', font=(fontconfig.getfont(), 22), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["primary_text"]).pack(fill='x')
mtk.Label(finish_page, text="\n"+l("InstallFinishInfo"),
anchor='center', font=(fontconfig.getfont(), 12), background=color_tmpl.default_color["background"], foreground=color_tmpl.default_color["secondary_text"]).pack(fill='x')
def closecallback(*args):
info("close from installer")
finish_page.root.quit()
btnframe = mtk.Frame(finish_page, height=30)
mtk.ButtonFill(finish_page, text=l(
"InstallFinishBtn"), func=closecallback, color_type="danger").pack()
btnframe.pack()
mtk.Frame(finish_page, height=30).pack()
mtk.Frame(finish_page, w=10000).pack(fill="both", expand=True)
finish_page.pack(fill="both", expand=True)
now_frame = finish_page
def installer_ui(root: mtk.Frame):
global master
install_root_frame = mtk.Frame(root)
master = install_root_frame
show_first_page()
install_root_frame.pack(fill="both", expand=True)

15
ui/lang.py Normal file
View File

@ -0,0 +1,15 @@
from logger.logger import *
import tomllib
l_obj = {}
def load_lang(lang: str):
info(f"[lang]load lang: {lang}")
global l_obj
with open("lang/"+lang+".toml", "rb") as file:
l_obj = tomllib.load(file)
def l(strs):
return l_obj.get(strs, f"__{strs}__")

61
ui/nav.py Normal file
View File

@ -0,0 +1,61 @@
from magictk import mtk, color_tmpl
from logger.logger import *
choose_id = 0
def nav_callback(obj):
ids = obj.ids
side = navlists[ids]["side"]
global choose_id
if (choose_id == ids):
return
choose_id = ids
if (side == "top"):
nav_frame_now.place_forget()
nav_frame_now.place(x=0, y=50*ids, width=3, height=50, anchor='nw')
else:
nav_frame_now.place_forget()
nav_frame_now.place(x=0, rely=1, width=3, height=50, anchor='sw')
def pack_nav(master: mtk.Frame, root: mtk.Frame, navlist: list):
global nav_frame_now, btn_list, navlists, nav_main, btn_frame_list
navlists = navlist
nav_frame = mtk.Frame(master)
nav_frame_show = mtk.Frame(nav_frame, w=3)
nav_frame_now = mtk.Frame(
nav_frame_show, w=3, bg=color_tmpl.default_color["primary"])
nav_frame_now.place(x=0, y=0, width=3, height=50)
nav_frame_show.pack(side="left", fill='y')
mtk.Frame(nav_frame, w=1).pack(
side="left", expand=True, fill='y')
nav_frame_main = mtk.Frame(nav_frame, w=50)
btn_list = []
btn_frame_list = []
ids = 0
for i in navlist:
icon = i["icon"]
frame = i["frame"]
side = i["side"]
btn_list.append(mtk.ButtonLight(
master=nav_frame_main, color_type="plain", iconname=icon, iconsize=32, w=50, h=50, func=nav_callback))
btn_list[-1].ids = ids
btn_list[-1].pack(side=side)
btn_frame_list.append(frame)
ids += 1
nav_frame_main.pack(side="left", fill='both')
mtk.Frame(nav_frame, w=2).pack(
side="left", expand=True, fill='y')
mtk.Frame(nav_frame, w=1, bg=color_tmpl.default_color["border_light"]).pack(
side="left", expand=True, fill='y')
nav_frame.pack(side="left", expand=True, fill='y')
nav_main = mtk.Frame(
master, w=1000)
btn_frame_list[0](nav_main)
nav_main.pack(side="right", fill='both')

53
ui/win.py Normal file
View File

@ -0,0 +1,53 @@
from tkinter import messagebox
from magictk import mtk
from logger.logger import *
from ui import nav
from ui import installer
from lib import get_disk
from ui.lang import load_lang, l
import sys
import getpass
import platform
import ctypes
init()
load_lang("zh_cn") # TODO:读取设置
disk_res = get_disk.find_hub_disk()
errno = disk_res[0]
root_disk = disk_res[1]
if (errno == 1):
messagebox.showerror("Injector Hub Error", root_disk)
sys.exit(1)
elif (errno == 2):
info("[win]cannot find installed disk")
if (platform.system() == "Linux" and getpass.getuser() != "root"):
messagebox.showerror("Injector Hub Error", l("PermissionDeniedLinux"))
sys.exit(1)
if (platform.system() == "Windows" and ctypes.windll.shell32.IsUserAnAdmin() == False):
messagebox.showerror("Injector Hub Error", l("PermissionDeniedWin"))
nav_list = [
{"icon": "lightning", "frame": installer.installer_ui, "side": "top"}
]
else:
info(f"[win]found installed disk \"{root_disk}\"")
nav_list = [
{"icon": "home-filled", "frame": None, "side": "top"},
{"icon": "dvd", "frame": None, "side": "top"},
{"icon": "plugin", "frame": None, "side": "top"},
{"icon": "setting", "frame": None, "side": "bottom"}
]
info("[win]init window")
mtk.load_icon_pack("res/icon.pack")
main_win = mtk.Tk(title="Injector Hub", w=1000, h=800)
main_frame = mtk.Frame(main_win, w=10000)
nav.pack_nav(main_win, main_frame, nav_list)
main_frame.pack(side="left", fill="both", expand=True)
def main():
info("[win]mainloop")
main_win.mainloop()