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 +
+ +
+
50%
+
+ +
+
+ Max percentage of errors over all runs +
+

Job details

+
+ +
+
{% if attribute(data, 'errorlevel') is not empty %}{{ attribute(data, 'errorlevel') }}{% else %}50{% endif %}%
+
+ +
+
+ Max percentage of errors over all runs +
+

Job details