diff --git a/agents/meshcore.js b/agents/meshcore.js index 5903cefb..9d3cd688 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -708,7 +708,6 @@ db = require('SimpleDataStore').Shared(); sha = require('SHA256Stream'); mesh = require('MeshAgent'); childProcess = require('child_process'); -try { scriptTask = require('script-task').CreateScriptTask(mesh); } catch (ex) { } if (mesh.hasKVM == 1) { // if the agent is compiled with KVM support // Check if this computer supports a desktop @@ -1556,10 +1555,6 @@ function handleServerCommand(data) { try { require(data.plugin).consoleaction(data, data.rights, data.sessionid, this); } catch (ex) { throw ex; } break; } - case 'task': { - if (scriptTask) { scriptTask.consoleAction(data, data.rights, data.sessionid, false); } - break; - } case 'coredump': // Set the current agent coredump situation.s if (data.value === true) { @@ -4565,11 +4560,6 @@ function processConsoleCommand(cmd, args, rights, sessionid) { } break; } - case 'task': { - if (!scriptTask) { response = "Tasks are not supported on this agent"; } - else { response = scriptTask.consoleAction(args, rights, sessionid, true); } - break; - } case 'plugin': { if (typeof args['_'][0] == 'string') { try { diff --git a/agents/modules_meshcore/script-task.js b/agents/modules_meshcore/script-task.js deleted file mode 100644 index d8b8febb..00000000 --- a/agents/modules_meshcore/script-task.js +++ /dev/null @@ -1,416 +0,0 @@ -/** -* @description MeshCentral Script-Task -* @author Ryan Blenis -* @copyright -* @license Apache-2.0 -*/ - -'use strict'; -function CreateScriptTask(parent) { - var obj = {}; - var db = require('SimpleDataStore').Shared(); - var pendingDownload = []; - var debugFlag = false; - var runningJobs = []; - var runningJobPIDs = {}; - - function dbg(str) { - if (debugFlag !== true) return; - var fs = require('fs'); - var logStream = fs.createWriteStream('scripttask.txt', { 'flags': 'a' }); - // use {'flags': 'a'} to append and {'flags': 'w'} to erase and write a new file - logStream.write('\n' + new Date().toLocaleString() + ': ' + str); - logStream.end('\n'); - } - - function removeFromArray(arr, from, to) { - var rest = arr.slice((to || from) + 1 || arr.length); - arr.length = from < 0 ? arr.length + from : from; - return arr.push.apply(arr, rest); - }; - - obj.consoleAction = function(args, rights, sessionid, interactive) { - //sendConsoleText('task: ' + JSON.stringify(args), sessionid); // Debug - - /* - if (typeof args['_'] == 'undefined') { - args['_'] = []; - args['_'][1] = args.pluginaction; // TODO - args['_'][2] = null; - args['_'][3] = null; - args['_'][4] = null; - } - */ - - var fnname = args['_'][0]; - if (fnname == null) { return "Valid task commands are: trigger, cache, clear, clearCache, debug, list"; } - - switch (fnname.toLowerCase()) { - case 'trigger': { - var jObj = { - jobId: args.jobId, - scriptId: args.scriptId, - replaceVars: args.replaceVars, - scriptHash: args.scriptHash, - dispatchTime: args.dispatchTime - }; - //dbg('jObj args is ' + JSON.stringify(jObj)); - var sObj = getScriptFromCache(jObj.scriptId); - //dbg('sobj = ' + JSON.stringify(sObj) + ', shash = ' + jObj.scriptHash); - if ((sObj == null) || (sObj.contentHash != jObj.scriptHash)) { - // get from the server, then run - //dbg('Getting and caching script '+ jObj.scriptId); - parent.SendCommand({ action: 'script-task', subaction: 'getScript', scriptId: jObj.scriptId, sessionid: sessionid, tag: 'console' }); - pendingDownload.push(jObj); - } else { - // ready to run - runScript(sObj, jObj, sessionid); - } - break; - } - case 'cache': { - var sObj = args.script; - cacheScript(sObj); - var setRun = []; - if (pendingDownload.length) { - pendingDownload.forEach(function (pd, k) { - if ((pd.scriptId == sObj._id) && (pd.scriptHash == sObj.contentHash)) { - if (setRun.indexOf(pd) === -1) { runScript(sObj, pd, sessionid); setRun.push(pd); } - removeFromArray(pendingDownload, k); - } - }); - } - break; - } - case 'clear': { - clearCache(); - parent.SendCommand({ action: 'script-task', subaction: 'clearAllPendingTasks', sessionid: sessionid, tag: 'console' }); - return "Cache cleared. All pending tasks cleared."; - } - case 'clearcache': { - clearCache(); - return "The script cache has been cleared"; - } - case 'debug': { - debugFlag = (debugFlag) ? false : true; - var str = (debugFlag) ? 'on' : 'off'; - return 'Debugging is now ' + str; - } - case 'list': { - var ret = ''; - if (pendingDownload.length == 0) return "No tasks pending script download"; - pendingDownload.forEach(function (pd, k) { ret += 'Task ' + k + ': ' + 'TaskID: ' + pd.jobId + ' ScriptID: ' + pd.scriptId + '\r\n'; }); - return ret; - } - default: { - dbg('Unknown action: ' + fnname + ' with data ' + JSON.stringify(args)); - break; - } - } - } - - function finalizeJob(job, retVal, errVal, sessionid) { - if (errVal != null && errVal.stack != null) errVal = errVal.stack; - removeFromArray(runningJobs, runningJobs.indexOf(job.jobId)); - if (typeof runningJobPIDs[job.jobId] != 'undefined') delete runningJobPIDs[job.jobId]; - parent.SendCommand({ - action: 'script-task', - subaction: 'taskComplete', - jobId: job.jobId, - scriptId: job.scriptId, - retVal: retVal, - errVal: errVal, - dispatchTime: job.dispatchTime, // include original run time (long running tasks could have tried a re-send) - sessionid: sessionid, - tag: 'console' - }); - } - - //@TODO Test powershell on *nix devices with and without powershell installed - function runPowerShell(sObj, jObj, sessionid) { - if (process.platform != 'win32') return runPowerShellNonWin(sObj, jObj); - const fs = require('fs'); - var rand = Math.random().toString(32).replace('0.', ''); - - var oName = 'st' + rand + '.txt'; - var pName = 'st' + rand + '.ps1'; - var pwshout = '', pwsherr = '', cancontinue = false; - try { - fs.writeFileSync(pName, sObj.content); - var outstr = '', errstr = ''; - var child = require('child_process').execFile(process.env['windir'] + '\\system32\\WindowsPowerShell\\v1.0\\powershell.exe', ['-NoLogo']); - child.stderr.on('data', function (chunk) { errstr += chunk; }); - child.stdout.on('data', function (chunk) { }); - runningJobPIDs[jObj.jobId] = child.pid; - child.stdin.write('.\\' + pName + ' | Out-File ' + oName + ' -Encoding UTF8\r\n'); - child.on('exit', function (procRetVal, procRetSignal) { - dbg('Exiting with ' + procRetVal + ', Signal: ' + procRetSignal); - if (errstr != '') { - finalizeJob(jObj, null, errstr, sessionid); - try { fs.unlinkSync(oName); fs.unlinkSync(pName); } catch (ex) { dbg('Could not unlink files, error was: ' + ex); } - return; - } - if (procRetVal == 1) { - finalizeJob(jObj, null, 'Process terminated unexpectedly.', sessionid); - try { fs.unlinkSync(oName); fs.unlinkSync(pName); } catch (ex) { dbg('Could not unlink files, error was: ' + ex); } - return; - } - try { outstr = fs.readFileSync(oName, 'utf8').toString(); } catch (ex) { outstr = (procRetVal) ? 'Failure' : 'Success'; } - if (outstr) { - //outstr = outstr.replace(/[^\x20-\x7E]/g, ''); - try { outstr = outstr.trim(); } catch (ex) { } - } else { - outstr = (procRetVal) ? 'Failure' : 'Success'; - } - dbg('Output is: ' + outstr); - finalizeJob(jObj, outstr, null, sessionid); - try { fs.unlinkSync(oName); fs.unlinkSync(pName); } catch (ex) { } - }); - child.stdin.write('exit\r\n'); - //child.waitExit(); // this was causing the event loop to stall on long-running scripts, switched to '.on exit' - - } catch (ex) { - dbg('Error block was (PowerShell): ' + ex); - finalizeJob(jObj, null, ex, sessionid); - } - } - - function runPowerShellNonWin(sObj, jObj, sessionid) { - const fs = require('fs'); - var rand = Math.random().toString(32).replace('0.', ''); - - var path = ''; - var pathTests = ['/usr/local/mesh', '/tmp', '/usr/local/mesh_services/meshagent', '/var/tmp']; - pathTests.forEach(function (p) { if (path == '' && fs.existsSync(p)) { path = p; } }); - dbg('Path chosen is: ' + path); - path = path + '/'; - - var oName = 'st' + rand + '.txt'; - var pName = 'st' + rand + '.ps1'; - var pwshout = '', pwsherr = '', cancontinue = false; - try { - var childp = require('child_process').execFile('/bin/sh', ['sh']); - childp.stderr.on('data', function (chunk) { pwsherr += chunk; }); - childp.stdout.on('data', function (chunk) { pwshout += chunk; }); - childp.stdin.write('which pwsh' + '\n'); - childp.stdin.write('exit\n'); - childp.waitExit(); - } catch (ex) { finalizeJob(jObj, null, "Couldn't determine pwsh in env: " + ex, sessionid); } - if (pwsherr != '') { finalizeJob(jObj, null, "PowerShell env determination error: " + pwsherr, sessionid); return; } - if (pwshout.trim() != '') { cancontinue = true; } - if (cancontinue === false) { finalizeJob(jObj, null, "PowerShell is not installed", sessionid); return; } - try { - fs.writeFileSync(path + pName, '#!' + pwshout + '\n' + sObj.content.split('\r\n').join('\n').split('\r').join('\n')); - var outstr = '', errstr = ''; - var child = require('child_process').execFile('/bin/sh', ['sh']); - child.stderr.on('data', function (chunk) { errstr += chunk; }); - child.stdout.on('data', function (chunk) { }); - runningJobPIDs[jObj.jobId] = child.pid; - - child.stdin.write('cd ' + path + '\n'); - child.stdin.write('chmod a+x ' + pName + '\n'); - child.stdin.write('./' + pName + ' > ' + oName + '\n'); - child.on('exit', function (procRetVal, procRetSignal) { - if (errstr != '') { - finalizeJob(jObj, null, errstr, sessionid); - try { - fs.unlinkSync(path + oName); - fs.unlinkSync(path + pName); - } catch (ex) { dbg('Could not unlink files, error was: ' + ex + ' for path ' + path); } - return; - } - if (procRetVal == 1) { - finalizeJob(jObj, null, 'Process terminated unexpectedly.', sessionid); - try { - fs.unlinkSync(path + oName); - fs.unlinkSync(path + pName); - } catch (ex) { dbg('Could not unlink files1, error was: ' + ex + ' for path ' + path); } - return; - } - try { outstr = fs.readFileSync(path + oName, 'utf8').toString(); } catch (es) { outstr = (procRetVal) ? 'Failure' : 'Success'; } - if (outstr) { - //outstr = outstr.replace(/[^\x20-\x7E]/g, ''); - try { outstr = outstr.trim(); } catch (ex) { } - } else { - outstr = (procRetVal) ? 'Failure' : 'Success'; - } - dbg('Output is: ' + outstr); - finalizeJob(jObj, outstr, null, sessionid); - try { fs.unlinkSync(path + oName); fs.unlinkSync(path + pName); } catch (ex) { dbg('Could not unlink files2, error was: ' + ex + ' for path ' + path); } - }); - child.stdin.write('exit\n'); - } catch (ex) { - dbg('Error block was (PowerShellNonWin): ' + ex); - finalizeJob(jObj, null, ex, sessionid); - } - } - - function runBat(sObj, jObj, sessionid) { - if (process.platform != 'win32') { finalizeJob(jObj, null, "Platform not supported.", sessionid); return; } - const fs = require('fs'); - var rand = Math.random().toString(32).replace('0.', ''); - var oName = 'st' + rand + '.txt'; - var pName = 'st' + rand + '.bat'; - try { - fs.writeFileSync(pName, sObj.content); - var outstr = '', errstr = ''; - var child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe'); - child.stderr.on('data', function (chunk) { errstr += chunk; }); - child.stdout.on('data', function (chunk) { }); - runningJobPIDs[jObj.jobId] = child.pid; - child.stdin.write(pName + ' > ' + oName + '\r\n'); - child.stdin.write('exit\r\n'); - - child.on('exit', function (procRetVal, procRetSignal) { - if (errstr != '') { - try { fs.unlinkSync(oName); fs.unlinkSync(pName); } catch (ex) { dbg('Could not unlink files, error was: ' + ex); } - finalizeJob(jObj, null, errstr, sessionid); - return; - } - if (procRetVal == 1) { - try { fs.unlinkSync(oName); fs.unlinkSync(pName); } catch (ex) { dbg('Could not unlink files, error was: ' + ex); } - finalizeJob(jObj, null, 'Process terminated unexpectedly.', sessionid); - return; - } - try { outstr = fs.readFileSync(oName, 'utf8').toString(); } catch (ex) { outstr = (procRetVal) ? 'Failure' : 'Success'; } - if (outstr) { - //outstr = outstr.replace(/[^\x20-\x7E]/g, ''); - try { outstr = outstr.trim(); } catch (ex) { } - } else { - outstr = (procRetVal) ? 'Failure' : 'Success'; - } - dbg('Output is: ' + outstr); - try { fs.unlinkSync(oName); fs.unlinkSync(pName); } catch (ex) { dbg('Could not unlink files, error was: ' + ex); } - finalizeJob(jObj, outstr, null, sessionid); - }); - } catch (ex) { - dbg('Error block was (BAT): ' + ex); - finalizeJob(jObj, null, ex, sessionid); - } - } - - function runBash(sObj, jObj, sessionid) { - if (process.platform == 'win32') { finalizeJob(jObj, null, "Platform not supported.", sessionid); return; } - //dbg('proc is ' + JSON.stringify(process)); - const fs = require('fs'); - var path = ''; - var pathTests = ['/usr/local/mesh', '/tmp', '/usr/local/mesh_services/meshagent', '/var/tmp']; - pathTests.forEach(function (p) { - if (path == '' && fs.existsSync(p)) { path = p; } - }); - dbg('Path chosen is: ' + path); - path = path + '/'; - //var child = require('child_process'); - //child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 }); - - var rand = Math.random().toString(32).replace('0.', ''); - var oName = 'st' + rand + '.txt'; - var pName = 'st' + rand + '.sh'; - try { - fs.writeFileSync(path + pName, sObj.content); - var outstr = '', errstr = ''; - var child = require('child_process').execFile('/bin/sh', ['sh']); - child.stderr.on('data', function (chunk) { errstr += chunk; }); - child.stdout.on('data', function (chunk) { }); - runningJobPIDs[jObj.jobId] = child.pid; - child.stdin.write('cd ' + path + '\n'); - child.stdin.write('chmod a+x ' + pName + '\n'); - child.stdin.write('./' + pName + ' > ' + oName + '\n'); - child.stdin.write('exit\n'); - - child.on('exit', function (procRetVal, procRetSignal) { - if (errstr != '') { - try { fs.unlinkSync(path + oName); fs.unlinkSync(path + pName); } catch (ex) { dbg('Could not unlink files, error was: ' + ex + ' for path ' + path); } - finalizeJob(jObj, null, errstr, sessionid); - return; - } - if (procRetVal == 1) { - try { fs.unlinkSync(path + oName); fs.unlinkSync(path + pName); } catch (ex) { dbg('Could not unlink files1, error was: ' + ex + ' for path ' + path); } - finalizeJob(jObj, null, "Process terminated unexpectedly.", sessionid); - return; - } - try { outstr = fs.readFileSync(path + oName, 'utf8').toString(); } catch (ex) { outstr = (procRetVal) ? 'Failure' : 'Success'; } - if (outstr) { - //outstr = outstr.replace(/[^\x20-\x7E]/g, ''); - try { outstr = outstr.trim(); } catch (ex) { } - } else { - outstr = (procRetVal) ? 'Failure' : 'Success'; - } - dbg('Output is: ' + outstr); - try { fs.unlinkSync(path + oName); fs.unlinkSync(path + pName); } catch (ex) { dbg('Could not unlink files2, error was: ' + ex + ' for path ' + path); } - finalizeJob(jObj, outstr, null, sessionid); - }); - } catch (ex) { - dbg('Error block was (bash): ' + ex); - finalizeJob(jObj, null, ex, sessionid); - } - } - - function jobIsRunning(jObj) { - if (runningJobs.indexOf(jObj.jobId) === -1) return false; - return true; - } - - function runScript(sObj, jObj, sessionid) { - // get current processes and clean running jobs if they are no longer running (computer fell asleep, user caused process to stop, etc.) - if (process.platform != 'linux' && runningJobs.length) { // linux throws errors here in the meshagent for some reason - require('process-manager').getProcesses(function (plist) { - dbg('Got process list'); - dbg('There are currently ' + runningJobs.length + ' running jobs.'); - if (runningJobs.length) { - runningJobs.forEach(function (jobId, idx) { - dbg('Checking for running job: ' + jobId + ' with PID ' + runningJobPIDs[jobId]); - if (typeof plist[runningJobPIDs[jobId]] == 'undefined' || typeof plist[runningJobPIDs[jobId]].cmd != 'string') { - dbg('Found job with no process. Removing running status.'); - delete runningJobPIDs[jobId]; - removeFromArray(runningJobs, runningJobs.indexOf(idx)); - //dbg('RunningJobs: ' + JSON.stringify(runningJobs)); - //dbg('RunningJobsPIDs: ' + JSON.stringify(runningJobPIDs)); - } - }); - } - }); - } - if (jobIsRunning(jObj)) { dbg('Job already running job id [' + jObj.jobId + ']. Skipping.'); return; } - if (jObj.replaceVars != null) { - Object.getOwnPropertyNames(jObj.replaceVars).forEach(function (key) { - var val = jObj.replaceVars[key]; - sObj.content = sObj.content.replace(new RegExp('#' + key + '#', 'g'), val); - dbg('replacing var ' + key + ' with ' + val); - }); - sObj.content = sObj.content.replace(new RegExp('#(.*?)#', 'g'), 'VAR_NOT_FOUND'); - } - runningJobs.push(jObj.jobId); - dbg('Running Script ' + sObj._id); - switch (sObj.filetype) { - case 'ps1': runPowerShell(sObj, jObj, sessionid); break; - case 'bat': runBat(sObj, jObj, sessionid); break; - case 'bash': runBash(sObj, jObj, sessionid); break; - default: dbg('Unknown filetype: ' + sObj.filetype); break; - } - } - - function getScriptFromCache(id) { - var script = db.Get('scriptTask_script_' + id); - if (script == '' || script == null) return null; - try { script = JSON.parse(script); } catch (ex) { return null; } - return script; - } - - function cacheScript(sObj) { - db.Put('scriptTask_script_' + sObj._id, sObj); - } - - function clearCache() { - db.Keys.forEach(function (k) { if (k.indexOf('scriptTask_script_') === 0) { db.Put(k, null); db.Delete(k); } }); - } - - function sendConsoleText(text, sessionid) { - if (typeof text == 'object') { text = JSON.stringify(text); } - parent.SendCommand({ action: 'msg', type: 'console', value: 'XXX: ' + text, sessionid: sessionid }); - } - - return obj; -} - -module.exports = { CreateScriptTask: CreateScriptTask }; \ No newline at end of file diff --git a/public/tail.datetime/tail.datetime-default-blue.min.css b/public/tail.datetime/tail.datetime-default-blue.min.css deleted file mode 100644 index 941a5aea..00000000 --- a/public/tail.datetime/tail.datetime-default-blue.min.css +++ /dev/null @@ -1,3 +0,0 @@ -@charset "UTF-8"; /* pytesNET/tail.DateTime v.0.4.14 */ -/* @author SamBrishes, pytesNET | @license MIT */ -.tail-datetime-calendar,.tail-datetime-calendar *,.tail-datetime-calendar :after,.tail-datetime-calendar :before{box-sizing:border-box;-webkit-box-sizing:border-box}.tail-datetime-calendar{top:0;left:0;width:275px;height:auto;margin:15px;padding:0;z-index:3000;display:block;position:absolute;visibility:hidden;direction:ltr;border-collapse:separate;font-family:"Open Sans",Calibri,Arial,sans-serif;background-color:#fff;border-width:0;border-style:solid;border-color:transparent;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.3125);-webkit-box-shadow:0 1px 3px rgba(0,0,0,.3125)}.tail-datetime-calendar:after{clear:both;content:"";display:block;font-size:0;visibility:hidden}.tail-datetime-calendar.calendar-static{top:auto;left:auto;margin-left:auto;margin-right:auto;position:static;visibility:visible}.tail-datetime-calendar button.calendar-close{top:100%;right:15px;color:#303438;width:35px;height:25px;margin:1px 0 0 0;padding:5px 10px;opacity:.5;outline:0;display:inline-block;position:absolute;font-size:14px;line-height:1.125em;text-shadow:none;background-color:#fff;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij48cGF0aCBmaWxsPSIjMzAzNDM4IiBkPSJNNy40OCA4bDMuNzUgMy43NS0xLjQ4IDEuNDhMNiA5LjQ4bC0zLjc1IDMuNzUtMS40OC0xLjQ4TDQuNTIgOCAuNzcgNC4yNWwxLjQ4LTEuNDhMNiA2LjUybDMuNzUtMy43NSAxLjQ4IDEuNDhMNy40OCA4eiIvPjwvc3ZnPg==");background-repeat:no-repeat;background-position:center center;border-width:0;border-style:solid;border-color:transparent;border-radius:0 0 3px 3px;box-shadow:0 1px 3px rgba(0,0,0,.3125);-webkit-box-shadow:0 1px 3px rgba(0,0,0,.3125);transition:opacity 142ms linear;-webkit-transition:opacity 142ms linear}.tail-datetime-calendar button.calendar-close:hover{opacity:1}.tail-datetime-calendar .calendar-tooltip{color:#fff;width:auto;margin:0;padding:0;display:block;position:absolute;background-color:#202428;border-radius:3px}.tail-datetime-calendar .calendar-tooltip:before{top:-7px;left:50%;width:0;height:0;margin:0 0 0 -6px;content:"";display:block;position:absolute;border-width:0 7px 7px 7px;border-style:solid;border-color:transparent transparent #202428 transparent}.tail-datetime-calendar .calendar-tooltip .tooltip-inner{width:auto;margin:0;padding:4px 7px;display:block;font-size:12px;line-height:14px}.tail-datetime-calendar .calendar-actions{color:#fff;width:100%;height:36px;margin:0;padding:0;display:table;overflow:hidden;border-spacing:0;border-collapse:separate;background-color:#149be6;border-width:0;border-style:solid;border-color:transparent;border-radius:3px 3px 0 0}.tail-datetime-calendar .calendar-actions span{margin:0;padding:0;display:table-cell;position:relative;text-align:center;line-height:36px;text-shadow:-1px -1px 0 #0e6ca0;background-repeat:no-repeat;background-position:center center}.tail-datetime-calendar .calendar-actions span[data-action]{cursor:pointer}.tail-datetime-calendar .calendar-actions span.action{width:36px;font-size:22px}.tail-datetime-calendar .calendar-actions span.label{width:auto}.tail-datetime-calendar .calendar-actions span:first-child:before,.tail-datetime-calendar .calendar-actions span:last-child:before{top:5px;bottom:5px;width:1px;height:auto;margin:0;padding:0;content:"";display:inline-block;position:absolute;background-color:#107bb7}.tail-datetime-calendar .calendar-actions span:first-child:before{right:-1px}.tail-datetime-calendar .calendar-actions span:last-child:before{left:-1px}.tail-datetime-calendar .calendar-actions span:first-child:hover:before,.tail-datetime-calendar .calendar-actions span:last-child:hover:before{display:none}.tail-datetime-calendar .calendar-actions span[data-action]:hover{background-color:#107bb7}.tail-datetime-calendar .calendar-actions span.action-prev{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgNiAxNiI+PHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTYgMkwwIDhsNiA2VjJ6Ii8+PC9zdmc+")}.tail-datetime-calendar .calendar-actions span.action-next{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgNiAxNiI+PHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTAgMTRsNi02LTYtNnYxMnoiLz48L3N2Zz4=")}.tail-datetime-calendar .calendar-actions span.action-submit{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij48cGF0aCBmaWxsPSIjZmZmZmZmIiBkPSJNMTIgNWwtOCA4LTQtNCAxLjUtMS41TDQgMTBsNi41LTYuNUwxMiA1eiIvPjwvc3ZnPg==")}.tail-datetime-calendar .calendar-actions span.action-cancel{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij48cGF0aCBmaWxsPSIjZmZmZmZmIiBkPSJNNy40OCA4bDMuNzUgMy43NS0xLjQ4IDEuNDhMNiA5LjQ4bC0zLjc1IDMuNzUtMS40OC0xLjQ4TDQuNTIgOCAuNzcgNC4yNWwxLjQ4LTEuNDhMNiA2LjUybDMuNzUtMy43NSAxLjQ4IDEuNDhMNy40OCA4eiIvPjwvc3ZnPg==")}.tail-datetime-calendar .calendar-datepicker{width:100%;margin:0;padding:0;display:block;position:relative}.tail-datetime-calendar .calendar-datepicker table{width:100%;margin:0;padding:0;border-spacing:0;border-collapse:separate}.tail-datetime-calendar .calendar-datepicker table tr td,.tail-datetime-calendar .calendar-datepicker table tr th{color:#303438;height:30px;padding:0;position:relative;font-size:13px;text-align:center;font-weight:400;text-shadow:none;line-height:30px;background-color:transparent;border-width:0;border-style:solid;border-color:transparent;border-radius:0}.tail-datetime-calendar .calendar-datepicker table tr th{color:#fff;background-color:#303438}.tail-datetime-calendar .calendar-datepicker table tr td{cursor:pointer}.tail-datetime-calendar .calendar-datepicker table tr td span.inner{margin:0;padding:0;display:inline-block}.tail-datetime-calendar .calendar-datepicker table tr td.date-disabled{cursor:not-allowed;color:#909498;background-color:#f0f0f0}.tail-datetime-calendar .calendar-datepicker table tr td.date-disabled:after{left:3px;bottom:3px;width:35px;height:1px;margin:0;padding:0;content:"";display:inline-block;position:absolute;background-color:#bfbfbf;transform-origin:2px -5px;transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}.tail-datetime-calendar .calendar-datepicker table tr td.date-next,.tail-datetime-calendar .calendar-datepicker table tr td.date-previous{color:#909498;background-color:#f0f0f0}.tail-datetime-calendar .calendar-datepicker table tr td .tooltip-tick,.tail-datetime-calendar .calendar-datepicker table tr td.date-today:before{top:5px;width:5px;height:5px;margin:0;padding:0;z-index:20;content:"";display:inline-block;position:absolute;border-width:0;border-style:solid;border-color:transparent;border-radius:50%}.tail-datetime-calendar .calendar-datepicker table tr td.date-today:before{left:5px;background-color:#32b93c}.tail-datetime-calendar .calendar-datepicker table tr td .tooltip-tick{right:5px;background-color:#202428}.tail-datetime-calendar .calendar-datepicker table tr td .tooltip-tick:after,.tail-datetime-calendar .calendar-datepicker table tr td .tooltip-tick:before{display:none}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day,.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week{width:14.28571429%;height:35px}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day span.inner,.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week span.inner{width:31px;height:31px;line-height:29px;border-width:1px;border-style:solid;border-color:transparent;border-radius:50%}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day:hover span.inner,.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week:hover span.inner{border-color:#ccc}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day.date-disabled span.inner,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day.date-disabled:hover span.inner,.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week.date-disabled span.inner,.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week.date-disabled:hover span.inner{border-color:transparent}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day.date-select span.inner,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day.date-select:hover span.inner,.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week.date-select span.inner,.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week.date-select:hover span.inner{color:#32b93c;border-color:#32b93c}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year{width:33.33333333%;height:40px;transition:color 142ms linear;-webkit-transition:color 142ms linear}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade.date-today:before,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month.date-today:before,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year.date-today:before{left:50%;margin-left:-2.5px}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner{width:auto;height:31px;line-height:29px}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner:after,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner:before,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner:after,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner:before,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner:after,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner:before{width:20px;height:20px;content:"";z-index:15;display:inline-block;position:absolute;border-width:1px;border-style:solid;border-color:transparent;transition:all 142ms linear;-webkit-transition:all 142ms linear}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner:before,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner:before,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner:before{top:0;left:0}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade:hover span.inner:before,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month:hover span.inner:before,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year:hover span.inner:before{top:6px;left:6px;border-top-color:#ccc;border-left-color:#ccc}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner:after,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner:after,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner:after{right:0;bottom:0}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade:hover span.inner:after,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month:hover span.inner:after,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year:hover span.inner:after{right:6px;bottom:6px;border-right-color:#ccc;border-bottom-color:#ccc}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade,.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year{width:25%}.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner{height:54px;padding:7px 15px;text-align:left;line-height:20px}.tail-datetime-calendar .calendar-timepicker{width:100%;margin:0;padding:0;display:block;text-align:center;border-width:1px 0 0 0;border-style:solid;border-color:#d9d9d9}.tail-datetime-calendar .calendar-timepicker .timepicker-field{width:28%;margin:0;padding:15px 0 7px 0;display:inline-block;position:relative;text-align:center}.tail-datetime-calendar .calendar-timepicker .timepicker-field:first-of-type{text-align:right}.tail-datetime-calendar .calendar-timepicker .timepicker-field:last-of-type{text-align:left}.tail-datetime-calendar .calendar-timepicker .timepicker-field input[type=text]{color:#303438;width:100%;height:29px;margin:0;z-index:4;padding:3px 20px 3px 5px;outline:0;display:inline-block;position:relative;font-size:12px;text-align:center;line-height:23px;appearance:textfield;-moz-appearance:textfield;-webkit-appearance:textfield;background-color:#f0f0f0;border-width:0;border-style:solid;border-color:transparent;border-radius:3px;box-shadow:none;-webkit-box-shadow:none;transition:color 142ms linear,border 142ms linear,background 142ms linear;-webkit-transition:color 142ms linear,border 142ms linear,background 142ms linear}.tail-datetime-calendar .calendar-timepicker .timepicker-field input[type=text]:hover{color:#303438;background-color:#e0e0e0}.tail-datetime-calendar .calendar-timepicker .timepicker-field input[type=text]:focus{color:#fff;background-color:#32b93c}.tail-datetime-calendar .calendar-timepicker .timepicker-field input[type=text]:disabled{cursor:not-allowed;color:#a0a4a8;background-color:#f6f6f6}.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step{width:20px;height:15px;right:0;margin:0;padding:0;z-index:15;display:inline-block;position:absolute;background-color:#f0f0f0;box-shadow:none;-webkit-box-shadow:none;transition:border 142ms linear,background 142ms linear;-webkit-transition:border 142ms linear,background 142ms linear}.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step:before{top:4px;left:50%;width:0;height:0;margin:0 0 0 -4px;padding:0;content:"";display:inline-block;position:absolute;transition:border 142ms linear;-webkit-transition:border 142ms linear}.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-up{top:15px;border-width:0 0 1px 1px;border-style:solid;border-color:#fff;border-radius:0 2px 0 0}.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-up:hover{background-color:#e0e0e0}.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-up:before{border-width:0 4px 5px 4px;border-style:solid;border-color:transparent transparent #303438 transparent}.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-down{top:29px;border-width:1px 0 0 1px;border-style:solid;border-color:#fff;border-radius:0 0 2px 0}.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-down:hover{background-color:#e0e0e0}.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-down:before{border-width:5px 4px 0 4px;border-style:solid;border-color:#303438 transparent transparent transparent}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus+button.step-up{border-color:rgba(255,255,255,.8);background-color:#32b93c}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus+button.step-up:hover{background-color:#27912f}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus+button.step-up:before{border-bottom-color:#fff}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus+button+button.step-down{border-color:rgba(255,255,255,.8);background-color:#32b93c}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus+button+button.step-down:hover{background-color:#27912f}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus+button+button.step-down:before{border-top-color:#fff}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled+button.step-up{cursor:not-allowed;border-color:rgba(255,255,255,.8);background-color:#f6f6f6}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled+button.step-up:hover{background-color:#f6f6f6}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled+button.step-up:before{border-bottom-color:#a0a4a8}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled+button+button.step-down{cursor:not-allowed;border-color:rgba(255,255,255,.8);background-color:#f6f6f6}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled+button+button.step-down:hover{background-color:#f6f6f6}.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled+button+button.step-down:before{border-top-color:#a0a4a8}.tail-datetime-calendar .calendar-timepicker .timepicker-field label{color:#303438;margin:0;padding:0;display:block;font-size:12px;text-align:center}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch{cursor:pointer;margin:15px 0 -5px 0;display:block;text-align:center;vertical-align:top}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch:after,.tail-datetime-calendar .calendar-timepicker label.timepicker-switch:before{width:auto;margin:0;padding:0 5px;font-size:12px;line-height:16px;vertical-align:top}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch:before{content:attr(data-am)}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch:after{content:attr(data-pm)}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type=checkbox]{display:none}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type=checkbox]+span{display:inline-block;position:relative;vertical-align:top}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type=checkbox]+span:before{width:50px;height:16px;content:"";display:inline-block;vertical-align:top;border-width:1px;border-style:solid;border-color:#149be6;border-radius:14px;transition:border 284ms linear;-webkit-transition:border 284ms linear}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type=checkbox]+span:after{top:3px;left:4px;right:30px;width:auto;height:10px;margin:0;padding:0;content:"";display:inline-block;position:absolute;background-color:#149be6;border-radius:15px;vertical-align:top;transition:left 284ms linear,right 284ms linear 284ms,background 284ms linear;-webkit-transition:left 284ms linear,right 284ms linear 284ms,background 284ms linear}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type=checkbox]:checked+span:before{border-color:#32b93c}.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type=checkbox]:checked+span:after{left:30px;right:4px;background-color:#32b93c;transition:right 284ms linear,left 284ms linear 284ms,background 284ms linear;-webkit-transition:right 284ms linear,left 284ms linear 284ms,background 284ms linear}.tail-datetime-calendar .calendar-actions+.calendar-timepicker{border-width:0}.tail-datetime-calendar.rtl{direction:rtl}.tail-datetime-calendar.rtl .calendar-actions span.action-next,.tail-datetime-calendar.rtl .calendar-actions span.action-prev{transform:rotate(180deg);-moz-transform:rotate(180deg);-webkit-transform:rotate(180deg)}.tail-datetime-calendar.rtl .calendar-datepicker table tr td.date-disabled:after{right:3px;transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg)}.tail-datetime-calendar.rtl .calendar-datepicker table tr td.date-today:before{right:5px}.tail-datetime-calendar.rtl .calendar-datepicker table tr td .tooltip-tick{left:5px}.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade.date-today:before,.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-month.date-today:before,.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-year.date-today:before{right:50%;margin-right:-2.5px}.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade:hover span.inner:before,.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-month:hover span.inner:before,.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-year:hover span.inner:before{right:6px;border-right-color:#ccc}.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade span.inner:after,.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-month span.inner:after,.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-year span.inner:after{left:0}.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade:hover span.inner:after,.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-month:hover span.inner:after,.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-year:hover span.inner:after{left:6px;border-left-color:#ccc}.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade span.inner{text-align:right}.tail-datetime-calendar.rtl .calendar-timepicker .timepicker-field:first-child{text-align:left;padding-left:0;padding-right:25px}.tail-datetime-calendar.rtl .calendar-timepicker .timepicker-field:last-child{text-align:right;padding-left:25px;padding-right:0}.tail-datetime-calendar.rtl .calendar-timepicker .timepicker-field:first-child input[type=text]{margin-left:-1px;margin-right:0;border-radius:0 3px 3px 0}.tail-datetime-calendar.rtl .calendar-timepicker .timepicker-field:last-child input[type=text]{margin-left:0;margin-right:-1px;border-radius:3px 0 0 3px} \ No newline at end of file diff --git a/public/tail.datetime/tail.datetime-default-blue.min.map b/public/tail.datetime/tail.datetime-default-blue.min.map deleted file mode 100644 index aa615d22..00000000 --- a/public/tail.datetime/tail.datetime-default-blue.min.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["$stdin"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/public/tail.datetime/tail.datetime.min.js b/public/tail.datetime/tail.datetime.min.js deleted file mode 100644 index 5225baa5..00000000 --- a/public/tail.datetime/tail.datetime.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/* pytesNET/tail.DateTime v.0.4.14 | Basic Version | @author SamBrishes, pytesNET | @license MIT */ -!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t,t.document)}):"object"==typeof module&&module.exports?module.exports=e(t,t.document):(void 0===t.tail&&(t.tail={}),t.tail.DateTime=t.tail.datetime=e(t,t.document),"undefined"!=typeof jQuery&&(jQuery.fn.DateTime=jQuery.fn.datetime=function(t){var e,i=[];return this.each(function(){!1!==(e=tail.DateTime(this,t))&&i.push(e)}),1===i.length?i[0]:0!==i.length&&i}),"undefined"!=typeof MooTools&&(Element.implement({DateTime:function(t){return new tail.DateTime(this,t)}}),Element.implement({datetime:function(t){return new tail.DateTime(this,t)}})))}(window,function(h,d){"use strict";function u(t,e){return!!(t&&"classList"in t)&&t.classList.contains(e)}function a(t,e){return t&&"classList"in t?t.classList.add(e):void 0}function n(t,e){return t&&"classList"in t?t.classList.remove(e):void 0}function s(t,e,i){if(CustomEvent&&CustomEvent.name)var a=new CustomEvent(e,i);else(a=d.createEvent("CustomEvent")).initCustomEvent(e,!!i.bubbles,!!i.cancelable,i.detail);return t.dispatchEvent(a)}function o(t,e){if("function"==typeof Object.assign)return Object.assign({},t,e||{});var i=Object.constructor();for(var a in t)i[a]=a in e?e[a]:t[a];return i}function p(t,e){var i=d.createElement(t);return i.className=e&&e.join?e.join(" "):e||"",i}function r(t){return t.charAt(0).toUpperCase()+t.slice(1)}function c(t,e,i){var a=t instanceof Date?t:!!t&&new Date(t);return a instanceof Date&&!isNaN(a.getDate())&&(i&&a.setHours(0,0,0,0),!0===e?a.getTime():a)}d.forms.inputmode=!0;var l=function(t,e){if((t="string"==typeof t?d.querySelectorAll(t):t)instanceof NodeList||t instanceof HTMLCollection||t instanceof Array){for(var i=[],a=t.length,n=0;n\n\n";for(var e=0;e<7;e++)this.weekdays+=''+t[e]+"";this.weekdays+="\n\n",this.select=c(this.e.getAttribute("data-value")||this.e.value),(!this.select||this.selectthis.con.dateEnd)&&(this.select=null),null==this.view&&(this.view={type:this.con.viewDefault,date:this.select||new Date});var i=["Hours","Minutes","Seconds"];for(e=0;e<3;e++)if("number"==typeof this.con["time"+i[e]])this.view.date["set"+i[e]](this.con["time"+i[e]]);else for(;this.view.date["get"+i[e]]()%this.con["timeStep"+i[e]]!=0;)this.view.date["set"+i[e]](this.view.date["get"+i[e]]()+1);return this.ampm=!!this.con.time12h&&12n[i].end?[n[i].end,n[i].end=n[i].start][0]:n[i].start),n[i].days=!("days"in n[i])||n[i].days,n[i].days="boolean"!=typeof n[i].days?function(t){for(var e=[],i=t.length,a=0;a'+s[i].text||"Tooltip",r)}));this.con.tooltips=t}var r;return this},bind:function(){var e=this;return void 0===this._bind&&(this.e.addEventListener("focusin",function(t){e.open.call(e)}),this.e.addEventListener("keyup",function(t){e.callback.call(e,t)}),d.addEventListener("keyup",function(t){e.dt.contains(t.target)&&e.callback.call(e,t)}),d.addEventListener("click",function(t){e.dt.contains(t.target)?e.callback.call(e,t):!e.e.contains(t.target)&&u(e.dt,"calendar-open")&&(t.target==e.dt||t.target==e.e||e.con.stayOpen||e.close.call(e))}),d.addEventListener("mouseover",function(t){e.dt.contains(t.target)&&e.callback.call(e,t)}),this._bind=!0),this},callback:function(t){var e,i=t.target,a="getAttribute",n="data-action",s=i[a](n)?i:i.parentElement[a](n)?i.parentElement:i,r="data-tooltip";if("mouseover"==t.type&&(!1!==(e=i[a](r)?i:!!s[a](r)&&s)?this.dt.querySelector("#tooltip-"+e[a](r)+"-"+e[a](r+"-time"))||this.showTooltip(e[a](r),e,e[a](r+"-time")):this.dt.querySelector(".calendar-tooltip:not(.remove)")&&this.hideTooltip(this.dt.querySelector(".calendar-tooltip").id.slice(8))),"click"==t.type){if(!s||1!=t.buttons&&1!=(t.which||t.button))return;if(s.hasAttribute("data-disabled"))return;switch(s[a](n)){case"prev":case"next":return this.browseView(s[a](n));case"cancel":this.con.stayOpen||this.close();break;case"submit":return this.con.stayOpen||this.close(),this.selectDate(this.fetchDate(parseInt(s[a]("data-date"))));case"view":return this.switchDate(s[a]("data-year")||null,s[a]("data-month")||null,s[a]("data-day")||null),this.switchView(s[a]("data-view"))}}if("keyup"==t.type){if("INPUT"!=t.target.tagName&&t.target!==this.e&&/calendar-(static|close)/i.test(this.dt.className))return!1;13==(t.keyCode||t.which)&&(this.selectDate(this.fetchDate(this.select)),t.stopPropagation(),this.con.stayOpen||this.close()),27==(t.keyCode||t.which)&&(this.con.stayOpen||this.close())}},trigger:function(t){var e={bubbles:!1,cancelable:!0,detail:{args:arguments,self:this}};"change"==t&&(s(this.e,"input",e),s(this.e,"change",e)),s(this.dt,"tail::"+t,e);for(var i=(this.events[t]||[]).length,a=0;a':this.con.timeFormat&&(n=''),a.innerHTML=n?'
'+n+"
":"",this.con.dateFormat&&this.renderDatePicker(a,this.con.viewDefault),this.con.timeFormat&&this.renderTimePicker(a),this.con.closeButton&&!i){var s=p("BUTTON","calendar-close"),r=this;s.addEventListener("click",function(t){t.preventDefault(),r.close()}),a.appendChild(s)}return(i||d.body).appendChild(a),a},renderDatePicker:function(t,e){if((!e||["decades","years","months","days"].indexOf(e)<0)&&(e=this.con.viewDays?"days":this.con.viewMonths?"months":this.con.viewYears?"years":!!this.con.viewDecades&&"decades"),!e||!this.con["view"+r(e)]||!this.con.dateFormat)return!1;var i=d.createElement("DIV");return i.className="calendar-datepicker calendar-view-"+e,i.innerHTML=this["view"+r(e)](),t.querySelector(".calendar-datepicker")?t.replaceChild(i,t.querySelector(".calendar-datepicker")):t.appendChild(i),this.view.type=e,this.handleLabel(t)},renderTimePicker:function(t){if(!this.con.timeFormat)return!1;var e,i,a=[],n=0;if(this.con.time12h){var s=12")}for(var r in{Hours:0,Minutes:0,Seconds:0})!1!==this.con["time"+r]?((e=d.createElement("INPUT")).type="text",e.disabled=null===this.con["time"+r],e.setAttribute("min","Hours"===r&&this.con.time12h?"01":"00"),e.setAttribute("max","Hours"!==r?"60":this.con.time12h?"13":"24"),e.setAttribute("step",this.con["timeStep"+r]),e.setAttribute("value",(i=this.view.date["get"+r]())<10?"0"+i:i),e.setAttribute("pattern","d*"),e.setAttribute("inputmode","numeric"),e.setAttribute("data-input",r.toLowerCase()),a.push('
'+e.outerHTML+'
")):a.push((n++,null));var o=p("DIV","calendar-timepicker"),c=this;o.innerHTML=a.join("\n");var l=o.querySelectorAll("input");for(n=0;n=e.getYear()&&i<=e.getYear()+10?" date-today":""),n='data-action="view" data-view="down" data-year="'+e.getFullYear()+'"',s.push(''+e.getFullYear()+" - "+(e.getFullYear()+10)+""),4<=o&&o%4==0&&(r.push("\n"+s.join("\n")+"\n"),s=[]),e.setFullYear(e.getFullYear()+10);return'"+r.join("\n")+"
'+this.__.header[2]+"
"},viewYears:function(){var t=this.view.date.getFullYear(),e=new Date(this.view.date.getTime()),i=this.con.today?(new Date).getYear():0;e.setFullYear(t-parseInt(t.toString()[3])-2);for(var a,n,s=[],r=[],o=1;o<=16;o++)a="calendar-year"+(e.getYear()==i?" date-today":""),n='data-action="view" data-view="down" data-year="'+e.getFullYear()+'"',s.push(''+e.getFullYear()+""),4<=o&&o%4==0&&(r.push("\n"+s.join("\n")+"\n"),s=[]),e.setFullYear(e.getFullYear()+1);return'"+r.join("\n")+"
'+this.__.header[1]+"
"},viewMonths:function(){var t=this.__.months,e=this.con.today?(new Date).getMonth():-1;e=this.view.date.getYear()==(new Date).getYear()?e:-1;for(var i,a,n=[],s=[],r=0;r<12;r++)i="calendar-month"+(e==r?" date-today":""),a='data-action="view" data-view="down" data-month="'+r+'"',n.push(''+t[r]+""),3==n.length&&(s.push("\n"+n.join("\n")+"\n"),n=[]);return'"+s.join("\n")+"
'+this.__.header[0]+"
"},viewDays:function(){var i,t,e,a,n,s,r=new Date(this.view.date.getTime()),o=(new Date).toDateString(),c=r.getMonth(),l=[],h=[],d=[0,[]],u=([].concat(this.con.tooltips),[0,0]);for(r.setHours(0,0,0,0),r.setDate(1),r.setDate(1-(r.getDay()-this.con.weekStart));h.length<6;)i=r.getTime(),s=[].concat(this.con.dateRanges),e='data-action="submit" data-date="'+r.getTime()+'"',t="calendar-day date-"+(r.getMonth()>c?"next":r.getMonth()this.con.dateEnd)?d=[i=t.start&&i<=t.end?!(d=[t.end,t.days]):t.start>i},this):3==d.length&&(d=[0,[0,1,2,3,4,5,6]]),0=i&&(u=[t.date[1],e,t.color]):t.date==i&&(u=[t.date,e,t.color])},this),u[0]=i&&0<=d[1].indexOf(r.getDay()))&&this.con.dateBlacklist||!n&&!this.con.dateBlacklist?(t+=" date-disabled",e+=' data-disabled="true"'):0!==d[0]&&d[0]<=i&&(d=[0,[]]),this.select&&this.select.toDateString()==r.toDateString()&&(t+=" date-select"),a=''+r.getDate()+"",0':a+=''),l.push('"+a+""),7==l.length&&(h.push("\n"+l.join("\n")+"\n"),l=[]),r.setDate(r.getDate()+1);return h=""+h.join("\n")+"",''+this.weekdays+h+"
"},showTooltip:function(t,e,i){var a,n=this.con.tooltips[t].element,s=n.style,r=this.dt.querySelector(".calendar-datepicker");s.cssText="opacity:0;visibility:hidden;",n.id="tooltip-"+t+"-"+i,r.appendChild(n),a=n.offsetWidth,n.offsetHeight,s.top=e.offsetTop+e.offsetHeight+"px",s.left=e.offsetLeft+e.offsetWidth/2-a/2+"px",s.visibility="visible",this.con.animate?(n.setAttribute("data-top",parseInt(s.top)),s.top=parseInt(s.top)+5+"px",function t(){parseFloat(s.top)>n.getAttribute("data-top")&&(s.top=parseFloat(s.top)-.5+"px"),(s.opacity=parseFloat(s.opacity)+.125)<1&&setTimeout(t,20)}()):s.opacity=1},hideTooltip:function(t){var e=this.dt.querySelector("#tooltip-"+t),i=e.style;this.con.animate?(e.className+=" remove",function t(){if(parseFloat(i.top)'); - }; - - /* - // may not be needed, saving for later. Can be called to resize iFrame - obj.resizeContent = function() { - var iFrame = document.getElementById('pluginIframeScriptTask'); - var newHeight = 800; - var sHeight = iFrame.contentWindow.document.body.scrollHeight; - if (sHeight > newHeight) newHeight = sHeight; - if (newHeight > 1600) newHeight = 1600; - iFrame.style.height = newHeight + 'px'; - }; - */ - - obj.queueRun = async function() { - var onlineAgents = Object.keys(obj.meshServer.webserver.wsagents); - //obj.debug('ScriptTask', 'Queue Running', Date().toLocaleString(), 'Online agents: ', onlineAgents); - - obj.db.getPendingJobs(onlineAgents) - .then(function(jobs) { - if (jobs.length == 0) return; - //@TODO check for a large number and use taskLimiter to queue the jobs - jobs.forEach(function(job) { - obj.db.get(job.scriptId) - .then(async function(script) { - script = script[0]; - var foundVars = script.content.match(/#(.*?)#/g); - var replaceVars = {}; - if (foundVars != null && foundVars.length > 0) { - var foundVarNames = []; - foundVars.forEach(function(fv) { foundVarNames.push(fv.replace(/^#+|#+$/g, '')); }); - - var limiters = { - scriptId: job.scriptId, - nodeId: job.node, - meshId: obj.meshServer.webserver.wsagents[job.node]['dbMeshKey'], - names: foundVarNames - }; - var finvals = await obj.db.getVariables(limiters); - var ordering = { 'global': 0, 'script': 1, 'mesh': 2, 'node': 3 } - finvals.sort(function(a, b) { return (ordering[a.scope] - ordering[b.scope]) || a.name.localeCompare(b.name); }); - finvals.forEach(function(fv) { replaceVars[fv.name] = fv.value; }); - replaceVars['GBL:meshId'] = obj.meshServer.webserver.wsagents[job.node]['dbMeshKey']; - replaceVars['GBL:nodeId'] = job.node; - //console.log('FV IS', finvals); - //console.log('RV IS', replaceVars); - } - var dispatchTime = Math.floor(new Date() / 1000); - var jObj = { - action: 'task', - subaction: 'triggerJob', - jobId: job._id, - scriptId: job.scriptId, - replaceVars: replaceVars, - scriptHash: script.contentHash, - dispatchTime: dispatchTime - }; - //obj.debug('ScriptTask', 'Sending job to agent'); - try { - obj.meshServer.webserver.wsagents[job.node].send(JSON.stringify(jObj)); - obj.db.update(job._id, { dispatchTime: dispatchTime }); - } catch (ex) { } - }) - .catch(function (ex) { console.log('task: Could not dispatch job.', ex) }); - }); - }) - .then(function() { - obj.makeJobsFromSchedules(); - obj.cleanHistory(); - }) - .catch(function(ex) { console.log('task: Queue Run Error: ', ex); }); - }; - - obj.cleanHistory = function() { - if (Math.round(Math.random() * 100) == 99) { - //obj.debug('Task', 'Running history cleanup'); - obj.db.deleteOldHistory(); - } - }; - - obj.downloadFile = function(req, res, user) { - var id = req.query.dl; - obj.db.get(id) - .then(function(found) { - if (found.length != 1) { res.sendStatus(401); return; } - var file = found[0]; - res.setHeader('Content-disposition', 'attachment; filename=' + file.name); - res.setHeader('Content-type', 'text/plain'); - //var fs = require('fs'); - res.send(file.content); - }); - }; - - obj.updateFrontEnd = async function(ids){ - if (ids.scriptId != null) { - var scriptHistory = null; - obj.db.getJobScriptHistory(ids.scriptId) - .then(function(sh) { - scriptHistory = sh; - return obj.db.getJobSchedulesForScript(ids.scriptId); - }) - .then(function(scriptSchedule) { - var targets = ['*', 'server-users']; - obj.meshServer.DispatchEvent(targets, obj, { nolog: true, action: 'task', subaction: 'historyData', scriptId: ids.scriptId, nodeId: null, scriptHistory: scriptHistory, nodeHistory: null, scriptSchedule: scriptSchedule }); - }); - } - if (ids.nodeId != null) { - var nodeHistory = null; - obj.db.getJobNodeHistory(ids.nodeId) - .then(function(nh) { - nodeHistory = nh; - return obj.db.getJobSchedulesForNode(ids.nodeId); - }) - .then(function(nodeSchedule) { - var targets = ['*', 'server-users']; - obj.meshServer.DispatchEvent(targets, obj, { nolog: true, action: 'task', subaction: 'historyData', scriptId: null, nodeId: ids.nodeId, scriptHistory: null, nodeHistory: nodeHistory, nodeSchedule: nodeSchedule }); - }); - } - if (ids.tree === true) { - obj.db.getScriptTree() - .then(function(tree) { - var targets = ['*', 'server-users']; - obj.meshServer.DispatchEvent(targets, obj, { nolog: true, action: 'task', subaction: 'newScriptTree', tree: tree }); - }); - } - if (ids.variables === true) { - obj.db.getVariables() - .then(function(vars) { - var targets = ['*', 'server-users']; - obj.meshServer.DispatchEvent(targets, obj, { nolog: true, action: 'task', subaction: 'variableData', vars: vars }); - }); - } - }; - - obj.handleAdminReq = function(req, res, user) { - if ((user.siteadmin & 0xFFFFFFFF) == 1 && req.query.admin == 1) - { - // admin wants admin, grant - var vars = {}; - res.render(obj.VIEWS + 'admin', vars); - return; - } else if (req.query.admin == 1 && (user.siteadmin & 0xFFFFFFFF) == 0) { - // regular user wants admin - res.sendStatus(401); - return; - } else if (req.query.user == 1) { - // regular user wants regular access, grant - if (req.query.dl != null) return obj.downloadFile(req, res, user); - var vars = {}; - - if (req.query.edit == 1) { // edit script - if (req.query.id == null) return res.sendStatus(401); - obj.db.get(req.query.id) - .then(function(scripts) { - if (scripts[0].filetype == 'proc') { - vars.procData = JSON.stringify(scripts[0]); - res.render(obj.VIEWS + 'procedit', vars); - } else { - vars.scriptData = JSON.stringify(scripts[0]); - res.render(obj.VIEWS + 'scriptedit', vars); - } - }); - return; - } else if (req.query.schedule == 1) { - var vars = {}; - res.render(obj.VIEWS + 'schedule', vars); - return; - } - // default user view (tree) - vars.scriptTree = 'null'; - obj.db.getScriptTree() - .then(function(tree) { - vars.scriptTree = JSON.stringify(tree); - res.render(obj.VIEWS + 'user', vars); - }); - return; - } else if (req.query.include == 1) { - switch (req.query.path.split('/').pop().split('.').pop()) { - case 'css': res.contentType('text/css'); break; - case 'js': res.contentType('text/javascript'); break; - } - res.sendFile(__dirname + '/includes/' + req.query.path); // don't freak out. Express covers any path issues. - return; - } - res.sendStatus(401); - return; - }; - - obj.historyData = function (message) { - if (typeof pluginHandler.scripttask.loadHistory == 'function') pluginHandler.scripttask.loadHistory(message); - if (typeof pluginHandler.scripttask.loadSchedule == 'function') pluginHandler.scripttask.loadSchedule(message); - }; - - obj.variableData = function (message) { - if (typeof pluginHandler.scripttask.loadVariables == 'function') pluginHandler.scripttask.loadVariables(message); - }; - - obj.determineNextJobTime = function(s) { - var nextTime = null; - var nowTime = Math.floor(new Date() / 1000); - - // special case: we've reached the end of our run - if (s.endAt !== null && s.endAt <= nowTime) { - return nextTime; - } - - switch (s.recur) { - case 'once': - if (s.nextRun == null) nextTime = s.startAt; - else nextTime = null; - break; - case 'minutes': - /*var lRun = s.nextRun || nowTime; - if (lRun == null) lRun = nowTime; - nextTime = lRun + (s.interval * 60); - if (s.startAt > nextTime) nextTime = s.startAt;*/ - if (s.nextRun == null) { // hasn't run yet, set to start time - nextTime = s.startAt; - break; - } - nextTime = s.nextRun + (s.interval * 60); - // this prevents "catch-up" tasks being scheduled if an endpoint is offline for a long period of time - // e.g. always make sure the next scheduled time is relevant to the scheduled interval, but in the future - if (nextTime < nowTime) { - // initially I was worried about this causing event loop lockups - // if there was a long enough time gap. Testing over 50 years of backlog for a 3 min interval - // still ran under a fraction of a second. Safe to say this approach is safe! (~8.5 million times) - while (nextTime < nowTime) { - nextTime = nextTime + (s.interval * 60); - } - } - if (s.startAt > nextTime) nextTime = s.startAt; - break; - case 'hourly': - if (s.nextRun == null) { // hasn't run yet, set to start time - nextTime = s.startAt; - break; - } - nextTime = s.nextRun + (s.interval * 60 * 60); - if (nextTime < nowTime) { - while (nextTime < nowTime) { - nextTime = nextTime + (s.interval * 60 * 60); - } - } - if (s.startAt > nextTime) nextTime = s.startAt; - break; - case 'daily': - if (s.nextRun == null) { // hasn't run yet, set to start time - nextTime = s.startAt; - break; - } - nextTime = s.nextRun + (s.interval * 60 * 60 * 24); - if (nextTime < nowTime) { - while (nextTime < nowTime) { - nextTime = nextTime + (s.interval * 60 * 60 * 24); - } - } - if (s.startAt > nextTime) nextTime = s.startAt; - break; - case 'weekly': - var tempDate = new Date(); - var nowDate = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate()); - - if (s.daysOfWeek.length == 0) { - nextTime = null; - break; - } - s.daysOfWeek = s.daysOfWeek.map(function (el) { Number(el) }); - var baseTime = s.startAt; - //console.log('dow is ', s.daysOfWeek); - var lastDayOfWeek = Math.max(...s.daysOfWeek); - var startX = 0; - //console.log('ldow is ', lastDayOfWeek); - if (s.nextRun != null) { - baseTime = s.nextRun; - //console.log('basetime 2: ', baseTime); - if (nowDate.getDay() == lastDayOfWeek) { - baseTime = baseTime + ( s.interval * 604800 ) - (lastDayOfWeek * 86400); - //console.log('basetime 3: ', baseTime); - } - startX = 0; - } else if (s.startAt < nowTime) { - baseTime = Math.floor(nowDate.getTime() / 1000); - //console.log('basetime 4: ', baseTime); - } - //console.log('startX is: ', startX); - //var secondsFromMidnight = nowTimeDate.getSeconds() + (nowTimeDate.getMinutes() * 60) + (nowTimeDate.getHours() * 60 * 60); - //console.log('seconds from midnight: ', secondsFromMidnight); - //var dBaseTime = new Date(0); dBaseTime.setUTCSeconds(baseTime); - //var dMidnight = new Date(dBaseTime.getFullYear(), dBaseTime.getMonth(), dBaseTime.getDate()); - //baseTime = Math.floor(dMidnight.getTime() / 1000); - for (var x = startX; x <= 7; x++){ - var checkDate = baseTime + (86400 * x); - var d = new Date(0); d.setUTCSeconds(checkDate); - var dm = new Date(d.getFullYear(), d.getMonth(), d.getDate()); - - console.log('testing date: ', dm.toLocaleString()); // dMidnight.toLocaleString()); - //console.log('if break check :', (s.daysOfWeek.indexOf(d.getDay()) !== -1 && checkDate >= nowTime)); - //console.log('checkDate vs nowTime: ', (checkDate - nowTime), ' if positive, nowTime is less than checkDate'); - if (s.nextRun == null && s.daysOfWeek.indexOf(dm.getDay()) !== -1 && dm.getTime() >= nowDate.getTime()) break; - if (s.daysOfWeek.indexOf(dm.getDay()) !== -1 && dm.getTime() > nowDate.getTime()) break; - //if (s.daysOfWeek.indexOf(d.getDay()) !== -1 && Math.floor(d.getTime() / 1000) >= nowTime) break; - } - var sa = new Date(0); sa.setUTCSeconds(s.startAt); - var sad = new Date(sa.getFullYear(), sa.getMonth(), sa.getDate()); - var diff = (sa.getTime() - sad.getTime()) / 1000; - nextTime = Math.floor(dm.getTime() / 1000) + diff; - //console.log('next schedule is ' + d.toLocaleString()); - break; - default: - nextTime = null; - break; - } - - if (s.endAt != null && nextTime > s.endAt) nextTime = null; // if the next time reaches the bound of the endAt time, nullify - - return nextTime; - }; - - obj.makeJobsFromSchedules = function(scheduleId) { - //obj.debug('ScriptTask', 'makeJobsFromSchedules starting'); - return obj.db.getSchedulesDueForJob(scheduleId) - .then(function(schedules) { - //obj.debug('ScriptTask', 'Found ' + schedules.length + ' schedules to process. Current time is: ' + Math.floor(new Date() / 1000)); - if (schedules.length) { - schedules.forEach(function(s) { - var nextJobTime = obj.determineNextJobTime(s); - var nextJobScheduled = false; - if (nextJobTime === null) { - //obj.debug('ScriptTask', 'Removing Job Schedule for', JSON.stringify(s)); - obj.db.removeJobSchedule(s._id); - } else { - //obj.debug('ScriptTask', 'Scheduling Job for', JSON.stringify(s)); - obj.db.get(s.scriptId) - .then(function(scripts) { - // if a script is scheduled to run, but a previous run hasn't completed, - // don't schedule another job for the same (device probably offline). - // results in the minimum jobs running once an agent comes back online. - return obj.db.getIncompleteJobsForSchedule(s._id) - .then(function(jobs) { - if (jobs.length > 0) { /* obj.debug('Task', 'Skipping job creation'); */ return Promise.resolve(); } - else { /* obj.debug('Task', 'Creating new job'); */ nextJobScheduled = true; return obj.db.addJob( { scriptId: s.scriptId, scriptName: scripts[0].name, node: s.node, runBy: s.scheduledBy, dontQueueUntil: nextJobTime, jobSchedule: s._id } ); } - }); - }) - .then(function() { - if (nextJobScheduled) { /* obj.debug('Plugin', 'ScriptTask', 'Updating nextRun time'); */ return obj.db.update(s._id, { nextRun: nextJobTime }); } - else { /* obj.debug('Plugin', 'ScriptTask', 'NOT updating nextRun time'); */ return Promise.resolve(); } - }) - .then(function() { - obj.updateFrontEnd( { scriptId: s.scriptId, nodeId: s.node } ); - }) - .catch(function(ex) { console.log('Task: Error managing job schedules: ', ex); }); - } - }); - } - }); - }; - - obj.deleteElement = function (command) { - var delObj = null; - obj.db.get(command.id) - .then(function(found) { - var file = found[0]; - delObj = {...{}, ...found[0]}; - return file; - }) - .then(function(file) { - if (file.type == 'folder') return obj.db.deleteByPath(file.path); //@TODO delete schedules for scripts within folders - if (file.type == 'script') return obj.db.deleteSchedulesForScript(file._id); - if (file.type == 'jobSchedule') return obj.db.deletePendingJobsForSchedule(file._id); - }) - .then(function() { - return obj.db.delete(command.id) - }) - .then(function() { - var updateObj = { tree: true }; - if (delObj.type == 'jobSchedule') { - updateObj.scriptId = delObj.scriptId; - updateObj.nodeId = delObj.node; - } - return obj.updateFrontEnd( updateObj ); - }) - .catch(function(ex) { console.log('Task: Error deleting ', ex.stack); }); - }; - - // Process 'task' commands received by an agent - obj.agentAction = function (command, agent) { - console.log('task-agentAction', command); - switch (command.subaction) { - case 'getScript': - // TODO - break; - case 'clearAllPendingTasks': - // TODO - break; - case 'taskComplete': - // TODO - break; - } - } - - obj.serveraction = function(command, myparent, grandparent) { - switch (command.subaction) { - case 'addScript': - obj.db.addScript(command.name, command.content, command.path, command.filetype) - .then(function() { obj.updateFrontEnd( { tree: true } ); }); - break; - case 'new': - var parent_path = '', new_path = ''; - obj.db.get(command.parent_id) - .then(function(found) { if (found.length > 0) { var file = found[0]; parent_path = file.path; } else { parent_path = 'Shared'; } }) - .then(function () { obj.db.addScript(command.name, '', parent_path, command.filetype); }) - .then(function() { obj.updateFrontEnd( { tree: true } ); }); - break; - case 'rename': - obj.db.get(command.id) - .then(function(docs) { - var doc = docs[0]; - if (doc.type == 'folder') { - console.log('old', doc.path, 'new', doc.path.replace(doc.path, command.name)); - return obj.db.update(command.id, { path: doc.path.replace(doc.name, command.name) }) - .then(function() { // update sub-items - return obj.db.getByPath(doc.path) - }) - .then(function(found) { - if (found.length > 0) { - var proms = []; - found.forEach(function(f) { proms.push(obj.db.update(f._id, { path: doc.path.replace(doc.name, command.name) } )); }) - return Promise.all(proms); - } - }) - } else { - return Promise.resolve(); - } - }) - .then(function() { - obj.db.update(command.id, { name: command.name }) - }) - .then(function() { - return obj.db.updateScriptJobName(command.id, command.name); - }) - .then(function() { - obj.updateFrontEnd( { scriptId: command.id, nodeId: command.currentNodeId, tree: true } ); - }); - break; - case 'move': - var toPath = null, fromPath = null, parentType = null; - obj.db.get(command.to) - .then(function(found) { // get target data - if (found.length > 0) { - var file = found[0]; - toPath = file.path; - } else throw Error('Target destination not found'); - }) - .then(function() { // get item to be moved - return obj.db.get(command.id); - }) - .then(function(found) { // set item to new location - var file = found[0]; - if (file.type == 'folder') { - fromPath = file.path; - toPath += '/' + file.name; - parentType = 'folder'; - if (file.name == 'Shared' && file.path == 'Shared') throw Error('Cannot move top level directory: Shared'); - } - return obj.db.update(command.id, { path: toPath } ); - }) - .then(function() { // update sub-items - return obj.db.getByPath(fromPath) - }) - .then(function(found) { - if (found.length > 0) { - var proms = []; - found.forEach(function(f) { - proms.push(obj.db.update(f._id, { path: toPath } )); - }) - return Promise.all(proms); - } - }) - .then(function() { - return obj.updateFrontEnd( { tree: true } ); - }) - .catch(function(ex) { console.log('Task: Error moving ', ex.stack); }); - break; - case 'newFolder': - var parent_path = ''; - var new_path = ''; - - obj.db.get(command.parent_id) - .then(function(found) { - if (found.length > 0) { - var file = found[0]; - parent_path = file.path; - } else { - parent_path = 'Shared'; - } - }) - .then(function() { - new_path = parent_path + '/' + command.name; - }) - .then(function() { - return obj.db.addFolder(command.name, new_path); - }) - .then(function () { - return obj.updateFrontEnd( { tree: true } ); - }) - .catch(function(ex) { console.log('Task: Error creating new folder ', ex.stack); }); - break; - case 'delete': - obj.deleteElement(command); - break; - case 'addScheduledJob': - /* { - scriptId: scriptId, - node: s, - scheduledBy: myparent.user.name, - recur: command.recur, // [once, minutes, hourly, daily, weekly, monthly] - interval: x, - daysOfWeek: x, // only used for weekly recur val - // onTheXDay: x, // only used for monthly - startAt: x, - endAt: x, - runCountLimit: x, - lastRun: x, - nextRun: x, - type: "scheduledJob" - } */ - var sj = command.schedule; - - var sched = { - scriptId: command.scriptId, - node: null, - scheduledBy: myparent.user.name, - recur: sj.recur, - interval: sj.interval, - daysOfWeek: sj.dayVals, - startAt: sj.startAt, - endAt: sj.endAt, - lastRun: null, - nextRun: null, - type: "jobSchedule" - }; - var sel = command.nodes; - var proms = []; - if (Array.isArray(sel)) { - sel.forEach(function(s) { - var sObj = {...sched, ...{ node: s }}; - proms.push(obj.db.addJobSchedule( sObj )); - }); - } else { test.push(sObj); - proms.push(obj.db.addJobSchedule( sObj )); - } - Promise.all(proms) - .then(function() { - obj.makeJobsFromSchedules(); - return Promise.resolve(); - }) - .catch(function(ex) { console.log('Task: Error adding schedules. The error was: ', ex); }); - break; - case 'runScript': - var scriptId = command.scriptId; - var sel = command.nodes; - var proms = []; - if (Array.isArray(sel)) { - sel.forEach(function(s) { - proms.push(obj.db.addJob( { scriptId: scriptId, node: s, runBy: myparent.user.name } )); - }); - } else { - proms.push(obj.db.addJob( { scriptId: scriptId, node: sel, runBy: myparent.user.name } )); - } - Promise.all(proms) - .then(function() { - return obj.db.get(scriptId); - }) - .then(function(scripts) { - return obj.db.updateScriptJobName(scriptId, scripts[0].name); - }) - .then(function() { - obj.resetQueueTimer(); - obj.queueRun(); - obj.updateFrontEnd( { scriptId: scriptId, nodeId: command.currentNodeId } ); - }); - break; - case 'getScript': - //obj.debug('ScriptTask', 'getScript Triggered', JSON.stringify(command)); - obj.db.get(command.scriptId) - .then(function(script) { - myparent.send(JSON.stringify({ - action: 'task', - subaction: 'cacheScript', - nodeid: myparent.dbNodeKey, - rights: true, - sessionid: true, - script: script[0] - })); - }); - break; - case 'jobComplete': - //obj.debug('ScriptTask', 'jobComplete Triggered', JSON.stringify(command)); - var jobNodeHistory = null, scriptHistory = null; - var jobId = command.jobId, retVal = command.retVal, errVal = command.errVal, dispatchTime = command.dispatchTime; - var completeTime = Math.floor(new Date() / 1000); - obj.db.update(jobId, { - completeTime: completeTime, - returnVal: retVal, - errorVal: errVal, - dispatchTime: dispatchTime - }) - .then(function() { - return obj.db.get(jobId) - .then(function(jobs) { - return Promise.resolve(jobs[0].jobSchedule); - }) - .then(function(sId) { - if (sId == null) return Promise.resolve(); - return obj.db.update(sId, { lastRun: completeTime } ) - .then(function() { - obj.makeJobsFromSchedules(sId); - }); - }); - }) - .then(function() { - obj.updateFrontEnd( { scriptId: command.scriptId, nodeId: myparent.dbNodeKey } ); - }) - .catch(function(ex) { console.log('Task: Failed to complete job. ', ex); }); - // update front end by eventing - break; - case 'loadNodeHistory': - obj.updateFrontEnd( { nodeId: command.nodeId } ); - break; - case 'loadScriptHistory': - obj.updateFrontEnd( { scriptId: command.scriptId } ); - break; - case 'editScript': - obj.db.update(command.scriptId, { type: command.scriptType, name: command.scriptName, content: command.scriptContent }) - .then(function() { obj.updateFrontEnd( { scriptId: command.scriptId, tree: true } ); }); - break; - case 'clearAllPendingJobs': - obj.db.deletePendingJobsForNode(myparent.dbNodeKey); - break; - case 'loadVariables': - obj.updateFrontEnd( { variables: true } ); - break; - case 'newVar': - obj.db.addVariable(command.name, command.scope, command.scopeTarget, command.value) - .then(function() { obj.updateFrontEnd( { variables: true } ); }) - break; - case 'editVar': - obj.db.update(command.id, { - name: command.name, - scope: command.scope, - scopeTarget: command.scopeTarget, - value: command.value - }) - .then(function() { obj.updateFrontEnd( { variables: true } ); }) - break; - case 'deleteVar': - obj.db.delete(command.id) - .then(function() { obj.updateFrontEnd( { variables: true } ); }) - break; - default: - console.log('Task: unknown action'); - break; - } - }; return obj; } \ No newline at end of file diff --git a/views/default.handlebars b/views/default.handlebars index e0ce4e73..7f9f9869 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -5537,25 +5537,7 @@ p2downloadDeviceInfo(); } else if (op == 106) { // Run commands - var wintype = false, linuxtype = false, agenttype = false, chkNodeIds = getCheckedDevices(); - for (var i in chkNodeIds) { - var n = getNodeFromId(chkNodeIds[i]); - if (n.agent) { if ((GetNodeRights(n) & 24) == 24) { agenttype = true; } if ((n.agent.id > 0) && (n.agent.id < 5)) { wintype = true; } else { linuxtype = true; } } - } - if ((wintype == true) || (linuxtype == true) || (agenttype == true)) { - var x = "Run commands on selected devices." + '
'; - x += ''; - x += ''; - x += ''; - setDialogMode(2, "Run Commands", 3, d2groupActionFunctionRunCommands, x); - Q('d2runcmd').focus(); - //QE('idx_dlgOkButton', true); - d2runCommandValidate(); - } + d2runCommandDialog({ nodeids: getCheckedDevices(), title: "Run commands on selected devices.", func: uncheckAllDevices }); } else if (op == 107) { // Edit tags var x = "Perform batch device tag operation" + '

'; @@ -5611,7 +5593,6 @@ } } - function d2runCommandValidate() { QV('d2cmduser', Q('d2cmdtype').value < 4); } function d2batchUploadValidate() { QE('idx_dlgOkButton', (Q('d2uploadinput').files.length != 0) && ((Q('d2winuploadpath') == null) || (Q('d2winuploadpath').value != '')) && ((Q('d2linuxuploadpath') == null) || (Q('d2linuxuploadpath').value != ''))); } function d2batchUploadValidateOk() { Q('d2batchUploadSubmit').click(); } function d2groupActionFunctionAgentUpdateExec() { meshserver.send({ action: 'updateAgents', nodeids: getCheckedDevices() }); } @@ -5728,10 +5709,34 @@ function d2groupActionFunctionDelCheck() { QE('idx_dlgOkButton', Q('d2check').checked); } function d2groupActionFunctionDelExec() { meshserver.send({ action: 'removedevices', nodeids: getCheckedDevices() }); uncheckAllDevices(); } - function d2groupActionFunctionRunCommands() { + + function d2runCommandDialog(options) { + var wintype = false, linuxtype = false, agenttype = false; + for (var i in options.nodeids) { + var n = getNodeFromId(options.nodeids[i]); + if (n.agent) { if ((GetNodeRights(n) & 24) == 24) { agenttype = true; } if ((n.agent.id > 0) && (n.agent.id < 5)) { wintype = true; } else { linuxtype = true; } } + } + if ((wintype == true) || (linuxtype == true) || (agenttype == true)) { + var x = options.title + '
'; + x += ''; + x += ''; + x += ''; + setDialogMode(2, "Run Commands", 3, d2groupActionFunctionRunCommands, x, options); + Q('d2runcmd').focus(); + //QE('idx_dlgOkButton', true); + d2runCommandValidate(); + } + } + function d2runCommandValidate() { QV('d2cmduser', Q('d2cmdtype').value < 4); } + function d2groupActionFunctionRunCommands(b, options) { var type = 3; try { type = parseInt(Q('d2cmdtype').value); } catch (ex) { } - meshserver.send({ action: 'runcommands', nodeids: getCheckedDevices(), type: type, cmds: Q('d2runcmd').value, runAsUser: parseInt(Q('d2cmduser').value) }); uncheckAllDevices(); + meshserver.send({ action: 'runcommands', nodeids: options.nodeids, type: type, cmds: Q('d2runcmd').value, runAsUser: parseInt(Q('d2cmduser').value) }); + if (options.func) { options.func(); } } function onSortSelectChange(skipsave) { @@ -7174,6 +7179,7 @@ if (((meshrights & (4 + 8 + 64 + 262144)) != 0) && (node.mtype < 3) && ((node.agent == null) || (node.agent.id != 34))) { x += ''; } x += ''; x += ''; + if ((node.mtype == 2) && (connectivity & 1) && (meshrights == 0xFFFFFFFF)) { x += ''; } if (node.mtype != 4) { if ((meshrights & 8) && ((connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0)))) { x += ''; } //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += ''; } @@ -7632,6 +7638,12 @@ return str.join(', '); } + // Run commands on current device + function runDeviceCmd(nodeid) { + if (xxdialogMode) return; + d2runCommandDialog({ nodeids: [ decodeURIComponent(nodeid) ], title: "Run commands on this device." }); + } + function writeDeviceEvent(nodeid) { if (xxdialogMode) return; setDialogMode(2, "Add Device Event", 3, writeDeviceEventEx, '' + "This will add an entry to this device's event log." + '', nodeid); diff --git a/views/task-schedule.handlebars b/views/task-schedule.handlebars deleted file mode 100644 index 228d8a96..00000000 --- a/views/task-schedule.handlebars +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - -
-
- - -
-
-
- Recurrence -
    -
  • -
  • -
  • -
  • -
  • - -
-
- -
-
- - - \ No newline at end of file diff --git a/views/task-scriptedit.handlebars b/views/task-scriptedit.handlebars deleted file mode 100644 index 0e79eaaf..00000000 --- a/views/task-scriptedit.handlebars +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - -
-
Script Name:
-
- - -
-
- -
-
- - - \ No newline at end of file diff --git a/views/task-user.handlebars b/views/task-user.handlebars deleted file mode 100644 index b1c70b30..00000000 --- a/views/task-user.handlebars +++ /dev/null @@ -1,1070 +0,0 @@ - - - - - - -
- - Upload: -
-
- New - Rename - Edit - Delete - New Folder - Download - Run -
-
-
-
-
-
-
Advanced Run
-
-
-
- - -
-
-
- - -
Meshes
-
-
- - -
Tags
-
-
-
Node Schedules
-
- - - - - - - - - -
ScriptAuthorEveryStartingEndingLast RunNext RunAction
-
-
Script Schedules
-
- - - - - - - - - -
NodeAuthorEveryStartingEndingLast RunNext RunAction
-
-
Node History
-
- - - - - - -
TimeRun ByScriptStatusReturn Value
-
-
Script History
-
- - - - - - -
TimeRun ByNodeStatusReturn Value
-
-
Variables
-
- - - - - - -
Variable NameValueScopeScope TargetAction
-
- [+] -
-
- -
-
-
- - - \ No newline at end of file