mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 14:33:33 -07:00
multi group supporot for job scheduler
This commit is contained in:
parent
e9107d48b9
commit
3f96961e35
6 changed files with 100 additions and 36 deletions
|
@ -3,9 +3,12 @@ from db.db_setup import generate_session
|
|||
from fastapi import APIRouter, Depends
|
||||
from schema.settings import SiteSettings
|
||||
from schema.snackbar import SnackResponse
|
||||
from schema.user import GroupInDB, UserInDB
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.post_webhooks import post_webhooks
|
||||
|
||||
from routes.deps import manager
|
||||
|
||||
router = APIRouter(prefix="/api/site-settings", tags=["Settings"])
|
||||
|
||||
|
||||
|
@ -27,7 +30,11 @@ def update_settings(data: SiteSettings, session: Session = Depends(generate_sess
|
|||
|
||||
|
||||
@router.post("/webhooks/test")
|
||||
def test_webhooks():
|
||||
def test_webhooks(
|
||||
current_user: UserInDB = Depends(manager),
|
||||
session: Session = Depends(generate_session),
|
||||
):
|
||||
""" Run the function to test your webhooks """
|
||||
group_entry: GroupInDB = db.groups.get(session, current_user.group, "name")
|
||||
|
||||
return post_webhooks()
|
||||
return post_webhooks(group_entry.id, session)
|
||||
|
|
|
@ -27,7 +27,7 @@ class MealPlanIn(BaseModel):
|
|||
meals: List[MealIn]
|
||||
|
||||
@validator("endDate")
|
||||
def endDate_after_startDate(cls, v, values, **kwargs):
|
||||
def endDate_after_startDate(v, values, config, field):
|
||||
if "startDate" in values and v < values["startDate"]:
|
||||
raise ValueError("EndDate should be greater than StartDate")
|
||||
return v
|
||||
|
|
10
mealie/schema/scheduler.py
Normal file
10
mealie/schema/scheduler.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class WebhookJob(BaseModel):
|
||||
webhook_urls: list[str] = []
|
||||
webhook_time: str = "00:00"
|
||||
webhook_enable: bool
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import date, timedelta
|
||||
|
||||
from db.database import db
|
||||
from schema.meal import MealIn, MealOut, MealPlanIn, MealPlanProcessed
|
||||
from schema.meal import MealIn, MealOut, MealPlanIn, MealPlanInDB, MealPlanProcessed
|
||||
from schema.recipe import Recipe
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
|
@ -38,9 +38,9 @@ def process_meals(session: Session, meal_plan_base: MealPlanIn) -> MealPlanProce
|
|||
|
||||
|
||||
def get_todays_meal(session):
|
||||
meal_plan = db.meals.get_all(session, limit=1, order_by="startDate")
|
||||
meal_plan: MealPlanInDB = db.groups.get(session, limit=1, order_by="startDate")
|
||||
|
||||
for meal in meal_plan:
|
||||
for meal in meal_plan.meals:
|
||||
meal: MealOut
|
||||
if meal.date == date.today():
|
||||
return meal.slug
|
||||
|
|
|
@ -1,32 +1,35 @@
|
|||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from fastapi.logger import logger
|
||||
from schema.user import GroupInDB
|
||||
from services.backups.exports import auto_backup_job
|
||||
from services.scheduler.global_scheduler import scheduler
|
||||
from services.scheduler.scheduler_utils import Cron, cron_parser
|
||||
from fastapi.logger import logger
|
||||
from schema.settings import SiteSettings
|
||||
from db.database import db
|
||||
from utils.post_webhooks import post_webhooks
|
||||
|
||||
|
||||
# TODO Fix Scheduler
|
||||
@scheduler.scheduled_job(trigger="interval", minutes=15)
|
||||
@scheduler.scheduled_job(trigger="interval", minutes=30)
|
||||
def update_webhook_schedule():
|
||||
"""
|
||||
A scheduled background job that runs every 15 minutes to
|
||||
A scheduled background job that runs every 30 minutes to
|
||||
poll the database for changes and reschedule the webhook time
|
||||
"""
|
||||
session = create_session()
|
||||
settings = db.settings.get(session, "main")
|
||||
settings = SiteSettings(**settings)
|
||||
time = cron_parser(settings.webhooks.webhookTime)
|
||||
job = JOB_STORE.get("webhooks")
|
||||
all_groups: list[GroupInDB] = db.groups.get_all(session)
|
||||
|
||||
scheduler.reschedule_job(
|
||||
job.scheduled_task.id,
|
||||
trigger="cron",
|
||||
hour=time.hours,
|
||||
minute=time.minutes,
|
||||
)
|
||||
for group in all_groups:
|
||||
|
||||
time = cron_parser(group.webhook_time)
|
||||
job = JOB_STORE.get(group.name)
|
||||
|
||||
scheduler.reschedule_job(
|
||||
job.scheduled_task.id,
|
||||
trigger="cron",
|
||||
hour=time.hours,
|
||||
minute=time.minutes,
|
||||
)
|
||||
|
||||
session.close()
|
||||
logger.info(scheduler.print_jobs())
|
||||
|
@ -34,7 +37,12 @@ def update_webhook_schedule():
|
|||
|
||||
class ScheduledFunction:
|
||||
def __init__(
|
||||
self, scheduler: BackgroundScheduler, function, cron: Cron, name: str
|
||||
self,
|
||||
scheduler: BackgroundScheduler,
|
||||
function,
|
||||
cron: Cron,
|
||||
name: str,
|
||||
args: list = None,
|
||||
) -> None:
|
||||
self.scheduled_task = scheduler.add_job(
|
||||
function,
|
||||
|
@ -44,6 +52,7 @@ class ScheduledFunction:
|
|||
minute=cron.minutes,
|
||||
max_instances=1,
|
||||
replace_existing=True,
|
||||
args=args,
|
||||
)
|
||||
|
||||
logger.info("New Function Scheduled")
|
||||
|
@ -56,9 +65,35 @@ JOB_STORE = {
|
|||
"backup_job": ScheduledFunction(
|
||||
scheduler, auto_backup_job, Cron(hours=00, minutes=00), "backups"
|
||||
),
|
||||
"webhooks": ScheduledFunction(
|
||||
scheduler, post_webhooks, Cron(hours=00, minutes=00), "webhooks"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def init_webhook_schedule(scheduler, job_store: dict):
|
||||
session = create_session()
|
||||
all_groups: list[GroupInDB] = db.groups.get_all(session)
|
||||
|
||||
for group in all_groups:
|
||||
cron = cron_parser(group.webhook_time)
|
||||
|
||||
job_store.update(
|
||||
{
|
||||
group.name: ScheduledFunction(
|
||||
scheduler,
|
||||
post_webhooks,
|
||||
cron=cron,
|
||||
name=group.name,
|
||||
args=[group.id],
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
session.close()
|
||||
logger.info("Init Webhook Schedule \n", scheduler.print_jobs())
|
||||
|
||||
return job_store
|
||||
|
||||
|
||||
JOB_STORE = init_webhook_schedule(scheduler=scheduler, job_store=JOB_STORE)
|
||||
|
||||
|
||||
scheduler.start()
|
||||
|
|
|
@ -1,23 +1,35 @@
|
|||
import json
|
||||
from datetime import date
|
||||
|
||||
import requests
|
||||
from db.database import db
|
||||
from db.db_setup import create_session
|
||||
from schema.settings import SiteSettings
|
||||
from services.meal_services import get_todays_meal
|
||||
from schema.meal import MealOut, MealPlanInDB
|
||||
from schema.user import GroupInDB
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
|
||||
def post_webhooks():
|
||||
session = create_session()
|
||||
all_settings = db.get(session, 1)
|
||||
all_settings = SiteSettings(**all_settings)
|
||||
def post_webhooks(group: int, session: Session = None):
|
||||
session = session if session else create_session()
|
||||
group_settings: GroupInDB = db.groups.get(session, group)
|
||||
|
||||
if group_settings.webhook_enable:
|
||||
today_slug = None
|
||||
|
||||
for mealplan in group_settings.mealplans:
|
||||
mealplan: MealPlanInDB
|
||||
for meal in mealplan.meals:
|
||||
meal: MealOut
|
||||
if meal.date == date.today():
|
||||
today_slug = meal.slug
|
||||
break
|
||||
|
||||
if not today_slug:
|
||||
return
|
||||
|
||||
if all_settings.webhooks.enabled:
|
||||
today_slug = get_todays_meal(session)
|
||||
todays_meal = db.recipes.get(session, today_slug)
|
||||
urls = all_settings.webhooks.webhookURLs
|
||||
|
||||
for url in urls:
|
||||
requests.post(url, json.dumps(todays_meal, default=str))
|
||||
for url in group_settings.webhook_urls:
|
||||
requests.post(url, json=todays_meal.json())
|
||||
|
||||
session.close()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue