Skip to content

Commit 7a053a6

Browse files
Merge pull request avinashkranjan#111 from Kreateer/file-mover-script
File Mover
2 parents af9527f + 10914bb commit 7a053a6

File tree

4 files changed

+253
-0
lines changed

4 files changed

+253
-0
lines changed

File Mover/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
venv/
2+
.idea/

File Mover/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Automatic File Mover
2+
3+
- This is a small program that automatically moves and sorts files from chosen source to destination. It uses [PySimpleGUI](https://github.com/PySimpleGUI/PySimpleGUI) to create a minimal GUI for the user.
4+
- Original project: [Automatic File Sorter](https://github.com/Kreateer/automatic-file-sorter)
5+
6+
## How to Use
7+
8+
- Install the dependencies ([PySimpleGUi](https://github.com/PySimpleGUI/PySimpleGUI)), which are found in `requirements.txt`
9+
- Run the script or create an executable version by using [PyInstaller](https://www.pyinstaller.org/)
10+
- When asked, choose source and destination folder to move/copy files
11+
- Choose whether to sort by file type or not
12+
- Click 'Ok' to move/copy files and sort them (if option is enabled)

File Mover/fmover.py

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
import os
2+
import shutil
3+
import PySimpleGUI as sg
4+
5+
source_folder = sg.popup_get_folder('Choose source location:', default_path='')
6+
destination_folder = sg.popup_get_folder('Choose destination folder:', default_path='')
7+
8+
file_type = []
9+
mode_list = []
10+
sort_list = []
11+
12+
image_list = ['.png', '.jpg', '.jpeg', '.gif']
13+
archive_list = ['.zip', '.rar', '.7z']
14+
textf_list = ['.txt', '.md', '.pdf', '.doc', '.docx']
15+
16+
17+
def get_path(src_or_dst):
18+
folders = {source_folder: destination_folder}
19+
source = folders.keys()
20+
destination = folders.values()
21+
if src_or_dst == 'src':
22+
return str(*source)
23+
elif src_or_dst == 'dst':
24+
return str(*destination)
25+
else:
26+
raise SystemError("Parameter has to be 'src' or 'dst'")
27+
28+
29+
class fmGUI:
30+
31+
def main_window(self):
32+
layout = [
33+
[sg.Text("Choose Operation to perform:")],
34+
[sg.Combo(['Copy', 'Move'], default_value='Move' ,key='OPERATION')],
35+
[sg.Frame(layout=[
36+
[sg.Text("Sort by Type")],
37+
[sg.Radio("Enabled", "RADIO1", default=False, key='SBYTE', enable_events=True),
38+
sg.Radio("Disabled", "RADIO1", default=True, key='SBYTD', enable_events=True)]
39+
], title='Sorting Options', title_color='red', relief=sg.RELIEF_SUNKEN)],
40+
[sg.Text("Choose filetype:")],
41+
[sg.Combo(["Archive ('.zip', '.rar'...)", "Image ('.png', '.jpg'...)", "Text ('.txt', '.docx'...)"], key='FILETYPE', enable_events=True)],
42+
[sg.Ok(), sg.Cancel()]]
43+
44+
window = sg.Window('Choose filetype to move', layout, default_element_size=(40, 1))
45+
46+
while True:
47+
event, values = window.read()
48+
if event in (sg.WIN_CLOSED, 'Cancel'):
49+
break
50+
elif event in 'Ok':
51+
if values['FILETYPE'] not in file_type:
52+
append_file_type(values['FILETYPE'])
53+
run_fmover = FileMover()
54+
append_mode(values['OPERATION'])
55+
if len(sort_list) == 1:
56+
for value in sort_list:
57+
if value == 'Sort by Type':
58+
run_fmover.filemover(values['OPERATION'], value)
59+
else:
60+
run_fmover.filemover(values['OPERATION'], None)
61+
else:
62+
run_fmover.filemover(values['OPERATION'], None)
63+
64+
else:
65+
run_fmover = FileMover()
66+
append_mode(values['OPERATION'])
67+
if len(sort_list) == 1:
68+
for value in sort_list:
69+
if value == 'Sort by Type':
70+
run_fmover.filemover(values['OPERATION'], value)
71+
else:
72+
run_fmover.filemover(values['OPERATION'], None)
73+
else:
74+
run_fmover.filemover(values['OPERATION'], None)
75+
76+
elif event in 'SBYTE':
77+
if values['SBYTE'] is True:
78+
sort_list.append('Sort by Type')
79+
else:
80+
pass
81+
82+
elif event in 'SBYTD':
83+
if values['SBYTD'] is True:
84+
sort_list.clear()
85+
else:
86+
pass
87+
else:
88+
pass
89+
90+
window.close()
91+
92+
def translate_filetype():
93+
for value in file_type:
94+
if value.startswith("Archive"):
95+
file_type.clear()
96+
for arch in archive_list:
97+
file_type.append(arch)
98+
return str(file_type)
99+
elif value.startswith("Image"):
100+
file_type.clear()
101+
for img in image_list:
102+
file_type.append(img)
103+
return str(file_type)
104+
elif value.startswith("Text"):
105+
file_type.clear()
106+
for txt in textf_list:
107+
file_type.append(txt)
108+
return str(file_type)
109+
else:
110+
pass
111+
112+
113+
def append_mode(mode):
114+
mode_list.append(mode)
115+
if mode in mode_list:
116+
return mode
117+
118+
119+
def detect_mode():
120+
return mode_list[0]
121+
122+
123+
def append_file_type(value):
124+
if len(file_type) == 1:
125+
file_type.clear()
126+
else:
127+
pass
128+
file_type.append(value)
129+
translate_filetype()
130+
return value
131+
132+
133+
class FileMover():
134+
135+
def filemover(self, operation, sortby):
136+
while True:
137+
num_files = len(os.listdir(get_path('src')))
138+
if num_files == 0:
139+
sg.PopupError("No files in folder!")
140+
raise SystemExit()
141+
elif sortby is None:
142+
for file in os.listdir(get_path('src')):
143+
#file_ending = get_file_type()
144+
is_file_in_curr_dir = os.path.isfile(get_path('dst') + "/" + file)
145+
for value in file_type:
146+
if file.endswith(value):
147+
result = None
148+
if is_file_in_curr_dir is False:
149+
if operation == "Copy":
150+
result = shutil.copy(get_path('src') + "/" + file, get_path('dst') + "/" + file)
151+
else:
152+
result = shutil.move(get_path('src') + "/" + file, get_path('dst') + "/" + file)
153+
#if file not in current_dir:
154+
# file_type.pop()
155+
156+
elif sortby == 'Sort by Type':
157+
for file in os.listdir(get_path('src')):
158+
sc = SortCriteria()
159+
is_file_in_dst_dir = os.path.isfile(get_path('dst') + "/" + file)
160+
get_subdir()
161+
for value in file_type:
162+
if file.endswith(value):
163+
if is_file_in_dst_dir is False and get_subdir() is False:
164+
result = None
165+
if operation == "Copy":
166+
result = shutil.copy(get_path('src') + "/" + file, sc.sortbytype(value) + "/" + file)
167+
else:
168+
result = shutil.move(get_path('src') + "/" + file, sc.sortbytype(value) + "/" + file)
169+
elif is_file_in_dst_dir is False and get_subdir() is True:
170+
result = None
171+
if operation == 'Copy':
172+
result = shutil.copy(get_path('src') + "/" + file, sc.sortbytype(value) + "/" + file)
173+
else:
174+
result = shutil.move(get_path('src') + "/" + file, sc.sortbytype(value) + "/" + file)
175+
else:
176+
pass
177+
178+
return sg.PopupOK(f"File transfer successful!\nFile(s) moved to '{get_path('dst')}'")
179+
180+
181+
fmover = FileMover()
182+
183+
source = get_path('src')
184+
destination = get_path('dst')
185+
186+
187+
def get_subdir():
188+
if os.path.exists(str(destination) + '/' + 'Images'):
189+
return True
190+
191+
elif os.path.exists(str(destination) + '/' + 'Archives'):
192+
return True
193+
194+
elif os.path.exists(str(destination) + '/' + 'Text Files'):
195+
return True
196+
197+
else:
198+
return False
199+
200+
201+
202+
class SortCriteria():
203+
204+
def sortbytype(self, ftype):
205+
type_list = [ftype]
206+
207+
# For image files
208+
for type in type_list:
209+
if type in image_list: #'.png' or '.jpg' or '.jpeg' or '.gif':
210+
if os.path.exists(str(destination) + '/' + 'Images'):
211+
return str(os.path.join(str(destination) + '/' + 'Images'))
212+
else:
213+
os.mkdir(str(destination) + '/' + 'Images')
214+
return str(os.path.join(str(destination) + '/' + 'Images'))
215+
216+
# For archive files
217+
elif type in archive_list:
218+
if os.path.exists(str(destination) + '/' + 'Archives'):
219+
return str(os.path.join(str(destination) + '/' + 'Archives'))
220+
else:
221+
os.mkdir(str(destination) + '/' + 'Archives')
222+
return str(os.path.join(str(destination) + '/' + 'Archives'))
223+
224+
# For text files
225+
elif type in textf_list:
226+
if os.path.exists(str(destination) + '/' + 'Text Files'):
227+
return str(os.path.join(str(destination) + '/' + 'Text Files'))
228+
else:
229+
os.mkdir(str(destination) + '/' + 'Text Files')
230+
return str(os.path.join(str(destination) + '/' + 'Text Files'))
231+
232+
else:
233+
sg.PopupError("File type not found!")
234+
raise SystemExit()
235+
236+
237+
main_gui = fmGUI()
238+
main_gui.main_window()

File Mover/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pysimplegui

0 commit comments

Comments
 (0)