#!/usr/local/bin/pythono """ """ from Tkinter import * import sys import tkFileDialog import gzip import string import os chunksize = 4096 fileToCompress = 0 fileToUncompress = 0 deleteOriginals = 0 onameC = 0 onameU = 0 proceed = 0 message = 0 AddTo = " " AddTo2 = " " addElem = " " KillVar = 0 root = Tk() #-------------------------------------------------------------------------------- # Suffixes. Compress and decompress are combined. #-------------------------------------------------------------------------------- suffixTableC = { '.pz3' : '.pzz', '.pz2' : '.p2z', '.cr2' : '.crz', '.cm2' : '.cmz', '.lt2' : '.ltz', '.hd2' : '.hdz', '.hr2' : '.hrz', '.pp2' : '.ppz', '.mt5' : '.mz5', '.fc2' : '.fcz', '.obj' : '.obz', '.psp' : '.psz', '.gmd' : '.gmz', '.gb1' : '.gbz', } suffixTableU = { '.pzz' : '.pz3', '.p2z' : '.pz2', '.crz' : '.cr2', '.cmz' : '.cm2', '.ltz' : '.lt2', '.hdz' : '.hd2', '.hrz' : '.hr2', '.ppz' : '.pp2', '.mz5' : '.mt5', '.fcz' : '.fc2', '.obz' : '.obj', '.psz' : '.psp', '.gmz' : '.gmd', '.gbz' : '.gb1' } openListC = '*.pz3 *.pz2 *.cr2 *.cm2 *.lt2 *.hd2 *.hr2 *.pp2 *.mt5 *.fc2 *.obj *.psp *.gmd *.gb1' openListU = '*.pzz *.p2z *.crz *.cmz *.ltz *.hdz *.ppz *.mz5 *.fcz *.obz *psz *.gmz *.gbz' #-------------------------------------------------------------------------------- # Figure out which OS we're running #-------------------------------------------------------------------------------- macver = 0 winver = 0 if(os.name == 'mac'): macver = 1 separator = ':' elif(os.name == 'dos' or os.name == 'nt'): winver = 1 separator = '\\' else: raise 'unrecognized operating system\n' if(macver): #---------------------------------------------------------------------------- # Keep a table for type #---------------------------------------------------------------------------- typeTable = { '.pzz' : 'PZZ ', '.p2z' : 'pz2Z', '.crz' : 'cr2Z', '.cmz' : 'cm2Z', '.ltz' : 'lt2Z', '.hdz' : 'hd2Z', '.hrz' : 'fc2Z', '.ppz' : 'pp2Z', '.mz5' : 'mt5Z', '.fcz' : 'fc2Z', '.pz3':'PZ3 ', '.pz2':'pz2 ', '.cr2':'cr2 ', '.cm2':'cm2 ', '.lt2':'lt2 ', '.hd2':'hd2 ', '.hr2':'fc2 ', '.pp2':'pp2 ', '.mt5':'mt5 ', '.fc2':'fc2 ' } #-------------------------------------------------------------------------------- def Stoppit(KillVar): ##Loop killer for recursion if KillVar ==1: #Without this it can go berserk and start dangerously tearing through the hard drive.... root.destroy() #----------------------------------------------------------------------------------------- def compressFile(fileToCompress, suffix, newSuffix, deleteOriginals): #if(string.find(fileToCompress, 'Default Guy.cr2') != -1): if(string.find(string.lower(fileToCompress), 'default guy.cr2') != -1): #TromNek case insensitive test return 0 newFileName = fileToCompress #extIndex = string.find(fileToCompress, suffix) extIndex = string.rfind(string.lower(fileToCompress), suffix) #TromNek, a more exact file extension search #if (extIndex == -1): if ( (extIndex + len(suffix)) != len(fileToCompress)): #TromNek, is it really the extension return -1 else: newFileName = newFileName[:extIndex] + newSuffix # change .*z3 to .*zz try: pz3 = open(fileToCompress, 'rb') except: return -2 try: #TromNek open a file object first pzzfo = open(newFileName, 'w+b') pzzfo.truncate(0) except: return -2 #pzz = gzip.GzipFile(newFileName, 'wb') pzz = gzip.GzipFile(fileobj=pzzfo, mode='wb') #TromNek pass gzip the file object instead of the name while 1: chunk = pz3.read(chunksize) # do the compression if(chunk == ""): break pzz.write(chunk) pz3.close() pzz.close() #TromNek next 13 lines hdrNameOffset = 10 # If there's a file name, where is is pzzfo.seek(hdrNameOffset + extIndex,0) # Seek the beginning of the file extension chunk = pzzfo.read( len(suffix) ) if chunk == newSuffix: # Make extra sure we want to do this pzzfo.seek(hdrNameOffset + extIndex,0) # Seek the beginning of the file extension, again pzzfo.write( suffix ) else: print "!!! Couldn't find file extension in header !!!" import struct pzzfo.seek( -4, 2 ) # original file size stored by GzipFile origfsize = struct.unpack("', newFileName if(deleteOriginals == 1): import os if os.stat(fileToCompress)[6] != origfsize: #TromNek minimum sanity check before deletion print '!!!Original file size does not equal value stored in gzip file!!! NOT DELETING ORIGINAL !!! ', os.stat(fileToCompress)[6], " != ",origfsize else: try: os.remove(fileToCompress) print ' (', fileToCompress, 'deleted)' except: print ' (Could not delete', fileToCompress print ' Permissions set to Read-Only?' #------------------------------------------------------------------------------------------------------ def uncompressFile(fileToUnCompress, suffix, newSuffix, deleteOriginals): if(string.find(fileToUnCompress, 'Default Guy.cr2') != -1): #if(string.find(string.lower(fileToCompress), 'default guy.cr2') != -1): #TromNek case insensitive test return 0 newFileName = fileToUnCompress extIndex = string.find(fileToUnCompress, suffix) #extIndex = string.rfind(string.lower(fileToCompress), suffix) #TromNek, a more exact file extension search if (extIndex == -1): #if ( (extIndex + len(suffix)) != len(fileToCompress)): #TromNek, is it really the extension return -1 else: newFileName = newFileName[:extIndex] + newSuffix # change .*z3 to .*zz try: pzz = gzip.GzipFile(fileToUnCompress, 'rb') except: return -2 pz3 = open(newFileName, 'wb') while 1: chunk = pzz.read(chunksize) # do the uncompression if(chunk == ""): break pz3.write(chunk) pz3.close() pzz.close() if(macver): # for mac version, we need to change file's import macfs # type and creator fs = macfs.FSSpec(newFileName) fs.SetCreatorType('PZ3A', typeTable[newSuffix]) print ' *** ', fileToUnCompress, ' ***' print ' -->', newFileName if(deleteOriginals == 1): import os try: os.remove(fileToUnCompress) print ' (', fileToUnCompress, 'deleted)' except: print ' (Could not delete', fileToUnCompress print ' Permissions set to Read-Only?' #------------------------------------------------------------------------------------------------ def visitC(something, dirname, names): if (recursive == 1) and (KillVar == 0): if fileToUncompress == 0: print 'Looking under directory:', dirname, '------' for name in names: for key in suffixTableC.keys(): #if (string.find(name, key) != -1): extIndex = string.rfind(string.lower(name), key ) #TromNek make sure it really is the extension. if ( (extIndex + len(key)) == len(name)): compressFile(dirname + separator + name, key, suffixTableC[key], deleteOriginals) break print from Tkinter import * #------------------------------------------------------------------------------------------ def visitU(something, dirname, names): if (recursive == 1) and (KillVar == 0): if fileToCompress == 0: print 'Looking under directory:', dirname, '------' for name in names: for key in suffixTableU.keys(): #if (string.find(name, key) != -1): extIndex = string.rfind(string.lower(name), key ) #TromNek make sure it really is the extension. if ( (extIndex + len(key)) == len(name)): uncompressFile(dirname + separator + name, key, suffixTableU[key], deleteOriginals) break print from Tkinter import * #----------------------------------------------------------------------------------------------- class App: def __init__(self, master, textMessage): global recurse, recursive, deleteOriginals, custUse recurse = IntVar() recurse.set(0) recursive = IntVar() recursive.set(0) custUse = IntVar() custUse.set(0) self.safety = 1 #To prevent "custom file list" checkbutton from looping at start self.master = master master.title("Poser Compressor") self.ButtonFrame = Frame(self.master,borderwidth=2,relief=RIDGE) self.ButtonFrame.grid(row=0,column=2) self.ListFrame = Frame(self.master,borderwidth=2,relief=RIDGE) self.ListFrame.grid(row = 0, column = 0) self.Label = Label(self.ListFrame,text="File Types:").grid(row=1, column=1) self.ListScroll = Scrollbar(self.ListFrame, orient=VERTICAL) self.ListScroll.grid( row=2, column=0,sticky=N+S+E) self.List = Listbox(self.ListFrame, height=20, width=10,selectmode=MULTIPLE,yscrollcommand = self.ListScroll.set) self.List.grid( row=2, column=1) self.ListScroll["command"] = self.List.yview TypeList = dict.items(suffixTableC) for i in TypeList: self.List.insert(END,i) self.Label = Label(self.ButtonFrame,text="Browse For Files").grid(row=0, column=0) self.buttonCompress = Button(self.ButtonFrame, text="Compress", command=self.openfileC) self.buttonCompress.grid(row = 3, column = 0) self.buttonUncompress = Button(self.ButtonFrame, text="Uncompress", command=self.openfileU) self.buttonUncompress.grid(row = 6, column = 0) self.buttonAddFile = Button(self.ButtonFrame, text="Add File Type", command=self.AddFile) self.buttonAddFile.grid(row = 9, column = 0) self.buttonClose = Button(self.ButtonFrame, text="Close", command=self.die) self.buttonClose.grid(row = 26, column = 0) self.List.bind("",self.handleSelect) #Useful? Yes. Delete fxn. #if custUse == 1: # self.List.bind("",self.handleCustom) #self.deleteVal = 0 #self.deleteVar = IntVar() self.deleteOrig = Checkbutton(self.ButtonFrame,text="Delete original files after compressing", variable=deleteOriginals, command=self.delFiles) self.deleteOrig.grid(row = 14, column = 0) #if recurse != 1: #recurse = 0 self.EntireFolder = Checkbutton(self.ButtonFrame,text="Process Entire Folder", variable=recurse, command=self.openfileR) self.EntireFolder.grid(row = 18, column = 0) #if recursive != 1: #recursive = 0 self.Subfolders = Checkbutton(self.ButtonFrame, text="Include Subfolders", variable=recursive, command=self.openfileS) self.Subfolders.grid(row=22, column = 0) self.UseCustom = Checkbutton(self.ButtonFrame,text="Use Custom File Type List", variable=custUse, command=self.handleCustom) self.UseCustom.grid(row=30, column = 0) self.Label = Label(self.master,text="Double-click to remove file types").grid(row = 2, column = 0) self.openfileR() #Priming the system to fend off IntVar value problems self.openfileS() #Emulate first clicks of checkbuttons self.handleCustom() #Okay, so it's a kludgy workaround.... def handleSelect(self,event): #self.handleGo() self.List.delete(ACTIVE) #Delete entries w/ double-click def handleGo(self): global openListC, openListU TempList = [] q = " " p = " " Selecteds = self.List.curselection() #You can see, here, that I have been learning from Ockham's code.... Sels = self.List.get(ACTIVE) #Hopefully you can't copyright variable names.... :) NumSel = len(Selecteds) print "number selected:" print NumSel if NumSel != 0: for i in Selecteds: Name = self.List.get(i) #print Name q,p = Name #Split the tuples suffixTableC[q] = p #Re-fill the suffix tables suffixTableU[p] = q openListC = " " openListU = " " for i in Selecteds: Name = self.List.get(i) q,p = Name q = "*" + q p = "*" + p openListC = (openListC + " " + q) #Re-fill the file open lists openListU = (openListU + " " + p) #print suffixTableC #print openListC #print suffixTableU #Testing verification #print openListU def die(self): self.master.destroy() self.master.quit() def handleCustom(self): global custUse, openListC, openListU, backupC, backupU, openCback, openUback if custUse ==0: custUse = 1 else: custUse = 0 print custUse if custUse == 1: NumSel = 0 if self.safety == 1: backupC = dict.copy(suffixTableC) #Back up original file tables only at start backupU = dict.copy(suffixTableU) openCback = openListC openUback = openListU Selecteds = self.List.curselection() NumSel = len(Selecteds) if NumSel != 0: dict.clear(suffixTableC) #Empty the file tables each time dict.clear(suffixTableU) openListC = " " #Clear the open file lists each time openListU = " " self.safety = 0 #A switch to prevent zero looping and to create backups only at start self.handleGo() if (custUse == 0) and (self.safety ==0): #When custom file types checkbox is unchecked dict.clear(suffixTableC) suffixTableC.update(backupC) #Restore old file tables from backup ##dict.clear(backupC) dict.clear(suffixTableU) suffixTableU.update(backupU) ##dict.clear(backupU) openListC = openCback #Restore old file open lists from backup #openCback = " " openListU = openUback #openUback = " " #print suffixTableC #Testing verification #print openListC #print suffixTableU #print openListU def openfileR(self): global recurse if recurse == 0: recurse = 1 else: recurse = 0 print recurse def openfileS(self): global recursive if recursive == 0: recursive = 1 else: recursive = 0 print recursive def delFiles(self): global deleteOriginals if deleteOriginals == 0: deleteOriginals = 1 else: deleteOriginals = 0 print deleteOriginals def AddFile(self): global AddTo, root d = self.MyDialog(root,AddTo) root.wait_window(d.top) self.boxAdd(addElem) def boxAdd(self,addElem): global AddTo addElem = AddTo AddTo = " " if addElem != " ": self.List.insert(END,addElem) #----------------------------------------------------------------------------------------- def openfileC(onameC): global message, names, dirname, listed, recurse, recursive, KillVar #proceed = 0 if recurse != 1: recurse = 0 if recursive != 1: recursive = 0 if recurse == 0: onameC = tkFileDialog.askopenfilename(filetypes=[("All Associated Files", openListC)]) print openListC if recurse == 1: message = tkFileDialog.askdirectory() if message != " ": dirname = message listed = os.listdir (message) if recursive == 0: names = listed if recursive == 1: if message != 0: dirname = message names = os.listdir (dirname) for i in names : onameC = i if onameC: proceed = 1 print onameC fileToCompress = onameC if recurse == 0: for key in suffixTableC.keys(): if (string.find(fileToCompress, key) != -1): compressFile(fileToCompress, key, suffixTableC[key], deleteOriginals) break elif (recurse ==1) and (recursive ==1): i = 0 for key in suffixTableC.keys(): if (i==0): message = message + key else: message = message + ', ' + key i = i + 1 try: #TromNek this allows us to run the script outside of poser initDir = poser.AppLocation() # <-this line was in the original script except: initDir = os.getcwd() # we must be running in native python fileIndex = string.rfind(initDir, separator) initDir = initDir[:fileIndex] dirToCompress = dirname #(proceed, dirToCompress, deleteOriginals) = message if proceed == 0: raise 'Script cancelled' print 'Recursing from ', dirToCompress, '\n\n' arg = None #TromNek next 15 lines reldir = separator+'Runtime'+separator # get path starting with first 'Runtime' folder #reldir = '' # or not dirToCompress = os.path.normpath( dirToCompress ) begpth = string.find( string.lower(dirToCompress+separator), string.lower(reldir) ) if (begpth < 1): begpth = 0 if ((winver==1) and (dirToCompress[1]==':')): begpth = 2 while (begpth < len(dirToCompress)) and (dirToCompress[begpth] == separator): begpth = begpth+1 # skip over path separators to get to the path if begpth > 0: os.chdir( dirToCompress[:begpth] ) # change to drive and initial folder of dirToCompress dirToCompress = dirToCompress[begpth:] # strip 'driveletter:\' and initial folder from dirToCompress os.path.walk(dirToCompress, visitC, arg) message = 0 print "Compression complete" KillVar = 1 Stoppit(KillVar) elif (recurse == 1) and (recursive==0): print 'Looking under directory:', dirname, '------' for name in names: for key in suffixTableC.keys(): #if (string.find(name, key) != -1): extIndex = string.rfind(string.lower(name), key ) #TromNek make sure it really is the extension. if ( (extIndex + len(key)) == len(name)): compressFile(dirname + separator + name, key, suffixTableC[key], deleteOriginals) break print "Compress, Folders, No Recursion, Done" #------------------------------------------------------------------------------------------------- def openfileU(onameU): global recurse, message, names, dirname, recursive, KillVar #proceed = 0 if recurse != 1: recurse = 0 if recursive != 1: recursive = 0 if recurse == 0: onameU = tkFileDialog.askopenfilename(filetypes=[("All Associated Files", openListU)]) if recurse == 1: message = tkFileDialog.askdirectory() if message != " ": dirname = message listed = os.listdir (message) if recursive == 0: names = listed if recursive == 1: if message != 0: dirname = message names = os.listdir (dirname) for i in names : onameU = i if onameU: proceed = 1 print onameU fileToUncompress = onameU if recurse == 0: for key in suffixTableU.keys(): if (string.find(fileToUncompress, key) != -1): uncompressFile(fileToUncompress, key, suffixTableU[key], deleteOriginals) break elif (recurse ==1) and (recursive ==1): i = 0 for key in suffixTableU.keys(): if (i==0): message = message + key else: message = message + ', ' + key i = i + 1 try: #TromNek this allows us to run the script outside of poser initDir = poser.AppLocation() # <-this line was in the original script except: initDir = os.getcwd() # we must be running in native python #initDir = poser.AppLocation() fileIndex = string.rfind(initDir, separator) initDir = initDir[:fileIndex] dirToUnCompress = dirname #(proceed, dirToUnCompress, deleteOriginals) = dialog(message, initDir) if proceed == 0: raise 'Script cancelled' print 'Recursing from ', dirToUnCompress, '\n\n' arg = None os.path.walk(dirToUnCompress, visitU, arg) message = 0 print "Uncompression complete" KillVar = 1 Stoppit(KillVar) elif (recurse == 1) and (recursive == 0): print names print 'Looking under directory:', dirname, '------' for name in names: for key in suffixTableU.keys(): #if (string.find(name, key) != -1): extIndex = string.rfind(string.lower(name), key ) #TromNek make sure it really is the extension. if ( (extIndex + len(key)) == len(name)): uncompressFile(dirname + separator + name, key, suffixTableU[key], deleteOriginals) break print #----------------------------------------------------------------------------------------------- class MyDialog: def __init__(self,parent,txt): top = self.top = Toplevel(parent) Label(top,text="Enter New Extensions").pack() self.e = Entry(top) self.e.insert(0,txt) self.e.pack(padx=5) Label(top,text="uncompressed extension").pack() self.e2 =Entry(top) self.e2.insert(10,txt) self.e2.pack(padx=5) Label(top,text="compressed extension").pack() b = Button(top, text="OK", command=self.ok) b.pack(pady=5) b2 = Button(top, text="Cancel", command=self.cancel) b2.pack(pady=5) def ok(self): global AddTo, root, parent fixit = self.e.get() fixit = string.lstrip(fixit,None) #Remove mysterious space at beginning of entry fixit2 = self.e2.get() fixit2 = string.lstrip(fixit2,None) nAddTo = ((fixit) ,(fixit2)) self.e = " " self.e2 = " " if nAddTo and nAddTo != " ": AddTo = nAddTo nAddTo = " " #App.boxAdd(self,addElem) self.top.destroy() if nAddTo == " ": self.top.destroy() def cancel(self): self.e = " " self.e2 = " " AddTo = " " nAddTo = " " self.top.destroy() #-------------------------------------------------------------------------------------------- app = App(root, "") root.mainloop() #--------------------------------------------------------------------------