Skip to content
Snippets Groups Projects
karma.py 2.73 KiB
Newer Older
Bruce Cowan's avatar
Bruce Cowan committed
# SPDX-FileCopyrightText: 2016-2021 Bruce Cowan <bruce@bcowan.me.uk>
Bruce Cowan's avatar
Bruce Cowan committed
#
Bruce Cowan's avatar
Bruce Cowan committed
# SPDX-License-Identifier: GPL-3.0-or-later
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
from __future__ import annotations

import collections
Bruce Cowan's avatar
Bruce Cowan committed
import re
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
import errbot
Bruce Cowan's avatar
Bruce Cowan committed
class Karma(errbot.BotPlugin):
Bruce Cowan's avatar
Bruce Cowan committed
    """Karma service"""

    def activate(self):
        super().activate()

Bruce Cowan's avatar
Bruce Cowan committed
        if "karma" not in self:
            self["karma"] = collections.Counter()
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
    def _change_karma(self, target: str, value: int) -> str:
        target = target.strip()
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
        with self.mutable("karma") as k:
            k[target] += value
Bruce Cowan's avatar
Bruce Cowan committed
            if k[target] == 0:
                del k[target]
Bruce Cowan's avatar
Bruce Cowan committed
        return f"Karma for '{target}' is now {self['karma'][target]}"
Bruce Cowan's avatar
Bruce Cowan committed
    @errbot.re_botcmd(pattern=r"(.+)\+\+", prefixed=False, flags=re.IGNORECASE)
    def on_karma_inc(self, message: errbot.Message, match: re.Match) -> str | None:
Bruce Cowan's avatar
Bruce Cowan committed
        """Adds karma"""
        if message.frm == self.bot_identifier:
            return
Bruce Cowan's avatar
Bruce Cowan committed
        if "c++" in message.body.casefold():
Bruce Cowan's avatar
Bruce Cowan committed
            return
Bruce Cowan's avatar
Bruce Cowan committed
        return self._change_karma(match.group(1), 1)
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
    @errbot.re_botcmd(pattern=r"(.+)--", prefixed=False, flags=re.IGNORECASE)
    def on_karma_dec(self, message: errbot.Message, match: re.Match) -> str | None:
Bruce Cowan's avatar
Bruce Cowan committed
        """Removes karma"""
        if message.frm == self.bot_identifier:
            return
Bruce Cowan's avatar
Bruce Cowan committed
        return self._change_karma(match.group(1), -1)
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
    @errbot.botcmd
    def karma(self, message: errbot.Message, args: str | None) -> str:
Bruce Cowan's avatar
Bruce Cowan committed
        """Gets karma"""
        if not args:
            return "**Usage**: !karma <target>"

Bruce Cowan's avatar
Bruce Cowan committed
        return f"Karma for '{args}' is {self['karma'][args]}"

    @errbot.botcmd
    def karma_top(self, message: errbot.Message, args: str | None) -> str:
        """Gets the top n items"""
        if len(self["karma"]) == 0:
            return "There are no items with karma"
Bruce Cowan's avatar
Bruce Cowan committed
            num = int(args)
        except (TypeError, ValueError):
            num = 5

        top = self["karma"].most_common(num)
        return ", ".join([f"{k}: {v}" for k, v in top])

    @errbot.botcmd
    def karma_bottom(self, message: errbot.Message, args: str | None) -> str:
        """Gets the bottom n items"""
        if len(self["karma"]) == 0:
            return "There are no items with karma"

        try:
            num = int(args)
        except (TypeError, ValueError):
            num = 5

        bottom = self["karma"].most_common()[: -num - 1 : -1]
        return ", ".join([f"{k}: {v}" for k, v in bottom])

    @errbot.botcmd
    def karma_reset(self, message: errbot.Message, args: str | None) -> str:
        args = args.strip()

        if args not in self["karma"]:
            return "**Error**: no such item"

        with self.mutable("karma") as k:
            del k[args]
        return f"Deleted {args}"