wger-project / docker

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

Images break the API #102

Open lsalgueiro opened 1 month ago

lsalgueiro commented 1 month 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 1 month 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 month 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 month 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).

lsalgueiro commented 1 month ago

Weird; I had replied to this issue via the email notification, but it somehow did not land. Excuse my lack of documentation (I can back it up later, if necessary), but I got the exact same error deploying it on my M1 MacBook Pro.

rolandgeider commented 1 month ago

I finally managed to reproduce this. Interestingly neither on my raspberry nor on my macbook air could I see this, only on the intel laptop did I get the error. In any case I know what's causing it, I've added a workaround in https://github.com/wger-project/wger/commit/35b0a0fc24aa4e849c0bb76900eb024784e8c1ab so stuff should at least work now