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