Add a django validator for urls-pointing-to-pictures
authorMagnus Hagander <magnus@hagander.net>
Fri, 31 Aug 2018 13:16:41 +0000 (15:16 +0200)
committerMagnus Hagander <magnus@hagander.net>
Fri, 31 Aug 2018 13:22:32 +0000 (15:22 +0200)
postgresqleu/util/validators.py

index a8f2382cd378b321905949d1635158149ef8855d..2647a509d2cb1c7d626be55ede0f2d354e8982f6 100644 (file)
@@ -1,6 +1,10 @@
 from django.core.exceptions import ValidationError
+from django.utils.deconstruct import deconstructible
+
+from StringIO import StringIO
 
 import requests
+from PIL import Image
 
 def validate_lowercase(value):
        if value != value.lower():
@@ -72,3 +76,35 @@ def validate_json_structure(config, structure):
                                _validate_json_level(v, structure[k], path+[k])
 
        _validate_json_level(config, structure, [])
+
+
+@deconstructible
+class PictureUrlValidator(object):
+       def __init__(self, aspect=None):
+               self.aspect = aspect
+
+       def __call__(self, value):
+               try:
+                       r = requests.get(value,
+                                                        headers={'User-agent': 'Firefox/60'},
+                                                        timeout=5)
+               except:
+                       raise ValidationError("Could not download promotion picture")
+
+               if r.status_code != 200:
+                       raise ValidationError("Downloading promo picture returned status %s" % r.status_code)
+               try:
+                       img = Image.open(StringIO(r.content))
+                       w,h = img.size
+                       if self.aspect:
+                               newaspect = round(float(w)/float(h), 2)
+                               if newaspect != self.aspect:
+                                       raise ValidationError("Image has aspect ratio %s, must have %s" % (newaspect, self.aspect))
+
+               except ValidationError:
+                       raise
+               except Exception, e:
+                       raise ValidationError("Failed to parse image: %s" % e)
+
+       def __eq__(self, other):
+               return self.aspect == other.aspect