diff --git a/frontend/src/components/UI/CardSection.vue b/frontend/src/components/UI/CardSection.vue
index a1d62564f..08614f03d 100644
--- a/frontend/src/components/UI/CardSection.vue
+++ b/frontend/src/components/UI/CardSection.vue
@@ -12,7 +12,7 @@
-
+
Sort
@@ -59,6 +59,9 @@ export default {
RecipeCard,
},
props: {
+ sortable: {
+ default: false,
+ },
title: String,
recipes: Array,
cardLimit: {
diff --git a/frontend/src/pages/HomePage.vue b/frontend/src/pages/HomePage.vue
index 4c7572c85..9a9589e7f 100644
--- a/frontend/src/pages/HomePage.vue
+++ b/frontend/src/pages/HomePage.vue
@@ -7,6 +7,7 @@
:card-limit="pageSettings.showLimit"
/>
a.name > b.name ? 1 : -1
);
- console.log(this.recipeByCategory[index].recipes);
},
sortRecent(index) {
this.recipeByCategory[index].recipes.sort((a, b) =>
a.dateAdded > b.dateAdded ? -1 : 1
);
- console.log(this.recipeByCategory[index].recipes);
},
},
};
diff --git a/mealie/app.py b/mealie/app.py
index 62f1769fa..6cc299602 100644
--- a/mealie/app.py
+++ b/mealie/app.py
@@ -14,7 +14,7 @@ from routes import (
user_routes,
)
-# from utils.api_docs import generate_api_docs
+from utils.api_docs import generate_api_docs
from utils.logger import logger
app = FastAPI(
@@ -46,6 +46,11 @@ if PRODUCTION:
api_routers()
+
+def start_scheduler():
+ import services.scheduler.scheduled_jobs
+
+
# API 404 Catch all CALL AFTER ROUTERS
@app.get("/api/{full_path:path}", status_code=404, include_in_schema=False)
def invalid_api():
@@ -56,8 +61,10 @@ app.include_router(static_routes.router)
# Generate API Documentation
-# if not PRODUCTION:
-# generate_api_docs(app)
+if not PRODUCTION:
+ generate_api_docs(app)
+
+start_scheduler()
if __name__ == "__main__":
logger.info("-----SYSTEM STARTUP-----")
diff --git a/mealie/routes/setting_routes.py b/mealie/routes/setting_routes.py
index 0763bc74a..0c3249787 100644
--- a/mealie/routes/setting_routes.py
+++ b/mealie/routes/setting_routes.py
@@ -1,9 +1,8 @@
from db.db_setup import generate_session
from fastapi import APIRouter, Depends, HTTPException
-from services.scheduler_services import post_webhooks
from services.settings_services import SiteSettings, SiteTheme
from sqlalchemy.orm.session import Session
-from utils.global_scheduler import scheduler
+from utils.post_webhooks import post_webhooks
from utils.snackbar import SnackResponse
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")
# )
- # scheduler.reschedule_webhooks() #! Need to fix Scheduler
return SnackResponse.success("Settings Updated")
diff --git a/mealie/services/scheduler/global_scheduler.py b/mealie/services/scheduler/global_scheduler.py
new file mode 100644
index 000000000..cffbf8e7a
--- /dev/null
+++ b/mealie/services/scheduler/global_scheduler.py
@@ -0,0 +1,3 @@
+from apscheduler.schedulers.background import BackgroundScheduler
+
+scheduler = BackgroundScheduler()
\ No newline at end of file
diff --git a/mealie/services/scheduler/scheduled_jobs.py b/mealie/services/scheduler/scheduled_jobs.py
new file mode 100644
index 000000000..b273a8446
--- /dev/null
+++ b/mealie/services/scheduler/scheduled_jobs.py
@@ -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()
diff --git a/mealie/services/scheduler/scheduler_utils.py b/mealie/services/scheduler/scheduler_utils.py
new file mode 100644
index 000000000..eb6240f4a
--- /dev/null
+++ b/mealie/services/scheduler/scheduler_utils.py
@@ -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
diff --git a/mealie/services/scheduler_services.py b/mealie/services/scheduler_services.py
deleted file mode 100644
index 96aa49d42..000000000
--- a/mealie/services/scheduler_services.py
+++ /dev/null
@@ -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())
diff --git a/mealie/services/settings_services.py b/mealie/services/settings_services.py
index 2f5b9323e..3e3c8398e 100644
--- a/mealie/services/settings_services.py
+++ b/mealie/services/settings_services.py
@@ -1,7 +1,7 @@
from typing import List, Optional
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 sqlalchemy.orm.session import Session
from utils.logger import logger
diff --git a/mealie/utils/global_scheduler.py b/mealie/utils/global_scheduler.py
deleted file mode 100644
index 9b30ebb2e..000000000
--- a/mealie/utils/global_scheduler.py
+++ /dev/null
@@ -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
diff --git a/mealie/utils/post_webhooks.py b/mealie/utils/post_webhooks.py
new file mode 100644
index 000000000..56bbedc33
--- /dev/null
+++ b/mealie/utils/post_webhooks.py
@@ -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()