mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-02-08 17:03:11 -05:00
Feature/user photo storage (#877)
* add default assets for user profile * add recipe avatar * change user_id to UUID * add profile image upload * setup image cache keys * cleanup tests and add image tests * purge user data on delete * new user repository tests * add user_id validator for int -> UUID conversion * delete depreciated route * force set content type * refactor tests to use temp directory * validate parent exists before createing * set user_id to correct type * update instruction id * reset primary key on migration
This commit is contained in:
@@ -23,6 +23,22 @@ def get_image_sizes(org_img: Path, min_img: Path, tiny_img: Path) -> ImageSizes:
|
||||
return ImageSizes(org=sizeof_fmt(org_img), min=sizeof_fmt(min_img), tiny=sizeof_fmt(tiny_img))
|
||||
|
||||
|
||||
def to_webp(image_file: Path, quality: int = 100) -> Path:
|
||||
"""
|
||||
Converts an image to the webp format in-place. The original image is not
|
||||
removed By default, the quality is set to 100.
|
||||
"""
|
||||
if image_file.suffix == ".webp":
|
||||
return image_file
|
||||
|
||||
img = Image.open(image_file)
|
||||
|
||||
dest = image_file.with_suffix(".webp")
|
||||
img.save(dest, "WEBP", quality=quality)
|
||||
|
||||
return dest
|
||||
|
||||
|
||||
def minify_image(image_file: Path, force=False) -> ImageSizes:
|
||||
"""Minifies an image in it's original file format. Quality is lost
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ from pathlib import Path
|
||||
from typing import Tuple
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.core import root_logger
|
||||
from mealie.db.database import Database
|
||||
from mealie.schema.recipe import Recipe
|
||||
@@ -27,7 +29,7 @@ class BaseMigrator(BaseService):
|
||||
report_id: int
|
||||
report: ReportOut
|
||||
|
||||
def __init__(self, archive: Path, db: Database, session, user_id: int, group_id: UUID, add_migration_tag: bool):
|
||||
def __init__(self, archive: Path, db: Database, session, user_id: UUID4, group_id: UUID, add_migration_tag: bool):
|
||||
self.archive = archive
|
||||
self.db = db
|
||||
self.session = session
|
||||
|
||||
@@ -51,6 +51,9 @@ class MealieAlphaMigrator(BaseMigrator):
|
||||
|
||||
recipe["comments"] = []
|
||||
|
||||
# Reset ID on migration
|
||||
recipe["id"] = None
|
||||
|
||||
return Recipe(**recipe)
|
||||
|
||||
def _migrate(self) -> None:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import TypeVar
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import UUID4, BaseModel
|
||||
from slugify import slugify
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -13,7 +13,7 @@ T = TypeVar("T", bound=BaseModel)
|
||||
|
||||
|
||||
class DatabaseMigrationHelpers:
|
||||
def __init__(self, db: Database, session: Session, group_id: int, user_id: int) -> None:
|
||||
def __init__(self, db: Database, session: Session, group_id: int, user_id: UUID4) -> None:
|
||||
self.group_id = group_id
|
||||
self.user_id = user_id
|
||||
self.session = session
|
||||
|
||||
@@ -60,10 +60,10 @@ class RecipeService(CrudHttpMixins[CreateRecipe, Recipe, Recipe], UserHttpServic
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def can_update(self) -> bool:
|
||||
if self.user.id == self.item.user_id:
|
||||
return True
|
||||
if self.item.settings.locked and self.user.id != self.item.user_id:
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN)
|
||||
return True
|
||||
|
||||
def get_all(self, start=0, limit=None, load_foods=False) -> list[RecipeSummary]:
|
||||
items = self.db.recipes.summary(self.user.group_id, start=start, limit=limit, load_foods=load_foods)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import HTTPException, status
|
||||
|
||||
from mealie.core.root_logger import get_logger
|
||||
@@ -43,3 +45,6 @@ class UserService(UserHttpService[int, str]):
|
||||
self.target_user.password = hash_password(password_change.new_password)
|
||||
|
||||
return self.db.users.update_password(self.target_user.id, self.target_user.password)
|
||||
|
||||
def set_profile_picture(self, file_path: Path) -> PrivateUser:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user