From bdac695c3816737b0e676e103e92f218ae305589 Mon Sep 17 00:00:00 2001 From: hay-kot Date: Fri, 2 Apr 2021 21:47:41 -0800 Subject: [PATCH] add image minification --- mealie/routes/recipe/recipe_crud_routes.py | 11 +++--- .../{image_services.py => image/image.py} | 35 +++++++++++++------ mealie/services/image/minify.py | 6 ++-- mealie/services/meal_services.py | 2 +- mealie/services/scraper/scraper.py | 2 +- 5 files changed, 37 insertions(+), 19 deletions(-) rename mealie/services/{image_services.py => image/image.py} (71%) diff --git a/mealie/routes/recipe/recipe_crud_routes.py b/mealie/routes/recipe/recipe_crud_routes.py index 48de618ef..b044a80a9 100644 --- a/mealie/routes/recipe/recipe_crud_routes.py +++ b/mealie/routes/recipe/recipe_crud_routes.py @@ -7,7 +7,7 @@ from mealie.db.db_setup import generate_session from mealie.routes.deps import get_current_user from mealie.schema.recipe import Recipe, RecipeURLIn from mealie.schema.snackbar import SnackResponse -from mealie.services.image_services import IMG_OPTIONS, read_image, write_image +from mealie.services.image.image import IMG_OPTIONS, delete_image, read_image, write_image from mealie.services.scraper.scraper import create_from_url from sqlalchemy.orm.session import Session @@ -74,6 +74,7 @@ def delete_recipe( try: db.recipes.delete(session, recipe_slug) + delete_image(recipe_slug) except: raise HTTPException(status_code=404, detail=SnackResponse.error("Unable to Delete Recipe")) @@ -90,13 +91,13 @@ class ImageType(str, Enum): async def get_recipe_img(recipe_slug: str, image_type: ImageType = ImageType.original): """ Takes in a recipe slug, returns the static image """ if image_type == ImageType.original: - image_type = IMG_OPTIONS.ORIGINAL_IMAGE + which_image = IMG_OPTIONS.ORIGINAL_IMAGE elif image_type == ImageType.small: - image_type = IMG_OPTIONS.MINIFIED_IMAGE + which_image = IMG_OPTIONS.MINIFIED_IMAGE elif image_type == ImageType.tiny: - image_type = IMG_OPTIONS.TINY_IMAGE + which_image = IMG_OPTIONS.TINY_IMAGE - recipe_image = read_image(recipe_slug, image_type=image_type) + recipe_image = read_image(recipe_slug, image_type=which_image) print(recipe_image) if recipe_image: return FileResponse(recipe_image) diff --git a/mealie/services/image_services.py b/mealie/services/image/image.py similarity index 71% rename from mealie/services/image_services.py rename to mealie/services/image/image.py index 9bd01da5c..a352de6a2 100644 --- a/mealie/services/image_services.py +++ b/mealie/services/image/image.py @@ -1,10 +1,12 @@ import shutil from dataclasses import dataclass from pathlib import Path +from typing import Union import requests from fastapi.logger import logger from mealie.core.config import app_dirs +from mealie.services.image import minify @dataclass @@ -27,23 +29,35 @@ def read_image(recipe_slug: str, image_type: str = "original") -> Path: Returns: Path: [description] """ + print(image_type) recipe_slug = recipe_slug.split(".")[0] # Incase of File Name recipe_image_dir = app_dirs.IMG_DIR.joinpath(recipe_slug) - glob_string = "original*" if image_type else "min-original*" - - for file in recipe_image_dir.glob(glob_string): + for file in recipe_image_dir.glob(image_type): return file return None def write_image(recipe_slug: str, file_data: bytes, extension: str) -> Path.name: - delete_image(recipe_slug) + try: + delete_image(recipe_slug) + except: + pass - image_path = Path(app_dirs.IMG_DIR.joinpath(f"{recipe_slug}.{extension}")) - with open(image_path, "ab") as f: - f.write(file_data) + image_dir = Path(app_dirs.IMG_DIR.joinpath(f"{recipe_slug}")) + image_dir.mkdir() + extension = extension.replace(".", "") + image_path = image_dir.joinpath(f"original.{extension}") + + if isinstance(file_data, bytes): + with open(image_path, "ab") as f: + f.write(file_data) + else: + with open(image_path, "ab") as f: + shutil.copyfileobj(file_data, f) + + minify.migrate_images() return image_path @@ -51,7 +65,7 @@ def write_image(recipe_slug: str, file_data: bytes, extension: str) -> Path.name def delete_image(recipe_slug: str) -> str: recipe_slug = recipe_slug.split(".")[0] for file in app_dirs.IMG_DIR.glob(f"{recipe_slug}*"): - return file.unlink() + return shutil.rmtree(file) def scrape_image(image_url: str, slug: str) -> Path: @@ -78,8 +92,9 @@ def scrape_image(image_url: str, slug: str) -> Path: if r.status_code == 200: r.raw.decode_content = True - with open(filename, "wb") as f: - shutil.copyfileobj(r.raw, f) + write_image(slug, r.raw, filename.suffix) + + filename.unlink() return filename diff --git a/mealie/services/image/minify.py b/mealie/services/image/minify.py index 09b7203cc..418ae6024 100644 --- a/mealie/services/image/minify.py +++ b/mealie/services/image/minify.py @@ -4,7 +4,7 @@ from mealie.core.config import app_dirs from PIL import Image, UnidentifiedImageError -def minify_image(my_path: Path, min_dest: Path, tiny_dest: Path): +def minify_image(image_file: Path, min_dest: Path, tiny_dest: Path): """Minifies an image in it's original file format. Quality is lost Args: @@ -13,7 +13,7 @@ def minify_image(my_path: Path, min_dest: Path, tiny_dest: Path): tiny_dest (Path): FULL Destination File Path """ try: - img = Image.open(my_path) + img = Image.open(image_file) basewidth = 720 wpercent = basewidth / float(img.size[0]) hsize = int((float(img.size[1]) * float(wpercent))) @@ -50,6 +50,8 @@ def sizeof_fmt(size, decimal_places=2): def move_all_images(): for image_file in app_dirs.IMG_DIR.iterdir(): if image_file.is_file(): + if image_file.name == ".DS_Store": + continue new_folder = app_dirs.IMG_DIR.joinpath(image_file.stem) new_folder.mkdir(parents=True, exist_ok=True) image_file.rename(new_folder.joinpath(f"original{image_file.suffix}")) diff --git a/mealie/services/meal_services.py b/mealie/services/meal_services.py index 46ff1fca0..7f5aaefa5 100644 --- a/mealie/services/meal_services.py +++ b/mealie/services/meal_services.py @@ -52,7 +52,7 @@ def get_todays_meal(session: Session, group: Union[int, GroupInDB]) -> Recipe: Returns: Recipe: Pydantic Recipe Object """ - session = session if session else create_session() + session = session or create_session() if isinstance(group, int): group: GroupInDB = db.groups.get(session, group) diff --git a/mealie/services/scraper/scraper.py b/mealie/services/scraper/scraper.py index 4ba9028e7..451827052 100644 --- a/mealie/services/scraper/scraper.py +++ b/mealie/services/scraper/scraper.py @@ -5,7 +5,7 @@ import requests import scrape_schema_recipe from mealie.core.config import app_dirs from fastapi.logger import logger -from mealie.services.image_services import scrape_image +from mealie.services.image.image import scrape_image from mealie.schema.recipe import Recipe from mealie.services.scraper import open_graph from mealie.services.scraper.cleaner import Cleaner