-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreto.py
230 lines (200 loc) Β· 8.61 KB
/
reto.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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# Import global variables and databases.
from definitions import bottoken, botname, botver, prefix, debug, db, srv, activity, customprefix, gusername, grepo
# Imports, database definitions and all that kerfuffle.
import discord
from discord.ext import commands, tasks
import asyncio
import pyfiglet
from tinydb import TinyDB, Query, where
from tinydb.operations import add, subtract, delete
import aiohttp
import aiofiles
import os.path
import os
import requests
import json
import random
from datetime import datetime, date
import logging
import traceback
import sys
from colorama import init, Fore, Back, Style
from yaspin import yaspin
# sharedFunctions
from sharedFunctions import printLeaderboard, createLeaderboardEmbed, getProfile, sendErrorEmbed, reactionAdded, reactionRemoved
# ----------------------------------------------------------------------------------------------
# Start Colorama ANSI
init(autoreset=True)
# Loading icon
spinner = yaspin(text="Loading " + botname + "... " + Style.DIM + "(This may take a while.)", color="blue")
spinner.start()
# Set up logging
logger = logging.getLogger('discord')
logger.setLevel(logging.DEBUG)
if not os.path.exists('logs'):
os.makedirs('logs')
handler = logging.FileHandler(filename='logs/discord-' + datetime.now().strftime("%Y-%m-%d") + '.log', encoding='utf-8', mode='w')
handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
logger.addHandler(handler)
getactivities = activity.all()
botactivity = []
for value in getactivities:
botactivity.append(value["activity"])
def get_prefix(bot, msg):
customprefix.clear_cache()
if not msg.guild: # is on DMs
return commands.when_mentioned_or(prefix)(bot,msg)
else:
pre = customprefix.search(Query().server == msg.guild.id)
if pre:
return pre[0]["prefix"] # custom prefix on json db
else:
return prefix # default prefix
bot = commands.Bot(command_prefix=get_prefix)
client = discord.Client()
asciiBanner = pyfiglet.figlet_format(botname, justify="center")
@bot.command
async def load(ctx, extension):
bot.load_extension(f'cogs.{extension}')
@bot.command
async def unload(ctx, extension):
bot.unload_extension(f'cogs.{extension}')
@bot.event
async def on_raw_reaction_add(payload):
await reactionAdded(bot, payload)
@bot.event
async def on_raw_reaction_remove(payload):
await reactionRemoved(bot, payload)
@bot.event
async def on_command(ctx):
print("β³ " + Fore.YELLOW + ctx.message.author.name + Style.RESET_ALL + " invoked " + Fore.YELLOW + prefix + ctx.command.name)
@bot.event
async def on_command_completion(ctx):
print("β
" + Fore.GREEN + ctx.message.author.name + Style.RESET_ALL + " invoked " + Fore.GREEN + prefix + ctx.command.name)
for file in os.listdir("./cogs"):
if file.endswith(".py"):
bot.load_extension(f'cogs.{file[:-3]}') #[:-3] removes the last 3 chars
# Error handler.
@bot.event
async def on_command_error(ctx, error):
ignored = (commands.CommandNotFound, )
error = getattr(error, 'original', error)
if isinstance(error, discord.ext.commands.errors.ChannelNotFound):
await sendErrorEmbed(ctx, "I can't find that channel! Make sure you're adding a (valid) Channel element.")
if isinstance(error, ignored):
return
if isinstance(error, discord.ext.commands.CommandNotFound):
return
if isinstance(error, discord.ext.commands.DisabledCommand):
await sendErrorEmbed(ctx, f'{ctx.command} has been disabled.')
elif isinstance(error, discord.ext.commands.NoPrivateMessage):
try:
await sendErrorEmbed(ctx.author, f'{ctx.command} can not be used in Private Messages.')
except discord.HTTPException:
pass
elif isinstance(error, commands.BadArgument):
if ctx.command.qualified_name == 'tag list':
await sendErrorEmbed(ctx, "Can't find that member, for whatever reason. Please try again.")
elif isinstance(error, discord.ext.commands.errors.MissingPermissions):
await sendErrorEmbed(ctx, "You're missing the required permissions to run this command!")
else:
print("β Ignoring exception in command {}:".format(ctx.command), file=sys.stderr)
traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
nameTraceback = str(error).capitalize()
formattedTraceback = "\n".join(traceback.format_exception(type(error), error, error.__traceback__))
await sendErrorEmbed(ctx, nameTraceback + ".\n\n```py\n%s\n```" % formattedTraceback)
raise error
@bot.event
async def on_ready():
# Windows
os.system('cls')
# Linux
os.system('clear')
# Stop spinner
spinner.stop()
# Coloured Reto banner
# Kinda hardcoded, but the alternative wasn't pretty either
asciiLines = asciiBanner.splitlines()
print(Style.BRIGHT +Fore.CYAN + asciiLines[0])
print(Fore.CYAN + asciiLines[1])
print(Style.BRIGHT + Fore.BLUE + asciiLines[2])
print(Fore.BLUE + asciiLines[3])
print(Style.DIM + Fore.BLUE + asciiLines[4])
print(Style.DIM + Fore.BLUE + asciiLines[5])
# Get bot info for the startup dashboard
serverPlural = "server"
if len(bot.guilds) > 1:
serverPlural = "servers"
print ("π’ " + botname + " is " + Fore.GREEN + "ONLINE" + Style.RESET_ALL + " | " + Fore.BLUE + str(bot.user)
+ Style.RESET_ALL + " on " + Fore.YELLOW + str(len(bot.guilds)) + Style.RESET_ALL + " " + serverPlural +
" | v" + Fore.CYAN + botver)
if debug:
print ('β οΈ ' + Fore.YELLOW + ' Running on Debug Mode' + Style.RESET_ALL + '. Disable it after you\'re done in json/config.json.')
print ("π« Invite link: " + Fore.BLUE + "https://discord.com/oauth2/authorize?client_id=" + str(bot.user.id) + "&permissions=1342524496&scope=bot")
# Check for updates
updateSpinner = yaspin(text="Looking for updates...", color="red")
updateSpinner.start()
r = requests.get("https://api.github.com/repos/" + gusername + "/" + grepo + "/releases")
j=r.json()
if j:
if not "message" in j:
if j[0]["tag_name"] != botver:
updateSpinner.stop()
print("π [v" + j[0]["tag_name"] + "] " + Fore.RED + "A new version of " + botname + " is available!\n"
+ Style.RESET_ALL + " Get it at " + Fore.BLUE + "https://github.com/despedite/reto/releases")
else:
updateSpinner.text = "You're up to date!"
await asyncio.sleep(1)
else:
updateSpinner.text = "Something went wrong while fetching updates."
await asyncio.sleep(1)
updateSpinner.stop()
print('\n' + 'β' * 25 + " Get started with " + Fore.GREEN + "?setup " + Style.RESET_ALL + 'β' * 25 + '\n')
# Warning for users who've yet to migrate to the new database system. (really, you guys?)
olddb = TinyDB("json/db.json")
if ((not db) and (olddb)):
print("""π It looks like you're using the old database system from v1.5.2
(or earlier!) If that isn't the case, dismiss this message. If you've just
upgraded your """ + botname + """ version, you may need to encrypt your old databases
to the new format before continuing to use """ + botname + """.
More info here: """ + Fore.BLUE + """https://github.com/despedite/reto/wiki/Migrating-databases
""")
print('β' * 75 + '\n')
#async def on_guild_post():
# print("Server count posted successfully")
# Set bot's activity
global botactivity
if not botactivity:
botactivity = [prefix + 'setup to get started!', 'Hey, bot owner - change the default activities with ' + prefix + 'activity!']
if botver != "":
game = discord.Game(botactivity[random.randrange(len(botactivity))] + " | v" + botver)
else:
game = discord.Game(botactivity[random.randrange(len(botactivity))])
await bot.change_presence(activity=game)
bot.loop.create_task(statusupdates())
@bot.event
async def on_guild_join(guild):
srv.upsert({'serverid': guild.id, 'heart': 'plus', 'crush': 'minus', 'star': '10', 'global': True}, Query().serverid == guild.id)
for channel in guild.text_channels:
if channel.permissions_for(guild.me).send_messages:
embed=discord.Embed(title="Thank you for inviting " + botname + "!", description="Try using the ?setup command to get started!\nIf any problems arise, [join our Discord server](https://google.com) so we can give you a hand.")
embed.set_thumbnail(url="https://i.ibb.co/ySfQhDG/reto.png")
await channel.send(embed=embed)
break
async def statusupdates():
while True:
await asyncio.sleep(60)
# update the activity list
activity.clear_cache()
getactivities = activity.all()
botactivity = []
for value in getactivities:
botactivity.append(value["activity"])
if not botactivity:
botactivity = [prefix + 'setup to get started!', 'Hey, bot owner - change the default activities with ' + prefix + 'activity!']
if botver != "":
game = discord.Game(botactivity[random.randrange(len(botactivity))] + " | v" + botver)
else:
game = discord.Game(botactivity[random.randrange(len(botactivity))])
await bot.change_presence(activity=game)
bot.run(bottoken)