mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-27 20:55:12 -05:00
feature/favorite-recipes (#443)
* add favorites options * bump dependencies * add badges to all cards * typo * remove console.log * fix site-loader viewport Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
@@ -78,7 +78,7 @@ class BaseDocument:
|
||||
return session.query(self.sql_model).filter_by(**{match_key: match_value}).one()
|
||||
|
||||
def get(
|
||||
self, session: Session, match_value: str, match_key: str = None, limit=1, any_case=False
|
||||
self, session: Session, match_value: str, match_key: str = None, limit=1, any_case=False, override_schema=None
|
||||
) -> Union[BaseModel, list[BaseModel]]:
|
||||
"""Retrieves an entry from the database by matching a key/value pair. If no
|
||||
key is provided the class objects primary key will be used to match against.
|
||||
@@ -91,6 +91,7 @@ class BaseDocument:
|
||||
|
||||
Returns:
|
||||
dict or list[dict]:
|
||||
|
||||
"""
|
||||
if match_key is None:
|
||||
match_key = self.primary_key
|
||||
@@ -103,12 +104,14 @@ class BaseDocument:
|
||||
else:
|
||||
result = session.query(self.sql_model).filter_by(**{match_key: match_value}).limit(limit).all()
|
||||
|
||||
eff_schema = override_schema or self.schema
|
||||
|
||||
if limit == 1:
|
||||
try:
|
||||
return self.schema.from_orm(result[0])
|
||||
return eff_schema.from_orm(result[0])
|
||||
except IndexError:
|
||||
return None
|
||||
return [self.schema.from_orm(x) for x in result]
|
||||
return [eff_schema.from_orm(x) for x in result]
|
||||
|
||||
def create(self, session: Session, document: dict) -> BaseModel:
|
||||
"""Creates a new database entry for the given SQL Alchemy Model.
|
||||
|
||||
@@ -19,7 +19,7 @@ class EventNotification(SqlAlchemyBase, BaseMixins):
|
||||
user = Column(Boolean, default=False)
|
||||
|
||||
def __init__(
|
||||
self, name, notification_url, type, general, recipe, backup, scheduled, migration, group, user, *args, **kwargs
|
||||
self, name, notification_url, type, general, recipe, backup, scheduled, migration, group, user, **_
|
||||
) -> None:
|
||||
self.name = name
|
||||
self.notification_url = notification_url
|
||||
@@ -41,7 +41,7 @@ class Event(SqlAlchemyBase, BaseMixins):
|
||||
time_stamp = Column(DateTime)
|
||||
category = Column(String)
|
||||
|
||||
def __init__(self, title, text, time_stamp, category, *args, **kwargs) -> None:
|
||||
def __init__(self, title, text, time_stamp, category, **_) -> None:
|
||||
self.title = title
|
||||
self.text = text
|
||||
self.time_stamp = time_stamp
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import sqlalchemy.ext.declarative as dec
|
||||
from requests import Session
|
||||
|
||||
SqlAlchemyBase = dec.declarative_base()
|
||||
|
||||
@@ -6,3 +7,7 @@ SqlAlchemyBase = dec.declarative_base()
|
||||
class BaseMixins:
|
||||
def update(self, *args, **kwarg):
|
||||
self.__init__(*args, **kwarg)
|
||||
|
||||
def get_ref(cls_type, session: Session, match_value: str, match_attr: str = "id"):
|
||||
eff_ref = getattr(cls_type, match_attr)
|
||||
return session.query(cls_type).filter(eff_ref == match_value).one_or_none()
|
||||
|
||||
@@ -68,6 +68,10 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||
date_added = sa.Column(sa.Date, default=date.today)
|
||||
date_updated = sa.Column(sa.DateTime)
|
||||
|
||||
# Favorited By
|
||||
favorited_by_id = sa.Column(sa.Integer, sa.ForeignKey("users.id"))
|
||||
favorited_by = orm.relationship("User", back_populates="favorite_recipes")
|
||||
|
||||
@validates("name")
|
||||
def validate_name(self, key, name):
|
||||
assert name != ""
|
||||
@@ -99,8 +103,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||
extras: dict = None,
|
||||
assets: list = None,
|
||||
settings: dict = None,
|
||||
*args,
|
||||
**kwargs
|
||||
**_
|
||||
) -> None:
|
||||
self.name = name
|
||||
self.description = description
|
||||
@@ -138,6 +141,6 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||
self.date_added = date_added
|
||||
self.date_updated = datetime.datetime.now()
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
def update(self, **_):
|
||||
"""Updated a database entry by removing nested rows and rebuilds the row through the __init__ functions"""
|
||||
self.__init__(*args, **kwargs)
|
||||
self.__init__(**_)
|
||||
|
||||
@@ -42,7 +42,7 @@ class CustomPage(SqlAlchemyBase, BaseMixins):
|
||||
slug = sa.Column(sa.String, nullable=False)
|
||||
categories = orm.relationship("Category", secondary=custom_pages2categories, single_parent=True)
|
||||
|
||||
def __init__(self, session=None, name=None, slug=None, position=0, categories=[], *args, **kwargs) -> None:
|
||||
def __init__(self, session=None, name=None, slug=None, position=0, categories=[], **_) -> None:
|
||||
self.name = name
|
||||
self.slug = slug
|
||||
self.position = position
|
||||
|
||||
@@ -9,7 +9,7 @@ class SiteThemeModel(SqlAlchemyBase, BaseMixins):
|
||||
name = Column(String, nullable=False, unique=True)
|
||||
colors = orm.relationship("ThemeColorsModel", uselist=False, single_parent=True, cascade="all, delete-orphan")
|
||||
|
||||
def __init__(self, name: str, colors: dict, *arg, **kwargs) -> None:
|
||||
def __init__(self, name: str, colors: dict, **_) -> None:
|
||||
self.name = name
|
||||
self.colors = ThemeColorsModel(**colors)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from mealie.core.config import settings
|
||||
from mealie.db.models.group import Group
|
||||
from mealie.db.models.model_base import BaseMixins, SqlAlchemyBase
|
||||
from mealie.db.models.recipe.recipe import RecipeModel
|
||||
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, orm
|
||||
|
||||
|
||||
@@ -22,11 +23,7 @@ class User(SqlAlchemyBase, BaseMixins):
|
||||
__tablename__ = "users"
|
||||
id = Column(Integer, primary_key=True)
|
||||
full_name = Column(String, index=True)
|
||||
username = Column(
|
||||
String,
|
||||
index=True,
|
||||
unique=True,
|
||||
)
|
||||
username = Column(String, index=True, unique=True)
|
||||
email = Column(String, unique=True, index=True)
|
||||
password = Column(String)
|
||||
group_id = Column(Integer, ForeignKey("groups.id"))
|
||||
@@ -36,21 +33,38 @@ class User(SqlAlchemyBase, BaseMixins):
|
||||
LongLiveToken, back_populates="user", cascade="all, delete, delete-orphan", single_parent=True
|
||||
)
|
||||
|
||||
favorite_recipes: list[RecipeModel] = orm.relationship(RecipeModel, back_populates="favorited_by")
|
||||
|
||||
def __init__(
|
||||
self, session, full_name, email, password, group: str = settings.DEFAULT_GROUP, admin=False, **_
|
||||
self,
|
||||
session,
|
||||
full_name,
|
||||
email,
|
||||
password,
|
||||
favorite_recipes: list[str] = None,
|
||||
group: str = settings.DEFAULT_GROUP,
|
||||
admin=False,
|
||||
**_
|
||||
) -> None:
|
||||
|
||||
group = group or settings.DEFAULT_GROUP
|
||||
favorite_recipes = favorite_recipes or []
|
||||
self.full_name = full_name
|
||||
self.email = email
|
||||
self.group = Group.get_ref(session, group)
|
||||
self.admin = admin
|
||||
self.password = password
|
||||
|
||||
self.favorite_recipes = [
|
||||
RecipeModel.get_ref(RecipeModel, session=session, match_value=x, match_attr="slug")
|
||||
for x in favorite_recipes
|
||||
]
|
||||
|
||||
if self.username is None:
|
||||
self.username = full_name
|
||||
|
||||
def update(self, full_name, email, group, admin, username, session=None, id=None, password=None, *args, **kwargs):
|
||||
def update(self, full_name, email, group, admin, username, session=None, favorite_recipes=None, password=None, **_):
|
||||
favorite_recipes = favorite_recipes or []
|
||||
self.username = username
|
||||
self.full_name = full_name
|
||||
self.email = email
|
||||
@@ -63,6 +77,11 @@ class User(SqlAlchemyBase, BaseMixins):
|
||||
if password:
|
||||
self.password = password
|
||||
|
||||
self.favorite_recipes = [
|
||||
RecipeModel.get_ref(RecipeModel, session=session, match_value=x, match_attr="slug")
|
||||
for x in favorite_recipes
|
||||
]
|
||||
|
||||
def update_password(self, password):
|
||||
self.password = password
|
||||
|
||||
|
||||
Reference in New Issue
Block a user