From 139b5065547bad4a0a3e36069ff429ff600acbfb Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 10 Jan 2022 20:11:52 -0500 Subject: [PATCH] Inital APScheduler code for integration with our SQLite DB in progress. Adding commands works with start/stop/restart --- app/classes/shared/tasks.py | 53 ++++++++++-- app/classes/web/panel_handler.py | 80 +++++++++++++++++++ .../templates/panel/server_tasks.html | 21 +++-- 3 files changed, 141 insertions(+), 13 deletions(-) diff --git a/app/classes/shared/tasks.py b/app/classes/shared/tasks.py index 46391226..97e43f3b 100644 --- a/app/classes/shared/tasks.py +++ b/app/classes/shared/tasks.py @@ -1,3 +1,4 @@ +from datetime import timedelta import os import sys import json @@ -6,6 +7,11 @@ import logging import threading import asyncio import shutil +from schedule import Scheduler +from tzlocal import get_localzone + +from pytz import HOUR, timezone +from app.classes.controllers.users_controller import Users_Controller from app.classes.shared.helpers import helper from app.classes.shared.console import console @@ -15,6 +21,8 @@ from app.classes.web.websocket_helper import websocket_helper from app.classes.minecraft.serverjars import server_jar_obj from app.classes.models.servers import servers_helper from app.classes.models.management import management_helper +from apscheduler.schedulers.background import BackgroundScheduler +from apscheduler.events import EVENT_JOB_ERROR, EVENT_JOB_EXECUTED, EVENT_ALL, EVENT_JOB_REMOVED logger = logging.getLogger(__name__) @@ -46,6 +54,10 @@ class TasksManager: self.controller = controller self.tornado = Webserver(controller, self) + self.scheduler = BackgroundScheduler() + + self.users_controller = Users_Controller() + self.webserver_thread = threading.Thread(target=self.tornado.run_tornado, daemon=True, name='tornado_thread') self.main_thread_exiting = False @@ -147,11 +159,42 @@ class TasksManager: console.info("Launching realtime thread...") self.realtime_thread.start() - @staticmethod - def scheduler_thread(): - while True: - schedule.run_pending() - time.sleep(1) + def scheduler_thread(self): + tz = get_localzone() + self.scheduler.configure(timezone=tz) + self.scheduler.add_listener(self.schedule_watcher, mask=EVENT_ALL) + self.scheduler.add_job(self.scheduler.print_jobs, 'interval', seconds=10, id='1225') + self.scheduler.start() + + + def schedule_job(self, job_data): + sch_id = management_helper.create_scheduled_task(job_data['server_id'], job_data['action'], job_data['interval'], job_data['interval_type'], job_data['time'], job_data['command'], job_data['enabled']) + if job_data['enabled']: + if job_data['interval_type'] == 'hours': + self.scheduler.add_job(management_helper.add_command, 'interval', hours = int(job_data['interval']), id=str(sch_id), args=[job_data['server_id'], self.users_controller.get_id_by_name('system'), '127.0.0.1', job_data['command']]) + elif job_data['interval_type'] == 'minutes': + self.scheduler.add_job(management_helper.add_command, 'interval', minutes = int(job_data['interval']), id=str(sch_id), args=[job_data['server_id'], self.users_controller.get_id_by_name('system'), '127.0.0.1', job_data['command']]) + elif job_data['interval_type'] == 'seconds': + self.scheduler.add_job(management_helper.add_command, 'interval', seconds = int(job_data['interval']), id=str(sch_id), args=[job_data['server_id'], self.users_controller.get_id_by_name('system'), '127.0.0.1', job_data['command']]) + elif job_data['interval_type'] == 'days': + self.scheduler.add_job(management_helper.add_command, 'interval', days = int(job_data['interval']), start_date = timedelta(job_data['time']), id=str(sch_id), args=[job_data['server_id'], self.users_controller.get_id_by_name('system'), '127.0.0.1', job_data['command']], ) + + def remove_job(self, sch_id): + management_helper.delete_scheduled_task(sch_id) + self.scheduler.remove_job(str(sch_id)) + + def update_job(self): + management_helper.update_scheduled_task() + + def schedule_watcher(self, event): + if not event.exception: + print(event.job_id, event.code) + job = self.scheduler.get_job(event.job_id) + trigger = job.trigger + if trigger.interval: + print(trigger.interval) + else: + print('well that failed') def start_stats_recording(self): stats_update_frequency = helper.get_setting('stats_update_frequency') diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 428e21f8..5d35bdb8 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -839,6 +839,86 @@ class PanelHandler(BaseHandler): self.tasks_manager.reload_schedule_from_db() self.redirect("/panel/server_detail?id={}&subpage=backup".format(server_id)) + + if page == "tasks": + server_id = self.get_argument('id', None) + difficulty = self.get_argument('difficulty', None) + server_obj = self.controller.servers.get_server_obj(server_id) + enabled = self.get_argument('enabled', '0') + if difficulty == 'basic': + action = self.get_argument('action', None) + interval = self.get_argument('interval', None) + interval_type = self.get_argument('interval_type', None) + #only check for time if it's number of days + if interval_type == "days": + time = self.get_argument('time', None) + if action == "command": + command = self.get_argument('command', None) + elif action == "start": + command = "start_server" + elif action == "stop": + command = "stop_server" + elif action == "restart": + command = "restar_server" + + if self.get_argument('enabled', '1'): + enabled = True + else: + enabled = False + if self.get_argument('one_time', '0'): + one_time = True + else: + one_time = False + + + if not exec_user['superuser'] and not permissions['Backup'] in user_perms: + self.redirect("/panel/error?error=Unauthorized access: User not authorized") + return + elif server_id is None: + self.redirect("/panel/error?error=Invalid Server ID") + return + else: + # does this server id exist? + if not self.controller.servers.server_id_exists(server_id): + self.redirect("/panel/error?error=Invalid Server ID") + return + + if interval_type == "days": + print("in job data") + job_data = { + "server_id": server_id, + "action": action, + "interval_type": interval_type, + "interval": interval, + "command": command, + "time": time, + "enabled": enabled, + "one_time": one_time + } + else: + print("in job data") + job_data = { + "server_id": server_id, + "action": action, + "interval_type": interval_type, + "interval": interval, + "command": command, + "enabled": enabled, + "time": '00:00', + "one_time": one_time + } + print(job_data['time']) + + self.tasks_manager.schedule_job(job_data) + + self.controller.management.add_to_audit_log(exec_user['user_id'], + "Edited server {}: updated backups".format(server_id), + server_id, + self.get_remote_ip()) + self.tasks_manager.reload_schedule_from_db() + self.redirect("/panel/server_detail?id={}&subpage=tasks".format(server_id)) + + elif page == "edit_user": if bleach.clean(self.get_argument('username', None)) == 'system': self.redirect("/panel/error?error=Unauthorized access: system user is not editable") diff --git a/app/frontend/templates/panel/server_tasks.html b/app/frontend/templates/panel/server_tasks.html index a345b135..5d152ad5 100644 --- a/app/frontend/templates/panel/server_tasks.html +++ b/app/frontend/templates/panel/server_tasks.html @@ -36,14 +36,14 @@
-
+ {% raw xsrf_form_html() %}
-
- @@ -61,7 +61,7 @@
- +

+
@@ -113,6 +113,7 @@

Scheduled Tasks

+ @@ -120,7 +121,10 @@ + + {% for schedule in data['schedules'] %} + @@ -146,8 +150,9 @@ - + {% end %} +
Action IntervalEnabled Edit

{{schedule.action}}