-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
180 lines (153 loc) · 6.23 KB
/
main.py
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/python3
# TODO standardize help
# TODO create a git commit for server join count
# TODO server invite link
# TODO update help files
# TODO redo the logging to actually be useful
# TODO fix mention suppression on quotes
import logging
import pendulum
import discord
import configparser
import switchboard
import tquote
import tcustom
from tutil import is_admin, config_create, fetch_file, is_admin_test
from tutil import setup as util_setup
from constants import TOKEN, POC_TOKEN, VERSION, DIVIDER, VERBOSE, DEFAULT_DIR, BOT
# Read in server config
config = configparser.ConfigParser()
config.read(DEFAULT_DIR + '/config.ini')
@BOT.event
async def on_ready() -> None:
print(
f'{BOT.user} has connected to Discord!\n'
f'Revision date: {VERSION}\n'
)
if VERBOSE >= 0:
count = 0
for each in BOT.guilds:
print(
f'{each.name}(id: {each.id})\n'
f'Member count: {each.member_count}'
)
count += each.member_count
print('Total guilds: {}'.format(len(BOT.guilds)))
print('Total members: {}'.format(count))
print('***🟢 ------------ Server Online ------------ 🟢***')
await BOT.change_presence(status=discord.Status.idle, activity=None)
@BOT.event
async def on_guild_join(guild: discord.guild) -> None:
"""
Create a blank new config in the database and send a DM to the guild owner.
:param guild:
:return:
"""
if VERBOSE >= 1:
print('[+] Joined a new guild: {}'.format(guild.name))
config_file = config_create(guild)
banner = 'Hello {}! \n{}'.format(guild.owner.mention, fetch_file('help', 'welcome'))
await guild.owner.send(file=discord.File('{}/docs/header.png'.format(DEFAULT_DIR)))
await guild.owner.send(banner, file=discord.File(config_file))
tquote.setup()
util_setup()
@BOT.event
async def on_message(message: discord.Message) -> None:
"""
Dispatch the raw message object to switchboard.py
Switchboard filters input then redirects to dedicated functions
Send discord.Message object to Discord API for posting, return None
:param message:
:return:
"""
banner = await switchboard.dispatch(message)
# TODO multi page pretty print
if banner:
if banner["rawText"] and banner["file"]:
await message.channel.send(banner["rawText"], file=banner["file"])
elif banner["embed"] and banner["file"]:
await message.channel.send(embed=banner["embed"], file=banner["file"])
elif banner["embed"]:
if type(banner["embed"]) is list:
await message.channel.send(embed=banner["embed"][0])
await message.channel.send(embed=banner["embed"][1])
else:
await message.channel.send(embed=banner["embed"])
elif banner["file"]:
print(banner)
with open(banner["file"], 'rb') as fp:
await message.channel.send(file=discord.File(fp, fp.name.split('\\')[-1]))
elif banner["rawText"]:
# TODO notify results are too long and clip
if type(banner["rawText"]) is list:
for each in banner["rawText"]:
await message.channel.send(each)
else:
await message.channel.send(banner["rawText"])
@BOT.event
async def on_raw_reaction_add(payload: discord.RawReactionActionEvent) -> None:
"""
Called whenever a reaction is added to a message.
Using on_raw_reaction_add() instead of on_reaction_add() because
on_raw is called regardless of the state of the internal message cache.
Python and Discord are picky about the emoji string comparison, if
you encounter issues, keep trying different things.
:param payload:
:return:
"""
channel = BOT.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
print(payload)
print(payload.emoji)
# Add a quote
# emoji is :speech_left:
if str(payload.emoji) == '🗨️' and not message.author.BOT:
# print('caught speech')
if not tquote.check_if_exists(message.guild.id, message.id):
# print('does not exist yet')
banner = tquote.insert_quote(message, None, payload.member.name)
if VERBOSE >= 2:
print('[+] Added quote {}.'.format(banner))
await message.channel.send(embed=banner)
# Remove a quote
# emoji is :x:
if str(payload.emoji) == '❌' and await is_admin_test(payload.member, message):
try:
banner = tquote.delete_quote(message.guild.id, message.id)
if VERBOSE >= 2:
print('[+] Deleted quote: {}'.format(banner))
await message.channel.send(banner)
except Exception as e:
if VERBOSE >= 1:
print('[!] Exception in Remove quote: {}'.format(e))
pass
if VERBOSE >= 2:
print('[+] Deleting command.')
await message.channel.send(await tcustom.delete_command(message))
# Add a custom guild command
# emoji is :gear:
if str(payload.emoji) == '⚙️' and await is_admin_test(payload.member, message):
if VERBOSE >= 2:
print('[+] Added command.')
await message.channel.send(embed=tcustom.insert_command(message))
# TODO redo logging with loguru
@BOT.event
async def on_error(event, *args, **kwargs):
# For errors with the BOT itself
with open('./log/err.log', 'a') as f:
if event == 'on_message':
timestamp = pendulum.now(tz='America/Phoenix').to_datetime_string()
location = '[!] Error in: {}; {}'.format(args[0].channel.name, args[0].guild.name)
content = '[!] Error content: {}'.format(args[0].content)
author = '[!] Error author: {}'.format(args[0].author)
f.write('{}\nUnhandled message:{}\n{}\n{}\n{}\n\n'.format(
timestamp,
args[0],
location,
author,
content,
))
else:
return
BOT.run(POC_TOKEN)
# client.run(config['discord']['Key'])