multi group supporot for job scheduler

This commit is contained in:
hay-kot 2021-03-14 18:44:02 -08:00
commit 3f96961e35
6 changed files with 100 additions and 36 deletions

View file

@ -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)

View file

@ -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

View 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

View file

@ -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

View file

@ -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()

View file

@ -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()