mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-06 05:55:23 +02:00
Feature/group based notifications (#918)
* fix group page * setup group notification for backend * update type generators * script to auto-generate schema exports * setup frontend CRUD interface * remove old notifications UI * drop old events api * add test functionality * update naming for fields * add event dispatcher functionality * bump to python 3.10 * bump python version * purge old event code * use-async apprise * set mealie logo as image * unify styles for buttons rows * add links to banners
This commit is contained in:
parent
50a341ed3f
commit
190773c5d7
74 changed files with 1992 additions and 1229 deletions
|
@ -1,3 +1,4 @@
|
|||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .about import *
|
||||
from .backup import *
|
||||
from .migration import *
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .cookbook import *
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
from .event_notifications import *
|
||||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .events import *
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
from fastapi_camelcase import CamelModel
|
||||
|
||||
|
||||
class DeclaredTypes(str, Enum):
|
||||
general = "General"
|
||||
discord = "Discord"
|
||||
gotify = "Gotify"
|
||||
pushover = "Pushover"
|
||||
home_assistant = "Home Assistant"
|
||||
|
||||
|
||||
class EventNotificationOut(CamelModel):
|
||||
id: Optional[int]
|
||||
name: str = ""
|
||||
type: DeclaredTypes = DeclaredTypes.general
|
||||
general: bool = True
|
||||
recipe: bool = True
|
||||
backup: bool = True
|
||||
scheduled: bool = True
|
||||
migration: bool = True
|
||||
group: bool = True
|
||||
user: bool = True
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class EventNotificationIn(EventNotificationOut):
|
||||
notification_url: str = ""
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class Discord(CamelModel):
|
||||
webhook_id: str
|
||||
webhook_token: str
|
||||
|
||||
@property
|
||||
def create_url(self) -> str:
|
||||
return f"discord://{self.webhook_id}/{self.webhook_token}/"
|
||||
|
||||
|
||||
class GotifyPriority(str, Enum):
|
||||
low = "low"
|
||||
moderate = "moderate"
|
||||
normal = "normal"
|
||||
high = "high"
|
||||
|
||||
|
||||
class Gotify(CamelModel):
|
||||
hostname: str
|
||||
token: str
|
||||
priority: GotifyPriority = GotifyPriority.normal
|
||||
|
||||
@property
|
||||
def create_url(self) -> str:
|
||||
return f"gotifys://{self.hostname}/{self.token}/?priority={self.priority}"
|
|
@ -1,2 +1,10 @@
|
|||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .group import *
|
||||
from .group_events import *
|
||||
from .group_exports import *
|
||||
from .group_migration import *
|
||||
from .group_permissions import *
|
||||
from .group_preferences import *
|
||||
from .group_shopping_list import *
|
||||
from .invite_token import *
|
||||
from .webhook import *
|
||||
|
|
89
mealie/schema/group/group_events.py
Normal file
89
mealie/schema/group/group_events.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
from fastapi_camelcase import CamelModel
|
||||
from pydantic import UUID4
|
||||
|
||||
# =============================================================================
|
||||
# Group Events Notifier Options
|
||||
|
||||
|
||||
class GroupEventNotifierOptions(CamelModel):
|
||||
"""
|
||||
These events are in-sync with the EventTypes found in the EventBusService.
|
||||
If you modify this, make sure to update the EventBusService as well.
|
||||
"""
|
||||
|
||||
recipe_created: bool = False
|
||||
recipe_updated: bool = False
|
||||
recipe_deleted: bool = False
|
||||
|
||||
user_signup: bool = False
|
||||
|
||||
data_migrations: bool = False
|
||||
data_export: bool = False
|
||||
data_import: bool = False
|
||||
|
||||
mealplan_entry_created: bool = False
|
||||
|
||||
shopping_list_created: bool = False
|
||||
shopping_list_updated: bool = False
|
||||
shopping_list_deleted: bool = False
|
||||
|
||||
cookbook_created: bool = False
|
||||
cookbook_updated: bool = False
|
||||
cookbook_deleted: bool = False
|
||||
|
||||
tag_created: bool = False
|
||||
tag_updated: bool = False
|
||||
tag_deleted: bool = False
|
||||
|
||||
category_created: bool = False
|
||||
category_updated: bool = False
|
||||
category_deleted: bool = False
|
||||
|
||||
|
||||
class GroupEventNotifierOptionsSave(GroupEventNotifierOptions):
|
||||
notifier_id: UUID4
|
||||
|
||||
|
||||
class GroupEventNotifierOptionsOut(GroupEventNotifierOptions):
|
||||
id: UUID4
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
# =======================================================================
|
||||
# Notifiers
|
||||
|
||||
|
||||
class GroupEventNotifierCreate(CamelModel):
|
||||
name: str
|
||||
apprise_url: str
|
||||
|
||||
|
||||
class GroupEventNotifierSave(GroupEventNotifierCreate):
|
||||
enabled: bool = True
|
||||
group_id: UUID4
|
||||
options: GroupEventNotifierOptions = GroupEventNotifierOptions()
|
||||
|
||||
|
||||
class GroupEventNotifierUpdate(GroupEventNotifierSave):
|
||||
id: UUID4
|
||||
apprise_url: str = None
|
||||
|
||||
|
||||
class GroupEventNotifierOut(CamelModel):
|
||||
id: UUID4
|
||||
name: str
|
||||
enabled: bool
|
||||
group_id: UUID4
|
||||
options: GroupEventNotifierOptionsOut
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class GroupEventNotifierPrivate(GroupEventNotifierOut):
|
||||
apprise_url: str
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
|
@ -1,36 +1,2 @@
|
|||
from fastapi_camelcase import CamelModel
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.schema.recipe import IngredientFood
|
||||
|
||||
|
||||
class MultiPurposeLabelCreate(CamelModel):
|
||||
name: str
|
||||
|
||||
|
||||
class MultiPurposeLabelSave(MultiPurposeLabelCreate):
|
||||
group_id: UUID4
|
||||
|
||||
|
||||
class MultiPurposeLabelUpdate(MultiPurposeLabelSave):
|
||||
id: UUID4
|
||||
|
||||
|
||||
class MultiPurposeLabelSummary(MultiPurposeLabelUpdate):
|
||||
pass
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class MultiPurposeLabelOut(MultiPurposeLabelUpdate):
|
||||
shopping_list_items: "list[ShoppingListItemOut]" = []
|
||||
foods: list[IngredientFood] = []
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
from mealie.schema.group.group_shopping_list import ShoppingListItemOut
|
||||
|
||||
MultiPurposeLabelOut.update_forward_refs()
|
||||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .multi_purpose_label import *
|
||||
|
|
36
mealie/schema/labels/multi_purpose_label.py
Normal file
36
mealie/schema/labels/multi_purpose_label.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
from fastapi_camelcase import CamelModel
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.schema.recipe import IngredientFood
|
||||
|
||||
|
||||
class MultiPurposeLabelCreate(CamelModel):
|
||||
name: str
|
||||
|
||||
|
||||
class MultiPurposeLabelSave(MultiPurposeLabelCreate):
|
||||
group_id: UUID4
|
||||
|
||||
|
||||
class MultiPurposeLabelUpdate(MultiPurposeLabelSave):
|
||||
id: UUID4
|
||||
|
||||
|
||||
class MultiPurposeLabelSummary(MultiPurposeLabelUpdate):
|
||||
pass
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class MultiPurposeLabelOut(MultiPurposeLabelUpdate):
|
||||
shopping_list_items: "list[ShoppingListItemOut]" = []
|
||||
foods: list[IngredientFood] = []
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
from mealie.schema.group.group_shopping_list import ShoppingListItemOut
|
||||
|
||||
MultiPurposeLabelOut.update_forward_refs()
|
|
@ -1,3 +1,4 @@
|
|||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .meal import *
|
||||
from .new_meal import *
|
||||
from .shopping_list import *
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .recipe import *
|
||||
from .recipe_asset import *
|
||||
from .recipe_bulk_actions import *
|
||||
from .recipe_category import *
|
||||
from .recipe_comments import *
|
||||
from .recipe_image_types import *
|
||||
from .recipe_ingredient import *
|
||||
from .recipe_notes import *
|
||||
from .recipe_nutrition import *
|
||||
from .recipe_settings import *
|
||||
from .recipe_share_token import *
|
||||
from .recipe_step import *
|
||||
from .recipe_tool import *
|
||||
from .request_helpers import *
|
||||
|
|
|
@ -2,7 +2,7 @@ import enum
|
|||
|
||||
from fastapi_camelcase import CamelModel
|
||||
|
||||
from . import CategoryBase, TagBase
|
||||
from mealie.schema.recipe.recipe_category import CategoryBase, TagBase
|
||||
|
||||
|
||||
class ExportTypes(str, enum.Enum):
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from typing import List
|
||||
|
||||
from fastapi_camelcase import CamelModel
|
||||
from pydantic.utils import GetterDict
|
||||
|
||||
|
@ -23,7 +21,7 @@ class CategoryBase(CategoryIn):
|
|||
|
||||
|
||||
class RecipeCategoryResponse(CategoryBase):
|
||||
recipes: List["Recipe"] = []
|
||||
recipes: "list[Recipe]" = []
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
@ -42,7 +40,7 @@ class RecipeTagResponse(RecipeCategoryResponse):
|
|||
pass
|
||||
|
||||
|
||||
from . import Recipe
|
||||
from mealie.schema.recipe.recipe import Recipe
|
||||
|
||||
RecipeCategoryResponse.update_forward_refs()
|
||||
RecipeTagResponse.update_forward_refs()
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .reports import *
|
||||
|
|
|
@ -1,17 +1,2 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class ErrorResponse(BaseModel):
|
||||
message: str
|
||||
error: bool = True
|
||||
exception: Optional[str] = None
|
||||
|
||||
@classmethod
|
||||
def respond(cls, message: str, exception: Optional[str] = None) -> dict:
|
||||
"""
|
||||
This method is an helper to create an obect and convert to a dictionary
|
||||
in the same call, for use while providing details to a HTTPException
|
||||
"""
|
||||
return cls(message=message, exception=exception).dict()
|
||||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .error_response import *
|
||||
|
|
17
mealie/schema/response/error_response.py
Normal file
17
mealie/schema/response/error_response.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class ErrorResponse(BaseModel):
|
||||
message: str
|
||||
error: bool = True
|
||||
exception: Optional[str] = None
|
||||
|
||||
@classmethod
|
||||
def respond(cls, message: str, exception: Optional[str] = None) -> dict:
|
||||
"""
|
||||
This method is an helper to create an obect and convert to a dictionary
|
||||
in the same call, for use while providing details to a HTTPException
|
||||
"""
|
||||
return cls(message=message, exception=exception).dict()
|
|
@ -1 +1,2 @@
|
|||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .tasks import *
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
from .auth import *
|
||||
from .registration import *
|
||||
from .sign_up import *
|
||||
from .user import *
|
||||
from .user_passwords import *
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue