#!/usr/bin/env python # Version 1.0 # A bit like cp -r but replaces characters invalid in FAT filenames import os import sys def patch_filename(filename): " Returns filename with illegal FAT chars replaced by _ " for c in '/?<>\\:*|"^' : filename = filename.replace(c, "_") return filename def copy_file(source, dest): " source & dest are files; dest's parent dir must exist " print 'Copying "' + source + '" -> "' + dest + '"' result = True dat = None try: fs = open(source, 'r') except: print >> sys.stderr, 'Unable to open "' + source + '" for reading' return False try: dat = fs.read() except: print >> sys.stderr, 'Unable to read from "' + source + '"' try: fs.close() except: print >> sys.stderr, 'Unable to close "' + source + '" after reading' result = False if dat == None: return False try: fd = open(dest, 'w') except: print >> sys.stderr, 'Unable to open "' + dest + '" for writing' return False try: fd.write(dat) except: print >> sys.stderr, 'Unable to write to "' + dest + '"' try: fd.close() except: print >> sys.stderr, 'Unable to close "' + dest + '" after writing' return False return result def copy_object_as(source, dest): """ Copies a single file or directory (recursively) *as* dest. """ if os.path.isdir(source): print 'Creating "' + dest + '"' try: os.mkdir(dest) except: print >> sys.stderr, 'Unable to create directory "' + dest + '"' return False contents = os.listdir(source) if contents: for n in range(len(contents)): contents[n] = os.path.join(source, contents[n]) return copy_objects_into(contents, dest) else: return True else: return copy_file(source, dest) def copy_object_into(source, dest): """ Copies a single file or directory (recursively) *into* dest. """ leaf = patch_filename(source.rstrip('/').split(os.path.sep)[-1]) dest = os.path.join(dest, leaf) return copy_object_as(source, dest) def copy_objects_into(sources, dest): """ sources is list of files or directories. dest is directory they'll be copied into. dest must be FAT-safe. """ result = True sources.sort() for src in sources: if not copy_object_into(src, dest): result = False return result def copy_objects(sources, dest): """ Like copy_objects_into, but if sources only has one object and dest isn't an existing directory, it will try to copy the object as dest instead of into it. """ if len(sources) == 1 and not os.path.isdir(dest): return copy_object_as(sources[0], patch_filename(dest)) else: return copy_objects_into(sources, dest) sources = sys.argv[1 : -1] print "Sources:", sources dest = sys.argv[-1] if not copy_objects(sources, dest): print >> sys.stderr, "There was a problem while copying" sys.exit(1)