Update v1.12.py
This commit is contained in:
parent
45c73c3c46
commit
4ce564b72f
|
@ -88,6 +88,11 @@ tk.resizable(0,0)
|
||||||
tk.configure(background="#f5f6f7")
|
tk.configure(background="#f5f6f7")
|
||||||
ThemedStyle(tk).set_theme("arc")
|
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
|
# Enable high DPI on Windows
|
||||||
def Get_HWND_DPI(window_handle):
|
def Get_HWND_DPI(window_handle):
|
||||||
from ctypes import windll,pointer,wintypes
|
from ctypes import windll,pointer,wintypes
|
||||||
|
@ -149,7 +154,7 @@ inputLabel.place(x=20,y=18)
|
||||||
clearInput = tkinter.ttk.Button(
|
clearInput = tkinter.ttk.Button(
|
||||||
tk,
|
tk,
|
||||||
text="Clear",
|
text="Clear",
|
||||||
command=lambda:resetUI()
|
command=lambda:[resetUI(),statusString.set("Ready.")]
|
||||||
)
|
)
|
||||||
clearInput.place(x=400,y=12,width=60,height=28)
|
clearInput.place(x=400,y=12,width=60,height=28)
|
||||||
clearInput["state"] = "disabled"
|
clearInput["state"] = "disabled"
|
||||||
|
@ -210,7 +215,7 @@ passwordLabel["state"] = "disabled"
|
||||||
# Allow password input to fill width
|
# Allow password input to fill width
|
||||||
passwordFrame = tkinter.Frame(
|
passwordFrame = tkinter.Frame(
|
||||||
tk,
|
tk,
|
||||||
width=440,
|
width=220,
|
||||||
height=24
|
height=24
|
||||||
)
|
)
|
||||||
passwordFrame.place(x=20,y=118)
|
passwordFrame.place(x=20,y=118)
|
||||||
|
@ -238,7 +243,7 @@ cPasswordLabel["state"] = "disabled"
|
||||||
# Allow confirm password input to fill width
|
# Allow confirm password input to fill width
|
||||||
cPasswordFrame = tkinter.Frame(
|
cPasswordFrame = tkinter.Frame(
|
||||||
tk,
|
tk,
|
||||||
width=418,
|
width=220,
|
||||||
height=24
|
height=24
|
||||||
)
|
)
|
||||||
cPasswordFrame.place(x=20,y=168)
|
cPasswordFrame.place(x=20,y=168)
|
||||||
|
@ -253,21 +258,60 @@ cPasswordInput = tkinter.ttk.Entry(
|
||||||
cPasswordInput.grid(sticky="nesw")
|
cPasswordInput.grid(sticky="nesw")
|
||||||
cPasswordInput["state"] = "disabled"
|
cPasswordInput["state"] = "disabled"
|
||||||
|
|
||||||
# Check if passwords match
|
# Show strength of password
|
||||||
def doPasswordsMatch(key,which):
|
def showStrength():
|
||||||
if which=="p":
|
global mode
|
||||||
matches = passwordInput.get()+key.char==cPasswordInput.get()
|
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:
|
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:
|
if passwordInput.get() and matches:
|
||||||
passwordMatchesString.set("✔")
|
passwordMatchesString.set("✔")
|
||||||
|
style.configure("PasswordMatches.TLabel",foreground="#149414")
|
||||||
startBtn["state"] = "normal"
|
startBtn["state"] = "normal"
|
||||||
else:
|
elif passwordInput.get() and not matches:
|
||||||
passwordMatchesString.set("×")
|
passwordMatchesString.set("❌")
|
||||||
|
style.configure("PasswordMatches.TLabel",foreground="#e3242b")
|
||||||
|
startBtn["state"] = "disabled"
|
||||||
|
elif not passwordInput.get():
|
||||||
|
passwordMatchesString.set("")
|
||||||
startBtn["state"] = "disabled"
|
startBtn["state"] = "disabled"
|
||||||
|
|
||||||
passwordInput.bind("<Key>",lambda key:doPasswordsMatch(key,"p"))
|
passwordInput.bind("<KeyRelease>",lambda e:[showStrength(),doPasswordsMatch()])
|
||||||
cPasswordInput.bind("<Key>",lambda key:doPasswordsMatch(key,"c"))
|
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
|
# Check box that indicates if password match
|
||||||
passwordMatchesString = tkinter.StringVar(tk)
|
passwordMatchesString = tkinter.StringVar(tk)
|
||||||
|
@ -275,7 +319,8 @@ passwordMatches = tkinter.ttk.Label(
|
||||||
tk,
|
tk,
|
||||||
textvariable=passwordMatchesString
|
textvariable=passwordMatchesString
|
||||||
)
|
)
|
||||||
passwordMatches.place(x=441,y=170)
|
passwordMatches.config(style="PasswordMatches.TLabel")
|
||||||
|
passwordMatches.place(x=242,y=172)
|
||||||
|
|
||||||
# Prompt user for optional metadata
|
# Prompt user for optional metadata
|
||||||
metadataString = tkinter.StringVar(tk)
|
metadataString = tkinter.StringVar(tk)
|
||||||
|
@ -367,14 +412,17 @@ rsBtn.place(x=18,y=369)
|
||||||
rsBtn["state"] = "disabled"
|
rsBtn["state"] = "disabled"
|
||||||
|
|
||||||
# "Reed-Solomon" which links to Wikipedia
|
# "Reed-Solomon" which links to Wikipedia
|
||||||
helpString = tkinter.StringVar(tk)
|
rsHelpString = tkinter.StringVar(tk)
|
||||||
helpString.set("(?)")
|
rsHelpString.set("(?)")
|
||||||
help = tkinter.ttk.Label(
|
rsHelp = tkinter.ttk.Label(
|
||||||
tk,
|
tk,
|
||||||
textvariable=helpString,
|
textvariable=rsHelpString,
|
||||||
cursor="hand2"
|
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
|
# Frame so start and cancel button can fill width
|
||||||
startFrame = tkinter.Frame(
|
startFrame = tkinter.Frame(
|
||||||
|
@ -396,10 +444,14 @@ startBtn = tkinter.ttk.Button(
|
||||||
startBtn.grid(row=0,column=0,stick="nesw")
|
startBtn.grid(row=0,column=0,stick="nesw")
|
||||||
startBtn["state"] = "disabled"
|
startBtn["state"] = "disabled"
|
||||||
|
|
||||||
|
def cancel():
|
||||||
|
global working
|
||||||
|
working = False
|
||||||
# Cancel button
|
# Cancel button
|
||||||
cancelBtn = tkinter.ttk.Button(
|
cancelBtn = tkinter.ttk.Button(
|
||||||
startFrame,
|
startFrame,
|
||||||
text="Cancel"
|
text="Cancel",
|
||||||
|
command=cancel
|
||||||
)
|
)
|
||||||
cancelBtn.grid(stick="nesw")
|
cancelBtn.grid(stick="nesw")
|
||||||
cancelBtn.grid(row=0,column=1)
|
cancelBtn.grid(row=0,column=1)
|
||||||
|
@ -603,6 +655,7 @@ def filesDragged(draggedFiles):
|
||||||
inputString.set(inputFile.split("/")[-1]+suffix)
|
inputString.set(inputFile.split("/")[-1]+suffix)
|
||||||
|
|
||||||
prompt.pack_forget()
|
prompt.pack_forget()
|
||||||
|
statusString.set("Ready.")
|
||||||
|
|
||||||
# UTF-8 decode error
|
# UTF-8 decode error
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
|
@ -648,6 +701,7 @@ def work():
|
||||||
reedsoloErrors = 0
|
reedsoloErrors = 0
|
||||||
password = passwordInput.get().encode("utf-8")
|
password = passwordInput.get().encode("utf-8")
|
||||||
metadata = metadataInput.get("1.0",tkinter.END).encode("utf-8")
|
metadata = metadataInput.get("1.0",tkinter.END).encode("utf-8")
|
||||||
|
cancelBtn["state"] = "normal"
|
||||||
|
|
||||||
# Decide if encrypting or decrypting
|
# Decide if encrypting or decrypting
|
||||||
if mode=="encrypt":
|
if mode=="encrypt":
|
||||||
|
@ -655,12 +709,6 @@ def work():
|
||||||
else:
|
else:
|
||||||
outputFile = outputInput.get()
|
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
|
# Set progress bar indeterminate
|
||||||
progress.config(mode="indeterminate")
|
progress.config(mode="indeterminate")
|
||||||
progress.start(15)
|
progress.start(15)
|
||||||
|
@ -811,6 +859,18 @@ def work():
|
||||||
|
|
||||||
Thread(target=updateStats,daemon=True,args=(total,)).start()
|
Thread(target=updateStats,daemon=True,args=(total,)).start()
|
||||||
while True:
|
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:
|
if mode=="decrypt" and reedsolo:
|
||||||
piece = fin.read(1104905)
|
piece = fin.read(1104905)
|
||||||
else:
|
else:
|
||||||
|
@ -976,12 +1036,12 @@ def work():
|
||||||
working = False
|
working = False
|
||||||
|
|
||||||
def updateStats(total):
|
def updateStats(total):
|
||||||
global startTime,previousTime,done,stopUpdating,reedsolo,reedsoloFixed,reedsoloErrors
|
global startTime,previousTime,done,stopUpdating,reedsolo,reedsoloFixed,reedsoloErrors,working
|
||||||
while True:
|
while True:
|
||||||
validStatus = (
|
validStatus = (
|
||||||
statusString.get().startswith("Working") or statusString.get().startswith("Deriving")
|
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
|
elapsed = (datetime.now()-previousTime).total_seconds() or 0.0001
|
||||||
sinceStart = (datetime.now()-startTime).total_seconds() or 0.0001
|
sinceStart = (datetime.now()-startTime).total_seconds() or 0.0001
|
||||||
previousTime = datetime.now()
|
previousTime = datetime.now()
|
||||||
|
@ -1032,6 +1092,8 @@ def secureWipe(fin):
|
||||||
|
|
||||||
# Reset UI to state where no files are selected
|
# Reset UI to state where no files are selected
|
||||||
def resetUI():
|
def resetUI():
|
||||||
|
global working
|
||||||
|
working = False
|
||||||
inputString.set(strings[18])
|
inputString.set(strings[18])
|
||||||
inputLabel["state"] = "normal"
|
inputLabel["state"] = "normal"
|
||||||
clearInput["state"] = "disabled"
|
clearInput["state"] = "disabled"
|
||||||
|
@ -1050,7 +1112,8 @@ def resetUI():
|
||||||
cPasswordInput["state"] = "normal"
|
cPasswordInput["state"] = "normal"
|
||||||
cPasswordInput.delete(0,"end")
|
cPasswordInput.delete(0,"end")
|
||||||
cPasswordInput["state"] = "disabled"
|
cPasswordInput["state"] = "disabled"
|
||||||
passwordMatchesString.set("×")
|
passwordMatchesString.set("")
|
||||||
|
style.configure("PasswordStrength.TLabel",foreground="")
|
||||||
metadataFrame.config(bg="#e5eaf0")
|
metadataFrame.config(bg="#e5eaf0")
|
||||||
metadataInput.config(bg="#fbfcfc")
|
metadataInput.config(bg="#fbfcfc")
|
||||||
metadataInput.config(fg="#000000")
|
metadataInput.config(fg="#000000")
|
||||||
|
@ -1074,6 +1137,10 @@ def resetUI():
|
||||||
|
|
||||||
# Set UI to encryption state
|
# Set UI to encryption state
|
||||||
def setEncryptionUI():
|
def setEncryptionUI():
|
||||||
|
global working
|
||||||
|
working = False
|
||||||
|
clearInput["state"] = "normal"
|
||||||
|
clearInput.config(cursor="hand2")
|
||||||
outputLabel["state"] = "normal"
|
outputLabel["state"] = "normal"
|
||||||
outputInput["state"] = "normal"
|
outputInput["state"] = "normal"
|
||||||
outputFrame.config(width=410)
|
outputFrame.config(width=410)
|
||||||
|
@ -1090,12 +1157,17 @@ def setEncryptionUI():
|
||||||
eraseBtn["state"] = "normal"
|
eraseBtn["state"] = "normal"
|
||||||
rsBtn["state"] = "normal"
|
rsBtn["state"] = "normal"
|
||||||
startBtn["state"] = "normal"
|
startBtn["state"] = "normal"
|
||||||
|
cancelBtn["state"] = "disabled"
|
||||||
progress.stop()
|
progress.stop()
|
||||||
progress.config(mode="determinate")
|
progress.config(mode="determinate")
|
||||||
progress["value"] = 0
|
progress["value"] = 0
|
||||||
|
|
||||||
# Set UI to decryption state
|
# Set UI to decryption state
|
||||||
def setDecryptionUI():
|
def setDecryptionUI():
|
||||||
|
global working
|
||||||
|
working = False
|
||||||
|
clearInput["state"] = "normal"
|
||||||
|
clearInput.config(cursor="hand2")
|
||||||
outputLabel["state"] = "normal"
|
outputLabel["state"] = "normal"
|
||||||
outputInput["state"] = "normal"
|
outputInput["state"] = "normal"
|
||||||
outputFrame.config(width=440)
|
outputFrame.config(width=440)
|
||||||
|
@ -1109,6 +1181,7 @@ def setDecryptionUI():
|
||||||
metadataInput["state"] = "disabled"
|
metadataInput["state"] = "disabled"
|
||||||
keepBtn["state"] = "normal"
|
keepBtn["state"] = "normal"
|
||||||
startBtn["state"] = "normal"
|
startBtn["state"] = "normal"
|
||||||
|
cancelBtn["state"] = "disabled"
|
||||||
progress.stop()
|
progress.stop()
|
||||||
progress.config(mode="determinate")
|
progress.config(mode="determinate")
|
||||||
progress["value"] = 0
|
progress["value"] = 0
|
||||||
|
|
Loading…
Reference in New Issue