diff --git a/app/classes/models/management.py b/app/classes/models/management.py index f7dbf81c..6c6c520c 100644 --- a/app/classes/models/management.py +++ b/app/classes/models/management.py @@ -113,6 +113,7 @@ class Schedules(Model): command = CharField(null=True) comment = CharField() one_time = BooleanField(default=False) + cron_string = CharField(default="") class Meta: table_name = 'schedules' @@ -206,7 +207,7 @@ class helpers_management: # Schedules Methods #************************************************************************************************ @staticmethod - def create_scheduled_task(server_id, action, interval, interval_type, start_time, command, comment=None, enabled=True, one_time=False): + def create_scheduled_task(server_id, action, interval, interval_type, start_time, command, comment=None, enabled=True, one_time=False, cron_string='* * * * *'): sch_id = Schedules.insert({ Schedules.server_id: server_id, Schedules.action: action, @@ -216,7 +217,9 @@ class helpers_management: Schedules.start_time: start_time, Schedules.command: command, Schedules.comment: comment, - Schedules.one_time: one_time + Schedules.one_time: one_time, + Schedules.cron_string: cron_string + }).execute() return sch_id diff --git a/app/classes/shared/tasks.py b/app/classes/shared/tasks.py index 772d2b89..65537d14 100644 --- a/app/classes/shared/tasks.py +++ b/app/classes/shared/tasks.py @@ -9,6 +9,7 @@ import asyncio import shutil from schedule import Scheduler from tzlocal import get_localzone +import tzlocal from pytz import HOUR, timezone from app.classes.controllers.users_controller import Users_Controller @@ -54,7 +55,7 @@ class TasksManager: self.controller = controller self.tornado = Webserver(controller, self) - self.scheduler = BackgroundScheduler() + self.scheduler = BackgroundScheduler(timezone=str(tzlocal.get_localzone())) self.users_controller = Users_Controller() @@ -163,33 +164,39 @@ class TasksManager: def scheduler_thread(self): schedules = management_helper.get_schedules_enabled() - tz = get_localzone() - self.scheduler.configure(timezone=tz) self.scheduler.add_listener(self.schedule_watcher, mask=EVENT_JOB_EXECUTED) #self.scheduler.add_job(self.scheduler.print_jobs, 'interval', seconds=10, id='-1') #load schedules from DB for schedule in schedules: - if schedule.interval_type == 'hours': - self.scheduler.add_job(management_helper.add_command, 'cron', minute = 0, hour = '*/'+str(schedule.interval), id=str(schedule.schedule_id), args=[schedule.server_id, self.users_controller.get_id_by_name('system'), '127.0.0.1', schedule.command]) - elif schedule.interval_type == 'minutes': - self.scheduler.add_job(management_helper.add_command, 'cron', minute = '*/'+str(schedule.interval), id=str(schedule.schedule_id), args=[schedule.server_id, self.users_controller.get_id_by_name('system'), '127.0.0.1', schedule.command]) - elif schedule.interval_type == 'days': - time = schedule.start_time.split(':') - self.scheduler.add_job(management_helper.add_command, 'cron', day = '*/'+str(schedule.interval), hour=time[0], minute=time[1], id=str(schedule.schedule_id), args=[schedule.server_id, self.users_controller.get_id_by_name('system'), '127.0.0.1', schedule.command]) + if schedule.cron_string != "": + cron = schedule.cron_string.split(' ') + self.scheduler.add_job(management_helper.add_command, 'cron', minute = cron[0], hour = cron[1], day = cron[2], month = cron[3], day_of_week = cron[4], id=str(schedule.schedule_id), args=[schedule.server_id, self.users_controller.get_id_by_name('system'), '127.0.0.1', schedule.command]) + else: + if schedule.interval_type == 'hours': + self.scheduler.add_job(management_helper.add_command, 'cron', minute = 0, hour = '*/'+str(schedule.interval), id=str(schedule.schedule_id), args=[schedule.server_id, self.users_controller.get_id_by_name('system'), '127.0.0.1', schedule.command]) + elif schedule.interval_type == 'minutes': + self.scheduler.add_job(management_helper.add_command, 'cron', minute = '*/'+str(schedule.interval), id=str(schedule.schedule_id), args=[schedule.server_id, self.users_controller.get_id_by_name('system'), '127.0.0.1', schedule.command]) + elif schedule.interval_type == 'days': + time = schedule.start_time.split(':') + self.scheduler.add_job(management_helper.add_command, 'cron', day = '*/'+str(schedule.interval), hour=time[0], minute=time[1], id=str(schedule.schedule_id), args=[schedule.server_id, self.users_controller.get_id_by_name('system'), '127.0.0.1', schedule.command]) 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'], "None", job_data['enabled'], job_data['one_time']) + 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'], "None", job_data['enabled'], job_data['one_time'], job_data['cron_string']) if job_data['enabled']: - if job_data['interval_type'] == 'hours': - self.scheduler.add_job(management_helper.add_command, 'cron', minute = 0, hour = '*/'+str(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, 'cron', minute = '*/'+str(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': - time = job_data['time'].split(':') - self.scheduler.add_job(management_helper.add_command, 'cron', day = '*/'+str(job_data['interval']), hour = time[0], minute = time[1], id=str(sch_id), args=[job_data['server_id'], self.users_controller.get_id_by_name('system'), '127.0.0.1', job_data['command']], ) + if job_data['cron_string'] != "": + cron = job_data['cron_string'].split(' ') + self.scheduler.add_job(management_helper.add_command, 'cron', minute = cron[0], hour = cron[1], day = cron[2], month = cron[3], day_of_week = cron[4], id=str(sch_id), args=[job_data['server_id'], self.users_controller.get_id_by_name('system'), '127.0.0.1', job_data['command']]) + else: + if job_data['interval_type'] == 'hours': + self.scheduler.add_job(management_helper.add_command, 'cron', minute = 0, hour = '*/'+str(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, 'cron', minute = '*/'+str(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': + time = job_data['time'].split(':') + self.scheduler.add_job(management_helper.add_command, 'cron', day = '*/'+str(job_data['interval']), hour = time[0], minute = time[1], 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) diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 4b653bc1..9dc137d6 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -859,7 +859,10 @@ class PanelHandler(BaseHandler): elif action == "backup": command = "backup_server" else: + interval_type = '' cron_string = bleach.clean(self.get_argument('cron', '')) + if len(cron_string.split(' ')) != 5: + self.redirect("/panel/error?error=INVALID FORMAT: Invalid Cron Format. Cron must have a space between each character and only have a max of 5 characters * * * * *") action = bleach.clean(self.get_argument('action', None)) if action == "command": command = bleach.clean(self.get_argument('command', None)) @@ -891,6 +894,13 @@ class PanelHandler(BaseHandler): if not self.controller.servers.server_id_exists(server_id): self.redirect("/panel/error?error=Invalid Server ID") return + minute = datetime.datetime.now().minute + hour = datetime.datetime.now().hour + if minute < 10: + minute = '0' + str(minute) + if hour < 10: + hour = '0'+str(hour) + current_time = str(hour)+':'+str(minute) if interval_type == "days": job_data = { @@ -901,12 +911,17 @@ class PanelHandler(BaseHandler): "command": command, "time": time, "enabled": enabled, - "one_time": one_time + "one_time": one_time, + "cron_string": '' } elif difficulty == "advanced": job_data = { "server_id": server_id, "action": action, + "interval_type": '', + "interval": '', + "command": '', + "time": current_time, "command": command, "cron_string": cron_string, "enabled": enabled, @@ -920,8 +935,9 @@ class PanelHandler(BaseHandler): "interval": interval, "command": command, "enabled": enabled, - "time": '00:00', - "one_time": one_time + "time": current_time, + "one_time": one_time, + "cron_string": '' } self.tasks_manager.schedule_job(job_data) diff --git a/app/frontend/templates/panel/server_tasks.html b/app/frontend/templates/panel/server_tasks.html index af108d37..b6d6f14f 100644 --- a/app/frontend/templates/panel/server_tasks.html +++ b/app/frontend/templates/panel/server_tasks.html @@ -35,79 +35,8 @@ {% include "parts/server_controls_list.html %}
-
-
- {% raw xsrf_form_html() %} - - - -
-
- -
-
-
- -
-
-
- - -
-
- -
- -
- - -
-
- - - -
- - -
-
- - -
- - - -
-
- -
+Create Task +

Scheduled Tasks

@@ -115,6 +44,7 @@ Action + Command Interval Start Time Enabled @@ -127,9 +57,17 @@

{{schedule.action}}

+ +

{{schedule.command}}

+ + {% if schedule.interval != '' %}

Every

{{schedule.interval}} {{schedule.interval_type}}

+ {% else %} +

Cron String:

+

{{schedule.cron_string}}

+ {% end %}

{{schedule.start_time}}

@@ -194,19 +132,34 @@ function yesnoCheck(that) { if (that.value == "command") { document.getElementById("ifYes").style.display = "block"; + document.getElementById("command").required = true; } else { document.getElementById("ifYes").style.display = "none"; + document.getElementById("command").required = false; } } function basicAdvanced(that) { if (that.value == "advanced") { document.getElementById("ifAdvanced").style.display = "block"; document.getElementById("ifBasic").style.display = "none"; + document.getElementById("interval").required = false; + document.getElementById("time").required = false; } else { document.getElementById("ifAdvanced").style.display = "none"; document.getElementById("ifBasic").style.display = "block"; + document.getElementById("interval").required = true; + document.getElementById("time").required = true; } } +function ifDays(that) { + if (that.value == "days") { + document.getElementById("ifDays").style.display = "block"; + document.getElementById("time").required = true; + } else { + document.getElementById("ifDays").style.display = "none"; + document.getElementById("time").required = false; + } +} $( ".del_button" ).click(function() { var sch_id = $(this).data('sch'); diff --git a/app/frontend/templates/panel/server_tasks_edit.html b/app/frontend/templates/panel/server_tasks_edit.html new file mode 100644 index 00000000..32372228 --- /dev/null +++ b/app/frontend/templates/panel/server_tasks_edit.html @@ -0,0 +1,215 @@ +{% extends ../base.html %} + +{% block meta %} + +{% end %} + +{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %} + +{% block content %} + +
+ + +
+
+ +
+ +
+ + + {% include "parts/details_stats.html %} + +
+ +
+
+
+ {% include "parts/server_controls_list.html %} + +
+
+
+ {% raw xsrf_form_html() %} + + + +
+
+ +
+
+
+ +
+
+
+ + +
+
+ +
+
+
+ + +
+
+
+ + + +
+ + +
+
+ + +
+ + + +
+
+ +
+
+
+
+ + + +
+ + +{% end %} + +{% block js %} + + +{% end %} \ No newline at end of file diff --git a/app/migrations/20210915205501_cron_task.py b/app/migrations/20210915205501_cron_task.py new file mode 100644 index 00000000..62767240 --- /dev/null +++ b/app/migrations/20210915205501_cron_task.py @@ -0,0 +1,16 @@ +# Generated by database migrator +import peewee + +def migrate(migrator, database, **kwargs): + migrator.add_columns('schedules', cron_string=peewee.CharField(default="")) + """ + Write your migrations here. + """ + + + +def rollback(migrator, database, **kwargs): + migrator.drop_columns('schedules', ['cron_string']) + """ + Write your rollback migrations here. + """