Monday, December 10, 2018

codingdirectional: Don’t delete the same file in it’s own directory

Welcome back to the next chapter of the delete duplicate application, in the previous chapters we have successfully created a multiple files selector which will delete all the duplicate files in another folder. And in this chapter we will further tune up the program to make sure we can also delete all those duplicate files in the nested folders that are contain in the same folder where the file which we want to search for it’s duplicate version is located. The first file which we need to change is the main file, the program will need to make sure the user has selected a file to search for it’s duplicate version as well as the user has selected a folder to search for the duplicate file or else a message box will pop up to warn the user about that. The program will also pass in the folder path which the selected file is located to the remove thread so the thread will not search and delete that selected file.

from tkinter import *
from tkinter import filedialog
from Remove import Remove
import os
from tkinter import messagebox

win = Tk() # 1 Create instance
win.title("Multitas") # 2 Add a title
win.resizable(0, 0) # 3 Disable resizing the GUI
win.configure(background='black') # 4 change background color

# 5 Create a label
aLabel = Label(win, text="Remove duplicate", anchor="center")
aLabel.grid(column=0, row=1)
aLabel.configure(foreground="white")
aLabel.configure(background="black")

# 6 Create a selectFile function to be used by button
def selectFile():

    fullfilenames = filedialog.askopenfilenames(initialdir="/", title="Select a file") # select multiple files from the hard drive

    if(fullfilenames != ''):

        fullfilenamelist = win.tk.splitlist(fullfilenames)
        directory_path = os.path.dirname(os.path.abspath(fullfilenamelist[0]))

        os.chdir(directory_path)  # change the directory to the selected file directory

        folder = filedialog.askdirectory()  # 7 open a folder then create and start a new remove thread to delete the duplicate file
        folder = folder.replace('/', '\\')  # 8 this is for the windows separator only

        if(folder != '' and folder != os.getcwd()):

            for fullfilename in fullfilenamelist:

                if(fullfilename != ''):
                    filename = fullfilename.split('/')[-1]
                    remove = Remove(folder, filename, fullfilename, directory_path)
                    remove.start()
                    remove.join()

        else:
            messagebox.showinfo("Error", "Kindly select one folder and it must be a different one")
            return

    else:
        messagebox.showinfo("Select file", "You need to select a file!")
        return


# 9 Adding a Button
action = Button(win, text="Select File", command=selectFile)
action.grid(column=0, row=0)
action.configure(background='brown')
action.configure(foreground='white')

win.mainloop()  # 10 start GUI

Next we will modify the remove class to match those changes in our program.

import threading
import os
import filecmp

class Remove(threading.Thread):

   def __init__(self, massage,  filename, fullfilename, directory_path):

      threading.Thread.__init__(self)
      self.massage = massage
      self.filename, self.file_extension = os.path.splitext(filename)
      self.fullfilename = fullfilename
      self.directory_path = directory_path

   def run(self):

      filepaths = os.listdir(self.massage)

      for filepath in list(filepaths):
         os.chdir(self.massage)
         if(os.getcwd() != self.directory_path): # make sure that we will not delete the same file in the selected file directory
            if(os.path.isfile(filepath)):
               filename, file_extension = os.path.splitext(filepath)
               self.remove_file(file_extension, filepath)
            else:
               self.delete_duplicate(os.path.join(self.massage, filepath))
         else:
            continue


   def delete_duplicate(self, folder): # sub method to pass folder to

      filepaths = os.listdir(folder)

      for filepath in list(filepaths):
         os.chdir(folder)
         if(os.getcwd() != self.directory_path):

            if(os.path.isfile(filepath)):
               filename, file_extension = os.path.splitext(filepath)
               self.remove_file(file_extension, filepath)
            else:
               self.delete_duplicate(os.path.join(folder, filepath))

         else:
            continue

   def remove_file(self, file_extension, filepath):
      if (file_extension == self.file_extension):
         if filecmp.cmp(filepath, self.fullfilename, shallow=False):
            os.remove(filepath)

That is it, the remove file sub method will compare the files’ extension first before further compares the two files which will reduce the time of thread process. Our next mission is to create a massage box to inform the user how many duplicate files have been deleted and we will do that on the next chapter.



from Planet Python
via read more

No comments:

Post a Comment

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...