mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'enhancement/pretzel-next-run' into 'dev'
Add next run to schedule info See merge request crafty-controller/crafty-4!417
This commit is contained in:
commit
bc8ec179a1
@ -10,7 +10,7 @@ TBD
|
||||
- Fix server creation with serverjars API ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/415))
|
||||
- Fix API Key delete confirmations ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/416))
|
||||
### Tweaks
|
||||
TBD
|
||||
- Add next run to schedule info ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/417))
|
||||
### Lang
|
||||
- Updated `es_ES` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/412))
|
||||
- Added `pl_PL` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/412))
|
||||
|
@ -115,6 +115,7 @@ class Schedules(BaseModel):
|
||||
cron_string = CharField(default="")
|
||||
parent = IntegerField(null=True)
|
||||
delay = IntegerField(default=0)
|
||||
next_run = CharField(default="")
|
||||
|
||||
class Meta:
|
||||
table_name = "schedules"
|
||||
@ -285,6 +286,7 @@ class HelpersManagement:
|
||||
Schedules.cron_string: cron_string,
|
||||
Schedules.parent: parent,
|
||||
Schedules.delay: delay,
|
||||
Schedules.next_run: "",
|
||||
}
|
||||
).execute()
|
||||
return sch_id
|
||||
|
@ -192,6 +192,7 @@ class TasksManager:
|
||||
def scheduler_thread(self):
|
||||
schedules = HelpersManagement.get_schedules_enabled()
|
||||
self.scheduler.add_listener(self.schedule_watcher, mask=EVENT_JOB_EXECUTED)
|
||||
self.scheduler.start()
|
||||
# self.scheduler.add_job(
|
||||
# self.scheduler.print_jobs, "interval", seconds=10, id="-1"
|
||||
# )
|
||||
@ -201,7 +202,7 @@ class TasksManager:
|
||||
if schedule.interval != "reaction":
|
||||
if schedule.cron_string != "":
|
||||
try:
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
CronTrigger.from_crontab(
|
||||
schedule.cron_string, timezone=str(self.tz)
|
||||
@ -215,6 +216,7 @@ class TasksManager:
|
||||
],
|
||||
)
|
||||
except Exception as e:
|
||||
new_job = "error"
|
||||
Console.error(f"Failed to schedule task with error: {e}.")
|
||||
Console.warning("Removing failed task from DB.")
|
||||
logger.error(f"Failed to schedule task with error: {e}.")
|
||||
@ -225,7 +227,7 @@ class TasksManager:
|
||||
)
|
||||
else:
|
||||
if schedule.interval_type == "hours":
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
minute=0,
|
||||
@ -239,7 +241,7 @@ class TasksManager:
|
||||
],
|
||||
)
|
||||
elif schedule.interval_type == "minutes":
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
minute="*/" + str(schedule.interval),
|
||||
@ -253,7 +255,7 @@ class TasksManager:
|
||||
)
|
||||
elif schedule.interval_type == "days":
|
||||
curr_time = schedule.start_time.split(":")
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
day="*/" + str(schedule.interval),
|
||||
@ -267,7 +269,18 @@ class TasksManager:
|
||||
schedule.command,
|
||||
],
|
||||
)
|
||||
self.scheduler.start()
|
||||
if new_job != "error":
|
||||
task = self.controller.management.get_scheduled_task_model(
|
||||
int(new_job.id)
|
||||
)
|
||||
self.controller.management.update_scheduled_task(
|
||||
task.schedule_id,
|
||||
{
|
||||
"next_run": str(
|
||||
new_job.next_run_time.strftime("%m/%d/%Y, %H:%M:%S")
|
||||
)
|
||||
},
|
||||
)
|
||||
jobs = self.scheduler.get_jobs()
|
||||
logger.info("Loaded schedules. Current enabled schedules: ")
|
||||
for item in jobs:
|
||||
@ -298,7 +311,7 @@ class TasksManager:
|
||||
if job_data["enabled"] and job_data["interval_type"] != "reaction":
|
||||
if job_data["cron_string"] != "":
|
||||
try:
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
CronTrigger.from_crontab(
|
||||
job_data["cron_string"], timezone=str(self.tz)
|
||||
@ -312,6 +325,7 @@ class TasksManager:
|
||||
],
|
||||
)
|
||||
except Exception as e:
|
||||
new_job = "error"
|
||||
Console.error(f"Failed to schedule task with error: {e}.")
|
||||
Console.warning("Removing failed task from DB.")
|
||||
logger.error(f"Failed to schedule task with error: {e}.")
|
||||
@ -320,7 +334,7 @@ class TasksManager:
|
||||
self.controller.management_helper.delete_scheduled_task(sch_id)
|
||||
else:
|
||||
if job_data["interval_type"] == "hours":
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
minute=0,
|
||||
@ -334,7 +348,7 @@ class TasksManager:
|
||||
],
|
||||
)
|
||||
elif job_data["interval_type"] == "minutes":
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
minute="*/" + str(job_data["interval"]),
|
||||
@ -348,7 +362,7 @@ class TasksManager:
|
||||
)
|
||||
elif job_data["interval_type"] == "days":
|
||||
curr_time = job_data["start_time"].split(":")
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
day="*/" + str(job_data["interval"]),
|
||||
@ -364,6 +378,14 @@ class TasksManager:
|
||||
)
|
||||
logger.info("Added job. Current enabled schedules: ")
|
||||
jobs = self.scheduler.get_jobs()
|
||||
if new_job != "error":
|
||||
task = self.controller.management.get_scheduled_task_model(
|
||||
int(new_job.id)
|
||||
)
|
||||
self.controller.management.update_scheduled_task(
|
||||
task.schedule_id,
|
||||
{"next_run": new_job.next_run_time.strftime("%m/%d/%Y, %H:%M:%S")},
|
||||
)
|
||||
for item in jobs:
|
||||
logger.info(f"JOB: {item}")
|
||||
|
||||
@ -418,7 +440,7 @@ class TasksManager:
|
||||
if job_data["enabled"] and job_data["interval"] != "reaction":
|
||||
if job_data["cron_string"] != "":
|
||||
try:
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
CronTrigger.from_crontab(
|
||||
job_data["cron_string"], timezone=str(self.tz)
|
||||
@ -432,12 +454,13 @@ class TasksManager:
|
||||
],
|
||||
)
|
||||
except Exception as e:
|
||||
new_job = "error"
|
||||
Console.error(f"Failed to schedule task with error: {e}.")
|
||||
Console.info("Removing failed task from DB.")
|
||||
self.controller.management_helper.delete_scheduled_task(sch_id)
|
||||
else:
|
||||
if job_data["interval_type"] == "hours":
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
minute=0,
|
||||
@ -451,7 +474,7 @@ class TasksManager:
|
||||
],
|
||||
)
|
||||
elif job_data["interval_type"] == "minutes":
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
minute="*/" + str(job_data["interval"]),
|
||||
@ -465,7 +488,7 @@ class TasksManager:
|
||||
)
|
||||
elif job_data["interval_type"] == "days":
|
||||
curr_time = job_data["start_time"].split(":")
|
||||
self.scheduler.add_job(
|
||||
new_job = self.scheduler.add_job(
|
||||
HelpersManagement.add_command,
|
||||
"cron",
|
||||
day="*/" + str(job_data["interval"]),
|
||||
@ -479,6 +502,14 @@ class TasksManager:
|
||||
job_data["command"],
|
||||
],
|
||||
)
|
||||
if new_job != "error":
|
||||
task = self.controller.management.get_scheduled_task_model(
|
||||
int(new_job.id)
|
||||
)
|
||||
self.controller.management.update_scheduled_task(
|
||||
task.schedule_id,
|
||||
{"next_run": new_job.next_run_time.strftime("%m/%d/%Y, %H:%M:%S")},
|
||||
)
|
||||
else:
|
||||
try:
|
||||
self.scheduler.get_job(str(sch_id))
|
||||
@ -506,6 +537,15 @@ class TasksManager:
|
||||
if task.one_time:
|
||||
self.remove_job(task.schedule_id)
|
||||
logger.info("one time task detected. Deleting...")
|
||||
else:
|
||||
self.controller.management.update_scheduled_task(
|
||||
task.schedule_id,
|
||||
{
|
||||
"next_run": self.scheduler.get_job(
|
||||
event.job_id
|
||||
).next_run_time.strftime("%m/%d/%Y, %H:%M:%S")
|
||||
},
|
||||
)
|
||||
# check for any child tasks for this. It's kind of backward,
|
||||
# but this makes DB management a lot easier. One to one
|
||||
# instead of one to many.
|
||||
|
@ -14,7 +14,8 @@
|
||||
<div class="col-12">
|
||||
<div class="page-header">
|
||||
<h4 class="page-title">
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{ data['server_stats']['server_id']['server_name'] }}
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
</h4>
|
||||
@ -46,23 +47,23 @@
|
||||
<h4 class="card-title"><i class="fas fa-calendar"></i> Scheduled Tasks</h4>
|
||||
{% if data['user_data']['hints'] %}
|
||||
<span class="too_small" title="{{ translate('serverSchedules', 'cannotSee', data['lang']) }}" ,
|
||||
data-content="{{ translate('serverSchedules', 'cannotSeeOnMobile', data['lang']) }}" ,
|
||||
data-placement="bottom"></span>
|
||||
data-content="{{ translate('serverSchedules', 'cannotSeeOnMobile', data['lang']) }}" ,
|
||||
data-placement="bottom"></span>
|
||||
{% end %}
|
||||
<div><button
|
||||
onclick="location.href=`/panel/add_schedule?id={{ data['server_stats']['server_id']['server_id'] }}`"
|
||||
class="btn btn-info">Create New Schedule <i class="fas fa-pencil-alt"></i></button></div>
|
||||
onclick="location.href=`/panel/add_schedule?id={{ data['server_stats']['server_id']['server_id'] }}`"
|
||||
class="btn btn-info">Create New Schedule <i class="fas fa-pencil-alt"></i></button></div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-hover d-none d-lg-block responsive-table" id="schedule_table" width="100%"
|
||||
style="table-layout:fixed;">
|
||||
style="table-layout:fixed;">
|
||||
<thead>
|
||||
<tr class="rounded">
|
||||
<th style="width: 2%; min-width: 10px;">ID</th>
|
||||
<th style="width: 23%; min-width: 50px;">Action</th>
|
||||
<th style="width: 40%; min-width: 50px;">Command</th>
|
||||
<th style="width: 10%; min-width: 50px;">Interval</th>
|
||||
<th style="width: 10%; min-width: 50px;">Start Time</th>
|
||||
<th style="width: 10%; min-width: 50px;">Next Run</th>
|
||||
<th style="width: 10%; min-width: 50px;">Enabled</th>
|
||||
<th style="width: 10%; min-width: 50px;">Edit</th>
|
||||
</tr>
|
||||
@ -91,13 +92,17 @@
|
||||
{% end %}
|
||||
</td>
|
||||
<td id="{{schedule.start_time}}" class="action">
|
||||
<p>{{schedule.start_time}}</p>
|
||||
<p>{{schedule.next_run}}</p>
|
||||
</td>
|
||||
<td id="{{schedule.enabled}}" class="action">
|
||||
<input style="width: 10px !important;" type="checkbox" class="schedule-enabled-toggle" data-schedule-id="{{schedule.schedule_id}}" data-schedule-enabled="{{ 'true' if schedule.enabled else 'false' }}">
|
||||
<input style="width: 10px !important;" type="checkbox" class="schedule-enabled-toggle"
|
||||
data-schedule-id="{{schedule.schedule_id}}"
|
||||
data-schedule-enabled="{{ 'true' if schedule.enabled else 'false' }}">
|
||||
</td>
|
||||
<td id="{{schedule.action}}" class="action">
|
||||
<button onclick="window.location.href='/panel/edit_schedule?id={{ data['server_stats']['server_id']['server_id'] }}&sch_id={{schedule.schedule_id}}'" class="btn btn-info">
|
||||
<button
|
||||
onclick="window.location.href='/panel/edit_schedule?id={{ data['server_stats']['server_id']['server_id'] }}&sch_id={{schedule.schedule_id}}'"
|
||||
class="btn btn-info">
|
||||
<i class="fas fa-pencil-alt"></i>
|
||||
</button>
|
||||
<br>
|
||||
@ -111,7 +116,8 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<table class="table table-hover d-block d-lg-none" id="mini_schedule_table" width="100%" style="table-layout:fixed;">
|
||||
<table class="table table-hover d-block d-lg-none" id="mini_schedule_table" width="100%"
|
||||
style="table-layout:fixed;">
|
||||
<thead>
|
||||
<tr class="rounded">
|
||||
<th style="width: 25%; min-width: 50px;">Action</th>
|
||||
@ -141,7 +147,8 @@
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="task_details_{{schedule.schedule_id}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal fade" id="task_details_{{schedule.schedule_id}}" tabindex="-1" role="dialog"
|
||||
aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@ -177,17 +184,22 @@
|
||||
{% end %}
|
||||
</li>
|
||||
<li id="{{schedule.start_time}}" class="action" style="border-top: .1em solid gray;">
|
||||
<h4>Start Time</h4>
|
||||
<p>{{schedule.start_time}}</p>
|
||||
<h4>Next Run</h4>
|
||||
<p>{{schedule.next_run}}</p>
|
||||
</li>
|
||||
<li id="{{schedule.enabled}}" class="action" style="border-top: .1em solid gray; border-bottom: .1em solid gray">
|
||||
<li id="{{schedule.enabled}}" class="action"
|
||||
style="border-top: .1em solid gray; border-bottom: .1em solid gray">
|
||||
<h4>Enabled</h4>
|
||||
<input type="checkbox" class="schedule-enabled-toggle" data-schedule-id="{{schedule.schedule_id}}" data-schedule-enabled="{{ 'true' if schedule.enabled else 'false' }}">
|
||||
<input type="checkbox" class="schedule-enabled-toggle"
|
||||
data-schedule-id="{{schedule.schedule_id}}"
|
||||
data-schedule-enabled="{{ 'true' if schedule.enabled else 'false' }}">
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button onclick="window.location.href='/panel/edit_schedule?id={{ data['server_stats']['server_id']['server_id'] }}&sch_id={{schedule.schedule_id}}'" class="btn btn-info">
|
||||
<button
|
||||
onclick="window.location.href='/panel/edit_schedule?id={{ data['server_stats']['server_id']['server_id'] }}&sch_id={{schedule.schedule_id}}'"
|
||||
class="btn btn-info">
|
||||
<i class="fas fa-pencil-alt"></i> Edit
|
||||
</button>
|
||||
<button data-sch={{ schedule.schedule_id }} class="btn btn-danger del_button">
|
||||
@ -215,12 +227,15 @@
|
||||
color: white !important;
|
||||
;
|
||||
}
|
||||
|
||||
.toggle-handle {
|
||||
background-color: white !important;
|
||||
}
|
||||
|
||||
.toggle-on {
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
height: 0px !important;
|
||||
}
|
||||
@ -250,7 +265,7 @@
|
||||
{% block js %}
|
||||
<script>
|
||||
|
||||
function debounce(func, timeout = 300){
|
||||
function debounce(func, timeout = 300) {
|
||||
let timer;
|
||||
return (...args) => {
|
||||
clearTimeout(timer);
|
||||
@ -265,17 +280,17 @@
|
||||
onstyle: 'success',
|
||||
offstyle: 'danger',
|
||||
})
|
||||
$('.schedule-enabled-toggle').each(function() {
|
||||
$('.schedule-enabled-toggle').each(function () {
|
||||
const enabled = JSON.parse(this.getAttribute('data-schedule-enabled'));
|
||||
$(this).bootstrapToggle(enabled ? 'on' : 'off')
|
||||
})
|
||||
$('.schedule-enabled-toggle').change(function() {
|
||||
$('.schedule-enabled-toggle').change(function () {
|
||||
const id = this.getAttribute('data-schedule-id');
|
||||
const enabled = this.checked;
|
||||
|
||||
fetch(`/api/v2/servers/{{data['server_id']}}/tasks/${id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({enabled}),
|
||||
body: JSON.stringify({ enabled }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
|
16
app/migrations/20220804_schedule_next_run.py
Normal file
16
app/migrations/20220804_schedule_next_run.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.add_columns("schedules", next_run=peewee.CharField(default=""))
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.drop_columns("schedules", ["next_run"])
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
Loading…
Reference in New Issue
Block a user