Skip to content
Snippets Groups Projects
Commit 6cb1fe5c authored by Bruce Cowan's avatar Bruce Cowan :airplane:
Browse files

Complete rewrite

Fixes #10, #11.
parent 9b870461
No related branches found
No related tags found
1 merge request!4Complete rewrite
Pipeline #3019 passed
# SPDX-FileCopyrightText: 2020 Bruce Cowan <bruce@bcowan.me.uk>
#
# SPDX-License-Identifier: GPL-3.0-or-later
[flake8]
max-line-length = 88
extend-ignore = E203
\ No newline at end of file
# SPDX-FileCopyrightText: 2018 Bruce Cowan <bruce@bcowan.me.uk>
#
# SPDX-License-Identifier: GPL-3.0-or-later
.pytest_cache/
__pycache__/
# SPDX-FileCopyrightText: 2018 Bruce Cowan <bruce@bcowan.me.uk>
#
# SPDX-License-Identifier: GPL-3.0-or-later
image: python:latest
stages:
- test
......@@ -9,7 +13,7 @@ check:
stage: test
script:
- pip install flake8
- flake8 karma.py --max-line-length 120
- flake8 karma.py
test:
stage: test
......
This diff is collapsed.
# SPDX-FileCopyrightText: 2016 Bruce Cowan <bruce@bcowan.me.uk>
#
# SPDX-License-Identifier: GPL-3.0-or-later
[Core]
name = Karma
module = karma
......
# Copyright © 2016, 2018 Bruce Cowan <bruce@bcowan.me.uk>
# SPDX-FileCopyrightText: 2016-2021 Bruce Cowan <bruce@bcowan.me.uk>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# SPDX-License-Identifier: GPL-3.0-or-later
from collections import defaultdict
from __future__ import annotations
import collections
import re
from errbot import BotPlugin, botcmd, re_botcmd
import errbot
class Karma(BotPlugin):
class Karma(errbot.BotPlugin):
"""Karma service"""
def activate(self):
super().activate()
self.karma = self.get('karma', defaultdict(int))
def deactivate(self):
self['karma'] = self.karma
if "karma" not in self:
self["karma"] = collections.Counter()
super().deactivate()
def _change_karma(self, target: str, value: int) -> str:
target = target.strip()
def _change_karma(self, target, value, message):
self.karma[target] += value
with self.mutable("karma") as k:
k[target] += value
if self.karma[target] == 0:
del self.karma[target]
if k[target] == 0:
del k[target]
return "Karma for '{}' is now {}".format(target, self.karma[target])
return f"Karma for '{target}' is now {self['karma'][target]}"
@re_botcmd(pattern=r'(.+)\+\+', prefixed=False, flags=re.IGNORECASE)
def on_karma_inc(self, message, match):
@errbot.re_botcmd(pattern=r"(.+)\+\+", prefixed=False, flags=re.IGNORECASE)
def on_karma_inc(self, message: errbot.Message, match: re.Match) -> str | None:
"""Adds karma"""
if message.frm == self.bot_identifier:
return
if 'c++' in message.body.casefold():
if "c++" in message.body.casefold():
return
return self._change_karma(match.group(1), 1, message)
return self._change_karma(match.group(1), 1)
@re_botcmd(pattern=r'(.+)--', prefixed=False, flags=re.IGNORECASE)
def on_karma_dec(self, message, match):
@errbot.re_botcmd(pattern=r"(.+)--", prefixed=False, flags=re.IGNORECASE)
def on_karma_dec(self, message: errbot.Message, match: re.Match) -> str | None:
"""Removes karma"""
if message.frm == self.bot_identifier:
return
return self._change_karma(match.group(1), -1, message)
return self._change_karma(match.group(1), -1)
@botcmd
def karma(self, message, args):
@errbot.botcmd
def karma(self, message: errbot.Message, args: str | None) -> str:
"""Gets karma"""
if not args:
return "**Usage**: !karma <target>"
return "Karma for '{}' is {}".format(args, self.karma[args])
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"
def _get_num_from_args(self, args):
try:
num = int(args[0])
return num
except ValueError:
return None
except IndexError:
return 5
@botcmd
def karma_top(self, message, args):
"""Gets the top 5 karmaed items"""
if not self.karma:
return "There are no karmaed items"
num = self._get_num_from_args(args)
if not num:
return "**Error**: Couldn't convert to an integer"
keys = sorted(self.karma, key=self.karma.get, reverse=True)[:num]
values = sorted(self.karma.values(), reverse=True)[:num]
return ", ".join(["{}: {}".format(k, v) for k, v in zip(keys, values)])
@botcmd
def karma_bottom(self, message, args):
"""Gets the bottom 5 karmaed items"""
if not self.karma:
return "There are no karmaed items"
num = self._get_num_from_args(args)
if not num:
return "**Error**: Couldn't convert to an integer"
keys = sorted(self.karma, key=self.karma.get)[:num]
values = sorted(self.karma.values())[:num]
return ", ".join(["{}: {}".format(k, v) for k, v in zip(keys, values)])
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}"
# Copyright © 2018, 2020 Bruce Cowan <bruce@bcowan.me.uk>
# SPDX-FileCopyrightText: 2018-2021 Bruce Cowan <bruce@bcowan.me.uk>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# SPDX-License-Identifier: GPL-3.0-or-later
import queue
......@@ -19,28 +8,28 @@ import pytest
pytest_plugins = ["errbot.backends.test"]
extra_plugin_dir = '.'
def test_regex(testbot):
testbot.assertCommand("test++", "Karma for 'test' is now 1")
testbot.assertCommand("!karma test", "Karma for 'test' is 1")
testbot.assertInCommand("test++", "Karma for 'test' is now 1")
testbot.assertInCommand("!karma test", "Karma for 'test' is 1")
testbot.assertCommand("test--", "Karma for 'test' is now 0")
testbot.assertCommand("!karma test", "Karma for 'test' is 0")
testbot.assertInCommand("test--", "Karma for 'test' is now 0")
testbot.assertInCommand("!karma test", "Karma for 'test' is 0")
def test_top_bottom(testbot):
testbot.assertCommand("high++", "Karma for 'high' is now 1")
testbot.assertCommand("high++", "Karma for 'high' is now 2")
testbot.assertCommand("medium++", "Karma for 'medium' is now 1")
testbot.assertCommand("low--", "Karma for 'low' is now -1")
testbot.assertInCommand("high++", "Karma for 'high' is now 1")
testbot.assertInCommand("high++", "Karma for 'high' is now 2")
testbot.assertInCommand("medium++", "Karma for 'medium' is now 1")
testbot.assertInCommand("low--", "Karma for 'low' is now -1")
testbot.assertCommand("!karma top", "high: 2, medium: 1, low: -1")
testbot.assertCommand("!karma bottom", "low: -1, medium: 1, high: 2")
testbot.assertInCommand("!karma top", "high: 2, medium: 1, low: -1")
testbot.assertInCommand("!karma bottom", "low: -1, medium: 1, high: 2")
testbot.assertCommand("!karma top 1", "high: 2")
testbot.assertCommand("!karma top 2", "high: 2, medium: 1")
testbot.assertInCommand("!karma top 1", "high: 2")
testbot.assertInCommand("!karma top 2", "high: 2, medium: 1")
def test_cpp(testbot):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment