From 5925872ac82f0c21c9a06d9505dc509dd79cb662 Mon Sep 17 00:00:00 2001 From: Humenius Date: Sat, 30 May 2020 19:32:12 +0200 Subject: [PATCH] Move SinusBotService to backend --- backend/src/app.controller.ts | 12 ++- backend/src/app.module.ts | 3 +- backend/src/models/TableEntry.ts | 4 + backend/src/models/TunakillLogin.ts | 5 ++ backend/src/models/TunakillUser.ts | 5 ++ backend/src/services/sinusbot.service.ts | 101 +++++++++++++++++++++++ frontend/src/App.tsx | 18 +--- frontend/src/services/SinusBotService.ts | 40 --------- 8 files changed, 129 insertions(+), 59 deletions(-) create mode 100644 backend/src/models/TableEntry.ts create mode 100644 backend/src/models/TunakillLogin.ts create mode 100644 backend/src/models/TunakillUser.ts create mode 100644 backend/src/services/sinusbot.service.ts delete mode 100644 frontend/src/services/SinusBotService.ts diff --git a/backend/src/app.controller.ts b/backend/src/app.controller.ts index cce879e..da6b2b2 100644 --- a/backend/src/app.controller.ts +++ b/backend/src/app.controller.ts @@ -1,12 +1,22 @@ import { Controller, Get } from '@nestjs/common'; import { AppService } from './app.service'; +import { TableEntry } from "./models/TableEntry"; +import { SinusBotService } from "./services/sinusbot.service"; @Controller() export class AppController { - constructor(private readonly appService: AppService) {} + constructor( + private readonly appService: AppService, + private readonly sinusBotService: SinusBotService + ) {} @Get() getHello(): string { return this.appService.getHello(); } + + @Get() + async getStats(): Promise { + return await this.sinusBotService.fetchStats(); + } } diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 8662803..b52d41f 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -1,10 +1,11 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { SinusBotService } from "./services/sinusbot.service"; @Module({ imports: [], controllers: [AppController], - providers: [AppService], + providers: [AppService, SinusBotService], }) export class AppModule {} diff --git a/backend/src/models/TableEntry.ts b/backend/src/models/TableEntry.ts new file mode 100644 index 0000000..18eb91d --- /dev/null +++ b/backend/src/models/TableEntry.ts @@ -0,0 +1,4 @@ +export interface TableEntry { + name: string; + onlineTime: string; +} diff --git a/backend/src/models/TunakillLogin.ts b/backend/src/models/TunakillLogin.ts new file mode 100644 index 0000000..8aa5e0c --- /dev/null +++ b/backend/src/models/TunakillLogin.ts @@ -0,0 +1,5 @@ +export interface TunakillLogin { + username: string; + password: string; + botId: string; +} diff --git a/backend/src/models/TunakillUser.ts b/backend/src/models/TunakillUser.ts new file mode 100644 index 0000000..85edb8a --- /dev/null +++ b/backend/src/models/TunakillUser.ts @@ -0,0 +1,5 @@ +export interface TunakillUser { + name: string; + time: number; + uid: string; +} diff --git a/backend/src/services/sinusbot.service.ts b/backend/src/services/sinusbot.service.ts new file mode 100644 index 0000000..340e934 --- /dev/null +++ b/backend/src/services/sinusbot.service.ts @@ -0,0 +1,101 @@ +import { TableEntry } from "../models/TableEntry"; +import { TunakillUser } from "../models/TunakillUser"; +import { Injectable } from "@nestjs/common"; +import {TunakillLogin} from "../models/TunakillLogin"; + +@Injectable() +export class SinusBotService { + private host = process.env.HOST + private botId = process.env.SINUSBOT_BOTID; + + private tunaKillURL = `${this.host}/api/v1/bot/i/${this.botId}/event/tunakill_rank_all_user`; + private loginURL = `${this.host}/api/v1/bot/login`; + private credentials = { + username: process.env.SINUSBOT_USER, + password: process.env.SINUSBOT_PASSWORD + } + private bearer: string; + + public async fetchStats(): Promise { + if (this.bearer === null) { + this.bearer = await this.login().catch(error => error.message); + } + + return await fetch(this.tunaKillURL) + .then(res => res.json()) + .then(data => this.consumeTunakillResponse(data)); + } + + /** + * Returns bearer token if login was successful + */ + private async login(): Promise { + const body: TunakillLogin = { + botId: this.botId, + username: this.credentials.password, + password: this.credentials.username, + } + + return await fetch(this.loginURL, this.requestConfig(JSON.stringify(body))) + .then(res => { + if (res.ok && res.body !== null) { + return res.json(); + } else { + throw new Error('Response is invalid.'); + } + }) + .then(data => { + if (data.token !== null) { + return data.token; + } else { + throw new Error('Token in response does not exist.'); + } + }); + } + + requestConfig = (body?: string, bearerToken?: string): RequestInit => { + return { + method: 'POST', + body: body, + headers: { + 'Content-Type': 'application/json', + 'User-Agent': 'HumeniusTSRankingBackend/0.0.1', + 'Authorization': `Bearer ${bearerToken}` + } + }; + } + + private consumeTunakillResponse(data: any): TableEntry[] | undefined { + if (!(data !== null || data[0] !== null || data[0].data !== null)) { + return undefined; + } + + const response = data[0].data; + if (!(response.length > 0)) { + return undefined; + } + + return response + .map((user: TunakillUser) => { + if (user.name === "Server Query Admin") { return null; } + return { + name: user.name, + rawTime: user.time, + onlineTime: new Date(user.time * 1000) + .toISOString() + .substr(11, 8) + }; + }) + .sort((a: any, b: any) => { + if (a.rawTime < b.rawTime) { + return -1; + } + + if (a.rawTime > b.rawTime) { + return 1; + } + + return 0; + }); + } +} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 8129ddd..ed0a3bd 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -16,23 +16,7 @@ export default class App extends React.Component { } componentDidMount() { - fetch('https://sinusbot.humenius.me/api/v1/bot/i/51314e26-13a1-4779-b2ac-e36d493687d4/event/tunakill_rank_all_user') - .then(res => res.json()) - .then((data) => SinusBotService.consumeTunakillResponse(data)) - .then( - (result) => { - this.setState({ - isLoaded: true, - users: result - }); - }, - (error) => { - this.setState({ - isLoaded: true, - error: error - }); - } - ); + } render() { diff --git a/frontend/src/services/SinusBotService.ts b/frontend/src/services/SinusBotService.ts deleted file mode 100644 index ffb5266..0000000 --- a/frontend/src/services/SinusBotService.ts +++ /dev/null @@ -1,40 +0,0 @@ -import TableEntry from "../models/TableEntry"; -import TunaKillUser from "../models/TunaKillUser"; - -class SinusBotService { - public static consumeTunakillResponse(data: any): TableEntry[] | undefined { - if (!(data !== null || data[0] !== null || data[0].data !== null)) { - return undefined; - } - - const response = data[0].data; - if (!(response.length > 0)) { - return undefined; - } - - return response - .map((user: TunaKillUser) => { - if (user.name === "Server Query Admin") { return null; } - return { - name: user.name, - rawTime: user.time, - onlineTime: new Date(user.time * 1000) - .toISOString() - .substr(11, 8) - }; - }) - .sort((a: any, b: any) => { - if (a.rawTime < b.rawTime) { - return -1; - } - - if (a.rawTime > b.rawTime) { - return 1; - } - - return 0; - }); - } -} - -export default SinusBotService;