-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcake.py
More file actions
108 lines (94 loc) · 3.71 KB
/
cake.py
File metadata and controls
108 lines (94 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
from collections import Counter
import logging
import re
from emoji import emojize
import plugins
import utils
log = logging.getLogger(__name__)
def _get_users(bot, conv):
users = bot.get_users_in_conversation(conv.id_)
# Handle synced rooms.
if bot.get_config_option("syncing_enabled"):
for sync in bot.get_config_option("sync_rooms", []):
if conv.id_ in sync:
for room in sync:
users += bot.get_users_in_conversation(room)
return dict((user.id_.chat_id, user) for user in users)
def _get_names(bot, users):
names = {}
for uid, user in users.items():
names[uid] = []
if not user.full_name == "Unknown":
names[uid].append(user.full_name)
try:
names[uid].append(bot.memory.get_by_path(["user_data", user.id_.chat_id, "nickname"]))
except KeyError:
pass
return names
def _format_name(name):
return re.sub(r"[^0-9a-z]+", "", utils.remove_accents(name).lower())
def _match_name(search, names, angel):
search = _format_name(search)
exact = []
substr = []
for user, nicks in names.items():
if user == angel:
continue
matches = [_format_name(name) for name in nicks]
if search == user or search in matches:
exact.append(user)
elif any(search in match for match in matches):
substr.append(user)
if len(exact) == 1:
return exact[0]
elif exact:
raise ValueError("Multiple people with that name! Maybe try a nickname instead?")
elif len(substr) == 1:
return substr[0]
elif substr:
raise ValueError("Multiple possible matches for that name! Try being more specific.")
else:
raise ValueError("No matches for that name...")
def _show_name(uid, names):
try:
return names[uid][0]
except IndexError:
return "<i>{0}</i>".format(uid)
def _initialise(bot):
plugins.register_user_command(["cake"])
def cake(bot, event, *args):
"""Cake for all! Be a cake angel -- reward someone with a slice using <b>cake give [name]</b>."""
cakes = bot.conversation_memory_get(event.conv_id, "cake") or []
users = _get_users(bot, event.conv)
names = _get_names(bot, users)
msg = None
if not args:
if cakes:
angels = Counter()
hoarders = Counter()
for angel, hoarder in cakes:
angels[angel] += 1
hoarders[hoarder] += 1
parts = ["<b>Top cake hoarders:</b>"]
for hoarder, count in sorted(hoarders.items(), key=lambda t: t[1], reverse=True):
parts.append("{0}: :cake:x{1}".format(_show_name(hoarder, names), count))
parts.append("<b>Top cake angels:</b>")
for angel, count in sorted(angels.items(), key=lambda t: t[1], reverse=True):
parts.append("{0}: :cake:x{1}".format(_show_name(angel, names), count))
msg = "\n".join(parts)
else:
msg = "No :cake: given out yet..."
elif args[0] == "give" and len(args) > 1:
who = " ".join(args[1:])
try:
user = _match_name(who, names, event.user)
except ValueError as e:
yield from bot.coro_send_message(event.conv_id, str(e))
return
angel, hoarder = event.user.id_.chat_id, user
log.debug("{0} gave cake to {1}".format(angel, hoarder))
cakes.append([angel, hoarder])
bot.conversation_memory_set(event.conv_id, "cake", cakes)
msg = ":heart_eyes: {0} gave a slice of :cake: to {1}!".format(_show_name(angel, names), _show_name(hoarder, names))
if msg:
yield from bot.coro_send_message(event.conv_id, emojize(msg, use_aliases=True))