commit
08aeda0de3
|
@ -54,7 +54,7 @@ const createBackup = () => {
|
||||||
if (err) {
|
if (err) {
|
||||||
error(err.message);
|
error(err.message);
|
||||||
}
|
}
|
||||||
logger('\x1b[32m%s\x1b[0m',stderr);
|
logger('\x1b[32m%s\x1b[0m', stderr);
|
||||||
logger('\x1b[35m%s\x1b[0m', new Date().toLocaleString()
|
logger('\x1b[35m%s\x1b[0m', new Date().toLocaleString()
|
||||||
+ ': cron job finished - CREATE BACKUP');
|
+ ': cron job finished - CREATE BACKUP');
|
||||||
})
|
})
|
||||||
|
|
|
@ -12,8 +12,16 @@ let check = (requiredPermission, actualPermission, res, next) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
checkSql: (req, res, next) => { check(1, req.user.permission, res, next) },
|
checkSql: (req, res, next) => {
|
||||||
checkHl: (req, res, next) => { check(2, req.user.permission, res, next) },
|
check(1, req.user.permission, res, next)
|
||||||
checkMT: (req, res, next) => { check(3, req.user.permission, res, next) },
|
},
|
||||||
checkAdmin: (req, res, next) => { check(4, req.user.permission, res, next) }
|
checkHl: (req, res, next) => {
|
||||||
|
check(2, req.user.permission, res, next)
|
||||||
|
},
|
||||||
|
checkMT: (req, res, next) => {
|
||||||
|
check(3, req.user.permission, res, next)
|
||||||
|
},
|
||||||
|
checkAdmin: (req, res, next) => {
|
||||||
|
check(4, req.user.permission, res, next)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,8 +34,8 @@ router.use((req, res, next) => {
|
||||||
// request type application/json check
|
// request type application/json check
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
if (['POST', 'PUT', 'PATCH'].indexOf(req.method) > -1 &&
|
if (['POST', 'PUT', 'PATCH'].indexOf(req.method) > -1 &&
|
||||||
(!( /multipart\/form-data/.test(req.get('Content-Type'))) &&
|
(!(/multipart\/form-data/.test(req.get('Content-Type'))) &&
|
||||||
!( /application\/json/.test(req.get('Content-Type'))))) {
|
!(/application\/json/.test(req.get('Content-Type'))))) {
|
||||||
// send error code 415: unsupported media type
|
// send error code 415: unsupported media type
|
||||||
res.status(415).send('wrong Content-Type'); // user has SEND the wrong type
|
res.status(415).send('wrong Content-Type'); // user has SEND the wrong type
|
||||||
} else if (!req.accepts('json')) {
|
} else if (!req.accepts('json')) {
|
||||||
|
|
|
@ -36,6 +36,6 @@ const LogTransportSchema = new Schema({
|
||||||
collection: 'logTransport'
|
collection: 'logTransport'
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogTransportSchema.index({war: 1});
|
LogTransportSchema.index({war: 1, driver: 1});
|
||||||
|
|
||||||
module.exports = mongoose.model('LogTransport', LogTransportSchema);
|
module.exports = mongoose.model('LogTransport', LogTransportSchema);
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
|
||||||
|
const LogVehicleKillSchema = new Schema({
|
||||||
|
war: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'War',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
type: Date,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
shooter: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
target: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fraction: {
|
||||||
|
type: String,
|
||||||
|
enum: ['BLUFOR', 'OPFOR', 'NONE'],
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
collection: 'logVehicle'
|
||||||
|
});
|
||||||
|
// optional more indices
|
||||||
|
LogVehicleKillSchema.index({war: 1, shooter: 1, target: 1});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('LogVehicle', LogVehicleKillSchema);
|
|
@ -24,6 +24,12 @@ const PlayerSchema = new Schema({
|
||||||
set: v => Math.round(v),
|
set: v => Math.round(v),
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
vehicle: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
death: {
|
death: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: v => Math.round(v),
|
||||||
|
@ -58,12 +64,17 @@ const PlayerSchema = new Schema({
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: v => Math.round(v),
|
||||||
set: v => Math.round(v)
|
set: v => Math.round(v)
|
||||||
|
},
|
||||||
|
steamUUID: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v)
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
collection: 'player',
|
collection: 'player',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'}
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
PlayerSchema.index({timestamp: 1});
|
PlayerSchema.index({warId: 1});
|
||||||
|
|
||||||
module.exports = mongoose.model('Player', PlayerSchema);
|
module.exports = mongoose.model('Player', PlayerSchema);
|
||||||
|
|
|
@ -11,7 +11,7 @@ const WarSchema = new Schema({
|
||||||
date: {
|
date: {
|
||||||
type: Date,
|
type: Date,
|
||||||
},
|
},
|
||||||
endDate : {
|
endDate: {
|
||||||
type: Date,
|
type: Date,
|
||||||
},
|
},
|
||||||
ptBlufor: {
|
ptBlufor: {
|
||||||
|
|
|
@ -15,70 +15,72 @@ const AppUserModel = require('../models/app-user');
|
||||||
const account = express.Router();
|
const account = express.Router();
|
||||||
|
|
||||||
account.route('/')
|
account.route('/')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
AppUserModel.find({}, {}, {sort: {username: 1}}).populate('squad').exec((err, items) => {
|
AppUserModel.find({}, {}, {sort: {username: 1}}).populate('squad').exec((err, items) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.locals.items = items;
|
res.locals.items = items;
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
next();
|
next();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
account.route('/:id')
|
account.route('/:id')
|
||||||
.patch((req, res, next) => {
|
.patch((req, res, next) => {
|
||||||
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
||||||
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
||||||
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
next(err);
|
next(err);
|
||||||
return; // prevent node to process this function further after next() has finished.
|
return; // prevent node to process this function further after next() has finished.
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment version manually as we do not use .save(.)
|
// increment version manually as we do not use .save(.)
|
||||||
req.body.updatedAt = new Date();
|
req.body.updatedAt = new Date();
|
||||||
req.body.$inc = {__v: 1};
|
req.body.$inc = {__v: 1};
|
||||||
|
|
||||||
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing.
|
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to
|
||||||
AppUserModel.findByIdAndUpdate(req.params.id, req.body, {new: true}).populate('squad').exec((err, item) => {
|
// reset attributes that are missing.
|
||||||
if (err) {
|
AppUserModel.findByIdAndUpdate(req.params.id, req.body, {new: true}).populate('squad').exec((err, item) => {
|
||||||
err.status = codes.wrongrequest;
|
if (err) {
|
||||||
}
|
err.status = codes.wrongrequest;
|
||||||
else if (!item) {
|
}
|
||||||
err = new Error("appUser not found");
|
else if (!item) {
|
||||||
err.status = codes.notfound;
|
err = new Error("appUser not found");
|
||||||
}
|
err.status = codes.notfound;
|
||||||
else {
|
}
|
||||||
res.locals.items = item;
|
else {
|
||||||
}
|
res.locals.items = item;
|
||||||
next(err);
|
}
|
||||||
})
|
next(err);
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
.delete((req, res, next) => {
|
.delete((req, res, next) => {
|
||||||
AppUserModel.findByIdAndRemove(req.params.id, (err, item) => {
|
AppUserModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
}
|
}
|
||||||
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler user.use(..)
|
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler
|
||||||
res.locals.processed = true;
|
// user.use(..)
|
||||||
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
res.locals.processed = true;
|
||||||
});
|
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
||||||
})
|
});
|
||||||
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// 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
|
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||||
|
|
|
@ -21,25 +21,25 @@ const authenticate = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
authenticate.route('/')
|
authenticate.route('/')
|
||||||
.post((req, res, next) => {
|
.post((req, res, next) => {
|
||||||
authCheck(req.body.username, req.body.password, res)
|
authCheck(req.body.username, req.body.password, res)
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
if (user) {
|
if (user) {
|
||||||
// authentication successful
|
// authentication successful
|
||||||
res.send(user);
|
res.send(user);
|
||||||
} else {
|
} else {
|
||||||
// authentication failed
|
// authentication failed
|
||||||
res.status(codes.unauthorized).send('Username or password is incorrect');
|
res.status(codes.unauthorized).send('Username or password is incorrect');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
res.status(codes.wrongrequest).send(err);
|
res.status(codes.wrongrequest).send(err);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
let authCheck = (username, password, res) => {
|
let authCheck = (username, password, res) => {
|
||||||
const deferred = Q.defer();
|
const deferred = Q.defer();
|
||||||
|
@ -76,19 +76,19 @@ let authCheck = (username, password, res) => {
|
||||||
// ******************************** SIGNUP ************************
|
// ******************************** SIGNUP ************************
|
||||||
|
|
||||||
authenticate.route('/signup')
|
authenticate.route('/signup')
|
||||||
.post((req, res, next) => {
|
.post((req, res, next) => {
|
||||||
create(req.body)
|
create(req.body)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
res.status(400).send(err);
|
res.status(400).send(err);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
let create = (userParam) => {
|
let create = (userParam) => {
|
||||||
const deferred = Q.defer();
|
const deferred = Q.defer();
|
||||||
|
|
|
@ -31,127 +31,129 @@ const awarding = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
awarding.route('/')
|
awarding.route('/')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
if (req.query.userId) {
|
if (req.query.userId) {
|
||||||
filter.userId = req.query.userId;
|
filter.userId = req.query.userId;
|
||||||
}
|
|
||||||
if (req.query.inProgress) {
|
|
||||||
filter.confirmed = 0;
|
|
||||||
}
|
|
||||||
if (req.query.simple) {
|
|
||||||
AwardingModel.find(filter, {}, {sort: {date: 'desc'}}, (err, items) => {
|
|
||||||
if (err) {
|
|
||||||
err.status = codes.servererror;
|
|
||||||
return next(err);
|
|
||||||
// with return before (or after) the next(err) we prevent that the code continues here after next(err) has finished.
|
|
||||||
// this saves an extra else {..}
|
|
||||||
}
|
|
||||||
// if the collection is empty we do not send empty arrays back.
|
|
||||||
if (items && items.length > 0) {
|
|
||||||
res.locals.items = items;
|
|
||||||
}
|
|
||||||
res.locals.processed = true;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
AwardingModel.find(filter, {}, {sort: {date: 'desc'}})
|
|
||||||
.populate('decorationId').populate('proposer', resultSet).populate('userId').exec((err, items) => {
|
|
||||||
if (err) {
|
|
||||||
err.status = codes.servererror;
|
|
||||||
return next(err);
|
|
||||||
// with return before (or after) the next(err) we prevent that the code continues here after next(err) has finished.
|
|
||||||
// this saves an extra else {..}
|
|
||||||
}
|
|
||||||
let results = [];
|
|
||||||
if (req.query.fractFilter) {
|
|
||||||
for (let item of items) {
|
|
||||||
if (item.decorationId.fraction === req.query.fractFilter) {
|
|
||||||
results.push(item)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
res.locals.items = results;
|
if (req.query.inProgress) {
|
||||||
|
filter.confirmed = 0;
|
||||||
|
}
|
||||||
|
if (req.query.simple) {
|
||||||
|
AwardingModel.find(filter, {}, {sort: {date: 'desc'}}, (err, items) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.servererror;
|
||||||
|
return next(err);
|
||||||
|
// with return before (or after) the next(err) we prevent that the code continues here after next(err)
|
||||||
|
// has finished. this saves an extra else {..}
|
||||||
|
}
|
||||||
|
// if the collection is empty we do not send empty arrays back.
|
||||||
|
if (items && items.length > 0) {
|
||||||
|
res.locals.items = items;
|
||||||
|
}
|
||||||
|
res.locals.processed = true;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
AwardingModel.find(filter, {}, {sort: {date: 'desc'}})
|
||||||
|
.populate('decorationId').populate('proposer', resultSet).populate('userId').exec((err, items) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.servererror;
|
||||||
|
return next(err);
|
||||||
|
// with return before (or after) the next(err) we prevent that the code continues here after next(err)
|
||||||
|
// has finished. this saves an extra else {..}
|
||||||
|
}
|
||||||
|
let results = [];
|
||||||
|
if (req.query.fractFilter) {
|
||||||
|
for (let item of items) {
|
||||||
|
if (item.decorationId.fraction === req.query.fractFilter) {
|
||||||
|
results.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.locals.items = results;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
res.locals.items = items;
|
res.locals.items = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.post(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
const award = new AwardingModel(req.body);
|
const award = new AwardingModel(req.body);
|
||||||
award.confirmed = 1;
|
award.confirmed = 1;
|
||||||
award.proposer = req.user._id;
|
award.proposer = req.user._id;
|
||||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||||
award.save((err) => {
|
award.save((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
res.status(codes.created);
|
||||||
res.locals.items = award;
|
res.locals.items = award;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
awarding.route('/:id')
|
awarding.route('/:id')
|
||||||
|
|
||||||
.patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
||||||
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
||||||
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
next(err);
|
next(err);
|
||||||
return; // prevent node to process this function further after next() has finished.
|
return; // prevent node to process this function further after next() has finished.
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional task 3: increment version manually as we do not use .save(.)
|
// optional task 3: increment version manually as we do not use .save(.)
|
||||||
req.body.updatedAt = new Date();
|
req.body.updatedAt = new Date();
|
||||||
req.body.$inc = {__v: 1};
|
req.body.$inc = {__v: 1};
|
||||||
|
|
||||||
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing.
|
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to
|
||||||
AwardingModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
// reset attributes that are missing.
|
||||||
if (err) {
|
AwardingModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
||||||
err.status = codes.wrongrequest;
|
if (err) {
|
||||||
}
|
err.status = codes.wrongrequest;
|
||||||
else if (!item) {
|
}
|
||||||
err = new Error("item not found");
|
else if (!item) {
|
||||||
err.status = codes.notfound;
|
err = new Error("item not found");
|
||||||
}
|
err.status = codes.notfound;
|
||||||
else {
|
}
|
||||||
res.locals.items = item;
|
else {
|
||||||
}
|
res.locals.items = item;
|
||||||
next(err);
|
}
|
||||||
})
|
next(err);
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
AwardingModel.findByIdAndRemove(req.params.id, (err, item) => {
|
AwardingModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
}
|
}
|
||||||
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler user.use(..)
|
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler
|
||||||
res.locals.processed = true;
|
// user.use(..)
|
||||||
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
res.locals.processed = true;
|
||||||
});
|
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
||||||
})
|
});
|
||||||
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// 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
|
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||||
|
|
|
@ -23,63 +23,63 @@ const campaigns = express.Router();
|
||||||
// routes **********************
|
// routes **********************
|
||||||
campaigns.route('/')
|
campaigns.route('/')
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkMT, (req, res, next) => {
|
.post(apiAuthenticationMiddleware, checkMT, (req, res, next) => {
|
||||||
const campaign = new CampaignModel(req.body);
|
const campaign = new CampaignModel(req.body);
|
||||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||||
campaign.save((err) => {
|
campaign.save((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
res.status(codes.created);
|
||||||
res.locals.items = campaign;
|
res.locals.items = campaign;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
campaigns.route('/:id')
|
campaigns.route('/:id')
|
||||||
.get(idValidator, (req, res, next) => {
|
.get(idValidator, (req, res, next) => {
|
||||||
CampaignModel.findById(req.params.id, (err, item) => {
|
CampaignModel.findById(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.locals.items = item;
|
res.locals.items = item;
|
||||||
return next();
|
return next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.delete((req, res, next) => {
|
.delete((req, res, next) => {
|
||||||
CampaignModel.findByIdAndRemove(req.params.id, (err, item) => {
|
CampaignModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
WarModel.find({campaign: req.params.id}).remove().exec();
|
WarModel.find({campaign: req.params.id}).remove().exec();
|
||||||
|
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
next();
|
next();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// 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
|
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||||
|
|
|
@ -14,23 +14,23 @@ const createSignature = require('../tools/signature-tool');
|
||||||
const command = express.Router();
|
const command = express.Router();
|
||||||
|
|
||||||
command.route('/createSignature')
|
command.route('/createSignature')
|
||||||
.post((req, res, next) => {
|
.post((req, res, next) => {
|
||||||
createAllSignatures();
|
createAllSignatures();
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
command.route('/createSignature/:id')
|
command.route('/createSignature/:id')
|
||||||
.post((req, res, next) => {
|
.post((req, res, next) => {
|
||||||
const userId = req.params.id;
|
const userId = req.params.id;
|
||||||
createSignature(userId, res, next);
|
createSignature(userId, res, next);
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// this middleware function can be used, if you like or remove it
|
||||||
|
|
|
@ -26,136 +26,145 @@ const decoration = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
decoration.route('/')
|
decoration.route('/')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
if (req.query.fractFilter) {
|
if (req.query.fractFilter) {
|
||||||
filter.fraction = req.query.fractFilter.toUpperCase()
|
filter.fraction = req.query.fractFilter.toUpperCase()
|
||||||
}
|
}
|
||||||
if (req.query.q) {
|
if (req.query.q) {
|
||||||
filter.name = {$regex: req.query.q, $options: 'i'}
|
filter.name = {$regex: req.query.q, $options: 'i'}
|
||||||
}
|
}
|
||||||
DecorationModel.find(filter, {}, {sort: {fraction: 'asc', isMedal: 'asc', sortingNumber: 'asc', name: 'asc'}}, (err, items) => {
|
DecorationModel.find(filter, {}, {
|
||||||
if (err) {
|
sort: {
|
||||||
err.status = codes.servererror;
|
fraction: 'asc',
|
||||||
return next(err);
|
isMedal: 'asc',
|
||||||
}
|
sortingNumber: 'asc',
|
||||||
if (items && items.length > 0) {
|
name: 'asc'
|
||||||
res.locals.items = items;
|
}
|
||||||
} else {
|
}, (err, items) => {
|
||||||
res.locals.items = [];
|
if (err) {
|
||||||
}
|
err.status = codes.servererror;
|
||||||
res.locals.processed = true;
|
return next(err);
|
||||||
next();
|
}
|
||||||
});
|
if (items && items.length > 0) {
|
||||||
})
|
res.locals.items = items;
|
||||||
|
} else {
|
||||||
|
res.locals.items = [];
|
||||||
|
}
|
||||||
|
res.locals.processed = true;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
||||||
const decoration = new DecorationModel(req.body);
|
const decoration = new DecorationModel(req.body);
|
||||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||||
decoration.save((err) => {
|
decoration.save((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
res.status(codes.created);
|
||||||
res.locals.items = decoration;
|
res.locals.items = decoration;
|
||||||
fs.appendFile(__dirname + '/../resource/decoration/' + decoration.id + '.png', new Buffer(req.file.buffer),
|
fs.appendFile(__dirname + '/../resource/decoration/' + decoration.id + '.png', new Buffer(req.file.buffer),
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) next(err);
|
if (err) next(err);
|
||||||
});
|
});
|
||||||
next();
|
next();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
decoration.route('/:id')
|
decoration.route('/:id')
|
||||||
.get(idValidator, (req, res, next) => {
|
.get(idValidator, (req, res, next) => {
|
||||||
DecorationModel.findById(req.params.id, (err, item) => {
|
DecorationModel.findById(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.locals.items = item;
|
res.locals.items = item;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
||||||
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
||||||
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
||||||
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
next(err);
|
next(err);
|
||||||
return; // prevent node to process this function further after next() has finished.
|
return; // prevent node to process this function further after next() has finished.
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional task 3: increment version manually as we do not use .save(.)
|
// optional task 3: increment version manually as we do not use .save(.)
|
||||||
req.body.updatedAt = new Date();
|
req.body.updatedAt = new Date();
|
||||||
req.body.$inc = {__v: 1};
|
req.body.$inc = {__v: 1};
|
||||||
|
|
||||||
if (req.file) {
|
if (req.file) {
|
||||||
const file = __dirname + '/../resource/decoration/' + req.body._id + '.png';
|
const file = __dirname + '/../resource/decoration/' + req.body._id + '.png';
|
||||||
fs.unlink(file, (err) => {
|
fs.unlink(file, (err) => {
|
||||||
if (err) next(err);
|
if (err) next(err);
|
||||||
fs.appendFile(file, new Buffer(req.file.buffer), (err) => {
|
fs.appendFile(file, new Buffer(req.file.buffer), (err) => {
|
||||||
if (err) next(err);
|
if (err) next(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing.
|
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need
|
||||||
DecorationModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
// to reset attributes that are missing.
|
||||||
if (err) {
|
DecorationModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
||||||
err.status = codes.wrongrequest;
|
if (err) {
|
||||||
}
|
err.status = codes.wrongrequest;
|
||||||
else if (!item) {
|
}
|
||||||
err = new Error("item not found");
|
else if (!item) {
|
||||||
err.status = codes.notfound;
|
err = new Error("item not found");
|
||||||
}
|
err.status = codes.notfound;
|
||||||
else {
|
}
|
||||||
res.locals.items = item;
|
else {
|
||||||
}
|
res.locals.items = item;
|
||||||
next(err);
|
}
|
||||||
})
|
next(err);
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
DecorationModel.findByIdAndRemove(req.params.id, (err, item) => {
|
DecorationModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleted all awardings linked to this decoration
|
// deleted all awardings linked to this decoration
|
||||||
AwardingsModel.find({decorationId: req.params.id}).remove().exec();
|
AwardingsModel.find({decorationId: req.params.id}).remove().exec();
|
||||||
|
|
||||||
// delete graphic
|
// delete graphic
|
||||||
fs.unlink(__dirname + '/../resource/decoration/' + req.params.id + '.png',
|
fs.unlink(__dirname + '/../resource/decoration/' + req.params.id + '.png',
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) next(err);
|
if (err) next(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(..)
|
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler
|
||||||
res.locals.processed = true;
|
// user.use(..)
|
||||||
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
res.locals.processed = true;
|
||||||
});
|
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
||||||
})
|
});
|
||||||
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// 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
|
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||||
|
|
|
@ -13,6 +13,7 @@ const LogBudgetModel = require('../models/logs/budget');
|
||||||
const LogRespawnModel = require('../models/logs/respawn');
|
const LogRespawnModel = require('../models/logs/respawn');
|
||||||
const LogReviveModel = require('../models/logs/revive');
|
const LogReviveModel = require('../models/logs/revive');
|
||||||
const LogKillModel = require('../models/logs/kill');
|
const LogKillModel = require('../models/logs/kill');
|
||||||
|
const LogVehicleModel = require('../models/logs/vehicle');
|
||||||
const LogTransportModel = require('../models/logs/transport');
|
const LogTransportModel = require('../models/logs/transport');
|
||||||
const LogFlagModel = require('../models/logs/flag');
|
const LogFlagModel = require('../models/logs/flag');
|
||||||
const LogPointsModel = require('../models/logs/points');
|
const LogPointsModel = require('../models/logs/points');
|
||||||
|
@ -34,122 +35,124 @@ function processLogRequest(model, filter, res, next) {
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
logsRouter.route('/:warId')
|
logsRouter.route('/:warId')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {war: req.params.warId};
|
const filter = {war: req.params.warId};
|
||||||
const sort = {sort: {time: 1}};
|
const sort = {sort: {time: 1}};
|
||||||
|
|
||||||
const pointsObjects = LogPointsModel.find(filter, {}, sort);
|
const pointsObjects = LogPointsModel.find(filter, {}, sort);
|
||||||
const budgetObjects = LogBudgetModel.find(filter, {}, sort);
|
const budgetObjects = LogBudgetModel.find(filter, {}, sort);
|
||||||
const respawnObjects = LogRespawnModel.find(filter, {}, sort);
|
const respawnObjects = LogRespawnModel.find(filter, {}, sort);
|
||||||
const reviveObjects = LogReviveModel.find(filter, {}, sort);
|
const reviveObjects = LogReviveModel.find(filter, {}, sort);
|
||||||
const killObjects = LogKillModel.find(filter, {}, sort);
|
const killObjects = LogKillModel.find(filter, {}, sort);
|
||||||
const transportObjects = LogTransportModel.find(filter, {}, sort);
|
const vehicleObjects = LogVehicleModel.find(filter, {}, sort);
|
||||||
const flagObjects = LogFlagModel.find(filter, {}, sort);
|
const transportObjects = LogTransportModel.find(filter, {}, sort);
|
||||||
const resources = {
|
const flagObjects = LogFlagModel.find(filter, {}, sort);
|
||||||
points: pointsObjects.exec.bind(pointsObjects),
|
const resources = {
|
||||||
budget: budgetObjects.exec.bind(budgetObjects),
|
points: pointsObjects.exec.bind(pointsObjects),
|
||||||
respawn: respawnObjects.exec.bind(respawnObjects),
|
budget: budgetObjects.exec.bind(budgetObjects),
|
||||||
revive: reviveObjects.exec.bind(reviveObjects),
|
respawn: respawnObjects.exec.bind(respawnObjects),
|
||||||
kill: killObjects.exec.bind(killObjects),
|
revive: reviveObjects.exec.bind(reviveObjects),
|
||||||
transport: transportObjects.exec.bind(transportObjects),
|
kill: killObjects.exec.bind(killObjects),
|
||||||
flag: flagObjects.exec.bind(flagObjects)
|
vehicle: killObjects.exec.bind(vehicleObjects),
|
||||||
};
|
transport: transportObjects.exec.bind(transportObjects),
|
||||||
|
flag: flagObjects.exec.bind(flagObjects)
|
||||||
|
};
|
||||||
|
|
||||||
async.parallel(resources, function (error, results){
|
async.parallel(resources, function (error, results) {
|
||||||
if (error) {
|
if (error) {
|
||||||
res.status(500).send(error);
|
res.status(500).send(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res.locals.items = results;
|
res.locals.items = results;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
logsRouter.route('/:warId/budget')
|
logsRouter.route('/:warId/budget')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {war: req.params.warId};
|
const filter = {war: req.params.warId};
|
||||||
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
||||||
processLogRequest(LogBudgetModel, filter, res, next);
|
processLogRequest(LogBudgetModel, filter, res, next);
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
logsRouter.route('/:warId/respawn')
|
logsRouter.route('/:warId/respawn')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {war: req.params.warId};
|
const filter = {war: req.params.warId};
|
||||||
if (req.query.player) filter['player'] = req.query.player;
|
if (req.query.player) filter['player'] = req.query.player;
|
||||||
processLogRequest(LogRespawnModel, filter, res, next);
|
processLogRequest(LogRespawnModel, filter, res, next);
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
logsRouter.route('/:warId/revive')
|
logsRouter.route('/:warId/revive')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {war: req.params.warId};
|
const filter = {war: req.params.warId};
|
||||||
if (req.query.medic) filter['medic'] = req.query.medic;
|
if (req.query.medic) filter['medic'] = req.query.medic;
|
||||||
if (req.query.patient) filter['patient'] = req.query.patient;
|
if (req.query.patient) filter['patient'] = req.query.patient;
|
||||||
if (req.query.stabilized) filter['stabilized'] = true;
|
if (req.query.stabilized) filter['stabilized'] = true;
|
||||||
if (req.query.revive) filter['stabilized'] = false;
|
if (req.query.revive) filter['stabilized'] = false;
|
||||||
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
||||||
processLogRequest(LogReviveModel, filter, res, next);
|
processLogRequest(LogReviveModel, filter, res, next);
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
logsRouter.route('/:warId/kills')
|
logsRouter.route('/:warId/kills')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {war: req.params.warId};
|
const filter = {war: req.params.warId};
|
||||||
if (req.query.shooter) filter['shooter'] = req.query.shooter;
|
if (req.query.shooter) filter['shooter'] = req.query.shooter;
|
||||||
if (req.query.target) filter['target'] = req.query.target;
|
if (req.query.target) filter['target'] = req.query.target;
|
||||||
if (req.query.friendlyFire) filter['friendlyFire'] = true;
|
if (req.query.friendlyFire) filter['friendlyFire'] = true;
|
||||||
if (req.query.noFriendlyFire) filter['friendlyFire'] = false;
|
if (req.query.noFriendlyFire) filter['friendlyFire'] = false;
|
||||||
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
||||||
processLogRequest(LogKillModel, filter, res, next);
|
processLogRequest(LogKillModel, filter, res, next);
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
logsRouter.route('/:warId/transport')
|
logsRouter.route('/:warId/transport')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {war: req.params.warId};
|
const filter = {war: req.params.warId};
|
||||||
if (req.query.driver) filter['driver'] = req.query.driver;
|
if (req.query.driver) filter['driver'] = req.query.driver;
|
||||||
if (req.query.passenger) filter['passenger'] = req.query.passenger;
|
if (req.query.passenger) filter['passenger'] = req.query.passenger;
|
||||||
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
||||||
processLogRequest(LogTransportModel, filter, res, next);
|
processLogRequest(LogTransportModel, filter, res, next);
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
logsRouter.route('/:warId/flag')
|
logsRouter.route('/:warId/flag')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {war: req.params.warId};
|
const filter = {war: req.params.warId};
|
||||||
if (req.query.player) filter['player'] = req.query.player;
|
if (req.query.player) filter['player'] = req.query.player;
|
||||||
if (req.query.capture) filter['capture'] = true;
|
if (req.query.capture) filter['capture'] = true;
|
||||||
if (req.query.defend) filter['capture'] = false;
|
if (req.query.defend) filter['capture'] = false;
|
||||||
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
||||||
processLogRequest(LogFlagModel, filter, res, next);
|
processLogRequest(LogFlagModel, filter, res, next);
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
logsRouter.route('/:warId/points')
|
logsRouter.route('/:warId/points')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {war: req.params.warId};
|
const filter = {war: req.params.warId};
|
||||||
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
if (req.query.fraction) filter['fraction'] = req.query.fraction;
|
||||||
processLogRequest(LogPointsModel, filter, res, next);
|
processLogRequest(LogPointsModel, filter, res, next);
|
||||||
})
|
})
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
logsRouter.use(routerHandling.emptyResponse);
|
logsRouter.use(routerHandling.emptyResponse);
|
||||||
|
|
||||||
|
|
|
@ -18,93 +18,93 @@ const overview = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
overview.route('/')
|
overview.route('/')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
let countOpfor = 0;
|
let countOpfor = 0;
|
||||||
let countBlufor = 0;
|
let countBlufor = 0;
|
||||||
const armyOverview = {
|
const armyOverview = {
|
||||||
BLUFOR: {
|
BLUFOR: {
|
||||||
squads: []
|
squads: []
|
||||||
},
|
},
|
||||||
OPFOR: {
|
OPFOR: {
|
||||||
squads: []
|
squads: []
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SquadModel.find({}, {'sortingNumber': 0, 'updatedAt': 0, 'timestamp': 0, '__v': 0}, {
|
SquadModel.find({}, {'sortingNumber': 0, 'updatedAt': 0, 'timestamp': 0, '__v': 0}, {
|
||||||
sort: {
|
sort: {
|
||||||
sortingNumber: 'asc',
|
sortingNumber: 'asc',
|
||||||
name: 'asc'
|
name: 'asc'
|
||||||
}
|
}
|
||||||
}, (err, squads) => {
|
}, (err, squads) => {
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
async.eachSeries(squads, (squad, callback) => {
|
|
||||||
UserModel.find({squadId: squad._id}, {
|
|
||||||
'squadId': 0,
|
|
||||||
'updatedAt': 0,
|
|
||||||
'timestamp': 0,
|
|
||||||
'__v': 0
|
|
||||||
}, {sort: {rankLvl: 'desc', name: 'asc'}}, (err, users) => {
|
|
||||||
const squadMembers = [];
|
|
||||||
async.eachSeries(users, (user, callback) => {
|
|
||||||
const usr = user.toObject();
|
|
||||||
RankModel.findOne({level: user.rankLvl, fraction: squad.fraction}, (err, rank) => {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
// not defined if rank was deleted / rankLvl not available for fraction
|
|
||||||
if (rank) {
|
|
||||||
usr.rank = rank.name;
|
|
||||||
}
|
|
||||||
delete usr.rankLvl;
|
|
||||||
squadMembers.push(usr)
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}, (err) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
async.eachSeries(squads, (squad, callback) => {
|
||||||
|
UserModel.find({squadId: squad._id}, {
|
||||||
|
'squadId': 0,
|
||||||
|
'updatedAt': 0,
|
||||||
|
'timestamp': 0,
|
||||||
|
'__v': 0
|
||||||
|
}, {sort: {rankLvl: 'desc', name: 'asc'}}, (err, users) => {
|
||||||
|
const squadMembers = [];
|
||||||
|
async.eachSeries(users, (user, callback) => {
|
||||||
|
const usr = user.toObject();
|
||||||
|
RankModel.findOne({level: user.rankLvl, fraction: squad.fraction}, (err, rank) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
// do not return empty squads
|
// not defined if rank was deleted / rankLvl not available for fraction
|
||||||
if (squadMembers.length > 0) {
|
if (rank) {
|
||||||
const s = squad.toObject();
|
usr.rank = rank.name;
|
||||||
s.members = squadMembers;
|
}
|
||||||
s.memberCount = squadMembers.length;
|
delete usr.rankLvl;
|
||||||
if (s.fraction === 'BLUFOR') {
|
squadMembers.push(usr)
|
||||||
delete s.fraction;
|
|
||||||
armyOverview.BLUFOR.squads.push(s);
|
|
||||||
countBlufor += s.members.length;
|
|
||||||
}
|
|
||||||
if (s.fraction === 'OPFOR') {
|
|
||||||
delete s.fraction;
|
|
||||||
armyOverview.OPFOR.squads.push(s);
|
|
||||||
countOpfor += s.members.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
|
});
|
||||||
|
}, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not return empty squads
|
||||||
|
if (squadMembers.length > 0) {
|
||||||
|
const s = squad.toObject();
|
||||||
|
s.members = squadMembers;
|
||||||
|
s.memberCount = squadMembers.length;
|
||||||
|
if (s.fraction === 'BLUFOR') {
|
||||||
|
delete s.fraction;
|
||||||
|
armyOverview.BLUFOR.squads.push(s);
|
||||||
|
countBlufor += s.members.length;
|
||||||
|
}
|
||||||
|
if (s.fraction === 'OPFOR') {
|
||||||
|
delete s.fraction;
|
||||||
|
armyOverview.OPFOR.squads.push(s);
|
||||||
|
countOpfor += s.members.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
armyOverview.BLUFOR.memberCount = countBlufor;
|
||||||
|
armyOverview.OPFOR.memberCount = countOpfor;
|
||||||
|
res.locals.items = armyOverview;
|
||||||
|
res.locals.processed = true;
|
||||||
|
next();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
|
|
||||||
}, (err) => {
|
.all(
|
||||||
if (err) {
|
routerHandling.httpMethodNotAllowed
|
||||||
return next(err);
|
);
|
||||||
}
|
|
||||||
armyOverview.BLUFOR.memberCount = countBlufor;
|
|
||||||
armyOverview.OPFOR.memberCount = countOpfor;
|
|
||||||
res.locals.items = armyOverview;
|
|
||||||
res.locals.processed = true;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
.all(
|
|
||||||
routerHandling.httpMethodNotAllowed
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
overview.use(routerHandling.emptyResponse);
|
overview.use(routerHandling.emptyResponse);
|
||||||
|
|
|
@ -14,99 +14,125 @@ const CampaignModel = require('../models/campaign');
|
||||||
const PlayerModel = require('../models/player');
|
const PlayerModel = require('../models/player');
|
||||||
const WarModel = require('../models/war');
|
const WarModel = require('../models/war');
|
||||||
|
|
||||||
|
// Util
|
||||||
|
const isSteamUUID = require('../tools/util').isSteamUUID;
|
||||||
|
|
||||||
const campaignPlayer = express.Router();
|
const campaignPlayer = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
campaignPlayer.route('/ranking/:campaignId')
|
campaignPlayer.route('/ranking/:campaignId')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
WarModel.find({campaign: req.params.campaignId}, '_id', (err, wars) => {
|
WarModel.find({campaign: req.params.campaignId}, '_id', (err, wars) => {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
const warIds = wars.map((obj) => {
|
const warIds = wars.map((obj) => {
|
||||||
return obj._id;
|
return obj._id;
|
||||||
});
|
});
|
||||||
PlayerModel.find({warId: {"$in": warIds}}, (err, items) => {
|
PlayerModel.find({warId: {"$in": warIds}}, (err, items) => {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
if (!items || items.length === 0) {
|
if (!items || items.length === 0) {
|
||||||
const err = new Error('No players for given campaignId');
|
const err = new Error('No players for given campaignId');
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const rankingItems = [];
|
const rankingItems = [];
|
||||||
new Set(items.map(x => x.name)).forEach(playerName => {
|
|
||||||
const playerInstances = items.filter(p => p.name === playerName);
|
|
||||||
const resItem = {name: playerName, kill: 0, death: 0, friendlyFire: 0, revive: 0, respawn: 0, flagTouch: 0};
|
|
||||||
for (let i = 0; i < playerInstances.length; i++) {
|
|
||||||
resItem.kill += playerInstances[i].kill;
|
|
||||||
resItem.death += playerInstances[i].death;
|
|
||||||
resItem.friendlyFire += playerInstances[i].friendlyFire;
|
|
||||||
resItem.revive += playerInstances[i].revive;
|
|
||||||
resItem.respawn += playerInstances[i].respawn;
|
|
||||||
resItem.flagTouch += playerInstances[i].flagTouch;
|
|
||||||
}
|
|
||||||
resItem.fraction = playerInstances[playerInstances.length - 1].fraction;
|
|
||||||
rankingItems.push(resItem);
|
|
||||||
});
|
|
||||||
|
|
||||||
function getSortedField(fieldName) {
|
// check only first player to have valid steamUUID - then decide if tracked by name or by ID
|
||||||
let num = 1;
|
const usesUUID = isSteamUUID(items[0].steamUUID);
|
||||||
rankingItems.sort((a, b) => b[fieldName] - a[fieldName])
|
|
||||||
const res = JSON.parse(JSON.stringify(rankingItems));
|
|
||||||
for (const entity of res) {
|
|
||||||
entity.num = num++;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.locals.items = {
|
new Set(items.map(usesUUID ? x => x.steamUUID : x => x.name))
|
||||||
kill: getSortedField('kill'),
|
.forEach(player => {
|
||||||
death: getSortedField('death'),
|
const playerInstances = items.filter(usesUUID ? p => p.steamUUID === player : p => p.name === player);
|
||||||
friendlyFire: getSortedField('friendlyFire'),
|
const resItem = {
|
||||||
revive: getSortedField('revive'),
|
name: usesUUID ? playerInstances[playerInstances.length - 1].name : player,
|
||||||
respawn: getSortedField('respawn'),
|
kill: 0,
|
||||||
flagTouch: getSortedField('flagTouch')
|
vehicle: 0,
|
||||||
};
|
death: 0,
|
||||||
next();
|
friendlyFire: 0,
|
||||||
})
|
revive: 0,
|
||||||
})
|
respawn: 0,
|
||||||
})
|
flagTouch: 0
|
||||||
|
};
|
||||||
|
for (let i = 0; i < playerInstances.length; i++) {
|
||||||
|
resItem.kill += playerInstances[i].kill;
|
||||||
|
resItem.death += playerInstances[i].death;
|
||||||
|
resItem.friendlyFire += playerInstances[i].friendlyFire;
|
||||||
|
resItem.vehicle += playerInstances[i].vehicle;
|
||||||
|
resItem.revive += playerInstances[i].revive;
|
||||||
|
resItem.respawn += playerInstances[i].respawn;
|
||||||
|
resItem.flagTouch += playerInstances[i].flagTouch;
|
||||||
|
}
|
||||||
|
resItem.fraction = playerInstances[playerInstances.length - 1].fraction;
|
||||||
|
rankingItems.push(resItem);
|
||||||
|
});
|
||||||
|
|
||||||
.all(
|
function getSortedField(fieldName) {
|
||||||
routerHandling.httpMethodNotAllowed
|
let num = 1;
|
||||||
);
|
rankingItems.sort((a, b) => b[fieldName] - a[fieldName])
|
||||||
|
const res = JSON.parse(JSON.stringify(rankingItems));
|
||||||
|
for (const entity of res) {
|
||||||
|
entity.num = num++;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
campaignPlayer.route('/single/:campaignId/:playerName')
|
res.locals.items = {
|
||||||
.get((req, res, next) => {
|
kill: getSortedField('kill'),
|
||||||
CampaignModel.findById(req.params.campaignId, (err, campaign) => {
|
death: getSortedField('death'),
|
||||||
if (err) return next(err);
|
friendlyFire: getSortedField('friendlyFire'),
|
||||||
WarModel.find({campaign: req.params.campaignId}, '_id', (err, wars) => {
|
vehicle: getSortedField('vehicle'),
|
||||||
if (err) return next(err);
|
revive: getSortedField('revive'),
|
||||||
const warIds = wars.map((obj) => {
|
respawn: getSortedField('respawn'),
|
||||||
return obj._id;
|
flagTouch: getSortedField('flagTouch')
|
||||||
});
|
};
|
||||||
PlayerModel.find({name: req.params.playerName, warId: {"$in": warIds}})
|
next();
|
||||||
.populate('warId')
|
})
|
||||||
.exec((err, items) => {
|
})
|
||||||
if (err) return next(err);
|
})
|
||||||
if (!items || items.length === 0) {
|
|
||||||
const err = new Error('Unknown player name');
|
|
||||||
err.status = codes.notfound;
|
|
||||||
return next(err)
|
|
||||||
}
|
|
||||||
res.locals.items = {
|
|
||||||
name: req.params.playerName,
|
|
||||||
campaign: campaign,
|
|
||||||
players: items
|
|
||||||
};
|
|
||||||
next();
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
campaignPlayer.route('/single/:campaignId/:playerId')
|
||||||
|
.get((req, res, next) => {
|
||||||
|
CampaignModel.findById(req.params.campaignId, (err, campaign) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
WarModel.find({campaign: req.params.campaignId}, '_id', (err, wars) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
const warIds = wars.map((obj) => {
|
||||||
|
return obj._id;
|
||||||
|
});
|
||||||
|
|
||||||
|
// find by player name until v1.6.12, afterwards by SteamUUID
|
||||||
|
const playerId = req.params.playerId;
|
||||||
|
const filter = {};
|
||||||
|
filter[isSteamUUID(playerId) ? 'steamUUID' : 'name'] = playerId;
|
||||||
|
filter['warId'] = {"$in": warIds};
|
||||||
|
|
||||||
|
PlayerModel.find(filter)
|
||||||
|
.populate('warId')
|
||||||
|
.exec((err, items) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
if (!items || items.length === 0) {
|
||||||
|
const err = new Error('Unknown player id');
|
||||||
|
err.status = codes.notfound;
|
||||||
|
return next(err)
|
||||||
|
}
|
||||||
|
res.locals.items = {
|
||||||
|
name: items[items.length - 1].name,
|
||||||
|
campaign: campaign,
|
||||||
|
players: items
|
||||||
|
};
|
||||||
|
next();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
.all(
|
||||||
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
campaignPlayer.use(routerHandling.emptyResponse);
|
campaignPlayer.use(routerHandling.emptyResponse);
|
||||||
|
|
|
@ -24,130 +24,132 @@ const ranks = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
ranks.route('/')
|
ranks.route('/')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
if (req.query.fractFilter) {
|
if (req.query.fractFilter) {
|
||||||
filter.fraction = req.query.fractFilter.toUpperCase()
|
filter.fraction = req.query.fractFilter.toUpperCase()
|
||||||
}
|
}
|
||||||
if (req.query.q) {
|
if (req.query.q) {
|
||||||
filter.name = {$regex: req.query.q, $options: 'i'}
|
filter.name = {$regex: req.query.q, $options: 'i'}
|
||||||
}
|
}
|
||||||
|
|
||||||
RankModel.find(filter, {}, {sort: {fraction: 'asc', level: 'asc'}}, (err, items) => {
|
RankModel.find(filter, {}, {sort: {fraction: 'asc', level: 'asc'}}, (err, items) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items && items.length > 0) {
|
if (items && items.length > 0) {
|
||||||
res.locals.items = items;
|
res.locals.items = items;
|
||||||
} else {
|
} else {
|
||||||
res.locals.items = [];
|
res.locals.items = [];
|
||||||
}
|
}
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
||||||
const rank = new RankModel(req.body);
|
const rank = new RankModel(req.body);
|
||||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||||
rank.save((err) => {
|
rank.save((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
next(err);
|
next(err);
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
res.status(codes.created);
|
||||||
res.locals.items = rank;
|
res.locals.items = rank;
|
||||||
fs.appendFile(__dirname + '/../resource/rank/' + rank.id + '.png', new Buffer(req.file.buffer),
|
fs.appendFile(__dirname + '/../resource/rank/' + rank.id + '.png', new Buffer(req.file.buffer),
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) next(err);
|
if (err) next(err);
|
||||||
});
|
});
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
ranks.route('/:id')
|
ranks.route('/:id')
|
||||||
.get(idValidator, (req, res, next) => {
|
.get(idValidator, (req, res, next) => {
|
||||||
RankModel.findById(req.params.id, (err, item) => {
|
RankModel.findById(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.locals.items = item;
|
res.locals.items = item;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
||||||
|
|
||||||
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
||||||
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
||||||
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
next(err);
|
next(err);
|
||||||
return; // prevent node to process this function further after next() has finished.
|
return; // prevent node to process this function further after next() has finished.
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional task 3: increment version manually as we do not use .save(.)
|
// optional task 3: increment version manually as we do not use .save(.)
|
||||||
req.body.updatedAt = new Date();
|
req.body.updatedAt = new Date();
|
||||||
req.body.$inc = {__v: 1};
|
req.body.$inc = {__v: 1};
|
||||||
|
|
||||||
if (req.file) {
|
if (req.file) {
|
||||||
const file = __dirname + '/../resource/rank/' + req.body._id + '.png';
|
const file = __dirname + '/../resource/rank/' + req.body._id + '.png';
|
||||||
fs.unlink(file, (err) => {
|
fs.unlink(file, (err) => {
|
||||||
if (err) next(err);
|
if (err) next(err);
|
||||||
fs.appendFile(file, new Buffer(req.file.buffer),
|
fs.appendFile(file, new Buffer(req.file.buffer),
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) next(err);
|
if (err) next(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing.
|
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to
|
||||||
RankModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
// reset attributes that are missing.
|
||||||
if (err) {
|
RankModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
||||||
err.status = codes.wrongrequest;
|
if (err) {
|
||||||
}
|
err.status = codes.wrongrequest;
|
||||||
else if (!item) {
|
}
|
||||||
err = new Error("item not found");
|
else if (!item) {
|
||||||
err.status = codes.notfound;
|
err = new Error("item not found");
|
||||||
}
|
err.status = codes.notfound;
|
||||||
else {
|
}
|
||||||
res.locals.items = item;
|
else {
|
||||||
}
|
res.locals.items = item;
|
||||||
next(err);
|
}
|
||||||
})
|
next(err);
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
RankModel.findByIdAndRemove(req.params.id, (err, item) => {
|
RankModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
}
|
}
|
||||||
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler user.use(..)
|
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler
|
||||||
res.locals.processed = true;
|
// user.use(..)
|
||||||
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
res.locals.processed = true;
|
||||||
})
|
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// this middleware function can be used, if you like or remove it
|
||||||
|
|
|
@ -35,145 +35,146 @@ const request = express.Router();
|
||||||
// routes **********************
|
// routes **********************
|
||||||
request.route('/award')
|
request.route('/award')
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkSql, (req, res, next) => {
|
.post(apiAuthenticationMiddleware, checkSql, (req, res, next) => {
|
||||||
const award = new AwardingModel(req.body);
|
const award = new AwardingModel(req.body);
|
||||||
award.confirmed = 0;
|
award.confirmed = 0;
|
||||||
award.proposer = req.user._id;
|
award.proposer = req.user._id;
|
||||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||||
award.save((err) => {
|
award.save((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
res.status(codes.created);
|
||||||
res.locals.items = award;
|
res.locals.items = award;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
request.route('/promotion')
|
request.route('/promotion')
|
||||||
|
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
// TODO: add SQL authentication
|
// TODO: add SQL authentication
|
||||||
const squadFilter = req.query.squadId;
|
const squadFilter = req.query.squadId;
|
||||||
const fractFilter = req.query.fractFilter;
|
const fractFilter = req.query.fractFilter;
|
||||||
const progressFilter = req.query.inProgress;
|
const progressFilter = req.query.inProgress;
|
||||||
let filter;
|
let filter;
|
||||||
if (squadFilter) {
|
if (squadFilter) {
|
||||||
filter = {squadId: squadFilter};
|
filter = {squadId: squadFilter};
|
||||||
}
|
}
|
||||||
let userIds = [];
|
let userIds = [];
|
||||||
UserModel.find(filter).populate('squadId').exec((err, items) => {
|
UserModel.find(filter).populate('squadId').exec((err, items) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let item of items) {
|
for (let item of items) {
|
||||||
if (!fractFilter || (fractFilter && item.squadId && item.squadId.fraction === fractFilter)) {
|
if (!fractFilter || (fractFilter && item.squadId && item.squadId.fraction === fractFilter)) {
|
||||||
userIds.push(item._id);
|
userIds.push(item._id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let promotionFilter = {
|
let promotionFilter = {
|
||||||
userId: {"$in": userIds}
|
userId: {"$in": userIds}
|
||||||
};
|
};
|
||||||
if (progressFilter) {
|
if (progressFilter) {
|
||||||
promotionFilter.confirmed = 0;
|
promotionFilter.confirmed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PromotionModel.find(promotionFilter, {}, {sort: {timestamp: 'desc'}})
|
PromotionModel.find(promotionFilter, {}, {sort: {timestamp: 'desc'}})
|
||||||
.populate('userId').populate('proposer', resultSet).exec((err, items) => {
|
.populate('userId').populate('proposer', resultSet).exec((err, items) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items && items.length > 0) {
|
if (items && items.length > 0) {
|
||||||
res.locals.items = items;
|
res.locals.items = items;
|
||||||
} else {
|
} else {
|
||||||
res.locals.items = [];
|
res.locals.items = [];
|
||||||
}
|
}
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
next();
|
next();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkSql, (req, res, next) => {
|
.post(apiAuthenticationMiddleware, checkSql, (req, res, next) => {
|
||||||
const promotion = new PromotionModel(req.body);
|
const promotion = new PromotionModel(req.body);
|
||||||
promotion.confirmed = 0;
|
promotion.confirmed = 0;
|
||||||
promotion.proposer = req.user._id;
|
promotion.proposer = req.user._id;
|
||||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||||
promotion.save((err) => {
|
promotion.save((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
res.status(codes.created);
|
||||||
res.locals.items = promotion;
|
res.locals.items = promotion;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
request.route('/promotion/:id')
|
request.route('/promotion/:id')
|
||||||
.patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
||||||
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
||||||
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
next(err);
|
next(err);
|
||||||
return; // prevent node to process this function further after next() has finished.
|
return; // prevent node to process this function further after next() has finished.
|
||||||
}
|
}
|
||||||
|
|
||||||
req.body.updatedAt = new Date();
|
req.body.updatedAt = new Date();
|
||||||
req.body.$inc = {__v: 1};
|
req.body.$inc = {__v: 1};
|
||||||
|
|
||||||
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing.
|
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to
|
||||||
PromotionModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
// reset attributes that are missing.
|
||||||
if (err) {
|
PromotionModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
||||||
err.status = codes.wrongrequest;
|
if (err) {
|
||||||
}
|
err.status = codes.wrongrequest;
|
||||||
else if (!item) {
|
}
|
||||||
err = new Error("item not found");
|
else if (!item) {
|
||||||
err.status = codes.notfound;
|
err = new Error("item not found");
|
||||||
}
|
err.status = codes.notfound;
|
||||||
else {
|
}
|
||||||
if (item.confirmed === 1) {
|
else {
|
||||||
let updateUser = {
|
if (item.confirmed === 1) {
|
||||||
_id: item.userId,
|
let updateUser = {
|
||||||
rankLvl: item.newRankLvl
|
_id: item.userId,
|
||||||
};
|
rankLvl: item.newRankLvl
|
||||||
UserModel.findByIdAndUpdate(updateUser._id, updateUser, {new: true}, (err, item) => {
|
};
|
||||||
if (err) {
|
UserModel.findByIdAndUpdate(updateUser._id, updateUser, {new: true}, (err, item) => {
|
||||||
err.status = codes.wrongrequest;
|
if (err) {
|
||||||
}
|
err.status = codes.wrongrequest;
|
||||||
else if (!item) {
|
}
|
||||||
err = new Error("user not found");
|
else if (!item) {
|
||||||
err.status = codes.notfound;
|
err = new Error("user not found");
|
||||||
}
|
err.status = codes.notfound;
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
res.locals.items = item;
|
}
|
||||||
}
|
res.locals.items = item;
|
||||||
next(err);
|
}
|
||||||
})
|
next(err);
|
||||||
})
|
})
|
||||||
.all(
|
})
|
||||||
routerHandling.httpMethodNotAllowed
|
.all(
|
||||||
);
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// 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
|
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||||
|
|
|
@ -16,38 +16,38 @@ const signatures = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
signatures.route('/:id')
|
signatures.route('/:id')
|
||||||
// does not use idValidator since it works by username
|
// does not use idValidator since it works by username
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
// decode UTF8-escape sequences (special characters)
|
// decode UTF8-escape sequences (special characters)
|
||||||
const uri = decodeURIComponent(req.params.id);
|
const uri = decodeURIComponent(req.params.id);
|
||||||
UserModel.findOne({username: uri}, (err, user) => {
|
UserModel.findOne({username: uri}, (err, user) => {
|
||||||
|
|
||||||
const emptyFile = 'resource/signature/0.png';
|
const emptyFile = 'resource/signature/0.png';
|
||||||
if (user === null) {
|
if (user === null) {
|
||||||
res.sendFile(emptyFile, {root: __dirname + '/../'});
|
res.sendFile(emptyFile, {root: __dirname + '/../'});
|
||||||
} else {
|
} else {
|
||||||
const file = 'resource/signature/' + user._id + '.png';
|
const file = 'resource/signature/' + user._id + '.png';
|
||||||
|
|
||||||
fs.stat(__dirname + '/../' + file, (err, stat) => {
|
fs.stat(__dirname + '/../' + file, (err, stat) => {
|
||||||
if (err === null) {
|
if (err === null) {
|
||||||
res.sendFile(file, {root: __dirname + '/../'});
|
res.sendFile(file, {root: __dirname + '/../'});
|
||||||
} else if (err.code === 'ENOENT') {
|
} else if (err.code === 'ENOENT') {
|
||||||
res.sendFile(emptyFile, {root: __dirname + '/../'});
|
res.sendFile(emptyFile, {root: __dirname + '/../'});
|
||||||
} else {
|
} else {
|
||||||
err = new Error("Internal server error");
|
err = new Error("Internal server error");
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// this middleware function can be used, if you like or remove it
|
||||||
|
|
|
@ -24,138 +24,140 @@ const squads = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
squads.route('/')
|
squads.route('/')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
if (req.query.fractFilter) {
|
if (req.query.fractFilter) {
|
||||||
filter.fraction = req.query.fractFilter.toUpperCase()
|
filter.fraction = req.query.fractFilter.toUpperCase()
|
||||||
}
|
|
||||||
if (req.query.q) {
|
|
||||||
filter.name = {$regex: req.query.q, $options: 'i'}
|
|
||||||
}
|
|
||||||
SquadModel.find(filter, {}, {sort: {fraction: 'asc', sortingNumber: 'asc'}}, (err, items) => {
|
|
||||||
if (err) {
|
|
||||||
err.status = codes.servererror;
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
if (items) {
|
|
||||||
res.locals.items = items;
|
|
||||||
} else {
|
|
||||||
res.locals.items = [];
|
|
||||||
}
|
|
||||||
res.locals.processed = true;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
|
||||||
const squad = new SquadModel(req.body);
|
|
||||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
|
||||||
if (req.file) {
|
|
||||||
squad.save((err) => {
|
|
||||||
if (err) {
|
|
||||||
err.status = codes.wrongrequest;
|
|
||||||
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
|
||||||
return next(err);
|
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
if (req.query.q) {
|
||||||
res.locals.items = squad;
|
filter.name = {$regex: req.query.q, $options: 'i'}
|
||||||
fs.appendFile(__dirname + '/../resource/squad/' + squad.id + '.png', new Buffer(req.file.buffer), (err) => {
|
}
|
||||||
if (err) next(err);
|
SquadModel.find(filter, {}, {sort: {fraction: 'asc', sortingNumber: 'asc'}}, (err, items) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.servererror;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (items) {
|
||||||
|
res.locals.items = items;
|
||||||
|
} else {
|
||||||
|
res.locals.items = [];
|
||||||
|
}
|
||||||
|
res.locals.processed = true;
|
||||||
|
next();
|
||||||
});
|
});
|
||||||
next();
|
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
const err = new Error('no image file provided');
|
|
||||||
err.status = codes.wrongmediasend;
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
.all(
|
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
||||||
routerHandling.httpMethodNotAllowed
|
const squad = new SquadModel(req.body);
|
||||||
);
|
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||||
|
if (req.file) {
|
||||||
|
squad.save((err) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.wrongrequest;
|
||||||
|
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.status(codes.created);
|
||||||
|
res.locals.items = squad;
|
||||||
|
fs.appendFile(__dirname + '/../resource/squad/' + squad.id + '.png', new Buffer(req.file.buffer), (err) => {
|
||||||
|
if (err) next(err);
|
||||||
|
});
|
||||||
|
next();
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const err = new Error('no image file provided');
|
||||||
|
err.status = codes.wrongmediasend;
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
.all(
|
||||||
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
squads.route('/:id')
|
squads.route('/:id')
|
||||||
.get(idValidator, (req, res, next) => {
|
.get(idValidator, (req, res, next) => {
|
||||||
SquadModel.findById(req.params.id, (err, item) => {
|
SquadModel.findById(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.locals.items = item;
|
res.locals.items = item;
|
||||||
next();
|
next();
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
|
||||||
|
|
||||||
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
|
||||||
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
|
||||||
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
|
||||||
err.status = codes.notfound;
|
|
||||||
next(err);
|
|
||||||
return; // prevent node to process this function further after next() has finished.
|
|
||||||
}
|
|
||||||
|
|
||||||
// increment version manually as we do not use .save(.)
|
|
||||||
req.body.updatedAt = new Date();
|
|
||||||
req.body.$inc = {__v: 1};
|
|
||||||
|
|
||||||
if (req.file) {
|
|
||||||
const file = __dirname + '/../resource/squad/' + req.body._id + '.png';
|
|
||||||
fs.unlink(file, (err) => {
|
|
||||||
if (err) next(err);
|
|
||||||
fs.appendFile(file, new Buffer(req.file.buffer), (err) => {
|
|
||||||
if (err) next(err);
|
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
}
|
|
||||||
|
|
||||||
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing.
|
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
|
||||||
SquadModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
|
||||||
if (err) {
|
|
||||||
err.status = codes.wrongrequest;
|
|
||||||
}
|
|
||||||
else if (!item) {
|
|
||||||
err = new Error("item not found");
|
|
||||||
err.status = codes.notfound;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res.locals.items = item;
|
|
||||||
}
|
|
||||||
next(err);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
||||||
SquadModel.findByIdAndRemove(req.params.id, (err, item) => {
|
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
||||||
if (err) {
|
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.notfound;
|
||||||
}
|
next(err);
|
||||||
else if (!item) {
|
return; // prevent node to process this function further after next() has finished.
|
||||||
err = new Error("item not found");
|
}
|
||||||
err.status = codes.notfound;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete graphic
|
// increment version manually as we do not use .save(.)
|
||||||
fs.unlink(__dirname + '/../resource/squad/' + req.params.id + '.png', (err) => {
|
req.body.updatedAt = new Date();
|
||||||
if (err) next(err);
|
req.body.$inc = {__v: 1};
|
||||||
});
|
|
||||||
|
|
||||||
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler user.use(..)
|
if (req.file) {
|
||||||
res.locals.processed = true;
|
const file = __dirname + '/../resource/squad/' + req.body._id + '.png';
|
||||||
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
fs.unlink(file, (err) => {
|
||||||
});
|
if (err) next(err);
|
||||||
})
|
fs.appendFile(file, new Buffer(req.file.buffer), (err) => {
|
||||||
|
if (err) next(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
.all(
|
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to
|
||||||
routerHandling.httpMethodNotAllowed
|
// reset attributes that are missing.
|
||||||
);
|
SquadModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.wrongrequest;
|
||||||
|
}
|
||||||
|
else if (!item) {
|
||||||
|
err = new Error("item not found");
|
||||||
|
err.status = codes.notfound;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res.locals.items = item;
|
||||||
|
}
|
||||||
|
next(err);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
|
SquadModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.wrongrequest;
|
||||||
|
}
|
||||||
|
else if (!item) {
|
||||||
|
err = new Error("item not found");
|
||||||
|
err.status = codes.notfound;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete graphic
|
||||||
|
fs.unlink(__dirname + '/../resource/squad/' + req.params.id + '.png', (err) => {
|
||||||
|
if (err) next(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(err); // this works because err is in normal case undefined and that is the same as no parameter
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.all(
|
||||||
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// 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
|
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||||
|
|
|
@ -28,212 +28,215 @@ users.get('/', offsetlimitMiddleware);
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
users.route('/')
|
users.route('/')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
const userQuery = () => {
|
const userQuery = () => {
|
||||||
UserModel.find(dbFilter, res.locals.filter, res.locals.limitskip)
|
UserModel.find(dbFilter, res.locals.filter, res.locals.limitskip)
|
||||||
.populate('squadId')
|
.populate('squadId')
|
||||||
.collation({locale: "en", strength: 2}) // case insensitive order
|
.collation({locale: "en", strength: 2}) // case insensitive order
|
||||||
.sort('username').exec((err, users) => {
|
.sort('username').exec((err, users) => {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
if (users.length === 0) {
|
if (users.length === 0) {
|
||||||
res.locals.items = users;
|
res.locals.items = users;
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
UserModel.count(dbFilter, (err, totalCount) => {
|
UserModel.count(dbFilter, (err, totalCount) => {
|
||||||
res.set('x-total-count', totalCount);
|
res.set('x-total-count', totalCount);
|
||||||
res.locals.items = users;
|
res.locals.items = users;
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
return next();
|
return next();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!req.query.q) req.query.q = '';
|
if (!req.query.q) req.query.q = '';
|
||||||
const dbFilter = {username: {"$regex": req.query.q, "$options": "i"}};
|
const dbFilter = {username: {"$regex": req.query.q, "$options": "i"}};
|
||||||
if (req.query.squadId) dbFilter["squadId"] = {"$eq": req.query.squadId};
|
if (req.query.squadId) dbFilter["squadId"] = {"$eq": req.query.squadId};
|
||||||
// squad / fraction filter setup
|
// squad / fraction filter setup
|
||||||
if (req.query.fractFilter && req.query.fractFilter !== 'UNASSIGNED' && !req.query.squadId) {
|
if (req.query.fractFilter && req.query.fractFilter !== 'UNASSIGNED' && !req.query.squadId) {
|
||||||
SquadModel.find({'fraction': req.query.fractFilter}, {_id: 1}, (err, squads) => {
|
SquadModel.find({'fraction': req.query.fractFilter}, {_id: 1}, (err, squads) => {
|
||||||
dbFilter['squadId'] = {$in: squads.map(squad => squad.id)};
|
dbFilter['squadId'] = {$in: squads.map(squad => squad.id)};
|
||||||
userQuery();
|
userQuery();
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (req.query.fractFilter === 'UNASSIGNED') {
|
if (req.query.fractFilter === 'UNASSIGNED') {
|
||||||
dbFilter['squadId'] = {$eq: null};
|
dbFilter['squadId'] = {$eq: null};
|
||||||
}
|
}
|
||||||
userQuery();
|
userQuery();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.post(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
const user = new UserModel(req.body);
|
const user = new UserModel(req.body);
|
||||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||||
user.save((err) => {
|
user.save((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
res.status(codes.created);
|
||||||
|
|
||||||
UserModel.populate(user, {path: 'squadId'}, (err, extUser) => {
|
UserModel.populate(user, {path: 'squadId'}, (err, extUser) => {
|
||||||
res.locals.items = extUser;
|
res.locals.items = extUser;
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
return next();
|
return next();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(routerHandling.httpMethodNotAllowed);
|
.all(routerHandling.httpMethodNotAllowed);
|
||||||
|
|
||||||
|
|
||||||
users.route('/:id')
|
users.route('/:id')
|
||||||
.get(idValidator, (req, res, next) => {
|
.get(idValidator, (req, res, next) => {
|
||||||
UserModel.findById(req.params.id).populate('squadId').exec((err, user) => {
|
UserModel.findById(req.params.id).populate('squadId').exec((err, user) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.servererror;
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
else if (!user) {
|
else if (!user) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.locals.items = user;
|
res.locals.items = user;
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
return next();
|
return next();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
||||||
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
||||||
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
next(err);
|
next(err);
|
||||||
return; // prevent node to process this function further after next() has finished.
|
return; // prevent node to process this function further after next() has finished.
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional task 3: increment version manually as we do not use .save(.)
|
// optional task 3: increment version manually as we do not use .save(.)
|
||||||
req.body.updatedAt = new Date();
|
req.body.updatedAt = new Date();
|
||||||
req.body.$inc = {__v: 1};
|
req.body.$inc = {__v: 1};
|
||||||
|
|
||||||
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing.
|
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to
|
||||||
UserModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
// reset attributes that are missing.
|
||||||
if (err) {
|
UserModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => {
|
||||||
err.status = codes.wrongrequest;
|
if (err) {
|
||||||
}
|
err.status = codes.wrongrequest;
|
||||||
else if (!item) {
|
}
|
||||||
err = new Error("item not found");
|
else if (!item) {
|
||||||
err.status = codes.notfound;
|
err = new Error("item not found");
|
||||||
}
|
err.status = codes.notfound;
|
||||||
UserModel.populate(item, {path: 'squadId'}, (err, extUser) => {
|
}
|
||||||
if (err) {
|
UserModel.populate(item, {path: 'squadId'}, (err, extUser) => {
|
||||||
err.status = codes.servererror;
|
if (err) {
|
||||||
return next(err);
|
err.status = codes.servererror;
|
||||||
}
|
return next(err);
|
||||||
if (!user) {
|
}
|
||||||
res.locals.items = {};
|
if (!user) {
|
||||||
res.locals.processed = true;
|
res.locals.items = {};
|
||||||
return next();
|
res.locals.processed = true;
|
||||||
}
|
return next();
|
||||||
res.locals.items = extUser;
|
}
|
||||||
res.locals.processed = true;
|
res.locals.items = extUser;
|
||||||
return next();
|
res.locals.processed = true;
|
||||||
})
|
return next();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
.put(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.put(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
// first check that the given element id is the same as the URL id
|
// first check that the given element id is the same as the URL id
|
||||||
if (!req.body || req.body._id !== req.params.id) {
|
if (!req.body || req.body._id !== req.params.id) {
|
||||||
// the URL does not fit the given element
|
// the URL does not fit the given element
|
||||||
var err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
var err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
next(err);
|
next(err);
|
||||||
return; // prevent node to process this function further after next() has finished.
|
return; // prevent node to process this function further after next() has finished.
|
||||||
}
|
}
|
||||||
// main difference of PUT and PATCH is that PUT expects all data in request: checked by using the schema
|
// main difference of PUT and PATCH is that PUT expects all data in request: checked by using the schema
|
||||||
const user = new UserModel(req.body);
|
const user = new UserModel(req.body);
|
||||||
UserModel.findById(req.params.id, req.body, {new: true}, function (err, item) {
|
UserModel.findById(req.params.id, req.body, {new: true}, function (err, item) {
|
||||||
// with parameter {new: true} the TweetNModel will return the new and changed object from the DB and not the old one.
|
// with parameter {new: true} the TweetNModel will return the new and changed object from the DB and not the
|
||||||
if (err) {
|
// old one.
|
||||||
err.status = codes.wrongrequest;
|
if (err) {
|
||||||
return next(err);
|
err.status = codes.wrongrequest;
|
||||||
}
|
return next(err);
|
||||||
else if (!item) {
|
}
|
||||||
err = new Error("item not found");
|
else if (!item) {
|
||||||
err.status = codes.notfound;
|
err = new Error("item not found");
|
||||||
return next(err);
|
err.status = codes.notfound;
|
||||||
}
|
return next(err);
|
||||||
// check that version is still accurate
|
}
|
||||||
else if (user.__v !== item.__v) {
|
// check that version is still accurate
|
||||||
err = new Error("version outdated. Meanwhile update on item happened. Please GET resource again")
|
else if (user.__v !== item.__v) {
|
||||||
err.status = codes.conflict;
|
err = new Error("version outdated. Meanwhile update on item happened. Please GET resource again")
|
||||||
return next(err);
|
err.status = codes.conflict;
|
||||||
}
|
return next(err);
|
||||||
// now update all fields in DB item with body data in variable video
|
}
|
||||||
for (var field in UserModel.schema.paths) {
|
// now update all fields in DB item with body data in variable video
|
||||||
if ((field !== '_id') && (field !== '__v')) {
|
for (var field in UserModel.schema.paths) {
|
||||||
// this includes undefined. is important to reset attributes that are missing in req.body
|
if ((field !== '_id') && (field !== '__v')) {
|
||||||
item.set(field, user[field]);
|
// this includes undefined. is important to reset attributes that are missing in req.body
|
||||||
}
|
item.set(field, user[field]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update updatedAt and increase version
|
// update updatedAt and increase version
|
||||||
item.updatedAt = new Date();
|
item.updatedAt = new Date();
|
||||||
item.increment(); // this sets __v++
|
item.increment(); // this sets __v++
|
||||||
item.save(function (err) {
|
item.save(function (err) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
res.locals.items = item;
|
res.locals.items = item;
|
||||||
} else {
|
} else {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel.populate(item, {path: 'squadId'}, (err, extUser) => {
|
UserModel.populate(item, {path: 'squadId'}, (err, extUser) => {
|
||||||
res.locals.items = extUser;
|
res.locals.items = extUser;
|
||||||
res.locals.processed = true;
|
res.locals.processed = true;
|
||||||
return next();
|
return next();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||||
UserModel.findByIdAndRemove(req.params.id, (err, item) => {
|
UserModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
err.status = codes.wrongrequest;
|
err.status = codes.wrongrequest;
|
||||||
}
|
}
|
||||||
else if (!item) {
|
else if (!item) {
|
||||||
err = new Error("item not found");
|
err = new Error("item not found");
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleted all awardings linked to this user
|
// deleted all awardings linked to this user
|
||||||
AwardingModel.find({userId: req.params.id}).remove().exec();
|
AwardingModel.find({userId: req.params.id}).remove().exec();
|
||||||
|
|
||||||
// check if signature exists and delete compressed and uncompressed file
|
// check if signature exists and delete compressed and uncompressed file
|
||||||
const fileMinified = __dirname + '/../resource/signature/' + req.params.id + '.png';
|
const fileMinified = __dirname + '/../resource/signature/' + req.params.id + '.png';
|
||||||
if (fs.existsSync(fileMinified)) {
|
if (fs.existsSync(fileMinified)) {
|
||||||
fs.unlink(fileMinified, (err) => {
|
fs.unlink(fileMinified, (err) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const file = __dirname + '/../resource/signature/big/' + req.params.id + '.png';
|
const file = __dirname + '/../resource/signature/big/' + req.params.id + '.png';
|
||||||
if (fs.existsSync(file)) {
|
if (fs.existsSync(file)) {
|
||||||
fs.unlink(file, (err) => {
|
fs.unlink(file, (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(..)
|
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler
|
||||||
res.locals.processed = true;
|
// user.use(..)
|
||||||
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
res.locals.processed = true;
|
||||||
});
|
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
||||||
})
|
});
|
||||||
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// this middleware function can be used, if you like or remove it
|
||||||
|
|
|
@ -27,6 +27,7 @@ const CampaignModel = require('../models/campaign');
|
||||||
const WarModel = require('../models/war');
|
const WarModel = require('../models/war');
|
||||||
const PlayerModel = require('../models/player');
|
const PlayerModel = require('../models/player');
|
||||||
const LogKillModel = require('../models/logs/kill');
|
const LogKillModel = require('../models/logs/kill');
|
||||||
|
const LogVehicleKillModel = require('../models/logs/vehicle');
|
||||||
const LogRespawnModel = require('../models/logs/respawn');
|
const LogRespawnModel = require('../models/logs/respawn');
|
||||||
const LogReviveModel = require('../models/logs/revive');
|
const LogReviveModel = require('../models/logs/revive');
|
||||||
const LogTransportModel = require('../models/logs/transport');
|
const LogTransportModel = require('../models/logs/transport');
|
||||||
|
@ -38,87 +39,91 @@ const wars = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
wars.route('/')
|
wars.route('/')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
let result = [];
|
let result = [];
|
||||||
CampaignModel.find({}, {}, {sort: {timestamp: 'desc'}}, (err, campaigns) => {
|
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) => {
|
|
||||||
const body = req.body;
|
|
||||||
const warBody = new WarModel(body);
|
|
||||||
|
|
||||||
if (req.file) {
|
|
||||||
fs.readFile(req.file.buffer, (file, err) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
err.status = codes.servererror;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
const lineArray = file.toString().split("\n");
|
if (campaigns) {
|
||||||
const statsResult = parseWarLog(lineArray, warBody);
|
WarModel.find({}, {}, {sort: {date: 'desc'}}, (err, wars) => {
|
||||||
statsResult.war.save((err, war) => {
|
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) => {
|
||||||
|
const body = req.body;
|
||||||
|
const warBody = new WarModel(body);
|
||||||
|
|
||||||
|
if (req.file) {
|
||||||
|
fs.readFile(req.file.buffer, (file, err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
PlayerModel.create(statsResult.players, function (err) {
|
const lineArray = file.toString().split("\n");
|
||||||
|
const statsResult = parseWarLog(lineArray, warBody);
|
||||||
|
statsResult.war.save((err, war) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
LogKillModel.create(statsResult.kills, function () {
|
PlayerModel.create(statsResult.players, function (err) {
|
||||||
LogRespawnModel.create(statsResult.respawn, function () {
|
if (err) {
|
||||||
LogReviveModel.create(statsResult.revive, function () {
|
return next(err);
|
||||||
LogFlagModel.create(statsResult.flag, function () {
|
}
|
||||||
LogBudgetModel.create(statsResult.budget, function () {
|
LogKillModel.create(statsResult.kills, function () {
|
||||||
LogTransportModel.create(statsResult.transport, function () {
|
LogVehicleKillModel.create(statsResult.vehicles, function () {
|
||||||
LogPointsModel.create(statsResult.points, function () {
|
|
||||||
const folderName = __dirname + '/../resource/logs/' + war._id;
|
|
||||||
mkdirp(folderName, function (err) {
|
|
||||||
if (err) return next(err);
|
|
||||||
|
|
||||||
// save clean log file
|
LogRespawnModel.create(statsResult.respawn, function () {
|
||||||
const cleanFile = fs.createWriteStream(folderName + '/clean.log');
|
LogReviveModel.create(statsResult.revive, function () {
|
||||||
statsResult.clean.forEach(cleanLine => {
|
LogFlagModel.create(statsResult.flag, function () {
|
||||||
cleanFile.write(cleanLine + '\n\n')
|
LogBudgetModel.create(statsResult.budget, function () {
|
||||||
});
|
LogTransportModel.create(statsResult.transport, function () {
|
||||||
cleanFile.end();
|
LogPointsModel.create(statsResult.points, function () {
|
||||||
|
const folderName = __dirname + '/../resource/logs/' + war._id;
|
||||||
|
mkdirp(folderName, function (err) {
|
||||||
|
if (err) return next(err);
|
||||||
|
|
||||||
// save raw log file
|
// save clean log file
|
||||||
const rawFile = fs.createWriteStream(folderName + '/war.log');
|
const cleanFile = fs.createWriteStream(folderName + '/clean.log');
|
||||||
lineArray.forEach(rawLine => {
|
statsResult.clean.forEach(cleanLine => {
|
||||||
rawFile.write(rawLine + '\n')
|
cleanFile.write(cleanLine + '\n\n')
|
||||||
});
|
});
|
||||||
rawFile.end();
|
cleanFile.end();
|
||||||
|
|
||||||
res.status(codes.created);
|
// save raw log file
|
||||||
res.locals.items = war;
|
const rawFile = fs.createWriteStream(folderName + '/war.log');
|
||||||
next();
|
lineArray.forEach(rawLine => {
|
||||||
|
rawFile.write(rawLine + '\n')
|
||||||
|
});
|
||||||
|
rawFile.end();
|
||||||
|
|
||||||
|
res.status(codes.created);
|
||||||
|
res.locals.items = war;
|
||||||
|
next();
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -128,95 +133,95 @@ wars.route('/')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
});
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const err = new Error('no Logfile provided');
|
const err = new Error('no Logfile provided');
|
||||||
err.status = codes.wrongmediasend;
|
err.status = codes.wrongmediasend;
|
||||||
next(err);
|
next(err);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
wars.route('/:id')
|
wars.route('/:id')
|
||||||
.get(idValidator, (req, res, next) => {
|
.get(idValidator, (req, res, next) => {
|
||||||
WarModel.findById(req.params.id, (err, item) => {
|
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}, {}, {sort: {kill: 'desc'}}, (err, items) => {
|
|
||||||
if (err) {
|
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}, {}, {sort: {kill: 'desc'}}, (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);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
const responseObj = item.toObject();
|
// delete linked appearances
|
||||||
responseObj.players = items;
|
PlayerModel.find({warId: item._id}).remove().exec();
|
||||||
res.locals.items = responseObj;
|
LogKillModel.find({war: item._id}).remove().exec();
|
||||||
return next();
|
LogRespawnModel.find({war: item._id}).remove().exec();
|
||||||
});
|
LogReviveModel.find({war: item._id}).remove().exec();
|
||||||
|
LogFlagModel.find({war: item._id}).remove().exec();
|
||||||
|
LogBudgetModel.find({war: item._id}).remove().exec();
|
||||||
|
LogTransportModel.find({war: item._id}).remove().exec();
|
||||||
|
LogPointsModel.find({war: item._id}).remove().exec();
|
||||||
|
|
||||||
});
|
// check if logfiles exist and delete from fs
|
||||||
})
|
const warDir = __dirname + '/../resource/logs/' + req.params.id;
|
||||||
|
|
||||||
.delete(apiAuthenticationMiddleware, checkMT, (req, res, next) => {
|
if (fs.existsSync(warDir)) {
|
||||||
WarModel.findByIdAndRemove(req.params.id, (err, item) => {
|
const cleanLog = warDir + '/clean.log';
|
||||||
if (err) {
|
if (fs.existsSync(cleanLog)) {
|
||||||
err.status = codes.wrongrequest;
|
fs.unlink(cleanLog, (err) => {
|
||||||
return next(err);
|
});
|
||||||
}
|
}
|
||||||
else if (!item) {
|
const sourceLog = warDir + '/war.log';
|
||||||
err = new Error("item not found");
|
if (fs.existsSync(sourceLog)) {
|
||||||
err.status = codes.notfound;
|
fs.unlink(sourceLog, (err) => {
|
||||||
return next(err);
|
});
|
||||||
}
|
}
|
||||||
|
fs.rmdir(warDir, (err) => {
|
||||||
// delete linked appearances
|
|
||||||
PlayerModel.find({warId: item._id}).remove().exec();
|
|
||||||
LogKillModel.find({war: item._id}).remove().exec();
|
|
||||||
LogRespawnModel.find({war: item._id}).remove().exec();
|
|
||||||
LogReviveModel.find({war: item._id}).remove().exec();
|
|
||||||
LogFlagModel.find({war: item._id}).remove().exec();
|
|
||||||
LogBudgetModel.find({war: item._id}).remove().exec();
|
|
||||||
LogTransportModel.find({war: item._id}).remove().exec();
|
|
||||||
LogPointsModel.find({war: 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';
|
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler
|
||||||
if (fs.existsSync(sourceLog)) {
|
// user.use(..)
|
||||||
fs.unlink(sourceLog, (err) => {
|
res.locals.processed = true;
|
||||||
});
|
next();
|
||||||
}
|
|
||||||
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(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
// 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
|
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||||
|
|
|
@ -24,13 +24,13 @@ describe('Awardings', () => {
|
||||||
describe('/GET awardings', () => {
|
describe('/GET awardings', () => {
|
||||||
it('it should GET all awardings', (done) => {
|
it('it should GET all awardings', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.get(urls.awards)
|
.get(urls.awards)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.success);
|
res.should.have.status(codes.success);
|
||||||
res.body.should.be.a('array');
|
res.body.should.be.a('array');
|
||||||
res.body.length.should.be.eql(0);
|
res.body.length.should.be.eql(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,15 +41,15 @@ describe('Awardings', () => {
|
||||||
|
|
||||||
it('it should not POST an awarding without auth-token provided', (done) => {
|
it('it should not POST an awarding without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.post(urls.awards)
|
.post(urls.awards)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -60,15 +60,15 @@ describe('Awardings', () => {
|
||||||
|
|
||||||
it('it should not PATCH an awarding without auth-token provided', (done) => {
|
it('it should not PATCH an awarding without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.patch(urls.awards + '/someId')
|
.patch(urls.awards + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -81,28 +81,28 @@ describe('Awardings', () => {
|
||||||
|
|
||||||
it('it should not accept DELETE method without id in url', (done) => {
|
it('it should not accept DELETE method without id in url', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.awards)
|
.delete(urls.awards)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.wrongmethod);
|
res.should.have.status(codes.wrongmethod);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('error').property('message')
|
res.body.should.have.property('error').property('message')
|
||||||
.eql('this method is not allowed at ' + urls.awards);
|
.eql('this method is not allowed at ' + urls.awards);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should not DELETE an awarding without auth-token provided', (done) => {
|
it('it should not DELETE an awarding without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.awards + '/someId')
|
.delete(urls.awards + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,15 +24,15 @@ describe('Command', () => {
|
||||||
describe('/POST command to create signature', () => {
|
describe('/POST command to create signature', () => {
|
||||||
it('it should not succeed without auth-token provided', (done) => {
|
it('it should not succeed without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.post(urls.cmdCreateSig + "/someId")
|
.post(urls.cmdCreateSig + "/someId")
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,13 @@ describe('Decorations', () => {
|
||||||
describe('/GET decorations', () => {
|
describe('/GET decorations', () => {
|
||||||
it('it should GET all the decorations', (done) => {
|
it('it should GET all the decorations', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.get(urls.decorations)
|
.get(urls.decorations)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.success);
|
res.should.have.status(codes.success);
|
||||||
res.body.should.be.a('array');
|
res.body.should.be.a('array');
|
||||||
res.body.length.should.be.eql(0);
|
res.body.length.should.be.eql(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,15 +41,15 @@ describe('Decorations', () => {
|
||||||
|
|
||||||
it('it should not POST a decoration without auth-token provided', (done) => {
|
it('it should not POST a decoration without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.post(urls.decorations)
|
.post(urls.decorations)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -60,15 +60,15 @@ describe('Decorations', () => {
|
||||||
|
|
||||||
it('it should not PATCH a decoration without auth-token provided', (done) => {
|
it('it should not PATCH a decoration without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.patch(urls.decorations + '/someId')
|
.patch(urls.decorations + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -80,28 +80,28 @@ describe('Decorations', () => {
|
||||||
describe('/DELETE decorations', () => {
|
describe('/DELETE decorations', () => {
|
||||||
it('it should not accept DELETE method without id in url', (done) => {
|
it('it should not accept DELETE method without id in url', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.decorations)
|
.delete(urls.decorations)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.wrongmethod);
|
res.should.have.status(codes.wrongmethod);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('error').property('message')
|
res.body.should.have.property('error').property('message')
|
||||||
.eql('this method is not allowed at ' + urls.decorations);
|
.eql('this method is not allowed at ' + urls.decorations);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should not DELETE a decoration without auth-token provided', (done) => {
|
it('it should not DELETE a decoration without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.decorations + '/someId')
|
.delete(urls.decorations + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,13 +24,13 @@ describe('Ranks', () => {
|
||||||
describe('/GET ranks', () => {
|
describe('/GET ranks', () => {
|
||||||
it('it should GET all the ranks', (done) => {
|
it('it should GET all the ranks', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.get(urls.ranks)
|
.get(urls.ranks)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.success);
|
res.should.have.status(codes.success);
|
||||||
res.body.should.be.a('array');
|
res.body.should.be.a('array');
|
||||||
res.body.length.should.be.eql(0);
|
res.body.length.should.be.eql(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,15 +41,15 @@ describe('Ranks', () => {
|
||||||
|
|
||||||
it('it should not POST a rank without auth-token provided', (done) => {
|
it('it should not POST a rank without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.post(urls.ranks)
|
.post(urls.ranks)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -60,15 +60,15 @@ describe('Ranks', () => {
|
||||||
|
|
||||||
it('it should not PATCH a rank without auth-token provided', (done) => {
|
it('it should not PATCH a rank without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.patch(urls.ranks + '/someId')
|
.patch(urls.ranks + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -80,29 +80,29 @@ describe('Ranks', () => {
|
||||||
describe('/DELETE ranks', () => {
|
describe('/DELETE ranks', () => {
|
||||||
it('it should not accept DELETE method without id in url', (done) => {
|
it('it should not accept DELETE method without id in url', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.ranks)
|
.delete(urls.ranks)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.wrongmethod);
|
res.should.have.status(codes.wrongmethod);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('error').property('message')
|
res.body.should.have.property('error').property('message')
|
||||||
.eql('this method is not allowed at ' + urls.ranks);
|
.eql('this method is not allowed at ' + urls.ranks);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('it should not DELETE a rank without auth-token provided', (done) => {
|
it('it should not DELETE a rank without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.ranks + '/someId')
|
.delete(urls.ranks + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,13 +24,13 @@ describe('Squads', () => {
|
||||||
describe('/GET squads', () => {
|
describe('/GET squads', () => {
|
||||||
it('it should GET all the squads', (done) => {
|
it('it should GET all the squads', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.get(urls.squads)
|
.get(urls.squads)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.success);
|
res.should.have.status(codes.success);
|
||||||
res.body.should.be.a('array');
|
res.body.should.be.a('array');
|
||||||
res.body.length.should.be.eql(0);
|
res.body.length.should.be.eql(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,15 +41,15 @@ describe('Squads', () => {
|
||||||
|
|
||||||
it('it should not POST a squad without auth-token provided', (done) => {
|
it('it should not POST a squad without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.post(urls.squads)
|
.post(urls.squads)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -60,15 +60,15 @@ describe('Squads', () => {
|
||||||
|
|
||||||
it('it should not PATCH a squad without auth-token provided', (done) => {
|
it('it should not PATCH a squad without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.patch(urls.squads + '/someId')
|
.patch(urls.squads + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -80,28 +80,28 @@ describe('Squads', () => {
|
||||||
describe('/DELETE squads', () => {
|
describe('/DELETE squads', () => {
|
||||||
it('it should not accept DELETE method without id in url', (done) => {
|
it('it should not accept DELETE method without id in url', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.squads)
|
.delete(urls.squads)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.wrongmethod);
|
res.should.have.status(codes.wrongmethod);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('error').property('message')
|
res.body.should.have.property('error').property('message')
|
||||||
.eql('this method is not allowed at ' + urls.squads);
|
.eql('this method is not allowed at ' + urls.squads);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should not DELETE a squad without auth-token provided', (done) => {
|
it('it should not DELETE a squad without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.squads + '/someId')
|
.delete(urls.squads + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,13 +25,13 @@ describe('Users', () => {
|
||||||
describe('/GET users', () => {
|
describe('/GET users', () => {
|
||||||
it('it should GET all the users', (done) => {
|
it('it should GET all the users', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.get(urls.users)
|
.get(urls.users)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.success);
|
res.should.have.status(codes.success);
|
||||||
res.body.should.be.a('array');
|
res.body.should.be.a('array');
|
||||||
res.body.length.should.be.eql(0);
|
res.body.length.should.be.eql(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -73,15 +73,15 @@ describe('Users', () => {
|
||||||
|
|
||||||
it('it should not POST a user without auth-token provided', (done) => {
|
it('it should not POST a user without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.post(urls.users)
|
.post(urls.users)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('it should POST a user with provided username', (done) => {
|
// it('it should POST a user with provided username', (done) => {
|
||||||
|
@ -109,15 +109,15 @@ describe('Users', () => {
|
||||||
|
|
||||||
it('it should not PATCH a user without auth-token provided', (done) => {
|
it('it should not PATCH a user without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.patch(urls.users + '/someId')
|
.patch(urls.users + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -129,28 +129,28 @@ describe('Users', () => {
|
||||||
describe('/DELETE users', () => {
|
describe('/DELETE users', () => {
|
||||||
it('it should not accept DELETE method without id in url', (done) => {
|
it('it should not accept DELETE method without id in url', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.users)
|
.delete(urls.users)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.wrongmethod);
|
res.should.have.status(codes.wrongmethod);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('error').property('message')
|
res.body.should.have.property('error').property('message')
|
||||||
.eql('this method is not allowed at ' + urls.users);
|
.eql('this method is not allowed at ' + urls.users);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should not DELETE a user without auth-token provided', (done) => {
|
it('it should not DELETE a user without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.users + '/someId')
|
.delete(urls.users + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,13 +20,13 @@ describe('Wars', () => {
|
||||||
describe('/GET wars', () => {
|
describe('/GET wars', () => {
|
||||||
it('it should GET all wars', (done) => {
|
it('it should GET all wars', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.get(urls.wars)
|
.get(urls.wars)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.success);
|
res.should.have.status(codes.success);
|
||||||
res.body.should.be.a('array');
|
res.body.should.be.a('array');
|
||||||
res.body.length.should.be.eql(0);
|
res.body.length.should.be.eql(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,15 +37,15 @@ describe('Wars', () => {
|
||||||
|
|
||||||
it('it should not POST a war without auth-token provided', (done) => {
|
it('it should not POST a war without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.post(urls.wars)
|
.post(urls.wars)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,28 +56,28 @@ describe('Wars', () => {
|
||||||
|
|
||||||
it('it should not accept DELETE method without id in url', (done) => {
|
it('it should not accept DELETE method without id in url', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.wars)
|
.delete(urls.wars)
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.wrongmethod);
|
res.should.have.status(codes.wrongmethod);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('error').property('message')
|
res.body.should.have.property('error').property('message')
|
||||||
.eql('this method is not allowed at ' + urls.wars);
|
.eql('this method is not allowed at ' + urls.wars);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should not DELETE an awarding without auth-token provided', (done) => {
|
it('it should not DELETE an awarding without auth-token provided', (done) => {
|
||||||
chai.request(server)
|
chai.request(server)
|
||||||
.delete(urls.wars + '/someId')
|
.delete(urls.wars + '/someId')
|
||||||
.send({})
|
.send({})
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
res.should.have.status(codes.forbidden);
|
res.should.have.status(codes.forbidden);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('success').eql(false);
|
res.body.should.have.property('success').eql(false);
|
||||||
res.body.should.have.property('message').eql('No token provided.');
|
res.body.should.have.property('message').eql('No token provided.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@ const playerArrayContains = require('./util').playerArrayContains;
|
||||||
const WHITESPACE = ' ';
|
const WHITESPACE = ' ';
|
||||||
|
|
||||||
const parseWarLog = (lineArray, war) => {
|
const parseWarLog = (lineArray, war) => {
|
||||||
|
|
||||||
const NAME_TOO_LONG_ERROR = 'Error: ENAMETOOLONG: name too long, open \'';
|
const NAME_TOO_LONG_ERROR = 'Error: ENAMETOOLONG: name too long, open \'';
|
||||||
|
|
||||||
const stats = {
|
const stats = {
|
||||||
|
@ -13,6 +14,7 @@ const parseWarLog = (lineArray, war) => {
|
||||||
budget: [],
|
budget: [],
|
||||||
points: [],
|
points: [],
|
||||||
kills: [],
|
kills: [],
|
||||||
|
vehicles: [],
|
||||||
respawn: [],
|
respawn: [],
|
||||||
revive: [],
|
revive: [],
|
||||||
flag: [],
|
flag: [],
|
||||||
|
@ -20,10 +22,21 @@ const parseWarLog = (lineArray, war) => {
|
||||||
players: []
|
players: []
|
||||||
};
|
};
|
||||||
|
|
||||||
const addPlayerIfNotExists = (inputPlayer) => {
|
const vehicleBlacklist = [
|
||||||
|
'Prowler (Unbewaffnet)', 'Prowler (Bewaffnet)', 'Hunter',
|
||||||
|
'HEMTT Transporter', 'HEMTT Transporter (abgedeckt)', 'HEMTT SanitÀtsfahrzeug',
|
||||||
|
'Remote Designator [NATO]', 'UGV Stomper',
|
||||||
|
'Qilin (Unbewaffnet)', 'Qilin (Bewaffnet)', 'Ifrit',
|
||||||
|
'Tempest-Transporter', 'Tempest-Transporter (abgedeckt)', 'Tempest SanitÀtsfahrzeug',
|
||||||
|
'Remote Designator [CSAT]', 'UBF Saif',
|
||||||
|
'Quad Bike', 'HuntIR'
|
||||||
|
];
|
||||||
|
|
||||||
|
const addPlayerIfNotExists = (inputPlayer, steamUUID) => {
|
||||||
const player = getPlayerAndFractionFromString(inputPlayer);
|
const player = getPlayerAndFractionFromString(inputPlayer);
|
||||||
if (player && player.name && player.fraction && !playerArrayContains(stats.players, player)) {
|
if (player && player.name && player.fraction && !playerArrayContains(stats.players, player)) {
|
||||||
player['warId'] = war._id;
|
player['warId'] = war._id;
|
||||||
|
player['steamUUID'] = steamUUID;
|
||||||
stats.players.push(player);
|
stats.players.push(player);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -37,23 +50,38 @@ const parseWarLog = (lineArray, war) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KILLS
|
* KILLS & VEHICLE KILLS
|
||||||
*/
|
*/
|
||||||
if (line.includes('(Abschuss)') && !line.includes('Fahrzeug')) {
|
if (line.includes('(Abschuss)')) {
|
||||||
stats.clean.push(line);
|
stats.clean.push(line);
|
||||||
|
|
||||||
const shooterString = line.substring(line.lastIndexOf(' von: ') + 6, line.lastIndexOf('."'));
|
const shooterString = line.substring(line.lastIndexOf(' von: ') + 6, line.lastIndexOf('."'));
|
||||||
const shooter = getPlayerAndFractionFromString(shooterString);
|
const shooter = getPlayerAndFractionFromString(shooterString);
|
||||||
const targetString = line.substring(line.lastIndexOf(' --- ') + 5, line.lastIndexOf(' von:'));
|
|
||||||
const target = getPlayerAndFractionFromString(targetString);
|
|
||||||
|
|
||||||
stats.kills.push({
|
if (line.includes('Fahrzeug:')) {
|
||||||
war: war._id,
|
const targetString = line.substring(line.lastIndexOf(' --- Fahrzeug: ') + 15, line.lastIndexOf(' von:'));
|
||||||
time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]),
|
const target = getVehicleAndFractionFromString(targetString);
|
||||||
shooter: shooter ? shooter.name : null,
|
if (target && shooter && target.fraction !== shooter.fraction) {
|
||||||
target: target ? target.name : null,
|
stats.vehicles.push({
|
||||||
friendlyFire: shooter ? target.fraction === shooter.fraction : false,
|
war: war._id,
|
||||||
fraction: shooter ? shooter.fraction : 'NONE'
|
time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]),
|
||||||
});
|
shooter: shooter ? shooter.name : null,
|
||||||
|
target: target ? target.name : null,
|
||||||
|
fraction: shooter ? shooter.fraction : 'NONE'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const targetString = line.substring(line.lastIndexOf(' --- ') + 5, line.lastIndexOf(' von:'));
|
||||||
|
const target = getPlayerAndFractionFromString(targetString);
|
||||||
|
stats.kills.push({
|
||||||
|
war: war._id,
|
||||||
|
time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]),
|
||||||
|
shooter: shooter ? shooter.name : null,
|
||||||
|
target: target ? target.name : null,
|
||||||
|
friendlyFire: shooter ? target.fraction === shooter.fraction : false,
|
||||||
|
fraction: shooter ? shooter.fraction : 'NONE'
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,7 +199,8 @@ const parseWarLog = (lineArray, war) => {
|
||||||
*/
|
*/
|
||||||
else if (line.includes('(Fraktionsuebersicht)')) {
|
else if (line.includes('(Fraktionsuebersicht)')) {
|
||||||
const playerString = line.substring(line.lastIndexOf('--- ') + 4, line.lastIndexOf(', PUID'));
|
const playerString = line.substring(line.lastIndexOf('--- ') + 4, line.lastIndexOf(', PUID'));
|
||||||
addPlayerIfNotExists(playerString)
|
const playerUUID = line.substring(line.lastIndexOf('PUID ') + 5, line.lastIndexOf('"'));
|
||||||
|
addPlayerIfNotExists(playerString, playerUUID)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -179,6 +208,7 @@ const parseWarLog = (lineArray, war) => {
|
||||||
const playerName = stats.players[i].name;
|
const playerName = stats.players[i].name;
|
||||||
stats.players[i]['respawn'] = stats.respawn.filter(res => res.player === playerName).length;
|
stats.players[i]['respawn'] = stats.respawn.filter(res => res.player === playerName).length;
|
||||||
stats.players[i]['kill'] = stats.kills.filter(kill => kill.shooter === playerName && !kill.friendlyFire).length;
|
stats.players[i]['kill'] = stats.kills.filter(kill => kill.shooter === playerName && !kill.friendlyFire).length;
|
||||||
|
stats.players[i]['vehicle'] = stats.vehicles.filter(vehicle => vehicle.shooter === playerName && vehicleBlacklist.indexOf(vehicle.target) < 0).length;
|
||||||
stats.players[i]['friendlyFire'] = stats.kills.filter(kill => kill.shooter === playerName && kill.friendlyFire).length;
|
stats.players[i]['friendlyFire'] = stats.kills.filter(kill => kill.shooter === playerName && kill.friendlyFire).length;
|
||||||
stats.players[i]['death'] = stats.kills.filter(kill => kill.target === playerName).length;
|
stats.players[i]['death'] = stats.kills.filter(kill => kill.target === playerName).length;
|
||||||
stats.players[i]['revive'] = stats.revive.filter(rev => rev.medic === playerName && !rev.stabilized).length;
|
stats.players[i]['revive'] = stats.revive.filter(rev => rev.medic === playerName && !rev.stabilized).length;
|
||||||
|
@ -231,6 +261,21 @@ const getPlayerAndFractionFromString = (nameAndFractionString) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getVehicleAndFractionFromString = (nameAndFractionString) => {
|
||||||
|
const nameArray = nameAndFractionString.trim().split(WHITESPACE);
|
||||||
|
const fractionPart = nameArray[nameArray.length - 1];
|
||||||
|
|
||||||
|
// escape it is some parachute fraction identifier
|
||||||
|
if (fractionPart === 'OPF_F' || fractionPart === 'BLU_F') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fraction = fractionPart === '(OPT_NATO)' || fractionPart === '(OPT_NATO_T)' ? 'BLUFOR' : 'OPFOR';
|
||||||
|
const name = nameAndFractionString.substring(0, nameAndFractionString.indexOf(fractionPart) - 1);
|
||||||
|
|
||||||
|
return {name: name, fraction: fraction};
|
||||||
|
};
|
||||||
|
|
||||||
const transformMoneyString = (budgetString) => {
|
const transformMoneyString = (budgetString) => {
|
||||||
if (!budgetString.includes('e+')) {
|
if (!budgetString.includes('e+')) {
|
||||||
return parseInt(budgetString);
|
return parseInt(budgetString);
|
||||||
|
|
|
@ -31,79 +31,79 @@ let createSignature = (userId, res, next) => {
|
||||||
return next(error);
|
return next(error);
|
||||||
}
|
}
|
||||||
UserModel.findById(userId, ['username', 'rankLvl', 'squadId'])
|
UserModel.findById(userId, ['username', 'rankLvl', 'squadId'])
|
||||||
.populate('squadId', ['name', 'fraction'])
|
.populate('squadId', ['name', 'fraction'])
|
||||||
.exec()
|
.exec()
|
||||||
.then((resUser) => {
|
.then((resUser) => {
|
||||||
user = resUser;
|
user = resUser;
|
||||||
let platePath;
|
let platePath;
|
||||||
if (resUser && resUser.squadId && resUser.squadId.fraction === 'BLUFOR') {
|
if (resUser && resUser.squadId && resUser.squadId.fraction === 'BLUFOR') {
|
||||||
platePath = __dirname + '/backplate/blufor' + fileExt;
|
platePath = __dirname + '/backplate/blufor' + fileExt;
|
||||||
} else if (resUser && resUser.squadId && resUser.squadId.fraction === 'OPFOR') {
|
} else if (resUser && resUser.squadId && resUser.squadId.fraction === 'OPFOR') {
|
||||||
platePath = __dirname + '/backplate/opfor' + fileExt;
|
platePath = __dirname + '/backplate/opfor' + fileExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// kill process on undefined platePath
|
// kill process on undefined platePath
|
||||||
if (!platePath) {
|
if (!platePath) {
|
||||||
throw new Error('Fraction not defined for user with id ' + userId);
|
throw new Error('Fraction not defined for user with id ' + userId);
|
||||||
}
|
}
|
||||||
return jimp.read(platePath)
|
return jimp.read(platePath)
|
||||||
})
|
})
|
||||||
.then((image) => {
|
.then((image) => {
|
||||||
loadedImage = image;
|
loadedImage = image;
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return jimp.loadFont(__dirname + '/font/DEVAJU_SANS_19.fnt');
|
return jimp.loadFont(__dirname + '/font/DEVAJU_SANS_19.fnt');
|
||||||
})
|
})
|
||||||
.then((font) => {
|
.then((font) => {
|
||||||
loadedImage.print(font, 128, 8, user.username)
|
loadedImage.print(font, 128, 8, user.username)
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return jimp.loadFont(__dirname + '/font/DEJAVU_SANS_13.fnt');
|
return jimp.loadFont(__dirname + '/font/DEJAVU_SANS_13.fnt');
|
||||||
})
|
})
|
||||||
.then((font) => {
|
.then((font) => {
|
||||||
loadedImage.print(font, 128, 35, user.squadId.name);
|
loadedImage.print(font, 128, 35, user.squadId.name);
|
||||||
return font;
|
return font;
|
||||||
})
|
})
|
||||||
.then((font) => {
|
.then((font) => {
|
||||||
let rankH, rankW, rankX, rankY;
|
let rankH, rankW, rankX, rankY;
|
||||||
|
|
||||||
RankModel.findOne({'level': user.rankLvl, 'fraction': user.squadId.fraction}, (err, result) => {
|
RankModel.findOne({'level': user.rankLvl, 'fraction': user.squadId.fraction}, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
if (user.squadId.fraction === 'BLUFOR') {
|
if (user.squadId.fraction === 'BLUFOR') {
|
||||||
rankW = 25;
|
rankW = 25;
|
||||||
rankH = 60;
|
rankH = 60;
|
||||||
rankX = 36;
|
rankX = 36;
|
||||||
rankY = 34;
|
rankY = 34;
|
||||||
} else {
|
} else {
|
||||||
rankW = 37;
|
rankW = 37;
|
||||||
rankH = 58;
|
rankH = 58;
|
||||||
rankX = 30;
|
rankX = 30;
|
||||||
rankY = 34;
|
rankY = 34;
|
||||||
}
|
}
|
||||||
|
|
||||||
jimp.read(resourceDir + 'rank/' + result._id + fileExt)
|
jimp.read(resourceDir + 'rank/' + result._id + fileExt)
|
||||||
.then((rankImage) => {
|
.then((rankImage) => {
|
||||||
rankImage.resize(rankW, rankH);
|
rankImage.resize(rankW, rankH);
|
||||||
loadedImage
|
loadedImage
|
||||||
.print(font, 128, 55, result.name)
|
.print(font, 128, 55, result.name)
|
||||||
.composite(rankImage, rankX, rankY)
|
.composite(rankImage, rankX, rankY)
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
addDecorationsAndSave(userId, loadedImage, res, next);
|
addDecorationsAndSave(userId, loadedImage, res, next);
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// user has not any assignable rank in his fraction at this point,
|
// user has not any assignable rank in his fraction at this point,
|
||||||
// e.g. assigned rank has been deleted or switched fraction so rankLvl is not defined
|
// e.g. assigned rank has been deleted or switched fraction so rankLvl is not defined
|
||||||
addDecorationsAndSave(userId, loadedImage, res, next);
|
addDecorationsAndSave(userId, loadedImage, res, next);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
next(err);
|
next(err);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,110 +130,110 @@ let addDecorationsAndSave = (userId, loadedImage, res, next) => {
|
||||||
'userId': userId,
|
'userId': userId,
|
||||||
'confirmed': 1
|
'confirmed': 1
|
||||||
}, ['decorationId', 'date']).populate('decorationId', ['isMedal', 'fraction'])
|
}, ['decorationId', 'date']).populate('decorationId', ['isMedal', 'fraction'])
|
||||||
.exec((err, awardings) => {
|
.exec((err, awardings) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
if (awardings.length > 0) {
|
if (awardings.length > 0) {
|
||||||
|
|
||||||
//TODO: simplify this sorting hell
|
//TODO: simplify this sorting hell
|
||||||
awardings.sort((a1, a2) => {
|
awardings.sort((a1, a2) => {
|
||||||
if (!a1.decorationId.isMedal && !a2.decorationId.isMedal) {
|
if (!a1.decorationId.isMedal && !a2.decorationId.isMedal) {
|
||||||
if (a1.decorationId.fraction === a2.decorationId.fraction) {
|
if (a1.decorationId.fraction === a2.decorationId.fraction) {
|
||||||
if (a1.date !== a2.date) {
|
if (a1.date !== a2.date) {
|
||||||
if (a1.date < a2.date) {
|
if (a1.date < a2.date) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (a1.date > a2.date) {
|
if (a1.date > a2.date) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if (a1.decorationId.fraction === 'GLOBAL' && a2.decorationId.fraction !== 'GLOBAL') {
|
if (a1.decorationId.fraction === 'GLOBAL' && a2.decorationId.fraction !== 'GLOBAL') {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (a2.decorationId.fraction === 'GLOBAL' && a1.decorationId.fraction !== 'GLOBAL') {
|
if (a2.decorationId.fraction === 'GLOBAL' && a1.decorationId.fraction !== 'GLOBAL') {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (a1.decorationId.isMedal !== a2.decorationId.isMedal) {
|
if (a1.decorationId.isMedal !== a2.decorationId.isMedal) {
|
||||||
if (a1.decorationId.isMedal && !a2.decorationId.isMedal) {
|
if (a1.decorationId.isMedal && !a2.decorationId.isMedal) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!a1.decorationId.isMedal && a2.decorationId.isMedal) {
|
if (!a1.decorationId.isMedal && a2.decorationId.isMedal) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (a1.decorationId.isMedal && a2.decorationId.isMedal) {
|
if (a1.decorationId.isMedal && a2.decorationId.isMedal) {
|
||||||
if (a1.date !== a2.date) {
|
if (a1.date !== a2.date) {
|
||||||
if (a1.date < a2.date) {
|
if (a1.date < a2.date) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (a1.date > a2.date) {
|
if (a1.date > a2.date) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// use synchronized call to keep correct order of decorations
|
// use synchronized call to keep correct order of decorations
|
||||||
async.eachSeries(awardings, (award, callback) => {
|
async.eachSeries(awardings, (award, callback) => {
|
||||||
jimp.read(resourceDir + 'decoration/' + award.decorationId._id + fileExt).then((decorationImage) => {
|
jimp.read(resourceDir + 'decoration/' + award.decorationId._id + fileExt).then((decorationImage) => {
|
||||||
if (award.decorationId.isMedal) {
|
if (award.decorationId.isMedal) {
|
||||||
decorationImage.resize(medalW, medalH);
|
decorationImage.resize(medalW, medalH);
|
||||||
loadedImage.composite(decorationImage, medalPx, medalPy);
|
loadedImage.composite(decorationImage, medalPx, medalPy);
|
||||||
if (medalPy === 5) {
|
if (medalPy === 5) {
|
||||||
medalPx = medalPx - 1 - medalW;
|
medalPx = medalPx - 1 - medalW;
|
||||||
} else {
|
} else {
|
||||||
medalPx = medalPx + 1 + medalW;
|
medalPx = medalPx + 1 + medalW;
|
||||||
}
|
}
|
||||||
if (medalPx <= 300) {
|
if (medalPx <= 300) {
|
||||||
medalPy = medalPy + 3 + medalH;
|
medalPy = medalPy + 3 + medalH;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
decorationImage.resize(ribbonW, ribbonH);
|
decorationImage.resize(ribbonW, ribbonH);
|
||||||
loadedImage.composite(decorationImage, ribbonPx, ribbonPy);
|
loadedImage.composite(decorationImage, ribbonPx, ribbonPy);
|
||||||
ribbonPx = ribbonPx - 2 - ribbonW;
|
ribbonPx = ribbonPx - 2 - ribbonW;
|
||||||
if (ribbonPx <= 154) {
|
if (ribbonPx <= 154) {
|
||||||
ribbonPy = ribbonPy - 3 - ribbonH;
|
ribbonPy = ribbonPy - 3 - ribbonH;
|
||||||
ribbonPx = 598;
|
ribbonPx = 598;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
})
|
})
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
compareImagesAndSave(loadedImage, userId, res, next);
|
compareImagesAndSave(loadedImage, userId, res, next);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
compareImagesAndSave(loadedImage, userId, res, next);
|
compareImagesAndSave(loadedImage, userId, res, next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let compareImagesAndSave = (generatedImage, userId, res, next) => {
|
let compareImagesAndSave = (generatedImage, userId, res, next) => {
|
||||||
|
|
||||||
return jimp.read(resourceDir + 'signature/big/' + userId + fileExt)
|
return jimp.read(resourceDir + 'signature/big/' + userId + fileExt)
|
||||||
.then((oldImage) => {
|
.then((oldImage) => {
|
||||||
// compare hashes of image map to recognize difference
|
// compare hashes of image map to recognize difference
|
||||||
const sig1 = SHA1(generatedImage.bitmap.data);
|
const sig1 = SHA1(generatedImage.bitmap.data);
|
||||||
const sig2 = SHA1(oldImage.bitmap.data);
|
const sig2 = SHA1(oldImage.bitmap.data);
|
||||||
if (sig1 !== sig2) {
|
if (sig1 !== sig2) {
|
||||||
saveJimpImageAndCompress(generatedImage, userId, res, next)
|
saveJimpImageAndCompress(generatedImage, userId, res, next)
|
||||||
} else {
|
} else {
|
||||||
res.locals.items = {status: 'nothing to do'};
|
res.locals.items = {status: 'nothing to do'};
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
saveJimpImageAndCompress(generatedImage, userId, res, next);
|
saveJimpImageAndCompress(generatedImage, userId, res, next);
|
||||||
})
|
})
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const isSteamUUID = (input) => {
|
||||||
|
const steamUIDPattern = new RegExp("[0-9]{17}");
|
||||||
|
return steamUIDPattern.test(input)
|
||||||
|
};
|
||||||
|
|
||||||
const sortCollectionBy = (collection, key) => {
|
const sortCollectionBy = (collection, key) => {
|
||||||
collection.sort((a, b) => {
|
collection.sort((a, b) => {
|
||||||
a = a[key].toLowerCase();
|
a = a[key].toLowerCase();
|
||||||
|
@ -44,6 +49,7 @@ const decimalToTimeString = (decimal) => {
|
||||||
(seconds < 10 ? '0' + seconds : seconds);
|
(seconds < 10 ? '0' + seconds : seconds);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.isSteamUUID = isSteamUUID;
|
||||||
exports.sortCollection = sortCollectionBy;
|
exports.sortCollection = sortCollectionBy;
|
||||||
exports.playerArrayContains = playerArrayContains;
|
exports.playerArrayContains = playerArrayContains;
|
||||||
exports.timeStringToDecimal = timeStringToDecimal;
|
exports.timeStringToDecimal = timeStringToDecimal;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "opt-cc",
|
"name": "opt-cc",
|
||||||
"version": "1.6.12",
|
"version": "1.7.0",
|
||||||
"author": "Florian Hartwich <hardi@noarch.de>",
|
"author": "Florian Hartwich <hardi@noarch.de>",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.overview {
|
.overview {
|
||||||
padding: 80px 0 0 10%!important;
|
padding: 80px 0 0 10% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trash {
|
.trash {
|
||||||
|
|
|
@ -45,19 +45,19 @@ export class AdminComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.appUserService.updateUser(updateObject)
|
this.appUserService.updateUser(updateObject)
|
||||||
.subscribe(user => {
|
.subscribe(user => {
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showSuccessLabel = false;
|
this.showSuccessLabel = false;
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteUser(user) {
|
deleteUser(user) {
|
||||||
if (confirm('Soll der Nutzer "' + user.username + '" wirklich gelöscht werden?')) {
|
if (confirm('Soll der Nutzer "' + user.username + '" wirklich gelöscht werden?')) {
|
||||||
this.appUserService.deleteUser(user)
|
this.appUserService.deleteUser(user)
|
||||||
.subscribe((res) => {
|
.subscribe((res) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ li {
|
||||||
}
|
}
|
||||||
|
|
||||||
.version-label {
|
.version-label {
|
||||||
display:block;
|
display: block;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 32px;
|
top: 32px;
|
||||||
left: 106px;
|
left: 106px;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
.army-member-view-container {
|
.army-member-view-container {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
min-width: 870px;
|
min-width: 870px;
|
||||||
margin:auto
|
margin: auto
|
||||||
}
|
}
|
||||||
|
|
||||||
.return-button {
|
.return-button {
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
<div class="army-member-view-container">
|
<div class="army-member-view-container">
|
||||||
<div class="return-button">
|
<div class="return-button">
|
||||||
<span class="btn btn-default" style="position:absolute;" (click)="backToOverview()">< zurück zur Übersicht</span>
|
<span class="btn btn-default" style="position:absolute;" (click)="backToOverview()">< zurück zur Übersicht</span>
|
||||||
<h3 class="text-center" style="font-weight: 600" [style.color]="user.squadId?.fraction === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
<h3 class="text-center" style="font-weight: 600"
|
||||||
|
[style.color]="user.squadId?.fraction === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
||||||
Auszeichnungen von {{user.username}}
|
Auszeichnungen von {{user.username}}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -41,16 +41,16 @@ export class ArmyMemberComponent {
|
||||||
this.document.getElementById('right').setAttribute('style', CSSHelpers.getBackgroundCSS('../assets/bg.jpg'));
|
this.document.getElementById('right').setAttribute('style', CSSHelpers.getBackgroundCSS('../assets/bg.jpg'));
|
||||||
|
|
||||||
this.subscription = this.route.params
|
this.subscription = this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.filter(id => id != undefined)
|
.filter(id => id != undefined)
|
||||||
.flatMap(id => this.userService.getUser(id))
|
.flatMap(id => this.userService.getUser(id))
|
||||||
.subscribe(user => {
|
.subscribe(user => {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.signatureUrl = window.location.origin + '/resource/signature/' + user._id + '.png';
|
this.signatureUrl = window.location.origin + '/resource/signature/' + user._id + '.png';
|
||||||
this.awardingService.getUserAwardings(user._id).subscribe((awards => {
|
this.awardingService.getUserAwardings(user._id).subscribe((awards => {
|
||||||
this.awards = awards;
|
this.awards = awards;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@ export class ArmyComponent {
|
||||||
|
|
||||||
// init army data
|
// init army data
|
||||||
this.armyService.getArmy()
|
this.armyService.getArmy()
|
||||||
.subscribe(army => {
|
.subscribe(army => {
|
||||||
this.army = army;
|
this.army = army;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<decoration-item *ngFor="let decoration of decorations$ | async"
|
<decoration-item *ngFor="let decoration of decorations$ | async"
|
||||||
[decoration]="decoration"
|
[decoration]="decoration"
|
||||||
(decorationDelete)="deleteDecoration(decoration)"
|
(decorationDelete)="deleteDecoration(decoration)"
|
||||||
(decorationSelected)="selectDecoration($event)"
|
(decorationSelected)="selectDecoration($event)"
|
||||||
[selected]="decoration._id == selectedDecorationId">
|
[selected]="decoration._id == selectedDecorationId">
|
||||||
</decoration-item>
|
</decoration-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -35,17 +35,17 @@ export class DecorationListComponent implements OnInit {
|
||||||
this.decorations$ = this.decorationService.decorations$;
|
this.decorations$ = this.decorationService.decorations$;
|
||||||
|
|
||||||
const paramsStream = this.route.queryParams
|
const paramsStream = this.route.queryParams
|
||||||
.map(params => decodeURI(params['query'] || ''))
|
.map(params => decodeURI(params['query'] || ''))
|
||||||
.do(query => this.searchTerm.setValue(query));
|
.do(query => this.searchTerm.setValue(query));
|
||||||
|
|
||||||
const searchTermStream = this.searchTerm.valueChanges
|
const searchTermStream = this.searchTerm.valueChanges
|
||||||
.debounceTime(400)
|
.debounceTime(400)
|
||||||
.do(query => this.adjustBrowserUrl(query));
|
.do(query => this.adjustBrowserUrl(query));
|
||||||
|
|
||||||
Observable.merge(paramsStream, searchTermStream)
|
Observable.merge(paramsStream, searchTermStream)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.switchMap(query => this.decorationService.findDecorations(query, this.radioModel))
|
.switchMap(query => this.decorationService.findDecorations(query, this.radioModel))
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
openNewDecorationForm() {
|
openNewDecorationForm() {
|
||||||
|
@ -65,8 +65,8 @@ export class DecorationListComponent implements OnInit {
|
||||||
|
|
||||||
if (confirm('Soll die Auszeichnung "' + decoration.name + '" (' + fraction + ') wirklich gelöscht werden?')) {
|
if (confirm('Soll die Auszeichnung "' + decoration.name + '" (' + fraction + ') wirklich gelöscht werden?')) {
|
||||||
this.decorationService.deleteDecoration(decoration)
|
this.decorationService.deleteDecoration(decoration)
|
||||||
.subscribe((res) => {
|
.subscribe((res) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,13 +35,13 @@ export class EditDecorationComponent {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.subscription = this.route.params
|
this.subscription = this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.filter(id => id != undefined)
|
.filter(id => id != undefined)
|
||||||
.flatMap(id => this.decorationService.getDecoration(id))
|
.flatMap(id => this.decorationService.getDecoration(id))
|
||||||
.subscribe(decoration => {
|
.subscribe(decoration => {
|
||||||
this.decoration = decoration;
|
this.decoration = decoration;
|
||||||
this.imagePreviewSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
|
this.imagePreviewSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
@ -64,9 +64,9 @@ export class EditDecorationComponent {
|
||||||
if (this.fileList) {
|
if (this.fileList) {
|
||||||
file = this.fileList[0];
|
file = this.fileList[0];
|
||||||
this.decorationService.submitDecoration(this.decoration, file)
|
this.decorationService.submitDecoration(this.decoration, file)
|
||||||
.subscribe(rank => {
|
.subscribe(rank => {
|
||||||
this.router.navigate(['..'], {relativeTo: this.route});
|
this.router.navigate(['..'], {relativeTo: this.route});
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return window.alert(`Bild ist ein Pflichtfeld`);
|
return window.alert(`Bild ist ein Pflichtfeld`);
|
||||||
}
|
}
|
||||||
|
@ -76,16 +76,16 @@ export class EditDecorationComponent {
|
||||||
}
|
}
|
||||||
delete this.decoration['__v'];
|
delete this.decoration['__v'];
|
||||||
this.decorationService.submitDecoration(this.decoration, file)
|
this.decorationService.submitDecoration(this.decoration, file)
|
||||||
.subscribe(rank => {
|
.subscribe(rank => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.imagePreviewSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
|
this.imagePreviewSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
|
||||||
}, 300);
|
}, 300);
|
||||||
fileInput.value = '';
|
fileInput.value = '';
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showSuccessLabel = false;
|
this.showSuccessLabel = false;
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,18 +35,18 @@ export class LoginComponent implements OnInit {
|
||||||
if (username.length > 0 && password.length > 0) {
|
if (username.length > 0 && password.length > 0) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.loginService.login(username, password)
|
this.loginService.login(username, password)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
data => {
|
data => {
|
||||||
this.router.navigate([this.returnUrl]);
|
this.router.navigate([this.returnUrl]);
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.error = error._body;
|
this.error = error._body;
|
||||||
this.showErrorLabel = true;
|
this.showErrorLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showErrorLabel = false;
|
this.showErrorLabel = false;
|
||||||
}, 4000);
|
}, 4000);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,19 +38,19 @@ export class SignupComponent implements OnInit {
|
||||||
if (username.length > 0 && password.length > 0 && secret.length > 0) {
|
if (username.length > 0 && password.length > 0 && secret.length > 0) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.loginService.signUp(username, password, secret)
|
this.loginService.signUp(username, password, secret)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
data => {
|
data => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.error = error;
|
this.error = error;
|
||||||
this.showErrorLabel = true;
|
this.showErrorLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showErrorLabel = false;
|
this.showErrorLabel = false;
|
||||||
}, 4000);
|
}, 4000);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ export interface Player {
|
||||||
name?: string;
|
name?: string;
|
||||||
warId?: War;
|
warId?: War;
|
||||||
kill?: number;
|
kill?: number;
|
||||||
|
vehicle?: number;
|
||||||
death?: number;
|
death?: number;
|
||||||
friendlyFire?: number;
|
friendlyFire?: number;
|
||||||
revive?: number;
|
revive?: number;
|
||||||
|
|
|
@ -38,13 +38,13 @@ export class EditRankComponent {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.subscription = this.route.params
|
this.subscription = this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.filter(id => id != undefined)
|
.filter(id => id != undefined)
|
||||||
.flatMap(id => this.rankService.getRank(id))
|
.flatMap(id => this.rankService.getRank(id))
|
||||||
.subscribe(rank => {
|
.subscribe(rank => {
|
||||||
this.rank = rank;
|
this.rank = rank;
|
||||||
this.imagePreviewSrc = 'resource/rank/' + this.rank._id + '.png?' + Date.now();
|
this.imagePreviewSrc = 'resource/rank/' + this.rank._id + '.png?' + Date.now();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
@ -67,10 +67,10 @@ export class EditRankComponent {
|
||||||
if (this.fileList) {
|
if (this.fileList) {
|
||||||
file = this.fileList[0];
|
file = this.fileList[0];
|
||||||
this.rankService.submitRank(this.rank, file)
|
this.rankService.submitRank(this.rank, file)
|
||||||
.subscribe(rank => {
|
.subscribe(rank => {
|
||||||
this.saved = true;
|
this.saved = true;
|
||||||
this.router.navigate(['..'], {relativeTo: this.route});
|
this.router.navigate(['..'], {relativeTo: this.route});
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return window.alert(`Bild ist ein Pflichtfeld`);
|
return window.alert(`Bild ist ein Pflichtfeld`);
|
||||||
}
|
}
|
||||||
|
@ -80,16 +80,16 @@ export class EditRankComponent {
|
||||||
}
|
}
|
||||||
delete this.rank['__v'];
|
delete this.rank['__v'];
|
||||||
this.rankService.submitRank(this.rank, file)
|
this.rankService.submitRank(this.rank, file)
|
||||||
.subscribe(rank => {
|
.subscribe(rank => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.imagePreviewSrc = 'resource/rank/' + this.rank._id + '.png?' + Date.now();
|
this.imagePreviewSrc = 'resource/rank/' + this.rank._id + '.png?' + Date.now();
|
||||||
}, 300);
|
}, 300);
|
||||||
fileInput.value = '';
|
fileInput.value = '';
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showSuccessLabel = false;
|
this.showSuccessLabel = false;
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,17 +36,17 @@ export class RankListComponent implements OnInit {
|
||||||
this.ranks$ = this.rankService.ranks$;
|
this.ranks$ = this.rankService.ranks$;
|
||||||
|
|
||||||
const paramsStream = this.route.queryParams
|
const paramsStream = this.route.queryParams
|
||||||
.map(params => decodeURI(params['query'] || ''))
|
.map(params => decodeURI(params['query'] || ''))
|
||||||
.do(query => this.searchTerm.setValue(query));
|
.do(query => this.searchTerm.setValue(query));
|
||||||
|
|
||||||
const searchTermStream = this.searchTerm.valueChanges
|
const searchTermStream = this.searchTerm.valueChanges
|
||||||
.debounceTime(400)
|
.debounceTime(400)
|
||||||
.do(query => this.adjustBrowserUrl(query));
|
.do(query => this.adjustBrowserUrl(query));
|
||||||
|
|
||||||
Observable.merge(paramsStream, searchTermStream)
|
Observable.merge(paramsStream, searchTermStream)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.switchMap(query => this.rankService.findRanks(query, this.radioModel))
|
.switchMap(query => this.rankService.findRanks(query, this.radioModel))
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +68,8 @@ export class RankListComponent implements OnInit {
|
||||||
const fraction = rank.fraction === 'OPFOR' ? Fraction.OPFOR : Fraction.BLUFOR;
|
const fraction = rank.fraction === 'OPFOR' ? Fraction.OPFOR : Fraction.BLUFOR;
|
||||||
if (confirm('Soll der Rang ' + rank.name + ' (' + fraction + ') wirklich gelöscht werden?')) {
|
if (confirm('Soll der Rang ' + rank.name + ' (' + fraction + ') wirklich gelöscht werden?')) {
|
||||||
this.rankService.deleteRank(rank)
|
this.rankService.deleteRank(rank)
|
||||||
.subscribe((res) => {
|
.subscribe((res) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.overview {
|
.overview {
|
||||||
width: 100%!important;
|
width: 100% !important;
|
||||||
margin-left: 25px!important;
|
margin-left: 25px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.decoration-preview {
|
.decoration-preview {
|
||||||
|
|
|
@ -88,16 +88,16 @@ export class RequestAwardComponent {
|
||||||
};
|
};
|
||||||
this.awardingService.requestAwarding(award).subscribe(() => {
|
this.awardingService.requestAwarding(award).subscribe(() => {
|
||||||
this.awardingService.getUserAwardings(this.user._id)
|
this.awardingService.getUserAwardings(this.user._id)
|
||||||
.subscribe(awards => {
|
.subscribe(awards => {
|
||||||
this.awards = awards;
|
this.awards = awards;
|
||||||
this.decoration = {_id: '0'};
|
this.decoration = {_id: '0'};
|
||||||
this.reason = previewImage.src = descriptionField.innerHTML = '';
|
this.reason = previewImage.src = descriptionField.innerHTML = '';
|
||||||
this.decoPreviewDisplay = 'none';
|
this.decoPreviewDisplay = 'none';
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showSuccessLabel = false;
|
this.showSuccessLabel = false;
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.overview {
|
.overview {
|
||||||
margin-left: 25px!important;
|
margin-left: 25px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.decoration-preview {
|
.decoration-preview {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.overview {
|
.overview {
|
||||||
margin-left: 25px!important;
|
margin-left: 25px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.decoration-preview {
|
.decoration-preview {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.overview {
|
.overview {
|
||||||
margin-left: 25px!important;
|
margin-left: 25px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.decoration-preview {
|
.decoration-preview {
|
||||||
|
|
|
@ -19,10 +19,10 @@ export class AppUserService {
|
||||||
|
|
||||||
getUsers() {
|
getUsers() {
|
||||||
this.http.get(this.config.apiAppUserPath)
|
this.http.get(this.config.apiAppUserPath)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do((users) => {
|
.do((users) => {
|
||||||
this.appUserStore.dispatch({type: LOAD, data: users});
|
this.appUserStore.dispatch({type: LOAD, data: users});
|
||||||
}).subscribe(_ => {
|
}).subscribe(_ => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.users$;
|
return this.users$;
|
||||||
|
@ -30,18 +30,18 @@ export class AppUserService {
|
||||||
|
|
||||||
updateUser(user: AppUser) {
|
updateUser(user: AppUser) {
|
||||||
return this.http.patch(this.config.apiAppUserPath + user._id, user)
|
return this.http.patch(this.config.apiAppUserPath + user._id, user)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do(savedUser => {
|
.do(savedUser => {
|
||||||
const action = {type: EDIT, data: savedUser};
|
const action = {type: EDIT, data: savedUser};
|
||||||
this.appUserStore.dispatch(action);
|
this.appUserStore.dispatch(action);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteUser(user) {
|
deleteUser(user) {
|
||||||
return this.http.delete(this.config.apiAppUserPath + user._id)
|
return this.http.delete(this.config.apiAppUserPath + user._id)
|
||||||
.do(res => {
|
.do(res => {
|
||||||
this.appUserStore.dispatch({type: REMOVE, data: user});
|
this.appUserStore.dispatch({type: REMOVE, data: user});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,25 +18,25 @@ export class LoginService {
|
||||||
|
|
||||||
login(username: string, password: string) {
|
login(username: string, password: string) {
|
||||||
return this.http.post(this.config.apiAuthenticationPath, {username: username, password: password})
|
return this.http.post(this.config.apiAuthenticationPath, {username: username, password: password})
|
||||||
.map((response: Response) => {
|
.map((response: Response) => {
|
||||||
// login successful if there's a jwt token in the response
|
// login successful if there's a jwt token in the response
|
||||||
let user = response.json();
|
let user = response.json();
|
||||||
if (user && user.token) {
|
if (user && user.token) {
|
||||||
// store user details and jwt token in cookie
|
// store user details and jwt token in cookie
|
||||||
this.cookieService.set('currentUser', JSON.stringify(user));
|
this.cookieService.set('currentUser', JSON.stringify(user));
|
||||||
if (user.permission >= 2) {
|
if (user.permission >= 2) {
|
||||||
const fraction = user.squad.fraction;
|
const fraction = user.squad.fraction;
|
||||||
this.awardingService.checkUnprocessedAwards(fraction);
|
this.awardingService.checkUnprocessedAwards(fraction);
|
||||||
this.promotionService.checkUnconfirmedPromotions(fraction);
|
this.promotionService.checkUnconfirmedPromotions(fraction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
signUp(username: string, password: string, secret: string) {
|
signUp(username: string, password: string, secret: string) {
|
||||||
return this.http.post(this.config.apiSignupPath, {username: username, password: password, secret: secret})
|
return this.http.post(this.config.apiSignupPath, {username: username, password: password, secret: secret})
|
||||||
.map((response: Response) => {
|
.map((response: Response) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
logout() {
|
logout() {
|
||||||
|
|
|
@ -14,7 +14,7 @@ export class AwardingService {
|
||||||
|
|
||||||
getUnconfirmedAwards(fraction?: string) {
|
getUnconfirmedAwards(fraction?: string) {
|
||||||
return this.http.get(this.config.apiAwardPath + '?inProgress=true&fractFilter=' + fraction)
|
return this.http.get(this.config.apiAwardPath + '?inProgress=true&fractFilter=' + fraction)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
checkUnprocessedAwards(fraction?: string) {
|
checkUnprocessedAwards(fraction?: string) {
|
||||||
|
@ -30,7 +30,7 @@ export class AwardingService {
|
||||||
*/
|
*/
|
||||||
getUserAwardings(userId: string) {
|
getUserAwardings(userId: string) {
|
||||||
return this.http.get(this.config.apiAwardPath + '?userId=' + userId)
|
return this.http.get(this.config.apiAwardPath + '?userId=' + userId)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
addAwarding(award: Award) {
|
addAwarding(award: Award) {
|
||||||
|
@ -39,7 +39,7 @@ export class AwardingService {
|
||||||
|
|
||||||
updateAward(award) {
|
updateAward(award) {
|
||||||
return this.http.patch(this.config.apiAwardPath + '/' + award._id, award)
|
return this.http.patch(this.config.apiAwardPath + '/' + award._id, award)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
requestAwarding(award: Award) {
|
requestAwarding(award: Award) {
|
||||||
|
|
|
@ -27,10 +27,10 @@ export class DecorationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.http.get(this.config.apiDecorationPath, searchParams)
|
this.http.get(this.config.apiDecorationPath, searchParams)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do((squads) => {
|
.do((squads) => {
|
||||||
this.decorationStore.dispatch({type: LOAD, data: squads});
|
this.decorationStore.dispatch({type: LOAD, data: squads});
|
||||||
}).subscribe(_ => {
|
}).subscribe(_ => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.decorations$;
|
return this.decorations$;
|
||||||
|
@ -38,7 +38,7 @@ export class DecorationService {
|
||||||
|
|
||||||
getDecoration(id: number | string): Observable<Decoration> {
|
getDecoration(id: number | string): Observable<Decoration> {
|
||||||
return this.http.get(this.config.apiDecorationPath + id)
|
return this.http.get(this.config.apiDecorationPath + id)
|
||||||
.map(res => res.json());
|
.map(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,19 +79,19 @@ export class DecorationService {
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.http.request(requestUrl, options)
|
return this.http.request(requestUrl, options)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do(savedDecoration => {
|
.do(savedDecoration => {
|
||||||
const action = {type: accessType, data: savedDecoration};
|
const action = {type: accessType, data: savedDecoration};
|
||||||
this.decorationStore.dispatch(action);
|
this.decorationStore.dispatch(action);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
deleteDecoration(decoration: Decoration) {
|
deleteDecoration(decoration: Decoration) {
|
||||||
return this.http.delete(this.config.apiDecorationPath + decoration._id)
|
return this.http.delete(this.config.apiDecorationPath + decoration._id)
|
||||||
.do(res => {
|
.do(res => {
|
||||||
this.decorationStore.dispatch({type: REMOVE, data: decoration});
|
this.decorationStore.dispatch({type: REMOVE, data: decoration});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ export class PromotionService {
|
||||||
|
|
||||||
getUnconfirmedPromotions(fraction?: string) {
|
getUnconfirmedPromotions(fraction?: string) {
|
||||||
return this.http.get(this.config.apiPromotionPath + '?inProgress=true&fractFilter=' + fraction)
|
return this.http.get(this.config.apiPromotionPath + '?inProgress=true&fractFilter=' + fraction)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
checkUnconfirmedPromotions(fraction?: string) {
|
checkUnconfirmedPromotions(fraction?: string) {
|
||||||
|
@ -27,7 +27,7 @@ export class PromotionService {
|
||||||
|
|
||||||
getSquadPromotions(squadId: string) {
|
getSquadPromotions(squadId: string) {
|
||||||
return this.http.get(this.config.apiPromotionPath + '?squadId=' + squadId)
|
return this.http.get(this.config.apiPromotionPath + '?squadId=' + squadId)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
requestPromotion(promotion: Promotion) {
|
requestPromotion(promotion: Promotion) {
|
||||||
|
@ -36,7 +36,7 @@ export class PromotionService {
|
||||||
|
|
||||||
updatePromotion(promotion) {
|
updatePromotion(promotion) {
|
||||||
return this.http.patch(this.config.apiPromotionPath + '/' + promotion._id, promotion)
|
return this.http.patch(this.config.apiPromotionPath + '/' + promotion._id, promotion)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
deletePromotion(promotionId) {
|
deletePromotion(promotionId) {
|
||||||
|
|
|
@ -28,10 +28,10 @@ export class RankService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.http.get(this.config.apiRankPath, searchParams)
|
this.http.get(this.config.apiRankPath, searchParams)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do((ranks) => {
|
.do((ranks) => {
|
||||||
this.rankStore.dispatch({type: LOAD, data: ranks});
|
this.rankStore.dispatch({type: LOAD, data: ranks});
|
||||||
}).subscribe(_ => {
|
}).subscribe(_ => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.ranks$;
|
return this.ranks$;
|
||||||
|
@ -39,7 +39,7 @@ export class RankService {
|
||||||
|
|
||||||
getRank(id: number | string): Observable<Decoration> {
|
getRank(id: number | string): Observable<Decoration> {
|
||||||
return this.http.get(this.config.apiRankPath + id)
|
return this.http.get(this.config.apiRankPath + id)
|
||||||
.map(res => res.json());
|
.map(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,14 +80,14 @@ export class RankService {
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.http.request(requestUrl, options)
|
return this.http.request(requestUrl, options)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do(savedRank => {
|
.do(savedRank => {
|
||||||
const action = {type: accessType, data: savedRank};
|
const action = {type: accessType, data: savedRank};
|
||||||
// leave some time to save image file before accessing it through listview
|
// leave some time to save image file before accessing it through listview
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.rankStore.dispatch(action);
|
this.rankStore.dispatch(action);
|
||||||
}, 300);
|
}, 300);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,11 +103,11 @@ export class RankService {
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.http.request(this.config.apiRankPath + rank._id, options)
|
return this.http.request(this.config.apiRankPath + rank._id, options)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do(savedRank => {
|
.do(savedRank => {
|
||||||
const action = {type: EDIT, data: savedRank};
|
const action = {type: EDIT, data: savedRank};
|
||||||
this.rankStore.dispatch(action);
|
this.rankStore.dispatch(action);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,18 +125,18 @@ export class RankService {
|
||||||
// provide token as query value, because there is no actual body
|
// provide token as query value, because there is no actual body
|
||||||
// and x-access-token is ignored in multipart request
|
// and x-access-token is ignored in multipart request
|
||||||
return this.http.patch(this.config.apiRankPath + rankId, formData)
|
return this.http.patch(this.config.apiRankPath + rankId, formData)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do(savedDecoration => {
|
.do(savedDecoration => {
|
||||||
const action = {type: EDIT, data: savedDecoration};
|
const action = {type: EDIT, data: savedDecoration};
|
||||||
this.rankStore.dispatch(action);
|
this.rankStore.dispatch(action);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteRank(rank: Rank) {
|
deleteRank(rank: Rank) {
|
||||||
return this.http.delete(this.config.apiRankPath + rank._id)
|
return this.http.delete(this.config.apiRankPath + rank._id)
|
||||||
.do(res => {
|
.do(res => {
|
||||||
this.rankStore.dispatch({type: REMOVE, data: rank});
|
this.rankStore.dispatch({type: REMOVE, data: rank});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@ export class SquadService {
|
||||||
searchParams.append('fractFilter', fractionFilter);
|
searchParams.append('fractFilter', fractionFilter);
|
||||||
|
|
||||||
this.http.get(this.config.apiSquadPath, searchParams)
|
this.http.get(this.config.apiSquadPath, searchParams)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do((squads) => {
|
.do((squads) => {
|
||||||
this.squadStore.dispatch({type: LOAD, data: squads});
|
this.squadStore.dispatch({type: LOAD, data: squads});
|
||||||
}).subscribe(_ => {
|
}).subscribe(_ => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.squads$;
|
return this.squads$;
|
||||||
|
@ -36,7 +36,7 @@ export class SquadService {
|
||||||
|
|
||||||
getSquad(id: number | string): Observable<Squad> {
|
getSquad(id: number | string): Observable<Squad> {
|
||||||
return this.http.get(this.config.apiSquadPath + id)
|
return this.http.get(this.config.apiSquadPath + id)
|
||||||
.map(res => res.json());
|
.map(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,18 +77,18 @@ export class SquadService {
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.http.request(requestUrl, options)
|
return this.http.request(requestUrl, options)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do(savedSquad => {
|
.do(savedSquad => {
|
||||||
const action = {type: accessType, data: savedSquad};
|
const action = {type: accessType, data: savedSquad};
|
||||||
this.squadStore.dispatch(action);
|
this.squadStore.dispatch(action);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteSquad(squad: Squad) {
|
deleteSquad(squad: Squad) {
|
||||||
return this.http.delete(this.config.apiSquadPath + squad._id)
|
return this.http.delete(this.config.apiSquadPath + squad._id)
|
||||||
.do(res => {
|
.do(res => {
|
||||||
this.squadStore.dispatch({type: REMOVE, data: squad});
|
this.squadStore.dispatch({type: REMOVE, data: squad});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,46 +31,47 @@ export class UserService {
|
||||||
searchParams.append('limit', limit);
|
searchParams.append('limit', limit);
|
||||||
searchParams.append('offset', offset);
|
searchParams.append('offset', offset);
|
||||||
this.http.get(this.config.apiUserPath, searchParams)
|
this.http.get(this.config.apiUserPath, searchParams)
|
||||||
.do((res) => {
|
.do((res) => {
|
||||||
let headerCount = parseInt(res.headers.get('x-total-count'));
|
let headerCount = parseInt(res.headers.get('x-total-count'));
|
||||||
if (headerCount) {
|
if (headerCount) {
|
||||||
this.totalCount = headerCount;
|
this.totalCount = headerCount;
|
||||||
}
|
}
|
||||||
}).map(res => res.json()).do((users) => {
|
}).map(res => res.json()).do((users) => {
|
||||||
this.userStore.dispatch({type: action, data: users});
|
this.userStore.dispatch({type: action, data: users});
|
||||||
}).subscribe(_ => {});
|
}).subscribe(_ => {
|
||||||
|
});
|
||||||
|
|
||||||
return this.users$;
|
return this.users$;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUser(_id: number | string): Observable<User> {
|
getUser(_id: number | string): Observable<User> {
|
||||||
return this.http.get(this.config.apiUserPath + _id)
|
return this.http.get(this.config.apiUserPath + _id)
|
||||||
.map(res => res.json());
|
.map(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
submitUser(user) {
|
submitUser(user) {
|
||||||
return this.http.post(this.config.apiUserPath, user)
|
return this.http.post(this.config.apiUserPath, user)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do(savedUser => {
|
.do(savedUser => {
|
||||||
const action = {type: ADD, data: savedUser};
|
const action = {type: ADD, data: savedUser};
|
||||||
this.userStore.dispatch(action);
|
this.userStore.dispatch(action);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUser(user) {
|
updateUser(user) {
|
||||||
return this.http.put(this.config.apiUserPath + user._id, user)
|
return this.http.put(this.config.apiUserPath + user._id, user)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.do(savedUser => {
|
.do(savedUser => {
|
||||||
const action = {type: EDIT, data: savedUser};
|
const action = {type: EDIT, data: savedUser};
|
||||||
this.userStore.dispatch(action);
|
this.userStore.dispatch(action);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteUser(user) {
|
deleteUser(user) {
|
||||||
return this.http.delete(this.config.apiUserPath + user._id)
|
return this.http.delete(this.config.apiUserPath + user._id)
|
||||||
.do(res => {
|
.do(res => {
|
||||||
this.userStore.dispatch({type: REMOVE, data: user});
|
this.userStore.dispatch({type: REMOVE, data: user});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ export class ArmyService {
|
||||||
|
|
||||||
getArmy() {
|
getArmy() {
|
||||||
return this.http.get(this.config.apiOverviewPath)
|
return this.http.get(this.config.apiOverviewPath)
|
||||||
.map(res => res.json());
|
.map(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,17 +14,17 @@ export class CampaignService {
|
||||||
|
|
||||||
getAllCampaigns() {
|
getAllCampaigns() {
|
||||||
return this.http.get(this.config.apiWarPath)
|
return this.http.get(this.config.apiWarPath)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
submitCampaign(campaign: Campaign) {
|
submitCampaign(campaign: Campaign) {
|
||||||
return this.http.post(this.config.apiCampaignPath, campaign)
|
return this.http.post(this.config.apiCampaignPath, campaign)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteCampaign(id: string) {
|
deleteCampaign(id: string) {
|
||||||
return this.http.delete(this.config.apiCampaignPath + '/' + id)
|
return this.http.delete(this.config.apiCampaignPath + '/' + id)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,28 +12,28 @@ export class LogsService {
|
||||||
|
|
||||||
getFullLog(warId: string) {
|
getFullLog(warId: string) {
|
||||||
return this.http.get(this.config.apiLogsPath + '/' + warId)
|
return this.http.get(this.config.apiLogsPath + '/' + warId)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
getBudgetLogs(warId: string, fraction = '') {
|
getBudgetLogs(warId: string, fraction = '') {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append('fraction', fraction);
|
params.append('fraction', fraction);
|
||||||
return this.http.get(this.config.apiLogsPath + '/' + warId + '/budget', params)
|
return this.http.get(this.config.apiLogsPath + '/' + warId + '/budget', params)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
getRespawnLogs(warId: string, playerName = '') {
|
getRespawnLogs(warId: string, playerName = '') {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append('player', playerName);
|
params.append('player', playerName);
|
||||||
return this.http.get(this.config.apiLogsPath + '/' + warId + '/respawn', params)
|
return this.http.get(this.config.apiLogsPath + '/' + warId + '/respawn', params)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
getPointsLogs(warId: string, fraction = '') {
|
getPointsLogs(warId: string, fraction = '') {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append('fraction', fraction);
|
params.append('fraction', fraction);
|
||||||
return this.http.get(this.config.apiLogsPath + '/' + warId + '/points', params)
|
return this.http.get(this.config.apiLogsPath + '/' + warId + '/points', params)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
getReviveLogs(warId: string, medicName = '', patientName = '', fraction = '', stabilizedOnly = false, reviveOnly = false) {
|
getReviveLogs(warId: string, medicName = '', patientName = '', fraction = '', stabilizedOnly = false, reviveOnly = false) {
|
||||||
|
@ -44,7 +44,7 @@ export class LogsService {
|
||||||
params.append('stabilized', stabilizedOnly ? 'true' : '');
|
params.append('stabilized', stabilizedOnly ? 'true' : '');
|
||||||
params.append('revive', reviveOnly ? 'true' : '');
|
params.append('revive', reviveOnly ? 'true' : '');
|
||||||
return this.http.get(this.config.apiLogsPath + '/' + warId + '/revive', params)
|
return this.http.get(this.config.apiLogsPath + '/' + warId + '/revive', params)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
getKillLogs(warId: string, shooterName = '', targetName = '', fraction = '', friendlyFireOnly = false, notFriendlyFireOnly = false) {
|
getKillLogs(warId: string, shooterName = '', targetName = '', fraction = '', friendlyFireOnly = false, notFriendlyFireOnly = false) {
|
||||||
|
@ -55,7 +55,7 @@ export class LogsService {
|
||||||
params.append('friendlyFire', friendlyFireOnly ? 'true' : '');
|
params.append('friendlyFire', friendlyFireOnly ? 'true' : '');
|
||||||
params.append('noFriendlyFire', notFriendlyFireOnly ? 'true' : '');
|
params.append('noFriendlyFire', notFriendlyFireOnly ? 'true' : '');
|
||||||
return this.http.get(this.config.apiLogsPath + '/' + warId + '/kills', params)
|
return this.http.get(this.config.apiLogsPath + '/' + warId + '/kills', params)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
getTransportLogs(warId: string, driverName = '', passengerName = '', fraction = '') {
|
getTransportLogs(warId: string, driverName = '', passengerName = '', fraction = '') {
|
||||||
|
@ -64,7 +64,7 @@ export class LogsService {
|
||||||
params.append('passenger', passengerName);
|
params.append('passenger', passengerName);
|
||||||
params.append('fraction', fraction);
|
params.append('fraction', fraction);
|
||||||
return this.http.get(this.config.apiLogsPath + '/' + warId + '/transport', params)
|
return this.http.get(this.config.apiLogsPath + '/' + warId + '/transport', params)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
getFlagLogs(warId: string, playerName = '', fraction = '', captureOnly = false, defendOnly = false) {
|
getFlagLogs(warId: string, playerName = '', fraction = '', captureOnly = false, defendOnly = false) {
|
||||||
|
@ -74,7 +74,7 @@ export class LogsService {
|
||||||
params.append('capture', captureOnly ? 'true' : '');
|
params.append('capture', captureOnly ? 'true' : '');
|
||||||
params.append('defend', defendOnly ? 'true' : '');
|
params.append('defend', defendOnly ? 'true' : '');
|
||||||
return this.http.get(this.config.apiLogsPath + '/' + warId + '/flag', params)
|
return this.http.get(this.config.apiLogsPath + '/' + warId + '/flag', params)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,12 @@ export class PlayerService {
|
||||||
|
|
||||||
getCampaignPlayer(campaignId: string, playerName: string) {
|
getCampaignPlayer(campaignId: string, playerName: string) {
|
||||||
return this.http.get(this.config.apiPlayersPath + '/single/' + campaignId + '/' + playerName)
|
return this.http.get(this.config.apiPlayersPath + '/single/' + campaignId + '/' + playerName)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
getCampaignHighscore(campaignId: string) {
|
getCampaignHighscore(campaignId: string) {
|
||||||
return this.http.get(this.config.apiPlayersPath + '/ranking/' + campaignId)
|
return this.http.get(this.config.apiPlayersPath + '/ranking/' + campaignId)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ export class WarService {
|
||||||
|
|
||||||
getWar(warId: string) {
|
getWar(warId: string) {
|
||||||
return this.http.get(this.config.apiWarPath + '/' + warId)
|
return this.http.get(this.config.apiWarPath + '/' + warId)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,12 +30,12 @@ export class WarService {
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.http.post(this.config.apiWarPath, body)
|
return this.http.post(this.config.apiWarPath, body)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteWar(id: string) {
|
deleteWar(id: string) {
|
||||||
return this.http.delete(this.config.apiWarPath + '/' + id)
|
return this.http.delete(this.config.apiWarPath + '/' + id)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,13 +38,13 @@ export class EditSquadComponent {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.subscription = this.route.params
|
this.subscription = this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.filter(id => id != undefined)
|
.filter(id => id != undefined)
|
||||||
.flatMap(id => this.squadService.getSquad(id))
|
.flatMap(id => this.squadService.getSquad(id))
|
||||||
.subscribe(squad => {
|
.subscribe(squad => {
|
||||||
this.squad = squad;
|
this.squad = squad;
|
||||||
this.imagePreviewSrc = 'resource/squad/' + this.squad._id + '.png?' + Date.now();
|
this.imagePreviewSrc = 'resource/squad/' + this.squad._id + '.png?' + Date.now();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
@ -67,10 +67,10 @@ export class EditSquadComponent {
|
||||||
if (this.fileList) {
|
if (this.fileList) {
|
||||||
file = this.fileList[0];
|
file = this.fileList[0];
|
||||||
this.squadService.submitSquad(this.squad, file)
|
this.squadService.submitSquad(this.squad, file)
|
||||||
.subscribe(rank => {
|
.subscribe(rank => {
|
||||||
this.saved = true;
|
this.saved = true;
|
||||||
this.router.navigate(['..'], {relativeTo: this.route});
|
this.router.navigate(['..'], {relativeTo: this.route});
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return window.alert(`Bild ist ein Pflichtfeld`);
|
return window.alert(`Bild ist ein Pflichtfeld`);
|
||||||
}
|
}
|
||||||
|
@ -80,16 +80,16 @@ export class EditSquadComponent {
|
||||||
}
|
}
|
||||||
delete this.squad['__v'];
|
delete this.squad['__v'];
|
||||||
this.squadService.submitSquad(this.squad, file)
|
this.squadService.submitSquad(this.squad, file)
|
||||||
.subscribe(rank => {
|
.subscribe(rank => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.imagePreviewSrc = 'resource/squad/' + this.squad._id + '.png?' + Date.now();
|
this.imagePreviewSrc = 'resource/squad/' + this.squad._id + '.png?' + Date.now();
|
||||||
}, 300);
|
}, 300);
|
||||||
fileInput.value = '';
|
fileInput.value = '';
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showSuccessLabel = false;
|
this.showSuccessLabel = false;
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,17 +36,17 @@ export class SquadListComponent implements OnInit {
|
||||||
this.squads$ = this.squadService.squads$;
|
this.squads$ = this.squadService.squads$;
|
||||||
|
|
||||||
const paramsStream = this.route.queryParams
|
const paramsStream = this.route.queryParams
|
||||||
.map(params => decodeURI(params['query'] || ''))
|
.map(params => decodeURI(params['query'] || ''))
|
||||||
.do(query => this.searchTerm.setValue(query));
|
.do(query => this.searchTerm.setValue(query));
|
||||||
|
|
||||||
const searchTermStream = this.searchTerm.valueChanges
|
const searchTermStream = this.searchTerm.valueChanges
|
||||||
.debounceTime(400)
|
.debounceTime(400)
|
||||||
.do(query => this.adjustBrowserUrl(query));
|
.do(query => this.adjustBrowserUrl(query));
|
||||||
|
|
||||||
Observable.merge(paramsStream, searchTermStream)
|
Observable.merge(paramsStream, searchTermStream)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.switchMap(query => this.squadService.findSquads(query, this.radioModel))
|
.switchMap(query => this.squadService.findSquads(query, this.radioModel))
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,8 +64,8 @@ export class SquadListComponent implements OnInit {
|
||||||
const fraction = squad.fraction === 'OPFOR' ? Fraction.OPFOR : Fraction.BLUFOR;
|
const fraction = squad.fraction === 'OPFOR' ? Fraction.OPFOR : Fraction.BLUFOR;
|
||||||
if (confirm('Soll das Squad "' + squad.name + '" (' + fraction + ') wirklich gelöscht werden?')) {
|
if (confirm('Soll das Squad "' + squad.name + '" (' + fraction + ') wirklich gelöscht werden?')) {
|
||||||
this.squadService.deleteSquad(squad)
|
this.squadService.deleteSquad(squad)
|
||||||
.subscribe((res) => {
|
.subscribe((res) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,26 @@
|
||||||
</ngx-charts-line-chart>
|
</ngx-charts-line-chart>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="chart-container">
|
||||||
|
<ngx-charts-line-chart
|
||||||
|
[results]="vehicleKillData"
|
||||||
|
[showRefLines]="showRefLines"
|
||||||
|
[showRefLabels]="showRefLabels"
|
||||||
|
[referenceLines]="killRefLines"
|
||||||
|
[scheme]="colorScheme"
|
||||||
|
[gradient]="gradient"
|
||||||
|
[xAxis]="xAxis"
|
||||||
|
[yAxis]="yAxis"
|
||||||
|
[legend]="legend"
|
||||||
|
[showXAxisLabel]="showXAxisLabel"
|
||||||
|
[showYAxisLabel]="showYAxisLabel"
|
||||||
|
[yAxisLabel]="yAxisVehicleKill"
|
||||||
|
[autoScale]="autoscale"
|
||||||
|
[timeline]="timeline"
|
||||||
|
[roundDomains]="roundDomains">
|
||||||
|
</ngx-charts-line-chart>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="chart-container">
|
<div class="chart-container">
|
||||||
<ngx-charts-line-chart
|
<ngx-charts-line-chart
|
||||||
[results]="deathData"
|
[results]="deathData"
|
||||||
|
|
|
@ -25,6 +25,7 @@ export class CampaignPlayerDetailComponent {
|
||||||
sumData: any[] = [];
|
sumData: any[] = [];
|
||||||
killData: any[] = [];
|
killData: any[] = [];
|
||||||
friendlyFireData: any[] = [];
|
friendlyFireData: any[] = [];
|
||||||
|
vehicleKillData: any[] = [];
|
||||||
deathData: any[] = [];
|
deathData: any[] = [];
|
||||||
respawnData: any[] = [];
|
respawnData: any[] = [];
|
||||||
reviveData: any[] = [];
|
reviveData: any[] = [];
|
||||||
|
@ -32,6 +33,7 @@ export class CampaignPlayerDetailComponent {
|
||||||
|
|
||||||
yAxisKill = 'Kills';
|
yAxisKill = 'Kills';
|
||||||
yAxisFriendlyFire = 'FriendlyFire';
|
yAxisFriendlyFire = 'FriendlyFire';
|
||||||
|
yAxisVehicleKill = 'Farzeug-Kills';
|
||||||
yAxisDeath = 'Tode';
|
yAxisDeath = 'Tode';
|
||||||
yAxisRespawn = 'Respawn';
|
yAxisRespawn = 'Respawn';
|
||||||
yAxisRevive = 'Revive';
|
yAxisRevive = 'Revive';
|
||||||
|
@ -49,6 +51,7 @@ export class CampaignPlayerDetailComponent {
|
||||||
showRefLines = true;
|
showRefLines = true;
|
||||||
showRefLabels = true;
|
showRefLabels = true;
|
||||||
killRefLines = [];
|
killRefLines = [];
|
||||||
|
vehicleKillRefLines = [];
|
||||||
deathRefLines = [];
|
deathRefLines = [];
|
||||||
captureRefLines = [];
|
captureRefLines = [];
|
||||||
friendlyFireRefLines = [];
|
friendlyFireRefLines = [];
|
||||||
|
@ -67,6 +70,7 @@ export class CampaignPlayerDetailComponent {
|
||||||
|
|
||||||
totalKills;
|
totalKills;
|
||||||
totalFriendlyFire;
|
totalFriendlyFire;
|
||||||
|
totalVehicleKills;
|
||||||
totalDeath;
|
totalDeath;
|
||||||
totalRespawn;
|
totalRespawn;
|
||||||
totalRevive;
|
totalRevive;
|
||||||
|
@ -84,49 +88,54 @@ export class CampaignPlayerDetailComponent {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.playerService.getCampaignPlayer(this.campaignId, encodeURIComponent(this.playerName))
|
this.playerService.getCampaignPlayer(this.campaignId, encodeURIComponent(this.playerName))
|
||||||
.subscribe(campaignPlayer => {
|
.subscribe(campaignPlayer => {
|
||||||
this.campaignPlayer = campaignPlayer;
|
this.campaignPlayer = campaignPlayer;
|
||||||
this.killData = this.assignData(this.yAxisKill, "kill");
|
this.killData = this.assignData(this.yAxisKill, "kill");
|
||||||
this.friendlyFireData = this.assignData(this.yAxisFriendlyFire, "friendlyFire");
|
this.vehicleKillData = this.assignData(this.yAxisVehicleKill, "vehicle");
|
||||||
this.deathData = this.assignData(this.yAxisDeath, "death");
|
this.friendlyFireData = this.assignData(this.yAxisFriendlyFire, "friendlyFire");
|
||||||
this.respawnData = this.assignData(this.yAxisRespawn, "respawn");
|
this.deathData = this.assignData(this.yAxisDeath, "death");
|
||||||
this.reviveData = this.assignData(this.yAxisRevive, "revive");
|
this.respawnData = this.assignData(this.yAxisRespawn, "respawn");
|
||||||
this.captureData = this.assignData(this.yAxisCapture, "flagTouch");
|
this.reviveData = this.assignData(this.yAxisRevive, "revive");
|
||||||
|
this.captureData = this.assignData(this.yAxisCapture, "flagTouch");
|
||||||
|
|
||||||
this.kdRatio = parseFloat((this.totalKills / (this.totalDeath === 0 ? 1 : this.totalDeath)).toFixed(2));
|
this.kdRatio = parseFloat((this.totalKills / (this.totalDeath === 0 ? 1 : this.totalDeath)).toFixed(2));
|
||||||
if (this.kdRatio > 1) this.maxKd = this.kdRatio * 1.7;
|
if (this.kdRatio > 1) this.maxKd = this.kdRatio * 1.7;
|
||||||
|
|
||||||
this.respawnDeathRatio = parseFloat((this.totalRespawn / (this.totalDeath === 0 ? 1 : this.totalDeath)).toFixed(2));
|
this.respawnDeathRatio = parseFloat((this.totalRespawn / (this.totalDeath === 0 ? 1 : this.totalDeath)).toFixed(2));
|
||||||
|
|
||||||
this.sumData = [
|
this.sumData = [
|
||||||
{
|
{
|
||||||
name: this.yAxisKill,
|
name: this.yAxisKill,
|
||||||
value: this.totalKills
|
value: this.totalKills
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: this.yAxisFriendlyFire,
|
name: this.yAxisFriendlyFire,
|
||||||
value: this.totalFriendlyFire
|
value: this.totalFriendlyFire
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: this.yAxisDeath,
|
name: this.yAxisVehicleKill,
|
||||||
value: this.totalDeath
|
value: this.totalVehicleKills
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: this.yAxisRespawn,
|
name: this.yAxisDeath,
|
||||||
value: this.totalRespawn
|
value: this.totalDeath
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: this.yAxisRevive,
|
name: this.yAxisRespawn,
|
||||||
value: this.totalRevive
|
value: this.totalRespawn
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: this.yAxisCapture,
|
name: this.yAxisRevive,
|
||||||
value: this.totalCapture
|
value: this.totalRevive
|
||||||
}
|
},
|
||||||
];
|
{
|
||||||
|
name: this.yAxisCapture,
|
||||||
|
value: this.totalCapture
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
Object.assign(this, [this.sumData, this.killData, this.friendlyFireData, this.deathData, this.respawnData, this.reviveData, this.captureData]);
|
Object.assign(this, [this.sumData, this.killData, this.friendlyFireData, this.vehicleKillData, this.deathData, this.respawnData, this.reviveData, this.captureData]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private assignData(label, field) {
|
private assignData(label, field) {
|
||||||
|
@ -138,12 +147,12 @@ export class CampaignPlayerDetailComponent {
|
||||||
let total = 0;
|
let total = 0;
|
||||||
for (let i = 0; i < playerLength; i++) {
|
for (let i = 0; i < playerLength; i++) {
|
||||||
const warDateString = ChartUtils.getShortDateString(this.campaignPlayer.players[i].warId.date);
|
const warDateString = ChartUtils.getShortDateString(this.campaignPlayer.players[i].warId.date);
|
||||||
const warKills = this.campaignPlayer.players[i][field];
|
const value = this.campaignPlayer.players[i][field];
|
||||||
killObj.series.push({
|
killObj.series.push({
|
||||||
name: warDateString,
|
name: warDateString,
|
||||||
value: warKills
|
value: value
|
||||||
});
|
});
|
||||||
total += warKills;
|
total += value;
|
||||||
}
|
}
|
||||||
switch (field) {
|
switch (field) {
|
||||||
case 'kill':
|
case 'kill':
|
||||||
|
@ -154,6 +163,10 @@ export class CampaignPlayerDetailComponent {
|
||||||
this.friendlyFireRefLines.push({value: total / playerLength, name: this.avgLabel});
|
this.friendlyFireRefLines.push({value: total / playerLength, name: this.avgLabel});
|
||||||
this.totalFriendlyFire = total;
|
this.totalFriendlyFire = total;
|
||||||
break;
|
break;
|
||||||
|
case 'vehicle':
|
||||||
|
this.vehicleKillRefLines.push({value: total / playerLength, name: this.avgLabel});
|
||||||
|
this.totalVehicleKills = total;
|
||||||
|
break;
|
||||||
case 'death':
|
case 'death':
|
||||||
this.deathRefLines.push({value: total / playerLength, name: this.avgLabel});
|
this.deathRefLines.push({value: total / playerLength, name: this.avgLabel});
|
||||||
this.totalDeath = total;
|
this.totalDeath = total;
|
||||||
|
|
|
@ -27,13 +27,13 @@ export class CampaignSubmitComponent {
|
||||||
|
|
||||||
saveCampaign() {
|
saveCampaign() {
|
||||||
this.campaignService.submitCampaign(this.campaign)
|
this.campaignService.submitCampaign(this.campaign)
|
||||||
.subscribe(campaign => {
|
.subscribe(campaign => {
|
||||||
this.router.navigate(['../overview/' + campaign._id], {relativeTo: this.route});
|
this.router.navigate(['../overview/' + campaign._id], {relativeTo: this.route});
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.error = error._body.error.message;
|
this.error = error._body.error.message;
|
||||||
this.showErrorLabel = true;
|
this.showErrorLabel = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
|
|
|
@ -18,12 +18,10 @@ ngx-datatable {
|
||||||
float: left;
|
float: left;
|
||||||
border: solid #dfdfdf 1px;
|
border: solid #dfdfdf 1px;
|
||||||
border-radius: 10px 10px 2px 2px;
|
border-radius: 10px 10px 2px 2px;
|
||||||
border-right-style: none;
|
|
||||||
border-top-style: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .datatable-header {
|
:host /deep/ .datatable-header {
|
||||||
width: 350px!important;
|
width: 350px !important;
|
||||||
background: #222222;
|
background: #222222;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
border-radius: 10px 10px 0 0;
|
border-radius: 10px 10px 0 0;
|
||||||
|
@ -74,5 +72,4 @@ ngx-datatable {
|
||||||
background: #4b4b4b;
|
background: #4b4b4b;
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.5);
|
-webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Table Scrollbar END */
|
/* Table Scrollbar END */
|
||||||
|
|
|
@ -36,6 +36,48 @@
|
||||||
<ngx-datatable-column [width]="valueColWidth" name="Kills" prop="kill"></ngx-datatable-column>
|
<ngx-datatable-column [width]="valueColWidth" name="Kills" prop="kill"></ngx-datatable-column>
|
||||||
</ngx-datatable>
|
</ngx-datatable>
|
||||||
|
|
||||||
|
<ngx-datatable
|
||||||
|
[rows]="players.friendlyFire"
|
||||||
|
[messages]="emptyMessage"
|
||||||
|
[headerHeight]="cellHeight"
|
||||||
|
[rowHeight]="cellHeight"
|
||||||
|
[cssClasses]='customClasses'
|
||||||
|
[columnMode]="'force'"
|
||||||
|
[scrollbarV]="true"
|
||||||
|
[selectionType]="'single'">
|
||||||
|
<ngx-datatable-column [width]="numberColWidth" name="#" prop="num"></ngx-datatable-column>
|
||||||
|
<ngx-datatable-column name="Spieler" prop="name" [width]="nameColWidth" style="padding-left:10px">
|
||||||
|
<ng-template ngx-datatable-cell-template let-row="row" let-value="value">
|
||||||
|
<span class="player-name"
|
||||||
|
[style.color]="row['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
||||||
|
{{value}}
|
||||||
|
</span>
|
||||||
|
</ng-template>
|
||||||
|
</ngx-datatable-column>
|
||||||
|
<ngx-datatable-column [width]="valueColWidth" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column>
|
||||||
|
</ngx-datatable>
|
||||||
|
|
||||||
|
<ngx-datatable
|
||||||
|
[rows]="players.vehicle"
|
||||||
|
[messages]="emptyMessage"
|
||||||
|
[headerHeight]="cellHeight"
|
||||||
|
[rowHeight]="cellHeight"
|
||||||
|
[cssClasses]='customClasses'
|
||||||
|
[columnMode]="'force'"
|
||||||
|
[scrollbarV]="true"
|
||||||
|
[selectionType]="'single'">
|
||||||
|
<ngx-datatable-column [width]="numberColWidth" name="#" prop="num"></ngx-datatable-column>
|
||||||
|
<ngx-datatable-column name="Spieler" prop="name" [width]="nameColWidth" style="padding-left:10px">
|
||||||
|
<ng-template ngx-datatable-cell-template let-row="row" let-value="value">
|
||||||
|
<span class="player-name"
|
||||||
|
[style.color]="row['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
||||||
|
{{value}}
|
||||||
|
</span>
|
||||||
|
</ng-template>
|
||||||
|
</ngx-datatable-column>
|
||||||
|
<ngx-datatable-column [width]="valueColWidth" name="Fahrzeug-Kills" prop="vehicle"></ngx-datatable-column>
|
||||||
|
</ngx-datatable>
|
||||||
|
|
||||||
<ngx-datatable
|
<ngx-datatable
|
||||||
[rows]="players.death"
|
[rows]="players.death"
|
||||||
[messages]="emptyMessage"
|
[messages]="emptyMessage"
|
||||||
|
@ -78,27 +120,6 @@
|
||||||
<ngx-datatable-column [width]="valueColWidth" name="Respawn" prop="respawn"></ngx-datatable-column>
|
<ngx-datatable-column [width]="valueColWidth" name="Respawn" prop="respawn"></ngx-datatable-column>
|
||||||
</ngx-datatable>
|
</ngx-datatable>
|
||||||
|
|
||||||
<ngx-datatable
|
|
||||||
[rows]="players.friendlyFire"
|
|
||||||
[messages]="emptyMessage"
|
|
||||||
[headerHeight]="cellHeight"
|
|
||||||
[rowHeight]="cellHeight"
|
|
||||||
[cssClasses]='customClasses'
|
|
||||||
[columnMode]="'force'"
|
|
||||||
[scrollbarV]="true"
|
|
||||||
[selectionType]="'single'">
|
|
||||||
<ngx-datatable-column [width]="numberColWidth" name="#" prop="num"></ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="Spieler" prop="name" [width]="nameColWidth" style="padding-left:10px">
|
|
||||||
<ng-template ngx-datatable-cell-template let-row="row" let-value="value">
|
|
||||||
<span class="player-name"
|
|
||||||
[style.color]="row['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
|
||||||
{{value}}
|
|
||||||
</span>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column [width]="valueColWidth" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column>
|
|
||||||
</ngx-datatable>
|
|
||||||
|
|
||||||
<ngx-datatable
|
<ngx-datatable
|
||||||
[rows]="players.revive"
|
[rows]="players.revive"
|
||||||
[messages]="emptyMessage"
|
[messages]="emptyMessage"
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class StatisticHighScoreComponent {
|
||||||
|
|
||||||
searchTerm = new FormControl();
|
searchTerm = new FormControl();
|
||||||
|
|
||||||
players : Player = {};
|
players: Player = {};
|
||||||
|
|
||||||
playersStored = {};
|
playersStored = {};
|
||||||
|
|
||||||
|
@ -50,28 +50,28 @@ export class StatisticHighScoreComponent {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.route.params
|
this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.subscribe((id) => {
|
.subscribe((id) => {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
if (this.campaignService.campaigns) {
|
if (this.campaignService.campaigns) {
|
||||||
this.initData();
|
this.initData();
|
||||||
} else {
|
} else {
|
||||||
this.campaignService.getAllCampaigns().subscribe(campaigns => {
|
this.campaignService.getAllCampaigns().subscribe(campaigns => {
|
||||||
this.initData()
|
this.initData()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchTermStream = this.searchTerm.valueChanges.debounceTime(400);
|
const searchTermStream = this.searchTerm.valueChanges.debounceTime(400);
|
||||||
|
|
||||||
Observable.merge(searchTermStream)
|
Observable.merge(searchTermStream)
|
||||||
.distinctUntilChanged().map(query => this.filterPlayers())
|
.distinctUntilChanged().map(query => this.filterPlayers())
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
initData() {
|
initData() {
|
||||||
this.title = this.campaignService.campaigns
|
this.title = this.campaignService.campaigns
|
||||||
.filter(camp => camp._id === this.id).pop().title;
|
.filter(camp => camp._id === this.id).pop().title;
|
||||||
|
|
||||||
this.playerService.getCampaignHighscore(this.id).subscribe(players => {
|
this.playerService.getCampaignHighscore(this.id).subscribe(players => {
|
||||||
this.players = players;
|
this.players = players;
|
||||||
|
@ -86,6 +86,7 @@ export class StatisticHighScoreComponent {
|
||||||
this.players = {
|
this.players = {
|
||||||
kill: this.filterPlayerAttribute('kill'),
|
kill: this.filterPlayerAttribute('kill'),
|
||||||
friendlyFire: this.filterPlayerAttribute('friendlyFire'),
|
friendlyFire: this.filterPlayerAttribute('friendlyFire'),
|
||||||
|
vehicle: this.filterPlayerAttribute('vehicle'),
|
||||||
death: this.filterPlayerAttribute('death'),
|
death: this.filterPlayerAttribute('death'),
|
||||||
respawn: this.filterPlayerAttribute('respawn'),
|
respawn: this.filterPlayerAttribute('respawn'),
|
||||||
revive: this.filterPlayerAttribute('revive'),
|
revive: this.filterPlayerAttribute('revive'),
|
||||||
|
|
|
@ -43,17 +43,17 @@ export class StatisticOverviewComponent {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.route.params
|
this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.subscribe((id) => {
|
.subscribe((id) => {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
if (this.campaignService.campaigns) {
|
if (this.campaignService.campaigns) {
|
||||||
this.initWars(this.campaignService.campaigns);
|
this.initWars(this.campaignService.campaigns);
|
||||||
} else {
|
} else {
|
||||||
this.campaignService.getAllCampaigns().subscribe(campaigns => {
|
this.campaignService.getAllCampaigns().subscribe(campaigns => {
|
||||||
this.initWars(campaigns);
|
this.initWars(campaigns);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initWars(campaigns) {
|
initWars(campaigns) {
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
btnRadio="{{labelKill}}">{{labelKill}}</label>
|
btnRadio="{{labelKill}}">{{labelKill}}</label>
|
||||||
<label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel"
|
<label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel"
|
||||||
btnRadio="{{labelFriendlyFire}}">{{labelFriendlyFire}}</label>
|
btnRadio="{{labelFriendlyFire}}">{{labelFriendlyFire}}</label>
|
||||||
|
<label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel"
|
||||||
|
btnRadio="{{labelVehicle}}">{{labelVehicle}}</label>
|
||||||
<label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel"
|
<label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel"
|
||||||
btnRadio="{{labelRevive}}">{{labelRevive}}</label>
|
btnRadio="{{labelRevive}}">{{labelRevive}}</label>
|
||||||
<label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel"
|
<label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel"
|
||||||
|
|
|
@ -34,6 +34,7 @@ export class FractionStatsComponent {
|
||||||
tmpBudgetData;
|
tmpBudgetData;
|
||||||
tmpKillData;
|
tmpKillData;
|
||||||
tmpFrienlyFireData;
|
tmpFrienlyFireData;
|
||||||
|
tmpVehicleData;
|
||||||
tmpTransportData;
|
tmpTransportData;
|
||||||
tmpReviveData;
|
tmpReviveData;
|
||||||
tmpStabilizeData;
|
tmpStabilizeData;
|
||||||
|
@ -47,6 +48,7 @@ export class FractionStatsComponent {
|
||||||
labelBudget = 'Budget';
|
labelBudget = 'Budget';
|
||||||
labelKill = 'Kills';
|
labelKill = 'Kills';
|
||||||
labelFriendlyFire = 'FriendlyFire';
|
labelFriendlyFire = 'FriendlyFire';
|
||||||
|
labelVehicle = 'Fahrzeug-Kills';
|
||||||
labelTransport = 'Lufttransport';
|
labelTransport = 'Lufttransport';
|
||||||
labelRevive = 'Revive';
|
labelRevive = 'Revive';
|
||||||
labelStabilize = 'Stabilisiert';
|
labelStabilize = 'Stabilisiert';
|
||||||
|
@ -111,6 +113,10 @@ export class FractionStatsComponent {
|
||||||
this.initKillData();
|
this.initKillData();
|
||||||
this.lineChartData = this.tmpFrienlyFireData;
|
this.lineChartData = this.tmpFrienlyFireData;
|
||||||
break;
|
break;
|
||||||
|
case this.labelVehicle:
|
||||||
|
this.initVehicleData();
|
||||||
|
this.lineChartData = this.tmpVehicleData;
|
||||||
|
break;
|
||||||
case this.labelRevive:
|
case this.labelRevive:
|
||||||
this.initRevive();
|
this.initRevive();
|
||||||
this.lineChartData = this.tmpReviveData;
|
this.lineChartData = this.tmpReviveData;
|
||||||
|
@ -250,6 +256,30 @@ export class FractionStatsComponent {
|
||||||
this.initialized.revive = true;
|
this.initialized.revive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initVehicleData() {
|
||||||
|
if (this.initialized.vehicle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let vehicleKillCountBlufor = 0, vehicleKillCountOpfor = 0;
|
||||||
|
for (const {transportEntry: vehicleEntry, index} of this.logData.vehicle.map((transportEntry, index) => ({
|
||||||
|
transportEntry,
|
||||||
|
index
|
||||||
|
}))) {
|
||||||
|
const vehicleEntryDate = new Date(vehicleEntry.time);
|
||||||
|
if (vehicleEntry.fraction === 'BLUFOR') {
|
||||||
|
vehicleKillCountBlufor++;
|
||||||
|
} else {
|
||||||
|
vehicleKillCountOpfor++;
|
||||||
|
}
|
||||||
|
if (this.isTwoMinutesAhead(vehicleEntryDate, this.tmpVehicleData) || index === this.logData.vehicle.length - 1) {
|
||||||
|
this.tmpVehicleData[0].series.push(ChartUtils.getSeriesEntry(vehicleEntryDate, vehicleKillCountBlufor));
|
||||||
|
this.tmpVehicleData[1].series.push(ChartUtils.getSeriesEntry(vehicleEntryDate, vehicleKillCountOpfor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.addFinalTimeData(this.tmpVehicleData);
|
||||||
|
this.initialized.vehicle = true;
|
||||||
|
}
|
||||||
|
|
||||||
initTransportData() {
|
initTransportData() {
|
||||||
if (this.initialized.transport) {
|
if (this.initialized.transport) {
|
||||||
return;
|
return;
|
||||||
|
@ -272,7 +302,6 @@ export class FractionStatsComponent {
|
||||||
}
|
}
|
||||||
this.addFinalTimeData(this.tmpTransportData);
|
this.addFinalTimeData(this.tmpTransportData);
|
||||||
this.initialized.transport = true;
|
this.initialized.transport = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initFlagHoldData() {
|
initFlagHoldData() {
|
||||||
|
@ -308,12 +337,13 @@ export class FractionStatsComponent {
|
||||||
this.tmpBudgetData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpBudgetData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
this.tmpKillData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpKillData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
this.tmpFrienlyFireData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpFrienlyFireData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
|
this.tmpVehicleData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
this.tmpTransportData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpTransportData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
this.tmpReviveData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpReviveData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
this.tmpStabilizeData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpStabilizeData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
this.tmpFlagCaptureData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpFlagCaptureData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
|
|
||||||
[this.tmpKillData, this.tmpFrienlyFireData, this.tmpReviveData, this.tmpStabilizeData, this.tmpTransportData].forEach(tmp => {
|
[this.tmpKillData, this.tmpFrienlyFireData, this.tmpVehicleData, this.tmpReviveData, this.tmpStabilizeData, this.tmpTransportData].forEach(tmp => {
|
||||||
[0, 1].forEach(index => {
|
[0, 1].forEach(index => {
|
||||||
tmp[index].series.push(ChartUtils.getSeriesEntry(this.startDateObj, 0));
|
tmp[index].series.push(ChartUtils.getSeriesEntry(this.startDateObj, 0));
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,7 +11,7 @@ ngx-datatable {
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .datatable-header {
|
:host /deep/ .datatable-header {
|
||||||
width: 1100px!important;
|
width: 1100px !important;
|
||||||
background: #222222;
|
background: #222222;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
border-radius: 10px 10px 0 0;
|
border-radius: 10px 10px 0 0;
|
||||||
|
|
|
@ -25,18 +25,22 @@
|
||||||
</ngx-datatable-column>
|
</ngx-datatable-column>
|
||||||
<ngx-datatable-column [width]="90" name="Kills" prop="kill"></ngx-datatable-column>
|
<ngx-datatable-column [width]="90" name="Kills" prop="kill"></ngx-datatable-column>
|
||||||
<ngx-datatable-column [width]="104" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column>
|
<ngx-datatable-column [width]="104" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column>
|
||||||
|
<ngx-datatable-column [width]="90" name="Fahrzeug" prop="vehicle"></ngx-datatable-column>
|
||||||
<ngx-datatable-column [width]="80" name="Revive" prop="revive"></ngx-datatable-column>
|
<ngx-datatable-column [width]="80" name="Revive" prop="revive"></ngx-datatable-column>
|
||||||
<ngx-datatable-column [width]="100" name="Eroberung" prop="flagTouch"></ngx-datatable-column>
|
<ngx-datatable-column [width]="100" name="Eroberung" prop="flagTouch"></ngx-datatable-column>
|
||||||
<ngx-datatable-column [width]="70" name="Tod" prop="death"></ngx-datatable-column>
|
<ngx-datatable-column [width]="70" name="Tod" prop="death"></ngx-datatable-column>
|
||||||
<ngx-datatable-column [width]="90" name="Respawn" prop="respawn"></ngx-datatable-column>
|
<ngx-datatable-column [width]="90" name="Respawn" prop="respawn"></ngx-datatable-column>
|
||||||
<ngx-datatable-column [width]="80" name="" prop="name">
|
<!--<ngx-datatable-column [width]="80" name="" prop="name">-->
|
||||||
<ng-template ngx-datatable-cell-template let-value="value">
|
<!--<ng-template ngx-datatable-cell-template let-value="value">-->
|
||||||
<span class="btn btn-sm btn-default in-table-btn disabled">Detail</span>
|
<!--<span class="btn btn-sm btn-default in-table-btn disabled">Detail</span>-->
|
||||||
</ng-template>
|
<!--</ng-template>-->
|
||||||
</ngx-datatable-column>
|
<!--</ngx-datatable-column>-->
|
||||||
<ngx-datatable-column [width]="80" name="" prop="name">
|
<ngx-datatable-column [width]="80">
|
||||||
<ng-template ngx-datatable-cell-template let-value="value">
|
<ng-template ngx-datatable-cell-template let-row="row">
|
||||||
<span class="btn btn-sm btn-default in-table-btn" (click)="selectPlayerDetail(1, value)">Gesamt</span>
|
<span class="btn btn-sm btn-default in-table-btn"
|
||||||
|
(click)="selectPlayerDetail(1, isSteamUUID(row['steamUUID']) ? row['steamUUID'] : row['name'])">
|
||||||
|
Gesamt
|
||||||
|
</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ngx-datatable-column>
|
</ngx-datatable-column>
|
||||||
</ngx-datatable>
|
</ngx-datatable>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {Component, EventEmitter, SimpleChanges} from "@angular/core";
|
import {Component, ElementRef, EventEmitter, SimpleChanges} from "@angular/core";
|
||||||
import {War} from "../../../models/model-interfaces";
|
import {War} from "../../../models/model-interfaces";
|
||||||
import {Fraction} from "../../../utils/fraction.enum";
|
import {Fraction} from "../../../utils/fraction.enum";
|
||||||
|
import {PlayerUtils} from "../../../utils/player-utils";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'scoreboard',
|
selector: 'scoreboard',
|
||||||
|
@ -17,6 +18,8 @@ export class ScoreboardComponent {
|
||||||
|
|
||||||
war: War;
|
war: War;
|
||||||
|
|
||||||
|
isSteamUUID = PlayerUtils.isSteamUUID;
|
||||||
|
|
||||||
fractionFilterSelected: string;
|
fractionFilterSelected: string;
|
||||||
|
|
||||||
cellHeight = 40;
|
cellHeight = 40;
|
||||||
|
@ -30,19 +33,22 @@ export class ScoreboardComponent {
|
||||||
sortDescending: 'glyphicon glyphicon-triangle-bottom',
|
sortDescending: 'glyphicon glyphicon-triangle-bottom',
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor(private elRef: ElementRef) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
selectPlayerDetail(view: number, player) {
|
||||||
}
|
this.playerTabSwitch.emit({
|
||||||
|
view: view,
|
||||||
selectPlayerDetail(view: number, playerName: string) {
|
player: player
|
||||||
this.playerTabSwitch.emit({view: view, player: playerName})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (changes.war) {
|
if (changes.war) {
|
||||||
this.rows = changes.war.currentValue.players;
|
this.rows = changes.war.currentValue.players;
|
||||||
|
this.elRef.nativeElement
|
||||||
|
.querySelector('.datatable-body')
|
||||||
|
.scrollTo(0, 0);
|
||||||
}
|
}
|
||||||
if (changes.fractionFilterSelected) {
|
if (changes.fractionFilterSelected) {
|
||||||
this.filterPlayersByFraction(this.fractionFilterSelected)
|
this.filterPlayersByFraction(this.fractionFilterSelected)
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs {
|
.nav-tabs {
|
||||||
|
width: 980px;
|
||||||
|
margin: auto;
|
||||||
|
clear: both;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="nav nav-tabs" style="width:980px; margin:auto">
|
<ul class="nav nav-tabs">
|
||||||
<li class="nav-item" [ngClass]="{active :tab === 0}" (click)="switchTab(0)">
|
<li class="nav-item" [ngClass]="{active :tab === 0}" (click)="switchTab(0)">
|
||||||
<a class="nav-link"><img src="../../../assets/scoreboard-btn.png"> Scoreboard</a>
|
<a class="nav-link"><img src="../../../assets/scoreboard-btn.png"> Scoreboard</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -43,19 +43,19 @@ export class WarDetailComponent {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.route.params
|
this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.filter(id => id != undefined)
|
.filter(id => id != undefined)
|
||||||
.flatMap(id => this.warService.getWar(id))
|
.flatMap(id => this.warService.getWar(id))
|
||||||
.subscribe(war => {
|
.subscribe(war => {
|
||||||
this.war = war;
|
this.war = war;
|
||||||
|
|
||||||
this.switchTab(0);
|
this.switchTab(0);
|
||||||
this.fractionStatsInitialized = false;
|
this.fractionStatsInitialized = false;
|
||||||
this.fractionFilterSelected = undefined;
|
this.fractionFilterSelected = undefined;
|
||||||
|
|
||||||
this.playerChart = ChartUtils.getSingleDataArray(Fraction.OPFOR, war.playersOpfor, Fraction.BLUFOR, war.playersBlufor);
|
this.playerChart = ChartUtils.getSingleDataArray(Fraction.OPFOR, war.playersOpfor, Fraction.BLUFOR, war.playersBlufor);
|
||||||
Object.assign(this, [this.playerChart]);
|
Object.assign(this, [this.playerChart]);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
switchTab(index: number) {
|
switchTab(index: number) {
|
||||||
|
|
|
@ -78,24 +78,24 @@ export class WarListComponent implements OnInit {
|
||||||
deleteWar(war: War) {
|
deleteWar(war: War) {
|
||||||
if (confirm('Soll die Schlacht ' + war.title + ' wirklich gelöscht werden?')) {
|
if (confirm('Soll die Schlacht ' + war.title + ' wirklich gelöscht werden?')) {
|
||||||
this.warService.deleteWar(war._id)
|
this.warService.deleteWar(war._id)
|
||||||
.subscribe((res) => {
|
.subscribe((res) => {
|
||||||
if (this.selectedWarId === war._id) {
|
if (this.selectedWarId === war._id) {
|
||||||
this.selectOverview('all');
|
this.selectOverview('all');
|
||||||
}
|
}
|
||||||
this.campaigns.splice(this.campaigns.indexOf(war), 1);
|
this.campaigns.splice(this.campaigns.indexOf(war), 1);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteCampaign(campaign) {
|
deleteCampaign(campaign) {
|
||||||
if (confirm('Soll die Kampagne ' + campaign.title + ' wirklich gelöscht werden?')) {
|
if (confirm('Soll die Kampagne ' + campaign.title + ' wirklich gelöscht werden?')) {
|
||||||
this.campaignService.deleteCampaign(campaign._id)
|
this.campaignService.deleteCampaign(campaign._id)
|
||||||
.subscribe((res) => {
|
.subscribe((res) => {
|
||||||
if (this.selectedWarId === campaign._id) {
|
if (this.selectedWarId === campaign._id) {
|
||||||
this.selectOverview('all');
|
this.selectOverview('all');
|
||||||
}
|
}
|
||||||
this.campaigns.splice(this.campaigns.indexOf(campaign), 1);
|
this.campaigns.splice(this.campaigns.indexOf(campaign), 1);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,14 +52,14 @@ export class WarSubmitComponent {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
this.warService.submitWar(this.war, file)
|
this.warService.submitWar(this.war, file)
|
||||||
.subscribe(war => {
|
.subscribe(war => {
|
||||||
this.router.navigate(['../war/' + war._id], {relativeTo: this.route});
|
this.router.navigate(['../war/' + war._id], {relativeTo: this.route});
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.error = error._body.error.message;
|
this.error = error._body.error.message;
|
||||||
this.showErrorLabel = true;
|
this.showErrorLabel = true;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return window.alert(`Logfile ist ein Pflichtfeld`);
|
return window.alert(`Logfile ist ein Pflichtfeld`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.overview {
|
.overview {
|
||||||
overflow: hidden!important;
|
overflow: hidden !important;
|
||||||
padding-top: 80px!important;
|
padding-top: 80px !important;
|
||||||
width: 20%;
|
width: 20%;
|
||||||
min-width: 280px;
|
min-width: 280px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ div.user-list-entry, a.user-list-entry {
|
||||||
background: lightgrey;
|
background: lightgrey;
|
||||||
}
|
}
|
||||||
|
|
||||||
span > a, span.glyphicon, span.icon-award{
|
span > a, span.glyphicon, span.icon-award {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,15 +40,15 @@ export class AwardUserComponent {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route.params
|
this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.flatMap(id => this.awardingService.getUserAwardings(id))
|
.flatMap(id => this.awardingService.getUserAwardings(id))
|
||||||
.subscribe(awards => {
|
.subscribe(awards => {
|
||||||
this.awards = awards;
|
this.awards = awards;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route.params
|
this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.subscribe(id => this.userId = id)
|
.subscribe(id => this.userId = id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,16 +79,16 @@ export class AwardUserComponent {
|
||||||
};
|
};
|
||||||
this.awardingService.addAwarding(award).subscribe(() => {
|
this.awardingService.addAwarding(award).subscribe(() => {
|
||||||
this.awardingService.getUserAwardings(this.userId)
|
this.awardingService.getUserAwardings(this.userId)
|
||||||
.subscribe(awards => {
|
.subscribe(awards => {
|
||||||
this.awards = awards;
|
this.awards = awards;
|
||||||
this.decoPreviewDisplay = 'none';
|
this.decoPreviewDisplay = 'none';
|
||||||
decorationField.value = undefined;
|
decorationField.value = undefined;
|
||||||
reasonField.value = previewImage.src = descriptionField.innerHTML = '';
|
reasonField.value = previewImage.src = descriptionField.innerHTML = '';
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showSuccessLabel = false;
|
this.showSuccessLabel = false;
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,13 +96,13 @@ export class AwardUserComponent {
|
||||||
deleteAwarding(awardingId) {
|
deleteAwarding(awardingId) {
|
||||||
this.awardingService.deleteAwarding(awardingId).subscribe((res) => {
|
this.awardingService.deleteAwarding(awardingId).subscribe((res) => {
|
||||||
this.awardingService.getUserAwardings(this.userId)
|
this.awardingService.getUserAwardings(this.userId)
|
||||||
.subscribe((awards) => {
|
.subscribe((awards) => {
|
||||||
this.awards = awards;
|
this.awards = awards;
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showSuccessLabel = false;
|
this.showSuccessLabel = false;
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,21 +45,21 @@ export class EditUserComponent {
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
||||||
this.subscription = this.route.params
|
this.subscription = this.route.params
|
||||||
.map(params => params['id'])
|
.map(params => params['id'])
|
||||||
.filter(id => id != undefined)
|
.filter(id => id != undefined)
|
||||||
.flatMap(id => this.userService.getUser(id))
|
.flatMap(id => this.userService.getUser(id))
|
||||||
.subscribe(user => {
|
.subscribe(user => {
|
||||||
if (!user.squadId) {
|
if (!user.squadId) {
|
||||||
user.squadId = "0";
|
user.squadId = "0";
|
||||||
this.ranksDisplay = 'none';
|
this.ranksDisplay = 'none';
|
||||||
} else {
|
} else {
|
||||||
this.rankService.findRanks('', user.squadId.fraction).subscribe(ranks => {
|
this.rankService.findRanks('', user.squadId.fraction).subscribe(ranks => {
|
||||||
this.ranks = ranks;
|
this.ranks = ranks;
|
||||||
this.ranksDisplay = 'block';
|
this.ranksDisplay = 'block';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.user = user;
|
this.user = user;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.squadService.findSquads().subscribe(squads => {
|
this.squadService.findSquads().subscribe(squads => {
|
||||||
this.squads = squads;
|
this.squads = squads;
|
||||||
|
@ -92,32 +92,32 @@ export class EditUserComponent {
|
||||||
|
|
||||||
if (this.user._id) {
|
if (this.user._id) {
|
||||||
this.userService.updateUser(updateObject)
|
this.userService.updateUser(updateObject)
|
||||||
.subscribe(user => {
|
.subscribe(user => {
|
||||||
if (!user.squad) {
|
if (!user.squad) {
|
||||||
user.squad = '0';
|
user.squad = '0';
|
||||||
}
|
}
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.showSuccessLabel = true;
|
this.showSuccessLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showSuccessLabel = false;
|
this.showSuccessLabel = false;
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.userService.submitUser(updateObject)
|
this.userService.submitUser(updateObject)
|
||||||
.subscribe(user => {
|
.subscribe(user => {
|
||||||
this.router.navigate(['..'], {relativeTo: this.route});
|
this.router.navigate(['..'], {relativeTo: this.route});
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
// duplicated user error message
|
// duplicated user error message
|
||||||
if (error._body.includes('duplicate')) {
|
if (error._body.includes('duplicate')) {
|
||||||
this.error = "Benutzername existiert bereits";
|
this.error = "Benutzername existiert bereits";
|
||||||
this.showErrorLabel = true;
|
this.showErrorLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showErrorLabel = false;
|
this.showErrorLabel = false;
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ export class UserListComponent implements OnInit {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
||||||
limit = 20;
|
limit = 20;
|
||||||
|
|
||||||
readonly fraction = Fraction;
|
readonly fraction = Fraction;
|
||||||
|
|
||||||
constructor(private userService: UserService,
|
constructor(private userService: UserService,
|
||||||
|
@ -45,17 +45,17 @@ export class UserListComponent implements OnInit {
|
||||||
this.users$ = this.userService.users$;
|
this.users$ = this.userService.users$;
|
||||||
|
|
||||||
const paramsStream = this.route.queryParams
|
const paramsStream = this.route.queryParams
|
||||||
.map(params => decodeURI(params['query'] || ''))
|
.map(params => decodeURI(params['query'] || ''))
|
||||||
.do(query => this.searchTerm.setValue(query));
|
.do(query => this.searchTerm.setValue(query));
|
||||||
|
|
||||||
const searchTermStream = this.searchTerm.valueChanges
|
const searchTermStream = this.searchTerm.valueChanges
|
||||||
.debounceTime(400)
|
.debounceTime(400)
|
||||||
.do(query => this.adjustBrowserUrl(query));
|
.do(query => this.adjustBrowserUrl(query));
|
||||||
|
|
||||||
Observable.merge(paramsStream, searchTermStream)
|
Observable.merge(paramsStream, searchTermStream)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.switchMap(query => this.filterUsers())
|
.switchMap(query => this.filterUsers())
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
openNewUserForm() {
|
openNewUserForm() {
|
||||||
|
@ -76,8 +76,8 @@ export class UserListComponent implements OnInit {
|
||||||
deleteUser(user: User) {
|
deleteUser(user: User) {
|
||||||
if (confirm('Soll der Teilnehmer "' + user.username + '" wirklich gelöscht werden?')) {
|
if (confirm('Soll der Teilnehmer "' + user.username + '" wirklich gelöscht werden?')) {
|
||||||
this.userService.deleteUser(user)
|
this.userService.deleteUser(user)
|
||||||
.subscribe((res) => {
|
.subscribe((res) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ export class ChartUtils {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getMultiDataArray(...args: string[]) : any[] {
|
public static getMultiDataArray(...args: string[]): any[] {
|
||||||
const obj = [];
|
const obj = [];
|
||||||
for (let i = 0, arg; arg = args[i]; i++) {
|
for (let i = 0, arg; arg = args[i]; i++) {
|
||||||
obj.push({
|
obj.push({
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
export class PlayerUtils {
|
||||||
|
|
||||||
|
public static isSteamUUID(input: string): boolean {
|
||||||
|
const steamUIDPattern = new RegExp("[0-9]{17}");
|
||||||
|
return steamUIDPattern.test(input)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue