From 1047f4acdbbcb7669fd13ebcc0e54f6fb32de44c Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 17:25:19 +0100 Subject: [PATCH 01/12] Fix PermissionError during file copy in updater Files that require special permissions, such as those in ".github" or "tests/" directories, are usually not necessary for the update. --- updater.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/updater.py b/updater.py index 30b9186..f259f56 100644 --- a/updater.py +++ b/updater.py @@ -121,7 +121,11 @@ def update_to_latest_release(tag_name): yaml.dump(existing_config, merged_file) else: # Overwrite other files - shutil.copy2(extracted_path, dest_path) + try: + shutil.copy2(extracted_path, dest_path) + except PermissionError: + print(f"Permission denied: {dest_path}. Skipping file.") + pass else: shutil.copy2(extracted_path, dest_path) From ed5440922f183d304dcad68a4bf7c82ecd4e03d3 Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 18:18:27 +0100 Subject: [PATCH 02/12] Add dynamic resizing for game icons - Integrated `resize_image` function to dynamically resize game icons based on request parameters. - Updated `get_game_icon` function to use the resized image path. - Modified the `get_nx` endpoint to handle width and height parameters for icon requests. - Updated readme --- README.md | 4 ++-- main.py | 19 +++++++++++++++++-- utils/resize_image.py | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 utils/resize_image.py diff --git a/README.md b/README.md index 2752451..f651bab 100644 --- a/README.md +++ b/README.md @@ -175,8 +175,8 @@ Returns the full games database JSON. This is NOT RECOMMENDED due to the large s ### Game Assets -#### `GET api.nlib.cc/nx/[tid]/icon` -Returns the game icon (1024x1024 JPEG). +#### `GET api.nlib.cc/nx/[tid]/icon/[width]/[height]` +Returns the game icon. If `width` and `height` are not specified, the default size of 1024x1024 JPEG is returned. #### `GET api.nlib.cc/nx/[tid]/banner` Returns the game banner (1980x1080 JPEG). diff --git a/main.py b/main.py index e277358..06708e4 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,7 @@ from starlette.middleware.base import BaseHTTPMiddleware from time import time from collections import defaultdict +from utils.resize_image import resize_image import updater # Change directory to the main.py dir @@ -167,6 +168,7 @@ def get_game_icon(tid, size: tuple = (1024, 1024)): return icon_cache[cache_key] icon_path = os.path.join(config['database-path'], 'media', f'{tid}', 'icon.jpg') + icon_path = resize_image(icon_path, *size) if os.path.exists(icon_path): with open(icon_path, 'rb') as file: icon = file.read() @@ -248,7 +250,9 @@ def format_json_dates(data: dict) -> dict: @app.get('/{platform}/{tid}/{asset_type}/') @app.get('/{platform}/{tid}/{asset_type}/{screen_id}') @app.get('/{platform}/{tid}/{asset_type}/{screen_id}/') -async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id = 1): +@app.get('/{platform}/{tid}/{asset_type}/{screen_id}/{media_height}') +@app.get('/{platform}/{tid}/{asset_type}/{screen_id}/{media_height}/') +async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id: int = 1, media_height=None): if platform.lower() not in ['nx', 'switch']: raise HTTPException(status_code=404, detail=f"Platform {platform} not supported") @@ -299,7 +303,18 @@ async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id = 1) # nx/0100A0D004FB0000/icon if asset_type == 'icon': # Handle icon request - content = get_game_icon(tid, size=(1024, 1024)) + width = screen_id + height = media_height + if height: + height = int(height) + + if width != 1 and not height: + height = width + if width == 1 and height: + height = 1 + if width != height: + width, height = 1024, 1024 + content = get_game_icon(tid, size=(width, height)) if content: return Response(content=content, media_type="image/jpeg") else: diff --git a/utils/resize_image.py b/utils/resize_image.py new file mode 100644 index 0000000..5d530b6 --- /dev/null +++ b/utils/resize_image.py @@ -0,0 +1,38 @@ +from PIL import Image +import os + + +def resize_image(file_path: str, width: int, height: int) -> str: + allowed_sizes = [8 * (2 ** i) for i in range(8)] # [8, 16, 32, 64, 128, 256, 512, 1024] + + def nearest_size(size): + return min(allowed_sizes, key=lambda x: abs(x - size)) + + width = nearest_size(width) + height = nearest_size(height) + + base, ext = os.path.splitext(file_path) + new_file_path = f"{base}_{width}x{height}{ext}" + + # Default icon size + if width == 1024 and height == 1024: + return file_path + + if os.path.exists(new_file_path): + return new_file_path + + if not os.path.exists(file_path): + return None + + with Image.open(file_path) as img: + resized_img = img.resize((width, height)) + resized_img.save(new_file_path) + + return new_file_path + + +# Testing +if __name__ == '__main__': + file_path = '/data/NX-DB/media/01002AA01C7C2000/icon.jpg' + new_file_path = resize_image(file_path, 100, 100) + print(f"Resized image saved to: {new_file_path}") \ No newline at end of file From aa11a0bc608e658356873d89df2f9db119512286 Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 18:41:16 +0100 Subject: [PATCH 03/12] Ensure headers include width, height, and filename for resized icons - Moved `nearest_size` function utilization to ensure width and height are valid sizes before resizing. - Added headers to the response for icon requests to include content type, width, height, and filename. - Updated imports to include `nearest_size` in `main.py`. --- main.py | 17 +++++++++++++++-- utils/resize_image.py | 12 ++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/main.py b/main.py index 06708e4..f37ba31 100644 --- a/main.py +++ b/main.py @@ -8,7 +8,7 @@ from starlette.middleware.base import BaseHTTPMiddleware from time import time from collections import defaultdict -from utils.resize_image import resize_image +from utils.resize_image import resize_image, nearest_size import updater # Change directory to the main.py dir @@ -308,15 +308,28 @@ async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id: int if height: height = int(height) + # Determine the height if not provided if width != 1 and not height: height = width if width == 1 and height: height = 1 if width != height: width, height = 1024, 1024 + + # Ensure width and height are nearest valid sizes + width = nearest_size(width) + height = nearest_size(height) + content = get_game_icon(tid, size=(width, height)) + if content: - return Response(content=content, media_type="image/jpeg") + headers = { + "Content-Type": "image/jpeg", + "Content-Width": str(width), + "Content-Height": str(height), + "Content-Disposition": f'inline; filename="icon_{width}x{height}.jpg"' + } + return Response(content=content, headers=headers) else: raise HTTPException(status_code=404, detail=f"Icon for {tid} not found") diff --git a/utils/resize_image.py b/utils/resize_image.py index 5d530b6..39d9e32 100644 --- a/utils/resize_image.py +++ b/utils/resize_image.py @@ -2,15 +2,11 @@ import os -def resize_image(file_path: str, width: int, height: int) -> str: +def nearest_size(size): allowed_sizes = [8 * (2 ** i) for i in range(8)] # [8, 16, 32, 64, 128, 256, 512, 1024] - - def nearest_size(size): - return min(allowed_sizes, key=lambda x: abs(x - size)) - - width = nearest_size(width) - height = nearest_size(height) - + return min(allowed_sizes, key=lambda x: abs(x - size)) + +def resize_image(file_path: str, width: int, height: int) -> str: base, ext = os.path.splitext(file_path) new_file_path = f"{base}_{width}x{height}{ext}" From 60ce7f8c29ecdc1480a44e49b50ec6b881214976 Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 18:47:58 +0100 Subject: [PATCH 04/12] Ensure icon width and height are integers Raised HTTP 422 error if width or height are not valid integers. --- main.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index f37ba31..d98689d 100644 --- a/main.py +++ b/main.py @@ -252,7 +252,7 @@ def format_json_dates(data: dict) -> dict: @app.get('/{platform}/{tid}/{asset_type}/{screen_id}/') @app.get('/{platform}/{tid}/{asset_type}/{screen_id}/{media_height}') @app.get('/{platform}/{tid}/{asset_type}/{screen_id}/{media_height}/') -async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id: int = 1, media_height=None): +async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id=1, media_height=None): if platform.lower() not in ['nx', 'switch']: raise HTTPException(status_code=404, detail=f"Platform {platform} not supported") @@ -303,10 +303,16 @@ async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id: int # nx/0100A0D004FB0000/icon if asset_type == 'icon': # Handle icon request - width = screen_id + try: + width = int(screen_id) + except ValueError: + raise HTTPException(status_code=422, detail="Width must be an integer") height = media_height if height: - height = int(height) + try: + height = int(height) + except ValueError: + raise HTTPException(status_code=422, detail="Height must be an integer") # Determine the height if not provided if width != 1 and not height: From 2ae49d778a917afb6f05e414fd07fcc37b818c51 Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 18:48:42 +0100 Subject: [PATCH 05/12] Add tests for custom icon dimensions and invalid sizes --- tests/test_main.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/tests/test_main.py b/tests/test_main.py index 573f677..077b8c2 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -31,6 +31,7 @@ def test_get_switch_without_asset_type(): assert response.status_code == 200 assert response.json().get("console") == "nx" + def test_get_nx_icon(): response = client.get(f"/nx/{GAME_ID}/icon") if response.status_code == 200: @@ -38,6 +39,59 @@ def test_get_nx_icon(): else: assert response.status_code == 404 +def test_get_nx_icon_custom_size(): + response = client.get(f"/nx/{GAME_ID}/icon/512") + if response.status_code == 200: + assert response.headers['content-type'] == 'image/jpeg' + assert response.headers['content-width'] == '512' + else: + assert response.status_code == 404 + +def test_get_nx_icon_custom_width_height(): + response = client.get(f"/nx/{GAME_ID}/icon/512/512") + if response.status_code == 200: + assert response.headers['content-type'] == 'image/jpeg' + assert response.headers['content-width'] == '512' + assert response.headers['content-height'] == '512' + else: + assert response.status_code == 404 + +def test_get_nx_icon_custom_dimension_512_500(): + response = client.get(f"/nx/{GAME_ID}/icon/512/500") + if response.status_code == 200: + assert response.headers['content-type'] == 'image/jpeg' + assert response.headers['content-width'] == '1024' + assert response.headers['content-height'] == '1024' + else: + assert response.status_code == 404 + +def test_get_nx_icon_custom_dimension_1(): + response = client.get(f"/nx/{GAME_ID}/icon/1") + if response.status_code == 200: + assert response.headers['content-type'] == 'image/jpeg' + assert response.headers['content-width'] == '1024' + assert response.headers['content-height'] == '1024' + else: + assert response.status_code == 404 + +def test_get_nx_icon_custom_dimension_1_1(): + response = client.get(f"/nx/{GAME_ID}/icon/1/1") + if response.status_code == 200: + assert response.headers['content-type'] == 'image/jpeg' + assert response.headers['content-width'] == '8' + assert response.headers['content-height'] == '8' + else: + assert response.status_code == 404 + +def test_get_nx_icon_invalid_size(): + response = client.get(f"/nx/{GAME_ID}/icon/invalid") + assert response.status_code == 422 + +def test_get_nx_icon_invalid_width_height(): + response = client.get(f"/nx/{GAME_ID}/icon/512/invalid") + assert response.status_code == 422 + + def test_get_nx_banner(): response = client.get(f"/nx/{GAME_ID}/banner") if response.status_code == 200: @@ -45,6 +99,7 @@ def test_get_nx_banner(): else: assert response.status_code == 404 + def test_get_nx_screen(): response = client.get(f"/nx/{GAME_ID}/screen") if response.status_code == 200: @@ -65,6 +120,7 @@ def test_get_nx_screens(): assert "count" in response.json() assert "screenshots" in response.json() + def test_get_nx_full(): response = client.get("/nx/full") assert response.status_code == 200 @@ -75,6 +131,7 @@ def test_get_nx_all(): response = client.get("/nx/all") assert response.status_code == 200 + def test_get_nx_base(): response = client.get(f"/nx/BASE/{GAME_ID}") assert response.status_code == 200 From 429888be94b00904202e08728374b83f6e8113b5 Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 21:02:05 +0100 Subject: [PATCH 06/12] Add dynamic resizing for game banners - Added support for custom banner dimensions in the `/banner` endpoint. - Updated `resize_image` function to handle default banner sizes and maintain aspect ratio. - Modified `get_game_banner` to use the resized image path. - Updated README to reflect changes in banner endpoint usage. --- README.md | 4 ++-- main.py | 41 ++++++++++++++++++++++++++++++++++++++--- utils/resize_image.py | 11 +++++++++-- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f651bab..97ad27f 100644 --- a/README.md +++ b/README.md @@ -178,8 +178,8 @@ Returns the full games database JSON. This is NOT RECOMMENDED due to the large s #### `GET api.nlib.cc/nx/[tid]/icon/[width]/[height]` Returns the game icon. If `width` and `height` are not specified, the default size of 1024x1024 JPEG is returned. -#### `GET api.nlib.cc/nx/[tid]/banner` -Returns the game banner (1980x1080 JPEG). +#### `GET api.nlib.cc/nx/[tid]/banner/[width]/[height]` +Returns the game banner. Supported sizes are 1920x1080 and 1280x720. You can also use `/banner/720p` or `/banner/1080p`. If neither `width` nor `height` is specified, the default size of 1920x1080 JPEG is returned. #### `GET api.nlib.cc/nx/[tid]/screen/[screen_id]` Returns a specific screenshot of the game (JPEG). If `screen_id` is not specified, the first screenshot is returned by default. diff --git a/main.py b/main.py index d98689d..9b400f3 100644 --- a/main.py +++ b/main.py @@ -185,7 +185,7 @@ def get_game_icon(tid, size: tuple = (1024, 1024)): # Custom cache for game banners banner_cache = {} banner_cache_max_size = 128 -def get_game_banner(tid, size: tuple = (1980, 1080)): +def get_game_banner(tid, size: tuple = (1920, 1080)): cache_key = f"{tid}_{size}" # Check if result is in cache @@ -193,6 +193,7 @@ def get_game_banner(tid, size: tuple = (1980, 1080)): return banner_cache[cache_key] banner_path = os.path.join(config['database-path'], 'media', f'{tid}', 'banner.jpg') + banner_path = resize_image(banner_path, *size) if os.path.exists(banner_path): with open(banner_path, 'rb') as file: banner = file.read() @@ -342,9 +343,43 @@ async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id=1, m # nx/0100A0D004FB0000/banner if asset_type == 'banner': # Handle banner request - content = get_game_banner(tid, size=(1980, 1080)) + try: + if screen_id in ["720p", "1080p"]: + width = {"720p": 1280, "1080p": 1920}[screen_id] + height = {"720p": 720, "1080p": 1080}[screen_id] + else: + width = int(screen_id) + height = media_height + except ValueError: + raise HTTPException(status_code=422, detail="Width must be an integer or one of '480p', '720p', '1080p'") + + print(width, height) + if not height: + height = 1080 # Default height for banners + else: + try: + height = int(height) + except ValueError: + raise HTTPException(status_code=422, detail="Height must be an integer") + + # Ensure both width and height are provided + if width == 1: + width = 1920 # Default width for banners + + print(width, height) + if width / height == 16 / 9: + content = get_game_banner(tid, size=(width, height)) + else: + raise HTTPException(status_code=422, detail="Width and height must maintain a 16:9 aspect ratio") + if content: - return Response(content=content, media_type="image/jpeg") + headers = { + "Content-Type": "image/jpeg", + "Content-Width": str(width), + "Content-Height": str(height), + "Content-Disposition": f'inline; filename="banner_{width}x{height}.jpg"' + } + return Response(content=content, headers=headers) else: raise HTTPException(status_code=404, detail=f"Banner for {tid} not found") diff --git a/utils/resize_image.py b/utils/resize_image.py index 39d9e32..0e68d89 100644 --- a/utils/resize_image.py +++ b/utils/resize_image.py @@ -14,6 +14,10 @@ def resize_image(file_path: str, width: int, height: int) -> str: if width == 1024 and height == 1024: return file_path + # Default banner size + if width == 1920 and height == 1080: + return file_path + if os.path.exists(new_file_path): return new_file_path @@ -21,8 +25,11 @@ def resize_image(file_path: str, width: int, height: int) -> str: return None with Image.open(file_path) as img: - resized_img = img.resize((width, height)) - resized_img.save(new_file_path) + aspect_ratio = width / height + if (width == height and width == nearest_size(width)) or \ + (aspect_ratio == 16/9 and height in [720, 1080]): + resized_img = img.resize((width, height)) + resized_img.save(new_file_path) return new_file_path From 4bd1d0dd17c7fa1a5a21c0ee80d277b922a0c9b0 Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 21:14:16 +0100 Subject: [PATCH 07/12] Fix banner endpoint errors - Corrected the error message for invalid width values in the banner endpoint. - Removed debug print statements. - Added a check to raise an HTTP 422 error if the resolution is not accepted instead of 'banner not found'. --- main.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index 9b400f3..0670124 100644 --- a/main.py +++ b/main.py @@ -351,9 +351,8 @@ async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id=1, m width = int(screen_id) height = media_height except ValueError: - raise HTTPException(status_code=422, detail="Width must be an integer or one of '480p', '720p', '1080p'") + raise HTTPException(status_code=422, detail="Width must be an integer or one of '720p' or '1080p'") - print(width, height) if not height: height = 1080 # Default height for banners else: @@ -366,7 +365,6 @@ async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id=1, m if width == 1: width = 1920 # Default width for banners - print(width, height) if width / height == 16 / 9: content = get_game_banner(tid, size=(width, height)) else: @@ -381,7 +379,10 @@ async def get_nx(platform: str, tid: str, asset_type: str = None, screen_id=1, m } return Response(content=content, headers=headers) else: - raise HTTPException(status_code=404, detail=f"Banner for {tid} not found") + if width != 1920 or height != 1080: + raise HTTPException(status_code=422, detail="Resolution not accepted.") + else: + raise HTTPException(status_code=404, detail=f"Banner for {tid} not found") # nx/0100A0D004FB0000/screen # nx/0100A0D004FB0000/screen/4 From 9697cc71a7ea4336393d0eeb703d4181d95a5a8c Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 21:14:51 +0100 Subject: [PATCH 08/12] Add tests for custom banner dimensions and invalid sizes --- tests/test_main.py | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/test_main.py b/tests/test_main.py index 077b8c2..b4a03c3 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -99,6 +99,53 @@ def test_get_nx_banner(): else: assert response.status_code == 404 +def test_get_nx_banner_custom_size(): + response = client.get(f"/nx/{GAME_ID}/banner/1280/720") + if response.status_code == 200: + assert response.headers['content-type'] == 'image/jpeg' + assert response.headers['content-width'] == '1280' + assert response.headers['content-height'] == '720' + else: + assert response.status_code == 404 + +def test_get_nx_banner_720p(): + response = client.get(f"/nx/{GAME_ID}/banner/720p") + if response.status_code == 200: + assert response.headers['content-type'] == 'image/jpeg' + assert response.headers['content-width'] == '1280' + assert response.headers['content-height'] == '720' + else: + assert response.status_code == 404 + +def test_get_nx_banner_1080p(): + response = client.get(f"/nx/{GAME_ID}/banner/1080p") + if response.status_code == 200: + assert response.headers['content-type'] == 'image/jpeg' + assert response.headers['content-width'] == '1920' + assert response.headers['content-height'] == '1080' + else: + assert response.status_code == 404 + +def test_get_nx_banner_480p(): + response = client.get(f"/nx/{GAME_ID}/banner/480p") + assert response.status_code == 422 + +def test_get_nx_banner_invalid_resolution(): + response = client.get(f"/nx/{GAME_ID}/banner/16/9") + assert response.status_code == 422 + +def test_get_nx_banner_invalid_ratio(): + response = client.get(f"/nx/{GAME_ID}/banner/1280/1280") + assert response.status_code == 422 + +def test_get_nx_banner_invalid_size(): + response = client.get(f"/nx/{GAME_ID}/banner/invalid") + assert response.status_code == 422 + +def test_get_nx_banner_invalid_width_height(): + response = client.get(f"/nx/{GAME_ID}/banner/1280/invalid") + assert response.status_code == 422 + def test_get_nx_screen(): response = client.get(f"/nx/{GAME_ID}/screen") From ee43f3aff676492ea1ab7ed404c303239931a15c Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 21:17:26 +0100 Subject: [PATCH 09/12] Fix: ensure returning None for invalid dimensions --- utils/resize_image.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/resize_image.py b/utils/resize_image.py index 0e68d89..e897923 100644 --- a/utils/resize_image.py +++ b/utils/resize_image.py @@ -30,6 +30,8 @@ def resize_image(file_path: str, width: int, height: int) -> str: (aspect_ratio == 16/9 and height in [720, 1080]): resized_img = img.resize((width, height)) resized_img.save(new_file_path) + else: + return None return new_file_path From 76553df97dbca78cf8188372427f69845c2d232d Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 21:22:57 +0100 Subject: [PATCH 10/12] Fix image resizing to use nearest neighbor algorithm --- utils/resize_image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/resize_image.py b/utils/resize_image.py index e897923..c3dca0f 100644 --- a/utils/resize_image.py +++ b/utils/resize_image.py @@ -28,7 +28,7 @@ def resize_image(file_path: str, width: int, height: int) -> str: aspect_ratio = width / height if (width == height and width == nearest_size(width)) or \ (aspect_ratio == 16/9 and height in [720, 1080]): - resized_img = img.resize((width, height)) + resized_img = img.resize((width, height), Image.NEAREST) resized_img.save(new_file_path) else: return None From 7a274746593f2ab4abc33265c9e8441c5634f77d Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 21:34:08 +0100 Subject: [PATCH 11/12] Add `pillow` to requirements --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a3b45a2..d258163 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ uvicorn PyYAML pytest httpx -requests \ No newline at end of file +requests +pillow \ No newline at end of file From de12468622d54c7c710966b6c8c20dcfb7c736ae Mon Sep 17 00:00:00 2001 From: Lenoch <81lennoch@gmail.com> Date: Fri, 8 Nov 2024 21:42:48 +0100 Subject: [PATCH 12/12] Fix error for unsupported resolutions Updated `get_game_icon` and `get_game_banner` functions to return None if the requested resolution is not supported. --- main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.py b/main.py index 0670124..4b28d40 100644 --- a/main.py +++ b/main.py @@ -169,6 +169,8 @@ def get_game_icon(tid, size: tuple = (1024, 1024)): icon_path = os.path.join(config['database-path'], 'media', f'{tid}', 'icon.jpg') icon_path = resize_image(icon_path, *size) + if not icon_path: + return None if os.path.exists(icon_path): with open(icon_path, 'rb') as file: icon = file.read() @@ -194,6 +196,8 @@ def get_game_banner(tid, size: tuple = (1920, 1080)): banner_path = os.path.join(config['database-path'], 'media', f'{tid}', 'banner.jpg') banner_path = resize_image(banner_path, *size) + if not banner_path: + return None if os.path.exists(banner_path): with open(banner_path, 'rb') as file: banner = file.read()