def move(src, dst, overwrite=False, make_safe_path=get_safe_path, name_pairs=[]): """Recursively move a file or directory to another location. This is similar to the Unix "mv" command. If the destination is a directory or a symlink to a directory, the source is moved inside the directory. The destination path must not already exist. If the destination already exists but is not a directory, it may be overwritten depending on os.rename() semantics. If the destination is on our current filesystem, then rename() is used. Otherwise, src is copied to the destination and then removed. A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over. """ real_dst = dst if os.path.isdir(dst): if _samefile(src, dst): # We might be on a case insensitive filesystem, # perform the rename anyway. os.rename(src, dst) name_pairs.append((src, dst)) return real_dst = os.path.join(dst, _basename(src)) if not overwrite: real_dst = make_safe_path(real_dst) try: os.rename(src, real_dst) name_pairs.append((src, real_dst)) except OSError: if os.path.isdir(src): if _destinsrc(src, dst): raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) for done in copytree(src, real_dst, symlinks=True, overwrite=overwrite, make_safe_path=make_safe_path): yield done rmtree(src) name_pairs.append((src, real_dst)) else: for done in copy2(src, real_dst, symlinks=True, overwrite=overwrite, make_safe_path=make_safe_path): yield done os.unlink(src) name_pairs.append((src, real_dst))
def test_destinsrc_false_positive(self): os.mkdir(TESTFN) try: for src, dst in [('srcdir', 'src/dest'), ('srcdir', 'srcdir.new')]: src = os.path.join(TESTFN, src) dst = os.path.join(TESTFN, dst) self.assertFalse(shutil._destinsrc(src, dst), msg='_destinsrc() wrongly concluded that ' 'dst (%s) is in src (%s)' % (dst, src)) finally: shutil.rmtree(TESTFN, ignore_errors=True)
def test_destinsrc_false_positive(self): os.mkdir(TESTFN) try: for src, dst in [("srcdir", "src/dest"), ("srcdir", "srcdir.new")]: src = os.path.join(TESTFN, src) dst = os.path.join(TESTFN, dst) self.assertFalse( shutil._destinsrc(src, dst), msg="_destinsrc() wrongly concluded that " "dst (%s) is in src (%s)" % (dst, src), ) finally: shutil.rmtree(TESTFN, ignore_errors=True)
def shutil_move(src, dst): """Recursively move a file or directory to another location. This is similar to the Unix "mv" command. Return the file or directory's destination. If the destination is a directory or a symlink to a directory, the source is moved inside the directory. The destination path must not already exist. If the destination already exists but is not a directory, it may be overwritten depending on os.rename() semantics. If the destination is on our current filesystem, then rename() is used. Otherwise, src is copied to the destination and then removed. Symlinks are recreated under the new name if os.rename() fails because of cross filesystem renames. A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over. """ real_dst = dst if _os.path.isdir(dst): if shutil._samefile(src, dst): # We might be on a case insensitive filesystem, # perform the rename anyway. _os.rename(src, dst) return real_dst = _os.path.join(dst, shutil._basename(src)) if _os.path.exists(real_dst): raise shutil.Error("Destination path '%s' already exists" % real_dst) try: _os.rename(src, real_dst) except OSError: if _os.path.islink(src): linkto = _os.readlink(src) _os.symlink(linkto, real_dst) _os.unlink(src) elif _os.path.isdir(src): if shutil._destinsrc(src, dst): raise shutil.Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) shutil.copytree(src, real_dst, symlinks=True) shutil.rmtree(src) else: shutil.copy2(src, real_dst) _os.unlink(src) return real_dst
def _moveFolder(self, src, dst): real_dst = dst try: os.rename(src, real_dst) except OSError: if self.info['finished'] != 0: return if os.path.isdir(src): if shutil._destinsrc(src, dst): raise Exception, "Cannot move a directory '%s' into itself '%s'." % ( src, dst) self.copytree(src, real_dst, symlinks=True) self.rmtree(src) sqlStr = 'update mediafolder set url=? where url=?' ProfileFunc.execAllScanFolderSql(sqlStr, (real_dst, src)) else: shutil.copy2(src, real_dst) os.unlink(src)
def move(src, dst): """Recursively move a file or directory to another location. This is similar to the Unix "mv" command. If the destination is a directory or a symlink to a directory, the source is moved inside the directory. The destination path must not already exist. If the destination already exists but is not a directory, it may be overwritten depending on os.rename() semantics. If the destination is on our current filesystem, then rename() is used. Otherwise, src is copied to the destination and then removed. A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over. """ real_dst = dst if os.path.isdir(dst): if _samefile(src, dst): # We might be on a case insensitive filesystem, # perform the rename anyway. os.rename(src, dst) return real_dst = os.path.join(dst, _basename(src)) if os.path.exists(real_dst): raise Error("Destination path '%s' already exists" % real_dst) try: os.rename(src, real_dst) except OSError: if os.path.isdir(src): if _destinsrc(src, dst): msg = "Cannot move a directory '%s' into itself '%s'." % (src, dst) raise Error(msg) copytree(src, real_dst, symlinks=True) rmtree(src) else: copy(src, real_dst) os.unlink(src)
def flatten_dir(path, parent, parententry): if parent == None or (args.traverse_mount_points and os.path.ismount(path)): return nameinparent = parent + "/" + parententry files = os.listdir(path) if len(files) == 0: if args.remove_empty_dirs: question = "Remove empty directory '" + path + "'" if util.confirm(question, default_answer = args.default_yes, path = parent, always_yes = args.always): util.rmdir(nameinparent) elif len(files) == 1: #move single entry of dir to parent dir, and delete dir if util.names_similar(files[0], parententry): #filename is similar to parent filename, do not concatenate newname = files[0] else: newname = parententry + " - " + files[0] #find a free new name for the file newname = parent + "/" + util.find_free_name(parent, newname, [parententry]) while True: def question(newname): result = "Move '" result += parent + "/" + util.colored(parententry + "/" + files[0], 36) result += "' to '" result += util.colored(os.path.relpath(newname, parent), 36) result += "'" return result def checker(newname): if newname == "": return "Path is empty" elif os.path.exists(newname) and os.path.normpath(newname) != os.path.normpath(parent + "/" + parententry): return "Path exists" else: return True newname = util.confirm(question, default_answer = args.default_yes, path = parent, val = newname, valname = "move to", valchecker = checker, valcompleter = util.filename_completer(), always_yes = args.always) if newname == False: break newname = os.path.normpath(newname) #if newname is equal to the dirname, we need to rename the dir first ('mv a b', 'mv b/a a', 'rmdir b') if os.path.normpath(parent + '/' + parententry) == newname: newparententry = util.find_free_name(parent, parententry) util.mv(parent + '/' + parententry, parent + '/' + newparententry) parententry = newparententry #check whether the file would be moved into a subdirectory of its old location if shutil._destinsrc(parent + '/' + parententry, newname): print("Can not move file to a subdirectory of its old location") if args.always: break else: continue #if the parent directory of newname does not exist yet, create it newdirname = util.dirname(newname) if not os.path.exists(newdirname): os.makedirs(newdirname) #move util.mv(parent + '/' + parententry + '/' + files[0], newname) util.rmdir(parent + '/' + parententry) break
def update_event(self, inp=-1): self.set_output_val(0, shutil._destinsrc(self.input(0), self.input(1)))