wger-project / docker

Production...ish docker-compose image for wger
GNU Affero General Public License v3.0
125 stars 43 forks source link

Images break the API #102

Open lsalgueiro opened 2 days ago

lsalgueiro commented 2 days ago

I'm giving this self-hosting this a whirl. I had some problems with my installation, and so I retraced everything back from a fresh installation to try and pinpoint this, and it seems that downloading the images (with docker compose exec web python3 manage.py download-exercise-images) functionally breaks the API: PIL throws an exception, which throws a wrench on the whole gear:

nginx-1          | 192.168.1.70 - - [04/Oct/2024:15:52:23 +0000] "GET /api/v2/exercise/search/?language=en,en&term=ches HTTP/1.1" 499 0 "http://192.168.1.20:8080/en/routine/set/1/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:130.0) Gecko/20100101 Firefox/130.0" "-"
web-1            | ERROR 2024-10-04 16:52:24,398 log Internal Server Error: /api/v2/exercise/search/
web-1            | Traceback (most recent call last):
web-1            |   File "/usr/local/lib/python3.10/dist-packages/PIL/JpegImagePlugin.py", line 639, in _save
web-1            |     rawmode = RAWMODE[im.mode]
web-1            | KeyError: 'P'
web-1            |
web-1            | The above exception was the direct cause of the following exception:
web-1            |
web-1            | Traceback (most recent call last):
web-1            |   File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/exception.py", line 55, in inner
web-1            |     response = get_response(request)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/base.py", line 197, in _get_response
web-1            |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
web-1            |     return view_func(*args, **kwargs)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/django/views/generic/base.py", line 104, in view
web-1            |     return self.dispatch(request, *args, **kwargs)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/views.py", line 509, in dispatch
web-1            |     response = self.handle_exception(exc)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/views.py", line 469, in handle_exception
web-1            |     self.raise_uncaught_exception(exc)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
web-1            |     raise exc
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/views.py", line 506, in dispatch
web-1            |     response = handler(request, *args, **kwargs)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/decorators.py", line 50, in handler
web-1            |     return func(*args, **kwargs)
web-1            |   File "/home/wger/src/wger/exercises/api/views.py", line 378, in search
web-1            |     thumbnail = t.get_thumbnail(aliases.get('micro_cropped')).url
web-1            |   File "/usr/local/lib/python3.10/dist-packages/easy_thumbnails/files.py", line 513, in get_thumbnail
web-1            |     thumbnail = self.generate_thumbnail(
web-1            |   File "/usr/local/lib/python3.10/dist-packages/easy_thumbnails/files.py", line 401, in generate_thumbnail
web-1            |     img = engine.save_pil_image(
web-1            |   File "/usr/local/lib/python3.10/dist-packages/easy_thumbnails/engine.py", line 77, in save_pil_image
web-1            |     image.save(destination, format=format, **options)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/PIL/Image.py", line 2568, in save
web-1            |     save_handler(self, fp, filename)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/PIL/JpegImagePlugin.py", line 642, in _save
web-1            |     raise OSError(msg) from e
web-1            | OSError: cannot write mode P as JPEG
web-1            | ERROR 2024-10-04 16:52:26,808 log Internal Server Error: /api/v2/exercise/search/
web-1            | Traceback (most recent call last):
web-1            |   File "/usr/local/lib/python3.10/dist-packages/PIL/JpegImagePlugin.py", line 639, in _save
web-1            |     rawmode = RAWMODE[im.mode]
web-1            | KeyError: 'P'
web-1            |
web-1            | The above exception was the direct cause of the following exception:
web-1            |
web-1            | Traceback (most recent call last):
web-1            |   File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/exception.py", line 55, in inner
web-1            |     response = get_response(request)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/base.py", line 197, in _get_response
web-1            |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
web-1            |     return view_func(*args, **kwargs)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/django/views/generic/base.py", line 104, in view
web-1            |     return self.dispatch(request, *args, **kwargs)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/views.py", line 509, in dispatch
web-1            |     response = self.handle_exception(exc)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/views.py", line 469, in handle_exception
web-1            |     self.raise_uncaught_exception(exc)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
web-1            |     raise exc
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/views.py", line 506, in dispatch
web-1            |     response = handler(request, *args, **kwargs)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/rest_framework/decorators.py", line 50, in handler
web-1            |     return func(*args, **kwargs)
web-1            |   File "/home/wger/src/wger/exercises/api/views.py", line 378, in search
web-1            |     thumbnail = t.get_thumbnail(aliases.get('micro_cropped')).url
web-1            |   File "/usr/local/lib/python3.10/dist-packages/easy_thumbnails/files.py", line 513, in get_thumbnail
web-1            |     thumbnail = self.generate_thumbnail(
web-1            |   File "/usr/local/lib/python3.10/dist-packages/easy_thumbnails/files.py", line 401, in generate_thumbnail
web-1            |     img = engine.save_pil_image(
web-1            |   File "/usr/local/lib/python3.10/dist-packages/easy_thumbnails/engine.py", line 77, in save_pil_image
web-1            |     image.save(destination, format=format, **options)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/PIL/Image.py", line 2568, in save
web-1            |     save_handler(self, fp, filename)
web-1            |   File "/usr/local/lib/python3.10/dist-packages/PIL/JpegImagePlugin.py", line 642, in _save
web-1            |     raise OSError(msg) from e
web-1            | OSError: cannot write mode P as JPEG

Thanks in advance for the attention!

rolandgeider commented 2 days ago

hi! never seen this error before, and a quick google says this is probably due to the color space of the image, mhh. Are you perhaps using this on an arm/v7 (I think the raspi 3 had one of those, but I'm not 100% sure)? I ask because I had some reports of the docker image for that arch having some problems but I could never test that

lsalgueiro commented 1 day ago

Hi, thanks for getting back and sorry that this turned out to be lateral to the codebase!

No, I'm on x86_64. It's running on an Ubuntu VM, virtualized on Proxmox, running the host's instruction set.

rolandgeider commented 1 day ago

Did you add some exercises yourself with some images? Otherwise this doesn't make much sense, I just started a fresh docker install, pulled all exercises and images and didn't get any errors (plus this should also happen on the "official" server, which uses the exact same docker setup).