/[sudobot]/branches/7.x/src/services/StatsService.ts
ViewVC logotype

Contents of /branches/7.x/src/services/StatsService.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 4877 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 /**
2 * This file is part of SudoBot.
3 *
4 * Copyright (C) 2021-2024 OSN Developers.
5 *
6 * SudoBot is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * SudoBot is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 import { UserStatistics } from "@prisma/client";
21 import { Message, PartialMessage, Snowflake } from "discord.js";
22 import Service from "../core/Service";
23 import { HasEventListeners } from "../types/HasEventListeners";
24
25 export const name = "statsService";
26
27 type CacheEntry = Omit<UserStatistics, "id" | "createdAt" | "updatedAt"> & { id?: number; createdAt?: Date; updatedAt?: Date };
28
29 export default class StatsService extends Service implements HasEventListeners {
30 protected readonly cache = new Map<`${Snowflake}_${Snowflake}`, CacheEntry>();
31 protected hasQueue: boolean = false;
32
33 getOrCreateUserInfo(guildId: string, userId: string, callback: (info: CacheEntry) => void) {
34 const config = this.client.configManager.systemConfig?.statistics;
35 const guildConfig = this.client.configManager.config[guildId]?.statistics;
36
37 if (!config?.enabled || !guildConfig?.enabled) {
38 return;
39 }
40
41 const key = `${guildId}_${userId}` as const;
42 let info = this.cache.get(key);
43 let setInfo = false;
44
45 if (!info) {
46 info = {
47 guildId,
48 userId,
49 messagesSent: 0,
50 messagesDeleted: 0,
51 messagesEdited: 0
52 } as UserStatistics;
53 setInfo = true;
54 }
55
56 callback(info);
57
58 if (setInfo) {
59 this.cache.set(key, info);
60 }
61
62 if (!this.hasQueue) {
63 this.hasQueue = true;
64
65 setTimeout(async () => {
66 await this.syncWithDatabase();
67 this.hasQueue = false;
68 }, config.sync_delay);
69 }
70 }
71
72 onMessageCreate(message: Message<boolean>) {
73 if (message.author.bot) {
74 return;
75 }
76
77 this.getOrCreateUserInfo(message.guildId!, message.author.id, info => {
78 info.messagesSent++;
79 });
80 }
81
82 onMessageUpdate(oldMessage: Message<boolean> | PartialMessage, newMessage: Message<boolean> | PartialMessage) {
83 if (!newMessage.author || newMessage.author.bot || !newMessage.guildId) {
84 return;
85 }
86
87 this.getOrCreateUserInfo(newMessage.guildId, newMessage.author.id, info => {
88 info.messagesEdited++;
89 });
90 }
91
92 onMessageDelete(message: Message<boolean> | PartialMessage) {
93 if (!message.author || !message.guildId! || message.author.bot) {
94 return;
95 }
96
97 this.getOrCreateUserInfo(message.guildId, message.author.id, info => {
98 info.messagesDeleted++;
99 });
100 }
101
102 async syncWithDatabase() {
103 const config = this.client.configManager.systemConfig?.statistics;
104
105 if (!config?.enabled) {
106 return;
107 }
108
109 const values = [...this.cache.values()];
110 const existingRecords = (
111 await this.client.prisma.userStatistics.findMany({
112 where: {
113 id: {
114 in: values.filter(value => value.id !== undefined).map(value => value.id!)
115 }
116 },
117 select: {
118 id: true
119 }
120 })
121 ).map(value => value.id);
122 const toBeCreated = [];
123
124 for (const value of values) {
125 if (value.id !== undefined && existingRecords.includes(value.id)) {
126 await this.client.prisma.userStatistics.update({
127 where: {
128 id: value.id
129 },
130 data: {
131 messagesDeleted: value.id,
132 messagesEdited: value.messagesEdited,
133 messagesSent: value.messagesSent,
134 userId: value.userId,
135 guildId: value.guildId
136 }
137 });
138 } else {
139 toBeCreated.push(value);
140 }
141 }
142
143 if (toBeCreated.length > 0) {
144 await this.client.prisma.userStatistics.createMany({
145 data: toBeCreated
146 });
147 }
148
149 this.cache.clear();
150 }
151 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26