Update v1.12.py

This commit is contained in:
Evan Su 2021-03-31 11:45:38 -04:00 committed by GitHub
parent 45c73c3c46
commit 4ce564b72f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -88,6 +88,11 @@ tk.resizable(0,0)
tk.configure(background="#f5f6f7")
ThemedStyle(tk).set_theme("arc")
# Some styling
style = tkinter.ttk.Style()
style.configure("PasswordMatches.TLabel",foreground="#e3242b")
style.configure("PasswordStrength.TLabel",foreground="")
# Enable high DPI on Windows
def Get_HWND_DPI(window_handle):
from ctypes import windll,pointer,wintypes
@ -149,7 +154,7 @@ inputLabel.place(x=20,y=18)
clearInput = tkinter.ttk.Button(
tk,
text="Clear",
command=lambda:resetUI()
command=lambda:[resetUI(),statusString.set("Ready.")]
)
clearInput.place(x=400,y=12,width=60,height=28)
clearInput["state"] = "disabled"
@ -210,7 +215,7 @@ passwordLabel["state"] = "disabled"
# Allow password input to fill width
passwordFrame = tkinter.Frame(
tk,
width=440,
width=220,
height=24
)
passwordFrame.place(x=20,y=118)
@ -238,7 +243,7 @@ cPasswordLabel["state"] = "disabled"
# Allow confirm password input to fill width
cPasswordFrame = tkinter.Frame(
tk,
width=418,
width=220,
height=24
)
cPasswordFrame.place(x=20,y=168)
@ -253,21 +258,60 @@ cPasswordInput = tkinter.ttk.Entry(
cPasswordInput.grid(sticky="nesw")
cPasswordInput["state"] = "disabled"
# Check if passwords match
def doPasswordsMatch(key,which):
if which=="p":
matches = passwordInput.get()+key.char==cPasswordInput.get()
# Show strength of password
def showStrength():
global mode
if mode=="decrypt":
return
password = passwordInput.get()
containsLetters = any(i.isalpha() for i in password)
containsNumbers = any(i.isdigit() for i in password)
containsSymbols = any(not i.isalnum() for i in password)
longEnough = len(password)>8
if containsLetters and containsNumbers and containsSymbols and longEnough:
style.configure("PasswordStrength.TLabel",foreground="#149414")
elif containsLetters and containsNumbers and containsSymbols:
style.configure("PasswordStrength.TLabel",foreground="#fada52")
elif containsLetters and containsNumbers or \
(containsLetters and containsSymbols) or \
(containsNumbers and containsSymbols):
style.configure("PasswordStrength.TLabel",foreground="#ff781f")
elif not password:
style.configure("PasswordStrength.TLabel",foreground="")
else:
matches = passwordInput.get()==cPasswordInput.get()+key.char
style.configure("PasswordStrength.TLabel",foreground="#e3242b")
# Check if passwords match
def doPasswordsMatch():
global mode
if mode=="decrypt":
return
matches = passwordInput.get()==cPasswordInput.get()
if passwordInput.get() and matches:
passwordMatchesString.set("")
style.configure("PasswordMatches.TLabel",foreground="#149414")
startBtn["state"] = "normal"
else:
passwordMatchesString.set("×")
elif passwordInput.get() and not matches:
passwordMatchesString.set("")
style.configure("PasswordMatches.TLabel",foreground="#e3242b")
startBtn["state"] = "disabled"
elif not passwordInput.get():
passwordMatchesString.set("")
startBtn["state"] = "disabled"
passwordInput.bind("<Key>",lambda key:doPasswordsMatch(key,"p"))
cPasswordInput.bind("<Key>",lambda key:doPasswordsMatch(key,"c"))
passwordInput.bind("<KeyRelease>",lambda e:[showStrength(),doPasswordsMatch()])
cPasswordInput.bind("<KeyRelease>",lambda e:doPasswordsMatch())
# Show indicator of password strength
passwordStrengthString = tkinter.StringVar(tk)
passwordStrengthString.set("")
passwordStrength = tkinter.ttk.Label(
tk,
textvariable=passwordStrengthString
)
passwordStrength.config(style="PasswordStrength.TLabel")
passwordStrength.place(x=245,y=122)
# Check box that indicates if password match
passwordMatchesString = tkinter.StringVar(tk)
@ -275,7 +319,8 @@ passwordMatches = tkinter.ttk.Label(
tk,
textvariable=passwordMatchesString
)
passwordMatches.place(x=441,y=170)
passwordMatches.config(style="PasswordMatches.TLabel")
passwordMatches.place(x=242,y=172)
# Prompt user for optional metadata
metadataString = tkinter.StringVar(tk)
@ -367,14 +412,17 @@ rsBtn.place(x=18,y=369)
rsBtn["state"] = "disabled"
# "Reed-Solomon" which links to Wikipedia
helpString = tkinter.StringVar(tk)
helpString.set("(?)")
help = tkinter.ttk.Label(
rsHelpString = tkinter.StringVar(tk)
rsHelpString.set("(?)")
rsHelp = tkinter.ttk.Label(
tk,
textvariable=helpString,
cursor="hand2"
textvariable=rsHelpString,
cursor="hand2",
font=("TkDefaultFont",7)
)
help.place(x=279,y=373)
rsHelp.place(x=259,y=374)
rsHelpLink = "https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction"
rsHelp.bind("<Button-1>",lambda e:webbrowser.open(rsHelpLink))
# Frame so start and cancel button can fill width
startFrame = tkinter.Frame(
@ -396,10 +444,14 @@ startBtn = tkinter.ttk.Button(
startBtn.grid(row=0,column=0,stick="nesw")
startBtn["state"] = "disabled"
def cancel():
global working
working = False
# Cancel button
cancelBtn = tkinter.ttk.Button(
startFrame,
text="Cancel"
text="Cancel",
command=cancel
)
cancelBtn.grid(stick="nesw")
cancelBtn.grid(row=0,column=1)
@ -603,6 +655,7 @@ def filesDragged(draggedFiles):
inputString.set(inputFile.split("/")[-1]+suffix)
prompt.pack_forget()
statusString.set("Ready.")
# UTF-8 decode error
except UnicodeDecodeError:
@ -648,18 +701,13 @@ def work():
reedsoloErrors = 0
password = passwordInput.get().encode("utf-8")
metadata = metadataInput.get("1.0",tkinter.END).encode("utf-8")
cancelBtn["state"] = "normal"
# Decide if encrypting or decrypting
if mode=="encrypt":
outputFile = outputInput.get()+".pcv"
else:
outputFile = outputInput.get()
# Make sure passwords match
if passwordInput.get()!=cPasswordInput.get() and mode=="encrypt":
setEncryptionUI()
statusString.set("Passwords don't match.")
return
# Set progress bar indeterminate
progress.config(mode="indeterminate")
@ -811,6 +859,18 @@ def work():
Thread(target=updateStats,daemon=True,args=(total,)).start()
while True:
if not working:
fin.close()
fout.close()
remove(outputFile)
if mode=="encrypt":
setEncryptionUI()
else:
setDecryptionUI()
statusString.set("Operation canceled by user.")
dummy.focus()
return
if mode=="decrypt" and reedsolo:
piece = fin.read(1104905)
else:
@ -976,12 +1036,12 @@ def work():
working = False
def updateStats(total):
global startTime,previousTime,done,stopUpdating,reedsolo,reedsoloFixed,reedsoloErrors
global startTime,previousTime,done,stopUpdating,reedsolo,reedsoloFixed,reedsoloErrors,working
while True:
validStatus = (
statusString.get().startswith("Working") or statusString.get().startswith("Deriving")
)
if not stopUpdating and validStatus:
if not stopUpdating and validStatus and working:
elapsed = (datetime.now()-previousTime).total_seconds() or 0.0001
sinceStart = (datetime.now()-startTime).total_seconds() or 0.0001
previousTime = datetime.now()
@ -1032,6 +1092,8 @@ def secureWipe(fin):
# Reset UI to state where no files are selected
def resetUI():
global working
working = False
inputString.set(strings[18])
inputLabel["state"] = "normal"
clearInput["state"] = "disabled"
@ -1050,7 +1112,8 @@ def resetUI():
cPasswordInput["state"] = "normal"
cPasswordInput.delete(0,"end")
cPasswordInput["state"] = "disabled"
passwordMatchesString.set("×")
passwordMatchesString.set("")
style.configure("PasswordStrength.TLabel",foreground="")
metadataFrame.config(bg="#e5eaf0")
metadataInput.config(bg="#fbfcfc")
metadataInput.config(fg="#000000")
@ -1074,6 +1137,10 @@ def resetUI():
# Set UI to encryption state
def setEncryptionUI():
global working
working = False
clearInput["state"] = "normal"
clearInput.config(cursor="hand2")
outputLabel["state"] = "normal"
outputInput["state"] = "normal"
outputFrame.config(width=410)
@ -1090,12 +1157,17 @@ def setEncryptionUI():
eraseBtn["state"] = "normal"
rsBtn["state"] = "normal"
startBtn["state"] = "normal"
cancelBtn["state"] = "disabled"
progress.stop()
progress.config(mode="determinate")
progress["value"] = 0
# Set UI to decryption state
def setDecryptionUI():
global working
working = False
clearInput["state"] = "normal"
clearInput.config(cursor="hand2")
outputLabel["state"] = "normal"
outputInput["state"] = "normal"
outputFrame.config(width=440)
@ -1109,6 +1181,7 @@ def setDecryptionUI():
metadataInput["state"] = "disabled"
keepBtn["state"] = "normal"
startBtn["state"] = "normal"
cancelBtn["state"] = "disabled"
progress.stop()
progress.config(mode="determinate")
progress["value"] = 0