"use strict"; // modules const fs = require('fs'); const mkdirp = require("mkdirp"); const {exec} = require('child_process'); const express = require('express'); const multer = require('multer'); const storage = multer.memoryStorage(); const upload = multer({storage: storage}); const logger = require('debug')('cc:wars'); // HTTP status codes by name const codes = require('./http-codes'); const apiAuthenticationMiddleware = require('../middleware/auth-middleware'); const checkMT = require('../middleware/permission-check').checkMT; const routerHandling = require('../middleware/router-handling'); // Mongoose Model using mongoDB const CampaignModel = require('../models/campaign'); const WarModel = require('../models/war'); const PlayerModel = require('../models/player'); const wars = express.Router(); // routes ********************** wars.route('/') .get((req, res, next) => { let result = []; CampaignModel.find({}, {}, {sort: {timestamp: 'desc'}}, (err, campaigns) => { if (err) { err.status = codes.servererror; return next(err); } if (campaigns) { WarModel.find({}, {}, {sort: {date: 'desc'}}, (err, wars) => { if (err) { err.status = codes.servererror; return next(err); } if (wars) { campaigns.forEach(campaign => { let entry = {_id: campaign._id, title: campaign.title, wars: []}; wars.forEach((war) => { if (String(campaign._id) === String(war.campaign)) { entry.wars.push(war); } }); result.push(entry); }); res.locals.items = result; } res.locals.processed = true; next(); } ) ; } }) }) .post(apiAuthenticationMiddleware, checkMT, upload.single('log'), (req, res, next) => { let body = req.body; let parts = body.date.split("-"); body.date = new Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10)); const war = new WarModel(body); if (req.file) { war.save((err, war) => { if (err) { return next(err); } const folderName = __dirname + '/../resource/logs/' + war._id; mkdirp(folderName, function (err) { if (err) { return next(err); } fs.appendFile(folderName + '/war.log', new Buffer(req.file.buffer), (err) => { if (err) { return next(err); } exec(__dirname + '/../war-parser/run.sh ' + folderName + ' ' + war._id, (error, stdout) => { if (error) { return next(error); } exec(__dirname + '/../war-parser/clean.sh /../' + folderName + ' | tee ' + folderName + '/clean.log', (error) => { if (error) { return next(error); } let obj = JSON.parse(`${stdout}`); for (let i = 0; i < obj.length; i++) { if (!obj[i].fraction) { obj.splice(i, 1); } else if (obj[i].fraction === 'BLUFOR') { war.playersBlufor++; } else { war.playersOpfor++; } } WarModel.findByIdAndUpdate(war._id, war, {new: true}, (err, item) => { if (err) { err.status = codes.wrongrequest; } else if (!item) { err = new Error("item not found"); err.status = codes.notfound; } else { PlayerModel.create(obj, function (err) { if (err) { return next(err); } res.status(codes.created); res.locals.items = war; return next(); }); } }) }); }); }); }); }) } else { const err = new Error('no Logfile provided'); err.status = codes.wrongmediasend; next(err); } }) .all( routerHandling.httpMethodNotAllowed ); wars.route('/:id') .get((req, res, next) => { WarModel.findById(req.params.id, (err, item) => { if (err) { err.status = codes.servererror; return next(err); } else if (!item) { err = new Error("item not found"); err.status = codes.notfound; return next(err); } PlayerModel.find({warId: item._id}, (err, items) => { if (err) { return next(err); } const responseObj = item.toObject(); responseObj.players = items; res.locals.items = responseObj; return next(); }); }); }) .delete(apiAuthenticationMiddleware, checkMT, (req, res, next) => { WarModel.findByIdAndRemove(req.params.id, (err, item) => { if (err) { err.status = codes.wrongrequest; return next(err); } else if (!item) { err = new Error("item not found"); err.status = codes.notfound; return next(err); } // delete players having this war ID as foreign key PlayerModel.find({warId: item._id}).remove().exec(); // check if logfiles exist and delete from fs const warDir = __dirname + '/../resource/logs/' + req.params.id; if (fs.existsSync(warDir)) { const cleanLog = warDir + '/clean.log'; if (fs.existsSync(cleanLog)) { fs.unlink(cleanLog, (err) => { }); } const sourceLog = warDir + '/war.log'; if (fs.existsSync(sourceLog)) { fs.unlink(sourceLog, (err) => { }); } fs.rmdir(warDir, (err) => { }); } // we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler user.use(..) res.locals.processed = true; next(); }) }) .all( routerHandling.httpMethodNotAllowed ); // this middleware function can be used, if you like or remove it // it looks for object(s) in res.locals.items and if they exist, they are send to the client as json wars.use(routerHandling.emptyResponse); module.exports = wars;