2023-01-07 15:56:18 +00:00
import os , shutil , platform
import zipfile , rarfile
from py7zr import SevenZipFile , exceptions
2023-03-10 12:48:29 +00:00
from utils . settings import BAD_DIR_NAME
2023-01-07 15:56:18 +00:00
2023-03-03 13:13:28 +00:00
def mark_file_as_BAD ( file : str , bad_exception : Exception ) - > None :
2023-01-07 15:56:18 +00:00
try :
filename = os . path . basename ( file )
bad_dir = os . path . join ( os . path . dirname ( file ) , BAD_DIR_NAME )
os . makedirs ( bad_dir , exist_ok = True )
bad_file_path = os . path . join ( bad_dir , filename )
shutil . move ( file , bad_file_path )
print ( f ' [Warning] Found BAD compressed file: { filename } \n Moved to: { bad_file_path } \n Error message: { bad_exception } ' )
except Exception as e :
print ( f ' [Error] { e } ' )
2023-03-05 14:56:10 +00:00
def extract_zip ( zip_file : str , target_dir : str ) - > None | Exception :
2023-01-07 15:56:18 +00:00
try :
with zipfile . ZipFile ( zip_file , ' r ' ) as zip_ref :
members = [ m for m in zip_ref . infolist ( ) if " __MACOSX " not in m . filename ]
zip_ref . extractall ( target_dir , members = members ) # extract all files, ignoring those with the "__MACOSX" string in the name
zip_ref . close ( )
except zipfile . BadZipfile as e :
mark_file_as_BAD ( zip_file , e )
2023-03-01 00:43:34 +00:00
except Exception as e :
2023-03-03 13:13:28 +00:00
print ( f ' [ERROR] Something went wrong while extracting the contents of a submitted zip file. Check the error message, get student id and download / organise manually \n Error message: { e } ' )
2023-03-05 14:56:10 +00:00
return e
2023-01-07 15:56:18 +00:00
2023-03-03 13:13:28 +00:00
def extract_rar ( rar_file : str , target_dir : str ) - > None :
2023-01-07 15:56:18 +00:00
try :
with rarfile . RarFile ( rar_file , ' r ' ) as rar_ref :
if platform . system ( ) == ' Windows ' :
rarfile . UNRAR_TOOL = os . path . join ( ' utils ' , ' UnRAR.exe ' )
else : # if Linux or Mac
rarfile . UNRAR_TOOL = ' unrar '
files = rar_ref . namelist ( )
files = [ f for f in files if " __MACOSX " not in f ] # filter out files with "__MACOSX" in the name
2024-02-23 18:03:13 +00:00
try :
rar_ref . extractall ( target_dir , files ) # extract the remaining files
rar_ref . close ( )
except OSError :
mark_file_as_BAD ( rar_file , e )
2023-01-07 15:56:18 +00:00
except rarfile . BadRarFile as e :
mark_file_as_BAD ( rar_file , e )
except rarfile . NotRarFile as e :
mark_file_as_BAD ( rar_file , e )
except rarfile . RarCannotExec as e :
print ( ' [Error] Missing unrar tool \n for Windows: make sure file UnRAR.exe exists in directory \' utils \' \n for Linux/Mac: need to install unrar (check README) ' )
exit ( )
2023-03-03 13:13:28 +00:00
def extract_7z ( seven_zip_file : str , target_dir : str ) - > None :
2023-01-07 15:56:18 +00:00
try : # extract the 7z file using py7zr
with open ( seven_zip_file , ' rb ' ) as f :
seven_zip = SevenZipFile ( seven_zip_file , mode = ' r ' )
if not seven_zip . getnames ( ) :
raise exceptions . Bad7zFile
files = seven_zip . getnames ( )
files = [ f for f in files if " __MACOSX " not in f ] # filter out files with "__MACOSX" in the name
seven_zip . extract ( target_dir , targets = files ) # extract the remaining files
seven_zip . close ( )
except exceptions . Bad7zFile as e :
mark_file_as_BAD ( seven_zip_file , e )
except Exception as e :
mark_file_as_BAD ( seven_zip_file , e )
2023-03-05 14:56:10 +00:00
def extract_file_to_dir ( file_path : str , student_dir : str ) - > None | Exception :
2023-01-07 15:56:18 +00:00
os . makedirs ( student_dir , exist_ok = True ) # create the subdirectory for student
if file_path . lower ( ) . endswith ( ' .zip ' ) :
2023-03-05 14:56:10 +00:00
return extract_zip ( file_path , student_dir )
2023-01-07 15:56:18 +00:00
elif file_path . lower ( ) . endswith ( ' .rar ' ) :
extract_rar ( file_path , student_dir )
elif file_path . lower ( ) . endswith ( ' .7z ' ) :
extract_7z ( file_path , student_dir )
else :
print ( f " [Error] unknown file type: { file_path } " )