diff --git a/.env.sample b/.env.sample
index f226956..4a120f8 100644
--- a/.env.sample
+++ b/.env.sample
@@ -31,6 +31,9 @@ HASHING_METHOD="sha256"
### ENVIRONMENT ###
###################
+## Debug mode is solely for development purposes only. It disables caching and enables your webcam to stream it to the web
+DEBUG=false
+
## Cookies are used for saving autologin credentials. This sets the amount of time in seconds the credentials are saved.
## Grandma probably has a calculator somewhere if you need to check how many seconds are in a week :)
COOKIE_LIFETIME=2592000
diff --git a/assets/fonts/icomoon.svg b/assets/fonts/icomoon.svg
index 7c3b0b5..20a10fe 100644
--- a/assets/fonts/icomoon.svg
+++ b/assets/fonts/icomoon.svg
@@ -10,5 +10,6 @@
+
\ No newline at end of file
diff --git a/assets/fonts/icomoon.ttf b/assets/fonts/icomoon.ttf
index ac72224..1740fea 100644
Binary files a/assets/fonts/icomoon.ttf and b/assets/fonts/icomoon.ttf differ
diff --git a/assets/fonts/icomoon.woff b/assets/fonts/icomoon.woff
index 7927c3b..7daef36 100644
Binary files a/assets/fonts/icomoon.woff and b/assets/fonts/icomoon.woff differ
diff --git a/assets/fonts/selection.json b/assets/fonts/selection.json
index f95355f..381e896 100644
--- a/assets/fonts/selection.json
+++ b/assets/fonts/selection.json
@@ -1 +1 @@
-{"IcoMoonType":"selection","icons":[{"icon":{"paths":["M658.286 475.429c0-141.143-114.857-256-256-256s-256 114.857-256 256 114.857 256 256 256 256-114.857 256-256zM950.857 950.857c0 40-33.143 73.143-73.143 73.143-19.429 0-38.286-8-51.429-21.714l-196-195.429c-66.857 46.286-146.857 70.857-228 70.857-222.286 0-402.286-180-402.286-402.286s180-402.286 402.286-402.286 402.286 180 402.286 402.286c0 81.143-24.571 161.143-70.857 228l196 196c13.143 13.143 21.143 32 21.143 51.429z"],"width":950.8571428571428,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["search"],"defaultCode":61442,"grid":14},"attrs":[],"properties":{"name":"view","id":6,"order":198,"prevSize":28,"code":61442},"setIdx":0,"setId":0,"iconIdx":6},{"icon":{"paths":["M207.429 877.714l52-52-134.286-134.286-52 52v61.143h73.143v73.143h61.143zM506.286 347.429c0-7.429-5.143-12.571-12.571-12.571-3.429 0-6.857 1.143-9.714 4l-309.714 309.714c-2.857 2.857-4 6.286-4 9.714 0 7.429 5.143 12.571 12.571 12.571 3.429 0 6.857-1.143 9.714-4l309.714-309.714c2.857-2.857 4-6.286 4-9.714zM475.429 237.714l237.714 237.714-475.429 475.429h-237.714v-237.714zM865.714 292.571c0 19.429-8 38.286-21.143 51.429l-94.857 94.857-237.714-237.714 94.857-94.286c13.143-13.714 32-21.714 51.429-21.714s38.286 8 52 21.714l134.286 133.714c13.143 13.714 21.143 32.571 21.143 52z"],"width":865.7188571428571,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["pencil"],"defaultCode":61504,"grid":14},"attrs":[],"properties":{"name":"edit","id":64,"order":199,"prevSize":28,"code":61504},"setIdx":0,"setId":0,"iconIdx":64},{"icon":{"paths":["M790.857 529.714l-758.857 421.714c-17.714 9.714-32 1.143-32-18.857v-841.143c0-20 14.286-28.571 32-18.857l758.857 421.714c17.714 9.714 17.714 25.714 0 35.429z"],"width":808.5942857142857,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["play"],"defaultCode":61515,"grid":14},"attrs":[],"properties":{"name":"run","id":75,"order":197,"prevSize":28,"code":61515},"setIdx":0,"setId":0,"iconIdx":75},{"icon":{"paths":["M292.571 786.286v-402.286c0-10.286-8-18.286-18.286-18.286h-36.571c-10.286 0-18.286 8-18.286 18.286v402.286c0 10.286 8 18.286 18.286 18.286h36.571c10.286 0 18.286-8 18.286-18.286zM438.857 786.286v-402.286c0-10.286-8-18.286-18.286-18.286h-36.571c-10.286 0-18.286 8-18.286 18.286v402.286c0 10.286 8 18.286 18.286 18.286h36.571c10.286 0 18.286-8 18.286-18.286zM585.143 786.286v-402.286c0-10.286-8-18.286-18.286-18.286h-36.571c-10.286 0-18.286 8-18.286 18.286v402.286c0 10.286 8 18.286 18.286 18.286h36.571c10.286 0 18.286-8 18.286-18.286zM274.286 219.429h256l-27.429-66.857c-1.714-2.286-6.857-5.714-9.714-6.286h-181.143c-3.429 0.571-8 4-9.714 6.286zM804.571 237.714v36.571c0 10.286-8 18.286-18.286 18.286h-54.857v541.714c0 62.857-41.143 116.571-91.429 116.571h-475.429c-50.286 0-91.429-51.429-91.429-114.286v-544h-54.857c-10.286 0-18.286-8-18.286-18.286v-36.571c0-10.286 8-18.286 18.286-18.286h176.571l40-95.429c11.429-28 45.714-50.857 76-50.857h182.857c30.286 0 64.571 22.857 76 50.857l40 95.429h176.571c10.286 0 18.286 8 18.286 18.286z"],"width":804.5714285714286,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["trash"],"defaultCode":61944,"grid":14},"attrs":[],"properties":{"name":"delete","id":459,"order":201,"prevSize":28,"code":61944},"setIdx":0,"setId":0,"iconIdx":459}],"height":1024,"metadata":{"name":"icomoon"},"preferences":{"showGlyphs":true,"showCodes":true,"showQuickUse":false,"showQuickUse2":true,"showSVGs":true,"fontPref":{"prefix":"icon-","metadata":{"fontFamily":"icomoon","majorVersion":1,"minorVersion":0},"metrics":{"emSize":512,"baseline":6.25,"whitespace":50},"embed":false,"noie8":true,"ie7":false,"cssVars":true,"cssVarsFormat":"scss","showSelector":true,"showMetrics":true,"showMetadata":false,"showVersion":false},"imagePref":{"prefix":"icon-","png":true,"useClassSelector":true,"color":0,"bgColor":16777215},"historySize":50}}
\ No newline at end of file
+{"IcoMoonType":"selection","icons":[{"icon":{"paths":["M658.286 475.429c0-141.143-114.857-256-256-256s-256 114.857-256 256 114.857 256 256 256 256-114.857 256-256zM950.857 950.857c0 40-33.143 73.143-73.143 73.143-19.429 0-38.286-8-51.429-21.714l-196-195.429c-66.857 46.286-146.857 70.857-228 70.857-222.286 0-402.286-180-402.286-402.286s180-402.286 402.286-402.286 402.286 180 402.286 402.286c0 81.143-24.571 161.143-70.857 228l196 196c13.143 13.143 21.143 32 21.143 51.429z"],"width":950.8571428571428,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["search"],"defaultCode":61442,"grid":14},"attrs":[],"properties":{"name":"view","id":6,"order":198,"prevSize":28,"code":61442},"setIdx":0,"setId":0,"iconIdx":6},{"icon":{"paths":["M207.429 877.714l52-52-134.286-134.286-52 52v61.143h73.143v73.143h61.143zM506.286 347.429c0-7.429-5.143-12.571-12.571-12.571-3.429 0-6.857 1.143-9.714 4l-309.714 309.714c-2.857 2.857-4 6.286-4 9.714 0 7.429 5.143 12.571 12.571 12.571 3.429 0 6.857-1.143 9.714-4l309.714-309.714c2.857-2.857 4-6.286 4-9.714zM475.429 237.714l237.714 237.714-475.429 475.429h-237.714v-237.714zM865.714 292.571c0 19.429-8 38.286-21.143 51.429l-94.857 94.857-237.714-237.714 94.857-94.286c13.143-13.714 32-21.714 51.429-21.714s38.286 8 52 21.714l134.286 133.714c13.143 13.714 21.143 32.571 21.143 52z"],"width":865.7188571428571,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["pencil"],"defaultCode":61504,"grid":14},"attrs":[],"properties":{"name":"edit","id":64,"order":199,"prevSize":28,"code":61504},"setIdx":0,"setId":0,"iconIdx":64},{"icon":{"paths":["M790.857 529.714l-758.857 421.714c-17.714 9.714-32 1.143-32-18.857v-841.143c0-20 14.286-28.571 32-18.857l758.857 421.714c17.714 9.714 17.714 25.714 0 35.429z"],"width":808.5942857142857,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["play"],"defaultCode":61515,"grid":14},"attrs":[],"properties":{"name":"run","id":75,"order":197,"prevSize":28,"code":61515},"setIdx":0,"setId":0,"iconIdx":75},{"icon":{"paths":["M585.143 785.714v-108.571c0-10.286-8-18.857-18.286-18.857h-109.714c-10.286 0-18.286 8.571-18.286 18.857v108.571c0 10.286 8 18.857 18.286 18.857h109.714c10.286 0 18.286-8.571 18.286-18.857zM584 572l10.286-262.286c0-3.429-1.714-8-5.714-10.857-3.429-2.857-8.571-6.286-13.714-6.286h-125.714c-5.143 0-10.286 3.429-13.714 6.286-4 2.857-5.714 8.571-5.714 12l9.714 261.143c0 7.429 8.571 13.143 19.429 13.143h105.714c10.286 0 18.857-5.714 19.429-13.143zM576 38.286l438.857 804.571c12.571 22.286 12 49.714-1.143 72s-37.143 36-62.857 36h-877.714c-25.714 0-49.714-13.714-62.857-36s-13.714-49.714-1.143-72l438.857-804.571c12.571-23.429 37.143-38.286 64-38.286s51.429 14.857 64 38.286z"],"width":1024,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["exclamation-triangle","warning"],"defaultCode":61553,"grid":14},"attrs":[],"properties":{"name":"warning","id":107,"order":202,"prevSize":28,"code":61553},"setIdx":0,"setId":0,"iconIdx":107},{"icon":{"paths":["M292.571 786.286v-402.286c0-10.286-8-18.286-18.286-18.286h-36.571c-10.286 0-18.286 8-18.286 18.286v402.286c0 10.286 8 18.286 18.286 18.286h36.571c10.286 0 18.286-8 18.286-18.286zM438.857 786.286v-402.286c0-10.286-8-18.286-18.286-18.286h-36.571c-10.286 0-18.286 8-18.286 18.286v402.286c0 10.286 8 18.286 18.286 18.286h36.571c10.286 0 18.286-8 18.286-18.286zM585.143 786.286v-402.286c0-10.286-8-18.286-18.286-18.286h-36.571c-10.286 0-18.286 8-18.286 18.286v402.286c0 10.286 8 18.286 18.286 18.286h36.571c10.286 0 18.286-8 18.286-18.286zM274.286 219.429h256l-27.429-66.857c-1.714-2.286-6.857-5.714-9.714-6.286h-181.143c-3.429 0.571-8 4-9.714 6.286zM804.571 237.714v36.571c0 10.286-8 18.286-18.286 18.286h-54.857v541.714c0 62.857-41.143 116.571-91.429 116.571h-475.429c-50.286 0-91.429-51.429-91.429-114.286v-544h-54.857c-10.286 0-18.286-8-18.286-18.286v-36.571c0-10.286 8-18.286 18.286-18.286h176.571l40-95.429c11.429-28 45.714-50.857 76-50.857h182.857c30.286 0 64.571 22.857 76 50.857l40 95.429h176.571c10.286 0 18.286 8 18.286 18.286z"],"width":804.5714285714286,"attrs":[],"isMulticolor":false,"isMulticolor2":false,"tags":["trash"],"defaultCode":61944,"grid":14},"attrs":[],"properties":{"name":"delete","id":459,"order":201,"prevSize":28,"code":61944},"setIdx":0,"setId":0,"iconIdx":459}],"height":1024,"metadata":{"name":"icomoon"},"preferences":{"showGlyphs":true,"showCodes":true,"showQuickUse":true,"showQuickUse2":true,"showSVGs":true,"fontPref":{"prefix":"icon-","metadata":{"fontFamily":"icomoon","majorVersion":1,"minorVersion":0},"metrics":{"emSize":512,"baseline":6.25,"whitespace":50},"embed":false,"noie8":true,"ie7":false,"cssVars":true,"cssVarsFormat":"scss","showSelector":true,"showMetrics":true,"showMetadata":false,"showVersion":false,"autoHost":true},"imagePref":{"prefix":"icon-","png":true,"useClassSelector":true,"color":0,"bgColor":16777215},"historySize":50,"quickUsageToken":{"UntitledProject":"ZDkwNmUxODNhMDNhNzU4ODc2MmM0OTY4ZTNiY2EzZTgjMSMxNjI3ODk3NzcxIyMj"}}}
\ No newline at end of file
diff --git a/assets/js/job/add.js b/assets/js/job/add.js
index 2a3e43d..d1f1aa5 100644
--- a/assets/js/job/add.js
+++ b/assets/js/job/add.js
@@ -7,6 +7,7 @@ document.addEventListener("readystatechange", event => {
initHostType();
initContainerType();
initVarInputs();
+ initRangeInput();
initIntervalPattern();
initEternalCheckbox();
}
@@ -126,6 +127,12 @@ function initContainerType()
})
}
+function initRangeInput() {
+ document.querySelector('.range-input-errorlevel').addEventListener('input', event => {
+ document.querySelector('.range-value-errorlevel').innerHTML = event.target.value + '%';
+ })
+}
+
function initVarInputs()
{
document.querySelector('.addvar-btn').addEventListener('click', event => {
diff --git a/assets/scss/icons.scss b/assets/scss/icons.scss
index 9b254d7..da1e2f4 100644
--- a/assets/scss/icons.scss
+++ b/assets/scss/icons.scss
@@ -1,9 +1,11 @@
+@import "vars";
+
@font-face {
- font-family: 'icomoon';
+ font-family: '#{$icomoon-font-family}';
src:
- url('../fonts/icomoon.ttf?ov6ddj') format('truetype'),
- url('../fonts/icomoon.woff?ov6ddj') format('woff'),
- url('../fonts/icomoon.svg?ov6ddj#icomoon') format('svg');
+ url('#{$icomoon-font-path}/#{$icomoon-font-family}.ttf?ef3few') format('truetype'),
+ url('#{$icomoon-font-path}/#{$icomoon-font-family}.woff?ef3few') format('woff'),
+ url('#{$icomoon-font-path}/#{$icomoon-font-family}.svg?ef3few##{$icomoon-font-family}') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
@@ -11,7 +13,7 @@
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
- font-family: 'icomoon' !important;
+ font-family: '#{$icomoon-font-family}' !important;
speak: never;
font-style: normal;
font-weight: normal;
@@ -24,15 +26,28 @@
-moz-osx-font-smoothing: grayscale;
}
-.icon-view:before {
- content: "\f002";
+.icon-view {
+ &:before {
+ content: $icon-view;
+ }
}
-.icon-edit:before {
- content: "\f040";
+.icon-edit {
+ &:before {
+ content: $icon-edit;
+ }
}
-.icon-run:before {
- content: "\f04b";
+.icon-run {
+ &:before {
+ content: $icon-run;
+ }
}
-.icon-delete:before {
- content: "\f1f8";
+.icon-warning {
+ &:before {
+ content: $icon-warning;
+ }
+}
+.icon-delete {
+ &:before {
+ content: $icon-delete;
+ }
}
diff --git a/assets/scss/job/index.scss b/assets/scss/job/index.scss
index 16fe3fe..015c816 100644
--- a/assets/scss/job/index.scss
+++ b/assets/scss/job/index.scss
@@ -9,9 +9,17 @@ tr.running td {
background-color: #d4edda;
}
+.big-icon {
+ font-size: 1.5rem;
+}
+
+td.status-col {
+ width: 54px;
+}
.blur {
filter: blur(3px);
}
+
.runnow-overlay {
.runnow-blur {
bottom: 0;
diff --git a/assets/scss/vars.scss b/assets/scss/vars.scss
new file mode 100644
index 0000000..1dd5b4c
--- /dev/null
+++ b/assets/scss/vars.scss
@@ -0,0 +1,8 @@
+$icomoon-font-family: "icomoon" !default;
+$icomoon-font-path: "../fonts" !default;
+
+$icon-view: "\f002";
+$icon-edit: "\f040";
+$icon-run: "\f04b";
+$icon-warning: "\f071";
+$icon-delete: "\f1f8";
diff --git a/lib/Framework/Twig.php b/lib/Framework/Twig.php
index 28d6984..f4256ef 100644
--- a/lib/Framework/Twig.php
+++ b/lib/Framework/Twig.php
@@ -21,9 +21,13 @@ class Twig
public function __construct(Kernel $kernel)
{
$loader = new FilesystemLoader([$kernel->getTemplateDir()]);
- $cache = new FilesystemCache($kernel->getCacheDir() . '/twig');
$this->environment = new Environment($loader);
- $this->environment->setCache($cache);
+
+ if(!$_ENV['DEBUG']) {
+ $cache = new FilesystemCache($kernel->getCacheDir() . '/twig');
+ $this->environment->setCache($cache);
+ }
+
$this->kernel = $kernel;
$this->addExtensions();
$this->addFunctions();
diff --git a/src/Repository/Job.php b/src/Repository/Job.php
index 73e8934..a25eb78 100644
--- a/src/Repository/Job.php
+++ b/src/Repository/Job.php
@@ -14,6 +14,8 @@ class Job extends Repository
{
public function getAllJobs(bool $idiskey = false)
{
+ $runRepo = new Run($this->dbcon);
+
$jobsSql = "SELECT * FROM job";
$jobsStmt = $this->dbcon->prepare($jobsSql);
$jobsRslt = $jobsStmt->executeQuery();
@@ -26,6 +28,9 @@ class Job extends Repository
$job['service'] = $job['data']['service'] ?? '';
$job['norun'] = isset($job['lastrun']) && $job['nextrun'] > $job['lastrun'];
$job['running'] = $job['running'] != 0;
+ $failed = count($runRepo->getRunsForJob($job['id'], true));
+ $all = count($runRepo->getRunsForJob($job['id']));
+ $job['needschecking'] = $all > 0 && (($failed / $all) * 100) > $job['data']['errorlevel'];
if(!empty($job['data']['containertype']) && $job['data']['containertype'] != 'none') {
$job['host-displayname'] = $job['data']['service'] . ' on ' . $job['data']['host'];
}
@@ -41,6 +46,18 @@ class Job extends Repository
return $jobs;
}
+ public function getErrorRatio(int $jobId): bool
+ {
+ $errorSql = "SELECT count(*) as count FROM job WHERE id = :id";
+ $errorStmt = $this->dbcon->prepare($errorSql);
+ $errorRslt = $errorStmt->executeQuery([':timestamp' => time(), ':timestamplastrun' => time(), ':timestamprun' => time()]);
+ $error = $errorRslt->fetchAllAssociative();
+
+ $errorSql = "SELECT count(*) as count FROM job WHERE id = :id";
+ $errorStmt = $this->dbcon->prepare($errorSql);
+ $errorRslt = $errorStmt->executeQuery([':timestamp' => time(), ':timestamplastrun' => time(), ':timestamprun' => time()]);
+ $error = $errorRslt->fetchAllAssociative();
+ }
public function getJobsDue()
{
@@ -389,6 +406,7 @@ class Job extends Repository
$values['data']['crontype'] = $values['crontype'];
$values['data']['hosttype'] = $values['hosttype'];
$values['data']['containertype'] = $values['containertype'];
+ $values['data']['errorlevel'] = $values['errorlevel'];
if(empty($values['data']['crontype'])) {
throw new \InvalidArgumentException("Crontype cannot be empty");
diff --git a/src/Repository/Run.php b/src/Repository/Run.php
index d620256..b085c96 100644
--- a/src/Repository/Run.php
+++ b/src/Repository/Run.php
@@ -13,7 +13,7 @@ class Run extends Repository
const SUCCESS = 'S';
const MANUAL = 'M';
- public function getRunsForJob(int $id, $onlyfailed = false, $ordered = true): array
+ public function getRunsForJob(int $id, bool $onlyfailed = false, bool $ordered = true): array
{
$runsSql = "SELECT * FROM run WHERE job_id = :job";
$params = [':job' => $id];
diff --git a/templates/job/add.html.twig b/templates/job/add.html.twig
index 2ee342b..1026151 100644
--- a/templates/job/add.html.twig
+++ b/templates/job/add.html.twig
@@ -50,6 +50,17 @@
How many days (at least) to keep runs of this job in the database
+
+
Max error level (in Pct)
+
+
Max percentage of errors over all runs
+
+
Job details
diff --git a/templates/job/edit.html.twig b/templates/job/edit.html.twig
index d268222..71d929b 100644
--- a/templates/job/edit.html.twig
+++ b/templates/job/edit.html.twig
@@ -46,6 +46,17 @@
How many days (at least) to keep runs of this job in the database
+
+
Max error level (in Pct)
+
+
Max percentage of errors over all runs
+
+
Job details
diff --git a/templates/job/index.html.twig b/templates/job/index.html.twig
index ee4ae7a..a2594fa 100644
--- a/templates/job/index.html.twig
+++ b/templates/job/index.html.twig
@@ -6,6 +6,7 @@
+
Name
Host
Delay
@@ -16,7 +17,10 @@
{% for job in jobs %}
- {{ job.name }}
+ {% if job.needschecking %} {% endif %}
+
+ {% if job.needschecking %} {% endif %}
+ {{ job.name }}
{{ attribute(job, 'host-displayname') }}
{{ job.interval | interval }}
{{ job.nextrun | date("d/m/Y H:i:s") }}