Skip to content

Commit

Permalink
major algorithm overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
vihdutta committed Dec 30, 2021
1 parent ada1e91 commit a9bd0b9
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 172 deletions.
104 changes: 48 additions & 56 deletions asfuncs.py
Original file line number Diff line number Diff line change
@@ -1,61 +1,53 @@
import os
import shutil
from datetime import datetime
from pathlib import Path, PurePath
from random import randint
from shutil import move

RICH_TEXT_FORE_NL = '<span style=\' font-family:"Segoe UI Light"; font-size:18pt; font-weight:400; color:#a89769;\' ><br>'
RICH_TEXT_FORE = '<span style=\' font-family:"Segoe UI Light"; font-size:18pt; font-weight:400; color:#a89769;\' >'
PLAIN_TEXT_FORE = '<span style=\' font-family:"Segoe UI Light"; font-size:18pt; font-weight:400; color:#ffffff;\' >'
# styling
RICH_TEXTFORE_NL = '<span style=\' font-family:"Segoe UI Light"; font-size:18pt; font-weight:400; color:#a89769;\' ><br>'
RICH_TEXTFORE = '<span style=\' font-family:"Segoe UI Light"; font-size:18pt; font-weight:400; color:#a89769;\' >'
PLAIN_TEXTFORE = '<span style=\' font-family:"Segoe UI Light"; font-size:18pt; font-weight:400; color:#ffffff;\' >'
TEXTBACK = '</span>'

def filesnumrenamer(dstname, srcfiles, dstfiles, truepath, id_filelist):
filesidrenamer(dstname, srcfiles, dstfiles, truepath)

for file in Path(truepath).iterdir():
name, extension = PurePath(file).stem, PurePath(file).suffix #error #1
name = name.split('---', 1)[0]
id_filelist.append(name + '---' + extension)
fileamount = id_filelist.count(name + '---' + extension) - 1
if fileamount > 0:
iparentheses = '(' + str(fileamount) + ')'
# add number file for the directory
def duplicate_tagger(file, filecount_id, dstdir, folder, name, extension):
dst_filepath = Path(dstdir) / folder / file
if dst_filepath.is_file():
filecount_id += 1
return duplicate_tagger(f"{name}({filecount_id}){extension}", filecount_id, dstdir, folder, name, extension)
else:
if filecount_id == 0:
return f"{name}{extension}"
else:
iparentheses = ''
filerename = ''.join([name, iparentheses, extension])
os.rename(os.path.join(truepath, file), os.path.join(truepath, filerename))


def filesidrenamer(dstname, srcfiles, dstfiles, truepath):
for root, dirs, files in os.walk(dstname):
for file in os.listdir(truepath):
num = createid(srcfiles, dstfiles)
if '(' in file:
try:
file_ider = file.split('(')[0] + num + file.split('(')[1]
except IndexError:
file_ider = file + num
else:
try:
file_ider = file.split('.')[0] + num + '.' + file.split('.')[1]
except IndexError:
file_ider = file + num
os.rename(os.path.join(truepath, file), os.path.join(truepath, file_ider))



def dstsort(dstname, truepath):
files = [f for f in os.listdir(truepath) if os.path.isfile(os.path.join(truepath, f))]
for file in files:
name, extension = PurePath(file).stem, PurePath(file).suffix
new_dir = PurePath(truepath, extension).joinpath()
if not Path(new_dir).exists():
Path(new_dir).mkdir()
filename = name + extension
old_path = Path(truepath) / file
new_path = Path(truepath) / extension / filename
shutil.move(old_path, new_path)


def createid(srcfiles, dstfiles):
i1 = len(srcfiles) + len(dstfiles)
i2 = int(str(i1) + '0')
return '---' + str(randint(i1, i2))
return f"{name}({filecount_id}){extension}"


# gets filecount for src and destination directories
def total_filecount(srcdirs):
filecount = 0
for srcdir in srcdirs:
for path in Path(srcdir).rglob("*"):
if path.is_file():
filecount += 1
return filecount, filecount


# sorts files in directory
def sortdirs(dstdir, folder):
path = Path(dstdir) / folder
for filepath in path.iterdir():
if filepath.is_file():
name, extension = PurePath(filepath).stem, PurePath(filepath).suffix
new_dir = Path(dstdir) / folder / extension
if not Path(new_dir).exists():
Path(new_dir).mkdir()
filename = name + extension
old_path = Path(dstdir) / folder / filepath
new_path = Path(dstdir) / folder / extension / filename
move(old_path, new_path)


# creates folder
def folder_create(dstdir):
folder_name = f'autosort {datetime.now().strftime("%H-%M-%S-%f")}'
Path(PurePath(dstdir, folder_name).joinpath()).mkdir()
return folder_name
137 changes: 39 additions & 98 deletions autosort.py
Original file line number Diff line number Diff line change
@@ -1,104 +1,45 @@
import os
import shutil
from pathlib import Path, PurePath
from datetime import datetime
from asfuncs import (createid, dstsort, filesnumrenamer,
RICH_TEXT_FORE_NL, RICH_TEXT_FORE, PLAIN_TEXT_FORE, TEXTBACK)

IGNORE_DIRS = ('$RECYCLE.BIN', 'System Volume Information')

metadata = False
srcdirs = []
srcfiles = []
dstfiles = []
id_filelist = []

# base of the copyfromallusbs() function
def copyfromdirs(metadata, replace, fcmethod, sort, dstname):
all_srcfiles_len = 0

if fcmethod == 'Single-folder creation':
folder_name = f'autosort {datetime.now().strftime("%H-%M-%S-%f")}'
Path(PurePath(dstname, folder_name).joinpath()).mkdir()

for srcdir in srcdirs:
for root, dirs, files in os.walk(srcdir):
dirs[:] = [d for d in dirs if d not in IGNORE_DIRS]
for file in files:
all_srcfiles_len += 1

yield f'{RICH_TEXT_FORE}Discovered {all_srcfiles_len} files in directory(s): {", ".join(srcdirs)}{TEXTBACK}'
temp_all_srcfiles_len = all_srcfiles_len

for root, dirs, files in os.walk(dstname):
for file in files:
dstfiles.append(file)

for srcdir in srcdirs:
if fcmethod == 'Multi-folder creation':
folder_name = f'autosort {datetime.now().strftime("%H-%M-%S-%f")}'
Path(PurePath(dstname, folder_name).joinpath()).mkdir()

if 'folder_name' in locals():
truepath = PurePath(dstname, folder_name).joinpath()
else:
truepath = dstname

yield f'{RICH_TEXT_FORE_NL}In directory {srcdir}{TEXTBACK}'

for root, dirs, files in os.walk(srcdir):
dirs[:] = [d for d in dirs if d not in IGNORE_DIRS]
for file in files:
srcfiles.append(file)

for file in files:
if not replace:
try:
file_ider = file.split('.')[0] + createid(srcfiles, dstfiles) + '.' + file.split('.')[1]
except IndexError:
file_ider = file + createid(srcfiles, dstfiles)
from os import walk
from shutil import copy, copy2
from pathlib import Path
from asfuncs import (total_filecount, duplicate_tagger, folder_create,
sortdirs, RICH_TEXTFORE_NL, RICH_TEXTFORE, PLAIN_TEXTFORE, TEXTBACK)
from time import perf_counter

# copies from srcdirs to dstdir + creates filenumber for files
def copy_from_dirs(srcdirs, dstdir, fcmethod, sort, metadata, replace):
start_time = perf_counter()
folder = ""
filecount, filecount_temp = total_filecount(srcdirs)
yield f'{RICH_TEXTFORE}Discovered {filecount} files in directory(s): {", ".join(srcdirs)}{TEXTBACK}'

if fcmethod == "Single-folder creation":
folder = folder_create(dstdir)
for srcdir in srcdirs: # for each source directory
yield f'{RICH_TEXTFORE_NL}In directory {srcdir}{TEXTBACK}'
if fcmethod == "Multi-folder creation":
folder = folder_create(dstdir)
for root, _, files in walk(srcdir): # get data for source directory
for file in files: # iterate through each file
yield f'{PLAIN_TEXTFORE}Copying "{file}"... {filecount} of {filecount_temp} remain.{TEXTBACK}'
filecount_temp -= 1
filecount_id = 0
src_filepath = Path(root) / file
name, extension = src_filepath.stem, src_filepath.suffix

if replace:
new_filename = file
else:
file_ider = file
new_filename = duplicate_tagger(file, filecount_id, dstdir, folder, name, extension)
old_path = Path(root) / file
new_path = Path(dstdir) / folder / new_filename

yield f'{PLAIN_TEXT_FORE}Copying "{file}"... {temp_all_srcfiles_len} of {all_srcfiles_len} remain.{TEXTBACK}'
temp_all_srcfiles_len -= 1

if metadata:
shutil.copy2(PurePath(root, file).joinpath(), PurePath(truepath, file_ider).joinpath())
copy2(old_path, new_path)
else:
shutil.copy(PurePath(root, file).joinpath(), PurePath(truepath, file_ider).joinpath())
dstfiles.append(file_ider)

if fcmethod == 'Multi-folder creation':
if not replace:
yield f'{RICH_TEXT_FORE_NL}Enumerating...{TEXTBACK}'
filesnumrenamer(dstname, srcfiles, dstfiles, truepath, id_filelist)
if sort:
dstsort(dstname, truepath)
yield f'{RICH_TEXT_FORE}Finished{TEXTBACK}'
id_filelist.clear()

if fcmethod == 'Single-folder creation':
if not replace:
yield f'{RICH_TEXT_FORE_NL}Enumerating...{TEXTBACK}'
filesnumrenamer(dstname, srcfiles, dstfiles, truepath, id_filelist)
copy(old_path, new_path)
if sort:
dstsort(dstname, truepath)
yield f'{RICH_TEXT_FORE}Finished{TEXTBACK}'

elif fcmethod == 'No folder creation':
if not replace:
yield f'{RICH_TEXT_FORE_NL}Enumerating...{TEXTBACK}'
filesnumrenamer(dstname, srcfiles, dstfiles, truepath, id_filelist)
if sort:
dstsort(dstname, truepath)
yield f'{RICH_TEXT_FORE}Finished{TEXTBACK}'

id_filelist.clear()
yield f'{RICH_TEXTFORE}Sorting files...{TEXTBACK}'
sortdirs(dstdir, folder)


'''testing items'''
# tic = time.perf_counter()
# toc = time.perf_counter()
# with open('testing/filenamehere.txt', 'a') as f:
# f.write(f'File copied in {toc - tic:0.4f} seconds\n')
end_time = perf_counter()
yield f'{RICH_TEXTFORE}Finished in {start_time-end_time} seconds.{TEXTBACK}'
40 changes: 22 additions & 18 deletions autosortgui.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QLabel
from autosort import copyfromdirs, srcdirs
from asfuncs import RICH_TEXT_FORE, TEXTBACK
from autosort import copy_from_dirs
from asfuncs import RICH_TEXTFORE, TEXTBACK
from pathlib import Path
import qtfiles.qtresources.resources

srcdirs = []
dstdir = ""

class WorkerSignals(QtCore.QObject):
result = QtCore.pyqtSignal(object)
class Worker(QtCore.QRunnable):
def __init__(self, run_button, metadata, replace, fcmethod, sort, destdir):
def __init__(self, run_button, srcdirs, dstdir, fcmethod, sort, metadata, replace):
super().__init__()
self.signals = WorkerSignals()
self.run_button = run_button
self.metadata = metadata
self.replace = replace
self.srcdirs = srcdirs
self.dstdir = dstdir
self.fcmethod = fcmethod
self.sort = sort
self.destdir = destdir
self.metadata = metadata
self.replace = replace

@QtCore.pyqtSlot()
def run(self):
self.run_button.setEnabled(False)
function = copyfromdirs(self.metadata, self.replace, self.fcmethod, self.sort, self.destdir)
function = copy_from_dirs(self.srcdirs, self.dstdir, self.fcmethod, self.sort, self.metadata, self.replace)
for statement in function:
self.signals.result.emit(statement)
self.run_button.setEnabled(True)
Expand Down Expand Up @@ -515,17 +519,17 @@ def setupUi(self, MainWindow):


def source_button_click(self):
sourcedir = QFileDialog.getExistingDirectory()
if Path(sourcedir).is_dir() and sourcedir != '':
srcdirs.append(sourcedir)
srcdirsstring = f'{RICH_TEXT_FORE}, {TEXTBACK}'.join(srcdirs)
srcdir = QFileDialog.getExistingDirectory()
if Path(srcdir).is_dir() and srcdir != '':
srcdirs.append(srcdir)
srcdirsstring = f'{RICH_TEXTFORE}, {TEXTBACK}'.join(srcdirs)
self.sourcedisplay.setText(srcdirsstring)


def destination_button_click(self):
# bug: if user has selected destdir before then presses cancel on destdir file dialog.
self.destdir = QFileDialog.getExistingDirectory()
self.destinationdisplay.setText(self.destdir)
# bug: if user has selected dstdir before then presses cancel on dstdir file dialog.
self.dstdir = QFileDialog.getExistingDirectory()
self.destinationdisplay.setText(self.dstdir)


def run_button_click(self):
Expand All @@ -550,11 +554,11 @@ def run_button_click(self):
nosourceerror.setIcon(QMessageBox.Critical)
nosourceerror.exec_()
try:
if Path(self.destdir).is_dir() and srcdirs:
worker = Worker(self.run_button, metadata, replace, fcmethod, sort, self.destdir)
if Path(self.dstdir).is_dir() and srcdirs:
worker = Worker(self.run_button, srcdirs, self.dstdir, fcmethod, sort, metadata, replace)
worker.signals.result.connect(self.statement_returner)
self.threadpool.start(worker)
elif not Path(self.destdir).is_dir() or self.destdir == '':
elif not Path(self.dstdir).is_dir() or self.dstdir == '':
nodestinationerror = QMessageBox()
nodestinationerror.setWindowTitle('Error')
nodestinationerror.setText('Destination directory field cannot be empty.')
Expand All @@ -579,7 +583,7 @@ def sourcedisplay_clear(self):

def destinationdisplay_clear(self):
self.destinationdisplay.clear()
self.destdir = False
self.dstdir = False


def retranslateUi(self, MainWindow):
Expand Down

0 comments on commit a9bd0b9

Please sign in to comment.