From ab8a5806ba0553a3cc613055dab8e6cc239c0fd3 Mon Sep 17 00:00:00 2001 From: xmnlz Date: Sun, 3 Dec 2023 07:10:52 +0100 Subject: [PATCH] feat(): added timezone to moment --- package.json | 1 + pnpm-lock.yaml | 9 +++++++ src/commands/eventsmode/history.ts | 7 ++--- src/commands/eventsmode/top.ts | 43 ++++++++++++++++++------------ src/commands/eventsmode/weekly.ts | 20 +++++--------- src/lib/log-formatter.ts | 9 +++++++ src/main.ts | 9 +++++++ 7 files changed, 65 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 740b886..1ceede1 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "dotenv": "^16.3.1", "humanize-duration": "^3.30.0", "moment": "^2.29.4", + "moment-timezone": "^0.5.43", "node-html-to-image": "^4.0.0", "node-schedule": "^2.1.1", "pg": "^8.11.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a941715..e4d55f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ dependencies: moment: specifier: ^2.29.4 version: 2.29.4 + moment-timezone: + specifier: ^0.5.43 + version: 0.5.43 node-html-to-image: specifier: ^4.0.0 version: 4.0.0 @@ -1190,6 +1193,12 @@ packages: hasBin: true dev: false + /moment-timezone@0.5.43: + resolution: {integrity: sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==} + dependencies: + moment: 2.29.4 + dev: false + /moment@2.29.4: resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} dev: false diff --git a/src/commands/eventsmode/history.ts b/src/commands/eventsmode/history.ts index 617fd02..e849bc3 100644 --- a/src/commands/eventsmode/history.ts +++ b/src/commands/eventsmode/history.ts @@ -5,7 +5,6 @@ import { GuildMember, } from 'discord.js'; import { Discord, Guard, Slash, SlashOption } from 'discordx'; -import moment from 'moment/moment.js'; import { Between } from 'typeorm'; import { EventHistory } from '../../feature/event/event-history/event-history.entity.js'; import { Eventsmode } from '../../feature/eventsmode/eventsmode.entity.js'; @@ -14,7 +13,7 @@ import { BotMessages, Colors } from '../../lib/constants.js'; import { embedResponse } from '../../lib/embed-response.js'; import { CommandError } from '../../lib/errors/command.error.js'; import { humanizeMinutes } from '../../lib/humanize-duration.js'; -import { interpolate, userWithNameAndId } from '../../lib/log-formatter.js'; +import { interpolate, specialWeekInterval, userWithNameAndId } from '../../lib/log-formatter.js'; import { chunks, pagination } from '../../lib/pagination.js'; @Discord() @@ -59,11 +58,13 @@ export class Command { }); } + const [startOfTheWeek, endOfTheWeek] = specialWeekInterval(); + const eventHistory = weekly ? await EventHistory.findBy({ guild: { id: ctx.guild.id }, eventsmode: { guild: { id: author.guild.id }, userId: author.id, isHired: true }, - startedAt: Between(moment().startOf('week').toDate(), moment().endOf('week').toDate()), + startedAt: Between(startOfTheWeek, endOfTheWeek), }) : await EventHistory.findBy({ guild: { id: ctx.guild.id }, diff --git a/src/commands/eventsmode/top.ts b/src/commands/eventsmode/top.ts index 4163b2e..d397b4c 100644 --- a/src/commands/eventsmode/top.ts +++ b/src/commands/eventsmode/top.ts @@ -1,11 +1,12 @@ import { codeBlock, CommandInteraction, EmbedBuilder, inlineCode, Snowflake } from 'discord.js'; import { Discord, Guard, Slash } from 'discordx'; -import moment from 'moment/moment.js'; +import { Between } from 'typeorm'; import { EventHistory } from '../../feature/event/event-history/event-history.entity.js'; +import { Eventsmode } from '../../feature/eventsmode/eventsmode.entity.js'; import { EventsmodeGuard } from '../../guards/eventsmode.guard.js'; import { Colors } from '../../lib/constants.js'; import { humanizeMinutes } from '../../lib/humanize-duration.js'; -import { interpolate, userWithMentionAndId } from '../../lib/log-formatter.js'; +import { interpolate, specialWeekInterval, userWithMentionAndId } from '../../lib/log-formatter.js'; import { chunks, pagination } from '../../lib/pagination.js'; @Discord() @@ -15,32 +16,40 @@ export class Command { async top(ctx: CommandInteraction<'cached'>) { await ctx.deferReply(); - const eventStatsRaw = await EventHistory.query( + const [startOfTheWeek, endOfTheWeek] = specialWeekInterval(); + + const eventCountByWeek = await EventHistory.count({ + where: { startedAt: Between(startOfTheWeek, endOfTheWeek) }, + }); + + const totalEventTimeByWeekRaw = await Eventsmode.query( ` - SELECT sum(total_time) as "totalTime", count(*) as "count" - FROM public.event_history - LEFT JOIN guild ON event_history.guild_id = guild.id - WHERE guild_id = $1 AND started_at BETWEEN $2 AND $3`, - [ctx.guild.id, moment().startOf('week').toDate(), moment().endOf('week').toDate()], + SELECT sum(eventsmode.weekly_time) as "totalTime" + FROM public.eventsmode + LEFT JOIN guild ON eventsmode.guild_id = guild.id + WHERE eventsmode.guild_id = $1 + `, + [ctx.guild.id], ); - const eventStats: { totalTime: number; count: number } = eventStatsRaw[0]; + const totalEventTimeByWeek = totalEventTimeByWeekRaw[0].totalTime; - const test: { userId: Snowflake; totalTime: number; eventCount: number }[] = + const eventsmodeStats: { userId: Snowflake; totalTime: number; eventCount: number }[] = await EventHistory.query( ` - SELECT eventsmode.user_id as "userId", eventsmode.total_time as "totalTime", count(*) as "eventCount" + SELECT eventsmode.user_id as "userId", eventsmode.weekly_time as "totalTime", count(*) as "eventCount" FROM public.event_history LEFT JOIN guild ON event_history.guild_id = guild.id LEFT JOIN eventsmode ON event_history.eventsmode_id = eventsmode.id - GROUP BY eventsmode.user_id, eventsmode.total_time, eventsmode.total_time - ORDER BY eventsmode.total_time DESC, COUNT(*) DESC + WHERE event_history.guild_id = $1 AND started_at BETWEEN $2 AND $3 + GROUP BY eventsmode.user_id, eventsmode.weekly_time + ORDER BY eventsmode.weekly_time DESC, COUNT(*) DESC `, - [], + [ctx.guild.id, startOfTheWeek, endOfTheWeek], ); const textChunks = chunks( - test.map(({ userId, totalTime, eventCount }, index) => + eventsmodeStats.map(({ userId, totalTime, eventCount }, index) => interpolate(`${index + 1}. $1 - Время: $2, Ивенты: $3`, [ userWithMentionAndId(userId), inlineCode(humanizeMinutes(totalTime)), @@ -57,8 +66,8 @@ export class Command { codeBlock( 'ts', interpolate(`Топ ивентеров за неделю\nОбщее Время: $1\nОбщее Кол-во Ивентов: $2`, [ - humanizeMinutes(eventStats.totalTime), - String(eventStats.count), + humanizeMinutes(totalEventTimeByWeek || 0), + String(eventCountByWeek), ]), ) + `\n${textArray.join('\n')}`, ); diff --git a/src/commands/eventsmode/weekly.ts b/src/commands/eventsmode/weekly.ts index 189c51e..67de8f3 100644 --- a/src/commands/eventsmode/weekly.ts +++ b/src/commands/eventsmode/weekly.ts @@ -1,21 +1,13 @@ -import { - ApplicationCommandOptionType, - bold, - CommandInteraction, - EmbedBuilder, - GuildMember, - userMention, -} from 'discord.js'; -import { Discord, Guard, Slash, SlashOption } from 'discordx'; -import moment from 'moment'; +import { CommandInteraction, EmbedBuilder, userMention } from 'discord.js'; +import { Discord, Guard, Slash } from 'discordx'; import { Between } from 'typeorm'; import { EventHistory } from '../../feature/event/event-history/event-history.entity.js'; import { EventsmodeGuard } from '../../guards/eventsmode.guard.js'; -import { BotMessages, Colors } from '../../lib/constants.js'; +import { Colors } from '../../lib/constants.js'; import { embedResponse } from '../../lib/embed-response.js'; import { CommandError } from '../../lib/errors/command.error.js'; import { humanizeMinutes } from '../../lib/humanize-duration.js'; -import { interpolate } from '../../lib/log-formatter.js'; +import { interpolate, specialWeekInterval } from '../../lib/log-formatter.js'; import { chunks, pagination } from '../../lib/pagination.js'; @Discord() @@ -25,11 +17,13 @@ export class Command { async weekly(ctx: CommandInteraction<'cached'>) { await ctx.deferReply({ ephemeral: true }); + const [startOfTheWeek, endOfTheWeek] = specialWeekInterval(); + const eventHistory = await EventHistory.find({ order: { totalTime: 'DESC' }, where: { guild: { id: ctx.guild.id }, - startedAt: Between(moment().startOf('week').toDate(), moment().endOf('week').toDate()), + startedAt: Between(startOfTheWeek, endOfTheWeek), }, }); diff --git a/src/lib/log-formatter.ts b/src/lib/log-formatter.ts index ae1b6ea..a4e643f 100644 --- a/src/lib/log-formatter.ts +++ b/src/lib/log-formatter.ts @@ -1,4 +1,5 @@ import { inlineCode, Snowflake, User, userMention } from 'discord.js'; +import moment from 'moment'; export const userWithNameAndId = (user: User) => { return inlineCode(`${user.username} (${user.id})`); @@ -12,6 +13,14 @@ export const interpolate = (string: string, params: string[]) => { return string.replace(/\$(\d+)/g, (_, num) => params[num - 1]); }; +export const specialWeekInterval = () => { + const startOfTheWeek = moment().startOf('week'); + return [ + moment().startOf('week').toDate(), + startOfTheWeek.add(6, 'days').add(19, 'hours').toDate(), + ]; +}; + export const getStuffRole = (staffRole: number) => { switch (staffRole) { case 1: diff --git a/src/main.ts b/src/main.ts index 4bbb3e0..e45040c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import 'reflect-metadata'; import { dirname, importx } from '@discordx/importer'; import { IntentsBitField, Partials } from 'discord.js'; import { Client, DIService, tsyringeDependencyRegistryEngine } from 'discordx'; +import moment from 'moment-timezone'; import { env } from 'process'; import { container } from 'tsyringe'; import { Database } from './database/data-source.js'; @@ -11,6 +12,14 @@ import dotenv from 'dotenv'; import './lib/error-handling.js'; +moment.updateLocale('en', { + week: { + dow: 1, + }, +}); + +moment.tz.setDefault('Europe/Moscow'); + DIService.engine = tsyringeDependencyRegistryEngine.setInjector(container); dotenv.config({ path: '.env.' + env.NODE_ENV });