Compare commits

...

4 Commits

16 changed files with 100 additions and 87 deletions

View File

@ -63,6 +63,7 @@ const corsOptions = {
methods: ['GET'],
optionsSuccessStatus: 200,
};
app.use(cors(corsOptions));
app.use(favicon(path.join(__dirname + '/..', 'public', 'favicon.ico')));
@ -146,25 +147,40 @@ if (process.env.NODE_ENV === config.test.unit.env || process.env.NODE_ENV === co
});
} else {
mongoose.connect(config.database.uri + config.database.db, {useNewUrlParser: true}).then((db) => {
let cronWorkerPID;
if (cluster.isMaster) {
// Fork workers
for (let i = 0; i < numWorkers; i++) {
cluster.fork();
if (i === 0) {
const spawnedWorker = cluster.fork({START_CRON: true});
cronWorkerPID = spawnedWorker.process.pid;
} else {
cluster.fork();
}
}
logger(`Master ${process.pid} is running. Forking ${numWorkers} workers`);
// Check if worker id is died
cluster.on('exit', (worker, code, signal) => {
logger(`worker ${worker.process.pid} died`);
if (worker.process.pid === cronWorkerPID) {
const spawnedWorker = cluster.fork({START_CRON: true});
cronWorkerPID = spawnedWorker.process.pid;
} else {
cluster.fork();
}
});
} else {
app.listen(config.port, (err) => {
if (err !== undefined) {
if (err) {
error(`Error on startup ${err}`);
} else {
logger(`Worker ${process.pid} started. Listening on port ${config.port}`);
signatureCronJob.start();
backupCronJob.start();
if (process.env.START_CRON) {
logger(`Attaching cronJobs to cluster worker ${process.pid}`);
signatureCronJob.start();
backupCronJob.start();
}
}
});
}

View File

@ -11,7 +11,6 @@
<option name="RIGHT_MARGIN" value="120" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
<option name="SPACE_WITHIN_BRACKETS" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />

View File

@ -21,8 +21,8 @@ import {SnackBarService} from './services/user-interface/snack-bar/snack-bar.ser
import {HttpClientModule} from '@angular/common/http';
import {SpinnerService} from './services/user-interface/spinner/spinner.service';
import {MatSelectModule, MatSnackBarModule} from '@angular/material';
import {HttpClient} from './services/http-client';
import {SettingsService} from './services/settings.service';
import {HttpGateway} from './services/http-gateway';
@NgModule({
imports: [
@ -38,7 +38,7 @@ import {SettingsService} from './services/settings.service';
],
providers: [
HttpClient,
HttpGateway,
LoginService,
LoginGuardSQL,
LoginGuardHL,

View File

@ -3,7 +3,7 @@ import {AppUser} from '../../models/model-interfaces';
import {Observable} from 'rxjs/Observable';
import {EDIT, LOAD, REMOVE, Store} from '../stores/generic-store';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class AppUserService {
@ -12,13 +12,13 @@ export class AppUserService {
private appUserStore = new Store<AppUser>();
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
this.users$ = this.appUserStore.items$;
}
getUsers() {
this.http.get(this.config.apiAppUserPath)
this.httpGateway.get(this.config.apiAppUserPath)
.map(res => res.json())
.do((users) => {
this.appUserStore.dispatch({type: LOAD, data: users});
@ -29,7 +29,7 @@ export class AppUserService {
}
updateUser(user: AppUser) {
return this.http.patch(this.config.apiAppUserPath + user._id, user)
return this.httpGateway.patch(this.config.apiAppUserPath + user._id, user)
.map(res => res.json())
.do(savedUser => {
const action = {type: EDIT, data: savedUser};
@ -38,7 +38,7 @@ export class AppUserService {
}
deleteUser(user) {
return this.http.delete(this.config.apiAppUserPath + user._id)
return this.httpGateway.delete(this.config.apiAppUserPath + user._id)
.do(res => {
this.appUserStore.dispatch({type: REMOVE, data: user});
});

View File

@ -1,14 +1,14 @@
import {Injectable} from '@angular/core';
import {Award} from '../../models/model-interfaces';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class AwardingService {
hasUnprocessedAwards = false;
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
}
@ -18,24 +18,24 @@ export class AwardingService {
.concat('&fractFilter=').concat(fraction)
.concat('&userId=').concat(userId)
.concat('&squadId=').concat(squadId);
return this.http.get(getUrl).map(res => res.json());
return this.httpGateway.get(getUrl).map(res => res.json());
}
addAwarding(award: Award) {
return this.http.post(this.config.apiAwardPath, award);
return this.httpGateway.post(this.config.apiAwardPath, award);
}
updateAward(award) {
return this.http.patch(this.config.apiAwardPath + '/' + award._id, award)
return this.httpGateway.patch(this.config.apiAwardPath + '/' + award._id, award)
.map(res => res.json());
}
requestAwarding(award: Award) {
return this.http.post(this.config.apiRequestAwardPath, award);
return this.httpGateway.post(this.config.apiRequestAwardPath, award);
}
deleteAwarding(awardingId) {
return this.http.delete(this.config.apiAwardPath + '/' + awardingId);
return this.httpGateway.delete(this.config.apiAwardPath + '/' + awardingId);
}
getUnconfirmedAwards(fraction?: string) {

View File

@ -4,7 +4,7 @@ import {RequestMethod, RequestOptions, URLSearchParams} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {ADD, EDIT, LOAD, REMOVE, Store} from '../stores/generic-store';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class DecorationService {
@ -13,7 +13,7 @@ export class DecorationService {
decorationStore = new Store<Decoration>();
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
this.decorations$ = this.decorationStore.items$;
}
@ -25,7 +25,7 @@ export class DecorationService {
searchParams.append('fractFilter', fractionFilter);
}
this.http.get(this.config.apiDecorationPath, searchParams)
this.httpGateway.get(this.config.apiDecorationPath, searchParams)
.map(res => res.json())
.do((squads) => {
this.decorationStore.dispatch({type: LOAD, data: squads});
@ -36,7 +36,7 @@ export class DecorationService {
}
getDecoration(id: number | string): Observable<Decoration> {
return this.http.get(this.config.apiDecorationPath + id)
return this.httpGateway.get(this.config.apiDecorationPath + id)
.map(res => res.json());
}
@ -76,7 +76,7 @@ export class DecorationService {
method: requestMethod,
});
return this.http.request(requestUrl, options)
return this.httpGateway.request(requestUrl, options)
.map(res => res.json())
.do(savedDecoration => {
const action = {type: accessType, data: savedDecoration};
@ -85,7 +85,7 @@ export class DecorationService {
}
deleteDecoration(decoration: Decoration) {
return this.http.delete(this.config.apiDecorationPath + decoration._id)
return this.httpGateway.delete(this.config.apiDecorationPath + decoration._id)
.do(res => {
this.decorationStore.dispatch({type: REMOVE, data: decoration});
});

View File

@ -1,19 +1,19 @@
import {Injectable} from '@angular/core';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {Promotion} from '../../models/model-interfaces';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class PromotionService {
hasUnprocessedPromotion = false;
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
}
getUnconfirmedPromotions(fraction?: string) {
return this.http.get(this.config.apiPromotionPath + '?inProgress=true&fractFilter=' + fraction)
return this.httpGateway.get(this.config.apiPromotionPath + '?inProgress=true&fractFilter=' + fraction)
.map(res => res.json());
}
@ -26,21 +26,21 @@ export class PromotionService {
}
getSquadPromotions(squadId: string) {
return this.http.get(this.config.apiPromotionPath + '?squadId=' + squadId)
return this.httpGateway.get(this.config.apiPromotionPath + '?squadId=' + squadId)
.map(res => res.json());
}
requestPromotion(promotion: Promotion) {
return this.http.post(this.config.apiPromotionPath, promotion);
return this.httpGateway.post(this.config.apiPromotionPath, promotion);
}
updatePromotion(promotion) {
return this.http.patch(this.config.apiPromotionPath + '/' + promotion._id, promotion)
return this.httpGateway.patch(this.config.apiPromotionPath + '/' + promotion._id, promotion)
.map(res => res.json());
}
deletePromotion(promotionId) {
return this.http.delete(this.config.apiPromotionPath + promotionId);
return this.httpGateway.delete(this.config.apiPromotionPath + promotionId);
}
}

View File

@ -4,7 +4,7 @@ import {RequestMethod, RequestOptions, URLSearchParams} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {ADD, EDIT, LOAD, REMOVE, Store} from '../stores/generic-store';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class RankService {
@ -13,7 +13,7 @@ export class RankService {
rankStore = new Store<Rank>();
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
this.ranks$ = this.rankStore.items$;
}
@ -25,7 +25,7 @@ export class RankService {
searchParams.append('fractFilter', fractionFilter);
}
this.http.get(this.config.apiRankPath, searchParams)
this.httpGateway.get(this.config.apiRankPath, searchParams)
.map(res => res.json())
.do((ranks) => {
this.rankStore.dispatch({type: LOAD, data: ranks});
@ -36,7 +36,7 @@ export class RankService {
}
getRank(id: number | string): Observable<Rank> {
return this.http.get(this.config.apiRankPath + id)
return this.httpGateway.get(this.config.apiRankPath + id)
.map(res => res.json());
}
@ -77,7 +77,7 @@ export class RankService {
method: requestMethod
});
return this.http.request(requestUrl, options)
return this.httpGateway.request(requestUrl, options)
.map(res => res.json())
.do(savedRank => {
const action = {type: accessType, data: savedRank};
@ -89,7 +89,7 @@ export class RankService {
}
deleteRank(rank: Rank) {
return this.http.delete(this.config.apiRankPath + rank._id)
return this.httpGateway.delete(this.config.apiRankPath + rank._id)
.do(res => {
this.rankStore.dispatch({type: REMOVE, data: rank});
});

View File

@ -4,7 +4,7 @@ import {RequestMethod, RequestOptions, URLSearchParams} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {ADD, EDIT, LOAD, REMOVE, Store} from '../stores/generic-store';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class SquadService {
@ -13,7 +13,7 @@ export class SquadService {
squadStore = new Store<Squad>();
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
this.squads$ = this.squadStore.items$;
}
@ -23,7 +23,7 @@ export class SquadService {
searchParams.append('q', query);
searchParams.append('fractFilter', fractionFilter);
this.http.get(this.config.apiSquadPath, searchParams)
this.httpGateway.get(this.config.apiSquadPath, searchParams)
.map(res => res.json())
.do((squads) => {
this.squadStore.dispatch({type: LOAD, data: squads});
@ -34,7 +34,7 @@ export class SquadService {
}
getSquad(id: number | string): Observable<Squad> {
return this.http.get(this.config.apiSquadPath + id)
return this.httpGateway.get(this.config.apiSquadPath + id)
.map(res => res.json());
}
@ -74,7 +74,7 @@ export class SquadService {
method: requestMethod
});
return this.http.request(requestUrl, options)
return this.httpGateway.request(requestUrl, options)
.map(res => res.json())
.do(savedSquad => {
const action = {type: accessType, data: savedSquad};
@ -83,7 +83,7 @@ export class SquadService {
}
deleteSquad(squad: Squad) {
return this.http.delete(this.config.apiSquadPath + squad._id)
return this.httpGateway.delete(this.config.apiSquadPath + squad._id)
.do(res => {
this.squadStore.dispatch({type: REMOVE, data: squad});
});

View File

@ -4,7 +4,7 @@ import {URLSearchParams} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {ADD, EDIT, LOAD, REMOVE, Store} from '../stores/generic-store';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class UserService {
@ -15,7 +15,7 @@ export class UserService {
totalCount = 0;
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
this.users$ = this.userStore.items$;
}
@ -39,7 +39,7 @@ export class UserService {
searchParams.append('limit', limit);
searchParams.append('offset', offset);
this.http.get(this.config.apiUserPath, searchParams)
this.httpGateway.get(this.config.apiUserPath, searchParams)
.do((res) => {
const headerCount = parseInt(res.headers.get('x-total-count'), 10);
if (headerCount) {
@ -54,12 +54,12 @@ export class UserService {
}
getUser(_id: number | string): Observable<User> {
return this.http.get(this.config.apiUserPath + _id)
return this.httpGateway.get(this.config.apiUserPath + _id)
.map(res => res.json());
}
submitUser(user) {
return this.http.post(this.config.apiUserPath, user)
return this.httpGateway.post(this.config.apiUserPath, user)
.map(res => res.json())
.do(savedUser => {
const action = {type: ADD, data: savedUser};
@ -68,7 +68,7 @@ export class UserService {
}
updateUser(user) {
return this.http.put(this.config.apiUserPath + user._id, user)
return this.httpGateway.put(this.config.apiUserPath + user._id, user)
.map(res => res.json())
.do(savedUser => {
const action = {type: EDIT, data: savedUser};
@ -77,7 +77,7 @@ export class UserService {
}
deleteUser(user) {
return this.http.delete(this.config.apiUserPath + user._id)
return this.httpGateway.delete(this.config.apiUserPath + user._id)
.do(res => {
this.userStore.dispatch({type: REMOVE, data: user});
});

View File

@ -4,7 +4,7 @@ import {Router} from '@angular/router';
import {CookieService} from 'ngx-cookie-service';
@Injectable()
export class HttpClient {
export class HttpGateway {
constructor(private router: Router,
private http: Http,

View File

@ -1,10 +1,10 @@
import {Injectable} from '@angular/core';
import {Campaign} from '../../models/model-interfaces';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {ADD, EDIT, LOAD, REMOVE, Store} from '../stores/generic-store';
import {Observable} from 'rxjs';
import {RequestMethod, RequestOptions} from '@angular/http';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class CampaignService {
@ -13,24 +13,24 @@ export class CampaignService {
campaignStore = new Store<Campaign>();
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
this.campaigns$ = this.campaignStore.items$;
}
getAllCampaigns() {
return this.http.get(this.config.apiCampaignPath)
return this.httpGateway.get(this.config.apiCampaignPath)
.map(res => res.json())
.do((ranks) => this.campaignStore.dispatch({type: LOAD, data: ranks}));
}
getCampaign(id: string) {
return this.http.get(`${this.config.apiCampaignPath}/${id}`)
return this.httpGateway.get(`${this.config.apiCampaignPath}/${id}`)
.map(res => res.json());
}
getCampaignByWarId(warId) {
return this.http.get(`${this.config.apiCampaignPath}/with/war/${warId}`)
return this.httpGateway.get(`${this.config.apiCampaignPath}/with/war/${warId}`)
.map((res) => res.json());
}
@ -54,7 +54,7 @@ export class CampaignService {
method: requestMethod
});
return this.http.request(requestUrl, options)
return this.httpGateway.request(requestUrl, options)
.map(res => res.json())
.do(savedCampaign => {
const action = {type: accessType, data: savedCampaign};
@ -63,7 +63,7 @@ export class CampaignService {
}
deleteCampaign(campaign: Campaign) {
return this.http.delete(this.config.apiCampaignPath + '/' + campaign._id)
return this.httpGateway.delete(this.config.apiCampaignPath + '/' + campaign._id)
.do(res => this.campaignStore.dispatch({type: REMOVE, data: campaign}));
}
}

View File

@ -1,38 +1,38 @@
import {Injectable} from '@angular/core';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {URLSearchParams} from '@angular/http';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class LogsService {
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
}
getFullLog(warId: string) {
return this.http.get(this.config.apiLogsPath + '/' + warId)
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId)
.map(res => res.json());
}
getBudgetLogs(warId: string, fraction = '') {
const params = new URLSearchParams();
params.append('fraction', fraction);
return this.http.get(this.config.apiLogsPath + '/' + warId + '/budget', params)
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/budget', params)
.map(res => res.json());
}
getRespawnLogs(warId: string, playerName = '') {
const params = new URLSearchParams();
params.append('player', playerName);
return this.http.get(this.config.apiLogsPath + '/' + warId + '/respawn', params)
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/respawn', params)
.map(res => res.json());
}
getPointsLogs(warId: string, fraction = '') {
const params = new URLSearchParams();
params.append('fraction', fraction);
return this.http.get(this.config.apiLogsPath + '/' + warId + '/points', params)
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/points', params)
.map(res => res.json());
}
@ -43,7 +43,7 @@ export class LogsService {
params.append('fraction', fraction);
params.append('stabilized', stabilizedOnly ? 'true' : '');
params.append('revive', reviveOnly ? 'true' : '');
return this.http.get(this.config.apiLogsPath + '/' + warId + '/revive', params)
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/revive', params)
.map(res => res.json());
}
@ -54,7 +54,7 @@ export class LogsService {
params.append('fraction', fraction);
params.append('friendlyFire', friendlyFireOnly ? 'true' : '');
params.append('noFriendlyFire', notFriendlyFireOnly ? 'true' : '');
return this.http.get(this.config.apiLogsPath + '/' + warId + '/kills', params)
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/kills', params)
.map(res => res.json());
}
@ -63,7 +63,7 @@ export class LogsService {
params.append('driver', driverName);
params.append('passenger', passengerName);
params.append('fraction', fraction);
return this.http.get(this.config.apiLogsPath + '/' + warId + '/transport', params)
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/transport', params)
.map(res => res.json());
}
@ -73,8 +73,7 @@ export class LogsService {
params.append('fraction', fraction);
params.append('capture', captureOnly ? 'true' : '');
params.append('defend', defendOnly ? 'true' : '');
return this.http.get(this.config.apiLogsPath + '/' + warId + '/flag', params)
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/flag', params)
.map(res => res.json());
}
}

View File

@ -1,23 +1,21 @@
import {Injectable} from '@angular/core';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class PlayerService {
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
}
getCampaignPlayer(campaignId: string, playerName: string) {
return this.http.get(this.config.apiPlayersPath + '/single/' + campaignId + '/' + playerName)
return this.httpGateway.get(this.config.apiPlayersPath + '/single/' + campaignId + '/' + playerName)
.map(res => res.json());
}
getCampaignHighscore(campaignId: string) {
return this.http.get(this.config.apiPlayersPath + '/ranking/' + campaignId)
return this.httpGateway.get(this.config.apiPlayersPath + '/ranking/' + campaignId)
.map(res => res.json());
}
}

View File

@ -1,9 +1,9 @@
import {Injectable} from '@angular/core';
import {War} from '../../models/model-interfaces';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
import {ADD, EDIT, LOAD, REMOVE, Store} from '../stores/generic-store';
import {Observable} from 'rxjs';
import {HttpGateway} from '../http-gateway';
@Injectable()
export class WarService {
@ -12,7 +12,7 @@ export class WarService {
warStore = new Store<War>();
constructor(private http: HttpClient,
constructor(private httpGateway: HttpGateway,
private config: AppConfig) {
this.wars$ = this.warStore.items$;
}
@ -22,13 +22,13 @@ export class WarService {
if (campaignId) {
targetUrl += `?campaignId=${campaignId}`
}
return this.http.get(targetUrl)
return this.httpGateway.get(targetUrl)
.map(res => res.json())
.do((wars) => this.warStore.dispatch({type: LOAD, data: wars}));
}
getWar(warId: string) {
return this.http.get(this.config.apiWarPath + '/' + warId)
return this.httpGateway.get(this.config.apiWarPath + '/' + warId)
.map(res => res.json());
}
@ -45,19 +45,19 @@ export class WarService {
body.append('log', logFile, logFile.name);
}
return this.http.post(this.config.apiWarPath, body)
return this.httpGateway.post(this.config.apiWarPath, body)
.map(res => res.json())
.do((newWar) => this.warStore.dispatch({type: ADD, data: newWar}));
}
updateWar(war: War) {
return this.http.patch(this.config.apiWarPath + '/' + war._id, war)
return this.httpGateway.patch(this.config.apiWarPath + '/' + war._id, war)
.map(res => res.json())
.do((updatedWar) => this.warStore.dispatch({type: EDIT, data: updatedWar}));
}
deleteWar(war: War) {
return this.http.delete(this.config.apiWarPath + '/' + war._id)
return this.httpGateway.delete(this.config.apiWarPath + '/' + war._id)
.do((emptyRes) => this.warStore.dispatch({type: REMOVE, data: war}));
}
}

View File

@ -46,10 +46,11 @@ export class StatisticComponent implements OnInit {
const id = idFetchPattern.exec(url)[1];
if (id === 'all') {
this.switchCampaign({_id: id});
}
const filteredCampaigns = this.campaigns.filter(c => c._id === id);
if (filteredCampaigns.length === 1) {
this.switchCampaign(filteredCampaigns[0]);
} else {
const filteredCampaigns = this.campaigns.filter(c => c._id === id);
if (filteredCampaigns.length === 1) {
this.switchCampaign(filteredCampaigns[0]);
}
}
} else if (url.includes('right:war')) {
const id = idFetchPattern.exec(url)[1];