1
|
|
|
"""Cog the preforms health functions"""
|
2
|
|
|
from datetime import datetime
|
3
|
|
|
import logging
|
4
|
|
|
from discord.ext import commands
|
5
|
|
|
import discord
|
6
|
|
|
import utils
|
7
|
|
|
|
8
|
|
|
|
9
|
|
|
class HealthCog(commands.Cog, name="Health"):
|
10
|
|
|
"""HealthCog
|
11
|
|
|
---
|
12
|
|
|
|
13
|
|
|
Cog that holds the health commands and is responsible for updating the
|
14
|
|
|
tables when roles change in discord.
|
15
|
|
|
|
16
|
|
|
Commands:
|
17
|
|
|
---
|
18
|
|
|
`check-health`: Makes sure that all the roles in the tables `schools` and `regions` map
|
19
|
|
|
to roles in the discord server.
|
20
|
|
|
|
21
|
|
|
Events:
|
22
|
|
|
---
|
23
|
|
|
`on_guild_role_update`: Event that is triggered when a role is updated.
|
24
|
|
|
|
25
|
|
|
`on_guild_role_delete`: Event that is triggered when a role is deleted.
|
26
|
|
|
|
27
|
|
|
Arguments:
|
28
|
|
|
---
|
29
|
|
|
bot {discord.commands.Bot} -- The bot
|
30
|
|
|
"""
|
31
|
|
|
def __init__(self, bot):
|
32
|
|
|
self.bot = bot
|
33
|
|
|
self.log = logging.getLogger("bot")
|
34
|
|
|
|
35
|
|
|
async def cog_check(self, ctx):
|
36
|
|
|
"""cog_check
|
37
|
|
|
---
|
38
|
|
|
|
39
|
|
|
cog_check is set for the whole cog. Which makes all the commands in health admin only.
|
40
|
|
|
|
41
|
|
|
Arguments:
|
42
|
|
|
---
|
43
|
|
|
ctx {discord.ext.commands.Context} -- Context of the command.
|
44
|
|
|
|
45
|
|
|
Returns:
|
46
|
|
|
bool -- True if the user in the bot admins
|
47
|
|
|
"""
|
48
|
|
|
return await utils.check_admin(ctx)
|
49
|
|
|
|
50
|
|
|
@commands.command(name="check-health",
|
51
|
|
|
help="Checks health of roles for schools and regions")
|
52
|
|
|
async def check_health(self, ctx):
|
53
|
|
|
"""check-health
|
54
|
|
|
---
|
55
|
|
|
|
56
|
|
|
Checks health of roles for schools and regions. It pulls all the IDs for school and
|
57
|
|
|
region roles. Then compares the names of the matching ids to see if they match. If
|
58
|
|
|
they match then added to a list called success and if the check fails then then
|
59
|
|
|
both names are added to a list called fail.
|
60
|
|
|
|
61
|
|
|
Arguments:
|
62
|
|
|
---
|
63
|
|
|
ctx {discord.ext.commands.Context} -- Context of the command.
|
64
|
|
|
|
65
|
|
|
"""
|
66
|
|
|
async with ctx.typing():
|
67
|
|
|
table_schools = await utils.fetch("schools", "school")
|
68
|
|
|
regions = await utils.fetch("regions", "name")
|
69
|
|
|
success, fail = [], []
|
70
|
|
|
for roles in [table_schools, regions]:
|
71
|
|
|
for role in roles:
|
72
|
|
|
try:
|
73
|
|
|
role_name = discord.utils.get(ctx.guild.roles, name=role)
|
74
|
|
|
if role_name.name == role:
|
75
|
|
|
success.append(role_name)
|
76
|
|
|
else:
|
77
|
|
|
fail.append((role_name, role))
|
78
|
|
|
except AttributeError:
|
79
|
|
|
self.log.error("Attribute error with role {}".format(role))
|
80
|
|
|
fail.append((role, None))
|
81
|
|
|
|
82
|
|
|
message = "There were {} successes and {} failures".format(
|
83
|
|
|
len(success), len(fail))
|
84
|
|
|
await utils.make_embed(ctx, "28b463",
|
85
|
|
|
title="Check Complete",
|
86
|
|
|
description=message)
|
87
|
|
|
|
88
|
|
|
@commands.command(name="get-status", help="Gets all errors or reports for the day.",
|
89
|
|
|
description="Admin Only Feature")
|
90
|
|
|
async def get_status(self, ctx, which: str):
|
91
|
|
|
"""get-status
|
92
|
|
|
---
|
93
|
|
|
|
94
|
|
|
Gets all the errors for the same day.
|
95
|
|
|
|
96
|
|
|
Arguments:
|
97
|
|
|
---
|
98
|
|
|
ctx {discord.ext.commands.Context} -- Context of the command.
|
99
|
|
|
which {str} --- which item to get, reports or errors.
|
100
|
|
|
"""
|
101
|
|
|
if which == "errors":
|
102
|
|
|
columns = "id, message, command, error"
|
103
|
|
|
elif which == "reports":
|
104
|
|
|
columns = "name, message"
|
105
|
|
|
else:
|
106
|
|
|
return await utils.make_embed(ctx, "FF0000", title="Error",
|
107
|
|
|
description="Please pick a valid option.")
|
108
|
|
|
date = datetime.utcnow().strftime("%Y-%m-%d")
|
109
|
|
|
results = await utils.select(which,
|
110
|
|
|
columns,
|
111
|
|
|
"date_trunc('day', time)",
|
112
|
|
|
date)
|
113
|
|
|
if not results:
|
114
|
|
|
await utils.make_embed(ctx, "28b463", title="Success",
|
115
|
|
|
description="No {} for {}".format(which, date))
|
116
|
|
|
else:
|
117
|
|
|
results_string = []
|
118
|
|
|
for result in results:
|
119
|
|
|
results_string.append(" ".join(map(str, result)))
|
120
|
|
|
await utils.list_message(ctx, results_string, which)
|
121
|
|
|
|
122
|
|
|
@commands.command(name="test-log",
|
123
|
|
|
help="Tests to make sure that that logging feature works.",
|
124
|
|
|
description="Admin Only Feature")
|
125
|
|
|
async def check_log(self, ctx):
|
126
|
|
|
"""test-log
|
127
|
|
|
---
|
128
|
|
|
|
129
|
|
|
Tests to make sure that that logging feature works.
|
130
|
|
|
|
131
|
|
|
Arguments:
|
132
|
|
|
---
|
133
|
|
|
ctx {discord.ext.commands.Context} -- Context of the command.
|
134
|
|
|
"""
|
135
|
|
|
await utils.admin_log(self.bot, "TESTING LOG: True", True)
|
136
|
|
|
await utils.admin_log(self.bot, 'TESTING LOG: False', False)
|
137
|
|
|
await utils.make_embed(ctx, color="28b463", title="Test Complete")
|
138
|
|
|
|
139
|
|
|
@commands.Cog.listener()
|
140
|
|
|
async def on_guild_role_update(self, before: discord.Role, after: discord.Role):
|
141
|
|
|
"""on_guild_role_update
|
142
|
|
|
---
|
143
|
|
|
|
144
|
|
|
Runs when a role is edited. Logs the old name and new name then updates the name in the
|
145
|
|
|
table.
|
146
|
|
|
|
147
|
|
|
Arguments:
|
148
|
|
|
---
|
149
|
|
|
before {discord.Role} -- The discord role before it was edited.
|
150
|
|
|
after {discord.Role} -- The discord role after it was edited.
|
151
|
|
|
"""
|
152
|
|
|
managed, _ = await self.managed_role_check(before)
|
153
|
|
|
if managed:
|
154
|
|
|
await utils.update("schools", "school", before.name, after.name)
|
155
|
|
|
self.log.warning("Role \"{}\" was updated. It is now {}".format(before.name,
|
156
|
|
|
after.name))
|
157
|
|
|
else:
|
158
|
|
|
self.log.info("Old role {} now new role {}".format(before, after))
|
159
|
|
|
|
160
|
|
|
await utils.admin_log(self.bot, "Old role {} now new role {}".format(before, after), True)
|
161
|
|
|
|
162
|
|
|
@commands.Cog.listener()
|
163
|
|
|
async def on_guild_role_delete(self, role: discord.Role):
|
164
|
|
|
"""on_guild_role_delete
|
165
|
|
|
---
|
166
|
|
|
|
167
|
|
|
Runs when a role is deleted. Will only delete an entry if it existed in the schools or
|
168
|
|
|
regions table.
|
169
|
|
|
|
170
|
|
|
Arguments:
|
171
|
|
|
---
|
172
|
|
|
role {discord.Role} -- The role that was deleted.
|
173
|
|
|
"""
|
174
|
|
|
managed, table = await self.managed_role_check(role)
|
175
|
|
|
if managed:
|
176
|
|
|
await utils.delete("schools", "id", role.id)
|
177
|
|
|
self.log.warning("Role \"{}\" was deleted. It was in {}".format(role.name, table))
|
178
|
|
|
else:
|
179
|
|
|
self.log.info("Role \"{}\" was deleted. It was not a managed role".format(role.name))
|
180
|
|
|
|
181
|
|
|
await utils.admin_log(self.bot, "Role: {} was deleted".format(role.name), True)
|
182
|
|
|
|
183
|
|
|
async def managed_role_check(self, role: discord.Role):
|
184
|
|
|
"""managed_role_check
|
185
|
|
|
---
|
186
|
|
|
|
187
|
|
|
Checks to see if the updated one was one that the bot cares about.
|
188
|
|
|
|
189
|
|
|
Arguments:
|
190
|
|
|
role {discord.Role} -- [description]
|
191
|
|
|
|
192
|
|
|
Returns:
|
193
|
|
|
bool -- returns True if the role was cared about or does not return.
|
194
|
|
|
"""
|
195
|
|
|
for table in ["schools", "regions"]:
|
196
|
|
|
if await utils.select(table, "id", "id", role.id):
|
197
|
|
|
return True, table
|
198
|
|
|
|
199
|
|
|
|
200
|
|
|
def setup(bot):
|
201
|
|
|
"""Needed for extension loading"""
|
202
|
|
|
bot.add_cog(HealthCog(bot))
|
203
|
|
|
|