Put some order in my files with Python with FileCollector

Let’s make order in our files

The problem: I got a hard drive with folders positioned like this:

files in hard drive
files in hard drive

I have created different folder for different topics and for different classroom. So, I have different pdf, pptx, docx in these. What if I want to reunite all the pdf for all the topics in one folder for one classroom? Doing this I do not have to look into each folder, having them in the same folder. I can see if there are files that are similar, that are incomplete, I can join them… etc. And so for all the other type of files.

Goal: I want to get all the pdf, txt, docx files in all the folders containing “5bs” (and for other classes too) and copy them into one folder for each type of files? This post is about this goal.

Let’s do it: dividing a problem into many simple tasks

divide et impera
divide et impera

We want to find all the pdf files in the drive of our computer. That is our plan:

  1. say where to search to the pc
  2. copy into a destination all pdf
  3. print in a listbox all the pdfs names
  4. open the pdf when double clicked or <Return>

As we made these tasks yet, let go see those tutorial before doing this.

Copy files to new folder

Copy files to new folder

shutil.copy(arg1,arg2)
arg. 1 arg.2
file to copy destination folder of the copied file

As we didn’t selected the kind of file (pdf) we want to copy and we just looked in the current directory, we must modify the code in order to do this, but let’s take a look to this orher tutorial to see how we did it in that example.

import shutil
import os

def copyallfiles():
	"create a backup folder, if not exist, and copy all files in there"
	if not "backup" in os.listdir():
		os.makedirs("backup")

	for f in next(os.walk("."))[2]:
			shutil.copy(f, "backup")

copyallfiles()

In this code, from the post about copying files, after creating a backup folder with os.makedirs(), we just copied every file in the local dir.

We used:

  • os.listdir() to check if there was a folder with the name backup yet
  • next(walk(“.”))[2] to iterate all the files in the local folders and to copy then in the new destination(“backup”)

Now we want look into the folders in the root folder that has a name containing a keyword (“5bs” for example of the picture above), and in all the subfolders of these and copy all the pdf files (and/or other type of files. Each type of file will go into a separate backup folder.

scheme:

search in folder with “5bs” in the name:

-> copy pdf files in backup_5bs_pdf, txt files in backup_5bs_tx, etc.

if there are subfolders in those:

-> search in subfolders:

–> copy all pdf in backup_5bs_pdf

->copy all txt in backup_5bs_txt

 

Look for every pdf in the drive

Look fo every pdf in the drive

Now we got almost everything, but in our tasks list we wanted the list of pdf to be shown into a listbox. Let’s take a look at our previous tutorials about this topic.

The code

So, getting all the things together we have the working code and the code is quite abstract. You have this function copyallpdf where you can say what key_word you want to select the folders you want by some keyword you put in the folder name (see the video for the explanation of this way to solve the problem), where is the root of the search and in which folder you want to save all the pdf file.

import shutil
import os


def copyallfiles(filetype="pdf", key_word="5bs", root="F:\\", destination="backup_5bs"):
    "Copy all pdf from folders contaning keyword into a destination folder"
    if destination in os.listdir():
        pass
      # it check if there is a folder named 'backup'
    else:
        os.makedirs(destination)  # creates a folder named 'backup'
    n = 0  # counter for files with the same name to avoid shutil.SameFileError
    for d in next(os.walk(root))[1]:  # go look for folders in F:\\
        if key_word in d:
            for r, d2, f in os.walk(root + d):
                for file in f:
                    if file.endswith("." + filetype):
                        try:
                            shutil.copy(r + "\\" + file, root + destination)
                        except shutil.SameFileError:
                            newname = file[:-4] + "_" + str(n) + "." + filetype
                            os.rename(file, newname)
                            shutil.copy(r + "\\" + newname, root + destination)
                            n += 1
    os.system("start " + root + destination)

Going further in abstraction: find for different type of files

In the following code we can search for different type of files: txt, docx, xlsx, pptx etc.

def quinta(filetype):
    destination = "backup5a_" + filetype  # the folder to copyto the files
    copyallfiles(filetype=filetype, key_word="5bs", root="F:\\", destination=destination)


def quarta(filetype):
    destination = "backup4a_" + filetype  # the folder to copyto the files
    copyallfiles(filetype=filetype, key_word="4bs", root="F:\\", destination=destination)


def terza(filetype):
    destination = "backup3a_" + filetype  # the folder to copyto the files
    copyallfiles(filetype=filetype, key_word="3be", root="F:\\", destination=destination)
    copyallfiles(filetype=filetype, key_word="3acc", root="F:\\", destination=destination)
    copyallfiles(filetype=filetype, key_word="3e", root="F:\\", destination=destination)

And finally a further automation

def files(the_class, types):
    for t in types:
        the_class(t)


files(quarta, ["txt", "docx", "pdf", "pptx", "xlsx"])

A GUI to show the pdf files

Listbox 1

Now that we astabilished our goal and the route to achieve it, let’s do some live coding… in the next episode.

Utilities

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.