Skip to content

Commit d5b62ea

Browse files
committed
Merge branch 'VEX-13_Uv1.2' into main
2 parents e94e83a + f3e8d55 commit d5b62ea

18 files changed

+284
-181
lines changed

Updater.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
block_cipher = None
55

66

7-
a = Analysis(['src\\Updater.py'],
7+
a = Analysis(['src\\Updater\\main.py'],
88
pathex=['P:\\VexTrack'],
99
binaries=[],
1010
datas=[],

src/Updater/changelogDiag.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from tkinter import *
2+
from tkinter import simpledialog, messagebox, ttk
3+
4+
class ChangelogDiag(simpledialog.Dialog):
5+
def __init__(self, parent, title, changelog):
6+
self.changelog = changelog
7+
super().__init__(parent, title)
8+
9+
def body(self, frame):
10+
self.iconbitmap("Updater.exe")
11+
12+
ttk.Label(frame, text="Here is what's new:").grid(padx=8, pady=4, column=0, row=0, sticky="w")
13+
14+
self.changelogBox = Listbox(frame, width=64)
15+
self.changelogBox.grid(padx=8, pady=2, column=0, row=1, sticky="nswe")
16+
for i in range(0, len(self.changelog)):
17+
self.changelogBox.insert(i, self.changelog[i])
18+
19+
scrollbar = ttk.Scrollbar(frame, orient="vertical", command=self.changelogBox.yview)
20+
scrollbar.grid(column=1, row=1, sticky="nswe")
21+
22+
return frame
23+
24+
def buttonbox(self):
25+
self.okButton = ttk.Button(self, text='OK', command=lambda: self.destroy())
26+
self.okButton.pack(padx=8, pady=8, side=RIGHT)
27+
self.bind("<Return>", lambda event: self.destroy())

src/Updater/core.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
from sys import version
2+
from tkinter import *
3+
from tkinter import messagebox
4+
import os
5+
import requests
6+
from Updater import changelogDiag, downloadDiag, legacy
7+
from vars import *
8+
from tokenString import *
9+
import json
10+
import time
11+
12+
root = Tk()
13+
root.withdraw()
14+
15+
def downloadNewVersion(versionString, softwareName, legacyMode):
16+
os.system("taskkill /f /im " + softwareName + ".exe")
17+
18+
url = "https://github.com/" + GITHUB_USER + "/" + GITHUB_REPO + "/releases/download/" + versionString + "/" + softwareName + ".exe"
19+
r = requests.get(url, stream=True)
20+
21+
downDiag = downloadDiag.DownloadDiag(root, "Downloading " + softwareName + " " + versionString)
22+
while downDiag == None: pass
23+
24+
with open(softwareName + ".exe", 'wb') as f:
25+
startTime = time.mktime(time.localtime())
26+
downloaded = 0
27+
total = int(r.headers.get('content-length'))
28+
29+
for chunk in r.iter_content(chunk_size=max(int(total/1000), 1024*1024)):
30+
if chunk:
31+
downloaded += len(chunk)
32+
f.write(chunk)
33+
cTime = time.mktime(time.localtime())
34+
35+
downDiag.updateValues(downloaded, total, 0 if cTime == startTime else round(downloaded / (cTime - startTime), 2))
36+
37+
downDiag.destroy()
38+
39+
if not legacyMode:
40+
content = []
41+
with open(VERSION_PATH, 'r') as f:
42+
content = json.loads(f.read())
43+
44+
content[softwareName] = versionString
45+
with open(VERSION_PATH, 'w') as f:
46+
f.write(json.dumps(content, indent = 4, separators=(',', ': ')))
47+
else:
48+
content = []
49+
with open(OLD_VERSION_PATH, 'r') as f:
50+
content = f.readlines()
51+
52+
content[LEGACY_VERSIONS.index(softwareName)] = versionString
53+
for i in range(0, len(content)):
54+
if i != len(content) - 1: content[i] += "\n"
55+
56+
with open(OLD_VERSION_PATH, 'w') as f:
57+
f.writelines(content)
58+
59+
def restartProgram(softwareName):
60+
os.startfile(softwareName + ".exe")
61+
62+
def checkNewVersion(softwareName):
63+
isNewVersion = False
64+
legacyMode = False
65+
66+
# Update old version file
67+
if not os.path.exists(VERSION_PATH):
68+
if os.path.exists(OLD_VERSION_PATH):
69+
version = []
70+
with open(OLD_VERSION_PATH, 'r') as f:
71+
version = f.readlines()
72+
73+
for i in range(0, len(version)): version[i] = version[i].strip()
74+
legacyMode = legacy.checkLegacy(version)
75+
76+
if not legacyMode:
77+
newVersion = {GITHUB_REPO: version[0], "Updater": version[1]}
78+
os.remove(OLD_VERSION_PATH)
79+
else:
80+
newVersion = {GITHUB_REPO: "v1.0", "Updater": "v1.0"}
81+
82+
if not legacyMode:
83+
with open(VERSION_PATH, 'w') as f:
84+
f.write(json.dumps(newVersion, indent = 4, separators=(',', ': ')))
85+
86+
if legacyMode:
87+
with open(OLD_VERSION_PATH, 'r') as f:
88+
versionString = f.readlines()[LEGACY_VERSIONS.index(softwareName)]
89+
else:
90+
with open(VERSION_PATH, 'r') as f:
91+
versionString = json.loads(f.read())[softwareName]
92+
93+
versionNumber = versionString.split("v")[1]
94+
95+
response = requests.get("https://api.github.com/repos/" + GITHUB_USER + "/" + GITHUB_REPO + "/releases", headers={"Authorization": TOKEN})
96+
releases = response.json()
97+
98+
for r in releases:
99+
tokenized = r["name"].split()
100+
if tokenized[0] == softwareName:
101+
latestVersionString = tokenized[1]
102+
latestVersionNumber = latestVersionString.split("v")[1]
103+
104+
if versionNumber > latestVersionNumber:
105+
break
106+
107+
if versionNumber < latestVersionNumber:
108+
res = messagebox.askquestion("Updater", "A new version of " + softwareName + " is available: " + latestVersionString + "\nDo you want to update?")
109+
if res == "yes":
110+
downloadNewVersion(latestVersionString, softwareName, legacyMode)
111+
112+
changelogRaw = r["body"].split("##")[1].split("\r\n")
113+
changelog = []
114+
for c in changelogRaw[1:]:
115+
if c != "": changelog.append(c)
116+
117+
changelogDiag.ChangelogDiag(root, "Changelog", changelog)
118+
119+
isNewVersion = True
120+
121+
restartProgram(softwareName)
122+
break
123+
124+
root.destroy()
125+
return isNewVersion

src/Updater/downloadDiag.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from tkinter import *
2+
from tkinter import ttk, messagebox
3+
4+
class DownloadDiag(Toplevel):
5+
def close(self):
6+
pass
7+
8+
def __init__(self, parent, title):
9+
super().__init__(parent)
10+
self.title(title)
11+
self.transient()
12+
self.iconbitmap("Updater.exe")
13+
self.resizable(False, False)
14+
15+
ttk.Label(self, text="Download progress", font=('TkDefaultFont', 9,'bold')).grid(padx=8, pady=4, column=0, row=0, columnspan=7, sticky="w")
16+
17+
self.progressBar = ttk.Progressbar(self, length=64, orient="horizontal", mode="determinate")
18+
self.progressBar.grid(padx=8, pady=2, columnspan=6, column=0, row=1, sticky="we")
19+
20+
self.percentageLabel = ttk.Label(self, text="0 %")
21+
self.percentageLabel.grid(padx=8, pady=4, column=6, row=1, sticky="w")
22+
23+
ttk.Label(self, text="Downloaded:", font=('TkDefaultFont', 9,'bold')).grid(padx=8, pady=4, column=0, row=2, sticky="w")
24+
ttk.Label(self, text="File Size:", font=('TkDefaultFont', 9,'bold')).grid(padx=8, pady=4, column=2, row=2, sticky="w")
25+
ttk.Label(self, text="Speed:", font=('TkDefaultFont', 9,'bold')).grid(padx=8, pady=4, column=4, row=2, sticky="w")
26+
27+
self.downloadedLabel = ttk.Label(self, text="0 B")
28+
self.downloadedLabel.grid(padx=8, pady=4, column=1, row=2, sticky="w")
29+
30+
self.fileSizeLabel = ttk.Label(self, text="0 B")
31+
self.fileSizeLabel.grid(padx=8, pady=4, column=3, row=2, sticky="w")
32+
33+
self.speedLabel = ttk.Label(self, text="0 b/s")
34+
self.speedLabel.grid(padx=8, pady=4, column=5, row=2, sticky="w")
35+
36+
self.protocol("WM_DELETE_WINDOW", self.close)
37+
38+
def formatSize(self, value, suffix):
39+
amount = 0
40+
while value > 1024:
41+
value /= 1024
42+
amount += 1
43+
44+
value = round(value, 2)
45+
valueStr = f'{value:.2f}'
46+
47+
if amount >= 3: return valueStr + " G" + suffix
48+
if amount >= 2: return valueStr + " M" + suffix
49+
if amount >= 1: return valueStr + " K" + suffix
50+
return valueStr + " " + suffix
51+
52+
def updateValues(self, downloaded, size, speed):
53+
progress = round(downloaded / size * 100, 2)
54+
55+
self.progressBar["value"] = progress
56+
self.percentageLabel["text"] = f'{progress:.2f}' + " %"
57+
self.downloadedLabel["text"] = self.formatSize(downloaded, "B")
58+
self.fileSizeLabel["text"] = self.formatSize(size, "B")
59+
self.speedLabel["text"] = self.formatSize(speed, "b/s")
60+
self.update()

src/Updater/legacy.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from vars import *
2+
3+
def checkLegacy(version):
4+
if float(version[LEGACY_VERSIONS.index(APP_NAME)].split("v")[1]) <= LEGACY_LAST_APP or float(version[LEGACY_VERSIONS.index("Updater")].split("v")[1]) >= LEGACY_LAST_UPDATER:
5+
return True
6+
return False

src/Updater/main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import os, sys
2+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
3+
4+
from Updater import core
5+
from vars import *
6+
7+
core.checkNewVersion(APP_NAME)
File renamed without changes.

0 commit comments

Comments
 (0)