allow customAutoLoad to get blocks, js, and css automatically from fs

merge-requests/49/head
Moe 2019-01-23 22:15:17 -08:00
parent fe3121a7a8
commit 2d5434ac21
5 changed files with 314 additions and 57 deletions

View File

@ -1,33 +1,109 @@
var fs = require('fs')
var express = require('express')
module.exports = function(s,config,lang,app,io){
var checkFolder = function(folderName){
var folderPath = __dirname + '/' + folderName
fs.readdir(folderPath,function(err,folderContents){
if(!err && folderContents){
folderContents.forEach(function(filename){
var customModulePath = folderPath + '/' + filename
if(filename.indexOf('.js') > -1){
s.customAutoLoadModules = {}
s.customAutoLoadTree = {
pages: [],
PageBlocks: [],
LibsJs: [],
LibsCss: [],
adminPageBlocks: [],
adminLibsJs: [],
adminLibsCss: [],
superPageBlocks: [],
superLibsJs: [],
superLibsCss: []
}
var folderPath = __dirname + '/customAutoLoad'
var search = function(searchFor,searchIn){return searchIn.indexOf(searchFor) > -1}
fs.readdir(folderPath,function(err,folderContents){
if(!err && folderContents){
folderContents.forEach(function(filename){
s.customAutoLoadModules[filename] = {}
var customModulePath = folderPath + '/' + filename
if(filename.indexOf('.js') > -1){
s.customAutoLoadModules[filename].type = 'file'
try{
require(customModulePath)(s,config,lang,app,io)
}catch(err){
console.log('Failed to Load Module : ' + filename)
console.log(err)
}
}else{
if(fs.lstatSync(customModulePath).isDirectory()){
s.customAutoLoadModules[filename].type = 'folder'
try{
require(customModulePath)(s,config,lang,app,io)
fs.readdir(customModulePath,function(err,folderContents){
folderContents.forEach(function(name){
switch(name){
case'web':
var webFolder = s.checkCorrectPathEnding(customModulePath) + 'web/'
fs.readdir(webFolder,function(err,webFolderContents){
webFolderContents.forEach(function(name){
switch(name){
case'libs':
case'pages':
if(name === 'libs')app.use("/libs", express.static(webFolder + "/libs"))
var libFolder = webFolder + name + '/'
fs.readdir(libFolder,function(err,webFolderContents){
webFolderContents.forEach(function(libName){
var thirdLevelName = libFolder + libName
switch(libName){
case'js':
case'css':
case'blocks':
fs.readdir(thirdLevelName,function(err,webFolderContents){
webFolderContents.forEach(function(filename){
var fullPath = thirdLevelName + '/' + filename
var blockPrefix = ''
switch(true){
case search('super.',filename):
blockPrefix = 'super'
break;
case search('admin.',filename):
blockPrefix = 'admin'
break;
}
switch(libName){
case'js':
s.customAutoLoadTree[blockPrefix + 'LibsJs'].push(filename)
break;
case'css':
s.customAutoLoadTree[blockPrefix + 'LibsCss'].push(filename)
break;
case'blocks':
s.customAutoLoadTree[blockPrefix + 'PageBlocks'].push(fullPath)
break;
}
})
})
break;
default:
if(libName.indexOf('.ejs') > -1){
s.customAutoLoadTree.pages.push(thirdLevelName)
}
break;
}
})
})
break;
}
})
})
break;
}
})
})
}catch(err){
console.log('Failed to Load Module : ' + filename)
console.log(err)
}
}else{
if(fs.lstatSync(customModulePath).isDirectory()){
try{
require(customModulePath)(s,config,lang,app,io)
}catch(err){
console.log('Failed to Load Module : ' + filename)
console.log(err)
}
}
}
})
}else{
fs.mkdirSync(folderPath)
}
})
}
checkFolder('customAutoLoad')
}
})
}else{
fs.mkdirSync(folderPath)
}
})
}

View File

@ -286,7 +286,8 @@ module.exports = function(s,config,lang,app,io){
// config: config,
$user: req.resp,
lang: r.lang,
define: s.getDefinitonFile(r.details.lang)
define: s.getDefinitonFile(r.details.lang),
customAutoLoad: s.customAutoLoadTree
})
})
break;
@ -297,7 +298,8 @@ module.exports = function(s,config,lang,app,io){
// config: config,
$user: req.resp,
lang: r.lang,
define: s.getDefinitonFile(r.details.lang)
define: s.getDefinitonFile(r.details.lang),
customAutoLoad: s.customAutoLoadTree
})
})
break;
@ -311,17 +313,36 @@ module.exports = function(s,config,lang,app,io){
$subs: rr,
$mons: rrr,
lang: r.lang,
define: s.getDefinitonFile(r.details.lang)
define: s.getDefinitonFile(r.details.lang),
customAutoLoad: s.customAutoLoadTree
})
})
})
}else{
//not admin user
renderPage(config.renderPaths.home,{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs,__dirname:s.mainDirectory});
renderPage(config.renderPaths.home,{
$user:req.resp,
config:config,
lang:r.lang,
define:s.getDefinitonFile(r.details.lang),
addStorage:s.dir.addStorage,
fs:fs,
__dirname:s.mainDirectory,
customAutoLoad: s.customAutoLoadTree
});
}
break;
default:
renderPage(config.renderPaths.home,{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs,__dirname:s.mainDirectory});
renderPage(config.renderPaths.home,{
$user:req.resp,
config:config,
lang:r.lang,
define:s.getDefinitonFile(r.details.lang),
addStorage:s.dir.addStorage,
fs:fs,
__dirname:s.mainDirectory,
customAutoLoad: s.customAutoLoadTree
});
break;
}
s.userLog({ke:r.ke,mid:'$USER'},{type:r.lang['New Authentication Token'],msg:{for:req.body.function,mail:r.mail,id:r.uid,ip:req.ip}})
@ -511,6 +532,7 @@ module.exports = function(s,config,lang,app,io){
r=[]
}
data.Logs = r
data.customAutoLoad = s.customAutoLoadTree
fs.readFile(s.location.config,'utf8',function(err,file){
data.plainConfig = JSON.parse(file)
renderPage(config.renderPaths.super,data)
@ -1375,7 +1397,7 @@ module.exports = function(s,config,lang,app,io){
values.push(time)
})
s.sqlQuery('SELECT * FROM Videos WHERE '+where.join(' OR '),values,function(err,r){
var resp = {ok:false}
var resp = {ok: false}
if(r && r[0]){
resp.ok = true
var zipDownload = null
@ -1396,7 +1418,7 @@ module.exports = function(s,config,lang,app,io){
fs.mkdirSync(fileBinDir);
}
r.forEach(function(video){
timeFormatted = s.formattedTime(video.time)
var timeFormatted = s.formattedTime(video.time)
video.filename = timeFormatted+'.'+video.ext
var dir = s.getVideoDirectory(video)+video.filename
var tempVideoFile = timeFormatted+' - '+video.mid+'.'+video.ext
@ -1418,16 +1440,27 @@ module.exports = function(s,config,lang,app,io){
var zipDownload = fs.createReadStream(zippedFile)
zipDownload.pipe(res)
zipDownload.on('error', function (error) {
s.userLog({ke:req.params.ke,mid:'$USER'},{title:'Zip Download Error',msg:error.toString()})
var errorString = error.toString()
s.userLog({
ke: req.params.ke,
mid: '$USER'
},{
title: 'Zip Download Error',
msg: errorString
})
if(zipDownload && zipDownload.destroy){
zipDownload.destroy()
}
});
res.end(s.prettyPrint({
ok: false,
msg: errorString
}))
})
zipDownload.on('close', function () {
res.end()
zipDownload.destroy();
fs.unlinkSync(zippedFile);
});
zipDownload.destroy()
fs.unlinkSync(zippedFile)
})
})
}else{
failed({ok:false,msg:'No Videos Found'})
@ -1437,7 +1470,121 @@ module.exports = function(s,config,lang,app,io){
}else{
failed({ok:false,msg:'"videos" query variable is missing from request.'})
}
});
})
/**
* API : Zip Cloud Videos and Get Link from fileBin
*/
app.get(config.webPaths.apiPrefix+':auth/zipCloudVideos/:ke', function (req,res){
res.header("Access-Control-Allow-Origin",req.headers.origin);
var failed = function(resp){
res.setHeader('Content-Type', 'application/json');
res.end(s.prettyPrint(resp))
}
if(req.query.videos && req.query.videos !== ''){
s.auth(req.params,function(user){
var videosSelected = JSON.parse(req.query.videos)
var where = []
var values = []
videosSelected.forEach(function(video){
where.push("(ke=? AND mid=? AND `time`=?)")
if(!video.ke)video.ke = req.params.ke
values.push(video.ke)
values.push(video.mid)
var time = s.nameToTime(video.filename)
if(req.query.isUTC === 'true'){
time = s.utcToLocal(time)
}
time = new Date(time)
values.push(time)
})
s.sqlQuery('SELECT * FROM `Cloud Videos` WHERE '+where.join(' OR '),values,function(err,r){
var resp = {ok: false}
if(r && r[0]){
resp.ok = true
var zipDownload = null
var tempFiles = []
var fileId = s.gid()
var fileBinDir = s.dir.fileBin+req.params.ke+'/'
var tempScript = s.dir.streams+req.params.ke+'/'+fileId+'.sh'
var zippedFilename = s.formattedTime()+'-'+fileId+'-Shinobi_Cloud_Backed_Recordings.zip'
var zippedFile = fileBinDir+zippedFilename
var script = 'cd '+fileBinDir+' && zip -9 -r '+zippedFile
res.on('close', () => {
if(zipDownload && zipDownload.destroy){
zipDownload.destroy()
}
fs.unlink(zippedFile);
})
if(!fs.existsSync(fileBinDir)){
fs.mkdirSync(fileBinDir);
}
var cloudDownloadCount = 0
var getFile = function(video,completed){
if(!video)completed();
s.checkDetails(video)
var filename = video.href.split('/')
filename = filename[filename.length - 1]
var timeFormatted = s.formattedTime(video.time)
var tempVideoFile = video.details.type + '-' + video.mid + '-' + filename
var tempFileWriteStream = fs.createWriteStream(fileBinDir+tempVideoFile)
tempFileWriteStream.on('finish', function() {
++cloudDownloadCount
getFile(r[cloudDownloadCount],completed)
})
var cloudVideoDownload = request(video.href)
cloudVideoDownload.on('response', function (res) {
res.pipe(tempFileWriteStream)
})
tempFiles.push(fileBinDir+tempVideoFile)
script += ' "'+tempVideoFile+'"'
}
getFile(r[cloudDownloadCount],function(){
fs.writeFileSync(tempScript,script,'utf8')
var zipCreate = spawn('sh',(tempScript).split(' '),{detached: true})
zipCreate.stderr.on('data',function(data){
s.userLog({ke:req.params.ke,mid:'$USER'},{title:'Zip Create Error',msg:data.toString()})
})
zipCreate.on('exit',function(data){
fs.unlinkSync(tempScript)
tempFiles.forEach(function(file){
fs.unlink(file,function(){})
})
res.setHeader('Content-Disposition', 'attachment; filename="' + zippedFilename + '"')
var zipDownload = fs.createReadStream(zippedFile)
zipDownload.pipe(res)
zipDownload.on('error', function (error) {
var errorString = error.toString()
s.userLog({
ke: req.params.ke,
mid: '$USER'
},{
title: 'Zip Download Error',
msg: errorString
})
if(zipDownload && zipDownload.destroy){
zipDownload.destroy()
}
res.end(s.prettyPrint({
ok: false,
msg: errorString
}))
})
zipDownload.on('close', function () {
res.end()
zipDownload.destroy()
fs.unlinkSync(zippedFile)
})
})
})
}else{
failed({ok:false,msg:'No Videos Found'})
}
})
},res,req);
}else{
failed({ok:false,msg:'"videos" query variable is missing from request.'})
}
})
/**
* API : Get Cloud Video File (proxy)
*/
@ -1524,27 +1671,34 @@ module.exports = function(s,config,lang,app,io){
/**
* API : Motion Trigger via GET request
*/
app.get(config.webPaths.apiPrefix+':auth/motion/:ke/:id', function (req,res){
s.auth(req.params,function(user){
if(req.query.data){
try{
var d={id:req.params.id,ke:req.params.ke,details:JSON.parse(req.query.data)};
}catch(err){
res.end('Data Broken',err);
return;
}
}else{
res.end('No Data');
return;
}
if(!d.ke||!d.id||!s.group[d.ke]){
res.end(user.lang['No Group with this key exists']);
return;
}
s.triggerEvent(d)
res.end(user.lang['Trigger Successful'])
},res,req);
})
app.get(config.webPaths.apiPrefix+':auth/motion/:ke/:id', function (req,res){
s.auth(req.params,function(user){
var endData = {
}
if(req.query.data){
try{
var d = {
id: req.params.id,
ke: req.params.ke,
details: JSON.parse(req.query.data)
}
}catch(err){
res.end('Data Broken',err)
return
}
}else{
res.end('No Data')
return
}
if(!d.ke||!d.id||!s.group[d.ke]){
res.end(user.lang['No Group with this key exists'])
return
}
s.triggerEvent(d)
res.end(user.lang['Trigger Successful'])
},res,req)
})
/**
* API : WebHook Tester
*/

View File

@ -12,6 +12,9 @@
<link rel="stylesheet" href="<%-window.libURL%>libs/css/fullcalendar.min.css">
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap-table.min.css">
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css">
<% customAutoLoad.adminLibsCss.forEach(function(lib){ %>
<link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>">
<% }) %>
<body class="shinobi-bg">
<div class="container-fluid">
<div class="container">
@ -82,6 +85,9 @@
</div>
<% include blocks/confirm.ejs %>
<% include blocks/subpermissions.ejs %>
<% customAutoLoad.adminPageBlocks.forEach(function(block){ %>
<%- include(block) %>
<% }) %>
</body>
<script><% include ../libs/js/basic.js %></script>
<script><% include ../libs/js/socket.io.js %></script>
@ -275,3 +281,6 @@ $('body')
localStorage.removeItem('ShinobiLogin_'+location.host);location.href=location.href;
})
</script>
<% customAutoLoad.adminLibsJs.forEach(function(lib){ %>
<script src="<%-window.libURL%>libs/js/<%-lib%>"></script>
<% }) %>

View File

@ -27,6 +27,9 @@
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css">
-->
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.old.css">
<% customAutoLoad.LibsCss.forEach(function(lib){ %>
<link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>">
<% }) %>
<style id="theme">
<% if(details.theme&&details.theme!==''){ %><%- include(__dirname+'/web/libs/themes/'+details.theme+'/style.css'); %><% } %>
</style>
@ -184,6 +187,9 @@
<% include blocks/monitorStates.ejs %>
<% include blocks/schedules.ejs %>
<% include blocks/confirm.ejs %>
<% customAutoLoad.PageBlocks.forEach(function(block){ %>
<%- include(block) %>
<% }) %>
<% if(config.DropboxAppKey){ %>
<!--Dropbox Library, Change data-app-key to your app key. -->
<script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="<%= config.DropboxAppKey %>"></script>
@ -222,4 +228,7 @@
<script src="<%-window.libURL%>libs/js/dash2.elements.js"></script>
<script src="<%-window.libURL%>libs/js/dash2.elementbuilder.js"></script>
<script src="<%-window.libURL%>libs/js/dash2.init.js"></script>
<% customAutoLoad.LibsJs.forEach(function(lib){ %>
<script src="<%-window.libURL%>libs/js/<%-lib%>"></script>
<% }) %>
<% include blocks/help.ejs %>

View File

@ -27,6 +27,9 @@
.list-group li .form-group {margin:0}
a {cursor:pointer}
</style>
<% customAutoLoad.superLibsCss.forEach(function(lib){ %>
<link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>">
<% }) %>
</head>
<body class="index-page sidebar-collapse bg-hexagon">
@ -172,6 +175,9 @@
<div id="temp" style="display:none"></div>
</body>
<% include blocks/confirm.ejs %>
<% customAutoLoad.superPageBlocks.forEach(function(block){ %>
<%- include(block) %>
<% }) %>
<script src="<%-window.libURL%>libs/js/pnotify.custom.min.js" type="text/javascript"></script>
<script><% include ../libs/js/moment.js %></script>
<script src="<%-window.libURL%>libs/js/livestamp.min.js" type="text/javascript"></script>
@ -532,4 +538,7 @@ $('body')
})
</script>
<% include blocks/mainpermissions.ejs %>
<% customAutoLoad.superLibsJs.forEach(function(lib){ %>
<script src="<%-window.libURL%>libs/js/<%-lib%>"></script>
<% }) %>
</html>