diff --git a/LICENSE.md b/LICENSE.md index 4dc11eca968a0b1931fd904c53f9184876cf683d..4c1034a1f7f175e619d83b56eec67a85461fc228 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2018-2019 Benedikt Magnus +Copyright (c) 2018-2021 Benedikt Magnus Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/locale/de-DE.commands.json b/locale/de-DE.commands.json index 6f4baec22bda0900f1e41ac110001dbef15f7d23..46f6fe31fc35e4445e6267091ca9498ac38f8d2c 100644 --- a/locale/de-DE.commands.json +++ b/locale/de-DE.commands.json @@ -36,6 +36,12 @@ "Tag" ] }, + "goodEvening": { + "commands": [ + "guten Abend", + "Abend" + ] + }, "goodMorning": { "commands": [ "guten Morgen", @@ -86,6 +92,14 @@ "maybe": { "commands": ["vielleicht", "vllt", "eventuell", "evtl"] }, + "moddingStatus": + { + "commands": [ + "Wichtelstatus", + "Status" + ], + "info": "Gibt Informationen zum aktuellen Status des Wichtelns aus." + }, "no": { "commands": ["nein", "ne", "nö", "ausgeschlossen", "auf keinen Fall"] }, @@ -96,7 +110,26 @@ "sternenrose": { "commands": ["sternenrose"] }, + "thankYou": { + "commands": [ + "Danke", + "Dankeschön", + "Dankesehr", + "Danke dir", + "Vielen Dank", + "Großen Dank" + ] + }, "yes": { "commands": ["ja", "jap", "jawohl", "okay", "ok", "meinetwegen"] + }, + "yourAreWelcome": { + "commands": [ + "Bitte", + "Bittesehr", + "Bitte sehr", + "Bitteschön", + "Bitte schön" + ] } } diff --git a/locale/de-DE.texts.json b/locale/de-DE.texts.json index 446d00c505d8ffa2dfb726ac3bd564b8ab79d72f..0401117030d05a5ec3bfacb84b6f0e8012e0ab10 100644 --- a/locale/de-DE.texts.json +++ b/locale/de-DE.texts.json @@ -14,6 +14,7 @@ "deregistration": "Schade, {contact.nickname}! Ich hab dich vom Wichteln abgemeldet. Wenn du wieder mitmachen möchtest, schreibe „registrieren“.", "deregistrationCancelled": "Puh, nochmal Glück gehabt! Schön, dass du dabei bleibst!", "goodAfternoon": "Guten Tag, {contact.nickname}!", + "goodEvening": "Guten Abend, {contact.nickname}!", "goodMorning": "Guten Morgen, {contact.nickname}!", "goodNight": "Schlaf schön, {contact.nickname}!", "hello": "Hallööö, {contact.nickname}!", @@ -35,6 +36,9 @@ "notUnderstood": "Häää? Probiers nochmal.", "oldInformation": "Dies findet sich aktuell dazu in meiner Datenbank:\n>>> {var.informationValue}", "moderationNeedHelp": "<@&{var.moderationRoleId}> Der Wichtel {contact.nickname} ({contact.tag}) bittet um Hilfe.", + "moderationStatus": "**Status des Wichtelns {var.currentEventName}**\nAktuelle Phase: {var.eventPhaseString}\n\nAnzahl Teilnehmer: {var.contactCount}\nDavon vollständig registriert: {var.waitingMemberCount}\n\nBewichtelungsarten:\nAls Wichtelpate: {var.analogueGiverCount} mal analog, {var.digitalGiverCount} mal digital, {var.allGiverCount} mal beides\nAls Wichtelkind: {var.analogueTakerCount} mal analog, {var.digitalTakerCount} mal digital, {var.allTakerCount} mal beides\n\nPakete: {var.parcelSentCount} versendet, {var.parcelReceivedCount} erhalten", + "moderationStatusEventPhase": "{var.currentEventPhase}", + "moderationStatusEventPhaseWithNextPhase": "{var.currentEventPhase} ({var.nextEventPhase} startet am {date.day}.{date.month}.{date.year} um {date.hour}:{date.minute} Uhr)", "modsCalled": "Keine Sorge! Hilfe ist unterwegs! (So schnell sie kann...)", "profileName": "Name", "profileGiftType": "Bewichtelungsart", @@ -49,5 +53,7 @@ "registrationCancelled": "Schade! Wenn du es dir anders überlegen solltest, schreibe einfach „registrieren“, um den Anmeldevorgang erneut zu starten.", "registrationProfileOverview": "Hier noch einen Überblick über deinen aktuellen Steckbrief:", "sentComponentText": "Klicken! Du sollst klicken!", - "sternenrose": "Vielen Dank, Sterni! :)" + "sternenrose": "Vielen Dank, Sterni! :)", + "thankYouResponse": "Bitte!", + "yourAreWelcomeRespone": "🙂" } diff --git a/locale/de-DE.values.json b/locale/de-DE.values.json index c8ec56629af88bbd90ed91eaa6f63269b90182f5..c0aa406b6c6672027c5015161dbabebbed36a296 100644 --- a/locale/de-DE.values.json +++ b/locale/de-DE.values.json @@ -4,5 +4,9 @@ "giftTypeAll": "beides", "giftTypeNothing": "nichts", "no": "nein", - "yes": "ja" -} \ No newline at end of file + "yes": "ja", + "wichtelEventPhaseEnded": "Postwichteln", + "wichtelEventPhaseRegistration": "Registrierung", + "wichtelEventPhaseWaiting": "Präwichteln", + "wichtelEventPhaseWichteln": "Wichteln" +} diff --git a/scripts/utility/localisation.ts b/scripts/utility/localisation.ts index a7eacd6d590fb692f9fac8a4d2f78197305b61d8..6a5c812e0442ca062b82e58d27bce9064ad1f662 100644 --- a/scripts/utility/localisation.ts +++ b/scripts/utility/localisation.ts @@ -3,6 +3,7 @@ import * as fs from 'fs'; import Config from './config'; import GiftType from '../wichtelbot/types/giftType'; import TokenString from './tokenString'; +import WichtelEventPhase from './wichtelEvent'; export interface CommandInfo { @@ -17,6 +18,7 @@ interface Commands contacting: CommandInfo; deregistration: CommandInfo; goodAfternoon: CommandInfo; + goodEvening: CommandInfo; goodMorning: CommandInfo; goodNight: CommandInfo; hello: CommandInfo; @@ -25,10 +27,13 @@ interface Commands informationBothAnalogueAndDigital: CommandInfo; informationDigital: CommandInfo; maybe: CommandInfo; + moddingStatus: CommandInfo; no: CommandInfo; registration: CommandInfo; sternenrose: CommandInfo; + thankYou: CommandInfo; yes: CommandInfo; + yourAreWelcome: CommandInfo; } // TODO: Documentation @@ -49,6 +54,7 @@ interface Texts deregistration: TokenString; deregistrationCancelled: TokenString; goodAfternoon: TokenString; + goodEvening: TokenString; goodMorning: TokenString; goodNight: TokenString; hello: TokenString; @@ -70,6 +76,9 @@ interface Texts notUnderstood: TokenString; oldInformation: TokenString; moderationNeedHelp: TokenString; // TODO: This includes a Discord specific mention which is not portable to other implementations. + moderationStatus: TokenString; + moderationStatusEventPhase: TokenString; + moderationStatusEventPhaseWithNextPhase: TokenString; modsCalled: TokenString; profileName: TokenString; profileGiftType: TokenString; @@ -85,6 +94,8 @@ interface Texts registrationProfileOverview: TokenString; sentComponentText: TokenString; sternenrose: TokenString; + thankYouResponse: TokenString; + yourAreWelcomeRespone: TokenString; } interface Values @@ -95,6 +106,10 @@ interface Values giftTypeNothing: string; no: string; yes: string; + wichtelEventPhaseEnded: string, + wichtelEventPhaseRegistration: string, + wichtelEventPhaseWaiting: string, + wichtelEventPhaseWichteln: string, } export default abstract class Localisation @@ -148,27 +163,19 @@ export default abstract class Localisation public static translateGiftType (giftType: GiftType): string { - let result = ''; - switch (giftType) { case GiftType.Analogue: - result = Localisation._values.giftTypeAnalogue; - break; + return Localisation._values.giftTypeAnalogue; case GiftType.Digital: - result = Localisation._values.giftTypeDigital; - break; + return Localisation._values.giftTypeDigital; case GiftType.All: - result = Localisation._values.giftTypeAll; - break; + return Localisation._values.giftTypeAll; case GiftType.Nothing: - result = Localisation._values.giftTypeNothing; - break; + return Localisation._values.giftTypeNothing; default: throw TypeError('Invalid gift type to translate.'); } - - return result; } public static translateCountry (country: string): string @@ -180,4 +187,21 @@ export default abstract class Localisation return localisedCountry; } + + public static translateWichtelEventPhase (eventPhase: WichtelEventPhase): string + { + switch (eventPhase) + { + case WichtelEventPhase.Waiting: + return Localisation._values.wichtelEventPhaseWaiting; + case WichtelEventPhase.Registration: + return Localisation._values.wichtelEventPhaseRegistration; + case WichtelEventPhase.Wichteln: + return Localisation._values.wichtelEventPhaseWichteln; + case WichtelEventPhase.Ended: + return Localisation._values.wichtelEventPhaseEnded; + default: + throw TypeError('Invalid event phase to translate.'); + } + } } diff --git a/scripts/utility/utils.ts b/scripts/utility/utils.ts index 9a94e34a5fcfbd25ce51238f416d8ea6b26229ee..097217b0186c566d2c5f75108d2dbe5937bdce5c 100644 --- a/scripts/utility/utils.ts +++ b/scripts/utility/utils.ts @@ -1,3 +1,12 @@ +interface DateStrings +{ + year: string; + month: string; + day: string; + hour: string; + minute: string; +} + export default abstract class Utils { private static readonly defaultMaxWordLength = 100; @@ -7,6 +16,17 @@ export default abstract class Utils return Math.floor(new Date().getTime() / 1000); } + public static dateToDateStrings (unixTime: Date): DateStrings + { + return { + 'year': unixTime.getFullYear().toString(), + 'month': (unixTime.getMonth() + 1).toString(), + 'day': unixTime.getDate().toString(), + 'hour': unixTime.getHours().toString(), + 'minute': unixTime.getMinutes().toString().padStart(2, '0'), + }; + } + /** * Split text naturally between words if possible and removing unnecessary whitespaces at the break points. * @param text The text to split. diff --git a/scripts/wichtelbot/database/database.ts b/scripts/wichtelbot/database/database.ts index c417075cfb113b3d68b3f6a6785b8f073e139eb8..e69178b90ee37670f6e743727f998008e9460568 100644 --- a/scripts/wichtelbot/database/database.ts +++ b/scripts/wichtelbot/database/database.ts @@ -4,8 +4,12 @@ import { Exclusion, ExclusionData } from '../classes/exclusion'; import { Relationship, RelationshipData } from '../classes/relationship'; import Config from '../../utility/config'; import ContactType from '../types/contactType'; +import GiftType from '../types/giftType'; +import { GiftTypeStatistics } from './giftTypeStatistics'; import { InformationData } from '../classes/information'; import Member from '../classes/member'; +import { ParcelStatistics } from './parcelStatistics'; +import { State } from '../endpoint/definitions'; import Utils from '../../utility/utils'; import Sqlite = require('better-sqlite3'); @@ -167,6 +171,18 @@ export default class Database return result; } + /** + * Runs the given statement with the given parameters and returns the result as a number. + */ + private getCount (statement: Sqlite.Statement, parameters: unknown): number + { + statement.pluck(true); + + const count = statement.get(parameters) as number; + + return count; + } + public hasContact (contactId: string): boolean { const statement = this.mainDatabase.prepare( @@ -249,6 +265,15 @@ export default class Database ); } + public getContactCount (): number + { + const statement = this.mainDatabase.prepare( + 'SELECT COUNT(*) FROM contact WHERE contact.state != ?' + ); + + return this.getCount(statement, State.Nothing); // All contacts in this event phase have a state not equal to "Nothing". + } + /** * Will check if there is information in the database. * @param contactId The ID of the contact the information must be linked to. @@ -270,9 +295,7 @@ export default class Database // this makes it much easier: statement.pluck(true); - let result = !!statement.get(contactId); - - result = !!result; // Makes sure the value is definitely a boolean. + const result = !!statement.get(contactId); // Make sure the value is definitely a boolean. return result; } @@ -403,6 +426,15 @@ export default class Database runTransaction(); } + public getWaitingMemberCount (): number + { + const statement = this.mainDatabase.prepare( + 'SELECT COUNT(*) FROM contact WHERE contact.state = ?' + ); + + return this.getCount(statement, State.Waiting); + } + /** * Will return the type of contact that can be found for this ID. \ * If no contact is found, the given contactCoreData will be returned instead. @@ -546,6 +578,55 @@ export default class Database statement.run(parameters); } } + + public getGiftTypeStatistics (): GiftTypeStatistics + { + const statement = this.mainDatabase.prepare( + `SELECT + COUNT(CASE WHEN information.giftTypeAsGiver = :analogueGiftType THEN 1 END) AS analogueGiverCount, + COUNT(CASE WHEN information.giftTypeAsGiver = :digitalGiftType THEN 1 END) AS digitalGiverCount, + COUNT(CASE WHEN information.giftTypeAsGiver = :allGiftType THEN 1 END) AS allGiverCount, + COUNT(CASE WHEN information.giftTypeAsTaker = :analogueGiftType THEN 1 END) AS analogueTakerCount, + COUNT(CASE WHEN information.giftTypeAsTaker = :digitalGiftType THEN 1 END) AS digitalTakerCount, + COUNT(CASE WHEN information.giftTypeAsTaker = :allGiftType THEN 1 END) AS allTakerCount + FROM + information + LEFT JOIN + contact ON information.contactId = contact.id + WHERE + information.lastUpdateTime >= :currentEventRegistrationTime + AND contact.state = :waitingState` + ); + + const result = statement.get( + { + analogueGiftType: GiftType.Analogue, + digitalGiftType: GiftType.Digital, + allGiftType: GiftType.All, + currentEventRegistrationTime: Config.main.currentEvent.registration, + waitingState: State.Waiting, + } + ) as GiftTypeStatistics; + + return result; + } + + public getParcelStatistics (): ParcelStatistics + { + const statement = this.mainDatabase.prepare( + `SELECT + COUNT(CASE WHEN shippingDate != '' THEN 1 END) AS sentCount, + COUNT(CASE WHEN receivingDate != '' THEN 1 END) AS receivedCount + FROM + parcel + WHERE + wichtelEvent = ?` + ); + + const result = statement.get(Config.main.currentEvent.name) as ParcelStatistics; + + return result; + } } /* diff --git a/scripts/wichtelbot/database/giftTypeStatistics.ts b/scripts/wichtelbot/database/giftTypeStatistics.ts new file mode 100644 index 0000000000000000000000000000000000000000..c1a3f0e0e209ba0f0f1a456d4efc4edc4972dac6 --- /dev/null +++ b/scripts/wichtelbot/database/giftTypeStatistics.ts @@ -0,0 +1,9 @@ +export interface GiftTypeStatistics +{ + analogueGiverCount: number; + digitalGiverCount: number; + allGiverCount: number; + analogueTakerCount: number; + digitalTakerCount: number; + allTakerCount: number; +} diff --git a/scripts/wichtelbot/database/parcelStatistics.ts b/scripts/wichtelbot/database/parcelStatistics.ts new file mode 100644 index 0000000000000000000000000000000000000000..52c3fa98700ed96cf27a0245fcf81622942c2101 --- /dev/null +++ b/scripts/wichtelbot/database/parcelStatistics.ts @@ -0,0 +1,5 @@ +export interface ParcelStatistics +{ + sentCount: number; + receivedCount: number; +} diff --git a/scripts/wichtelbot/endpoint/definitions/state.ts b/scripts/wichtelbot/endpoint/definitions/state.ts index a03d151561390eef6323c8e395b1188c34bebd9c..9f4db0ab08504923b9f24415fbbad6c7f9a6cbf6 100644 --- a/scripts/wichtelbot/endpoint/definitions/state.ts +++ b/scripts/wichtelbot/endpoint/definitions/state.ts @@ -1,7 +1,7 @@ enum State { // As contact: - Nothing = '', // Is allowed to do nothing but stateless commands. + Nothing = 'nothing', // Is allowed to do nothing but stateless commands. New = 'new', Registration = 'registration', // As contact/member: diff --git a/scripts/wichtelbot/message/handlingDefinition.ts b/scripts/wichtelbot/message/handlingDefinition.ts index fef9e9347e368950b42330c3acd7be7b54be41df..76b857e67bdbc3b743be6f9b5f5a2ae372aab509 100644 --- a/scripts/wichtelbot/message/handlingDefinition.ts +++ b/scripts/wichtelbot/message/handlingDefinition.ts @@ -6,6 +6,7 @@ import GeneralModule from './modules/generalModule'; import GiftType from '../types/giftType'; import InformationModule from './modules/informationModule'; import Message from '../endpoint/definitions/message'; +import { ModerationModule } from './modules/moderationModule'; import State from "../endpoint/definitions/state"; import TokenString from '../../utility/tokenString'; @@ -49,16 +50,18 @@ export default class HandlingDefinition { protected generalModule: GeneralModule; protected informationModule: InformationModule; + protected moderationModule: ModerationModule; private get maxShortMessageLength (): number { return Math.floor(Config.main.maxMessageLength / 2); } - constructor (generalModule: GeneralModule, informationModule: InformationModule) + constructor (generalModule: GeneralModule, informationModule: InformationModule, moderationModule: ModerationModule) { this.generalModule = generalModule; this.informationModule = informationModule; + this.moderationModule = moderationModule; } public stateCommands: StateCommandDefinition[] = [ @@ -72,13 +75,21 @@ export default class HandlingDefinition result: Localisation.texts.modsCalled, }, { - command: Localisation.commands.goodAfternoon, - result: Localisation.texts.goodAfternoon, + command: Localisation.commands.sternenrose, + result: Localisation.texts.sternenrose, }, { command: Localisation.commands.goodMorning, result: Localisation.texts.goodMorning, }, + { + command: Localisation.commands.goodAfternoon, + result: Localisation.texts.goodAfternoon, + }, + { + command: Localisation.commands.goodEvening, + result: Localisation.texts.goodEvening, + }, { command: Localisation.commands.goodNight, result: Localisation.texts.goodNight, @@ -92,10 +103,13 @@ export default class HandlingDefinition result: Localisation.texts.maybeResponse, }, { - command: Localisation.commands.sternenrose, - result: Localisation.texts.sternenrose, + command: Localisation.commands.thankYou, + result: Localisation.texts.thankYouResponse, + }, + { + command: Localisation.commands.yourAreWelcome, + result: Localisation.texts.yourAreWelcomeRespone, } - // TODO: Response to "thank you". ], handlerFunction: async (message: Message, result: TokenString): Promise<void> => { @@ -476,6 +490,9 @@ export default class HandlingDefinition ]; public moderatorCommands: CommandDefinition[] = [ - + { + commandInfo: Localisation.commands.moddingStatus, + handlerFunction: async (message: Message): Promise<void> => this.moderationModule.sendStatus(message) + } ]; } diff --git a/scripts/wichtelbot/message/messageHandler.ts b/scripts/wichtelbot/message/messageHandler.ts index 0cd6a9c539c2a2af3cde50c669f14daed0a1f6f0..41574479aa0e1a2ee0e4f9c95ed048d99c96c38f 100644 --- a/scripts/wichtelbot/message/messageHandler.ts +++ b/scripts/wichtelbot/message/messageHandler.ts @@ -6,6 +6,7 @@ import Database from '../database/database'; import GeneralModule from './modules/generalModule'; import HandlingDefinition from './handlingDefinition'; import InformationModule from './modules/informationModule'; +import { ModerationModule } from './modules/moderationModule'; import StateCommand from './handlingTools/stateCommand'; import StateCommandMap from './handlingTools/stateCommandMap'; @@ -29,6 +30,7 @@ export default class MessageHandler protected generalModule: GeneralModule; protected informationModule: InformationModule; + protected moderationModule: ModerationModule; // In private messages: protected stateCommands = new StateCommandMap(); @@ -56,8 +58,9 @@ export default class MessageHandler this.generalModule = new GeneralModule(database); this.informationModule = new InformationModule(database); + this.moderationModule = new ModerationModule(database); - this.handlingDefinition = new HandlingDefinition(this.generalModule, this.informationModule); + this.handlingDefinition = new HandlingDefinition(this.generalModule, this.informationModule, this.moderationModule); this.applyHandlingDefinition(); } diff --git a/scripts/wichtelbot/message/modules/generalModule.ts b/scripts/wichtelbot/message/modules/generalModule.ts index a28942dfd4c27e64ed2ed62c43d13d5a7c632d07..f851f05e22173ad7fc27c661e7e0e3bc2f564afc 100644 --- a/scripts/wichtelbot/message/modules/generalModule.ts +++ b/scripts/wichtelbot/message/modules/generalModule.ts @@ -9,6 +9,7 @@ import Member from '../../classes/member'; import Message from '../../endpoint/definitions/message'; import State from '../../endpoint/definitions/state'; import TokenString from '../../../utility/tokenString'; +import Utils from '../../../utility/utils'; import WichtelEventPhase from '../../../utility/wichtelEvent'; /** @@ -69,12 +70,14 @@ export default class GeneralModule const registrationPhaseTime = new Date(nowInMs + randomAdditionInMs); + const registrationDateStrings = Utils.dateToDateStrings(registrationPhaseTime); + const parameters = new KeyValuePairList(); - parameters.addPair('year', registrationPhaseTime.getFullYear().toString()); - parameters.addPair('month', (registrationPhaseTime.getMonth() + 1).toString()); - parameters.addPair('day', registrationPhaseTime.getDate().toString()); - parameters.addPair('hour', registrationPhaseTime.getHours().toString()); - parameters.addPair('minute', registrationPhaseTime.getMinutes().toString().padStart(2, '0')); + parameters.addPair('year', registrationDateStrings.year); + parameters.addPair('month', registrationDateStrings.month); + parameters.addPair('day', registrationDateStrings.day); + parameters.addPair('hour', registrationDateStrings.hour); + parameters.addPair('minute', registrationDateStrings.minute); answer = Localisation.texts.contactingTooEarly.process(message.author, parameters); } diff --git a/scripts/wichtelbot/message/modules/moderationModule.ts b/scripts/wichtelbot/message/modules/moderationModule.ts new file mode 100644 index 0000000000000000000000000000000000000000..bd0367f1a19c9a898dfc0b556f11e2ecd0612dc1 --- /dev/null +++ b/scripts/wichtelbot/message/modules/moderationModule.ts @@ -0,0 +1,93 @@ +import Config from "../../../utility/config"; +import Database from "../../database/database"; +import { KeyValuePairList } from "../../../utility/keyValuePair"; +import Localisation from "../../../utility/localisation"; +import { Message } from "../../endpoint/definitions"; +import Utils from "../../../utility/utils"; +import WichtelEventPhase from "../../../utility/wichtelEvent"; + +export class ModerationModule +{ + protected database: Database; + + constructor (database: Database) + { + this.database = database; + } + + public async sendStatus (message: Message): Promise<void> + { + // TODO: This could be improved with visualisations. + + const currentEventPhase = Localisation.translateWichtelEventPhase(Config.currentEventPhase); + + let nextEventPhase: WichtelEventPhase|null = null; + let nextEventPhaseUnixTime: number|null = null; + + switch (Config.currentEventPhase) + { + case WichtelEventPhase.Waiting: + nextEventPhase = WichtelEventPhase.Registration; + nextEventPhaseUnixTime = Config.main.currentEvent.registration; + break; + case WichtelEventPhase.Registration: + nextEventPhase = WichtelEventPhase.Wichteln; + nextEventPhaseUnixTime = Config.main.currentEvent.assignment; + break; + case WichtelEventPhase.Wichteln: + nextEventPhase = WichtelEventPhase.Ended; + nextEventPhaseUnixTime = Config.main.currentEvent.end; + break; + case WichtelEventPhase.Ended: + // No next phase + break; + } + + let eventPhaseString: string; + + if ((nextEventPhase === null) || (nextEventPhaseUnixTime === null)) + { + const parameters = new KeyValuePairList('currentEventPhase', currentEventPhase); + + eventPhaseString = Localisation.texts.moderationStatusEventPhase.process(message.author, parameters); + } + else + { + const parameters = new KeyValuePairList(); + parameters.addPair('currentEventPhase', currentEventPhase); + parameters.addPair('nextEventPhase', Localisation.translateWichtelEventPhase(nextEventPhase)); + + const registrationDateStrings = Utils.dateToDateStrings(new Date(nextEventPhaseUnixTime * 1000)); + parameters.addPair('year', registrationDateStrings.year); + parameters.addPair('month', registrationDateStrings.month); + parameters.addPair('day', registrationDateStrings.day); + parameters.addPair('hour', registrationDateStrings.hour); + parameters.addPair('minute', registrationDateStrings.minute); + + eventPhaseString = Localisation.texts.moderationStatusEventPhaseWithNextPhase.process(message.author, parameters); + } + + const contactCount = this.database.getContactCount(); + const waitingMemberCount = this.database.getWaitingMemberCount(); + const giftTypeStatistics = this.database.getGiftTypeStatistics(); + const parcelStatistics = this.database.getParcelStatistics(); + + const parameters = new KeyValuePairList(); + parameters.addPair('currentEventName', Config.main.currentEvent.name); + parameters.addPair('eventPhaseString', eventPhaseString); + parameters.addPair('contactCount', `${contactCount}`); + parameters.addPair('waitingMemberCount', `${waitingMemberCount}`); + parameters.addPair('analogueGiverCount', `${giftTypeStatistics.analogueGiverCount}`); + parameters.addPair('digitalGiverCount', `${giftTypeStatistics.digitalGiverCount}`); + parameters.addPair('allGiverCount', `${giftTypeStatistics.allGiverCount}`); + parameters.addPair('analogueTakerCount', `${giftTypeStatistics.analogueTakerCount}`); + parameters.addPair('digitalTakerCount', `${giftTypeStatistics.digitalTakerCount}`); + parameters.addPair('allTakerCount', `${giftTypeStatistics.allTakerCount}`); + parameters.addPair('parcelSentCount', `${parcelStatistics.sentCount}`); + parameters.addPair('parcelReceivedCount', `${parcelStatistics.receivedCount}`); + + const answer = Localisation.texts.moderationStatus.process(message.author, parameters); + + await message.reply(answer); + } +} diff --git a/tests/tests/utility.tokenString.ts b/tests/tests/utility.tokenString.ts index 52286738ce0b6ea86f2a32aa794648d7ce9bd594..c31918639ca5ade831f795e6bd7dd7b9e600985e 100644 --- a/tests/tests/utility.tokenString.ts +++ b/tests/tests/utility.tokenString.ts @@ -1,11 +1,10 @@ import 'mocha'; import { assert } from 'chai'; - +import Config from '../../scripts/utility/config'; import ContactTestUtility from '../utility/contact'; import { KeyValuePairList } from '../../scripts/utility/keyValuePair'; import Localisation from '../../scripts/utility/localisation'; import TokenString from '../../scripts/utility/tokenString'; -import Config from '../../scripts/utility/config'; describe('tokenString', function () diff --git a/tests/tests/wichtelbot.endpoint.implementations.discord.ts b/tests/tests/wichtelbot.endpoint.implementations.discord.ts index dff140404bec90693cbcf8a81abe9f5488a54a88..220e61da07c25125bde816e5db52b05355f14b89 100644 --- a/tests/tests/wichtelbot.endpoint.implementations.discord.ts +++ b/tests/tests/wichtelbot.endpoint.implementations.discord.ts @@ -4,7 +4,6 @@ import * as DiscordEndpoint from '../../scripts/wichtelbot/endpoint/implementati import * as mockito from 'ts-mockito'; import { assert } from 'chai'; import { ChannelType } from '../../scripts/wichtelbot/endpoint/definitions'; -import GeneralTestUtility from '../utility/general'; describe('discord client', function () diff --git a/tests/utility/message.ts b/tests/utility/message.ts index bcd44b1e384239fbb487107f9b36c0d28e8d78fb..38cec7817db37481f413da101a84fa4bff373399 100644 --- a/tests/utility/message.ts +++ b/tests/utility/message.ts @@ -1,4 +1,3 @@ - import { Channel, ChannelType, Client, Component, Message, State, User } from '../../scripts/wichtelbot/endpoint/definitions'; import Contact from '../../scripts/wichtelbot/classes/contact'; import Database from '../../scripts/wichtelbot/database/database';