forked from shashankpandey04/Cyni
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcyni.py
345 lines (290 loc) · 11.7 KB
/
cyni.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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
import discord
from discord.abc import User
from discord.ext import commands
from discord.ext import tasks
from utils.mongo import Document
from utils.constants import BLANK_COLOR
import sentry_sdk
import asyncio
import aiohttp
from pkgutil import iter_modules
import logging
import os
import time
from dotenv import load_dotenv
import motor.motor_asyncio
from utils.utils import get_prefix
from Modals.ban_appeal import BanAppealModal
from Datamodels.Settings import Settings
from Datamodels.Analytics import Analytics
from Datamodels.Warning import Warnings
from Datamodels.StaffActivity import StaffActivity
from Datamodels.Errors import Errors
from Datamodels.Sessions import Sessions
from Datamodels.Infraction_log import Infraction_log
from Datamodels.Infraction_types import Infraction_type
from Datamodels.Giveaway import Giveaway
from Datamodels.Backup import Backup
from Datamodels.afk import AFK
from Datamodels.Erlc_keys import ERLC_Keys
from Datamodels.Applications import Applications
from Datamodels.Partnership import Partnership
from utils.prc_api import PRC_API_Client
from decouple import config
load_dotenv()
intents = discord.Intents.all()
discord.utils.setup_logging(level=logging.INFO)
class Bot(commands.AutoShardedBot):
async def close(self):
print('Closing...')
await super().close()
print('Closed!')
async def is_owner(self, user: User) -> bool:
if user.id in [
1201129677457215558, #coding.nerd
707064490826530888, #imlimiteds
]:
return True
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.mongo = motor.motor_asyncio.AsyncIOMotorClient(os.getenv('MONGO_URI'))
self.db = self.mongo["cyni"] if os.getenv("PRODUCTION_TOKEN") else self.mongo["dev"]
self.settings_document = Document(self.db, 'settings')
self.analytics_document = Document(self.db, 'analytics')
self.warnings_document = Document(self.db, 'warnings')
self.actvity_document = Document(self.db, 'staff_activity')
self.appeals_document = Document(self.db, 'ban_appeals')
self.errors_document = Document(self.db, 'errors')
self.sessions_document = Document(self.db, 'sessions')
self.infraction_log_document = Document(self.db, 'infraction_log')
self.infraction_types_document = Document(self.db, 'infraction_types')
self.giveaway_document = Document(self.db, 'giveaways')
self.backup_document = Document(self.db, 'backup')
self.afk_document = Document(self.db,'afk')
self.erlc_keys_document = Document(self.db, 'erlc_keys')
self.applications_document = Document(self.db, 'applications')
self.partnership_document = Document(self.db, 'partnership')
async def setup_hook(self) -> None:
self.settings = Settings(self.db, 'settings')
self.analytics = Analytics(self.db, 'analytics')
self.warnings = Warnings(self.db, 'warnings')
self.staff_activity = StaffActivity(self.db, 'staff_activity')
self.ban_appeals = Document(self.db, 'ban_appeals')
self.errors = Errors(self.db, 'errors')
self.sessions = Sessions(self.db, 'sessions')
self.infraction_log = Infraction_log(self.db, 'infraction_log')
self.infraction_types = Infraction_type(self.db, 'infraction_types')
self.giveaways = Giveaway(self.db, 'giveaways')
self.backup = Backup(self.db, 'backup')
self.afk = AFK(self.db,'afk')
self.erlc_keys = ERLC_Keys(self.db, 'erlc_keys')
self.prc_api = PRC_API_Client(self, base_url=config('PRC_API_URL'), api_key=config('PRC_API_KEY'))
self.applications = Applications(self.db, 'applications')
self.partnership = Partnership(self.db, 'partnership')
Cogs = [m.name for m in iter_modules(['Cogs'],prefix='Cogs.')]
Events = [m.name for m in iter_modules(['events'],prefix='events.')]
for extension in Cogs:
try:
await self.load_extension(extension)
logging.info(f'Loaded extension {extension}.')
except Exception as e:
logging.error(f'Failed to load extension {extension}.', exc_info=True)
for extension in Events:
try:
await self.load_extension(extension)
logging.info(f'Loaded extension {extension}.')
except Exception as e:
logging.error(f'Failed to load extension {extension}.', exc_info=True)
logging.info("Connected to MongoDB")
change_status.start()
logging.info(f"Logged in as {bot.user}")
await bot.tree.sync()
bot = Bot(
command_prefix=get_prefix,
case_insensitive=True,
intents=intents,
help_command=None,
allowed_mentions=discord.AllowedMentions(everyone=False, roles=False, users=True),
shard_count=1
)
bot_debug_server = [1152949579407442050]
bot_shard_channel = 1203343926388330518
afk_users = {}
@bot.event
async def on_shard_ready(shard_id):
embed = discord.Embed(
title="Shard Connected",
description=f"Shard ID `{shard_id}` connected successfully.",
color=BLANK_COLOR
)
await bot.get_channel(bot_shard_channel).send(embed=embed)
@bot.event
async def on_shard_disconnect(shard_id):
embed = discord.Embed(
title="Shard Disconnected",
description=f"Shard ID `{shard_id}` disconnected.",
color=BLANK_COLOR
)
await bot.get_channel(bot_shard_channel).send(embed=embed)
@bot.before_invoke
async def AutoDefer(ctx: commands.Context):
webhook_link = os.getenv("CYNI_LOGS_WEBHOOK")
embed = discord.Embed(
title="Command Used",
description=f"Command `{ctx.command}` used.",
color=BLANK_COLOR
)
async with aiohttp.ClientSession() as session:
async with session.post(webhook_link, json={'embeds': [embed.to_dict()]}) as response:
if response.status == 204:
return
else:
logging.error(f"Failed to send webhook. Status: {response.status}")
analytics = await bot.analytics.find_by_id(
ctx.command.full_parent_name + f"{ctx.command.name}"
)
if not analytics:
await bot.analytics.insert(
{
"_id": ctx.command.full_parent_name + f"{ctx.command.name}",
"uses": 1
}
)
else:
await bot.analytics.upsert(
{
"_id": ctx.command.full_parent_name + f"{ctx.command.name}",
"uses": analytics["uses"] + 1
}
)
@bot.after_invoke
async def loggingCommand(ctx: commands.Context):
logging.info(f"{ctx.author} used {ctx.command} in {ctx.guild}.")
@bot.tree.command()
async def banappeal(interaction: discord.Interaction):
'''
Appeal a ban.
'''
await interaction.response.send_modal(BanAppealModal(bot))
@tasks.loop(hours=1)
async def change_status():
await bot.wait_until_ready()
logging.info("Changing status")
status = "✨ /about | Cyni v7.4"
await bot.change_presence(
activity=discord.CustomActivity(name=status)
)
up_time = time.time()
class PremiumRequired(commands.CheckFailure):
def __init__(self, message="<:declined:1268849944455024671> This server doesn't have Cyni Premium!"):
self.message = message
super().__init__(self.message)
async def staff_check(bot,guild,member):
if member.guild_permissions.administrator:
return True
guild_settings = await bot.settings.get(guild.id)
if guild_settings:
if "staff_roles" in guild_settings["basic_settings"].keys():
if guild_settings["basic_settings"]["staff_roles"] != []:
if isinstance(guild_settings["basic_settings"]["staff_roles"], list):
for role in guild_settings["basic_settings"]["staff_roles"]:
if role in [role.id for role in member.roles]:
return True
elif isinstance(guild_settings["basic_settings"]["staff_roles"], int):
if guild_settings["basic_settings"]["staff_roles"] in [role.id for role in member.roles]:
return True
if member.guild_permissions.administrator:
return True
return False
async def management_check(bot,guild,member):
if member.guild_permissions.administrator:
return True
guild_settings = await bot.settings.get(guild.id)
if guild_settings:
if "management_roles" in guild_settings["basic_settings"].keys():
if guild_settings["basic_settings"]["management_roles"] != []:
if isinstance(guild_settings["basic_settings"]["management_roles"], list):
for role in guild_settings["basic_settings"]["management_roles"]:
if role in [role.id for role in member.roles]:
return True
elif isinstance(guild_settings["basic_settings"]["management_roles"], int):
if guild_settings["basic_settings"]["management_roles"] in [role.id for role in member.roles]:
return True
if member.guild_permissions.administrator:
return True
return False
async def staff_or_management_check(bot,guild,member):
if member.guild_permissions.administrator:
return True
if await staff_check(bot,guild,member) or await management_check(bot,guild,member):
return True
return False
async def premium_check(bot, guild):
guild_settings = await bot.settings.get(guild.id)
if guild_settings:
try:
if "premium" in guild_settings.keys():
if guild_settings['premium']['enabled']:
return True
except KeyError:
return False
def is_staff():
async def predicate(ctx):
if await staff_check(ctx.bot,ctx.guild,ctx.author):
return True
raise commands.MissingPermissions(["Staff"])
return commands.check(predicate)
def is_management():
async def predicate(ctx):
if await management_check(ctx.bot,ctx.guild,ctx.author):
return True
raise commands.MissingPermissions(["Management"])
return commands.check(predicate)
def is_staff_or_management():
async def predicate(ctx):
if await staff_or_management_check(ctx.bot,ctx.guild,ctx.author):
return True
raise commands.MissingPermissions(["Staff or Management"])
return commands.check(predicate)
async def fetch_invite(guild_id):
guild = bot.get_guild(guild_id)
if not guild:
raise ValueError("Guild not found.")
try:
invite = await guild.vanity_invite()
return invite.url
except discord.Forbidden:
pass
try:
invites = await guild.invites()
if invites:
return invites[0].url
except discord.Forbidden:
pass
try:
invite = await guild.text_channels[0].create_invite()
return invite.url
except discord.Forbidden:
raise ValueError("Failed to get invite")
def is_premium():
async def predicate(ctx):
if await premium_check(ctx.bot, ctx.guild):
return True
raise PremiumRequired()
return commands.check(predicate)
if os.getenv("PRODUCTION_TOKEN"):
bot_token = os.getenv("PRODUCTION_TOKEN")
logging.info("Production Token")
elif os.getenv("PREMIUM_TOKEN"):
bot_token = os.getenv("PREMIUM_TOKEN")
logging.info("Using Premium Token")
else:
bot_token = os.getenv("DEV_TOKEN")
logging.info("Using Development Token")
def run():
try:
bot.run(bot_token)
except Exception as e:
logging.error(f"Error: {e}", exc_info=True)
if __name__ == "__main__":
run()