Skip to content

[CRON] Cron Manager #306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 41 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c2b2b72
cron database
HB9HIL Apr 22, 2024
09df09b
cron manager files
HB9HIL Apr 22, 2024
d9c7f47
set last run
HB9HIL Apr 22, 2024
9b71664
Cron Library
HB9HIL Apr 22, 2024
276eed8
set last run
HB9HIL Apr 22, 2024
452fbfa
tweaked database
HB9HIL Apr 22, 2024
ba3eaa9
cron stuff
HB9HIL Apr 22, 2024
ec80eb3
run function - first approach
HB9HIL Apr 22, 2024
b0444fc
tweaked language
HB9HIL Apr 22, 2024
cdbaefb
only admins are allowed to enter cron page
HB9HIL Apr 22, 2024
d9777bb
remove flush
HB9HIL Apr 23, 2024
a16b709
added some todo comments
HB9HIL Apr 23, 2024
c85f8ea
prepare javascript conversion
HB9HIL Apr 23, 2024
a615a93
full library
HB9HIL Apr 23, 2024
d43faa9
remove unnessesary files
HB9HIL Apr 23, 2024
284b55e
much smaller lib...
HB9HIL Apr 24, 2024
4459f0e
Merge branch 'dev' into cronmanager
HB9HIL Apr 24, 2024
53f124a
pushed current state (not functional atm)
HB9HIL Apr 24, 2024
b3d6fab
tweaked library to work with codeigniter
HB9HIL Apr 25, 2024
51766ec
started with some frontend stuff
HB9HIL Apr 25, 2024
1d3e849
various stuff
HB9HIL Apr 25, 2024
573017f
fixed cronstrue converter
HB9HIL Apr 25, 2024
1f13257
basic edit dialog
HB9HIL Apr 26, 2024
9c461d2
js magic in cron edit
HB9HIL Apr 26, 2024
9538d96
edit frontend
HB9HIL Apr 26, 2024
be33c3c
edit dialog save
HB9HIL Apr 26, 2024
2e24330
fixed enable switch
HB9HIL Apr 26, 2024
f2163cb
changed last_run function to be more generic
HB9HIL Apr 26, 2024
c695775
Merge remote-tracking branch 'upstream/dev' into cronmanager
HB9HIL Apr 26, 2024
e4b592c
thirdparty up/downloads are turned off by default in crons
HB9HIL Apr 26, 2024
ae7938d
show file update times based on cron table
HB9HIL Apr 26, 2024
21ae0a5
flash messages and user input validation (serverside based)
HB9HIL Apr 26, 2024
2d0211f
code formatting and removing some comments
HB9HIL Apr 26, 2024
d00e6d2
Merge branch 'dev' into cronmanager
HB9HIL Apr 26, 2024
8ccfae4
don't let the big jobs run all at once
HB9HIL Apr 26, 2024
fde8712
mastercron status badge
HB9HIL Apr 26, 2024
2ed1400
disable table if mastercron isn't running
HB9HIL Apr 26, 2024
1fca8d4
Merge branch 'dev' into cronmanager
HB9HIL Apr 29, 2024
1175bf6
Merge branch 'dev' into cronmanager
HB9HIL Apr 30, 2024
307f8bb
Merge branch 'dev' into cronmanager
HB9HIL May 1, 2024
e929c62
added comments
HB9HIL May 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion application/config/migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
|
*/

$config['migration_version'] = 195;
$config['migration_version'] = 196;

/*
|--------------------------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions application/controllers/Clublog.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public function index() {
public function upload() {
$this->load->model('clublog_model');

// set the last run in cron table for the correct cron id
$this->load->model('cron_model');
$this->cron_model->set_last_run($this->router->class.'_'.$this->router->method);

$users = $this->clublog_model->get_clublog_users();

foreach ($users as $user) {
Expand Down
262 changes: 262 additions & 0 deletions application/controllers/Cron.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class cron extends CI_Controller {
function __construct() {

parent::__construct();

if (ENVIRONMENT == 'maintenance' && $this->session->userdata('user_id') == '') {
echo "Maintenance Mode is active. Try again later.\n";
redirect('user/login');
}

$this->load->model('cron_model');
}

public function index() {

$this->load->model('user_model');
if (!$this->user_model->authorize(99)) {
$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
redirect('dashboard');
}

$this->load->helper('file');

$footerData = [];
$footerData['scripts'] = [
'assets/js/cronstrue.min.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/cronstrue.min.js")),
'assets/js/sections/cron.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/cron.js"))
];

$data['page_title'] = "Cron Manager";
$data['crons'] = $this->cron_model->get_crons();

$mastercron = array();
$mastercron = $this->get_mastercron_status();
$data['mastercron'] = $mastercron;

$this->load->view('interface_assets/header', $data);
$this->load->view('cron/index');
$this->load->view('interface_assets/footer', $footerData);
}

public function run() {

// This is the main function, which handles all crons, runs them if enabled and writes the 'next run' timestamp to the database

// TODO Add an API Key to the cronjob to improve security?

$crons = $this->cron_model->get_crons();

$status = 'pending';

foreach ($crons as $cron) {
if ($cron->enabled == 1) {

// calculate the crons expression
$data = array(
'expression' => $cron->expression,
'timeZone' => null
);
$this->load->library('CronExpression', $data);

$cronjob = $this->cronexpression;
$dt = new DateTime();
$isdue = $cronjob->isMatching($dt);

$next_run = $cronjob->getNext();
$next_run_date = date('Y-m-d H:i:s', $next_run);
$this->cron_model->set_next_run($cron->id, $next_run_date);

if ($isdue == true) {
$isdue_result = 'true';

// TODO Add log_message level debug here to have logging for the cron manager

echo "CRON: " . $cron->id . " -> is due: " . $isdue_result . "\n";
echo "CRON: " . $cron->id . " -> RUNNING...\n";

$url = base_url() . $cron->function;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Wavelog Updater');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$crun = curl_exec($ch);
curl_close($ch);

if ($crun !== false) {
echo "CRON: " . $cron->id . " -> CURL Result: " . $crun . "\n";
$status = 'healthy';
} else {
echo "ERROR: Something went wrong with " . $cron->id . "\n";
$status = 'failed';
}
} else {
$isdue_result = 'false';
echo "CRON: " . $cron->id . " -> is due: " . $isdue_result . " -> Next Run: " . $next_run_date . "\n";
$status = 'healthy';
}
} else {
echo 'CRON: ' . $cron->id . " is disabled. skipped..\n";
$status = 'disabled';

// Set the next_run timestamp to null to indicate in the view/database that this cron is disabled
$this->cron_model->set_next_run($cron->id, null);
}
$this->cron_model->set_status($cron->id, $status);
$this->cronexpression = null;
}

$datetime = new DateTime("now", new DateTimeZone('UTC'));
$datetime = $datetime->format('Ymd H:i:s');
$this->optionslib->update('mastercron_last_run', $datetime , 'no');
}

public function editDialog() {

$cron_query = $this->cron_model->cron(xss_clean($this->input->post('id', true)));

$data['cron'] = $cron_query->row();
$data['page_title'] = "Edit Cronjob";

$this->load->view('cron/edit', $data);
}

public function edit() {
$this->load->model('user_model');
if (!$this->user_model->authorize(99)) {
$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
redirect('dashboard');
}

$id = xss_clean($this->input->post('cron_id', true));
$description = xss_clean($this->input->post('cron_description', true));
$expression = xss_clean($this->input->post('cron_expression', true));
$enabled = xss_clean($this->input->post('cron_enabled', true));

$data = array(
'expression' => $expression,
'timeZone' => null
);
$this->load->library('CronExpression', $data);
$cron = $this->cronexpression;

if ($cron->isValid()) {
$this->cron_model->edit_cron($id, $description, $expression, $enabled);
$this->cronexpression = null;

header("Content-type: application/json");
echo json_encode(['success' => true, 'messagecategory' => 'success', 'message' => 'Changes saved for Cronjob "' . $id . '"']);
} else {
$this->session->set_flashdata('error', 'The Cron Expression you entered is not valid');
$this->cronexpression = null;

header("Content-type: application/json");
echo json_encode(['success' => false, 'messagecategory' => 'error', 'message' => 'The expression "' . $expression . '" is not valid. Please try again.']);
}
}

public function toogleEnableCronSwitch() {

$id = xss_clean($this->input->post('id', true));
$cron_enabled = xss_clean($this->input->post('checked', true));

if ($id ?? '' != '') {
$this->cron_model->set_cron_enabled($id, $cron_enabled);
$data['success'] = 1;
} else {
$data['success'] = 0;
$data['flashdata'] = 'Not allowed';
}
echo json_encode($data);
}

public function fetchCrons() {
$hres = [];
$result = $this->cron_model->get_crons();

foreach ($result as $cron) {
$single = (object) [];
$single->cron_id = $cron->id;
$single->cron_description = $cron->description;
$single->cron_status = $this->cronStatus2html($cron->enabled, $cron->status);
$single->cron_expression = $this->cronExpression2html($cron->expression);
$single->cron_last_run = $cron->last_run ?? 'never';
$single->cron_next_run = ($cron->enabled == '1') ? ($cron->next_run ?? 'calculating..') : 'never';
$single->cron_edit = $this->cronEdit2html($cron->id);
$single->cron_enabled = $this->cronEnabled2html($cron->id, $cron->enabled);
array_push($hres, $single);
}
echo json_encode($hres);
}

private function cronStatus2html($enabled, $status) {
if ($enabled == '1') {
if ($status == 'healthy') {
$htmlret = '<span class="badge text-bg-success">healthy</span>';
} else {
$htmlret = '<span class="badge text-bg-warning">' . $status . '</span>';
}
} else {
$htmlret = '<span class="badge text-bg-secondary">disabled</span>';
}
return $htmlret;
}

private function cronExpression2html($expression) {
$htmlret = '<code id="humanreadable_tooltip" data-bs-toggle="tooltip">' . $expression . '</code>';
return $htmlret;
}

private function cronEdit2html($id) {
$htmlret = '<button id="' . $id . '" class="editCron btn btn-outline-primary btn-sm"><i class="fas fa-edit"></i></button>';
return $htmlret;
}

private function cronEnabled2html($id, $enabled) {
if ($enabled == '1') {
$checked = 'checked';
} else {
$checked = '';
}
$htmlret = '<div class="form-check form-switch"><input name="cron_enable_switch" class="form-check-input enableCronSwitch" type="checkbox" role="switch" id="' . $id . '" ' . $checked . '></div>';
return $htmlret;
}

private function get_mastercron_status() {
$warning_timelimit_seconds = 120; // yellow - warning please check
$error_timelimit_seconds = 600; // red - "not running"

$result = array();

$last_run = $this->optionslib->get_option('mastercron_last_run') ?? null;

if ($last_run != null) {
$timestamp_last_run = DateTime::createFromFormat('Ymd H:i:s', $last_run, new DateTimeZone('UTC'));
$now = new DateTime();
$diff = $now->getTimestamp() - $timestamp_last_run->getTimestamp();

if ($diff >= 0 && $diff <= $warning_timelimit_seconds) {
$result['status'] = 'OK';
$result['status_class'] = 'success';
} else {
if ($diff <= $error_timelimit_seconds) {
$result['status'] = 'Last run occurred more than ' . $warning_timelimit_seconds . ' seconds ago.<br>Please check your master cron! It should run every minute (* * * * *).';
$result['status_class'] = 'warning';
} else {
$result['status'] = 'Last run occurred more than ' . ($error_timelimit_seconds / 60) . ' minutes ago.<br>Seems like your Mastercron isn\'t running!<br>It should run every minute (* * * * *).';
$result['status_class'] = 'danger';
}
}
} else {
$result['status'] = 'Not running';
$result['status_class'] = 'danger';
}

return $result;
}

}
9 changes: 9 additions & 0 deletions application/controllers/Debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function index() {
$this->load->model('Logbook_model');
$this->load->model('Debug_model');
$this->load->model('Stations');
$this->load->model('cron_model');

$footerData = [];
$footerData['scripts'] = ['assets/js/sections/debug.js'];
Expand Down Expand Up @@ -62,6 +63,14 @@ public function index() {
$data['userdata_status'] = $userdata_status;
}

$data['dxcc_update'] = $this->cron_model->cron('update_dxcc')->row();
$data['dok_update'] = $this->cron_model->cron('update_update_dok')->row();
$data['lotw_user_update'] = $this->cron_model->cron('update_lotw_users')->row();
$data['pota_update'] = $this->cron_model->cron('update_update_pota')->row();
$data['scp_update'] = $this->cron_model->cron('update_update_clublog_scp')->row();
$data['sota_update'] = $this->cron_model->cron('update_update_sota')->row();
$data['wwff_update'] = $this->cron_model->cron('update_update_wwff')->row();

$data['page_title'] = "Debug";

$this->load->view('interface_assets/header', $data);
Expand Down
5 changes: 5 additions & 0 deletions application/controllers/Eqsl.php
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,11 @@ public function mark_all_sent() {
* Used for CRON job
*/
public function sync() {

// set the last run in cron table for the correct cron id
$this->load->model('cron_model');
$this->cron_model->set_last_run($this->router->class.'_'.$this->router->method);

ini_set('memory_limit', '-1');
set_time_limit(0);
$this->load->model('eqslmethods_model');
Expand Down
4 changes: 4 additions & 0 deletions application/controllers/Hrdlog.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ function __construct()
public function upload() {
$this->setOptions();

// set the last run in cron table for the correct cron id
$this->load->model('cron_model');
$this->cron_model->set_last_run($this->router->class.'_'.$this->router->method);

$this->load->model('logbook_model');

$station_ids = $this->logbook_model->get_station_id_with_hrdlog_code();
Expand Down
4 changes: 4 additions & 0 deletions application/controllers/Lotw.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ public function lotw_upload() {
echo "You must install php OpenSSL for LoTW functions to work";
}

// set the last run in cron table for the correct cron id
$this->load->model('cron_model');
$this->cron_model->set_last_run($this->router->class.'_'.$this->router->method);

// Get Station Profile Data
$this->load->model('Stations');

Expand Down
6 changes: 6 additions & 0 deletions application/controllers/Qrz.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ public function qrz_apitest() {
public function upload() {
$this->setOptions();

// set the last run in cron table for the correct cron id
$this->load->model('cron_model');
$this->cron_model->set_last_run($this->router->class.'_'.$this->router->method);

$this->load->model('logbook_model');

$station_ids = $this->logbook_model->get_station_id_with_qrz_api();
Expand Down Expand Up @@ -260,6 +264,8 @@ function download($user_id_to_load = null, $lastqrz = null, $show_views = false)
$this->load->model('user_model');
$this->load->model('logbook_model');

$this->load->model('cron_model');
$this->cron_model->set_last_run($this->router->class.'_'.$this->router->method);

$api_keys = $this->logbook_model->get_qrz_apikeys();

Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy