I am writing a backup program. Thus far all my functions work fine. But now I am getting a strange problem where 1 single line seems to break my move function, yet it doesn't even interact with it (it returns total size of all files in folder).
shutil.move throws an already exists error, BUT still moves the file.
Here are all functions thus far, at the bottom commented indicates the line that breaks it:
import shutil
import glob, os
import time
##Zip selected folder
def createZip(outputName, sourceDir):
fileName = outputName+str(time.strftime("_%Y%m%d%H%M%S"))
shutil.make_archive(fileName, 'zip', sourceDir)
fileSize = os.path.getsize(fileName+'.zip')
print("This file's size", fileSize)
return fileSize, fileName+'.zip'
##Move zipped folder to selected location
def moveFile(file, outPath):
print(file)
shutil.move(file, outPath)
##Check how many previous backups exist
def listFiles(buDir):
fileList = []
os.chdir(buDir)
for file in glob.glob("*.zip"):
fileList.append(file)
return fileList
##Check total combined size of zip files in folder
def totalSize(fileList):
total = 0
for x in fileList:
total += os.path.getsize(x)
print(convertBytes(total)[0],convertBytes(total)[1])
return total
##Converts output to TB, GB, MB, or KB
def convertBytes(byte, unit = 'bytes'):
if byte/(1024**4) >= 1:
convert = round(byte/(1024**4), 2)
unit = "TB"
elif byte/(1024**4) < 1 and byte/(1024**3) >= 1:
convert = round(byte/(1024**3),2)
unit = "GB"
elif byte/(1024**3) < 1 and byte/(1024**2) >= 1:
convert = round(byte/(1024**2), 2)
unit = "MB"
elif byte/1024**2 < 1:
convert = round(byte/1024, 2)
unit = "KB"
return convert, unit
##Function for yes/no questions ensuring a yes/no answer
def yesNoInput(message, error = "Invalid input, try again"):
while True:
try:
i = input(message)
if isinstance(i, str) == True:
i = i.lower().strip()
if i != "yes" and i != "no" and i != "y" and i != "n":
raise ValueError
except Exception as e:
print(error)
continue
return i
##Delete oldest backup
def removeOld(folder):
fileList = [s.strip('.zip') for s in listFiles(folder)]
sortedList = sorted(fileList, key=lambda x: int(x[-12:-1]))
if len(fileList) == 1:
print("One backup file remains. Not deleting.")
elif len(fileList) == 0:
print("No backup files exist")
else:
toRemove = str(sortedList[0]+'.zip')
os.remove(folder+toRemove)
##Check if maximum number of desired backupfiles has been reached
def checkMax(maxKeep):
print(maxKeep, 'maximum number of files to keep selected')
i = len(listFiles(outputFolder))+1
print(i-1, 'number of files exist.')
if maxKeep == None:
print('No files removed')
elif maxKeep <= 0:
areSure = yesNoInput('WARNING: Max files to keep selected is 0! \nThis will delete ALL backup files. Are you sure? ')
if areSure == 'yes' or areSure == 'y':
filelist = listFiles(outputFolder)
for f in filelist:
os.remove(f)
print('Removed', i-1, 'files.')
else:
print('No files removed. Please adjust config file.')
elif maxKeep < i:
for x in range(1,i-maxKeep):
removeOld(outputFolder)
print('Removed', (i-1)-len(listFiles(outputFolder)), 'files.')
else:
print('No files removed')
##Convert string memory value to int and appropriate units
def conBytes(toConvert):
units = toConvert[-2:].upper()
number = float(toConvert[:-2])
if units == 'TB':
number = number * 1024**4
elif units == 'GB':
number = number * 1024**3
elif units == 'MB':
number = number * 1024**2
elif units == 'KB':
number = number * 1024
return number, units
##Confirm there is enough free space and that max space allotted is not exceeded.
##If either condition fails, deletes oldest file to make space
def makeWay(maxUse, freeSpace, totalSize):
print(convertBytes(fileSize))
print(maxUse)
while True:
if freeSpace < fileSize or maxUse < totalSize:
i = yesNoInput('Not enough storage space available. Remove oldest archive? ')
if i == 'yes' or i == 'y':
while freeSpace < fileSize or maxUse < totalSize:
removeOld(outputFolder)
##Below is used for function testing purposes
userName = ""
outputDrive = "D:\\"
maxKeep = 5
maxUse = '400MB'
backupFolder = "C:\\Tester"
userName = "User"
outputFolder = outputDrive+userName+'\\'
##This next line, when not commented out, for some reason breaks the move function. It throws a 'destination already exists' error, BUT still moves the file.
##print('Output total size',totalSize(listFiles(outputFolder)))
fileSize, fileName = createZip(userName, backupFolder)
moveFile(fileName, outputFolder)