1
1
import os
2
2
import shutil
3
+ from PyQt5 .QtWidgets import (
4
+ QApplication , QWidget , QVBoxLayout , QPushButton , QLineEdit , QFileDialog ,
5
+ QTextEdit , QLabel , QProgressBar
6
+ )
7
+ from PyQt5 .QtCore import QThread , pyqtSignal
3
8
9
+ # Define your file types mapping
4
10
FILE_TYPES = {
5
11
"PDFs" : [".pdf" ],
6
12
"Images" : [".jpg" , ".jpeg" , ".png" , ".gif" , ".bmp" , ".tiff" ],
10
16
"Videos" : [".mp4" , ".mkv" , ".avi" , ".mov" ],
11
17
}
12
18
13
- downloads_folder = os .path .expanduser ("~/Downloads" )
14
-
19
+ # Utility functions for file operations
15
20
def create_folder (folder_path ):
16
21
if not os .path .exists (folder_path ):
17
22
os .makedirs (folder_path )
@@ -33,27 +38,124 @@ def move_file(file_path, destination_folder):
33
38
destination = get_unique_destination (destination_folder , filename )
34
39
try :
35
40
shutil .move (file_path , destination )
36
- print (f"Moved: { filename } -> { destination } " )
37
41
except Exception as e :
38
- print (f"Error moving { file_path } : { e } " )
39
-
40
- def auto_sort_downloads ():
41
- for item in os .listdir (downloads_folder ):
42
- item_path = os .path .join (downloads_folder , item )
43
- if os .path .isdir (item_path ):
44
- continue
45
- _ , ext = os .path .splitext (item )
46
- ext = ext .lower ()
47
- sorted_file = False
48
- for folder_name , extensions in FILE_TYPES .items ():
49
- if ext in extensions :
50
- destination = os .path .join (downloads_folder , folder_name )
42
+ # You might want to handle errors or log them appropriately
43
+ pass
44
+
45
+ # Worker thread for sorting files so the GUI remains responsive
46
+ class SortWorker (QThread ):
47
+ log_signal = pyqtSignal (str )
48
+ progress_signal = pyqtSignal (int )
49
+ finished_signal = pyqtSignal ()
50
+
51
+ def __init__ (self , folder ):
52
+ super ().__init__ ()
53
+ self .folder = folder
54
+
55
+ def run (self ):
56
+ # Get list of non-directory files in the selected folder
57
+ files = [item for item in os .listdir (self .folder )
58
+ if os .path .isfile (os .path .join (self .folder , item ))]
59
+ total_files = len (files )
60
+ if total_files == 0 :
61
+ self .log_signal .emit ("No files found in the selected folder." )
62
+ self .finished_signal .emit ()
63
+ return
64
+
65
+ count = 0
66
+ for item in files :
67
+ item_path = os .path .join (self .folder , item )
68
+ _ , ext = os .path .splitext (item )
69
+ ext = ext .lower ()
70
+ sorted_file = False
71
+ for folder_name , extensions in FILE_TYPES .items ():
72
+ if ext in extensions :
73
+ destination = os .path .join (self .folder , folder_name )
74
+ move_file (item_path , destination )
75
+ self .log_signal .emit (f"Moved '{ item } ' to '{ folder_name } ' folder." )
76
+ sorted_file = True
77
+ break
78
+ if not sorted_file :
79
+ destination = os .path .join (self .folder , "Others" )
51
80
move_file (item_path , destination )
52
- sorted_file = True
53
- break
54
- if not sorted_file :
55
- destination = os .path .join (downloads_folder , "Others" )
56
- move_file (item_path , destination )
57
-
58
- if __name__ == "__main__" :
59
- auto_sort_downloads ()
81
+ self .log_signal .emit (f"Moved '{ item } ' to 'Others' folder." )
82
+ count += 1
83
+ progress = int ((count / total_files ) * 100 )
84
+ self .progress_signal .emit (progress )
85
+ self .log_signal .emit ("Sorting completed!" )
86
+ self .finished_signal .emit ()
87
+
88
+ # Main GUI window using PyQt5
89
+ class MainWindow (QWidget ):
90
+ def __init__ (self ):
91
+ super ().__init__ ()
92
+ self .setWindowTitle ("Downloads Auto Sorter" )
93
+ self .resize (600 , 400 )
94
+ self .layout = QVBoxLayout ()
95
+ self .setLayout (self .layout )
96
+
97
+ # Folder selection
98
+ self .folder_label = QLabel ("Folder to sort:" )
99
+ self .layout .addWidget (self .folder_label )
100
+
101
+ self .folder_line_edit = QLineEdit ()
102
+ self .folder_line_edit .setText (os .path .expanduser ("~/Downloads" ))
103
+ self .layout .addWidget (self .folder_line_edit )
104
+
105
+ self .browse_button = QPushButton ("Browse" )
106
+ self .browse_button .clicked .connect (self .browse_folder )
107
+ self .layout .addWidget (self .browse_button )
108
+
109
+ # Sorting control
110
+ self .sort_button = QPushButton ("Start Sorting" )
111
+ self .sort_button .clicked .connect (self .start_sorting )
112
+ self .layout .addWidget (self .sort_button )
113
+
114
+ # Progress bar
115
+ self .progress_bar = QProgressBar ()
116
+ self .progress_bar .setValue (0 )
117
+ self .layout .addWidget (self .progress_bar )
118
+
119
+ # Log window
120
+ self .log_text_edit = QTextEdit ()
121
+ self .log_text_edit .setReadOnly (True )
122
+ self .layout .addWidget (self .log_text_edit )
123
+
124
+ self .worker = None
125
+
126
+ def browse_folder (self ):
127
+ folder = QFileDialog .getExistingDirectory (self , "Select Folder" , os .path .expanduser ("~" ))
128
+ if folder :
129
+ self .folder_line_edit .setText (folder )
130
+
131
+ def start_sorting (self ):
132
+ folder = self .folder_line_edit .text ().strip ()
133
+ if not folder or not os .path .exists (folder ):
134
+ self .log ("Invalid folder selected." )
135
+ return
136
+
137
+ # Disable the sort button while sorting is in progress
138
+ self .sort_button .setEnabled (False )
139
+ self .log ("Starting sorting..." )
140
+ self .worker = SortWorker (folder )
141
+ self .worker .log_signal .connect (self .log )
142
+ self .worker .progress_signal .connect (self .update_progress )
143
+ self .worker .finished_signal .connect (self .sorting_finished )
144
+ self .worker .start ()
145
+
146
+ def log (self , message ):
147
+ self .log_text_edit .append (message )
148
+
149
+ def update_progress (self , value ):
150
+ self .progress_bar .setValue (value )
151
+
152
+ def sorting_finished (self ):
153
+ self .sort_button .setEnabled (True )
154
+ self .log ("Sorting process finished." )
155
+
156
+ if __name__ == '__main__' :
157
+ import sys
158
+ app = QApplication (sys .argv )
159
+ window = MainWindow ()
160
+ window .show ()
161
+ sys .exit (app .exec_ ())
0 commit comments