<SPAN class="keyword token">from</SPAN> fnmatch <SPAN class="keyword token">import</SPAN> fnmatch<SPAN class="punctuation token">,</SPAN> filter
<SPAN class="keyword token">from</SPAN> os<SPAN class="punctuation token">.</SPAN>path <SPAN class="keyword token">import</SPAN> isdir<SPAN class="punctuation token">,</SPAN> join
<SPAN class="keyword token">from</SPAN> shutil <SPAN class="keyword token">import</SPAN> copytree
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">include_patterns</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="operator token">*</SPAN>patterns<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="string token">"""Factory function that can be used with copytree() ignore parameter.
Arguments define a sequence of glob-style patterns
that are used to specify what files to NOT ignore.
Creates and returns a function that determines this for each directory
in the file hierarchy rooted at the source directory when used with
shutil.copytree().
"""</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">_ignore_patterns</SPAN><SPAN class="punctuation token">(</SPAN>path<SPAN class="punctuation token">,</SPAN> names<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
keep <SPAN class="operator token">=</SPAN> set<SPAN class="punctuation token">(</SPAN>name <SPAN class="keyword token">for</SPAN> pattern <SPAN class="keyword token">in</SPAN> patterns
<SPAN class="keyword token">for</SPAN> name <SPAN class="keyword token">in</SPAN> filter<SPAN class="punctuation token">(</SPAN>names<SPAN class="punctuation token">,</SPAN> pattern<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
ignore <SPAN class="operator token">=</SPAN> set<SPAN class="punctuation token">(</SPAN>name <SPAN class="keyword token">for</SPAN> name <SPAN class="keyword token">in</SPAN> names
<SPAN class="keyword token">if</SPAN> name <SPAN class="operator token">not</SPAN> <SPAN class="keyword token">in</SPAN> keep <SPAN class="operator token">and</SPAN> <SPAN class="operator token">not</SPAN> isdir<SPAN class="punctuation token">(</SPAN>join<SPAN class="punctuation token">(</SPAN>path<SPAN class="punctuation token">,</SPAN> name<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> ignore
<SPAN class="keyword token">return</SPAN> _ignore_patterns
<SPAN class="comment token"># sample usage</SPAN>
copytree<SPAN class="punctuation token">(</SPAN>src_directory<SPAN class="punctuation token">,</SPAN> dst_directory<SPAN class="punctuation token">,</SPAN>
ignore<SPAN class="operator token">=</SPAN>include_patterns<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'*.dwg'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'*.dxf'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
I have found the following Python Factory Function on Stack Overflow that uses Python shutil.copytree to copy the directory and files based on the inverse of the ignore argument. It adds all file types that are not part of the include_patterns("*.dwg", "*.dxf"). The problem is that it's copying directories where there are no CAD files and resulting in empty directories.
The link to the Stack Overflow post is: post
Solution:
I've found a very simple solution of removing the empty directories with some amendments.
<SPAN class="string token">'''
Created on 27 Feb 2017
Extract CAD files
from within all
directories
@author: PeterW
'''</SPAN>
<SPAN class="comment token"># import site-packages and modules</SPAN>
<SPAN class="keyword token">from</SPAN> fnmatch <SPAN class="keyword token">import</SPAN> filter
<SPAN class="keyword token">from</SPAN> os<SPAN class="punctuation token">.</SPAN>path <SPAN class="keyword token">import</SPAN> isdir<SPAN class="punctuation token">,</SPAN> join
<SPAN class="keyword token">from</SPAN> shutil <SPAN class="keyword token">import</SPAN> copytree<SPAN class="punctuation token">,</SPAN> rmtree
<SPAN class="keyword token">from</SPAN> os <SPAN class="keyword token">import</SPAN> listdir<SPAN class="punctuation token">,</SPAN> rmdir<SPAN class="punctuation token">,</SPAN> walk
<SPAN class="keyword token">import</SPAN> errno
<SPAN class="comment token"># set arguments</SPAN>
input_folder <SPAN class="operator token">=</SPAN> r<SPAN class="string token">"H:\Tanzania"</SPAN>
output_folder <SPAN class="operator token">=</SPAN> r<SPAN class="string token">"E:\CAD"</SPAN>
<SPAN class="comment token"># create ignore patterns dynamically based on include patterns</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">include_patterns</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="operator token">*</SPAN>patterns<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">_ignore_patterns</SPAN><SPAN class="punctuation token">(</SPAN>path<SPAN class="punctuation token">,</SPAN> names<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
keep <SPAN class="operator token">=</SPAN> set<SPAN class="punctuation token">(</SPAN>name <SPAN class="keyword token">for</SPAN> pattern <SPAN class="keyword token">in</SPAN> patterns <SPAN class="keyword token">for</SPAN> name <SPAN class="keyword token">in</SPAN> filter<SPAN class="punctuation token">(</SPAN>names<SPAN class="punctuation token">,</SPAN> pattern<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
ignore <SPAN class="operator token">=</SPAN> set<SPAN class="punctuation token">(</SPAN>name <SPAN class="keyword token">for</SPAN> name <SPAN class="keyword token">in</SPAN> names <SPAN class="keyword token">if</SPAN> name <SPAN class="operator token">not</SPAN> <SPAN class="keyword token">in</SPAN> keep <SPAN class="operator token">and</SPAN> <SPAN class="operator token">not</SPAN> isdir<SPAN class="punctuation token">(</SPAN>join<SPAN class="punctuation token">(</SPAN>path<SPAN class="punctuation token">,</SPAN> name<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> ignore
<SPAN class="keyword token">return</SPAN> _ignore_patterns
<SPAN class="comment token"># copy directory structure and files based on pattern</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">copytree_files</SPAN><SPAN class="punctuation token">(</SPAN>input_folder<SPAN class="punctuation token">,</SPAN> output_folder<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> isdir<SPAN class="punctuation token">(</SPAN>output_folder<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
rmtree<SPAN class="punctuation token">(</SPAN>output_folder<SPAN class="punctuation token">)</SPAN>
copytree<SPAN class="punctuation token">(</SPAN>input_folder<SPAN class="punctuation token">,</SPAN> output_folder<SPAN class="punctuation token">,</SPAN> ignore<SPAN class="operator token">=</SPAN>include_patterns<SPAN class="punctuation token">(</SPAN><SPAN class="string token">"*.dwg"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"*.dxf"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
copytree_files<SPAN class="punctuation token">(</SPAN>input_folder<SPAN class="punctuation token">,</SPAN> output_folder<SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># remove empty directories</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">remove_empty_dirs</SPAN><SPAN class="punctuation token">(</SPAN>output_folder<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
dirs <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN>x<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> x <SPAN class="keyword token">in</SPAN> walk<SPAN class="punctuation token">(</SPAN>output_folder<SPAN class="punctuation token">,</SPAN> topdown<SPAN class="operator token">=</SPAN><SPAN class="token boolean">False</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">for</SPAN> dir <SPAN class="keyword token">in</SPAN> dirs<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">try</SPAN><SPAN class="punctuation token">:</SPAN>
rmdir<SPAN class="punctuation token">(</SPAN>dir<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">except</SPAN> Exception <SPAN class="keyword token">as</SPAN> e<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> e<SPAN class="punctuation token">.</SPAN>errno <SPAN class="operator token">==</SPAN> errno<SPAN class="punctuation token">.</SPAN>ENOTEMPTY<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"Directory: {0} not empty"</SPAN><SPAN class="punctuation token">.</SPAN>format<SPAN class="punctuation token">(</SPAN>dir<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
remove_empty_dirs<SPAN class="punctuation token">(</SPAN>output_folder<SPAN class="punctuation token">)</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>I found an additional solution that could work from a solution provided on Stack Overflow, but due to time constraints I wasn't able to get it to work: How do I copy an entire directory of files into an existing directory using Python?
Mital Vora provided the following solution:
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">copytree</SPAN><SPAN class="punctuation token">(</SPAN>src<SPAN class="punctuation token">,</SPAN> dst<SPAN class="punctuation token">,</SPAN> symlinks<SPAN class="operator token">=</SPAN><SPAN class="token boolean">False</SPAN><SPAN class="punctuation token">,</SPAN> ignore<SPAN class="operator token">=</SPAN>None<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>exists<SPAN class="punctuation token">(</SPAN>dst<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
os<SPAN class="punctuation token">.</SPAN>makedirs<SPAN class="punctuation token">(</SPAN>dst<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">for</SPAN> item <SPAN class="keyword token">in</SPAN> os<SPAN class="punctuation token">.</SPAN>listdir<SPAN class="punctuation token">(</SPAN>src<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
s <SPAN class="operator token">=</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>join<SPAN class="punctuation token">(</SPAN>src<SPAN class="punctuation token">,</SPAN> item<SPAN class="punctuation token">)</SPAN>
d <SPAN class="operator token">=</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>join<SPAN class="punctuation token">(</SPAN>dst<SPAN class="punctuation token">,</SPAN> item<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">if</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>isdir<SPAN class="punctuation token">(</SPAN>s<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
copytree<SPAN class="punctuation token">(</SPAN>s<SPAN class="punctuation token">,</SPAN> d<SPAN class="punctuation token">,</SPAN> symlinks<SPAN class="punctuation token">,</SPAN> ignore<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>exists<SPAN class="punctuation token">(</SPAN>d<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">or</SPAN> os<SPAN class="punctuation token">.</SPAN>stat<SPAN class="punctuation token">(</SPAN>s<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>st_mtime <SPAN class="operator token">-</SPAN> os<SPAN class="punctuation token">.</SPAN>stat<SPAN class="punctuation token">(</SPAN>d<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>st_mtime <SPAN class="operator token">></SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">:</SPAN>
shutil<SPAN class="punctuation token">.</SPAN>copy2<SPAN class="punctuation token">(</SPAN>s<SPAN class="punctuation token">,</SPAN> d<SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
The idea of the following was to create a list of directories that contain CAD drawings thereby eliminating the need of removing empty directories afterwards:
Incomplete Solution:
<SPAN class="string token">'''
Created on 27 Feb 2017
Extract CAD files
from within all
directories
@author: PeterW
'''</SPAN>
<SPAN class="comment token"># import site-packages and modules</SPAN>
<SPAN class="keyword token">from</SPAN> fnmatch <SPAN class="keyword token">import</SPAN> fnmatch<SPAN class="punctuation token">,</SPAN> filter
<SPAN class="keyword token">import</SPAN> os
<SPAN class="keyword token">from</SPAN> os<SPAN class="punctuation token">.</SPAN>path <SPAN class="keyword token">import</SPAN> isdir<SPAN class="punctuation token">,</SPAN> join
<SPAN class="keyword token">from</SPAN> shutil <SPAN class="keyword token">import</SPAN> copytree<SPAN class="punctuation token">,</SPAN> copy2
<SPAN class="comment token"># set arguments</SPAN>
input_folder <SPAN class="operator token">=</SPAN> r<SPAN class="string token">"H:\Tanzania\fromDropbox\Infrastructure"</SPAN>
output_folder <SPAN class="operator token">=</SPAN> r<SPAN class="string token">"E:\CAD"</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">directories_list</SPAN><SPAN class="punctuation token">(</SPAN>input_folder<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
dirs_list <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">for</SPAN> root<SPAN class="punctuation token">,</SPAN> dirs<SPAN class="punctuation token">,</SPAN> files <SPAN class="keyword token">in</SPAN> os<SPAN class="punctuation token">.</SPAN>walk<SPAN class="punctuation token">(</SPAN>input_folder<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> any<SPAN class="punctuation token">(</SPAN>file<SPAN class="punctuation token">.</SPAN>endswith<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'.dwg'</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">or</SPAN> file<SPAN class="punctuation token">.</SPAN>endswith<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'.dxf'</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">for</SPAN> file <SPAN class="keyword token">in</SPAN> files<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
dirs_list<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>abspath<SPAN class="punctuation token">(</SPAN>root<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> dirs_list
dirs_list <SPAN class="operator token">=</SPAN> directories_list<SPAN class="punctuation token">(</SPAN>input_folder<SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># function</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">include_patterns</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="operator token">*</SPAN>patterns<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">_ignore_patterns</SPAN><SPAN class="punctuation token">(</SPAN>path<SPAN class="punctuation token">,</SPAN> names<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
keep <SPAN class="operator token">=</SPAN> set<SPAN class="punctuation token">(</SPAN>name <SPAN class="keyword token">for</SPAN> pattern <SPAN class="keyword token">in</SPAN> patterns <SPAN class="keyword token">for</SPAN> name <SPAN class="keyword token">in</SPAN> filter<SPAN class="punctuation token">(</SPAN>names<SPAN class="punctuation token">,</SPAN> pattern<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
ignore <SPAN class="operator token">=</SPAN> set<SPAN class="punctuation token">(</SPAN>name <SPAN class="keyword token">for</SPAN> name <SPAN class="keyword token">in</SPAN> names <SPAN class="keyword token">if</SPAN> name <SPAN class="operator token">not</SPAN> <SPAN class="keyword token">in</SPAN> keep <SPAN class="operator token">and</SPAN> <SPAN class="operator token">not</SPAN> isdir<SPAN class="punctuation token">(</SPAN>join<SPAN class="punctuation token">(</SPAN>path<SPAN class="punctuation token">,</SPAN> name<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> ignore
<SPAN class="keyword token">return</SPAN> _ignore_patterns
<SPAN class="comment token"># relook at the following, its not working as expected</SPAN>
<SPAN class="comment token"># due to copytree limitation of existing directory exists</SPAN>
<SPAN class="comment token"># after first loop</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">copytree_files</SPAN><SPAN class="punctuation token">(</SPAN>dirs_list<SPAN class="punctuation token">,</SPAN> output_folder<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>exists<SPAN class="punctuation token">(</SPAN>output_folder<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
os<SPAN class="punctuation token">.</SPAN>makedirs<SPAN class="punctuation token">(</SPAN>output_folder<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">for</SPAN> dir <SPAN class="keyword token">in</SPAN> dirs_list<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">for</SPAN> item <SPAN class="keyword token">in</SPAN> os<SPAN class="punctuation token">.</SPAN>listdir<SPAN class="punctuation token">(</SPAN>dir<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
s <SPAN class="operator token">=</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>join<SPAN class="punctuation token">(</SPAN>dir<SPAN class="punctuation token">,</SPAN> item<SPAN class="punctuation token">)</SPAN>
d <SPAN class="operator token">=</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>join<SPAN class="punctuation token">(</SPAN>output_folder<SPAN class="punctuation token">,</SPAN> item<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">if</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>isdir<SPAN class="punctuation token">(</SPAN>s<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
copytree<SPAN class="punctuation token">(</SPAN>s<SPAN class="punctuation token">,</SPAN> d<SPAN class="punctuation token">,</SPAN> ignore<SPAN class="operator token">=</SPAN>include_patterns<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'*.dwg'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"*.dxf"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>exists<SPAN class="punctuation token">(</SPAN>d<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">or</SPAN> os<SPAN class="punctuation token">.</SPAN>stat<SPAN class="punctuation token">(</SPAN>s<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>st_mtime <SPAN class="operator token">-</SPAN> os<SPAN class="punctuation token">.</SPAN>stat<SPAN class="punctuation token">(</SPAN>d<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>st_mtime <SPAN class="operator token">></SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">:</SPAN>
copy2<SPAN class="punctuation token">(</SPAN>s<SPAN class="punctuation token">,</SPAN> d<SPAN class="punctuation token">)</SPAN>
copytree_files<SPAN class="punctuation token">(</SPAN>dirs_list<SPAN class="punctuation token">,</SPAN> input_folder<SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>