From e106ed4e41441753b75180d92f00b465d655e29a Mon Sep 17 00:00:00 2001 From: klemek Date: Wed, 13 Jan 2021 15:12:28 +0100 Subject: [PATCH] emojis sorting --- src/data_types/emote.py | 39 ++++++++++++++++++++++---------- src/scanners/emotes_scanner.py | 41 +++++++++++++++++++++++++--------- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/data_types/emote.py b/src/data_types/emote.py index 6102dc0..63c05f3 100644 --- a/src/data_types/emote.py +++ b/src/data_types/emote.py @@ -5,7 +5,7 @@ import discord # Custom libs -from utils import mention, plural, from_now, top_key +from utils import mention, plural, from_now, top_key, percent class Emote: @@ -32,12 +32,16 @@ class Emote: def used(self) -> bool: return self.usages > 0 or self.reactions > 0 - def score(self) -> float: + def score(self, *, usage_weight: int = 1, react_weight: int = 1) -> float: # Score is compose of usages + reactions # When 2 emotes have the same score, # the days since last use is stored in the digits # (more recent first) - return self.usages + self.reactions + 1 / (100000 * (self.use_days() + 1)) + return ( + self.usages * usage_weight + + self.reactions * react_weight + + 1 / (100000 * (self.use_days() + 1)) + ) def life_days(self) -> int: return (datetime.today() - self.emoji.created_at).days @@ -52,7 +56,16 @@ class Emote: def get_top_member(self) -> int: return top_key(self.members) - def to_string(self, i: int, name: str, show_life: bool, show_members: bool) -> str: + def to_string( + self, + i: int, + name: str, + *, + total_usage: int, + total_react: int, + show_life: bool, + show_members: bool, + ) -> str: # place output = "" if i == 0: @@ -65,17 +78,19 @@ class Emote: output += f"**#{i + 1}**" output += f" {name} - " if not self.used(): - output += "never used " + output += "never used" else: - output += f"{plural(self.usages, 'time')} " - if self.reactions >= 1: - output += f"and {plural(self.reactions, 'reaction')} " - if show_life and not self.default: - output += f"(in {plural(self.life_days(), 'day')}) " - if self.used(): - output += f"(last used {from_now(self.last_used)})" + if self.usages > 0: + output += f"{plural(self.usages, 'time')} ({percent(self.usages/total_usage)})" + if self.usages > 0 and self.reactions > 0: + output += " and " + if self.reactions >= 1: + output += f"{plural(self.reactions, 'reaction')} ({percent(self.reactions/total_react)})" + output += f" (last used {from_now(self.last_used)})" if show_members: output += f" (mostly by {mention(self.get_top_member())}: {self.members[self.get_top_member()]})" + if show_life and not self.default: + output += f" (in {plural(self.life_days(), 'day')})" return output diff --git a/src/scanners/emotes_scanner.py b/src/scanners/emotes_scanner.py index ff99111..bef6174 100644 --- a/src/scanners/emotes_scanner.py +++ b/src/scanners/emotes_scanner.py @@ -22,6 +22,7 @@ class EmotesScanner(Scanner): + "* : top emojis, default is 20\n" + "* all : list all common emojis in addition to this guild's\n" + "* members : show top member for each emojis\n" + + "* sort:usage/reaction : other sorting methods\n" + "Example: %emojis 10 all #mychannel1 #mychannel2 @user\n" + "```" ) @@ -29,7 +30,7 @@ class EmotesScanner(Scanner): def __init__(self): super().__init__( has_digit_args=True, - valid_args=["all", "members"], + valid_args=["all", "members", "sort:usage", "sort:reaction"], help=EmotesScanner.help(), intro_context="Emoji usage", ) @@ -51,6 +52,11 @@ class EmotesScanner(Scanner): ) # Create emotes dict from custom emojis of the guild self.emotes = get_emote_dict(guild) + self.sort = None + if "sort:usage" in args: + self.sort = "usage" + elif "sort:reaction" in args: + self.sort = "reaction" return True def compute_message(self, channel: ChannelLogs, message: MessageLog): @@ -60,23 +66,36 @@ class EmotesScanner(Scanner): def get_results(self, intro: str) -> List[str]: names = [name for name in self.emotes] - names.sort(key=lambda name: self.emotes[name].score(), reverse=True) + names.sort( + key=lambda name: self.emotes[name].score( + usage_weight=(0 if self.sort == "reaction" else 1), + react_weight=(0 if self.sort == "usage" else 1), + ), + reverse=True, + ) names = names[: self.top] - res = [intro] - allow_unused = self.full and len(self.members) == 0 - res += [ - self.emotes[name].to_string( - names.index(name), name, False, self.show_members - ) - for name in names - if allow_unused or self.emotes[name].used() - ] # Get the total of all emotes used usage_count = 0 reaction_count = 0 for name in self.emotes: usage_count += self.emotes[name].usages reaction_count += self.emotes[name].reactions + res = [intro] + allow_unused = self.full and len(self.members) == 0 + if self.sort is not None: + res += [f"(Sorted by {self.sort})"] + res += [ + self.emotes[name].to_string( + names.index(name), + name, + total_usage=usage_count, + total_react=reaction_count, + show_life=False, + show_members=self.show_members, + ) + for name in names + if allow_unused or self.emotes[name].used() + ] res += [ f"Total: {plural(usage_count,'time')} ({precise(usage_count/self.msg_count)}/msg)" ]