mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-24 10:22:18 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61982b1199 | |||
| d50590aefb | |||
| c40ee917df | |||
| 8126665acd | |||
| 5826bf5b70 | |||
| fc5ba954fb | |||
| 4e9bf3676d | |||
| 31410f0bb9 | |||
| 1136d9dca1 | |||
| 967f53d73c | |||
| 8c24292195 | |||
| aba680cd52 |
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Configs for the Long Run Tasks
|
||||
*/
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
// Maximum LRTs for a single user in parallel
|
||||
$config['lrt_max_number_single_user'] = 10;
|
||||
|
||||
// Maximum LRTs for the whole system in parallel
|
||||
$config['lrt_max_number_system'] = 100;
|
||||
|
||||
// Maximum running time in hours for a single LRT before killing it
|
||||
$config['lrt_max_run_timeout'] = 24;
|
||||
|
||||
// List of existing LRT types
|
||||
$config['lrt_types'] = array('LRTDummy');
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
if (!defined("BASEPATH")) exit("No direct script access allowed");
|
||||
|
||||
/**
|
||||
* - This controller acts as interface of the LongRunTaskLib that contains
|
||||
* all the needed functionalities to operate with the Long Run Task system
|
||||
* that is built on top of the Jobs Queue System
|
||||
* - This is a Job Queue Worker that gets scheduled LRTs from the queue and executes them
|
||||
* - Once all the LRTs have been started checks if there are LRTs that are running for too long and kills them
|
||||
*/
|
||||
class LongRunTaskExecJob extends JOB_Controller
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Changes the needed configs for LogLib
|
||||
$this->LogLibJob->setConfigs(
|
||||
array(
|
||||
'dbExecuteUser' => get_class($this),
|
||||
'requestId' => 'LRT'
|
||||
)
|
||||
);
|
||||
|
||||
// Loads LongRunTaskLib library
|
||||
$this->load->library('LongRunTaskLib');
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes all the new LRTs
|
||||
*/
|
||||
public function execEmAll()
|
||||
{
|
||||
$this->logInfo('Execute long run tasks started');
|
||||
|
||||
// Get all the LRTs that is possible to execute now
|
||||
$lrtsResult = $this->longruntasklib->getNewLRTs();
|
||||
// If an error occurred then return it
|
||||
if (isError($lrtsResult)) return $lrtsResult;
|
||||
|
||||
if (hasData($lrtsResult))
|
||||
{
|
||||
// For each LRT
|
||||
foreach (getData($lrtsResult) as $lrt)
|
||||
{
|
||||
// Execute the task
|
||||
$executeLrtResult = $this->longruntasklib->executeLrt($lrt);
|
||||
if (isError($executeLrtResult)) $this->logError($executeLrtResult);
|
||||
}
|
||||
}
|
||||
|
||||
$this->logInfo('Execute long run tasks ended');
|
||||
}
|
||||
|
||||
/**
|
||||
* Kills all the hanging LRTs
|
||||
*/
|
||||
public function killHangingLRTs()
|
||||
{
|
||||
$this->logInfo('Kill hanging LRTs started');
|
||||
|
||||
// Get all the LRTs that is possible to execute now
|
||||
$lrtsResult = $this->longruntasklib->getHangingLRTs();
|
||||
// If an error occurred then return it
|
||||
if (isError($lrtsResult)) return $lrtsResult;
|
||||
|
||||
if (hasData($lrtsResult))
|
||||
{
|
||||
// For each LRT
|
||||
foreach (getData($lrtsResult) as $lrt)
|
||||
{
|
||||
// Kill the task
|
||||
$killLrtResult = $this->longruntasklib->killLrt($lrt);
|
||||
if (isError($killLrtResult)) $this->logError($killLrtResult);
|
||||
}
|
||||
}
|
||||
|
||||
$this->logInfo('Kill hanging LRTs ended');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function checkExecution()
|
||||
{
|
||||
$this->logInfo('Check execution long run tasks started');
|
||||
|
||||
// Get the related LRT data from the queue
|
||||
$lrtsResult = $this->longruntasklib->getRunningLRTs();
|
||||
// If an error occurred then return it
|
||||
if (isError($lrtsResult)) return $lrtsResult;
|
||||
|
||||
// If there are running LRTs
|
||||
if (hasData($lrtsResult))
|
||||
{
|
||||
// For each LRT
|
||||
foreach (getData($lrtsResult) as $lrt)
|
||||
{
|
||||
// Check the LRT execution
|
||||
$checkExecutionResult = $this->longruntasklib->checkExecution($lrt);
|
||||
if (isError($checkExecutionResult)) $this->logError($checkExecutionResult);
|
||||
}
|
||||
}
|
||||
|
||||
$this->logInfo('Check execution long run tasks ended');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
<?php
|
||||
/* Copyright (C) 2024 fhcomplete.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined("BASEPATH")) exit("No direct script access allowed");
|
||||
|
||||
class Modulgrafik extends JOB_Controller
|
||||
{
|
||||
const DEFAULT_XOFFSET = 40;
|
||||
const DEFAULT_YOFFSET = 30;
|
||||
const DEFAULT_WIDTH = 160;
|
||||
const DEFAULT_SEMESTER_LABEL_WIDTH = 80;
|
||||
const DEFAULT_ECTS_WIDTH = 40;
|
||||
const DEFAULT_HEIGHT = 50;
|
||||
const DEFAULT_SPACING = 40;
|
||||
const DEFAULT_FONTSIZE = 8;
|
||||
|
||||
protected $curx;
|
||||
protected $cury;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
|
||||
|
||||
$this->load->model('CL/Drawio_model', 'DrawioModel');
|
||||
|
||||
$this->load->library('DocsboxLib', null, 'DocsboxLib');
|
||||
}
|
||||
|
||||
public function drawModulGrafik($studienplan_id)
|
||||
{
|
||||
$sql = <<<EOSQL
|
||||
SELECT
|
||||
sl.studienplan_lehrveranstaltung_id,
|
||||
sl.lehrveranstaltung_id,
|
||||
sl.studienplan_lehrveranstaltung_id_parent,
|
||||
COALESCE(sl.studienplan_lehrveranstaltung_id_parent, sl.studienplan_lehrveranstaltung_id) AS lvgrp,
|
||||
sl.semester,
|
||||
lv.bezeichnung,
|
||||
lv.ects,
|
||||
lv.lehrtyp_kurzbz
|
||||
FROM
|
||||
lehre.tbl_studienplan_lehrveranstaltung sl
|
||||
JOIN
|
||||
lehre.tbl_lehrveranstaltung lv USING(lehrveranstaltung_id)
|
||||
WHERE
|
||||
sl.studienplan_id = {$studienplan_id}
|
||||
AND
|
||||
ects > '0.00'
|
||||
ORDER BY
|
||||
sl.semester ASC,
|
||||
lvgrp ASC,
|
||||
lv.lehrtyp_kurzbz DESC
|
||||
EOSQL;
|
||||
|
||||
$result = $this->StudienplanModel->execReadOnlyQuery($sql);
|
||||
$lvs = getData($result);
|
||||
|
||||
$errors = array();
|
||||
$assoclvs = array();
|
||||
$semester = array();
|
||||
if($lvs)
|
||||
{
|
||||
ob_start();
|
||||
|
||||
foreach($lvs as &$lv)
|
||||
{
|
||||
if( !isset($semester[$lv->semester]) ) {
|
||||
$semester[$lv->semester] = array();
|
||||
}
|
||||
$lv->parent = null;
|
||||
$lv->childs = array();
|
||||
$assoclvs[$lv->studienplan_lehrveranstaltung_id] = $lv;
|
||||
}
|
||||
|
||||
foreach($assoclvs as &$assoclv)
|
||||
{
|
||||
if( $assoclv->studienplan_lehrveranstaltung_id_parent === NULL )
|
||||
{
|
||||
$semester[$assoclv->semester][] = $assoclv;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( isset($assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent]) )
|
||||
{
|
||||
$assoclv->parent = $assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent];
|
||||
$assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent]->childs[] = $assoclv;
|
||||
}
|
||||
else
|
||||
{
|
||||
$errors[] = "ERROR: Missing parent lv " . $assoclv->studienplan_lehrveranstaltung_id_parent . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function printchilds($childs, $level) {
|
||||
if( count($childs) < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($childs as $child)
|
||||
{
|
||||
echo $level . $child->bezeichnung . " (" . $child->ects . ") " . $child->lehrtyp_kurzbz . "\n";
|
||||
printchilds($child->childs, $level . "\t");
|
||||
}
|
||||
}
|
||||
|
||||
echo "<!--\n\n";
|
||||
|
||||
foreach($semester as $sem => $mods)
|
||||
{
|
||||
echo $sem . ". Semester: \n";
|
||||
foreach($mods as $mod)
|
||||
{
|
||||
$level = "\t";
|
||||
echo $level . $mod->bezeichnung . " (" . $mod->ects . ") " . $mod->lehrtyp_kurzbz . "\n";
|
||||
printchilds($mod->childs, $level . "\t");
|
||||
}
|
||||
}
|
||||
echo "-->\n\n";
|
||||
|
||||
if (count($errors) === 0)
|
||||
{
|
||||
$this->DrawioModel->renderFileStart();
|
||||
$this->maxxoffset = self::DEFAULT_XOFFSET;
|
||||
$this->DrawioModel->renderDiagramStart($studienplan_id, 'Modulgrafik');
|
||||
$this->renderSemester($semester);
|
||||
$this->DrawioModel->renderDiagramEnd();
|
||||
$this->DrawioModel->renderFileEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($errors as $error)
|
||||
{
|
||||
echo $error;
|
||||
}
|
||||
}
|
||||
|
||||
$output = ob_get_clean();
|
||||
file_put_contents(sys_get_temp_dir().'/Modulgrafik.xml', $output);
|
||||
|
||||
$ret = DocsboxLib::convert(sys_get_temp_dir().'/Modulgrafik.xml', sys_get_temp_dir().'/Modulgrafik.png', 'png');
|
||||
|
||||
echo 'File: '.sys_get_temp_dir().'/Modulgrafik.png'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Keine LVs gefunden.\n";
|
||||
}
|
||||
}
|
||||
|
||||
protected function renderSemester($semester)
|
||||
{
|
||||
$cury = self::DEFAULT_YOFFSET;
|
||||
|
||||
foreach($semester as $sem => $mods)
|
||||
{
|
||||
$curx = self::DEFAULT_XOFFSET;
|
||||
$id = uniqid();
|
||||
$ects = 30; //TODO calc
|
||||
$this->DrawioModel->renderSemesterLabel($id, $sem, $ects, self::DEFAULT_XOFFSET, $cury, self::DEFAULT_SEMESTER_LABEL_WIDTH, self::DEFAULT_HEIGHT);
|
||||
$curx += self::DEFAULT_SEMESTER_LABEL_WIDTH + self::DEFAULT_SPACING;
|
||||
$maxmodulheight = 0;
|
||||
foreach($mods as $mod)
|
||||
{
|
||||
$modid = uniqid();
|
||||
$size = $this->DrawioModel->renderModulList($modid, $mod, $curx, $cury, self::DEFAULT_ECTS_WIDTH, self::DEFAULT_HEIGHT);
|
||||
$curx += $size->width + self::DEFAULT_SPACING;
|
||||
if( $size->height > $maxmodulheight)
|
||||
{
|
||||
$maxmodulheight = $size->height;
|
||||
}
|
||||
}
|
||||
$cury += $maxmodulheight + self::DEFAULT_SPACING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,339 +0,0 @@
|
||||
<?php
|
||||
/* Copyright (C) 2024 fhcomplete.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined("BASEPATH")) exit("No direct script access allowed");
|
||||
|
||||
class Organigramm extends JOB_Controller
|
||||
{
|
||||
const DEFAULT_XOFFSET = 40;
|
||||
const DEFAULT_YOFFSET = 30;
|
||||
const DEFAULT_WIDTH = 160;
|
||||
const DEFAULT_HEIGHT = 50;
|
||||
const DEFAULT_SPACING = 40;
|
||||
const DEFAULT_FONTSIZE = 8;
|
||||
const RENDER_CHILDS_HORIZONTAL = 1;
|
||||
const RENDER_CHILDS_VERTICAL = 2;
|
||||
|
||||
protected $maxxoffset;
|
||||
protected $donotrenderchildsoftype;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
|
||||
|
||||
$this->load->model('CL/Drawio_model', 'DrawioModel');
|
||||
|
||||
$this->load->library('DocsboxLib', null, 'DocsboxLib');
|
||||
|
||||
$this->maxxoffset = self::DEFAULT_XOFFSET;
|
||||
$this->donotrenderchildsoftype = array();
|
||||
}
|
||||
|
||||
public function getAllActiveOes()
|
||||
{
|
||||
$sql = <<<EOSQL
|
||||
SELECT
|
||||
oe.oe_kurzbz,
|
||||
CASE
|
||||
WHEN oe.oe_parent_kurzbz = 'atw' THEN 'gst'
|
||||
WHEN oe.oe_parent_kurzbz = 'etw' THEN 'gst'
|
||||
ELSE oe.oe_parent_kurzbz
|
||||
END AS oe_parent_kurzbz,
|
||||
oe.bezeichnung,
|
||||
oe.organisationseinheittyp_kurzbz,
|
||||
STRING_AGG(
|
||||
DISTINCT p.vorname || ' ' || p.nachname,
|
||||
', '
|
||||
) AS leitung_uid
|
||||
FROM
|
||||
"public"."tbl_organisationseinheit" oe
|
||||
LEFT JOIN public.tbl_benutzerfunktion bf ON bf.oe_kurzbz = oe.oe_kurzbz
|
||||
AND (
|
||||
bf.datum_bis IS NULL
|
||||
OR bf.datum_bis > NOW() :: date
|
||||
)
|
||||
AND (
|
||||
bf.funktion_kurzbz IS NULL
|
||||
OR bf.funktion_kurzbz = 'Leitung'
|
||||
)
|
||||
LEFT JOIN public.tbl_benutzer b USING(uid)
|
||||
LEFT JOIN public.tbl_person p USING(person_id)
|
||||
WHERE
|
||||
oe.aktiv = true
|
||||
AND oe.oe_kurzbz NOT IN ('betriebsrat', 'oeh', 'FUEWahl', 'atw', 'etw', 'gf20')
|
||||
GROUP BY
|
||||
oe.oe_kurzbz,
|
||||
oe.oe_parent_kurzbz,
|
||||
oe.bezeichnung,
|
||||
oe.organisationseinheittyp_kurzbz
|
||||
ORDER BY
|
||||
oe.oe_parent_kurzbz ASC NULLS FIRST,
|
||||
oe.oe_kurzbz ASC;
|
||||
EOSQL;
|
||||
|
||||
$result = $this->OrganisationseinheitModel->execReadOnlyQuery($sql);
|
||||
$oes = getData($result);
|
||||
|
||||
$errors = array();
|
||||
$assocoes = array();
|
||||
$roots = array();
|
||||
if($oes)
|
||||
{
|
||||
ob_start();
|
||||
|
||||
foreach($oes as &$oe)
|
||||
{
|
||||
$oe->parent = NULL;
|
||||
$oe->childs = array();
|
||||
$oe->renderchilds = self::RENDER_CHILDS_HORIZONTAL;
|
||||
$oe->childstorender = array();
|
||||
$oe->donotrenderchildsoftype = array();
|
||||
$assocoes[$oe->oe_kurzbz] = $oe;
|
||||
}
|
||||
|
||||
foreach($assocoes as &$assocoe)
|
||||
{
|
||||
if( $assocoe->oe_parent_kurzbz === NULL )
|
||||
{
|
||||
$roots[$assocoe->oe_kurzbz] = $assocoe;
|
||||
$assocoe->donotrenderchildsoftype = array(
|
||||
'Team',
|
||||
'Lehrgang',
|
||||
'Studiengang',
|
||||
'Kompetenzfeld',
|
||||
'Forschungsfeld',
|
||||
'Container'
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( isset($assocoes[$assocoe->oe_parent_kurzbz]) )
|
||||
{
|
||||
$assocoe->parent = $assocoes[$assocoe->oe_parent_kurzbz];
|
||||
$assocoes[$assocoe->oe_parent_kurzbz]->childs[] = $assocoe;
|
||||
|
||||
if( $assocoe->organisationseinheittyp_kurzbz === 'Fakultaet' )
|
||||
{
|
||||
$roots[$assocoe->oe_kurzbz] = $assocoe;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$errors[] = "ERROR: Missing parent oe " . $assocoe->oe_parent_kurzbz . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($errors) === 0)
|
||||
{
|
||||
$pages = count($roots);
|
||||
$this->DrawioModel->renderFileStart($pages);
|
||||
|
||||
foreach($roots AS &$root)
|
||||
{
|
||||
$this->maxxoffset = self::DEFAULT_XOFFSET;
|
||||
$this->donotrenderchildsoftype = $root->donotrenderchildsoftype;
|
||||
$this->prepareChildsToRender($root);
|
||||
$this->DrawioModel->renderDiagramStart($root->oe_kurzbz, $root->bezeichnung);
|
||||
$this->renderOE($root, 0, 0);
|
||||
$this->DrawioModel->renderDiagramEnd();
|
||||
}
|
||||
$this->DrawioModel->renderFileEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($errors as $error)
|
||||
{
|
||||
echo $error;
|
||||
}
|
||||
}
|
||||
|
||||
$output = ob_get_clean();
|
||||
file_put_contents(sys_get_temp_dir().'/Organigramm.xml', $output);
|
||||
|
||||
$ret = DocsboxLib::convert(sys_get_temp_dir().'/Organigramm.xml', sys_get_temp_dir().'/Organigramm.png', 'png');
|
||||
|
||||
echo 'File: '.sys_get_temp_dir().'//Organigramm.png'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Keine Oes gefunden.\n";
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareChildsToRender(&$oe)
|
||||
{
|
||||
$oe->childstorender = array();
|
||||
$oe->renderchilds = self::RENDER_CHILDS_HORIZONTAL;
|
||||
if( isset($oe->childsxoffset) )
|
||||
{
|
||||
unset($oe->childsxoffset);
|
||||
}
|
||||
|
||||
foreach($oe->childs AS &$oechild )
|
||||
{
|
||||
$this->prepareChildsToRender($oechild);
|
||||
if( !in_array($oechild->organisationseinheittyp_kurzbz, $this->donotrenderchildsoftype) )
|
||||
{
|
||||
$oe->childstorender[] = $oechild;
|
||||
}
|
||||
}
|
||||
|
||||
$nurLehrgaengeOderStudiengaengeOhneKinder = true;
|
||||
foreach($oe->childstorender AS &$oechildtorender )
|
||||
{
|
||||
if( !(count($oechildtorender->childstorender) === 0) )
|
||||
{
|
||||
$nurLehrgaengeOderStudiengaengeOhneKinder = false;
|
||||
}
|
||||
}
|
||||
|
||||
if( $nurLehrgaengeOderStudiengaengeOhneKinder && $oe->parent !== NULL )
|
||||
{
|
||||
$oe->renderchilds = self::RENDER_CHILDS_VERTICAL;
|
||||
}
|
||||
}
|
||||
|
||||
protected function renderOE($oe, $level, $parentrenderedchildcount)
|
||||
{
|
||||
$width = self::DEFAULT_WIDTH;
|
||||
$height = self::DEFAULT_HEIGHT;
|
||||
$spacing = self::DEFAULT_SPACING;
|
||||
$fontsize = self::DEFAULT_FONTSIZE;
|
||||
$nextlevel = $level + 1;
|
||||
$renderedchildcount = 0;
|
||||
|
||||
$curxoffset = $this->maxxoffset;
|
||||
|
||||
if( count($oe->childstorender) > 0 )
|
||||
{
|
||||
if( !isset($oe->childsxoffset) )
|
||||
{
|
||||
$oe->childsxoffset = (object) array(
|
||||
'min' => $curxoffset,
|
||||
'max' => $curxoffset
|
||||
);
|
||||
}
|
||||
|
||||
foreach($oe->childstorender AS $child)
|
||||
{
|
||||
$ret = $this->renderOE($child, $nextlevel, $renderedchildcount);
|
||||
$renderedchildcount++;
|
||||
if( $renderedchildcount === 1 )
|
||||
{
|
||||
$oe->childsxoffset->min = $ret->minx;
|
||||
}
|
||||
$oe->childsxoffset->max = $ret->maxx;
|
||||
}
|
||||
|
||||
if( count($oe->childstorender) === $renderedchildcount )
|
||||
{
|
||||
$curxoffset = $oe->childsxoffset->min +
|
||||
floor((($oe->childsxoffset->max - $oe->childsxoffset->min) / 2)) -
|
||||
floor((($width + $spacing) / 2));
|
||||
}
|
||||
}
|
||||
|
||||
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL )
|
||||
{
|
||||
$x = $curxoffset;
|
||||
$y = self::DEFAULT_YOFFSET
|
||||
+ (($level - 1) * ($height + $spacing))
|
||||
+ (($parentrenderedchildcount + 1) * ($height + floor($spacing / 2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
$x = $curxoffset;
|
||||
$y = self::DEFAULT_YOFFSET + ($level * ($height + $spacing));
|
||||
}
|
||||
$bezeichnung = htmlspecialchars($oe->bezeichnung);
|
||||
$leitung = ($oe->leitung_uid !== null) ? htmlspecialchars($oe->leitung_uid) : 'N.N.';
|
||||
$fillcolors = array(
|
||||
'Team' => '#ffe6cc',
|
||||
'Abteilung' => '#e6ffcc',
|
||||
'Studiengang' => '#cce6ff',
|
||||
'Lehrgang' => '#e6ccff',
|
||||
'Fakultaet' => '#f8cecc',
|
||||
'Department' => '#fff2cc',
|
||||
'Forschungsfeld' => '#e1d5e7',
|
||||
'Kompetenzfeld' => '#f5f5f5'
|
||||
);
|
||||
$fillcolor = (isset($fillcolors[$oe->organisationseinheittyp_kurzbz])) ? $fillcolors[$oe->organisationseinheittyp_kurzbz] : '#ffffff';
|
||||
$value = <<<EOVAL
|
||||
<font style="font-size: {$fontsize}px;"><div style="">[{$oe->organisationseinheittyp_kurzbz}]</div><b style="">{$bezeichnung}</b><div>({$leitung})</div></font>" style="whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;newEdgeStyle={"edgeStyle":"elbowEdgeStyle","startArrow":"none","endArrow":"none"};fillColor={$fillcolor};
|
||||
EOVAL;
|
||||
|
||||
$this->DrawioModel->renderCell($oe->oe_kurzbz, $value, $x, $y, $width, $height);
|
||||
|
||||
if( $oe->oe_parent_kurzbz !== NULL )
|
||||
{
|
||||
$exitX = '0.5';
|
||||
$exitY = '1';
|
||||
$entryX = '0.5';
|
||||
$entryY = '0';
|
||||
$points = array();
|
||||
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL)
|
||||
{
|
||||
$exitX = '0';
|
||||
$exitY = '0.5';
|
||||
$entryX = '0';
|
||||
$entryY = '0.5';
|
||||
$points = array(
|
||||
(object) array(
|
||||
'x' => ($x - floor($spacing / 2)),
|
||||
'y' => ($y + floor($height / 2))
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->DrawioModel->renderEdge($oe->oe_parent_kurzbz, $oe->oe_kurzbz, $exitX, $exitY, $entryX, $entryY, $points);
|
||||
}
|
||||
|
||||
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL )
|
||||
{
|
||||
if( count($oe->parent->childstorender) === ($parentrenderedchildcount + 1) )
|
||||
{
|
||||
if( $this->maxxoffset < ($x + $width + $spacing) )
|
||||
{
|
||||
$this->maxxoffset = ($x + $width + $spacing);
|
||||
}
|
||||
return (object) array(
|
||||
'minx' => $curxoffset,
|
||||
'maxx' => ($x + $width + $spacing)
|
||||
);
|
||||
}
|
||||
return (object) array(
|
||||
'minx' => $curxoffset,
|
||||
'maxx' => $x
|
||||
);
|
||||
}
|
||||
|
||||
if( $this->maxxoffset < ($x + $width + $spacing) )
|
||||
{
|
||||
$this->maxxoffset = ($x + $width + $spacing);
|
||||
}
|
||||
|
||||
return (object) array(
|
||||
'minx' => $curxoffset,
|
||||
'maxx' => ($x + $width + $spacing)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
if (!defined("BASEPATH")) exit("No direct script access allowed");
|
||||
|
||||
/**
|
||||
* Testing LRT to check if the LRT system is working properly
|
||||
* This will be called by the LongRunTaskExecJob
|
||||
*/
|
||||
class LRTDummy extends LRT_Controller
|
||||
{
|
||||
/**
|
||||
* This method must be implemented!
|
||||
*/
|
||||
public function run($jobid)
|
||||
{
|
||||
$this->logInfo('Long run tasks '.get_class($this).' started');
|
||||
|
||||
$this->_doIt($jobid);
|
||||
|
||||
$this->logInfo('Long run tasks '.get_class($this).' ended');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops on the number of seconds provided by the LRT input
|
||||
* Sleeps every time 1 sec
|
||||
* Writes the progress
|
||||
* Writes the output
|
||||
*/
|
||||
private function _doIt($jobid)
|
||||
{
|
||||
// Get the LRT record related to the provided jobid
|
||||
$lrtResult = $this->getLrt($jobid);
|
||||
|
||||
// If an error occurred or the record has not been found
|
||||
if (isError($lrtResult))
|
||||
{
|
||||
$this->logError($lrtResult);
|
||||
return;
|
||||
}
|
||||
if (!hasData($lrtResult))
|
||||
{
|
||||
$this->logError('LRT not found in database');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the record
|
||||
$lrt = getData($lrtResult)[0];
|
||||
|
||||
// Get and check the input
|
||||
$input = json_decode($lrt->{LongRunTaskLib::PROPERTY_INPUT});
|
||||
if ($input == null)
|
||||
{
|
||||
$this->logError('LRT input is not a valid json');
|
||||
return;
|
||||
}
|
||||
|
||||
// Operation
|
||||
for ($i = 0; $i < (int)$input->sleep; $i++)
|
||||
{
|
||||
sleep(1);
|
||||
// Set the progress
|
||||
$setProgressResult = $this->setProgress($jobid, (($i + 1) / (int)$input->sleep) * 100);
|
||||
if (isError($setProgressResult))
|
||||
{
|
||||
$this->logError($setProgressResult);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$sleepMsg = 'The user '.$lrt->{LongRunTaskLib::PROPERTY_UID}.' slept for '.$input->sleep.' seconds';
|
||||
|
||||
$this->logInfo($sleepMsg);
|
||||
|
||||
// Set the output
|
||||
$setOutputResult = $this->setOutput($jobid, $sleepMsg);
|
||||
if (isError($setOutputResult))
|
||||
{
|
||||
$this->logError($setOutputResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
use \stdClass as stdClass;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class LRTTest extends Auth_Controller
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
array(
|
||||
'index' => 'system/developer:r',
|
||||
'lrt1min' => 'system/developer:r',
|
||||
)
|
||||
);
|
||||
|
||||
// Loads LongRunTaskLib library
|
||||
$this->load->library('LongRunTaskLib');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* Everything has a beginning
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('system/lrtTest.php');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function lrt1min()
|
||||
{
|
||||
$lrtInput = new stdClass();
|
||||
$lrtInput->sleep = 1; // Sleep for 1 min
|
||||
|
||||
$this->outputJsonSuccess(
|
||||
$this->longruntasklib->addNewLrtToQueue(
|
||||
'LRTDummy', // LRT type
|
||||
getAuthUID(), // UID executer
|
||||
$lrtInput // LRT input
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
if (!defined("BASEPATH")) exit("No direct script access allowed");
|
||||
|
||||
/**
|
||||
* Long Run Task
|
||||
*
|
||||
* - This controller acts as interface of the LongRunTaskLib that contains
|
||||
* all the needed functionalities to operate with the Long Run Task system
|
||||
* that is built on top of the Jobs Queue System
|
||||
* - This is an abstract class that provide basic functionalities,
|
||||
* it has to be extended to broaden its logic
|
||||
* - Any implementation of a Long Run Task should extends this class to
|
||||
* properly operate with the LRT system
|
||||
*/
|
||||
abstract class LRT_Controller extends JOB_Controller
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Changes the needed configs for LogLib
|
||||
$this->LogLibJob->setConfigs(
|
||||
array(
|
||||
'dbExecuteUser' => get_class($this),
|
||||
'requestId' => 'LRT'
|
||||
)
|
||||
);
|
||||
|
||||
// Loads LongRunTaskLib library
|
||||
$this->load->library('LongRunTaskLib');
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
abstract public function run($jobid);
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Protected methods
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function getLrt($jobid)
|
||||
{
|
||||
return $this->longruntasklib->getLrt($jobid);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function setProgress($jobid, $progress)
|
||||
{
|
||||
return $this->longruntasklib->setProgress($jobid, $progress);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function setOutput($jobid, $output)
|
||||
{
|
||||
return $this->longruntasklib->setOutuput($jobid, $output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
/* Copyright (C) 2024 fhcomplete.net
|
||||
/* Copyright (C) 2022 fhcomplete.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as
|
||||
@@ -32,7 +32,7 @@ class DocsboxLib
|
||||
const STATUS_QUEUED = 'queued'; // Docsbox status when a file has been queued for the conversion
|
||||
const STATUS_STARTED = 'started'; // Docsbox status when a file has started being worked
|
||||
const STATUS_WORKING = 'working'; // Docsbox status when a file is being converted
|
||||
const JSON_FORMATS = '{"formats": ["%s"]}'; // JSON object to be sent to docsbox to specify the file format
|
||||
const OUTPUT_FILENAME = 'out.zip.pdf'; // File name used by docsbox to save a converted document
|
||||
|
||||
const DEFAULT_FORMAT = 'pdf'; // Default supported format
|
||||
|
||||
@@ -50,7 +50,7 @@ class DocsboxLib
|
||||
if (($format == null) || ($format != null && ctype_space($format) === true)) $format = self::DEFAULT_FORMAT;
|
||||
|
||||
// Posts the file to docsbox
|
||||
$queueId = self::_postFile($inputFileName, $format);
|
||||
$queueId = self::_postFile($inputFileName);
|
||||
// If an error occurred
|
||||
if ($queueId == null) return self::ERROR;
|
||||
|
||||
@@ -60,7 +60,7 @@ class DocsboxLib
|
||||
if ($resultUrl == null) return self::ERROR;
|
||||
|
||||
// Download and rename the converted file
|
||||
$downloaded = self::_downloadFile($inputFileName, $resultUrl, $outputFileName, $format);
|
||||
$downloaded = self::_downloadFile($resultUrl, $outputFileName);
|
||||
// If an error occurred
|
||||
if (!$downloaded) return self::ERROR;
|
||||
|
||||
@@ -74,7 +74,7 @@ class DocsboxLib
|
||||
* Posts the given file to a Docsboxserver and checks the response to return a valid queue id
|
||||
* On failure it returns a null value
|
||||
*/
|
||||
private static function _postFile($inputFileName, $format)
|
||||
private static function _postFile($inputFileName)
|
||||
{
|
||||
$queueId = null;
|
||||
|
||||
@@ -82,14 +82,8 @@ class DocsboxLib
|
||||
{
|
||||
// Posts the given file and expects a response in JSON format
|
||||
$postFileResponse = \Httpful\Request::post(DOCSBOX_SERVER.DOCSBOX_PATH_API)
|
||||
->sendsType(\Httpful\Mime::FORM)
|
||||
->expectsJson()
|
||||
->body(
|
||||
array(
|
||||
'options' => sprintf(self::JSON_FORMATS, $format)
|
||||
)
|
||||
)
|
||||
->attach(array('file' => $inputFileName))
|
||||
->expectsJson()
|
||||
->send();
|
||||
|
||||
// Checks that:
|
||||
@@ -227,7 +221,7 @@ class DocsboxLib
|
||||
/**
|
||||
* Download the converted file using the provided URL, unzip it, and renames it into the provided file name
|
||||
*/
|
||||
private static function _downloadFile($inputFileName, $resultUrl, $outputFileName, $format)
|
||||
private static function _downloadFile($resultUrl, $outputFileName)
|
||||
{
|
||||
$downloaded = false; // pessimistic assumption
|
||||
|
||||
@@ -259,7 +253,7 @@ class DocsboxLib
|
||||
// Opened, extracted and closed!
|
||||
|
||||
// Rename the extracted file to the given output file name
|
||||
if (@rename($inputFileName.'.'.$format, $outputFileName))
|
||||
if (rename($outputDirectory.'/'.self::OUTPUT_FILENAME, $outputFileName))
|
||||
{
|
||||
$downloaded = true;
|
||||
}
|
||||
@@ -267,7 +261,7 @@ class DocsboxLib
|
||||
{
|
||||
error_log(
|
||||
'An error occurred while renaming the extracted file: '.
|
||||
$inputFileName.'.'.$format.' into: '.
|
||||
$outputDirectory.'/'.self::OUTPUT_FILENAME.' into: '.
|
||||
$outputFileName
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
use \stdClass as stdClass;
|
||||
|
||||
/**
|
||||
* Library that contains all the needed functionalities to operate with the Jobs Queue System
|
||||
*/
|
||||
@@ -24,12 +26,12 @@ class JobsQueueLib
|
||||
const PROPERTY_END_TIME = 'endtime';
|
||||
const PROPERTY_ERROR = 'error';
|
||||
|
||||
private $_ci; // CI instance
|
||||
protected $_ci; // CI instance
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($authenticate = true)
|
||||
public function __construct()
|
||||
{
|
||||
// Gets CI instance
|
||||
$this->_ci =& get_instance();
|
||||
@@ -62,14 +64,29 @@ class JobsQueueLib
|
||||
*/
|
||||
public function getOldestJobs($type, $maxAmount = null)
|
||||
{
|
||||
$this->_ci->JobsQueueModel->resetQuery();
|
||||
|
||||
$this->_ci->JobsQueueModel->addOrder('creationtime', 'ASC');
|
||||
$types = $type; // default is array
|
||||
$limit = 0; // default query limit
|
||||
|
||||
// If the maximum amount of jobs to retrieve have been specified
|
||||
if (is_numeric($maxAmount)) $this->_ci->JobsQueueModel->addLimit($maxAmount);
|
||||
if (is_numeric($maxAmount)) $limit = $maxAmount;
|
||||
|
||||
return $this->_ci->JobsQueueModel->loadWhere(array('status' => self::STATUS_NEW, 'type' => $type));
|
||||
// If it is a string then include it into an array
|
||||
if (!isEmptyString($type) && is_string($type)) $types = array($type);
|
||||
|
||||
// Return the result of the query
|
||||
return $this->_ci->JobsQueueModel->execReadOnlyQuery('
|
||||
SELECT jq.*
|
||||
FROM system.tbl_jobsqueue jq
|
||||
WHERE jq.type IN ?
|
||||
AND jq.status = ?
|
||||
ORDER BY jq.creationtime DESC
|
||||
LIMIT ?',
|
||||
array(
|
||||
$types,
|
||||
self::STATUS_NEW,
|
||||
$limit
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,11 +94,23 @@ class JobsQueueLib
|
||||
*/
|
||||
public function getJobsByTypeStatus($type, $status)
|
||||
{
|
||||
$this->_ci->JobsQueueModel->resetQuery();
|
||||
$types = $type; // default is array
|
||||
|
||||
$this->_ci->JobsQueueModel->addOrder('creationtime', 'DESC');
|
||||
// If it is a string then include it into an array
|
||||
if (!isEmptyString($type) && is_string($type)) $types = array($type);
|
||||
|
||||
return $this->_ci->JobsQueueModel->loadWhere(array('status' => $status, 'type' => $type));
|
||||
// Return the result of the query
|
||||
return $this->_ci->JobsQueueModel->execReadOnlyQuery('
|
||||
SELECT jq.*
|
||||
FROM system.tbl_jobsqueue jq
|
||||
WHERE jq.type IN ?
|
||||
AND jq.status = ?
|
||||
ORDER BY jq.creationtime DESC',
|
||||
array(
|
||||
$types,
|
||||
$status
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,8 +282,30 @@ class JobsQueueLib
|
||||
return array($job);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Protected methods
|
||||
|
||||
/**
|
||||
* Checks if the given job contains a valid type
|
||||
*/
|
||||
protected function _checkJobType($type, $types)
|
||||
{
|
||||
return $this->_inArray($type, $types, self::PROPERTY_TYPE);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
/**
|
||||
* Drop not allowed properties from the given job
|
||||
*/
|
||||
private function _dropNotAllowedPropertiesNewJob(&$job)
|
||||
{
|
||||
unset($job->{self::PROPERTY_JOBID});
|
||||
unset($job->{self::PROPERTY_CREATIONTIME});
|
||||
unset($job->{self::PROPERTY_TYPE});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks the job object structure when needed for insert
|
||||
@@ -281,34 +332,6 @@ class JobsQueueLib
|
||||
return false; // better sorry than wrong
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the job object structure when needed for update
|
||||
*/
|
||||
private function _checkUpdateJobStructure(&$job)
|
||||
{
|
||||
// If job is a valid object
|
||||
if (is_object($job) && property_exists($job, self::PROPERTY_JOBID)) return true; // it is valid!
|
||||
|
||||
// If not object then object it!
|
||||
if (!is_object($job)) $job = new stdClass();
|
||||
|
||||
// If an error property was not already previously stored then store an error message in job object
|
||||
if (!property_exists($job, self::PROPERTY_ERROR))
|
||||
{
|
||||
$job->{self::PROPERTY_ERROR} = 'The structure of the provided job is not valid';
|
||||
}
|
||||
|
||||
return false; // better sorry than wrong
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given job contains a valid type
|
||||
*/
|
||||
private function _checkJobType($type, $types)
|
||||
{
|
||||
return $this->_inArray($type, $types, self::PROPERTY_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given job contains a valid status
|
||||
*/
|
||||
@@ -333,6 +356,26 @@ class JobsQueueLib
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the job object structure when needed for update
|
||||
*/
|
||||
private function _checkUpdateJobStructure(&$job)
|
||||
{
|
||||
// If job is a valid object
|
||||
if (is_object($job) && property_exists($job, self::PROPERTY_JOBID)) return true; // it is valid!
|
||||
|
||||
// If not object then object it!
|
||||
if (!is_object($job)) $job = new stdClass();
|
||||
|
||||
// If an error property was not already previously stored then store an error message in job object
|
||||
if (!property_exists($job, self::PROPERTY_ERROR))
|
||||
{
|
||||
$job->{self::PROPERTY_ERROR} = 'The structure of the provided job is not valid';
|
||||
}
|
||||
|
||||
return false; // better sorry than wrong
|
||||
}
|
||||
|
||||
/**
|
||||
* Search in an array the given value
|
||||
* The elements of the given array are objects
|
||||
@@ -354,16 +397,6 @@ class JobsQueueLib
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop not allowed properties from the given job
|
||||
*/
|
||||
private function _dropNotAllowedPropertiesNewJob(&$job)
|
||||
{
|
||||
unset($job->{self::PROPERTY_JOBID});
|
||||
unset($job->{self::PROPERTY_CREATIONTIME});
|
||||
unset($job->{self::PROPERTY_TYPE});
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop not allowed properties from the given job
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
|
||||
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once 'JobsQueueLib.php';
|
||||
|
||||
/**
|
||||
* Library that contains all the needed functionalities to operate with the Long Run Tasks
|
||||
*/
|
||||
class LongRunTaskLib extends JobsQueueLib
|
||||
{
|
||||
// Config names
|
||||
const CFG_LRT_MAX_NUMBER_SYSTEM = 'lrt_max_number_system';
|
||||
const CFG_LRT_TYPES = 'lrt_types';
|
||||
const CFG_LRT_MAX_RUN = 'lrt_max_run_timeout';
|
||||
const CFG_LRT_MAX_NUMBER_USER = 'lrt_max_number_single_user';
|
||||
|
||||
// LRT object properties
|
||||
const PROPERTY_UID = 'uid';
|
||||
const PROPERTY_PID = 'pid';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Loads the Long Run Tasks configs
|
||||
$this->_ci->config->load('lrt');
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods used by the LongRunTaskExecJob
|
||||
|
||||
/**
|
||||
* Get the oldest added LRTs to the queue having status = new
|
||||
* The maximum number of returned queued LRTs is limited by:
|
||||
* number of currently running LRTs - maximum allowed number of LRTs for the system
|
||||
*/
|
||||
public function getNewLRTs()
|
||||
{
|
||||
// Get all the running LRTs
|
||||
$runningLrtsResult = $this->getJobsByTypeStatus($this->_ci->config->item(self::CFG_LRT_TYPES), JobsQueueLib::STATUS_RUNNING);
|
||||
|
||||
if (isError($runningLrtsResult)) return $runningLrtsResult;
|
||||
|
||||
// The number of the currently running LRTs - the maximum LRTs for the system
|
||||
$max_number_of_lrts = $this->_ci->config->item(self::CFG_LRT_MAX_NUMBER_SYSTEM) - count(getData($runningLrtsResult));
|
||||
|
||||
// Get the oldest LRTs added to the queue
|
||||
return $this->getOldestJobs($this->_ci->config->item(self::CFG_LRT_TYPES), $max_number_of_lrts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the LRT that are running more then CFG_LRT_MAX_RUN hours
|
||||
*/
|
||||
public function getHangingLRTs()
|
||||
{
|
||||
// Return the result of the query
|
||||
return $this->_ci->JobsQueueModel->execReadOnlyQuery('
|
||||
SELECT jq.*
|
||||
FROM system.tbl_jobsqueue jq
|
||||
WHERE jq.type IN ?
|
||||
AND jq.status = ?
|
||||
AND jq.starttime < NOW() - INTERVAL \''.$this->_ci->config->item(self::CFG_LRT_MAX_RUN).' hours\'
|
||||
ORDER BY jq.creationtime DESC',
|
||||
array(
|
||||
$this->_ci->config->item(self::CFG_LRT_TYPES),
|
||||
JobsQueueLib::STATUS_RUNNING
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the LRT that are currently running
|
||||
*/
|
||||
public function getRunningLRTs()
|
||||
{
|
||||
// Return the result of the query
|
||||
return $this->_ci->JobsQueueModel->execReadOnlyQuery('
|
||||
SELECT jq.*
|
||||
FROM system.tbl_jobsqueue jq
|
||||
WHERE jq.type IN ?
|
||||
AND jq.status = ?
|
||||
ORDER BY jq.creationtime DESC',
|
||||
array(
|
||||
$this->_ci->config->item(self::CFG_LRT_TYPES),
|
||||
JobsQueueLib::STATUS_RUNNING
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a LRT in background
|
||||
* - Checks if the wanted LRT exists in the applcation/controllers/lrts directory
|
||||
* - Then executes it in background via CI CLI
|
||||
* - Stores the LRT pid into the database
|
||||
*/
|
||||
public function executeLrt($lrt)
|
||||
{
|
||||
$output = array();
|
||||
|
||||
// If does _not_ exist a LRT implementation for this LRT type, then return an error
|
||||
if (!file_exists(APPPATH.'controllers/lrts/'.$lrt->{self::PROPERTY_TYPE}.'.php'))
|
||||
{
|
||||
return error('The required LRT implementation has not been found');
|
||||
}
|
||||
|
||||
// Execute the LRT implementation (a CI controller from CLI) providing as parameter the jobid
|
||||
exec(
|
||||
// Command
|
||||
sprintf(
|
||||
'/usr/bin/php %s/../index.ci.php lrts/%s/run %s > /dev/null 2>&1 & echo $!',
|
||||
APPPATH,
|
||||
$lrt->{self::PROPERTY_TYPE},
|
||||
$lrt->{self::PROPERTY_JOBID}
|
||||
),
|
||||
$output // Here goes the output from the standard output and error
|
||||
);
|
||||
|
||||
// If a pid has not been returned
|
||||
if (isEmptyArray($output) || !is_numeric($output[0])) return error('Not a valid pid has been returned');
|
||||
|
||||
// Set the pid, status and starttime of this LRT into the database
|
||||
$updateLrtResult = $this->_ci->JobsQueueModel->update(
|
||||
$lrt->{self::PROPERTY_JOBID},
|
||||
array(
|
||||
'pid' => $output[0],
|
||||
'starttime' => 'NOW()',
|
||||
'status' => self::STATUS_RUNNING
|
||||
)
|
||||
);
|
||||
if (isError($updateLrtResult)) return $updateLrtResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill the provided LRT
|
||||
* To avoid to kill a process that is not this LRT,
|
||||
* since the same PID can be assigned to another process once this ended
|
||||
*/
|
||||
public function killLrt($lrt)
|
||||
{
|
||||
// Try to get the pid of this LRT from the system
|
||||
$pid = exec(
|
||||
sprintf(
|
||||
'ps -eo pid,cmd | grep "index.ci.php lrts/%s/run %s" | grep -v grep | awk \'{print $1}\'',
|
||||
$lrt->{self::PROPERTY_TYPE},
|
||||
$lrt->{self::PROPERTY_JOBID}
|
||||
)
|
||||
);
|
||||
|
||||
// If the pid is the same then kill the process with a SIGKILL
|
||||
if ($pid == $lrt->{self::PROPERTY_PID}) exec('kill -9 '.$lrt->{self::PROPERTY_PID}.' > /dev/null 2>&1');
|
||||
|
||||
// Set the LRT as failed in any case
|
||||
$lrtExecFailedResult = $this->_ci->JobsQueueModel->update(
|
||||
$lrt->{self::PROPERTY_JOBID},
|
||||
array(
|
||||
'endtime' => 'NOW()',
|
||||
'status' => self::STATUS_FAILED
|
||||
)
|
||||
);
|
||||
// If an error occurred then return it
|
||||
if (isError($lrtExecFailedResult)) return $lrtExecFailedResult;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function checkExecution($lrt)
|
||||
{
|
||||
// If the LRT stopped running
|
||||
if (!$this->_isRunning($lrt))
|
||||
{
|
||||
// Loads MessageLib library
|
||||
$this->_ci->load->library('MessageLib');
|
||||
// Load the BenutzerModel
|
||||
$this->_ci->load->model('person/Benutzer_model', 'BenutzerModel');
|
||||
|
||||
// Get the benutzer for this uid
|
||||
$benutzerResult = $this->_ci->BenutzerModel->loadWhere(array('uid' => $lrt->{LongRunTaskLib::PROPERTY_UID}));
|
||||
// If an error occurred then return it
|
||||
if (isError($benutzerResult)) return $benutzerResult;
|
||||
// If no benutzer has been found
|
||||
if (!hasData($benutzerResult)) return error('No benutzer found, uid: '.$lrt->{LongRunTaskLib::PROPERTY_UID});
|
||||
|
||||
$benutzer = getData($benutzerResult)[0];
|
||||
|
||||
// Sends a message to the user
|
||||
$messageResult = $this->_ci->messagelib->sendMessageUser(
|
||||
$benutzer->person_id,
|
||||
'Long run task ended',
|
||||
'The long run task '.$lrt->{self::PROPERTY_TYPE}.' ended, output: '.$lrt->{self::PROPERTY_OUTPUT}
|
||||
);
|
||||
// If an error occurred then return it
|
||||
if (isError($messageResult)) return $messageResult;
|
||||
|
||||
// Set the LRT as done
|
||||
$lrtExecOverResult = $this->_ci->JobsQueueModel->update(
|
||||
$lrt->{self::PROPERTY_JOBID},
|
||||
array(
|
||||
'endtime' => 'NOW()',
|
||||
'status' => self::STATUS_DONE
|
||||
)
|
||||
);
|
||||
// If an error occurred then return it
|
||||
if (isError($lrtExecOverResult)) return $lrtExecOverResult;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods used by the front end applications (standard controllers/end points, ex. controllers/system/LRTTest.php)
|
||||
|
||||
/**
|
||||
* Add a single LRT to the queue
|
||||
*/
|
||||
public function addNewLrtToQueue($type, $uid, $lrtInput)
|
||||
{
|
||||
// Checks parameters
|
||||
if (isEmptyString($type)) return error('The provided type parameter is not a valid string');
|
||||
if (isEmptyString($uid)) return error('The provided uid parameter is not a valid string');
|
||||
|
||||
// Get all the running task for this uid
|
||||
// Return the result of the query
|
||||
$runningLRTbyUIDResult = $this->_ci->JobsQueueModel->execReadOnlyQuery('
|
||||
SELECT jq.*
|
||||
FROM system.tbl_jobsqueue jq
|
||||
WHERE jq.status IN ?
|
||||
AND jq.uid = ?
|
||||
',
|
||||
array(
|
||||
array(
|
||||
self::STATUS_NEW,
|
||||
self::STATUS_RUNNING
|
||||
),
|
||||
$uid
|
||||
)
|
||||
);
|
||||
|
||||
// If an error occurred then return it
|
||||
if (isError($runningLRTbyUIDResult)) return $runningLRTbyUIDResult;
|
||||
|
||||
// If the running tasks for this user are too many
|
||||
if (count(getData($runningLRTbyUIDResult)) >= $this->_ci->config->item(self::CFG_LRT_MAX_NUMBER_USER))
|
||||
{
|
||||
return error('Too many running tasks for this user');
|
||||
}
|
||||
|
||||
// Convert input to JSON and check it
|
||||
$jsonLrtInput = json_encode($lrtInput);
|
||||
if ($jsonLrtInput == null) return error('The provided LRT input is not valid');
|
||||
|
||||
// Get all the job types
|
||||
$dbResult = $this->_ci->JobTypesModel->load();
|
||||
if (isError($dbResult)) return $dbResult;
|
||||
$types = getData($dbResult);
|
||||
|
||||
// If the given type is not present in database
|
||||
if (!$this->_checkJobType($type, $types)) return error('The provided type parameter is not valid');
|
||||
|
||||
// Get all the job statuses
|
||||
$dbResult = $this->_ci->JobStatusesModel->load();
|
||||
if (isError($dbResult)) return $dbResult;
|
||||
$statuses = getData($dbResult);
|
||||
|
||||
// Create an object that represent the new tbl_jobsqueue record with the provided input
|
||||
$lrt = $this->generateJobs(self::STATUS_NEW, $jsonLrtInput)[0];
|
||||
|
||||
// What you asked is what you get!
|
||||
$lrt->{self::PROPERTY_TYPE} = $type;
|
||||
$lrt->{self::PROPERTY_UID} = $uid;
|
||||
|
||||
// Try to insert the single lrt into database
|
||||
$dbNewLrtResult = $this->_ci->JobsQueueModel->insert($lrt);
|
||||
|
||||
// If an error occurred during while inserting in database
|
||||
if (isError($dbNewLrtResult)) return $dbNewLrtResult;
|
||||
|
||||
return success('LRT added to the queue');
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods used by the LRT implementation (controllers/ltrs/*, ex. controllers/ltrs/LRTDummy)
|
||||
|
||||
/**
|
||||
* Return a single record from the
|
||||
*/
|
||||
public function getLrt($jobid)
|
||||
{
|
||||
$this->_ci->JobsQueueModel->resetQuery();
|
||||
|
||||
return $this->_ci->JobsQueueModel->loadWhere(array('jobid' => $jobid));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function setProgress($jobid, $progress)
|
||||
{
|
||||
return $this->_ci->JobsQueueModel->update($jobid, array('progress' => $progress));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function setOutuput($jobid, $output)
|
||||
{
|
||||
return $this->_ci->JobsQueueModel->update($jobid, array('output' => json_encode($output)));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
/**
|
||||
* Return true if the LRT is still running
|
||||
*/
|
||||
private function _isRunning($lrt)
|
||||
{
|
||||
// Try to get the pid of this LRT from the system
|
||||
$pid = exec(
|
||||
sprintf(
|
||||
'ps -eo pid,cmd | grep "index.ci.php lrts/%s/run %s" | grep -v grep | awk \'{print $1}\'',
|
||||
$lrt->{self::PROPERTY_TYPE},
|
||||
$lrt->{self::PROPERTY_JOBID}
|
||||
)
|
||||
);
|
||||
|
||||
// If the pid is the same then the LRT is still running
|
||||
return $pid == $lrt->{self::PROPERTY_PID};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
<?php
|
||||
/* Copyright (C) 2024 fhcomplete.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
class Drawio_model extends CI_Model
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderFileStart($pages=1, $agent='FH-Complete', $timemodified='now')
|
||||
{
|
||||
$modified = (new DateTime($timemodified, new DateTimeZone('UTC')))->format(DateTime::ATOM);
|
||||
|
||||
echo <<<HEADER
|
||||
<mxfile modified="{$modified}" host="Electron" agent="{$agent}" type="device" pages="{$pages}">
|
||||
HEADER;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderFileEnd()
|
||||
{
|
||||
echo <<<FOOTER
|
||||
</mxfile>
|
||||
FOOTER;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderDiagramStart($diagram_id, $diagram_bezeichnung)
|
||||
{
|
||||
$bezeichnung = htmlspecialchars($diagram_bezeichnung);
|
||||
|
||||
echo <<<STARTDIAGRAMM
|
||||
<diagram id="diagram_{$diagram_id}" name="{$bezeichnung}">
|
||||
<mxGraphModel dx="1177" dy="687" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
STARTDIAGRAMM;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderDiagramEnd()
|
||||
{
|
||||
echo <<<ENDDIAGRAMM
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
ENDDIAGRAMM;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderCell($id, $value, $x, $y, $width, $height)
|
||||
{
|
||||
echo <<<OE
|
||||
<mxCell id="{$id}" value="{$value}" parent="1" vertex="1">
|
||||
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry" />
|
||||
</mxCell>
|
||||
OE;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderEdge($source, $target, $exitX, $exitY, $entryX, $entryY, $points=array())
|
||||
{
|
||||
if( count($points) > 0 )
|
||||
{
|
||||
$pointsxml = '';
|
||||
foreach($points as $point)
|
||||
{
|
||||
$pointsxml .= <<<EOPOINT
|
||||
<mxPoint x="{$point->x}" y="{$point->y}" />
|
||||
EOPOINT;
|
||||
}
|
||||
|
||||
$edgegeom = <<<EDGEPOINTS
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
{$pointsxml}
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
EDGEPOINTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
$edgegeom = ' <mxGeometry relative="1" as="geometry" />';
|
||||
}
|
||||
|
||||
echo <<<EDGE
|
||||
<mxCell id="edge_{$source}_{$target}" value="" style="edgeStyle=elbowEdgeStyle;elbow=vertical;sourcePerimeterSpacing=0;targetPerimeterSpacing=0;startArrow=none;endArrow=none;rounded=0;curved=0;exitX={$exitX};exitY={$exitY};exitDx=0;exitDy=0;entryX={$entryX};entryY={$entryY};entryDx=0;entryDy=0;" parent="1" source="{$source}" target="{$target}" edge="1">
|
||||
{$edgegeom}
|
||||
</mxCell>
|
||||
EDGE;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderSemesterLabel($id, $sem, $ects, $x, $y, $width, $height)
|
||||
{
|
||||
echo <<<RENDERSEM
|
||||
<mxCell id="{$id}" value="<b>{$sem}. Semester<br></b><div style="text-align: left;"><span style="background-color: initial;">{$ects} ECTS</span></div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry" />
|
||||
</mxCell>
|
||||
RENDERSEM;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderModulList($listid, $mod, $x, $y, $ects_width, $lv_height)
|
||||
{
|
||||
$width = ceil($mod->ects * $ects_width);
|
||||
$height = (count($mod->childs) + 1) * $lv_height;
|
||||
$modul_ects = (int) $mod->ects;
|
||||
|
||||
echo <<<RENDERMOD
|
||||
<mxCell id="{$listid}" value="{$mod->bezeichnung} ({$modul_ects})" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize={$lv_height};horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry">
|
||||
<mxRectangle x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
RENDERMOD;
|
||||
|
||||
$childnumber = 0;
|
||||
|
||||
foreach ($mod->childs as $child)
|
||||
{
|
||||
$childnumber++;
|
||||
$childid = uniqid();
|
||||
$childheight = $childnumber * $lv_height;
|
||||
$child_ects = (int) $child->ects;
|
||||
|
||||
echo <<<RENDERMODFOR
|
||||
<mxCell id="{$childid}" value="{$child->bezeichnung} ({$child_ects})" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="{$listid}">
|
||||
<mxGeometry y="{$childheight}" width="{$width}" height="{$lv_height}" as="geometry" />
|
||||
</mxCell>
|
||||
RENDERMODFOR;
|
||||
}
|
||||
|
||||
return (object) array(
|
||||
'width' => $width,
|
||||
'height' => $height
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
$includesArray = array(
|
||||
'title' => 'LRT Test Page',
|
||||
'axios027' => true,
|
||||
'bootstrap5' => true,
|
||||
'fontawesome6' => true,
|
||||
'vue3' => true,
|
||||
'navigationcomponent' => true,
|
||||
'phrases' => array(
|
||||
'global',
|
||||
'ui'
|
||||
),
|
||||
'customJSModules' => array('public/js/apps/LRTTest.js'),
|
||||
);
|
||||
|
||||
$this->load->view('templates/FHC-Header', $includesArray);
|
||||
?>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<!-- Navigation component -->
|
||||
<core-navigation-cmpt></core-navigation-cmpt>
|
||||
|
||||
<div id="content"></div>
|
||||
</div>
|
||||
|
||||
<?php $this->load->view('templates/FHC-Footer', $includesArray); ?>
|
||||
|
||||
@@ -287,7 +287,6 @@ class dokument_export
|
||||
{
|
||||
case 'pdf':
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
$ret = 0;
|
||||
$this->temp_filename = $this->temp_folder . '/out.' . $this->outputformat;
|
||||
|
||||
@@ -370,11 +369,6 @@ class dokument_export
|
||||
header('Content-Disposition: attachment; filename="'.$this->filename.'.doc"');
|
||||
header('Content-Length: '.$fsize);
|
||||
break;
|
||||
case 'docx':
|
||||
header('Content-type: application/vnd.ms-word');
|
||||
header('Content-Disposition: attachment; filename="'.$this->filename.'.docx"');
|
||||
header('Content-Length: '.$fsize);
|
||||
break;
|
||||
|
||||
case 'odt':
|
||||
header('Content-type: application/vnd.oasis.opendocument.text');
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
addNew1MinLrt()
|
||||
{
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/system/LRTTest/lrt1min'
|
||||
};
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (C) 2022 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import PluginsPhrasen from '../plugins/Phrasen.js';
|
||||
import {CoreNavigationCmpt} from '../components/navigation/Navigation.js'
|
||||
|
||||
import ApiLrt from "../api/LRTTEst.js";
|
||||
|
||||
const lrtTestApp = Vue.createApp({
|
||||
data: function() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
components: {
|
||||
CoreNavigationCmpt,
|
||||
},
|
||||
methods: {
|
||||
addNew1MinLrt() {
|
||||
this.$api.call(ApiLrt.addNew1MinLrt())
|
||||
.then(result => {
|
||||
this.dropdowns.studiensemester_array = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<button type="button" class="btn btn-primary" @click="addNew1MinLrt()">Add a 1 min LRT</button>
|
||||
`
|
||||
});
|
||||
|
||||
FhcApps.makeExtendable(lrtTestApp);
|
||||
|
||||
lrtTestApp.use(PluginsPhrasen).mount('#main');
|
||||
|
||||
@@ -94,6 +94,7 @@ require_once('dbupdate_3.4/71399_dashboard_update_widget_paths.php');
|
||||
require_once('dbupdate_3.4/71645_studvw_messagetab_ladezeit.php');
|
||||
require_once('dbupdate_3.4/71566_studienordnungsdokument_neuer_organisationseinheitstyp_programm.php');
|
||||
require_once('dbupdate_3.4/70376_lohnguide.php');
|
||||
require_once('dbupdate_3.4/76203_Asynchrone_Tasks.php');
|
||||
require_once('dbupdate_3.4/75888_reihungstest_mehrfachdurchfuehrung.php');
|
||||
require_once('dbupdate_3.4/76150_perm_other_lv_plan.php');
|
||||
require_once('dbupdate_3.4/68957_dashboard_bookmark_neue_Spalte_sort.php');
|
||||
@@ -433,7 +434,7 @@ $tabellen=array(
|
||||
"system.tbl_log" => array("log_id","person_id","zeitpunkt","app","oe_kurzbz","logtype_kurzbz","logdata","insertvon","taetigkeit_kurzbz"),
|
||||
"system.tbl_logtype" => array("logtype_kurzbz", "data_schema"),
|
||||
"system.tbl_filters" => array("filter_id","app","dataset_name","filter_kurzbz","person_id","description","sort","default_filter","filter","oe_kurzbz","statistik_kurzbz"),
|
||||
"system.tbl_jobsqueue" => array("jobid", "type", "creationtime", "status", "input", "output", "starttime", "endtime", "insertvon", "insertamum"),
|
||||
"system.tbl_jobsqueue" => array("jobid", "type", "creationtime", "status", "input", "output", "starttime", "endtime", "insertvon", "insertamum", "pid", "uid", "progress"),
|
||||
"system.tbl_jobstatuses" => array("status"),
|
||||
"system.tbl_jobtriggers" => array("type", "status", "following_type"),
|
||||
"system.tbl_jobtypes" => array("type", "description"),
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
// Add column pid to system.tbl_jobsqueue
|
||||
if (!$result = @$db->db_query('SELECT "pid" FROM "system"."tbl_jobsqueue" LIMIT 1'))
|
||||
{
|
||||
$qry = 'ALTER TABLE "system"."tbl_jobsqueue" ADD "pid" INT NULL DEFAULT NULL;';
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>system.tbl_jobsqueue: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Added column pid to table system.tbl_jobsqueue';
|
||||
}
|
||||
|
||||
// Add column uid to system.tbl_jobsqueue
|
||||
if (!$result = @$db->db_query('SELECT "uid" FROM "system"."tbl_jobsqueue" LIMIT 1'))
|
||||
{
|
||||
$qry = 'ALTER TABLE "system"."tbl_jobsqueue" ADD "uid" VARCHAR(32) NULL DEFAULT NULL;';
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>system.tbl_jobsqueue: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Added column uid to table system.tbl_jobsqueue';
|
||||
}
|
||||
|
||||
// Add column progress to system.tbl_jobsqueue
|
||||
if (!$result = @$db->db_query('SELECT "progress" FROM "system"."tbl_jobsqueue" LIMIT 1'))
|
||||
{
|
||||
$qry = 'ALTER TABLE "system"."tbl_jobsqueue" ADD "progress" NUMERIC(2,1) NULL DEFAULT 0;';
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>system.tbl_jobsqueue: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Added column progress to table system.tbl_jobsqueue';
|
||||
}
|
||||
|
||||
// Add foreign key fk_jobsqueue_benutzer_uid on system.tbl_jobsqueue.uid with public.tbl_benutzer.uid
|
||||
if ($result = $db->db_query("SELECT conname FROM pg_constraint WHERE conname = 'fk_jobsqueue_benutzer_uid'"))
|
||||
{
|
||||
if ($db->db_num_rows($result) == 0)
|
||||
{
|
||||
$qry = 'ALTER TABLE "system"."tbl_jobsqueue" ADD CONSTRAINT "fk_jobsqueue_benutzer_uid" FOREIGN KEY ("uid") REFERENCES "public"."tbl_benutzer" ("uid") ON DELETE RESTRICT ON UPDATE CASCADE;';
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>system.tbl_jobsqueue: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Created foreign key fk_jobsqueue_benutzer_uid';
|
||||
}
|
||||
}
|
||||
|
||||
// Add new webservice type in system.tbl_webservicetyp
|
||||
if ($result = @$db->db_query("SELECT 1 FROM system.tbl_webservicetyp WHERE webservicetyp_kurzbz = 'lrt';"))
|
||||
{
|
||||
if ($db->db_num_rows($result) == 0)
|
||||
{
|
||||
$qry = "INSERT INTO system.tbl_webservicetyp(webservicetyp_kurzbz, beschreibung) VALUES('lrt', 'Long Run Task');";
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>system.tbl_webservicetyp '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo ' system.tbl_webservicetyp: Added webservice type "lrt"<br>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1638,6 +1638,84 @@ $filters = array(
|
||||
}',
|
||||
'oe_kurzbz' => null,
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'dataset_name' => 'logs',
|
||||
'filter_kurzbz' => 'lrts24hours',
|
||||
'description' => '{Last 24 hours LRTs logs}',
|
||||
'sort' => 2,
|
||||
'default_filter' => false,
|
||||
'filter' => '
|
||||
{
|
||||
"name": "All Long Run Tasks logs from the last 24 hours",
|
||||
"columns": [
|
||||
{"name": "RequestId"},
|
||||
{"name": "ExecutionTime"},
|
||||
{"name": "ExecutedBy"},
|
||||
{"name": "Description"},
|
||||
{"name": "Data"}
|
||||
],
|
||||
"filters": [
|
||||
{
|
||||
"name": "WebserviceType",
|
||||
"operation": "contains",
|
||||
"condition": "job"
|
||||
},
|
||||
{
|
||||
"name": "RequestId",
|
||||
"operation": "contains",
|
||||
"condition": "LRT"
|
||||
},
|
||||
{
|
||||
"name": "ExecutionTime",
|
||||
"operation": "lt",
|
||||
"condition": "24",
|
||||
"option": "hours"
|
||||
}
|
||||
]
|
||||
}
|
||||
',
|
||||
'oe_kurzbz' => null,
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'dataset_name' => 'logs',
|
||||
'filter_kurzbz' => 'lrts48hours',
|
||||
'description' => '{Last 48 hours LRTs logs}',
|
||||
'sort' => 2,
|
||||
'default_filter' => false,
|
||||
'filter' => '
|
||||
{
|
||||
"name": "All Long Run Tasks logs from the last 48 hours",
|
||||
"columns": [
|
||||
{"name": "RequestId"},
|
||||
{"name": "ExecutionTime"},
|
||||
{"name": "ExecutedBy"},
|
||||
{"name": "Description"},
|
||||
{"name": "Data"}
|
||||
],
|
||||
"filters": [
|
||||
{
|
||||
"name": "WebserviceType",
|
||||
"operation": "contains",
|
||||
"condition": "job"
|
||||
},
|
||||
{
|
||||
"name": "RequestId",
|
||||
"operation": "contains",
|
||||
"condition": "LRT"
|
||||
},
|
||||
{
|
||||
"name": "ExecutionTime",
|
||||
"operation": "lt",
|
||||
"condition": "48",
|
||||
"option": "hours"
|
||||
}
|
||||
]
|
||||
}
|
||||
',
|
||||
'oe_kurzbz' => null,
|
||||
),
|
||||
);
|
||||
|
||||
// Loop through the filters array
|
||||
|
||||
Reference in New Issue
Block a user