mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 22:43:34 -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 fastapi import APIRouter, Depends
|
||||||
from schema.settings import SiteSettings
|
from schema.settings import SiteSettings
|
||||||
from schema.snackbar import SnackResponse
|
from schema.snackbar import SnackResponse
|
||||||
|
from schema.user import GroupInDB, UserInDB
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
from utils.post_webhooks import post_webhooks
|
from utils.post_webhooks import post_webhooks
|
||||||
|
|
||||||
|
from routes.deps import manager
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/site-settings", tags=["Settings"])
|
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")
|
@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 """
|
""" 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]
|
meals: List[MealIn]
|
||||||
|
|
||||||
@validator("endDate")
|
@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"]:
|
if "startDate" in values and v < values["startDate"]:
|
||||||
raise ValueError("EndDate should be greater than StartDate")
|
raise ValueError("EndDate should be greater than StartDate")
|
||||||
return v
|
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 datetime import date, timedelta
|
||||||
|
|
||||||
from db.database import db
|
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 schema.recipe import Recipe
|
||||||
from sqlalchemy.orm.session import Session
|
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):
|
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
|
meal: MealOut
|
||||||
if meal.date == date.today():
|
if meal.date == date.today():
|
||||||
return meal.slug
|
return meal.slug
|
||||||
|
|
|
@ -1,32 +1,35 @@
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
|
from db.database import db
|
||||||
from db.db_setup import create_session
|
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.backups.exports import auto_backup_job
|
||||||
from services.scheduler.global_scheduler import scheduler
|
from services.scheduler.global_scheduler import scheduler
|
||||||
from services.scheduler.scheduler_utils import Cron, cron_parser
|
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
|
from utils.post_webhooks import post_webhooks
|
||||||
|
|
||||||
|
|
||||||
# TODO Fix Scheduler
|
# TODO Fix Scheduler
|
||||||
@scheduler.scheduled_job(trigger="interval", minutes=15)
|
@scheduler.scheduled_job(trigger="interval", minutes=30)
|
||||||
def update_webhook_schedule():
|
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
|
poll the database for changes and reschedule the webhook time
|
||||||
"""
|
"""
|
||||||
session = create_session()
|
session = create_session()
|
||||||
settings = db.settings.get(session, "main")
|
all_groups: list[GroupInDB] = db.groups.get_all(session)
|
||||||
settings = SiteSettings(**settings)
|
|
||||||
time = cron_parser(settings.webhooks.webhookTime)
|
|
||||||
job = JOB_STORE.get("webhooks")
|
|
||||||
|
|
||||||
scheduler.reschedule_job(
|
for group in all_groups:
|
||||||
job.scheduled_task.id,
|
|
||||||
trigger="cron",
|
time = cron_parser(group.webhook_time)
|
||||||
hour=time.hours,
|
job = JOB_STORE.get(group.name)
|
||||||
minute=time.minutes,
|
|
||||||
)
|
scheduler.reschedule_job(
|
||||||
|
job.scheduled_task.id,
|
||||||
|
trigger="cron",
|
||||||
|
hour=time.hours,
|
||||||
|
minute=time.minutes,
|
||||||
|
)
|
||||||
|
|
||||||
session.close()
|
session.close()
|
||||||
logger.info(scheduler.print_jobs())
|
logger.info(scheduler.print_jobs())
|
||||||
|
@ -34,7 +37,12 @@ def update_webhook_schedule():
|
||||||
|
|
||||||
class ScheduledFunction:
|
class ScheduledFunction:
|
||||||
def __init__(
|
def __init__(
|
||||||
self, scheduler: BackgroundScheduler, function, cron: Cron, name: str
|
self,
|
||||||
|
scheduler: BackgroundScheduler,
|
||||||
|
function,
|
||||||
|
cron: Cron,
|
||||||
|
name: str,
|
||||||
|
args: list = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.scheduled_task = scheduler.add_job(
|
self.scheduled_task = scheduler.add_job(
|
||||||
function,
|
function,
|
||||||
|
@ -44,6 +52,7 @@ class ScheduledFunction:
|
||||||
minute=cron.minutes,
|
minute=cron.minutes,
|
||||||
max_instances=1,
|
max_instances=1,
|
||||||
replace_existing=True,
|
replace_existing=True,
|
||||||
|
args=args,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info("New Function Scheduled")
|
logger.info("New Function Scheduled")
|
||||||
|
@ -56,9 +65,35 @@ JOB_STORE = {
|
||||||
"backup_job": ScheduledFunction(
|
"backup_job": ScheduledFunction(
|
||||||
scheduler, auto_backup_job, Cron(hours=00, minutes=00), "backups"
|
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()
|
scheduler.start()
|
||||||
|
|
|
@ -1,23 +1,35 @@
|
||||||
import json
|
import json
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from db.database import db
|
from db.database import db
|
||||||
from db.db_setup import create_session
|
from db.db_setup import create_session
|
||||||
from schema.settings import SiteSettings
|
from schema.meal import MealOut, MealPlanInDB
|
||||||
from services.meal_services import get_todays_meal
|
from schema.user import GroupInDB
|
||||||
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
|
|
||||||
def post_webhooks():
|
def post_webhooks(group: int, session: Session = None):
|
||||||
session = create_session()
|
session = session if session else create_session()
|
||||||
all_settings = db.get(session, 1)
|
group_settings: GroupInDB = db.groups.get(session, group)
|
||||||
all_settings = SiteSettings(**all_settings)
|
|
||||||
|
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)
|
todays_meal = db.recipes.get(session, today_slug)
|
||||||
urls = all_settings.webhooks.webhookURLs
|
|
||||||
|
|
||||||
for url in urls:
|
for url in group_settings.webhook_urls:
|
||||||
requests.post(url, json.dumps(todays_meal, default=str))
|
requests.post(url, json=todays_meal.json())
|
||||||
|
|
||||||
session.close()
|
session.close()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue