mHelpText = ''' # ---------------------------------------------- # Name: DoM # Description: Expand and execute command from menu ## D20H-53 Expand and execute command # # Author: Philip S. Rist # Date: 10/26/2010 # Copyright 2010 by St. Thomas Software # ---------------------------------------------- # This program is freeware. It may be used # for any moral purpose. You use it at your # own risk. St. Thomas Software makes no # guarantees to its fitness to do anything. # # If you feel you must pay for it. Please # send one million dollars to # # The International Rescue Committee # 122 East 42nd Street # New York, N.Y. 10168-1289 # # Ok, we are in a recession. So, make it a half # million. # DoM.py - # The specified command in the specified section in the specified menu file will # be expanded with Do.py and executed. # Usage examples: # #[HKEY_CLASSES_ROOT\*\Shell\Rundom] #@="Run" #"EditFlags"=hex:01,00,00,00 #[HKEY_CLASSES_ROOT\*\Shell\Rundom\Command] #@="c:\\sys\\python25\\pythonw.exe c:\\bin\\dom.py -m c:\bin\menus.ini \"%1\" project open " # # Syntax: # dom.py [ options ] <file path> <section> <command key> # # Options: # -d <path> - set current working directory # -e <name>=<value> - set environment variable # -h - display this text, everything else is ignored # -l - list available commands, everything else is ignored # -m <menu path> - set path to menu file # default: '{o}\menus.ini;{i}\menus.ini' <- can be changed # -v - run in verbose mode # Sample menu file [DOS] Open,c:\source\TextFiles\qeditor.exe "{a}" ; Open file Print,c:\windows\nodepad.exe /P "{a}" ; Print file Edit,c:\windows\system32\wscript.exe c:\bin\editit.vbs "{a}" ; Edit file with Notetab Save,C:\Windows\system32\wscript.exe c:\bin\Util.vbs /S "{a}" Has Been Ssved,C:\Windows\system32\wscript.exe c:\bin\Util.vbs /K "{a}" UnTabify,c:\sys\python25\python.exe c:\sys\python25\tools\scripts\untabify.py "{a}" U2M,c:\bin\u2m.bat "{a}" Echo,c:\bin\messagebox.exe "{a}" Dir,c:\windows\system32\cmd.exe /C dir "{p}\*.{e}" ''' import sys import os import getopt import Do # Recipe: 577439 import Do2 # Recipe: 577440 import subprocess def FindCommand(pKey, pFilePath, pSearchPath, pSection, pList=False, pVerbose=False): ''' Find command keyword and extract containing line pKey -- String identifying line to use as command template pFilePath -- File to use in macro expansion pSearchPath -- File to scan for command pSection -- Section containing command pList -- ''' if pVerbose: print 'DoM.py FindCommand:', pKey, pFilePath, pSearchPath, pSection if not os.path.exists(pSearchPath): lCommand = '' print 'DoM.py Could not find menu file', pSearchPath else: lSection = pSection.lower() lKey = pKey.lower() # ---- Load menu file lFile = open(pSearchPath, 'r') lText = lFile.readlines() lFile.close() if len(lText) < 1: print 'DoM.py Menu', pSearchPath, 'read failed' lFound = False lCommand = '' lCount = 0 if pList: print 'DoM.py Available commands in', pSearchPath # ---- Scan menu file for lLine in lText: lLine = lLine.lstrip() if len(lLine) < 1: continue # ---- Start of section if lLine[0] == '[': lCount = 0 lPos = lLine.find(']') if lPos > 0: lFoundSection = lLine[1:lPos].lower() else: lFoundSection = '' # ---- Check for conditions, conditions are ignored if lFoundSection[0] == '/': lPos2 = lFoundSection.rfind('/') if lPos2 >= 0: lFoundSection = lFoundSection[lPos2+1:] elif lFoundSection[0] == '!': lPos2 = lFoundSection.rfind('!') if lPos2 >= 0: lFoundSection = lFoundSection[lPos2+1:] #if lSection != lFoundSection and lSection != '*': if not lFoundSection.startswith(lSection) and lSection != '*': if pVerbose: print 'DoM.py not found', lSection, 'in', lFoundSection if lFound == True: break continue elif lSection != '*' and lFound == True: break else: if pVerbose: print 'DoM.py found', lSection, 'in', lFoundSection if pList: print 'DoM.py Section:', lFoundSection lFound = True # ---- Comments elif lLine[0] == ';': if lFound and pList: print 'DoM.py ', lLine, # ---- Command lines and label lines else: if not lFound: continue if lLine[0] == '-': continue lPos = lLine.find(',') if lPos > 0: lMatch = lLine[0:lPos].lower() else: continue # ---- Check for conditions, conditions are ignored if lMatch[0] == '/': lPos2 = lMatch.rfind('/') if lPos2 >= 0: lMatch = lMatch[lPos2+1:] elif lMatch[0] == '!': lPos2 = lMatch.rfind('!') if lPos2 >= 0: lMatch = lMatch[lPos2+1:] lCount += 1 if pList: if lPos > 0: lLineText = lLine[lPos+1:] print "DoM.py %5d: %-20s| %s" % (lCount, lMatch, lLineText), # ---- Check for matching command #if lKey == lMatch: # must match command key if lMatch.startswith(lKey): # command key starts with key lCommand = lLine[lPos+1:] if pVerbose: print 'DoM.py found command', lKey, 'in', lMatch, 'for', lCommand break else: print 'DoM.py no command found in', pSearchPath, pSection return lCommand[0:-1] def Expand(pArgs, pFilePath, pSearchPath, pSection, pSep='!!', pList=False, pVerbose=False): ''' Extract command from file and replace all macros pArgs -- Args passed to program except file path and section name pFilePath -- File to use in macro expansion pSearchPath -- File to scan for command ' pCount -- Number of lines at the start of the file to scan pSep -- String used to identify end of command pHelp -- True to display available commands ''' # ---- Find command lCommand = FindCommand(pArgs[0], pFilePath, pSearchPath, pSection, pList=pList, pVerbose=pVerbose) # ---- Expand and insert/append any passed arguments # Arguments on original pb.py command line will replace {} from left to right # otherwise they will be appended to the end of the command lStart = 1 if len(lCommand) > 0: if len(pArgs) > lStart: for lArg in pArgs[lStart:]: if lArg.find('{') >= 0: lArg = Do2.ExpandArg(lArg, pFilePath, '') if len(lArg) > 0: try: lTest = os.path.abspath(lArg) if os.path.exists(lTest): if lTest.find(" ") > 0: lTest = '"' + lTest + '"' lArg = lTest except: pass lPos = lCommand.find('{}') if lPos >= 0: lCommand = lCommand[0:lPos] + lArg + lCommand[lPos+2:] else: lCommand += ' ' + lArg # ---- Prevent unwanted arguments appended to command lPos = lCommand.rfind(pSep) if lPos > 0: lCommand = lCommand[0:lPos] # ---- Expand all remaining macros if lCommand.find('{') >= 0: lCommand = Do.Expand(lCommand, pFilePath) return lCommand def submitnow(pArgs, pFilePath, pSearchPath, pSection, pVerbose, pList=False): 'Expand and submit command' if pVerbose: print 'DoM.py File path:', pFilePath print 'DoM.py Menu path:', pSearchPath print 'DoM.py Section: ', pSection print 'DoM.py Arguments:', pArgs lCommand = Expand(pArgs, pFilePath, pSearchPath, pSection, pList=pList, pVerbose=pVerbose) # ---- Any macro not expanded will be assumed to be an environment variable # If %...% had been used it would have been replaced when pb.py was run lCommand = lCommand.replace('{}',' ') #<-- may want to do something else lCommand = lCommand.replace('{', '%') # try to replace with environment variable lCommand = lCommand.replace('}', '%') if len(lCommand) == 0: print 'DoM.py Expansion failed' else: lCommand = '"' + lCommand + '"' if pVerbose: print 'DoM.py Submitting: ', lCommand subprocess.Popen(lCommand, shell=True) def setenviron(pValue, pFileName): 'Set environment variable' lParts = pValue.split('=') if len(lParts) > 1: lKey = lParts[0] lValue = lParts[1] if lValue.find('{') >= 0: lValue = Do2.ExpandArg(lValue, pFileName, '') os.environ[lKey] = lValue else: os.environ[pValue] = '' if __name__ == '__main__': (mOptions, mArgs) = getopt.getopt(sys.argv[1:], 'd:e:hlm:v') mVerbose = False mHelp = False mList = False mSearchPath = '{o}\menus.ini;{i}\menus.ini' for (mKey, mValue) in mOptions: if mKey == '-d': # Set current directory if mValue.find('{') >= 0: if len(mArgs) > 2: mFilePath = os.path.abspath(mArgs[0]) mValue = Do.ExpandArg(mValue, mFilePath) else: print 'DoM.py No primary file, could not set directory' break else: os.chdir(mValue) elif mKey == '-e': # Set environment variable setenviron(mValue, mFilePath) elif mKey == '-h': print mHelpText mHelp = True elif mKey == '-l': mList = True elif mKey == '-m': # mSearchPath = mValue elif mKey == '-v': mVerbose = True if len(mArgs) > 2: mFilePath = os.path.abspath(mArgs[0]) mSection = mArgs[1] if mSection.find('{'): mSection = Do.Expand(mSection, mFilePath) mKey = mArgs[2] if mKey.find('{'): mArgs[2] = Do.Expand(mKey, mFilePath) mArgs[2] = mArgs[2].replace('_', ' ') if mSearchPath.find('{') >= 0: mSearchPath = Do2.ExpandArg(mSearchPath, mFilePath, '') if mSearchPath[0] == '"': mSearchPath = mSearchPath[1:-1] mSearchPath = os.path.abspath(mSearchPath) if mHelp: print 'DoM.py Default menu: ', mSearchPath print 'DoM.py Default section:', mSection elif mList: Expand('???', mFilePath, mSearchPath, mSection, mVerbose, mList) else: submitnow(mArgs[2:], mFilePath, mSearchPath, mSection, mVerbose) elif mHelp == False: print 'DoM.pyCommand and/or file path missing'