Welcome, guest | Sign In | My Account | Store | Cart
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'
    

    

History