Annotation of hatari/tools/atari-convert-dir.py, revision 1.1

1.1     ! root        1: #!/usr/bin/python2
        !             2: #
        !             3: # for Python3, remove sorting cmp function
        !             4: """
        !             5: Script to copy Atari files with (potentially) too long names from
        !             6: source directory into target directory, using in latter file names
        !             7: clipped to 8+3 characters.
        !             8: 
        !             9: Clipping is done like Atari GEMDOS functions would do it, so that
        !            10: those file names can then be moved/copied to Atari media from another
        !            11: OS.
        !            12: 
        !            13: If original long names work with Hatari GEMDOS HD emulation, the
        !            14: clipped names should work with normal TOS on real harddisk (image)!
        !            15: """
        !            16: import sys, os, shutil
        !            17: 
        !            18: def debug(msg):
        !            19:     sys.stderr.write("%s\n" % msg)
        !            20: 
        !            21: def error_exit(msg):
        !            22:     name = os.path.basename(sys.argv[0])
        !            23:     debug("\nUsage: %s <source dir> <target dir>" % name)
        !            24:     debug(__doc__)
        !            25:     debug("ERROR: %s!\n" % msg)
        !            26:     sys.exit(1)
        !            27: 
        !            28: newnames = {}
        !            29: 
        !            30: def check_conflicts(srcdir, dstdir):
        !            31:     # how much to clip from paths
        !            32:     srcskip = len(srcdir)+1
        !            33:     dstskip = len(dstdir)+1
        !            34:     print "\nNames that aren't unique:"
        !            35:     conflicts = False
        !            36:     for key,names in newnames.items():
        !            37:         if len(names) > 1:
        !            38:             conflicts = True
        !            39:             print "- %s: %s" % (key[dstskip:], [name[srcskip:] for name in names])
        !            40:     if not conflicts:
        !            41:         print "- none, all OK!"
        !            42: 
        !            43: def hash_names(original, newname):
        !            44:     if newname not in newnames:
        !            45:         newnames[newname] = []
        !            46:     newnames[newname].append(original)
        !            47: 
        !            48: def clip_name(name):
        !            49:     dot = name.rfind('.')
        !            50:     if dot >= 0:
        !            51:         base = name[:dot]
        !            52:         ext = name[dot+1:]
        !            53:         name = "%s.%s" % (base[:8], ext[:3])
        !            54:     else:
        !            55:         name = name[:8]
        !            56:     # TODO: map non-ASCII characters
        !            57:     return name.upper()
        !            58: 
        !            59: def dirs_last(a, b):
        !            60:     # in alphabetical order, dirs last
        !            61:     adir = os.path.isdir(a)
        !            62:     bdir = os.path.isdir(b)
        !            63:     if adir and bdir:
        !            64:         return cmp(a, b)
        !            65:     if adir:
        !            66:         return 1
        !            67:     if bdir:
        !            68:         return -1
        !            69:     return cmp(a, b)
        !            70: 
        !            71: def convert_dir(srcdir, dstdir):
        !            72:     print "\n%s/ -> %s/:" % (srcdir, dstdir)
        !            73:     try:
        !            74:         os.mkdir(dstdir)
        !            75:     except OSError:
        !            76:         debug("ERROR: directory creation failed, name conflict???")
        !            77:         return
        !            78:     # directory sorting requires full names
        !            79:     dircontents = [os.path.join(srcdir, x) for x in os.listdir(srcdir)]
        !            80:     for original in sorted(dircontents, cmp=dirs_last):
        !            81:         origname = os.path.basename(original)
        !            82:         clipname = clip_name(origname)
        !            83:         newname = os.path.join(dstdir, clipname)
        !            84:         hash_names(original, newname)
        !            85:         if os.path.isdir(original):
        !            86:             convert_dir(original, newname)
        !            87:         else:
        !            88:             print "- %s -> %s" % (origname, clipname)
        !            89:             try:
        !            90:                 shutil.copyfile(original, newname)
        !            91:             except IOError:
        !            92:                 debug("ERROR: file copy failed, name conflict (with read-only file)???")
        !            93:                 continue
        !            94:             shutil.copystat(original, newname)
        !            95: 
        !            96: def main(args):
        !            97:     if len(args) != 3:
        !            98:         error_exit("too few arguments")
        !            99:     srcdir = args[1]
        !           100:     dstdir = args[2]
        !           101:     if not os.path.isdir(srcdir):
        !           102:         error_exit("source directory '%s' doesn't exist" % srcdir)
        !           103:     if os.path.isdir(dstdir):
        !           104:         error_exit("target directory '%s' exists, remove it to continue" % dstdir)
        !           105:     if srcdir[-1] == os.path.sep:
        !           106:         srcdir = srcdir[:-1]
        !           107:     if dstdir[-1] == os.path.sep:
        !           108:         dstdir = dstdir[:-1]
        !           109:     if dstdir.startswith(srcdir+os.path.sep):
        !           110:         error_exit("target directory '%s' is inside source directory '%s'" % (srcdir, dstdir))        
        !           111:     convert_dir(srcdir, dstdir)
        !           112:     check_conflicts(srcdir, dstdir)
        !           113: 
        !           114: if __name__ == '__main__':
        !           115:     main(sys.argv)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.