add web
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import hashlib
|
||||
from PIL import Image
|
||||
from app.routes.asset import CreateFakeAsset
|
||||
from app.routes.thumbnailer import ValidatePlaceFileRequest
|
||||
from app.enums.PlaceYear import PlaceYear
|
||||
from app.util import s3helper
|
||||
import uuid
|
||||
import time
|
||||
import json
|
||||
import os
|
||||
import logging
|
||||
import eyed3
|
||||
import tempfile
|
||||
import ffmpeg
|
||||
|
||||
# TODO: Make this less shit
|
||||
|
||||
def ValidateClothingImage( file, verifyResolution = True, validateFileSize = True, returnImage = False ):
|
||||
try:
|
||||
file.seek(0, os.SEEK_END)
|
||||
FileSize = file.tell()
|
||||
if FileSize > 1024 * 1024 and validateFileSize:
|
||||
raise Exception("File is larger than 1MB")
|
||||
|
||||
ImageObj = Image.open(file)
|
||||
ImageObj.verify()
|
||||
|
||||
if ImageObj.format != "PNG":
|
||||
raise Exception("File is not a PNG file")
|
||||
|
||||
if ImageObj.size != (585, 559) and verifyResolution:
|
||||
raise Exception("File is not 585 x 559")
|
||||
|
||||
if returnImage:
|
||||
file.seek(0, os.SEEK_END)
|
||||
|
||||
ImageObj = Image.open(file).convert("RGBA")
|
||||
ImageData = list(ImageObj.getdata())
|
||||
SanitizedImage = Image.new(ImageObj.mode, ImageObj.size)
|
||||
SanitizedImage.putdata(ImageData)
|
||||
|
||||
return SanitizedImage
|
||||
|
||||
except Exception as e:
|
||||
return False
|
||||
return True
|
||||
|
||||
def ValidatePlaceFile( file, keepFileWhenInvalid = False, TestPlaceYear : PlaceYear = PlaceYear.Eighteen, bypassCache : bool = False ):
|
||||
try:
|
||||
from app.extensions import redis_controller
|
||||
file.seek(0, os.SEEK_END)
|
||||
FileSize = file.tell()
|
||||
if FileSize > 1024 * 1024 * 30:
|
||||
raise Exception("File is larger than 30MB")
|
||||
file.seek(0)
|
||||
FileContents = file.read()
|
||||
FileHash = hashlib.sha512(FileContents).hexdigest()
|
||||
|
||||
if not bypassCache:
|
||||
validationResults : int | None = redis_controller.get(f"ValidatePlaceFile:{FileHash}:{TestPlaceYear.value}")
|
||||
if validationResults is not None:
|
||||
return validationResults == 1
|
||||
|
||||
s3helper.UploadBytesToS3(FileContents, FileHash)
|
||||
TemporaryAssetId = CreateFakeAsset(AssetName = "AssetValidationService", Expiration = 60 * 10, AssetFileHash = FileHash)
|
||||
PlaceValidationReqUUID = str(uuid.uuid4())
|
||||
|
||||
ValidatePlaceFileRequest( TemporaryAssetId, PlaceValidationReqUUID, TestPlaceYear)
|
||||
logging.info(f"Sent validation request for '{FileHash}' with UUID {PlaceValidationReqUUID}")
|
||||
StartTime = time.time()
|
||||
ResponseInfo = None
|
||||
while True:
|
||||
if time.time() - StartTime > 45:
|
||||
raise Exception("Timed out while waiting for a response from AssetValidation Service")
|
||||
ResponseInfo = redis_controller.get(f"ValidatePlaceFileRequest:{PlaceValidationReqUUID}")
|
||||
if ResponseInfo is None:
|
||||
time.sleep(0.2)
|
||||
continue
|
||||
else:
|
||||
break
|
||||
if ResponseInfo is not None:
|
||||
ResponseInfo = json.loads(ResponseInfo)
|
||||
if ResponseInfo["valid"]:
|
||||
redis_controller.set(f"ValidatePlaceFile:{FileHash}:{TestPlaceYear.value}", 1, 60 * 60 * 24 * 2)
|
||||
return True
|
||||
else:
|
||||
redis_controller.set(f"ValidatePlaceFile:{FileHash}:{TestPlaceYear.value}", 0, 60 * 60 * 24 * 2)
|
||||
raise Exception(ResponseInfo["error"])
|
||||
except Exception as e:
|
||||
if not keepFileWhenInvalid:
|
||||
try:
|
||||
s3helper.DeleteFileFromR2(FileHash)
|
||||
except:
|
||||
pass
|
||||
return str(e)
|
||||
return True
|
||||
|
||||
def ValidateMP3File( file ) -> int | None:
|
||||
"""
|
||||
Validates an MP3 file and returns duration in seconds
|
||||
"""
|
||||
TemporaryFile = tempfile.NamedTemporaryFile(suffix=".mp3", delete=True)
|
||||
file.seek(0)
|
||||
TemporaryFile.write(file.read())
|
||||
try:
|
||||
AudioFile = eyed3.load(TemporaryFile.name)
|
||||
if AudioFile is None:
|
||||
return None
|
||||
TemporaryFile.close()
|
||||
return AudioFile.info.time_secs
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to validate MP3 file: {e}")
|
||||
return None
|
||||
|
||||
def ValidateMP3AndConvertToOGG( file ) -> (bytes, int):
|
||||
"""
|
||||
Validates given file is a MP3 File and then converts it into the OGG format and returns the bytes and length of the sound in seconds
|
||||
"""
|
||||
TemporaryFile = tempfile.NamedTemporaryFile(suffix=".mp3", delete=True)
|
||||
OutputTemporaryFile = tempfile.NamedTemporaryFile(suffix=".ogg", delete=True)
|
||||
try:
|
||||
file.seek(0)
|
||||
TemporaryFile.write(file.read())
|
||||
|
||||
AudioFile = eyed3.load(TemporaryFile.name)
|
||||
if AudioFile is None:
|
||||
TemporaryFile.close()
|
||||
raise Exception("Failed to load MP3 file")
|
||||
FFmpegStream = ffmpeg.input(TemporaryFile.name, vn=None)
|
||||
FFmpegStream = ffmpeg.output(FFmpegStream, OutputTemporaryFile.name, acodec="libvorbis", f="ogg")
|
||||
ffmpeg.run(FFmpegStream, overwrite_output = True, quiet = True, capture_stdout = False, capture_stderr = False)
|
||||
OutputTemporaryFile.seek(0)
|
||||
OutputFileBytes = OutputTemporaryFile.read()
|
||||
|
||||
ProbeResult = ffmpeg.probe(OutputTemporaryFile.name, select_streams="a")
|
||||
AudioDuration = float(ProbeResult["streams"][0]["duration"])
|
||||
|
||||
OutputTemporaryFile.close()
|
||||
TemporaryFile.close()
|
||||
return OutputFileBytes, AudioDuration
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to validate MP3 file: {e}")
|
||||
|
||||
TemporaryFile.close()
|
||||
OutputTemporaryFile.close()
|
||||
raise e
|
||||
Reference in New Issue
Block a user