fixed broken scheduler

This commit is contained in:
hayden 2021-01-28 17:33:21 -09:00
commit 6bc533cf70
11 changed files with 113 additions and 94 deletions

View file

@ -12,7 +12,7 @@
</v-col> </v-col>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-col align="end"> <v-col align="end">
<v-menu offset-y> <v-menu offset-y v-if="sortable">
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn-toggle group> <v-btn-toggle group>
<v-btn text v-bind="attrs" v-on="on"> Sort </v-btn> <v-btn text v-bind="attrs" v-on="on"> Sort </v-btn>
@ -59,6 +59,9 @@ export default {
RecipeCard, RecipeCard,
}, },
props: { props: {
sortable: {
default: false,
},
title: String, title: String,
recipes: Array, recipes: Array,
cardLimit: { cardLimit: {

View file

@ -7,6 +7,7 @@
:card-limit="pageSettings.showLimit" :card-limit="pageSettings.showLimit"
/> />
<CardSection <CardSection
:sortable="true"
v-for="(section, index) in recipeByCategory" v-for="(section, index) in recipeByCategory"
:key="index" :key="index"
:title="section.title" :title="section.title"
@ -54,13 +55,11 @@ export default {
this.recipeByCategory[index].recipes.sort((a, b) => this.recipeByCategory[index].recipes.sort((a, b) =>
a.name > b.name ? 1 : -1 a.name > b.name ? 1 : -1
); );
console.log(this.recipeByCategory[index].recipes);
}, },
sortRecent(index) { sortRecent(index) {
this.recipeByCategory[index].recipes.sort((a, b) => this.recipeByCategory[index].recipes.sort((a, b) =>
a.dateAdded > b.dateAdded ? -1 : 1 a.dateAdded > b.dateAdded ? -1 : 1
); );
console.log(this.recipeByCategory[index].recipes);
}, },
}, },
}; };

View file

@ -14,7 +14,7 @@ from routes import (
user_routes, user_routes,
) )
# from utils.api_docs import generate_api_docs from utils.api_docs import generate_api_docs
from utils.logger import logger from utils.logger import logger
app = FastAPI( app = FastAPI(
@ -46,6 +46,11 @@ if PRODUCTION:
api_routers() api_routers()
def start_scheduler():
import services.scheduler.scheduled_jobs
# API 404 Catch all CALL AFTER ROUTERS # API 404 Catch all CALL AFTER ROUTERS
@app.get("/api/{full_path:path}", status_code=404, include_in_schema=False) @app.get("/api/{full_path:path}", status_code=404, include_in_schema=False)
def invalid_api(): def invalid_api():
@ -56,8 +61,10 @@ app.include_router(static_routes.router)
# Generate API Documentation # Generate API Documentation
# if not PRODUCTION: if not PRODUCTION:
# generate_api_docs(app) generate_api_docs(app)
start_scheduler()
if __name__ == "__main__": if __name__ == "__main__":
logger.info("-----SYSTEM STARTUP-----") logger.info("-----SYSTEM STARTUP-----")

View file

@ -1,9 +1,8 @@
from db.db_setup import generate_session from db.db_setup import generate_session
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from services.scheduler_services import post_webhooks
from services.settings_services import SiteSettings, SiteTheme from services.settings_services import SiteSettings, SiteTheme
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from utils.global_scheduler import scheduler from utils.post_webhooks import post_webhooks
from utils.snackbar import SnackResponse from utils.snackbar import SnackResponse
router = APIRouter(tags=["Settings"]) router = APIRouter(tags=["Settings"])
@ -34,7 +33,6 @@ def update_settings(data: SiteSettings, db: Session = Depends(generate_session))
# status_code=400, detail=SnackResponse.error("Unable to Save Settings") # status_code=400, detail=SnackResponse.error("Unable to Save Settings")
# ) # )
# scheduler.reschedule_webhooks() #! Need to fix Scheduler
return SnackResponse.success("Settings Updated") return SnackResponse.success("Settings Updated")

View file

@ -0,0 +1,3 @@
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()

View file

@ -0,0 +1,62 @@
from apscheduler.schedulers.background import BackgroundScheduler
from db.db_setup import create_session
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 services.settings_services import SiteSettings
from utils.logger import logger
from utils.post_webhooks import post_webhooks
@scheduler.scheduled_job(trigger="interval", minutes=15)
def update_webhook_schedule():
"""
A scheduled background job that runs every 15 minutes to
poll the database for changes and reschedule the webhook time
"""
session = create_session()
settings = SiteSettings.get_site_settings(session=session)
time = cron_parser(settings.webhooks.webhookTime)
job = JOB_STORE.get("webhooks")
scheduler.reschedule_job(
job.scheduled_task.id,
trigger="cron",
hour=time.hours,
minute=time.minutes,
)
session.close()
logger.info(scheduler.print_jobs())
class ScheduledFunction:
def __init__(
self, scheduler: BackgroundScheduler, function, cron: Cron, name: str
) -> None:
self.scheduled_task = scheduler.add_job(
function,
trigger="cron",
name=name,
hour=cron.hours,
minute=cron.minutes,
max_instances=1,
replace_existing=True,
)
logger.info("New Function Scheduled")
logger.info(scheduler.print_jobs())
logger.info("----INIT SCHEDULE OBJECT-----")
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"
),
}
scheduler.start()

View file

@ -0,0 +1,10 @@
import collections
Cron = collections.namedtuple("Cron", "hours minutes")
def cron_parser(time_str: str) -> Cron:
time = time_str.split(":")
cron = Cron(hours=int(time[0]), minutes=int(time[1]))
return cron

View file

@ -1,73 +0,0 @@
import collections
import json
import requests
from apscheduler.schedulers.background import BackgroundScheduler
from db.db_setup import create_session
from utils.logger import logger
from services.backups.exports import auto_backup_job
from services.meal_services import MealPlan
from services.recipe_services import Recipe
from services.settings_services import SiteSettings
Cron = collections.namedtuple("Cron", "hours minutes")
def cron_parser(time_str: str) -> Cron:
time = time_str.split(":")
cron = Cron(hours=int(time[0]), minutes=int(time[1]))
return cron
def post_webhooks():
all_settings = SiteSettings.get_site_settings()
if all_settings.webhooks.enabled:
todays_meal = Recipe.get_by_slug(MealPlan.today()).dict()
urls = all_settings.webhooks.webhookURLs
for url in urls:
requests.post(url, json.dumps(todays_meal, default=str))
class Scheduler:
def startup_scheduler(self):
self.scheduler = BackgroundScheduler()
logger.info("----INIT SCHEDULE OBJECT-----")
self.scheduler.start()
self.scheduler.add_job(
auto_backup_job, trigger="cron", hour="3", max_instances=1
)
settings = SiteSettings.get_site_settings(create_session())
time = cron_parser(settings.webhooks.webhookTime)
self.webhook = self.scheduler.add_job(
post_webhooks,
trigger="cron",
name="webhooks",
hour=time.hours,
minute=time.minutes,
max_instances=1,
)
logger.info(self.scheduler.print_jobs())
def reschedule_webhooks(self):
"""
Reads the site settings database entry to reschedule the webhooks task
Called after each post to the webhooks endpoint.
"""
settings = SiteSettings.get_site_settings()
time = cron_parser(settings.webhooks.webhookTime)
self.scheduler.reschedule_job(
self.webhook.id,
trigger="cron",
hour=time.hours,
minute=time.minutes,
)
logger.info(self.scheduler.print_jobs())

View file

@ -1,7 +1,7 @@
from typing import List, Optional from typing import List, Optional
from db.database import db from db.database import db
from db.db_setup import create_session, generate_session, sql_exists from db.db_setup import create_session, sql_exists
from pydantic import BaseModel from pydantic import BaseModel
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from utils.logger import logger from utils.logger import logger

View file

@ -1,11 +0,0 @@
from services.scheduler_services import Scheduler
def start_scheduler():
global scheduler
scheduler = Scheduler()
scheduler.startup_scheduler()
return scheduler
scheduler = start_scheduler

View file

@ -0,0 +1,21 @@
import json
import requests
from db.db_setup import create_session
from services.meal_services import MealPlan
from services.recipe_services import Recipe
from services.settings_services import SiteSettings
def post_webhooks():
session = create_session()
all_settings = SiteSettings.get_site_settings(session)
if all_settings.webhooks.enabled:
todays_meal = Recipe.get_by_slug(MealPlan.today()).dict()
urls = all_settings.webhooks.webhookURLs
for url in urls:
requests.post(url, json.dumps(todays_meal, default=str))
session.close()