diff --git a/src/data_types/other.py b/src/data_types/other.py index 5b4a0b3..3c04f78 100644 --- a/src/data_types/other.py +++ b/src/data_types/other.py @@ -1,14 +1,34 @@ from typing import List +from collections import defaultdict + + +from utils import mention, channel_mention class Other: def __init__(self): - pass # TODO + self.most_used_reaction = "" + self.most_used_reaction_count = 0 + self.used_reaction_total = 1 + self.channel_usage = defaultdict(int) + self.mentions = defaultdict(int) - def to_string(self) -> List[str]: - return [ - # f"- **most visited channel**: #c", - # f"- **mostly mentioned by**: @x", - # f"- **reactions**: n %", - # f"- **most used reaction**: xx (see more with %emotes)", + def to_string(self, *, show_top_channel: bool, show_mentioned: bool) -> List[str]: + ret = [] + if show_top_channel: + top_channel = sorted(self.channel_usage)[-1] + channel_sum = sum(self.channel_usage.values()) + ret += [ + f"- **most visited channel**: {channel_mention(top_channel)} ({self.channel_usage[top_channel]:,} msg, {100*self.channel_usage[top_channel]//channel_sum:.0f}%)" + ] + if show_mentioned and len(self.mentions) > 0: + top_mention = sorted(self.mentions)[-1] + mention_sum = sum(self.mentions.values()) + ret += [ + f"- **mentioned**: {mention_sum:,} times", + f"- **mostly mentioned by**: {mention(top_mention)} ({self.mentions[top_mention]:,} times, {100*self.mentions[top_mention]//mention_sum:.0f}%)", + ] + return ret + [ + f"- **reactions**: {self.used_reaction_total:,}", + f"- **most used reaction**: {self.most_used_reaction} ({self.most_used_reaction_count:,} uses, {100*self.most_used_reaction_count/self.used_reaction_total:.0f}%)", ] # TODO diff --git a/src/scanners/full_scanner.py b/src/scanners/full_scanner.py index afdd41f..c29e2c5 100644 --- a/src/scanners/full_scanner.py +++ b/src/scanners/full_scanner.py @@ -39,13 +39,15 @@ class FullScanner(Scanner): return True def compute_message(self, channel: ChannelLogs, message: MessageLog): - ret = FrequencyScanner.analyse_message(message, self.freq, self.raw_members) - ret &= CompositionScanner.analyse_message(message, self.comp, self.raw_members) - ret &= OtherScanner.analyse_message(message, self.other, self.raw_members) - ret &= EmotesScanner.analyse_message( + FrequencyScanner.analyse_message(message, self.freq, self.raw_members) + CompositionScanner.analyse_message(message, self.comp, self.raw_members) + OtherScanner.analyse_message(channel, message, self.other, self.raw_members) + EmotesScanner.analyse_message( message, self.emotes, self.raw_members, all_emojis=True ) - return ret + return not message.bot and ( + len(self.raw_members) == 0 or message.author in self.raw_members + ) def get_results(self, intro: str) -> List[str]: FrequencyScanner.compute_results(self.freq) @@ -57,5 +59,8 @@ class FullScanner(Scanner): res += ["__Composition__:"] res += self.comp.to_string() res += ["__Other__:"] - res += self.other.to_string() + res += self.other.to_string( + show_top_channel=len(self.channels) > 1, + show_mentioned=(len(self.members) != 1), + ) return res diff --git a/src/scanners/other_scanner.py b/src/scanners/other_scanner.py index 0a5c6ea..cb06405 100644 --- a/src/scanners/other_scanner.py +++ b/src/scanners/other_scanner.py @@ -34,29 +34,40 @@ class OtherScanner(Scanner): return True def compute_message(self, channel: ChannelLogs, message: MessageLog): - ret = OtherScanner.analyse_message(message, self.other, self.raw_members) - ret &= EmotesScanner.analyse_message( + EmotesScanner.analyse_message( message, self.emotes, self.raw_members, all_emojis=True ) - return ret + return OtherScanner.analyse_message( + channel, message, self.other, self.raw_members + ) def get_results(self, intro: str) -> List[str]: OtherScanner.compute_results(self.other, self.emotes) res = [intro] - res += self.other.to_string() + res += self.other.to_string( + show_top_channel=len(self.channels) > 1, + show_mentioned=(len(self.members) > 0), + ) return res @staticmethod def analyse_message( - message: MessageLog, other: Other, raw_members: List[int] + channel: ChannelLogs, message: MessageLog, other: Other, raw_members: List[int] ) -> bool: impacted = False # If author is included in the selection (empty list is all) - if len(raw_members) == 0 or message.author in raw_members: + if not message.bot and (len(raw_members) == 0 or message.author in raw_members): impacted = True - pass # TODO + other.channel_usage[channel.id] += 1 + for mention in message.mentions: + if mention in raw_members: + other.mentions[mention] += 1 return impacted @staticmethod def compute_results(other: Other, emotes: Dict[str, Emote]): - pass # TODO + # calculate most used reaction + other.most_used_reaction = sorted(emotes, key=lambda k: emotes[k].reactions)[-1] + other.most_used_reaction_count = emotes[other.most_used_reaction].reactions + # calculate total reactions + other.used_reaction_total = sum([emote.reactions for emote in emotes.values()]) diff --git a/src/utils/utils.py b/src/utils/utils.py index 11d3f3b..a0e9d1a 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -30,6 +30,10 @@ def mention(member_id: int) -> str: return f"<@{member_id}>" +def channel_mention(channel_id: int) -> str: + return f"<#{channel_id}>" + + class FakeMessage: def __init__(self, id: int): self.id = id