from flask_login import current_user from wtforms.validators import ValidationError, StopValidation from werkzeug.utils import secure_filename from app.utils.filesize import filesize import re def optional(form, files): if(len(files.data) == 0 or files.data[0].filename == ""): raise StopValidation() def count(form, files): if current_user.is_authenticated: if current_user.priv("no-upload-limits"): return if len(files.data) > 100: # 100 files for a authenticated user raise ValidationError("100 fichiers maximum autorisés") else: if len(files.data) > 3: raise ValidationError("3 fichiers maximum autorisés") def extension(form, files): valid_extensions = [ "g[123][a-z]|cpa|c1a|fxi|cat|mcs|xcp|fls", # Casio files "png|jpg|jpeg|bmp|tiff|gif|xcf", # Images "[ch](pp|\+\+|xx)?|s|py|bide|lua|lc", # Source code "txt|md|tex|pdf|odt|ods|docx|xlsx", # Office files "zip|7z|tar|bz2?|t?gz|xz|zst", # Archives ] r = re.compile("|".join(valid_extensions), re.IGNORECASE) errors = [] for f in files.data: name = secure_filename(f.filename) ext = name.split(".")[-1] if not r.fullmatch(ext): errors.append("." + ext) if len(errors) > 0: raise ValidationError(f"Extension(s) invalide(s) ({', '.join(errors)})") def size(form, files): """There is no global limit to file sizes""" size = sum([filesize(f) for f in files.data]) if current_user.is_authenticated: if current_user.priv("no-upload-limits"): return if size > 5e6: # 5 Mo per comment for an authenticated user raise ValidationError("Fichiers trop lourds (max 5 Mo)") else: if size > 500e3: # 500 ko per comment for a guest raise ValidationError("Fichiers trop lourds (max 500 ko)") def namelength(form, files): errors = [] for f in files.data: name = secure_filename(f.filename) if len(name) > 64: errors.append(f.filename) if len(errors) > 0: raise ValidationError(f"Noms trop longs, 64 caractères max " \ f"({', '.join(errors)})")