365 lines
13 KiB
JavaScript
365 lines
13 KiB
JavaScript
var fs = require('fs')
|
|
var moment = require('moment')
|
|
module.exports = function(s,config,lang,app,io){
|
|
const getFileBinDirectory = function(monitor){
|
|
return s.dir.fileBin + monitor.ke + '/' + monitor.mid + '/'
|
|
}
|
|
const getFileBinEntry = (options) => {
|
|
return new Promise((resolve, reject) => {
|
|
s.knexQuery({
|
|
action: "select",
|
|
columns: "*",
|
|
table: "Files",
|
|
where: options
|
|
},(err,rows) => {
|
|
if(rows[0]){
|
|
resolve(rows[0])
|
|
}else{
|
|
resolve()
|
|
}
|
|
})
|
|
})
|
|
}
|
|
const getFileBinBuffer = (file) => {
|
|
const filePath = getFileBinPath(file);
|
|
return fs.promises.readFile(filePath)
|
|
}
|
|
const getFileBinPath = (file) => {
|
|
return getFileBinDirectory(file) + file.name;
|
|
}
|
|
const getFileBinEntries = (options) => {
|
|
return new Promise((resolve, reject) => {
|
|
s.knexQuery({
|
|
action: "select",
|
|
columns: "*",
|
|
table: "Files",
|
|
where: options
|
|
},(err,rows) => {
|
|
if(rows){
|
|
resolve(rows)
|
|
}else{
|
|
resolve([])
|
|
}
|
|
})
|
|
})
|
|
}
|
|
const updateFileBinEntry = (options) => {
|
|
return new Promise((resolve, reject) => {
|
|
const groupKey = options.ke
|
|
const monitorId = options.mid
|
|
const filename = options.name
|
|
const update = options.update
|
|
if(!filename){
|
|
resolve('No Filename')
|
|
return
|
|
}
|
|
if(!update){
|
|
resolve('No Update Options')
|
|
return
|
|
}
|
|
s.knexQuery({
|
|
action: "select",
|
|
columns: "size",
|
|
table: "Files",
|
|
where: {
|
|
ke: groupKey,
|
|
mid: monitorId,
|
|
name: filename,
|
|
}
|
|
},(err,rows) => {
|
|
if(rows[0]){
|
|
const fileSize = rows[0].size
|
|
s.knexQuery({
|
|
action: "update",
|
|
table: "Files",
|
|
where: {
|
|
ke: groupKey,
|
|
mid: monitorId,
|
|
name: filename,
|
|
},
|
|
update: update
|
|
},(err) => {
|
|
resolve()
|
|
if(update.size){
|
|
s.setDiskUsedForGroup(groupKey,-(fileSize/1048576),'fileBin')
|
|
s.setDiskUsedForGroup(groupKey,(update.size/1048576),'fileBin')
|
|
s.purgeDiskForGroup(groupKey)
|
|
}
|
|
})
|
|
}else{
|
|
resolve()
|
|
}
|
|
})
|
|
})
|
|
}
|
|
const deleteFileBinEntry = (options) => {
|
|
return new Promise((resolve, reject) => {
|
|
const groupKey = options.ke
|
|
const monitorId = options.mid
|
|
const filename = options.name
|
|
const whereQuery = {
|
|
ke: groupKey,
|
|
mid: monitorId,
|
|
name: filename,
|
|
}
|
|
if(!filename){
|
|
resolve('No Filename')
|
|
return
|
|
}
|
|
const deleteRow = (fileSize) => {
|
|
s.knexQuery({
|
|
action: "delete",
|
|
table: "Files",
|
|
where: whereQuery
|
|
},(err,r) => {
|
|
resolve()
|
|
s.file('delete',getFileBinDirectory(whereQuery) + filename)
|
|
s.setDiskUsedForGroup(groupKey,-(fileSize/1048576),'fileBin')
|
|
s.purgeDiskForGroup(groupKey)
|
|
})
|
|
}
|
|
if(options.size){
|
|
deleteRow(options.size)
|
|
}else{
|
|
s.knexQuery({
|
|
action: "select",
|
|
columns: "size",
|
|
table: "Files",
|
|
where: whereQuery
|
|
},(err,rows) => {
|
|
if(rows[0]){
|
|
const fileSize = rows[0].size
|
|
deleteRow(fileSize)
|
|
}else{
|
|
resolve()
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
const insertFileBinEntry = (options) => {
|
|
return new Promise((resolve, reject) => {
|
|
const groupKey = options.ke
|
|
const monitorId = options.mid
|
|
const filename = options.name
|
|
if(!filename){
|
|
resolve('No Filename')
|
|
return
|
|
}
|
|
const monitorFileBinDirectory = getFileBinDirectory({ke: groupKey,mid: monitorId,})
|
|
const fileSize = options.size || fs.lstatSync(monitorFileBinDirectory + filename).size
|
|
const details = options.details instanceof Object ? JSON.stringify(options.details) : options.details
|
|
const status = options.status || 0
|
|
const time = options.time || new Date()
|
|
s.knexQuery({
|
|
action: "insert",
|
|
table: "Files",
|
|
insert: {
|
|
ke: groupKey,
|
|
mid: monitorId,
|
|
name: filename,
|
|
size: fileSize,
|
|
details: details,
|
|
status: status,
|
|
time: time,
|
|
}
|
|
},(err) => {
|
|
resolve()
|
|
s.setDiskUsedForGroup(groupKey,(fileSize/1048576),'fileBin')
|
|
s.purgeDiskForGroup(groupKey)
|
|
})
|
|
})
|
|
}
|
|
function archiveFileBinEntry(file,unarchive){
|
|
return new Promise((resolve) => {
|
|
s.knexQuery({
|
|
action: "update",
|
|
table: 'Files',
|
|
update: {
|
|
archive: unarchive ? '0' : 1
|
|
},
|
|
where: {
|
|
ke: file.ke,
|
|
mid: file.mid,
|
|
name: file.name,
|
|
}
|
|
},function(err){
|
|
resolve({
|
|
ok: !err,
|
|
err: err,
|
|
archived: !unarchive
|
|
})
|
|
})
|
|
})
|
|
}
|
|
s.getFileBinDirectory = getFileBinDirectory
|
|
s.getFileBinEntry = getFileBinEntry
|
|
s.getFileBinBuffer = getFileBinBuffer
|
|
s.getFileBinPath = getFileBinPath
|
|
s.insertFileBinEntry = insertFileBinEntry
|
|
s.updateFileBinEntry = updateFileBinEntry
|
|
s.deleteFileBinEntry = deleteFileBinEntry
|
|
s.archiveFileBinEntry = archiveFileBinEntry
|
|
/**
|
|
* API : Get fileBin file rows
|
|
*/
|
|
app.get([config.webPaths.apiPrefix+':auth/fileBin/:ke',config.webPaths.apiPrefix+':auth/fileBin/:ke/:id'],async (req,res) => {
|
|
s.auth(req.params,(user) => {
|
|
const userDetails = user.details
|
|
const monitorId = req.params.id
|
|
const groupKey = req.params.ke
|
|
const hasRestrictions = userDetails.sub && userDetails.allmonitors !== '1';
|
|
s.sqlQueryBetweenTimesWithPermissions({
|
|
table: 'Files',
|
|
user: user,
|
|
groupKey: req.params.ke,
|
|
monitorId: req.params.id,
|
|
startTime: req.query.start,
|
|
endTime: req.query.end,
|
|
startTimeOperator: req.query.startOperator,
|
|
endTimeOperator: req.query.endOperator,
|
|
limit: req.query.limit,
|
|
archived: req.query.archived,
|
|
endIsStartTo: true,
|
|
noFormat: true,
|
|
noCount: true,
|
|
preliminaryValidationFailed: (
|
|
user.permissions.get_monitors === "0"
|
|
)
|
|
},(response) => {
|
|
response.forEach(function(v){
|
|
v.details = s.parseJSON(v.details)
|
|
v.href = '/'+req.params.auth+'/fileBin/'+req.params.ke+'/'+req.params.id+'/'+v.name;
|
|
})
|
|
s.closeJsonResponse(res,{
|
|
ok: true,
|
|
files: response
|
|
})
|
|
})
|
|
},res,req);
|
|
});
|
|
/**
|
|
* API : Get fileBin file
|
|
*/
|
|
app.get(config.webPaths.apiPrefix+':auth/fileBin/:ke/:id/:file', async (req,res) => {
|
|
s.auth(req.params,function(user){
|
|
var failed = function(){
|
|
res.end(user.lang['File Not Found'])
|
|
}
|
|
const groupKey = req.params.ke
|
|
const monitorId = req.params.id
|
|
const {
|
|
monitorPermissions,
|
|
monitorRestrictions,
|
|
} = s.getMonitorsPermitted(user.details,monitorId)
|
|
const {
|
|
isRestricted,
|
|
isRestrictedApiKey,
|
|
apiKeyPermissions,
|
|
} = s.checkPermission(user)
|
|
if(
|
|
isRestrictedApiKey && apiKeyPermissions.watch_videos_disallowed ||
|
|
isRestricted && !monitorPermissions[`${monitorId}_video_view`]
|
|
){
|
|
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
|
|
return
|
|
}
|
|
s.knexQuery({
|
|
action: "select",
|
|
columns: "*",
|
|
table: "Files",
|
|
where: [
|
|
['ke','=',groupKey],
|
|
['mid','=',req.params.id],
|
|
['name','=',req.params.file],
|
|
monitorRestrictions
|
|
]
|
|
},(err,r) => {
|
|
if(r && r[0]){
|
|
r = r[0]
|
|
r.details = JSON.parse(r.details)
|
|
const filename = req.params.file
|
|
const filePath = s.dir.fileBin + req.params.ke + '/' + req.params.id + (r.details.year && r.details.month && r.details.day ? '/' + r.details.year + '/' + r.details.month + '/' + r.details.day : '') + '/' + filename;
|
|
fs.stat(filePath,function(err,stats){
|
|
if(!err){
|
|
if(filename.endsWith('.mp4')){
|
|
s.streamMp4FileOverHttp(filePath,req,res,!!req.query.pureStream)
|
|
}else{
|
|
res.on('finish',function(){res.end()})
|
|
fs.createReadStream(filePath).pipe(res)
|
|
}
|
|
}else{
|
|
failed()
|
|
}
|
|
})
|
|
}else{
|
|
failed()
|
|
}
|
|
})
|
|
},res,req);
|
|
});
|
|
/**
|
|
* API : Modify fileBin File
|
|
*/
|
|
app.get(config.webPaths.apiPrefix+':auth/fileBin/:ke/:id/:file/:mode', function (req,res){
|
|
let response = { ok: false };
|
|
res.setHeader('Content-Type', 'application/json');
|
|
s.auth(req.params,function(user){
|
|
const monitorId = req.params.id
|
|
const groupKey = req.params.ke
|
|
const filename = req.params.file
|
|
const {
|
|
monitorPermissions,
|
|
monitorRestrictions,
|
|
} = s.getMonitorsPermitted(user.details,monitorId)
|
|
const {
|
|
isRestricted,
|
|
isRestrictedApiKey,
|
|
apiKeyPermissions,
|
|
} = s.checkPermission(user);
|
|
if(
|
|
isRestrictedApiKey && apiKeyPermissions.delete_videos_disallowed ||
|
|
isRestricted && !monitorPermissions[`${monitorId}_video_delete`]
|
|
){
|
|
s.closeJsonResponse(res,{ok: false, msg: lang['Not Authorized']});
|
|
return
|
|
}
|
|
s.knexQuery({
|
|
action: "select",
|
|
columns: "*",
|
|
table: 'Files',
|
|
where: [
|
|
['ke','=',groupKey],
|
|
['mid','=',monitorId],
|
|
['name','=',filename]
|
|
],
|
|
limit: 1
|
|
},async (err,r) => {
|
|
if(r && r[0]){
|
|
const file = r[0];
|
|
var details = s.parseJSON(r.details) || {}
|
|
switch(req.params.mode){
|
|
case'archive':
|
|
response.ok = true
|
|
const unarchive = s.getPostData(req,'unarchive') == '1';
|
|
const archiveResponse = await archiveFileBinEntry(file,unarchive)
|
|
response.ok = archiveResponse.ok
|
|
response.archived = archiveResponse.archived
|
|
break;
|
|
case'delete':
|
|
response.ok = true;
|
|
await deleteFileBinEntry(file)
|
|
break;
|
|
default:
|
|
response.msg = user.lang.modifyVideoText1;
|
|
break;
|
|
}
|
|
}else{
|
|
response.msg = user.lang['No such file'];
|
|
}
|
|
s.closeJsonResponse(res,response);
|
|
})
|
|
},res,req);
|
|
})
|
|
}
|