$ps[2], 'file' => $dir.'/'.$jf, 'software' => $ps[0], 'instance' => $ps[1], 'time' => intval($ps[3]), ]; } foreach ($jobs as $job) { $ms = time() - filemtime($job->file); $data = null; $data = @unserialize(file_get_contents($job->file)); if ($data === false) { $data = ['last_accessed' => time(), 'sql' => $data]; file_put_contents($job->file, serialize($data)); } if ($ms < $job->time) continue; logi("Processing job: {$job->id}, software={$job->software}, instance={$job->instance}"); $ok = false; switch ($job->software) { case 'mastodon': $pg = new PgDatabase($job->software, $job->instance); if ($pg->is_ok()) { $result = $pg->fetch_all($data['sql']); content_cache__put($job->software.$job->instance.$data['sql'], 'always,'.$job->time, $result); $pg->close(); $ok = true; } break; } if ($ok) { logi("Job done: {$job->id}"); touch($job->file); } } } run__cronjobs_db(); // //////////////////////////////// /////////////////////////////// // CRONJOBS for caching cleanup // function run__cronjobs_cache_cleanup() { $cache_dir = $GLOBALS['appconf']['data_dir'].'/cache'; if (!file_exists($cache_dir)) return; $others = []; foreach (scandir($cache_dir) as $fl) { if (in_array($fl, ['.','..'])) continue; $ps = explode(',',$fl); if ($ps[1] !== 'ondemand') { $others []= $fl; continue; } $time = intval($ps[2]); $mtime = filemtime($cache_dir.'/'.$fl); if (time() - $mtime >= $time) { logi('CACHE-CLEANUP remove old file: '.$fl); unlink($cache_dir.'/'.$fl); } } $dir = $GLOBALS['appconf']['data_dir'].'/cron/db'; foreach ($others as $fl) { $ps = explode(',',$fl); if (count($ps) === 2 && $ps[1] === 'always') { $id = $ps[0]; $contains = false; foreach (scandir($dir) as $f) { if (in_array($f, ['.','..'])) continue; if (strpos($f, ','.$id.',') !== false) { $contains = true; break; } } if (!$contains) { logi('CACHE-CLEANUP remove unused "always" cache: '.$fl); unlink($cache_dir.'/'.$fl); } } } } run__cronjobs_cache_cleanup(); // /////////////////////////////// ////////////////////////////////////////// // CRONJOBS for creating jobs from filters // function run__cronjobs_filter_job($software, $instance, $filter, $action) { $_GET = [ 'filter_id' => $filter['id'], 'instance' => $instance ]; logi('Processing filter: '.serialize($_GET)); $users = mod_php('api/v1/database/'.$software.'/accounts/search'); if (gettype($users) !== 'array' || isset($users['error'])) { loge('Unexpected value for users: '.strval($users)); return false; } if (!isset($users['data'])) { loge('Unexpected value for users: '.strval($users)); return false; } foreach ($users['data'] as $user) { $jobname = $action['action']['name'].'_'.$user['id']; $jobmod = 'api/v1/http/'.$software.'/accounts/'.$action['action']['name']; $report = '[automatic_report] User has been reported because it matches filter "'.$filter['preset_name'].'"'; $explain = $report; if (isset($action['action']['explain'])) $explain = $action['action']['explain']; $args = base64_encode(json_encode([ '_get' => [ 'id' => $user['id'], 'instance' => $instance, ], '_post' => [ 'report' => $report, 'explain' => $explain, ], ])); $_POST = [ 'name' => $jobname, 'module' => $jobmod, 'args' => $args, ]; $result = mod_php('api/v1/cron/job/put'); if (isset($result['ok'])) logi($result['ok']); else if (isset($result['error'])) loge($result['error']); } touch($GLOBALS['appconf']['data_dir'].'/filter_actions/users,'.$instance.','.$action['id']); return true; } function run__cronjobs_filter_jobs() { $_GET = ['type' => 'users']; $filters = mod_php('api/v1/config/filters/get'); $config = mod_php('api/v1/config/get'); $filter_get = function($filters, $id) { foreach ($filters as $f) if ($f['id'] === $id) return $f; return null; }; foreach ($GLOBALS['supported_ap_software'] as $software) { foreach ($config['hosts'][$software] as $hostcfg) { $_GET['instance'] = $hostcfg['instance']; $actions = mod_php('api/v1/config/filters/actions/get'); if ($actions === null) continue; foreach ($actions as $action) { $filter = $filter_get($filters, $action['id']); if ($filter === null) continue; $ts_diff = time() - $action['filemtime']; if ($ts_diff >= $action['action']['interval']) run__cronjobs_filter_job($software, $hostcfg['instance'], $filter, $action); } } } } run__cronjobs_filter_jobs(); // ////////////////////////////////////////// /////////////////////////////////////// // CRONJOBS for running the actual jobs // function run_cronjobs() { $max = 1000; if (isset($GLOBALS['appconf']['cron__max_jobs'])) $max = intval($GLOBALS['appconf']['cron__max_jobs']); if (getenv('MAX_JOBS') !== false) $max = intval(getenv('MAX_JOBS')); $_GET = ['max' => $max]; $jobs = mod_php('api/v1/cron/jobs'); foreach ($jobs as $job) { $_GET = ['id' => $job]; $job_data = mod_php('api/v1/cron/job/get'); if (isset($job_data['args']['_get'])) $_GET = $job_data['args']['_get']; if (isset($job_data['args']['_post'])) $_POST = $job_data['args']['_post']; logi('Running job with data: '.serialize($job_data)); $r = mod_php($job_data['module']); if ($r === 'does_not_exist') { loge('Could not find module (mod.php file) for: '.$job_data['module']); continue; } $_GET = ['id' => $job]; $result = mod_php('api/v1/cron/job/del'); if (isset($result['ok'])) logi($result['ok']); else if (isset($result['error'])) loge($result['error']); } } run_cronjobs(); // /////////////////////////////////////// $ms_total = time() - $time_start; logi("Cron has finished in {$ms_total} seconds"); end_cronjobs();