Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Correctly resize and save small artwork #1238

Merged
merged 1 commit into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 19 additions & 18 deletions backend/endpoints/collections.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import json
from io import BytesIO
from shutil import rmtree

from anyio import open_file
from anyio import Path
from config import RESOURCES_BASE_PATH
from decorators.auth import protected_route
from endpoints.responses import MessageResponse
Expand All @@ -17,6 +18,7 @@
from handler.filesystem.base_handler import CoverSize
from logger.logger import log
from models.collection import Collection
from PIL import Image
from sqlalchemy.inspection import inspect
from utils.router import APIRouter

Expand Down Expand Up @@ -62,15 +64,14 @@ async def add_collection(
artwork_path,
) = await fs_resource_handler.build_artwork_path(_added_collection, file_ext)

artwork_file = artwork.file.read()
file_location_s = f"{artwork_path}/small.{file_ext}"
async with await open_file(file_location_s, "wb+") as artwork_s:
await artwork_s.write(artwork_file)
fs_resource_handler.resize_cover_to_small(file_location_s)

file_location_l = f"{artwork_path}/big.{file_ext}"
async with await open_file(file_location_l, "wb+") as artwork_l:
await artwork_l.write(artwork_file)
artwork_content = BytesIO(await artwork.read())
file_location_small = Path(f"{artwork_path}/small.{file_ext}")
file_location_large = Path(f"{artwork_path}/big.{file_ext}")
with Image.open(artwork_content) as img:
img.save(file_location_large)
fs_resource_handler.resize_cover_to_small(
img, save_path=file_location_small
)
else:
path_cover_s, path_cover_l = await fs_resource_handler.get_cover(
overwrite=True,
Expand Down Expand Up @@ -183,15 +184,15 @@ async def update_collection(
cleaned_data["path_cover_l"] = path_cover_l
cleaned_data["path_cover_s"] = path_cover_s

artwork_file = artwork.file.read()
file_location_s = f"{artwork_path}/small.{file_ext}"
async with await open_file(file_location_s, "wb+") as artwork_s:
await artwork_s.write(artwork_file)
fs_resource_handler.resize_cover_to_small(file_location_s)
artwork_content = BytesIO(await artwork.read())
file_location_small = Path(f"{artwork_path}/small.{file_ext}")
file_location_large = Path(f"{artwork_path}/big.{file_ext}")
with Image.open(artwork_content) as img:
img.save(file_location_large)
fs_resource_handler.resize_cover_to_small(
img, save_path=file_location_small
)

file_location_l = f"{artwork_path}/big.{file_ext}"
async with await open_file(file_location_l, "wb+") as artwork_l:
await artwork_l.write(artwork_file)
cleaned_data.update({"url_cover": ""})
else:
if data.get("url_cover", "") != collection.url_cover or not (
Expand Down
20 changes: 11 additions & 9 deletions backend/endpoints/rom.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import binascii
from base64 import b64encode
from io import BytesIO
from shutil import rmtree
from typing import Annotated
from urllib.parse import quote

from anyio import Path, open_file
from anyio import Path
from config import (
DEV_MODE,
DISABLE_DOWNLOAD_ENDPOINT_AUTH,
Expand All @@ -23,6 +24,7 @@
from handler.filesystem.base_handler import CoverSize
from handler.metadata import meta_igdb_handler, meta_moby_handler
from logger.logger import log
from PIL import Image
from starlette.requests import ClientDisconnect
from starlette.responses import FileResponse
from streaming_form_data import StreamingFormDataParser
Expand Down Expand Up @@ -433,15 +435,15 @@ async def update_rom(
{"path_cover_s": path_cover_s, "path_cover_l": path_cover_l}
)

artwork_file = artwork.file.read()
file_location_s = f"{artwork_path}/small.{file_ext}"
async with await open_file(file_location_s, "wb+") as artwork_s:
await artwork_s.write(artwork_file)
fs_resource_handler.resize_cover_to_small(file_location_s)
artwork_content = BytesIO(await artwork.read())
file_location_small = Path(f"{artwork_path}/small.{file_ext}")
file_location_large = Path(f"{artwork_path}/big.{file_ext}")
with Image.open(artwork_content) as img:
img.save(file_location_large)
fs_resource_handler.resize_cover_to_small(
img, save_path=file_location_small
)

file_location_l = f"{artwork_path}/big.{file_ext}"
async with await open_file(file_location_l, "wb+") as artwork_l:
await artwork_l.write(artwork_file)
cleaned_data.update({"url_cover": ""})
else:
if data.get("url_cover", "") != rom.url_cover or not (
Expand Down
20 changes: 10 additions & 10 deletions backend/handler/filesystem/resources_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from logger.logger import log
from models.collection import Collection
from models.rom import Rom
from PIL import Image
from PIL import Image, ImageFile
from utils.context import ctx_httpx_client

from .base_handler import CoverSize, FSHandler
Expand All @@ -33,9 +33,8 @@ async def cover_exists(entity: Rom | Collection, size: CoverSize) -> bool:
return False

@staticmethod
def resize_cover_to_small(cover_path: str) -> None:
"""Path of the cover image to resize"""
cover = Image.open(cover_path)
def resize_cover_to_small(cover: ImageFile.ImageFile, save_path: Path) -> None:
"""Resize cover to small size, and save it to filesystem."""
if cover.height >= 1000:
ratio = 0.2
else:
Expand All @@ -44,7 +43,7 @@ def resize_cover_to_small(cover_path: str) -> None:
small_height = int(cover.height * ratio)
small_size = (small_width, small_height)
small_img = cover.resize(small_size)
small_img.save(cover_path)
small_img.save(save_path)

async def _store_cover(
self, entity: Rom | Collection, url_cover: str, size: CoverSize
Expand All @@ -57,15 +56,15 @@ async def _store_cover(
url_cover: url to get the cover
size: size of the cover
"""
cover_file = f"{size.value}.png"
cover_path = f"{RESOURCES_BASE_PATH}/{entity.fs_resources_path}/cover"
cover_path = Path(f"{RESOURCES_BASE_PATH}/{entity.fs_resources_path}/cover")
cover_file = cover_path / Path(f"{size.value}.png")

httpx_client = ctx_httpx_client.get()
try:
async with httpx_client.stream("GET", url_cover, timeout=120) as response:
if response.status_code == 200:
await Path(cover_path).mkdir(parents=True, exist_ok=True)
async with await open_file(f"{cover_path}/{cover_file}", "wb") as f:
await cover_path.mkdir(parents=True, exist_ok=True)
async with await cover_file.open("wb") as f:
async for chunk in response.aiter_raw():
await f.write(chunk)
except httpx.NetworkError as exc:
Expand All @@ -77,7 +76,8 @@ async def _store_cover(
log.warning(f"Failure writing cover {url_cover} to file (ProtocolError)")

if size == CoverSize.SMALL:
self.resize_cover_to_small(f"{cover_path}/{cover_file}")
with Image.open(cover_file) as img:
self.resize_cover_to_small(img, save_path=cover_file)

@staticmethod
async def _get_cover_path(entity: Rom | Collection, size: CoverSize) -> str:
Expand Down
Loading