prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Сломался check_PR экшн на новые пуллреквесты
  Вот здесь все пошло не так после пары изменений в requirements и докерфайлах: https://github.com/vas3k/vas3k.club/blob/master/.github/workflows/CI.yml
  
  Из-за этого все новые пуллреквесты красненькие и мержить их приходится только суровой админской рукой. Надо бы переосмыслить этот CI как-нибудь. У кого есть идеи?
  
  По сути мне важны линтеры и чтобы докер с новым кодом успешно поднимался. Остального пока нет.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `utils/images.py`
  Content:
  ```
  1 import io
  2 import logging
  3 import os
  4 from urllib.parse import urlparse
  5 
  6 import requests
  7 from PIL import Image
  8 from django.conf import settings
  9 
  10 log = logging.getLogger(__name__)
  11 
  12 
  13 def upload_image_bytes(
  14     filename, data, resize=(192, 192), convert_to=None, quality=None
  15 ):
  16     if not data:
  17         return None
  18 
  19     if resize:
  20         try:
  21             image = Image.open(data)
  22         except Exception as ex:
  23             log.warning(f"Bad image data: {ex}")
  24             return None
  25 
  26         image.thumbnail(resize)
  27         saved_image = io.BytesIO()
  28         saved_image.name = filename
  29 
  30         try:
  31             image.save(saved_image)
  32         except OSError:
  33             log.warning(f"Error saving image data: {ex}")
  34             return None
  35 
  36         data = saved_image.getvalue()
  37 
  38     upload_params = {
  39         "code": settings.MEDIA_UPLOAD_CODE
  40     }
  41 
  42     if convert_to:
  43         upload_params["convert_to"] = convert_to
  44 
  45     if quality:
  46         upload_params["quality"] = quality
  47 
  48     try:
  49         uploaded = requests.post(
  50             url=settings.MEDIA_UPLOAD_URL,
  51             params=upload_params,
  52             files={"media": (filename, data)},
  53         )
  54     except requests.exceptions.RequestException as ex:
  55         log.error(f"Image upload error: {ex}")
  56         return None
  57 
  58     if 200 <= uploaded.status_code <= 299:
  59         try:
  60             response_data = uploaded.json()
  61         except Exception as ex:
  62             log.error(f"Image upload error: {ex} ({uploaded.content})")
  63             return None
  64 
  65         return response_data["uploaded"][0]
  66 
  67     return None
  68 
  69 
  70 def upload_image_from_url(url, resize=(192, 192), convert_to="jpg", quality=90):
  71     if settings.DEBUG or not settings.MEDIA_UPLOAD_URL or not settings.MEDIA_UPLOAD_CODE:
  72         return url
  73 
  74     if not url:
  75         return None
  76 
  77     image_name = os.path.basename(urlparse(url).path)
  78     if "." not in image_name:
  79         image_name += ".jpg"
  80 
  81     try:
  82         image_data = io.BytesIO(requests.get(url).content)
  83     except requests.exceptions.RequestException:
  84         return None
  85 
  86     return upload_image_bytes(image_name, image_data, resize=resize, convert_to=convert_to, quality=quality)
  87
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/utils/images.py b/utils/images.py
  --- a/utils/images.py
  +++ b/utils/images.py
  @@ -29,7 +29,7 @@
   
           try:
               image.save(saved_image)
  -        except OSError:
  +        except OSError as ex:
               log.warning(f"Error saving image data: {ex}")
               return None
  
verification_info: {"golden_diff": "diff --git a/utils/images.py b/utils/images.py\n--- a/utils/images.py\n+++ b/utils/images.py\n@@ -29,7 +29,7 @@\n \n         try:\n             image.save(saved_image)\n-        except OSError:\n+        except OSError as ex:\n             log.warning(f\"Error saving image data: {ex}\")\n             return None\n", "issue": "\u0421\u043b\u043e\u043c\u0430\u043b\u0441\u044f check_PR \u044d\u043a\u0448\u043d \u043d\u0430 \u043d\u043e\u0432\u044b\u0435 \u043f\u0443\u043b\u043b\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u044b\n\u0412\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u0432\u0441\u0435 \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a \u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0440\u044b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 requirements \u0438 \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b\u0430\u0445: https://github.com/vas3k/vas3k.club/blob/master/.github/workflows/CI.yml\r\n\r\n\u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0443\u043b\u043b\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u044b \u043a\u0440\u0430\u0441\u043d\u0435\u043d\u044c\u043a\u0438\u0435 \u0438 \u043c\u0435\u0440\u0436\u0438\u0442\u044c \u0438\u0445 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0443\u0440\u043e\u0432\u043e\u0439 \u0430\u0434\u043c\u0438\u043d\u0441\u043a\u043e\u0439 \u0440\u0443\u043a\u043e\u0439. \u041d\u0430\u0434\u043e \u0431\u044b \u043f\u0435\u0440\u0435\u043e\u0441\u043c\u044b\u0441\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 CI \u043a\u0430\u043a-\u043d\u0438\u0431\u0443\u0434\u044c. \u0423 \u043a\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u0438?\r\n\r\n\u041f\u043e \u0441\u0443\u0442\u0438 \u043c\u043d\u0435 \u0432\u0430\u0436\u043d\u044b \u043b\u0438\u043d\u0442\u0435\u0440\u044b \u0438 \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u043a\u0435\u0440 \u0441 \u043d\u043e\u0432\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u043b\u0441\u044f. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043a\u0430 \u043d\u0435\u0442.\n", "before_files": [{"content": "import io\nimport logging\nimport os\nfrom urllib.parse import urlparse\n\nimport requests\nfrom PIL import Image\nfrom django.conf import settings\n\nlog = logging.getLogger(__name__)\n\n\ndef upload_image_bytes(\n    filename, data, resize=(192, 192), convert_to=None, quality=None\n):\n    if not data:\n        return None\n\n    if resize:\n        try:\n            image = Image.open(data)\n        except Exception as ex:\n            log.warning(f\"Bad image data: {ex}\")\n            return None\n\n        image.thumbnail(resize)\n        saved_image = io.BytesIO()\n        saved_image.name = filename\n\n        try:\n            image.save(saved_image)\n        except OSError:\n            log.warning(f\"Error saving image data: {ex}\")\n            return None\n\n        data = saved_image.getvalue()\n\n    upload_params = {\n        \"code\": settings.MEDIA_UPLOAD_CODE\n    }\n\n    if convert_to:\n        upload_params[\"convert_to\"] = convert_to\n\n    if quality:\n        upload_params[\"quality\"] = quality\n\n    try:\n        uploaded = requests.post(\n            url=settings.MEDIA_UPLOAD_URL,\n            params=upload_params,\n            files={\"media\": (filename, data)},\n        )\n    except requests.exceptions.RequestException as ex:\n        log.error(f\"Image upload error: {ex}\")\n        return None\n\n    if 200 <= uploaded.status_code <= 299:\n        try:\n            response_data = uploaded.json()\n        except Exception as ex:\n            log.error(f\"Image upload error: {ex} ({uploaded.content})\")\n            return None\n\n        return response_data[\"uploaded\"][0]\n\n    return None\n\n\ndef upload_image_from_url(url, resize=(192, 192), convert_to=\"jpg\", quality=90):\n    if settings.DEBUG or not settings.MEDIA_UPLOAD_URL or not settings.MEDIA_UPLOAD_CODE:\n        return url\n\n    if not url:\n        return None\n\n    image_name = os.path.basename(urlparse(url).path)\n    if \".\" not in image_name:\n        image_name += \".jpg\"\n\n    try:\n        image_data = io.BytesIO(requests.get(url).content)\n    except requests.exceptions.RequestException:\n        return None\n\n    return upload_image_bytes(image_name, image_data, resize=resize, convert_to=convert_to, quality=quality)\n", "path": "utils/images.py"}], "after_files": [{"content": "import io\nimport logging\nimport os\nfrom urllib.parse import urlparse\n\nimport requests\nfrom PIL import Image\nfrom django.conf import settings\n\nlog = logging.getLogger(__name__)\n\n\ndef upload_image_bytes(\n    filename, data, resize=(192, 192), convert_to=None, quality=None\n):\n    if not data:\n        return None\n\n    if resize:\n        try:\n            image = Image.open(data)\n        except Exception as ex:\n            log.warning(f\"Bad image data: {ex}\")\n            return None\n\n        image.thumbnail(resize)\n        saved_image = io.BytesIO()\n        saved_image.name = filename\n\n        try:\n            image.save(saved_image)\n        except OSError as ex:\n            log.warning(f\"Error saving image data: {ex}\")\n            return None\n\n        data = saved_image.getvalue()\n\n    upload_params = {\n        \"code\": settings.MEDIA_UPLOAD_CODE\n    }\n\n    if convert_to:\n        upload_params[\"convert_to\"] = convert_to\n\n    if quality:\n        upload_params[\"quality\"] = quality\n\n    try:\n        uploaded = requests.post(\n            url=settings.MEDIA_UPLOAD_URL,\n            params=upload_params,\n            files={\"media\": (filename, data)},\n        )\n    except requests.exceptions.RequestException as ex:\n        log.error(f\"Image upload error: {ex}\")\n        return None\n\n    if 200 <= uploaded.status_code <= 299:\n        try:\n            response_data = uploaded.json()\n        except Exception as ex:\n            log.error(f\"Image upload error: {ex} ({uploaded.content})\")\n            return None\n\n        return response_data[\"uploaded\"][0]\n\n    return None\n\n\ndef upload_image_from_url(url, resize=(192, 192), convert_to=\"jpg\", quality=90):\n    if settings.DEBUG or not settings.MEDIA_UPLOAD_URL or not settings.MEDIA_UPLOAD_CODE:\n        return url\n\n    if not url:\n        return None\n\n    image_name = os.path.basename(urlparse(url).path)\n    if \".\" not in image_name:\n        image_name += \".jpg\"\n\n    try:\n        image_data = io.BytesIO(requests.get(url).content)\n    except requests.exceptions.RequestException:\n        return None\n\n    return upload_image_bytes(image_name, image_data, resize=resize, convert_to=convert_to, quality=quality)\n", "path": "utils/images.py"}]}