@@ -113,6 +113,9 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
113113 matchesCommand(e0Text, " msgall" ) ->
114114 doMessageTotalCommand(bot, message, chatId, text, entities)
115115
116+ matchesCommand(e0Text, " stats" ) ->
117+ doStatisticsCommand(bot, message, chatId, text)
118+
116119 matchesCommand(e0Text, " deletemydata" ) ->
117120 doDeleteMyDataCommand(bot, message, chatId, senderId)
118121
@@ -136,6 +139,7 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
136139 val deleteMessageData = wantToDeleteMessageData[chatId]
137140
138141 if (deleteOwnData?.contains(senderId) == true ) {
142+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
139143 shouldAnalyzeMessage = false
140144 deleteOwnData - = senderId
141145 if (deleteOwnData.isEmpty()) {
@@ -152,6 +156,7 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
152156 }
153157 reply(bot, message, replyText)
154158 } else if (deleteUserData?.contains(senderId) == true ) {
159+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
155160 shouldAnalyzeMessage = false
156161 val userIdToDelete = deleteUserData[senderId]!!
157162 deleteUserData - = senderId
@@ -169,6 +174,7 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
169174 }
170175 reply(bot, message, replyText)
171176 } else if (deleteMessageData?.contains(senderId) == true ) {
177+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
172178 shouldAnalyzeMessage = false
173179 val messageToDelete = deleteMessageData[senderId]!!
174180 deleteMessageData - = senderId
@@ -193,6 +199,7 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
193199 private fun doMessageCommand (bot : Bot , message : Message , chatId : String , text : String ,
194200 entities : List <MessageEntity >) {
195201
202+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
196203 var parseMode: ParseMode ? = null
197204
198205 val replyText = if (entities.size < 2 ) {
@@ -237,6 +244,7 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
237244 private fun doMessageTotalCommand (bot : Bot , message : Message , chatId : String , text : String ,
238245 entities : List <MessageEntity >) {
239246
247+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
240248 val e0 = entities[0 ]
241249 val remainingTexts = text.substring(e0.offset + e0.length).trim().takeIf { it.isNotBlank() }
242250 ?.split(whitespaceRegex).orEmpty()
@@ -257,7 +265,32 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
257265 reply(bot, message, replyText)
258266 }
259267
268+ private fun doStatisticsCommand (bot : Bot , message : Message , chatId : String , text : String ) {
269+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
270+ val markovPaths = getAllPersonalMarkovPaths(chatId)
271+ val userIdToWordCountsMap = markovPaths
272+ .mapNotNull { path ->
273+ tryOrNull { MarkovChain .read(path) }
274+ ?.let { Pair (File (path).nameWithoutExtension, it.wordCounts) }
275+ }
276+ .toMap()
277+ val universe = computeUniverse(userIdToWordCountsMap.values)
278+ val listText = userIdToWordCountsMap.mapNotNull { (userId, wordCounts) ->
279+ val response = bot.getChatMember(chatId.toLong(), userId.toLong())
280+ val chatMember = response.first?.body()?.result
281+ if (chatMember != null ) {
282+ val mostDistinguishingWords = scoreMostDistinguishingWords(wordCounts, universe).keys.take(5 )
283+ " ${chatMember.user.displayName} \n " +
284+ mostDistinguishingWords.mapIndexed { i, word -> " ${i + 1 } . $word " }.joinToString(" \n " )
285+ } else null
286+ }.filter { it.isNotBlank() }.joinToString(" \n\n " )
287+ val replyText = if (listText.isBlank()) " <no data available>"
288+ else " Most distinguishing words:\n\n $listText "
289+ reply(bot, message, replyText)
290+ }
291+
260292 private fun doDeleteMyDataCommand (bot : Bot , message : Message , chatId : String , senderId : String ) {
293+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
261294 wantToDeleteOwnData.getOrPut(chatId) { mutableSetOf () } + = senderId
262295 val replyText = " Are you sure you want to delete your Markov chain data in this group? " +
263296 " Say \" yes\" to confirm, or anything else to cancel."
@@ -267,6 +300,7 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
267300 private fun doDeleteUserDataCommand (bot : Bot , message : Message , chatId : String , from : User , senderId : String ,
268301 entities : List <MessageEntity >) {
269302
303+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
270304 var parseMode: ParseMode ? = null
271305 val replyText = if (isAdmin(bot, message.chat, from.id)) {
272306 if (entities.size < 2 ) {
@@ -299,6 +333,7 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
299333 }
300334
301335 private fun doDeleteMessageDataCommand (bot : Bot , message : Message , chatId : String , senderId : String ) {
336+ bot.sendChatAction(chatId.toLong(), ChatAction .TYPING )
302337 val replyText = message.replyToMessage?.let { replyToMessage ->
303338 replyToMessage.from?.takeIf { it.id.toString() == senderId }?.let { replyToMessageFrom ->
304339 wantToDeleteMessageData.getOrPut(chatId) { mutableMapOf () }[senderId] = replyToMessage.text ? : " "
@@ -413,9 +448,13 @@ class MarkovTelegramBot(private val token: String, private val dataPath: String)
413448 }
414449
415450 private fun readAllPersonalMarkov (chatId : String ): List <MarkovChain > =
451+ getAllPersonalMarkovPaths(chatId)
452+ .map { MarkovChain .read(it) }
453+
454+ private fun getAllPersonalMarkovPaths (chatId : String ): List <String > =
416455 File (getChatPath(chatId)).listFiles()
417456 .filter { ! it.name.endsWith(" total.json" ) }
418- .map { MarkovChain .read( it.path) }
457+ .map { it.path }
419458
420459 private fun getMarkovPath (chatId : String , userId : String ): String =
421460 Paths .get(getChatPath(chatId), " $userId .json" ).toString()
0 commit comments