Reputation: 29
I've a script that is organizing folders. I want to improve it so I'm trying to make GUI. I've spend more than a week on It and I can't find a solution... How do you mix link properly the second and third script to integrate them in the main script ? And then, how do you compile three file in one executable ?
Here is the main script
#Introduction of the code
"""The aim of this script is to organize your download folder by placing files in a sub-folder regarding of their extension"""
import os
import shutil
import getpass
def dot_exe_dir_download(x,y): # x is the complete name of the file and y is the current folder
destination=y+"Installer/" #destination of the file
a=path_download_directory+x #recreate the path of the file
#print(a)
test=os.path.exists(destination) #check if the folder exist or not
if test == True:
shutil.move(a,destination) #move the file to the destination
else:
os.mkdir(destination) # create the folder that doesn't exist
shutil.move(a,destination) #move the file to the destination
print(x," has been moved to:",destination,)
def dot_rmskin_dir_download(x,y): # x is the complete name of the file and y is the current folder
destination=y+"Skins/Rainmeter/" #destination of the file
a=path_download_directory+x #recreate the path of the file
#print(a)
test=os.path.exists(destination) #check if the folder exist or not
if test == True:
shutil.move(a,destination) #move the file to the destination
else:
os.mkdir(destination) # create the folder that doesn't exist
shutil.move(a,destination) #move the file to the destination
print(x," has been moved to:",destination,)
def dot_fonts_dir_download(x,y): # x is the complete name of the file and y is the current folder
destination=y+"Fonts/" #destination of the file
a=path_download_directory+x #recreate the path of the file
#print(a)
test=os.path.exists(destination) #check if the folder exist or not
if test == True:
shutil.move(a,destination) #move the file to the destination
else:
os.mkdir(destination) # create the folder that doesn't exist
shutil.move(a,destination) #move the file to the destination
print(x," has been moved to:",destination,)
def dot_video_dir_download(x,y): # x is the complete name of the file and y is the current folder
destination=path_raw+"Videos/Downloaded video's" #destination of the file
a=path_download_directory+x #recreate the path of the file*
#print(a)
test=os.path.exists(destination) #check if the folder exist or not
if test == True:
shutil.move(a,destination) #move the file to the destination
else:
os.mkdir(destination) # create the folder that doesn't exist
shutil.move(a,destination) #move the file to the destination
print(x," has been moved to:",destination,)
def archives_dir_download(x,y): # x is the complete name of the file and y is the current folder
destination=y+"Archives/" #destination of the file
a=path_download_directory+x #recreate the path of the file
#print(a)
test=os.path.exists(destination) #check if the folder exist or not
if test == True:
shutil.move(a,destination) #move the file to the destination
else:
os.mkdir(destination) # create the folder that doesn't exist
shutil.move(a,destination) #move the file to the destination
print(x," has been moved to:",destination,)
#Main body
#Part 1 (Main)
USER_ID=r'{}'.format(getpass.getuser())
USER_ID_MANUEL=""
while True:
yes_or_no=str(input('Is your download directory is C:/Users/'+ str(USER_ID) +'/Downloads ? \nwrite yes or no: '))
if yes_or_no == "yes":
path_raw="C:/Users/"+ str(USER_ID) +"/"
path_download_directory="C:/Users/"+ str(USER_ID) +"/Downloads/"
print("------------")
break
elif yes_or_no == "no":
USER_ID_MANUEL=(str(input(r"Please write down your exact user ID:")))
path_raw="C:/Users/"+ str(USER_ID) +"/"
path_download_directory="C:/Users/"+ str(USER_ID_MANUEL) +"/Downloads/"
path_download_directory.replace("\\" , "/" )
print("------------")
break
else:
print("That answer was not expected. Please write yes or no")
print("------------")
counter=0
#Part 2 (in /Download)
file_list=os.listdir(path_download_directory) # in the workspace directory "/Downloads"
#print(path_download_directory)# print the current workspace path
#print(file_list)
print("---------")
for file in file_list:
file_Name, file_Extension = os.path.splitext(file)
#print(file_Extension)
if file_Extension == ".exe":
dot_exe_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".msi":
dot_exe_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".zip":
archives_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".rar":
archives_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".7z":
archives_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".iso":
archives_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".rmskin":
dot_rmskin_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".ttf":
dot_fonts_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".otf":
dot_fonts_dir_download(file,path_download_directory)
counter+=1
print("---")
if file_Extension == ".mp4":
dot_video_dir_download(file,path_download_directory)
counter+=1
print("---")
if counter==0:
print("It's already organized :)")
else:
print("We have moved",counter,"files")
print("---------")
print("------------")
input("Press Enter to finish")
The objective is that when I click on a buttons, it's opening up a folder dialog. So I wrote the folder dialog program:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 directory dialogs'
self.left = 100
self.top = 100
self.width = 640
self.height = 480
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.openDirDialog()
#self.show()
def openDirDialog(self):
options = QFileDialog.Options()
file = str(QFileDialog.getExistingDirectory(self, "Select Directory", options=options))
if file:
print(file)
return file
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
I needed a window, so I programmed a window:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog
from PyQt5.QtGui import QIcon
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_FileOrganizer(object):
def setupUi(self, FileOrganizer):
FileOrganizer.setObjectName("FileOrganizer")
FileOrganizer.resize(800, 598)
FileOrganizer.setAcceptDrops(False)
FileOrganizer.setLayoutDirection(QtCore.Qt.LeftToRight)
FileOrganizer.setAnimated(True)
FileOrganizer.setDockNestingEnabled(False)
FileOrganizer.setUnifiedTitleAndToolBarOnMac(False)
self.centralwidget = QtWidgets.QWidget(FileOrganizer)
self.centralwidget.setObjectName("centralwidget")
self.Title = QtWidgets.QLabel(self.centralwidget)
self.Title.setGeometry(QtCore.QRect(170, 10, 451, 61))
font = QtGui.QFont()
font.setFamily("Yu Gothic UI")
font.setPointSize(20)
self.Title.setFont(font)
self.Title.setAlignment(QtCore.Qt.AlignCenter)
self.Title.setObjectName("Title")
self.Selectyourfolderbutton = QtWidgets.QPushButton(self.centralwidget)
self.Selectyourfolderbutton.setGeometry(QtCore.QRect(310, 90, 161, 41))
font = QtGui.QFont()
font.setFamily("Yu Gothic UI")
font.setPointSize(12)
self.Selectyourfolderbutton.setFont(font)
self.Selectyourfolderbutton.setAutoDefault(True)
self.Selectyourfolderbutton.setDefault(True)
self.Selectyourfolderbutton.setFlat(False)
self.Selectyourfolderbutton.setObjectName("Selectyourfolderbutton")
FileOrganizer.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(FileOrganizer)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
FileOrganizer.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(FileOrganizer)
self.statusbar.setObjectName("statusbar")
FileOrganizer.setStatusBar(self.statusbar)
self.retranslateUi(FileOrganizer)
QtCore.QMetaObject.connectSlotsByName(FileOrganizer)
self.Selectyourfolderbutton.clicked.connect(self.click)
def click(self):
import FolderSelect
self.ex = App()
def retranslateUi(self, FileOrganizer):
_translate = QtCore.QCoreApplication.translate
FileOrganizer.setWindowTitle(_translate("FileOrganizer", "File-Organizer"))
self.Title.setText(_translate("FileOrganizer", "Welcome into File-Organizer !"))
self.Selectyourfolderbutton.setText(_translate("FileOrganizer", "Select your folder"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
FileOrganizer = QtWidgets.QMainWindow()
ui = Ui_FileOrganizer()
ui.setupUi(FileOrganizer)
FileOrganizer.show()
sys.exit(app.exec_())
Thanks for reading. If you see anything that can be improve (even the question), let me know! And the same for questions or/and remarks, let me know !
Upvotes: 1
Views: 142
Reputation: 244282
If you want to implement an application that can be used by a CLI or by a GUI then you must first define the business logic. In your case, it is the organization of a specific directory under a predetermined structure so the GUI, CLI or any interface should only provide the directory and execute the business logic. Thus, your project must be restructured so that the above requirements are met:
lib.py
import os
import shutil
def move_file_to_directory(file, destination):
if not os.path.exists(destination):
os.mkdir(destination)
shutil.move(file, destination)
print("{} has been moved to: {}".format(os.path.basename(file), destination))
def organize_folder(folder):
counter = 0
for filename in os.listdir(folder):
name, extension = os.path.splitext(filename)
d = {
".exe": "Installer",
".msi": "Installer",
".zip": "Archives",
".rar": "Archives",
".7z": "Archives",
".iso": "Archives",
".rmskin": "Skins/Rainmeter/",
".ttf": "Fonts",
".otf": "Fonts",
".mp4": "Videos/Downloaded video's",
}
sub_path = d.get(extension)
if sub_path is not None:
destination = os.path.join(folder, sub_path)
source = os.path.join(folder, filename)
move_file_to_directory(source, destination)
counter += 1
if counter == 0:
print("It's already organized :)")
else:
print("We have moved {} files".format(counter))
As you can see the part of lib.py does not execute anything but it is a set of functions that allow you to organize a directory based on specific rules.
cli.py
import getpass
import os
from lib import organize_folder
def build_name_of_directory(id_):
return os.path.join("C:/Users", id_, "Downloads")
def main():
USER_ID = r"{}".format(getpass.getuser())
download_path = build_name_of_directory(USER_ID)
while True:
yes_or_no = input(
"Is your download directory is {}? \nwrite yes or no: ".format(
download_path
)
)
if yes_or_no in ("yes", "no"):
if yes_or_no == "no":
custom_id = str(input(r"Please write down your exact user ID:"))
download_path = build_name_of_directory(custom_id)
break
else:
print("That answer was not expected. Please write yes or no")
print("------------")
organize_folder(download_path)
if __name__ == "__main__":
main()
In the case of cli.py this implements a logic for the user to specify the directory based on the User ID and uses the functions of lib.py.
gui.py
import threading
from PyQt5 import QtCore, QtGui, QtWidgets
from lib import organize_folder
class MainWindow(QtWidgets.QMainWindow):
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle(self.tr("File-Organizer"))
font = QtGui.QFont()
font.setFamily("Yu Gothic UI")
font.setPointSize(20)
self.title = QtWidgets.QLabel(
self.tr("Welcome into File-Organizer !"), alignment=QtCore.Qt.AlignCenter
)
self.title.setFont(font)
self.button = QtWidgets.QPushButton(self.tr("Select your folder"))
font.setPointSize(12)
self.button.setFont(font)
self.button.setFixedSize(160, 40)
self.progressbar = QtWidgets.QProgressBar()
self.progressbar.setFixedSize(300, 40)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.setContentsMargins(0, 10, 0, 0)
lay.setSpacing(60)
lay.addWidget(self.title)
lay.addWidget(self.button, alignment=QtCore.Qt.AlignCenter)
lay.addWidget(self.progressbar, alignment=QtCore.Qt.AlignCenter)
lay.addStretch()
self.resize(640, 480)
self.button.clicked.connect(self.onClicked)
self.started.connect(self.onStarted)
self.finished.connect(self.onFinished)
@QtCore.pyqtSlot()
def onClicked(self):
directory = QtWidgets.QFileDialog.getExistingDirectory(
self,
"Select Directory",
QtCore.QStandardPaths.writableLocation(
QtCore.QStandardPaths.DownloadLocation
),
)
if directory:
threading.Thread(
target=self.organize_folder, args=(directory,), daemon=True
).start()
def organize_folder(self, directory):
self.started.emit()
organize_folder(directory)
self.finished.emit()
@QtCore.pyqtSlot()
def onStarted(self):
self.progressbar.setRange(0, 0)
@QtCore.pyqtSlot()
def onFinished(self):
self.progressbar.setRange(0, 1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
gui.py in the same way that cli.py only provides an interface to the user to obtain the necessary information to know which directory you want to order in addition to indicating the progress of the ordering. Since the number of files that should be moved is unknown, this task is potentially heavy, so it must be executed in another thread.
Structure:
├── cli.py
├── gui.py
└── lib.py
Upvotes: 1