feat(update): 实现软件自动更新功能

- 新增 update 函数用于执行更新操作
- 添加 check_update 函数用于检查更新
- 实现了更新进度条和错误处理
- 优化了用户交互界面,包括提示框和进度显示
- 重构了原有的更新逻辑,提高了更新的可靠性和用户体验
This commit is contained in:
2025-03-23 14:56:23 +08:00
parent 3bc1cc8b69
commit 725fd2f83b

182
update.py
View File

@ -1,40 +1,162 @@
import os import requests
import subprocess
import threading
import time import time
import tkinter.messagebox
import subprocess
import os
appdata = os.getenv("APPDATA") def update(labelframe_settings, check_update_button, root, version, resource_path, appdata, datalist, version_json, screen_height, screen_width, update_path, data_resp, latest_version, download_page, update_progressbar, app_progressbar, update_url, app_url):
update_path = appdata + "/.NFLmusic/update/" global downloaded, total_length
with open(f"{update_path}file_path", "r") as f: def f_update_progressbar():
data = f.read() while True:
version = data.split("\n")[0] progress = int((downloaded / total_length) * 100)
path = data.split("\n")[1] update_progressbar['value'] = progress
if downloaded == total_length:
source_file = f"{update_path}NFLmusicv{version}.exe"
new_path = path.rsplit("\\", 1)[0]
while True:
try:
with open(source_file, "rb") as f:
content = f.read()
with open(path, "wb") as f:
f.write(content)
break break
except:
pass
time.sleep(0.05) time.sleep(0.05)
try: def f_app_progressbar():
os.rename(path, f"NFLmusicv{version}.exe") while True:
except: progress = int((downloaded / total_length) * 100)
app_progressbar['value'] = progress
if downloaded == total_length:
break
time.sleep(0.05)
def prevent_closing():
pass pass
os.remove(source_file)
def run_update():
subprocess.Popen(update_path + "update.exe")
def run_NFLmusic(): if not os.path.exists(appdata + "/.NFLmusic/update"):
subprocess.Popen(new_path + f"/NFLmusicv{version}.exe") os.mkdir(appdata + "/.NFLmusic/update")
if not have_checked:
data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/data"
data_resp = requests.get(data_url)
data_resp.close()
datalist = data_resp.text.replace("\r", "").split("\n")
update_path = appdata + "/.NFLmusic/update/"
data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/latest_update_log"
data_resp = requests.get(data_url).text
latest_version = datalist[0]
if latest_version != version:
if not jsondata["auto_update"]:
response = tkinter.messagebox.askquestion(
lang.get(la, "mbox.title.update_reminding", {"_version_": latest_version}),
lang.get(la, "mbox.text.update_reminding", {"_update_": data_resp}))
if response == "yes":
check_update_button["state"] = "disabled"
# 将root隐藏
root.withdraw()
download_page = download_page
download_page.geometry(f"360x200+{x_dl}+{y_dl}")
download_page.title(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}))
download_page.protocol("WM_DELETE_WINDOW", prevent_closing)
download_page.resizable(False, False)
download_page.iconbitmap(resource_path + "/.NFLmusic/resource/icon.ico")
update_progressbar = update_progressbar
app_progressbar = app_progressbar
Label(download_page, text=lang.get(la, "ui.update.text.download_update")).pack()
update_progressbar.pack()
Label(download_page, text=f"\n\n{lang.get(la, 'ui.update.text.download_app')}").pack()
app_progressbar.pack()
update_url = datalist[1]
app_url = datalist[2]
try:
update_resp = requests.get(update_url, stream=True)
app_resp = requests.get(app_url, stream=True)
with open(update_path + "file_path", "w") as f:
f.write(latest_version + "\n" + os.path.abspath(sys.executable))
with open(update_path + "update.exe", "wb") as f:
total_length = int(update_resp.headers.get('content-length'))
downloaded = 0
utils.run(f_update_progressbar)
for data in update_resp.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
time.sleep(0.1)
with open(update_path + f"NFLmusicv{latest_version}.exe", "wb") as f:
total_length = int(app_resp.headers.get('content-length'))
downloaded = 0
utils.run(f_app_progressbar)
for data in app_resp.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
run_update()
download_page.destroy()
root.destroy()
except:
download_page.destroy()
tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.update_fail"),
message=lang.get(la, "mbox.text.update_fail", ))
else:
check_update_button["state"] = "normal"
else:
tkinter.messagebox.showinfo(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}),
lang.get(la, "mbox.text.update_start_auto", {"_update_": data_resp}))
check_update_button["state"] = "disabled"
# 将root隐藏
root.withdraw()
download_page = download_page
download_page.geometry(f"360x200+{x_dl}+{y_dl}")
download_page.title(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}))
download_page.protocol("WM_DELETE_WINDOW", prevent_closing)
download_page.resizable(False, False)
download_page.iconbitmap(resource_path + "/.NFLmusic/resource/icon.ico")
update_progressbar = update_progressbar
app_progressbar = app_progressbar
Label(download_page, text=lang.get(la, "ui.update.text.download_update")).pack()
update_progressbar.pack()
Label(download_page, text=f"\n\n{lang.get(la, 'ui.update.text.download_app')}").pack()
app_progressbar.pack()
update_url = datalist[1]
app_url = datalist[2]
try:
update_resp = requests.get(update_url, stream=True)
app_resp = requests.get(app_url, stream=True)
with open(update_path + "file_path", "w") as f:
f.write(latest_version + "\n" + os.path.abspath(sys.executable))
with open(update_path + "update.exe", "wb") as f:
total_length = int(update_resp.headers.get('content-length'))
downloaded = 0
utils.run(f_update_progressbar)
for data in update_resp.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
time.sleep(0.1)
with open(update_path + f"NFLmusicv{latest_version}.exe", "wb") as f:
total_length = int(app_resp.headers.get('content-length'))
downloaded = 0
utils.run(f_app_progressbar)
for data in app_resp.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
run_update()
download_page.destroy()
root.destroy()
except Exception as e:
# 重新显示窗口
root.deiconify()
print(e)
download_page.destroy()
tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.update_fail"),
message=lang.get(la, "mbox.text.update_fail", ))
def check_update(labelframe_settings, check_update_button, version, datalist, have_checked):
run_NFLmusic() check_update_button["state"] = "disabled"
try:
data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/data"
data_resp = requests.get(data_url)
datalist = data_resp.text.replace("\r", "").split("\n")
latest_version = datalist[0]
data_resp.close()
if version == latest_version:
tkinter.messagebox.showinfo(lang.get(la, "mbox.title.update_reminding", {"- v_version_": ""}),
lang.get(la, "mbox.text.update_latest"))
check_update_button["state"] = "normal"
else:
update(labelframe_settings, check_update_button, root, version, resource_path, appdata, datalist, version_json, screen_height, screen_width, update_path, data_resp, latest_version, download_page, update_progressbar, app_progressbar, update_url, app_url)
except:
check_update_button["state"] = "normal"
have_checked = True