Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm fairly new to programming in general. I need to develop a program that can copy multiple directories at once and also take into account multiple file type exceptions. I came across the shutil module which offers the copytree and ignore_patterns functions. Here is a snippet of my code which also uses the wxPython Multiple Directory Dialog:

import os
import wx
import wx.lib.agw.multidirdialog as MDD
from shutil import copytree
from shutil import ignore_patterns
app = wx.App(0)
dlg = MDD.MultiDirDialog(None, title="Custom MultiDirDialog", defaultPath=os.getcwd(),  agwStyle=MDD.DD_MULTIPLE|MDD.DD_DIR_MUST_EXIST)
dest = "Destination Path"
if dlg.ShowModal() != wx.ID_OK:
    dlg.Destroy()
paths = dlg.GetPaths()
ext = ['*.tiff', '*.raw', '*.p4p', '*.hkl', '*.xlsx']
for path in enumerate(paths):
    directory = path[1].replace('Local Disk (C:)','C:')
    copytree(directory, dest, ignore=ignore_patterns(directory, *ext))
dlg.Destroy()
app.MainLoop()

This code works well for me. At times, I'll be copying terabytes worth of data. Is there anyway that the shutil.copytree can be interrupted? I ask this, because the first time I ran this program, I selected a rather large directory and copied a ton of files (Successfully!) by accident and wanted to stop it :( . Once I get around this, I'll finally start on the GUI! If there is anymore information that I can provide, please let me know! Thanks in advance for any and all help!

You can run the copy in separate python process using multiprocessing module. The code may look something like this:

import time
import shutil
from multiprocessing import Process
def cp(src: str, dest: str):
    shutil.copytree(src, dest)
if __name__ == '__main__':
    proc = Process(target=cp, args=('Downloads', 'Tmp'), daemon=True)
    proc.start()
    time.sleep(3)
    proc.terminate()

In my example the main process starts a child process, which does the actual coping, and after 3 seconds terminates it. Also you can check if the process is running by calling is_alive() method of the process.

After termination, you can check whether there are copied files and cleanup them (the destination directory). – Vladimir Poghosyan Dec 17, 2018 at 14:50

copytree accepts copy_function as a parameter. If you pass a function that checks for a flag you could raise an error to interrupt the operation.

from shutil import copytree, copy2
# set this flag to True to interrupt a copytree operation
interrupt = False
class Interrupt(Exception):
    """ interrupts the copy operation """
def interruptable_copy(*args, **kwargs):
    if interrupt:
        raise Interrupt("Interrupting copy operation")
    return copy2(*args, **kwargs)
copytree(src, dst, copy_function=interruptable_copy)
                I believe this will stop the tree copy between files, but not during an individual copy.  This may or may not be a good enough solution for the original question, depending on how big the files are.
– gkimsey
                Sep 15, 2020 at 19:41
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.