Skip to content

Commit

Permalink
[FEAT] thumbor-doctor (#1284)
Browse files Browse the repository at this point in the history
**Is backwards compatible**: yes

Thumbor doctor is a console app that users can run to verify their
thumbor install. That way they can send it with their issues in order to
make it easier for contributors to investigate what's going on.

The idea is that we keep adding checks to thumbor doctor over time.
It can be refactored to make it easier to add a new check, but this will
do for now.
  • Loading branch information
heynemann committed Mar 25, 2020
1 parent a1d5994 commit 66a6e77
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 1 deletion.
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,16 @@ def run_setup(extension_modules=None):
'pytz==2019.*,>=2019.3.0',
'statsd==3.*,>=3.3.0',
'tornado==6.*,>=6.0.3',
'webcolors==1.*,>=1.10.0'
'webcolors==1.*,>=1.10.0',
'colorful==0.*,>=0.5.4',
],
extras_require={"tests": TESTS_REQUIREMENTS},
entry_points={
"console_scripts": [
"thumbor=thumbor.server:main",
"thumbor-url=thumbor.url_composer:main",
"thumbor-config=thumbor.config:generate_config",
"thumbor-doctor=thumbor.doctor:main",
],
},
ext_modules=extension_modules,
Expand Down
174 changes: 174 additions & 0 deletions thumbor/doctor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# thumbor imaging service
# https://github.com/thumbor/thumbor/wiki

# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license
# Copyright (c) 2011 globo.com thumbor@googlegroups.com

import argparse
import sys
from importlib import import_module
from shutil import which

import colorful as cf

from thumbor import __release_date__, __version__
from thumbor.ext import BUILTIN_EXTENSIONS
from thumbor.filters import BUILTIN_FILTERS


def get_options():
parser = argparse.ArgumentParser(description="thumbor doctor")

parser.add_argument(
"-n",
"--nocolor",
action="store_true",
help="Disables coloring of thumbor doctor",
)

options = parser.parse_args()

return {
"nocolor": options.nocolor,
}


def header(msg, color=cf.yellow):
print(color(msg))


def subheader(msg, color=cf.bold_coral):
print(color(msg))
newline()


def newline():
print()


def check_filters():
newline()
subheader('Verifying thumbor filters...')
errors = []

for filter_name in BUILTIN_FILTERS:
try:
import_module(filter_name)
print(cf.bold_green('✅ %s' % filter_name))
except ImportError as error:
print(cf.bold_red('❎ %s' % filter_name))
errors.append(error)

return errors


def check_compiled_extensions():
newline()
subheader('Verifying thumbor compiled extensions...')
errors = []

for extension in BUILTIN_EXTENSIONS:
ext_name = extension.replace('thumbor.ext.filters.', '')
try:
import_module(extension)
print(cf.bold_green('✅ %s' % ext_name))
except ImportError as error:
print(cf.bold_red('❎ %s' % ext_name))
errors.append(error)

return errors


def check_modules():
newline()
subheader('Verifying libraries support...')
errors = []

modules = (
('pycurl', 'Thumbor works much better with PyCurl. For more information visit http://pycurl.io/.'),
('cv2', 'Thumbor requires OpenCV for smart cropping. For more information check https://opencv.org/.'),
('pyexiv2', 'Thumbor uses exiv2 for reading image metadata. For more information check https://python3-exiv2.readthedocs.io/en/latest/.'),
('cairosvg', 'Thumbor uses CairoSVG for reading SVG files. For more information check https://cairosvg.org/.'),
)

for module, error_message in modules:
try:
import_module(module) # NOQA
print(cf.bold_green('✅ %s is installed correctly.' % module))
except ImportError as error:
print(cf.bold_red('❎ %s is not installed.' % module))
print(error_message)
newline()
errors.append('%s - %s' % (str(error), error_message))

return errors


def check_extensions():
newline()

subheader('Verifying extension programs...')
errors = []

programs = (
('jpegtran', 'Thumbor uses jpegtran for optimizing JPEG images. For more information visit https://linux.die.net/man/1/jpegtran.'),
('ffmpeg', 'Thumbor uses ffmpeg for rendering animated images as GIFV. For more information visit https://www.ffmpeg.org/.'),
('gifsicle', 'Thumbor uses gifsicle for better processing of GIF images. For more information visit https://www.lcdf.org/gifsicle/.'),
)

for program, error_message in programs:
path = which(program)
if path is None:
print(cf.bold_red('❎ %s is not installed.' % program))
print(error_message)
newline()
errors.append(error_message)
else:
print(cf.bold_green('✅ %s is installed correctly.' % program))

return errors


def main():
"""Converts a given url with the specified arguments."""

options = get_options()

cf.use_style('solarized')
if (options["nocolor"]):
cf.disable()

newline()
header('Thumbor v%s (of %s)' % (__version__, __release_date__))

newline()
print('Thumbor doctor will analyze your install and verify if everything is working as expected.')

errors = check_modules()
errors += check_compiled_extensions()
errors += check_filters()
errors += check_extensions()

newline()

if errors:
print(cf.bold_red('😞 Oh no! We found some things that could improve... 😞'))
newline()
print('\n'.join(['* %s' % str(err) for err in errors]))
newline()
newline()
print(cf.cyan("If you don't know how to fix them, please open an issue with thumbor."))
print(cf.cyan("Don't forget to copy this log and add it to the description of your issue."))
print("Open an issue at https://github.com/thumbor/thumbor/issues/new")
sys.exit(1)
return

print(cf.bold_green('🎉 Congratulations! No errors found! 🎉'))


if __name__ == "__main__":
main()
28 changes: 28 additions & 0 deletions thumbor/ext/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# thumbor imaging service
# https://github.com/thumbor/thumbor/wiki

# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license
# Copyright (c) 2011 globo.com thumbor@googlegroups.com

BUILTIN_EXTENSIONS = [
'thumbor.ext.filters._alpha',
'thumbor.ext.filters._bounding_box',
'thumbor.ext.filters._brightness',
'thumbor.ext.filters._colorize',
'thumbor.ext.filters._composite',
'thumbor.ext.filters._contrast',
'thumbor.ext.filters._convolution',
'thumbor.ext.filters._curve',
'thumbor.ext.filters._equalize',
'thumbor.ext.filters._fill',
'thumbor.ext.filters._nine_patch',
'thumbor.ext.filters._noise',
'thumbor.ext.filters._rgb',
'thumbor.ext.filters._round_corner',
'thumbor.ext.filters._saturation',
'thumbor.ext.filters._sharpen',
]

0 comments on commit 66a6e77

Please sign in to comment.