From a3119555347f9cf9635a2979c9fb7343d3416afe Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Wed, 23 Sep 2015 01:34:08 +0100 Subject: [PATCH 1/4] Add system check for libjpeg / zlib --- wagtail/wagtailimages/apps.py | 2 + wagtail/wagtailimages/check_files/wagtail.jpg | Bin 0 -> 1160 bytes wagtail/wagtailimages/check_files/wagtail.png | Bin 0 -> 849 bytes wagtail/wagtailimages/checks.py | 58 ++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 wagtail/wagtailimages/check_files/wagtail.jpg create mode 100644 wagtail/wagtailimages/check_files/wagtail.png create mode 100644 wagtail/wagtailimages/checks.py diff --git a/wagtail/wagtailimages/apps.py b/wagtail/wagtailimages/apps.py index 88cd6e3f03..3b5a619006 100644 --- a/wagtail/wagtailimages/apps.py +++ b/wagtail/wagtailimages/apps.py @@ -1,5 +1,7 @@ from django.apps import AppConfig +from . import checks + class WagtailImagesAppConfig(AppConfig): name = 'wagtail.wagtailimages' diff --git a/wagtail/wagtailimages/check_files/wagtail.jpg b/wagtail/wagtailimages/check_files/wagtail.jpg new file mode 100644 index 0000000000000000000000000000000000000000..58d26fba22deb864bcc85ff2d80a63d94fe5aeb6 GIT binary patch literal 1160 zcmex=``2_j6xdp@o1cgOJMMZh|#U;coyG6VInuyV4pa*FVB^NNrR z{vToxhWMC3xWEN!ne}qAbfsuh32oZpTftj6^jT0y*0`vqL_7kQPhiup1X^9!Ki<$jmX1Z^@@Z_X()h4r@H8vfOBVJ@~mQ~cV zo8eU=yx8&fh21`KM-8$Qv=k4=xm+^3vS!tZ&mgA?qC3?AYymSPqdlWK9tBJ=1x7&E zGBdIH#);rY)VDxVd%O zls;{_8Q$}f$FbkXP`SI8mr5rI@a65=z3O_(tNZIt zEY;$!57hc+CMn*$w901YLzBg|xBoMwo)DVX^SeCsmg)g>=@4;luSMUU-_U$j4-6(H z0brB>BMlL2z{CO!0HE(11r#POg!!7$UUAWp%YGHIYZy-j)^+Z;+IV2O>N;2LT`WaD zSvy`_N%`^3#Jc$4?}A0AcD&v(TV3a~W8};Zh1*K+Z|=Sl5wpTO`O`nnQqP+OH%^Be zxrqv>cTRb$JmbdND6{MN>truxDb=juIpol@`I5~!$Nh7!+X~0;T)&&|1p^Cf!-^HW zx}Mxd59J+Ui4mN91)4Zj7#LWD{P9FKC^ZNWN)2EIvI4*yjFK}L1r-^9;h>P%2ur#4 z0#A-@no#;cbsroLy1E% zMC+@F+Q=UY I^8arF04o$@P5=M^ literal 0 HcmV?d00001 diff --git a/wagtail/wagtailimages/check_files/wagtail.png b/wagtail/wagtailimages/check_files/wagtail.png new file mode 100644 index 0000000000000000000000000000000000000000..0597e9d90a5d2b39e698b376c5a97652438c58ef GIT binary patch literal 849 zcmV-X1FrmuP)A*Nen5r+2ncIK-^AJXR=)%>}6(me&2iZ-poq? zdrbjw9>8?~_W?Wra1+4D?Ch);du(R`Yy%+Pv$3&JBchP?BbQC^834)VfuW%xV`5?g zs;bskR#uqb@81XD3lSXwu&F4DZJv)?y}6)2UQrNZS+d2L=Y}wOWlE_o^wZR4UQAGw~+?pog`N z$}J}%pkawC<5fMZksj9OJE?*gfTPyIVzCIuSj&&5@1$0j-@d83-EIJg>S1k0HUi&x zwayr$(a}-Tb)7_6a3IF8eWUIN52s|MJpPHJY-rio`obV}_7XiCmE*cvfBgPnS{;Mebt_a-Y z@lYa>X!nlRF3Vf({lQ)9GZH~hPY()(0@l~pd9RR}#2-alY_2C=U0vk!`6w6+QY;pu z?(Xh(UcZxRcr@N(ilUI;?DT=b&mKXpo%3e6n0DK4V6u<|;3YZ6QNv65{>ka|% zyJ`P;RtE6XY|B0YcmW`7_wT$$zh5>R&tpooa%=b^>U< z4R2ZUz)?G4DXT+H3s`P~XPk!jS-c-{TEJ(^QF_=(_yrSOGwc7olW>>$N5f?^3cmmp boD}c}Hy%TsNJV*~00000NkvXXu0mjfI?aE+ literal 0 HcmV?d00001 diff --git a/wagtail/wagtailimages/checks.py b/wagtail/wagtailimages/checks.py new file mode 100644 index 0000000000..c4aafcf220 --- /dev/null +++ b/wagtail/wagtailimages/checks.py @@ -0,0 +1,58 @@ +import os + +from django.core.checks import register, Warning + +from willow.image import Image + + +def has_jpeg_support(): + wagtail_jpg = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.jpg') + is_ok = True + f = open(wagtail_jpg, 'rb') + + try: + Image.open(f) + except (IOError, Image.LoaderError): + is_ok = False + finally: + f.close() + + return is_ok + + +def has_png_support(): + wagtail_png = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.png') + is_ok = True + f = open(wagtail_png, 'rb') + + try: + Image.open(f) + except (IOError, Image.LoaderError): + is_ok = False + finally: + f.close() + + return is_ok + + +@register() +def image_library_check(app_configs, **kwargs): + errors = [] + + if not has_jpeg_support(): + errors.append( + Warning( + 'JPEG image support is not available', + hint="Check that the 'libjpeg' library is installed, then reinstall Pillow." + ) + ) + + if not has_png_support(): + errors.append( + Warning( + 'PNG image support is not available', + hint="Check that the 'zlib' library is installed, then reinstall Pillow." + ) + ) + + return errors From 1a743366fb440b2f7316e9ba76a7312c0549f031 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Wed, 23 Sep 2015 02:29:18 +0100 Subject: [PATCH 2/4] Cache the results of has_jpeg_support and has_png_support This means we can use them on the admin dashboard without performing redundant file/image operations. --- wagtail/wagtailimages/checks.py | 54 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/wagtail/wagtailimages/checks.py b/wagtail/wagtailimages/checks.py index c4aafcf220..9c2235eb52 100644 --- a/wagtail/wagtailimages/checks.py +++ b/wagtail/wagtailimages/checks.py @@ -5,34 +5,48 @@ from django.core.checks import register, Warning from willow.image import Image +_has_jpeg_support = None +_has_png_support = None + + def has_jpeg_support(): - wagtail_jpg = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.jpg') - is_ok = True - f = open(wagtail_jpg, 'rb') + global _has_jpeg_support - try: - Image.open(f) - except (IOError, Image.LoaderError): - is_ok = False - finally: - f.close() + if _has_jpeg_support is None: + wagtail_jpg = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.jpg') + succeeded = True + f = open(wagtail_jpg, 'rb') - return is_ok + try: + Image.open(f) + except (IOError, Image.LoaderError): + succeeded = False + finally: + f.close() + + _has_jpeg_support = succeeded + + return _has_jpeg_support def has_png_support(): - wagtail_png = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.png') - is_ok = True - f = open(wagtail_png, 'rb') + global _has_png_support - try: - Image.open(f) - except (IOError, Image.LoaderError): - is_ok = False - finally: - f.close() + if _has_png_support is None: + wagtail_png = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.png') + succeeded = True + f = open(wagtail_png, 'rb') - return is_ok + try: + Image.open(f) + except (IOError, Image.LoaderError): + succeeded = False + finally: + f.close() + + _has_png_support = succeeded + + return _has_png_support @register() From 8a98b5ab8c3f8ff0d3b9c208002a2f8da6ce1953 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Wed, 23 Sep 2015 02:35:38 +0100 Subject: [PATCH 3/4] suppress PEP8 warning from unused import --- wagtail/wagtailimages/apps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagtail/wagtailimages/apps.py b/wagtail/wagtailimages/apps.py index 3b5a619006..6ef3ddb1e8 100644 --- a/wagtail/wagtailimages/apps.py +++ b/wagtail/wagtailimages/apps.py @@ -1,6 +1,6 @@ from django.apps import AppConfig -from . import checks +from . import checks # NOQA class WagtailImagesAppConfig(AppConfig): From 99b99f28d4345be8d7c28102ed4e5e7dca60d41c Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Wed, 23 Sep 2015 10:11:52 +0100 Subject: [PATCH 4/4] Use lru_cache and 'with open' to clean up code --- wagtail/wagtailimages/checks.py | 37 ++++++++++----------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/wagtail/wagtailimages/checks.py b/wagtail/wagtailimages/checks.py index 9c2235eb52..bf785682d0 100644 --- a/wagtail/wagtailimages/checks.py +++ b/wagtail/wagtailimages/checks.py @@ -1,52 +1,37 @@ import os from django.core.checks import register, Warning +from django.utils.lru_cache import lru_cache from willow.image import Image -_has_jpeg_support = None -_has_png_support = None - - +@lru_cache() def has_jpeg_support(): - global _has_jpeg_support - - if _has_jpeg_support is None: - wagtail_jpg = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.jpg') - succeeded = True - f = open(wagtail_jpg, 'rb') + wagtail_jpg = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.jpg') + succeeded = True + with open(wagtail_jpg, 'rb') as f: try: Image.open(f) except (IOError, Image.LoaderError): succeeded = False - finally: - f.close() - _has_jpeg_support = succeeded - - return _has_jpeg_support + return succeeded +@lru_cache() def has_png_support(): - global _has_png_support - - if _has_png_support is None: - wagtail_png = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.png') - succeeded = True - f = open(wagtail_png, 'rb') + wagtail_png = os.path.join(os.path.dirname(__file__), 'check_files', 'wagtail.png') + succeeded = True + with open(wagtail_png, 'rb') as f: try: Image.open(f) except (IOError, Image.LoaderError): succeeded = False - finally: - f.close() - _has_png_support = succeeded - - return _has_png_support + return succeeded @register()