From a77dc1c724c7980b94050c6549f402336c750de7 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sun, 15 Jul 2018 19:21:06 -0400 Subject: [PATCH] Fixed message box text width, renamed Display Hash, added Duplicate file finder FINALLY got the message box text width sizing correct. Required change to Text Elements so watch out for possible side effects. Added a new Duplicate File Finder demo program that uses an input form an a progress meter --- ...sh1and256.py => Demo DisplayHash1and256.py | 26 ++++++++- Demo DuplicateFileFinder.py | 58 +++++++++++++++++++ PySimpleGUI.py | 15 +++-- 3 files changed, 91 insertions(+), 8 deletions(-) rename DemoDisplayHash1and256.py => Demo DisplayHash1and256.py (80%) create mode 100644 Demo DuplicateFileFinder.py diff --git a/DemoDisplayHash1and256.py b/Demo DisplayHash1and256.py similarity index 80% rename from DemoDisplayHash1and256.py rename to Demo DisplayHash1and256.py index 1aa0f902..fa4545cc 100644 --- a/DemoDisplayHash1and256.py +++ b/Demo DisplayHash1and256.py @@ -66,6 +66,25 @@ def HashManuallyBuiltGUI(): else: SG.MsgBoxError('Display A Hash in PySimpleGUI', '* Cancelled *') +def HashManuallyBuiltGUINonContext(): + # ------- Form design ------- # + form = SG.FlexForm('SHA-1 & 256 Hash', AutoSizeText=True) + form_rows = [[SG.Text('SHA-1 and SHA-256 Hashes for the file')], + [SG.InputText(), SG.FileBrowse()], + [SG.Submit(), SG.Cancel()]] + (button, (source_filename, )) = form.LayoutAndShow(form_rows) + + if button == 'Submit': + if source_filename != '': + hash_sha1 = compute_sha1_hash_for_file(source_filename).upper() + hash_sha256 = compute_sha256_hash_for_file(source_filename).upper() + SG.MsgBox( 'Display A Hash in PySimpleGUI', 'The SHA-1 Hash for the file\n', source_filename, hash_sha1, 'SHA-256 is', hash_sha256, LineWidth=75) + else: SG.MsgBoxError('Display A Hash in PySimpleGUI', 'Illegal filename') + else: + SG.MsgBoxError('Display A Hash in PySimpleGUI', '* Cancelled *') + + + # ---------------------------------------------------------------------- # # Compute and display SHA1 hash # @@ -80,7 +99,7 @@ def HashMostCompactGUI(): # ------- OUTPUT GUI results portion ------- # if rc == True: - hash = compute_sha1_hash_for_file(source_filename).upper() + hash = compute_sha1_hash_for_file(source_filename) SG.MsgBox('Display Hash - Compact GUI', 'The SHA-1 Hash for the file\n', source_filename, hash) else: SG.MsgBox('Display Hash - Compact GUI', '* Cancelled *') @@ -90,8 +109,9 @@ def HashMostCompactGUI(): # Our main calls two GUIs that act identically but use different calls # # ---------------------------------------------------------------------- # def main(): - # HashMostCompactGUI() - HashManuallyBuiltGUI() + HashManuallyBuiltGUINonContext() + HashMostCompactGUI() + # ====____====____==== Pseudo-MAIN program ====____====____==== # # This is our main-alike piece of code # diff --git a/Demo DuplicateFileFinder.py b/Demo DuplicateFileFinder.py new file mode 100644 index 00000000..b32f8cf1 --- /dev/null +++ b/Demo DuplicateFileFinder.py @@ -0,0 +1,58 @@ +import hashlib +import os +import win32clipboard +import PySimpleGUI as gg + + +# ====____====____==== FUNCTION DeDuplicate_folder(path) ====____====____==== # +# Function to de-duplicate the folder passed in # +# --------------------------------------------------------------------------- # +def FindDuplicatesFilesInFolder(path): + shatab = [] + total = 0 + small = (1024) + small_count, dup_count, error_count = 0,0,0 + pngdir = path + if not os.path.exists(path): + gg.MsgBox('De-Dupe', '** Folder doesn\'t exist***', path) + return + pngfiles = os.listdir(pngdir) + total_files = len(pngfiles) + not_cancelled = True + for idx, f in enumerate(pngfiles): + if not gg.EasyProgressMeter('Counting Duplicates', idx+1, total_files, 'Counting Duplicate Files'): + break + total += 1 + fname = os.path.join(pngdir, f) + if os.path.isdir(fname): + continue + x = open(fname, "rb").read() + + m = hashlib.sha256() + m.update(x) + f_sha = m.digest() + if f_sha in shatab: + # os.remove(fname) + dup_count += 1 + continue + shatab.append(f_sha) + + msg = f'{total} Files processed\n'\ + f'{dup_count} Duplicates found\n' + gg.MsgBox('Duplicate Finder Ended', msg) + +# ====____====____==== Pseudo-MAIN program ====____====____==== # +# This is our main-alike piece of code # +# + Starts up the GUI # +# + Gets values from GUI # +# + Runs DeDupe_folder based on GUI inputs # +# ------------------------------------------------------------- # +if __name__ == '__main__': + + source_folder = None + rc, source_folder = gg.GetPathBox('DeDuplicate a Folder\'s image files', 'Enter path to folder you wish to find duplicates in') + if rc is True and source_folder is not None: + FindDuplicatesFilesInFolder(source_folder) + else: + gg.MsgBox('Cancelling', '*** Cancelling ***') + exit(0) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 28469b3c..1e45abc4 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -18,7 +18,7 @@ DEFAULT_ELEMENT_PADDING = (5,3) # Padding between elements (row, col) in DEFAULT_AUTOSIZE_TEXT = False DEFAULT_FONT = ("Helvetica", 10) -DEFAULT_BORDER_WIDTH = 7 +DEFAULT_BORDER_WIDTH = 6 DEFAULT_AUTOCLOSE_TIME = 3 # time in seconds to show an autoclose form MAX_SCROLLED_TEXT_BOX_HEIGHT = 50 #################### COLOR STUFF #################### @@ -973,11 +973,13 @@ def ConvertFlexToTK(MyFlexForm): stringvar = tk.StringVar() element.TKStringVar = stringvar stringvar.set(display_text) + if auto_size_text: + width = 0 tktext_label = tk.Label(tk_row_frame,anchor=tk.NW, textvariable=stringvar, width=width, height=height, justify=tk.LEFT, bd=border_depth, fg=element.TextColor) # tktext_label = tk.Label(tk_row_frame,anchor=tk.NW, text=display_text, width=width, height=height, justify=tk.LEFT, bd=border_depth) # Set wrap-length for text (in PIXELS) == PAIN IN THE ASS wraplen = tktext_label.winfo_reqwidth() # width of widget in Pixels - tktext_label.configure( anchor=tk.NW, font=font, wraplen=wraplen*2 ) # set wrap to width of widget + tktext_label.configure(anchor=tk.NW, font=font, wraplen=wraplen*2 ) # set wrap to width of widget tktext_label.pack(side=tk.LEFT) # ------------------------- BUTTON element ------------------------- # elif element_type == BUTTON: @@ -1240,20 +1242,23 @@ def MsgBox(*args, ButtonColor=None, ButtonType=MSG_BOX_OK, AutoClose=False, Aut args_to_print = [''] else: args_to_print = args - with FlexForm(args_to_print[0], AutoSizeText=True, ButtonColor=ButtonColor, AutoClose=AutoClose, AutoCloseDuration=AutoCloseDuration, Icon=Icon, Font=Font) as form: + with FlexForm(args_to_print[0], AutoSizeText=True, ButtonColor=ButtonColor, AutoClose=AutoClose, AutoCloseDuration=AutoCloseDuration, Icon=Icon, Font=Font) as form: max_line_total, total_lines = 0,0 for message in args_to_print: # fancy code to check if string and convert if not is not need. Just always convert to string :-) # if not isinstance(message, str): message = str(message) message = str(message) - message_wrapped = textwrap.fill(message, LineWidth) + if message.count('\n'): + message_wrapped = message + else: + message_wrapped = textwrap.fill(message, LineWidth) message_wrapped_lines = message_wrapped.count('\n')+1 longest_line_len = max([len(l) for l in message.split('\n')]) width_used = min(longest_line_len, LineWidth) max_line_total = max(max_line_total, width_used) # height = _GetNumLinesNeeded(message, width_used) height = message_wrapped_lines - form.AddRow(Text(message_wrapped, Size=(width_used, height), AutoSizeText=True),) + form.AddRow(Text(message_wrapped, AutoSizeText=True)) total_lines += height pad = max_line_total-15 if max_line_total > 15 else 1