#!/usr/bin/env python from getopt import getopt from sys import stdout, argv, exit from os.path import isfile, isdir from os import getcwd, system from string import split, strip, find program = 'difxcopy' version = '0.4' author = 'Walter Brisken' verdate = '20150126' fileTypes = ['input', 'calc', 'flag'] def usage(prog): prefixes = '' for f in fileTypes: prefixes = prefixes + f + ' ' print '\n%s ver. %s %s %s' % (program, version, author, verdate) print '\nA program to copy DiFX input (and other) files to a different directory,\nproperly modifying the path of references to other files in the process.\nThis program is typically run by difxqueue.' print '\nUsage: %s [options] [ [ ... ] ] \n' % prog print 'options can include\n' print ' --help' print ' -h print this help information and quit\n' print ' --verbose' print ' -v be more verbose in operation\n' print 'jobPrefixN is the prefix of a job name, e.g., mt911_03 would be\n the prefix for files mt911_03.input and mt911_03.calc.\n' print 'destDir is the destination directory for the copy.\n' print '\nFiles with the following suffixes will be copied:' print ' %s\n' % prefixes exit(0) def outstring(k, v): key = k + ':' return '%-20s%s' % (key, v) def handleVex(pathName, destination, verbose, vexFiles): pair = [pathName, destination] if not pair in vexFiles: vexFiles.append(pair) cmd = 'cp %s %s' % (pathName, destination) if verbose: print 'Vex copy %s --> %s\n' % (pathName, destination) system(cmd) else: if verbose > 1: print 'Not copying vex file %s to %s more than once\n' % (pathName, destination) def copyfile(pathName, destination, listOfFiles, verbose, vexFiles): if destination[-1] == '/': dest = destination else: dest = destination + '/' fileName = dest + split(pathName, '/')[-1] if pathName in listOfFiles: return [] else: listOfFiles.append(pathName) if isdir(pathName): if verbose: print 'Skipping %s as it is a directory.' % pathName return [] if not isfile(pathName): if verbose: print 'File %s not found. Skipping.' % pathName return [] if verbose: print '%s --> %s' % (pathName, fileName) indatalines = open(pathName, 'r').readlines() out = open(fileName, 'w') changedFiles = [] indatatable = False for indata in indatalines: colonPos = find(indata, ':') if len(indata) < 21: outdata = indata elif colonPos < 1: outdata = indata elif indata[0:5] == 'FILE ' and indatatable: outdata = indata elif indata[0] == '@': outdata = indata elif indata[0:12] == 'DATA FORMAT:': outdata = indata else: fn = strip(indata[colonPos+1:]) s = split(fn, '/') if len(s) == 1 or fn[0] != '/' or split(indata, ':')[0] == 'DATA FORMAT': outdata = indata else: outdata = outstring(indata[:colonPos], dest + s[-1]) + '\n' changedFiles.append(fn) if verbose > 1 and indata != outdata: stdout.write(' <-- %s' % indata) stdout.write(' --> %s' % outdata) out.write(outdata) if len(indata.split()) > 2 and indata.split()[0] == 'D/STREAM' \ and indata.split()[2] == 'FILES:': indatatable = True out.close() if verbose: print '' for f in changedFiles: pathName = f if pathName[0] != '/': pathName = getcwd()+'/'+pathName if len(pathName) > 4 and pathName[-4:] == '.vex': handleVex(pathName, destination, verbose, vexFiles) else: copyfile(pathName, destination, listOfFiles, verbose, vexFiles) def copyfiles(jobPrefix, destination, verbose, vexFiles): j = split(jobPrefix)[-1] listOfFiles = [] for f in fileTypes: pathName = jobPrefix + '.' + f if pathName[0] != '/': pathName = getcwd()+'/'+pathName if isfile(pathName) and pathName not in listOfFiles: copyfile(pathName, destination, listOfFiles, verbose, vexFiles) prefixes = [] verbose = 0 for a in argv[1:]: if a[0] == '-': if a in ['-h', '--help']: usage(argv[0]) if a in ['-v', '--verbose']: verbose += 1 else: if a[-6:] == '.input': jobPrefix = a[:-6] else: jobPrefix = a prefixes.append(jobPrefix) if len(prefixes) < 2: usage(argv[0]) destination = prefixes[-1] prefixes = prefixes[:-1] vexFiles = [] for p in prefixes: if not isfile(p) and not isfile(p+'.input'): print 'No job named %s found here. Continuing anyway.' % p else: copyfiles(p, destination, verbose, vexFiles)