1 #!/usr/bin/env python
  2 # encoding: utf-8
  3 
  4 import re, os, getopt, sys
  5 from getopt import (getopt, error)
  6 import scriptutil as SU
  7 
  8 toolName = sys.argv[0].split("/")[-1].strip()
  9 help_message = '''
 10 %s: a tool to rename a set of numbered files so that they
 11 are 10 "slots" apart.
 12 
 13 %s [-n] [-p path] [-v]
 14 
 15     -c cmd  | --cmd cmd   : rename command to use (default: 'mv')
 16     -n      | --noaction  : no action, just show what would be done
 17     -p path | --path path : path where the files reside
 18     -v      | --verbose   : verbose output
 19 ''' % (toolName, toolName)
 20 
 21 class Usage(Exception):
 22     def __init__(self, msg):
 23         self.msg = msg
 24 
 25 def main(argv=None):
 26     verbose = noaction = False
 27     nfpath = '.'
 28     rcmd = 'mv'
 29     # command line arguments handling
 30     if argv is None: argv = sys.argv
 31     try:
 32         # no command line args? print help.
 33         if not argv[1:]: raise Usage(help_message.lstrip())
 34         try:
 35             opts, args = getopt(argv[1:], "hc:p:nv", ["help", "cmd=", "path=",
 36                                                       "noaction", "verbose"])
 37         except error, msg: raise Usage(msg)
 38 
 39         # option processing
 40         for option, value in opts:
 41             if option == "-n": noaction = True
 42             if option == "-v": verbose = True
 43             if option in ("-h", "--help"): raise Usage(help_message.lstrip())
 44             if option in ("-c", "--cmd"): rcmd = value
 45             if option in ("-p", "--path"): nfpath = value
 46     except Usage, err:
 47         print >> sys.stderr, str(err.msg)
 48         print >> sys.stderr, "For help use --help"
 49         return 2
 50 
 51     # template of command to run in order to rename/resequence a numbered file
 52     template = "%s %%s %%s%%03d-%%s" % rcmd
 53     # regex for finding and taking apart a numbered file (path)
 54     numberedf = re.compile('^(.+/)(?:\d{3}-)?([^/]+)$')
 55     # ignore all subversion internal files
 56     ignore_svn = lambda s: '.svn' not in s
 57 
 58     # get the list of files and sort it
 59     files = sorted(SU.ffind(nfpath, namefs=(ignore_svn, numberedf.search)))
 60 
 61     # iterate over all files found
 62     for fidx, f in enumerate(files):
 63         m = numberedf.match(f)
 64         if m:
 65             # found a numbered file, compute its (potentially) new name
 66             nfn = "%s%03d-%s" % (m.group(1) or '', (fidx+1)*10, m.group(2))
 67             if f != nfn:    # current and new names different?
 68                 # yes, build the command string for the file at hand
 69                 cmd = template % (f, m.group(1) or '', (fidx+1)*10, m.group(2))
 70                 if noaction: print(cmd)
 71                 else:
 72                     if verbose: print("running: '%s'" % cmd)
 73                     os.system(cmd)
 74             else:
 75                 if verbose: print("ok: %s" % f)
 76 
 77 if __name__ == '__main__':
 78     main()