
Digging in the Dirt
Find and display the paths of all of the files in a directory (and, potentially, all of its subdirectories, and their subdirectories, and so on), and then take action (such as reading, modifying, calculating their bytes, duplicating, touching, etc.) on some of the files that have interesting characteristics.
import os
import shutil
from pathlib import Path
def subdirectoryCheck(subdirectory: Path, listPaths: [Path]) -> Path:
'''Checks and returns the list of files inside a subdirectory and repeats if necessary.'''
for subPath in sorted(Path(subdirectory).()):
if subPath.is_file() == True:
listPaths.append(subPath)
for subelement in subdirectory.iterdir():
if subelement.is_dir() == True:
subdirectoryCheck(subelement, listPaths)
return listPaths
def userInputSpecifier(userInput: str) -> (str, str):
'''Splits the user's input if multi-part and returns the user's input in an organized manner.'''
checkLetter = ''
searchStatement = ''
while True:
if userInput == "A" or userInput == "F" or userInput == "D" or userInput == "T":
checkLetter = userInput[0]
searchStatement = ''
return checkLetter, searchStatement
elif " " in userInput:
splitInput = userInput.split(" ", 1)
checkLetter = splitInput[0]
searchStatement = splitInput[-1]
if checkLetter == "N" or checkLetter == "E" or checkLetter == "T" or checkLetter == "<" or checkLetter == ">":
if searchStatement != "":
return checkLetter, searchStatement
else:
print("ERROR")
userInput = input()
continue
else:
print("ERROR")
userInput = input()
continue
else:
print("ERROR")
userInput = input()
continue
def letterA(listPaths: [Path], interesting: [], checkStatement: bool, missingCheck: bool) -> (bool, [Path], bool):
'''Adds all the files to the 'interesting' list if user's input is just 'A'. '''
if listPaths != []:
for element in listPaths:
print(element)
interesting.append(element)
missingCheck = True
checkStatement = False
return checkStatement, interesting, missingCheck
def letterN(searchStatement: str, checkStatement: bool, listPaths: [Path], interesting: [], missingCheck: bool) -> (bool, [Path], bool):
'''Splits the path to see if matches part of user's input. If so, considered interesting.'''
if listPaths != []:
for element in listPaths:
splitPath = os.path.split(element)
if searchStatement == splitPath[-1]:
print(element)
interesting.append(element)
missingCheck = True
checkStatement = False
return checkStatement, interesting, missingCheck
def letterE(searchStatement: str, checkStatement: bool, listPaths: [Path], interesting: [], missingCheck: bool) -> (bool, [Path], bool):
'''split each individual line to find their extension. see if extension matches searchStatement. If so, considered interesting.'''
if listPaths != []:
for element in listPaths:
pathSuffix = element.suffix
if searchStatement[0] != ".":
searchStatement = "." + searchStatement
if searchStatement == pathSuffix and element.exists():
print(element)
interesting.append(element)
missingCheck = True
checkStatement = False
return checkStatement, interesting, missingCheck
def letterT(searchStatement: str, checkStatement: bool, listPaths: [Path], interesting: [], missingCheck: bool) -> (bool, [Path], bool):
'''if opened file's readlines contains the specified phrase, is considered interesting.'''
for element in listPaths:
openFile = None
try:
openFile = open(element, 'r')
for eachLine in openFile.readlines():
if searchStatement in eachLine:
print(element)
interesting.append(element)
missingCheck = True
break
except ValueError or PermissionError:
pass
finally:
if openFile != None:
openFile.close()
checkStatement = False
return checkStatement, interesting, missingCheck
def lessBytes(searchStatement: str, checkStatement: bool, listPaths: [Path], interesting: [], missingCheck: bool) -> (bool, [Path], bool):
'''checks the amount of bytes the file contains and compares to the amount of bytes user specifies. If less than, considered interesting.'''
try:
if "," in searchStatement:
searchStatement = searchStatement.replace(",", "")
threshold = int(searchStatement)
if type(threshold) == int and threshold >= 0:
if listPaths != []:
for element in listPaths:
if element.is_file() == True:
elementInfo = os.stat(element)
fileSize = elementInfo.st_size
if fileSize < threshold:
print(element)
interesting.append(element)
missingCheck = True
except ValueError:
print("ERROR")
userInput = input()
checkLetter, searchStatement = userInputSpecifier(userInput)
checkStatement, interesting, missingCheck = lessBytes(searchStatement, checkStatement, listPaths, interesting, missingCheck)
finally:
checkStatement = False
return checkStatement, interesting, missingCheck
def greaterBytes(searchStatement: str, checkStatement: bool, listPaths: [Path], interesting: [], missingCheck: bool) -> (bool, [Path], bool):
'''checks the amount of bytes the file contains and compares to the amount of bytes user specifies. If greater than, considered interesting.'''
try:
if "," in searchStatement:
searchStatement = searchStatement.replace(",", "")
threshold = int(searchStatement)
if type(threshold) == int and threshold >= 0:
if listPaths != []:
for element in listPaths:
if element.is_file() == True:
elementInfo = os.stat(element)
fileSize = elementInfo.st_size
if fileSize > threshold:
print(element)
interesting.append(element)
missingCheck = True
except ValueError:
print("ERROR")
userInput = input()
checkLetter, searchStatement = userInputSpecifier(userInput)
checkStatement, interesting, missingCheck = lessBytes(searchStatement, checkStatement, listPaths, interesting, missingCheck)
finally:
checkStatement = False
return checkStatement, interesting, missingCheck
def interestingF(interesting: [Path], loopControl: bool) -> (bool):
'''If this line of input contains the letter F by itself, print the first line of text from the file if it's a text file; print NOT TEXT if it is not.'''
for element in interesting:
textCheck = None
try:
textCheck = open(element, 'r')
read_the_file = textCheck.readline()
if '\n' in read_the_file:
print(read_the_file, end='')
else:
print(read_the_file)
loopControl = False
except:
print('NOT TEXT')
loopControl = True
finally:
if textCheck != None:
textCheck.close()
loopControl = False
return loopControl
def interestingD(interesting: [Path], loopControl: bool) -> (bool):
'''Duplicates the file specified, stores in same directory as found, but renames the extension.'''
for element in interesting:
dupTitle = str(element) + '.dup'
duplicate = shutil.copy(element, dupTitle)
loopControl = False
return loopControl
def interestingT(interesting: [Path], loopControl: bool) -> (bool):
'''Touches the file - modifies its last timestamp to be the current date/time.'''
for element in interesting:
element.touch()
loopControl = False
return loopControl
def fileOpen():
'''Calls functions based on the user's input'''
listPaths = []
interesting = []
while True:
file_path = input()
if file_path != '' and len(file_path) > 2:
splitStatement = file_path.split(' ')
if splitStatement[1] != '':
location = Path(splitStatement[1])
if location.exists():
beginningLetter = splitStatement[0]
if beginningLetter != 'D' and beginningLetter != 'R':
print('ERROR')
else:
break
else:
print('ERROR')
else:
print('ERROR')
else:
print('ERROR')
if beginningLetter == 'D':
for element in location.iterdir():
if element.is_file():
listPaths.append(element)
for file in listPaths:
print(file)
elif beginningLetter == 'R':
listPaths = subdirectoryCheck(location, listPaths)
sortedList = []
for element in listPaths:
if element not in sortedList:
sortedList.append(element)
print(element)
userInput = input()
checkLetter, searchStatement = userInputSpecifier(userInput)
checkStatement = True
'''False means break while loop'''
missingCheck = False
while checkStatement == True:
if checkLetter == "A":
checkStatement, interesting, missingCheck = letterA(listPaths, interesting, checkStatement, missingCheck)
elif checkLetter == "N":
checkStatement, interesting, missingCheck = letterN(searchStatement, checkStatement, listPaths, interesting, missingCheck)
elif checkLetter == "E":
checkStatement, interesting, missingCheck = letterE(searchStatement, checkStatement, listPaths, interesting, missingCheck)
elif checkLetter == "T":
checkStatement, interesting, missingCheck = letterT(searchStatement, checkStatement, listPaths, interesting, missingCheck)
elif checkLetter == "<":
checkStatement, interesting, missingCheck = lessBytes(searchStatement, checkStatement, listPaths, interesting, missingCheck)
elif checkLetter == ">":
checkStatement, interesting, missingCheck = greaterBytes(searchStatement, checkStatement, listPaths, interesting,missingCheck )
else:
print("ERROR")
userInput = input()
userInputSpecifier(userInput)
if missingCheck:
loopControl = True
while loopControl == True:
checkLetter = input()
if checkLetter == 'F':
loopControl = interestingF(interesting, loopControl)
elif checkLetter == 'D':
loopControl = interestingD(interesting, loopControl)
elif checkLetter == 'T':
loopControl = interestingT(interesting, loopControl)
else:
print("ERROR")
if __name__ == "__main__":
fileOpen()