This repository has been archived by the owner on Aug 4, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcode.py
1255 lines (1147 loc) · 64.1 KB
/
code.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
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env python3.7
# -*- coding: utf-8 -*-
import gtts
import gtts.lang
from discord.ext import commands
import urllib.request
import urllib.parse
import discord
import math
import random
import time
import datetime
import aiohttp
import functools
import inspect
import re
import io
import contextlib
import traceback
from googletrans import Translator
import json
from databasestuff import GuildDB
from paginator import *
from simplepaginator import SimplePaginator
import quantumutils as utils
from dbwrapper import *
blacklisted = []
info = json.loads(open("configs.json").read())
async def getprefix(bot,message:discord.Member):
bot.db.set_collection("guilds")
m = await bot.db.find(length=2,id=message.guild.id)
if m:
m=[m[0]["prefix"]]
return commands.when_mentioned_or(*(list(info["bot"]["prefixes"])+m))(bot,message)
bot = commands.Bot(description='Tune in to lots of fun with this bot!',
command_prefix=getprefix)
bot.db=GuildDB()
premium_embed=discord.Embed(title="This is a Premium feature.",description="In order to use this feature, please consider buying **Quantum Bot premium**. It's very cheap, at USD0.80 per month!",
colour=discord.Colour.dark_blue(),footer="Type \"q!premium buy\" for more info.")
class MemberInThisGuild(commands.Converter):
async def convert(self, ctx, argument):
if not ctx.guild:
raise commands.CheckError('This can only be run in a guild')
member = None
try:
id = int(argument)
member = ctx.guild.get_member(id)
except ValueError:
match = re.match("<!?@(\d+)>", argument)
if match:
id = int(match.group(1))
member = ctx.guild.get_member(id)
else:
member = ctx.guild.get_member_named(argument)
if member is None:
raise commands.BadArgument('Unrecognised member')
return member
# commands
class Math:
'''for mathematical fun'''
@commands.command()
async def add(self, ctx, *, numbers):
'''returns sum of numbers separated with spaces'''
try:
await ctx.send(str(sum([int(i) for i in numbers.split()])))
except:
await ctx.send("You didn't give the correct arguments.")
@commands.command()
async def mul(self, ctx, *, numbers):
'''returns product of arguments separated with spaces'''
try:
m = lambda x, y: x * y
await ctx.send(str(functools.reduce(m, [int(i) for i in numbers.split()])))
except:
await ctx.send("You didn't give the correct arguments.")
@commands.command()
async def factorial(self, ctx, num: int):
'''returns the factorial of the given input'''
try:
await ctx.send(embed=discord.Embed(title="%d! is equal to..." % num, description=str(math.factorial(num))))
except Exception as p:
await ctx.send(embed=discord.Embed(title=type(p) + " raised!", description=p.args[1]))
@commands.command()
async def collatz(self, ctx, num: int):
'''dedicated to the famous conjecture, will return the steps from input to 1'''
nums = [num]
last = num
while last > 1:
if last % 2 == 0:
last //= 2
else:
last = last * 3 + 1
nums.append(last)
nums = list(map(str, nums))
ranhex = random.randint(0, 255)
await ctx.send(embed=discord.Embed(title="Collatzing your way through %d" % num, description=",".join(nums),
colour=discord.Colour.from_rgb(ranhex, ranhex, ranhex)))
class Admin:
'''for administrative purposes'''
@commands.command()
async def kick(self, ctx, member: MemberInThisGuild):
'''Kick members from your server'''
try:
await member.kick(reason=f'{ctx.author} banned {member}')
await ctx.message.add_reaction('\u2705')
except:
await ctx.message.add_reaction('\u274C')
@commands.command()
async def ban(self, ctx, member: MemberInThisGuild):
'''Ban toxic members from your server'''
try:
await member.ban(reason=f'{ctx.author} banned {member}')
await ctx.message.add_reaction('\u2705')
except:
await ctx.message.add_reaction('\u274C')
@commands.command(aliases=['ar', 'updaterole'])
async def changerole(self, ctx, member: MemberInThisGuild, role: discord.Role):
'''to add/remove a role from a person'''
try:
if role not in member.roles:
await ctx.author.add_roles(role)
else:
await ctx.author.remove_roles(role)
await ctx.message.add_reaction('\u2705')
except:
await ctx.message.add_reaction('\u274C')
class General:
'''commands available for everyone'''
@commands.command(aliases=['how2makebots','howtomakebot','how2makebot'])
async def howtomakebots(self,ctx):
'''For people who want to make discord bots'''
await ctx.send(embed=discord.Embed(title="Join this server",
colour=discord.Colour.dark_blue(),
description="This server teaches how to make Discord Bots using Python or Javascript.\nClick Here --> [Bot Tutorial Server](https://discord.gg/GWdhBSp)").set_thumbnail(
url="https://images-ext-1.discordapp.net/external/3Nz9MrHwWr8gwkV8c7LBTioqIr4pX7akzwufLBQoMEM/%3Fsize%3D1024/https/cdn.discordapp.com/icons/265828729970753537/88327d2afd3b45a0e08cbd81caabf357.webp"))
@commands.command()
async def ping(self, ctx):
'''checks the time taken for the bot to respond'''
start = time.monotonic()
msg = await ctx.send("Pinging... 🕒")
millis = (time.monotonic() - start) * 1000
heartbeat = ctx.bot.latency * 1000
await msg.edit(content=f'Heartbeat: {heartbeat:,.2f}ms Response: {millis:,.2f}ms. ⏲️')
@commands.command()
async def say(self, ctx, *, text='Quantum Bot here!!'):
'''The bot becomes your copycat='''
await ctx.send(text)
await ctx.message.delete()
@commands.command()
async def now(self, ctx):
'''Get current date and time'''
m = str(datetime.datetime.now()).split()
embed = discord.Embed(title="Date-time information", color=eval(hex(ctx.author.color.value)))
embed.add_field(name="Date", value="{}".format(m[0]))
embed.add_field(name="Time", value="{}GMT".format(m[1]))
await ctx.send(embed=embed)
class Feedback:
'''feedback related commands'''
@commands.command(aliases=['fb'])
async def feedback(self, ctx, *, message):
'''My bot is not very good, feedback is appreciated!'''
author = ctx.message.author.name + " said in " + "'" + ctx.guild.name + "'"
await bot.get_guild(413290013254615041).get_channel(413631317272690688).send(
embed=discord.Embed(color=eval(hex(ctx.author.color.value)), title=author,
description="#" + ctx.channel.name + ":\n" + message))
await ctx.message.add_reaction('\u2705')
@commands.command()
async def suggest(self, ctx, command, *, description):
'''suggest commands I should work on, and follow by a short description on how it works'''
author = ctx.message.author.name
m = await bot.get_guild(413290013254615041).get_channel(413631317272690688).send(
embed=discord.Embed(title=author + " suggested a command '" + command + "'", description=description,
color=ctx.author.color))
await m.add_reaction("\u2705")
await m.add_reaction("\u274C")
r = await bot.wait_for('reaction_add', check=lambda reaction, author: (author.id == info["hierarchy"]["owner"]) and (
reaction.emoji in ["\u2705", "\u274C"]))
if r[0].emoji == "\u2705":
await ctx.author.send("Your command {} has been accepted by the owner.".format(command))
await m.edit(embed=discord.Embed(title="Command to work on: " + command, description=description))
elif r[0].emoji == "\u274C":
await ctx.author.send("Your command {} has been rejected by the owner.".format(command))
await m.delete()
class Information:
'''To know more about the bot'''
@commands.command()
async def botinfo(self, ctx):
'''some stats about the bot'''
serv = len(bot.guilds)
membs = len(bot.users)
creator = "Pegasus#4022"
date = f"{bot.user.created_at: %B %d, %Y at %H:%M:%S GMT}"
await ctx.send(embed=discord.Embed(title="Some bot statistics",
description="```Servers streaming: {}\nUsers streaming: {}\nCreator: {}\nCreation date: {}\nBot Owner: {}```".format(
serv, membs, creator, date, "Dark Angel#4022"), color=ctx.author.colour))
@commands.command()
async def prefix(self, ctx):
'''list of all prefixes my bot uses'''
prefixlist = tuple(["@Quantum Bot"] + list(info["bot"]["prefixes"]))
await ctx.send("```" + ",".join(list(prefixlist)) + "```" + '\n' + str(len(prefixlist)) + " prefixes")
@commands.command()
async def invite(self, ctx):
'''link to invite my bot elsewhere'''
await ctx.send(embed=discord.Embed(title="Some bot related links",
description="This is my bot invite:\nhttps://discordapp.com/api/oauth2/authorize?client_id=384623978028859392&permissions=335932630&scope=bot\nPlease consider joining this server too:https://discord.gg/ngaC2Bh\nCheck out Quantum Bot's official site:http://quantum-bot.me",
color=eval(hex(ctx.author.color.value))))
@commands.command()
async def getpeople(self, ctx, *, rolename=None):
'''find all people with a particular role name,bolding means that that is the user's top role'''
people = []
role = discord.utils.get(ctx.guild.roles, name=rolename)
for i in role.members:
if i.top_role == role:
people.append("**" + i.name + "**")
else:
people.append(i.name)
if len(people) > 80:
content = "More than 80 people have this role. I'd rather not state all the people with this role"
else:
content = ",".join(people)
await ctx.send(
embed=discord.Embed(title="People with the role '%s'" % role.name, color=eval(hex(ctx.author.color.value)),
description=content))
@commands.command()
async def serverinfo(self, ctx):
'''get more info on the server'''
members = len(ctx.guild.members)
owner = ctx.guild.owner
created = f"{ctx.guild.created_at: %B %d, %Y at %H:%M:%S GMT}"
server = ctx.guild.name
sid = ctx.guild.id
ver = ["None", "Low", "Medium", "High", "Ultra High"][ctx.guild.verification_level]
region = ctx.guild.region
embed = discord.Embed(color=discord.Color(0x000000), title="Server Info:", description="""Server Name:{}\nServer Id:{}\n
Server Region:{}\nMember count:{}\nOwner:{}\nCreated On:{}\nNumber of text channels:{}\nNumber of voice channels:{}\nVerification Level={}""".format(
server, sid, region, members, owner, created, len(ctx.guild.text_channels), len(ctx.guild.voice_channels),
ver))
embed.set_thumbnail(url=ctx.guild.icon_url)
await ctx.send(embed=embed)
@commands.command(pass_context=True)
async def perms(self, ctx, user: discord.Member = None):
'''find what you can do on this server'''
user = ctx.message.author if user is None else user
if not user:
user = ctx.author
mess = []
for i in user.guild_permissions:
if i[1]:
mess.append("\u2705 {}".format(i[0]))
else:
mess.append("\u274C {}".format(i[0]))
await ctx.send(embed=discord.Embed(colour=discord.Colour(0xFF0000), title=user.name + " guild permissions",
description="\n".join(mess)))
@commands.command()
async def roleperms(self, ctx, role: discord.Role = None):
'''gets the server permissions of a role'''
role = ctx.author.top_role if role is None else role
mess = []
for i in role.permissions:
if i[1]:
mess.append("\u2705 {}".format(i[0]))
else:
mess.append("\u274C {}".format(i[0]))
await ctx.send(embed=discord.Embed(colour=discord.Colour(0xFF0000), title=role.name + " guild permissions",
description="\n".join(mess)))
@commands.command()
async def permcheck(self, ctx, perm='all_perms', user: discord.Member = None):
'''checks specific permissions,type all_perms/leave empty for full list'''
user = ctx.message.author if user is None else user
permlist = dict(user.guild_permissions)
if perm == 'all_perms':
await ctx.send(embed=discord.Embed(colour=discord.Colour(0x000000), title="All permissions listed",
description="\n".join(dict(user.guild_permissions).keys())))
return "\n".join(dict(user.guild_permissions).keys())
await ctx.send(permlist[perm] * "\u2705" + (1 - permlist[perm]) * "\u274C")
return permlist[perm]
@commands.command(name='help')
async def _help(self, ctx, *, command: str = None):
"""Shows help about a command or the bot"""
try:
if command is None:
p = await HelpPaginator.from_bot(ctx)
else:
entity = bot.get_cog(command) or bot.get_command(command)
if entity is None:
clean = command.replace('@', '@\u200b')
return await ctx.send(f'Command or category "{clean}" not found.')
elif isinstance(entity, commands.Command):
p = await HelpPaginator.from_command(ctx, entity)
else:
p = await HelpPaginator.from_cog(ctx, entity)
await p.paginate()
except Exception as e:
await ctx.send(traceback.format_exception(None, e, e.__traceback__))
class Fun:
'''have fun with these commands'''
@commands.command()
async def dice(self, ctx, times=1):
'''Roll a dice as many times as you like'''
total = []
for i in range(times):
total.append(random.randint(1, 6))
botmessage = (('Numbers:' + ','.join([str(i) for i in total])) + '\nTheir sum:') + str(sum(total))
await ctx.send(botmessage)
@commands.command()
async def think(self, ctx):
'''let the bot think for a while'''
await ctx.message.delete()
await ctx.send(discord.utils.get(bot.emojis, name='fidgetthink'))
@commands.command()
async def morse(self, ctx, *, message):
'''Converts your ENGLISH message to morse. And vice versa.\nAdd an e to say it's English and m to say it's morse.'''
CODE = {'A': '.-', 'B': '-...', 'C': '-.-.',
'D': '-..', 'E': '.', 'F': '..-.',
'G': '--.', 'H': '....', 'I': '..',
'J': '.---', 'K': '-.-', 'L': '.-..',
'M': '--', 'N': '-.', 'O': '---',
'P': '.--.', 'Q': '--.-', 'R': '.-.',
'S': '...', 'T': '-', 'U': '..-',
'V': '...-', 'W': '.--', 'X': '-..-',
'Y': '-.--', 'Z': '--..',
'0': '-----', '1': '.----', '2': '..---',
'3': '...--', '4': '....-', '5': '.....',
'6': '-....', '7': '--...', '8': '---..',
'9': '----.',
' ': '/', '.': '.-.-.-', ',': '--..--',
':': '---...', '?': '..--..', "'": '.----.',
'-': '-....-', '/': '-..-.', '@': '.--.-.',
'=': '-...-', '(': '-.--.', ')': '-.--.-',
'+': '.-.-.'}
REVERSE_CODE = {CODE[i]: i for i in CODE}
a = ""
scope = ""
if message[1] != "|" or message[0].lower() not in "me":
await ctx.send(embed=discord.Embed(title="Morse conversion failed!",
description="You did not specify whether you want it Morse or English",
colour=discord.Colour.red()))
else:
await ctx.send(message[2:])
if message[0].lower() == "m":
for i in message[2:].upper():
if i not in CODE.keys():
await ctx.send(embed=discord.Embed(title="Morse conversion failed!",
description="Unidentified character spotted!",
colour=discord.Colour.red()))
break
else:
a += CODE[i]
else:
for i in message[2:]:
scope += i
if scope in REVERSE_CODE.keys():
a += REVERSE_CODE[scope]
scope = ""
elif i not in r"\-.":
await ctx.send(embed=discord.Embed(title="Morse conversion failed!",
description="Unidentified character spotted!",
colour=discord.Colour.red()))
break
elif len(scope) > 6:
await ctx.send(title="Morse conversion failed!", description="Unidentified character spotted!",
colour=discord.Colour.red())
break
m = len(a) // 1900
for x in range(m):
await ctx.send(embed=discord.Embed(title="Page {}/{} of Morse Translation".format(x + 1, m + 1),
description="```\n" + a[1900 * x:1900 * (x + 1)] + "```",
colour=discord.Colour.dark_gold()))
await ctx.send(embed=discord.Embed(title="Page {}/{} of Morse Translation".format(m + 1, m + 1),
description="```\n" + a[1900 * m:] + "```",
colour=discord.Colour.dark_gold()))
@commands.command()
async def emojify(self, ctx, *, text='Hello'):
'''all *English* letters and numbers turn into emojis!'''
nums = {'0': ':zero:', '1': ':one:', '2': ':two:', "3": ":three:", "4": ":four:", "5": ":five:", "6": ":six:",
"7": ":seven:", "8": ":eight:", "9": ":nine:", "!": ":grey_exclamation:", "?": ":grey_question:"}
said = ''
for i in text:
if i.isalpha():
said += (':regional_indicator_' + i.lower()) + ':'
elif i in nums:
said += nums[i]
else:
said += i
await ctx.send(said)
@commands.command()
async def emojirep(self, ctx, emoji: discord.Emoji, number=1):
'''[WIP] repeats a given emoji with input'''
try:
if number < 1 or number > 10:
await ctx.send("Stop being enthusiastic!")
else:
await ctx.send((discord.Emoji(emoji.id)) * number)
except:
await ctx.send("Error ocurred!")
@commands.command(aliases=["f", "respect"])
async def rip(self, ctx, member: discord.Member = None):
'''Rest in piece, my comrade'''
if member is None:
member = ctx.author
elif member.id == info["hierarchy"]["owner"] or member.id == info["hierarchy"]["bot_id"]:
member = ctx.author
embed = discord.Embed(title="RIP {}{}".format(member.name, discord.utils.get(bot.emojis, name="rip")),
description="Press :regional_indicator_f: to pay your respects",
colour=discord.Colour.from_rgb(255, 255, 255))
embed.set_thumbnail(url=member.avatar_url)
p = await ctx.send(embed=embed)
await p.add_reaction(discord.utils.get(bot.emojis, name="f_"))
@commands.command()
async def playing(self, ctx):
'''returns the current bot status'''
async with ctx.typing():
embed = discord.Embed(title="Quantum Bot's status:",
description=ctx.guild.get_member(info["hierarchy"]["bot"]).activity.name)
embed.set_thumbnail(url=ctx.guild.get_member(info["hierarchy"]["bot"]).avatar_url)
await ctx.send(embed=embed)
@commands.group(invoke_without_subcommand=True)
async def tts(self,ctx):
'''a group of commands that lets you get a speech output'''
await ctx.send(embed=discord.Embed(title="Available Subcommands", description="""
** say**: Returns an audio file with the spoken words. Default language is English
** langs**: Returns the list of supported languages and their codes
""", colour=discord.Colour.blurple()))
@tts.command(name="say")
async def tts_say(self,ctx,speaking_language:str=None,*,text:str=None):
'''Returns an audio file with the spoken words. Default language is English'''
if speaking_language in gtts.lang.tts_langs():
file = gtts.gTTS(text,lang=speaking_language)
else:
if text==None:
if speaking_language==None:
speaking_language="Please"
text="input a language"
else:
text=""
file = gtts.gTTS(speaking_language+" "+text)
file.save("Extras/gtts.mp3")
await ctx.send(file=discord.File("Extras/gtts.mp3"))
@tts.command(name="langs")
async def tts_langs(self,ctx):
'''shows list of supported languages and their codes'''
langs=[]
for key in gtts.lang.tts_langs():
langs.append("**%5s**"%key+": "+gtts.lang.tts_langs()[key])
embeds=[]
for i in range(len(langs)//15):
embeds.append(discord.Embed(title="List of available languages [{}/5]".format(i+1),
description="\n".join(langs[15*i:15*(i+1)]),
colour=discord.Colour.blurple()))
await SimplePaginator(extras=embeds).paginate(ctx)
class Owner:
'''commands only the bot owner can use, besides repl and exec'''
@commands.command(pass_context=True)
async def shutdown(self, ctx):
'''for me to close the bot'''
if ctx.message.author.id != info["hierarchy"]["owner"]:
await ctx.send("You're not the bot owner!")
else:
await ctx.send("Shutting down...")
await bot.logout()
@commands.command()
async def clear(self, ctx, number=1, author: discord.Member = None):
'''[WIP] clears messages from a channel, if you're allowed'''
allowed = info["hierarchy"]["owner"]
if ctx.author.id in allowed or ctx.author.guild_permissions.manage_messages:
if author is not None:
check = lambda x: x.author == author
await ctx.channel.purge(limit=number + 1, check=check)
await ctx.send("Purged %d messages from %s" % (number, author), delete_after=3)
else:
await ctx.channel.purge(limit=number + 1)
await ctx.send("Purged %d messages in this channel" % number, delete_after=3)
else:
await ctx.send("You're not approved by the bot owner to delete stuff!")
@commands.command()
async def getsource(self, ctx, command):
'''getting the code for command'''
people = info["hierarchy"]
if ctx.author.id in people["owner"]+people["collaborators"]+people["premium"]:
a = inspect.getsource(bot.get_command(command).callback)
m = len(a) // 1900
embedlist=[]
for x in range(m):
embedlist.append(discord.Embed(title="Page {}/{} of '{}' command".format(x + 1, m + 1, command),
description="```py\n" + a[1900 * x:1900 * (x + 1)] + "```",
colour=discord.Colour.dark_gold()))
embedlist.append(discord.Embed(title="Page {}/{} of '{}' command".format(m + 1, m + 1, command),
description="```py\n" + a[1900 * m:] + "```",
colour=discord.Colour.dark_gold()))
await SimplePaginator(extras=embedlist).paginate(ctx)
else:
await ctx.send(embed=premium_embed)
@commands.command(pass_context=True)
async def warn(self, ctx, member: discord.Member, serious: bool, *, reason):
'''for owner to issue warnings'''
if ctx.author.id == info["hierarchy"]["owner"]:
if serious:
await ctx.guild.get_member(member.id).send(embed=discord.Embed(title="Warning! [SERIOUS]",
description="**My bot owner warned your because**:{}".format(
reason),
colour=discord.Colour(0xFF0000)))
else:
await ctx.guild.get_member(member.id).send(embed=discord.Embed(title="Warning!",
description="**My bot owner warned your because**:{}".format(
reason),
colour=discord.Colour(0xFFFF00)))
await ctx.message.add_reaction('\u2705')
class Pystuff():
'''commands that relate to Python coding'''
@commands.command()
async def pydir(self, ctx, *, command=None):
'''list of methods of a given object'''
people = info["hierarchy"]
for i in ["bot.http.token","open("]:
if i in command:
await ctx.send(embed=discord.Embed(title="Access Denied!",description="You are not allowed to use these.",colour=discord.Colour.red()))
return
if ctx.message.author.id not in people["owner"]+people["collaborators"]+people["premium"]:
await ctx.send(embed=premium_embed)
else:
if command is None:
await ctx.send("Argument [command name] must be provided!")
else:
try:
dire = []
a = eval("dir(" + command + ")")
for i in a:
if i[0] != "_":
dire.append("**" + i + "**")
elif i[1] != "_":
dire.append(i)
content = ",".join(dire)
except NameError:
content = "Object %s is not found!" % command
await ctx.send(embed=discord.Embed(title="Useful methods for object '%s'" % command,
color=eval(hex(ctx.author.color.value)), description=content))
@commands.command()
async def pyhelp(self, ctx, *, command=None):
'''the Python help message for a given object'''
people=info["hierarchy"]
if ctx.message.author.id not in people["owner"]+people["collaborators"]+people["premium"] or "bot.http.token" in command or "open(" in command:
await ctx.send(embed=premium_embed)
else:
if command is None:
await ctx.send("Argument [command name] must be provided!")
else:
try:
embeds = []
sio = io.StringIO()
with contextlib.redirect_stdout(sio):
command.replace("print","")
help(command)
sio.seek(0)
a = sio.getvalue()
sio = None
for i in range(1, len(a) // 1950 + 1):
embeds.append(discord.Embed(title="Python help Page [%d/%d]" % (i, len(a) // 1950 + 1),
description="```{}```".format(a[1950 * (i - 1):1950 * i]),
color=ctx.author.color))
embeds.append(
discord.Embed(title="Python help Page [%d/%d]" % (len(a) // 1950 + 1, len(a) // 1950 + 1),
description="```{}```".format(a[1950 * (len(a) // 1950):]),
color=ctx.author.color))
await SimplePaginator(extras=embeds).paginate(ctx)
except NameError:
await ctx.send(
embed=discord.Embed(title="Error raised!", description="Object %s is not found!" % command))
@commands.command()
async def pypi(self, ctx, search):
'''searches information about the PyPI for the module you want'''
base = "https://pypi.org/pypi/{}/json".format(urllib.request.pathname2url(search))
try:
f = await utils.getjson(base)
embed = discord.Embed(title="Details about the PyPI module {}".format(search),
colour=discord.Colour.dark_gold())
author = f['info']['author']
email = f['info']['author_email']
homepage = f['info']['home_page']
project = f['info']['project_url']
required_version = f['info']['requires_python']
module_version = f['info']['version']
embed.add_field(name="Author", value=author)
embed.add_field(name="Author's Email", value=email)
embed.add_field(name="Module's Homepage", value=f"[Homepage]({homepage})")
embed.add_field(name="Project Url", value="[{}, version {}]({})".format(search, module_version, project))
embed.add_field(name="Minimum Python version required", value=required_version[2:])
await ctx.send(embed=embed)
except aiohttp.client_exceptions.ContentTypeError:
await ctx.send(embed=discord.Embed(title="Module Cannot Be Found!",
description=f"The module with the name **{search}** does not exist.",
colour=discord.Colour.red()))
except discord.errors.HTTPException:
await ctx.send(embed=discord.Embed(title="Module Information Cannot Be Obtained",
description=f"The module with the name **{search}** does not have a complete description, if one even exists.",
colour=discord.Colour.red()))
@commands.command()
async def pypisearch(self, ctx, module):
'''gets a list of PyPI modules with roughly similar names'''
async with aiohttp.ClientSession() as session:
async with session.get("https://pypi.org/search/?" + urllib.parse.urlencode({"q": module})) as response:
f = await response.text()
indicess = list(utils.find('<h3 class="package-snippet__title">', f))
indicese = list(utils.find('</h3>', f))
modules = []
for i in range(len(indicess)):
e = (f[indicess[i]:indicese[i]])
namestart = list(utils.find('<span class="package-snippet__name">', e))[0] + 36
verstart = list(utils.find('<span class="package-snippet__version">', e))[0] + 39
spans = list(utils.find('</span>', e))
modules.append(f"{e[namestart:spans[0]]}: v{e[verstart:spans[1]]}")
send = discord.Embed(title=f"PyPI search results for {module}", colour=ctx.author.colour,
description="```" + "\n".join(modules) + "```")
await ctx.send(embed=send)
class Media:
'''commands that help you get various media'''
@commands.command(passcontext=True)
async def youtube(self, ctx, *, youtube):
'''Searches youtube videos with inputted queries'''
embed = discord.Embed(title="Youtube search for " + youtube, color=eval(hex(ctx.author.color.value)))
try:
query_string = urllib.parse.urlencode({'search_query': youtube, })
html_content = urllib.request.urlopen('http://www.youtube.com/results?' + query_string)
search_results = re.findall('href=\\"\\/watch\\?v=(.{11})', html_content.read().decode())
if len(search_results) >= 3:
embed.add_field(name="Top result", value='http://www.youtube.com/watch?v=' + search_results[0])
embed.add_field(name="Other results", value='http://www.youtube.com/watch?v=' + search_results[
1] + "\n" + 'http://www.youtube.com/watch?v=' + search_results[2])
else:
embed.add_field(name="Top result", value='http://www.youtube.com/watch?v=' + search_results[0])
except:
embed.add_field(name="Error",
value="Your request did not produce any output. Perhaps try searching a different query?")
finally:
await ctx.send(embed=embed)
@commands.command()
async def google(self, ctx, *, query):
'''Search Google for something'''
content = []
async with ctx.typing():
m = await utils.getjson("http://api.tanvis.xyz/search/" + urllib.request.pathname2url(query))
for i in m:
content.append(i['link'])
embed = discord.Embed(title="'%s' search results:" % query, description="\n".join(content),
colour=discord.Colour.from_rgb(66, 133, 244))
embed.set_footer(text="using tanvis.xyz API")
await ctx.send(embed=embed)
@commands.command(aliases=['wiki'])
async def wikipedia(self, ctx, *, anything):
'''look through wikipedia for what you want'''
wew = urllib.request.pathname2url(anything)
f = await utils.getjson(
f"https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&indexpageids=1&redirects=1&explaintext=1&exsectionformat=plain&titles={wew}")
query = f['query']
pageids = query['pageids']
title = list(query['pages'].values())[0]['title']
extract = list(query['pages'].values())[0]['extract']
texts=utils.partition(extract,1000)
embedlist=[discord.Embed(title=title+" Page {}/{}".format(i+1,len(texts)),description=texts[i],colour=discord.Colour.lighter_grey()).set_thumbnail(url="https://images-ext-1.discordapp.net/external/CYCtSp1meQ0f_ZFd5y0T14UlI_xvqqLWPjUJ2gINt58/https/en.wikipedia.org/static/images/project-logos/enwiki.png") for i in range(len(texts))]
await SimplePaginator(extras=embedlist).paginate(ctx)
@commands.command()
async def xkcd(self, ctx, num: int = None):
'''read the famous comic strip, leaving blank gets random comic'''
try:
async with ctx.typing():
if num is None: num = random.randint(1, 1996)
url = f'https://xkcd.com/{num}/info.0.json'
f = await utils.getjson(url)
m = discord.Embed(colour=discord.Color.from_rgb(245, 245, 220),
title="xkcd #{}:{}".format(str(f['num']), f['safe_title']),
description=f['transcript'], timestamp=datetime.datetime.now())
m.set_image(url=f['img'])
m.add_field(name="Links", value=f['img'] + '\nhttps://xkcd.com/' + str(f['num']))
m.add_field(name="Publication date:", value=f['day'] + '/' + f['month'] + '/' + f['year'], inline=False)
await ctx.send(embed=m)
except:
if num == 404:
m = discord.Embed(title="xkcd #404: Think again, does it exist?",
description="This came between Monday and Wednesday, 2 consecutive days of xkcd comic publication. This can be considered an April Fools prank or a reference to the 404 Error: Not Found")
m.set_image(url='https://www.explainxkcd.com/wiki/images/9/92/not_found.png')
else:
await ctx.send("Fetching your a random xkcd comic...", delete_after=2)
async with ctx.typing():
num = random.randint(1, 1996)
url = f'https://xkcd.com/{num}/info.0.json'
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
f = await response.json(encoding='utf8')
m = discord.Embed(colour=discord.Color.from_rgb(245, 245, 220),
title="xkcd #{}:{}".format(str(f['num']), f['safe_title']),
description=f['transcript'], timestamp=datetime.datetime.now())
m.set_image(url=f['img'])
m.add_field(name="Links", value=f['img'] + '\nhttps://xkcd.com/' + str(f['num']))
m.add_field(name="Publication date:", value=f['day'] + '/' + f['month'] + '/' + f['year'],
inline=False)
await ctx.send(embed=m)
@commands.cooldown(rate=1, per=8, type=commands.BucketType.guild)
@commands.command()
async def weather(self, ctx, *, location):
'''to get the weather of a given location'''
try:
async with ctx.typing():
url = "http://api.tanvis.xyz/weather/" + urllib.request.pathname2url(location)
f = await utils.getjson(url)
if 'error' in f:
await ctx.send(embed=discord.Embed(title="An error occurred",
description="I could not find your given location",
colour=discord.Colour.red()))
else:
embed = discord.Embed(title="Weather information gathered", colour=discord.Colour.dark_orange(),
description="Here is your result, " + ctx.author.mention)
embed.add_field(name="Location", value=f['name'], inline=False);
embed.add_field(name="Temperature in °C", value=f['celsius'])
embed.add_field(name="Temperature in °F", value=f['fahrenheit']);
embed.add_field(name="Weather", value=f['weather'])
embed.add_field(name="Wind Speed", value=f['windSpeed']);
embed.set_thumbnail(url=f['icon'])
embed.set_footer(text="using **tanvis.xyz** API")
await ctx.send(embed=embed)
except:
await ctx.send("An error occurred. Please try again.", delete_after=3)
@commands.cooldown(rate=1, per=8, type=commands.BucketType.guild)
@commands.command(aliases=['define', 'def', 'dict'])
async def dictionary(self, ctx, word):
'''search Oxford Dictionaries to get the definition you need'''
language = 'en'
word_id = word
url = 'https://od-api.oxforddictionaries.com:443/api/v1/entries/' + language + '/' + word_id.lower()
r = __import__("requests").get(url, headers={'app_id': info["dict"]["app_id"], 'app_key': info["dict"]["app_key"]})
definitions = {}
if r.status_code == 200:
for i in r.json()["results"]:
for j in i["lexicalEntries"]:
for k in j["entries"]:
for v in k["senses"]:
deff = v["definitions"][0]
examples = []
try:
for f in v["examples"]:
examples += ["- " + "".join(f["text"])]
definitions[deff] = "\n".join(examples)
except KeyError:
definitions[deff] = "(no examples)"
embed = discord.Embed(title="Definitions for the word %s" % word, colour=discord.Colour.blue())
desc_text = []
for key in definitions:
temp = "***{}. {}***".format(len(desc_text) + 1, key)
exam = definitions[key]
desc_text += [temp + "\n**Examples:**\n" + exam]
embed.description = "\n".join(desc_text)
embed.set_footer(text="Using **Oxford Dictionaries** API")
await ctx.send(embed=embed)
else:
embed = discord.Embed(title="An error occurred while processing your request!", colour=discord.Colour.red())
embed.add_field(name="Error Code {}".format(r.status_code), value=info["dict"]["status_code"][r.status_code.__str__()])
await ctx.send(embed=embed)
@commands.command()
async def qrcode(self, ctx, *, message="Please provide an argument"):
'''Generate a QR Code'''
try:
async with ctx.typing():
url = "http://api.qrserver.com/v1/create-qr-code/?"
add = urllib.parse.urlencode({'size': '300x300', 'data': message})
send = (url + add).replace(' ', '')
embed = discord.Embed(title=ctx.author.name + ", here is your QR Code!", colour=ctx.author.colour)
embed.set_footer(text="Used **api.qrserver.com** API")
embed.set_image(url=send)
await ctx.send(embed=embed)
except:
await ctx.send("An error occurred. Please try again.", delete_after=3)
@commands.cooldown(rate=1, per=8, type=commands.BucketType.guild)
@commands.command(aliases=["trans"])
async def translate(self, ctx, *, message="Hello"):
'''Uses google translate to translate given message, opens an interactive support'''
try:
m = await ctx.send(
ctx.author.mention + ", please choose your source language. Can be its name or its code. Anything not detected defaults to auto.")
src = await bot.wait_for('message', check=lambda x: x.author == ctx.author, timeout=60)
await m.delete()
m = await ctx.send(
ctx.author.mention + ", please choose your destination language. Can be its name or its code. Anything not detected defaults to en,English.")
dest = await bot.wait_for('message', check=lambda x: x.author == ctx.author, timeout=60)
await m.delete()
src = src.content.lower()
dest = dest.content.lower()
if src not in list(info["languages"].keys()) + list(info["languages"].values()):
src = "auto"
if dest not in list(info["languages"].keys()) + list(info["languages"].values()):
dest = "en"
async with ctx.typing():
translator = Translator()
f = translator.translate(message, dest=dest, src=src)
sourcelang = info["languages"][f.src] + "({})".format(f.src)
destlang = info["languages"][f.dest] + "({})".format(f.dest)
embed = discord.Embed(title="Translation output", colour=discord.Colour.from_rgb(79, 255, 176))
embed.add_field(name="Input [ {} ]:".format(sourcelang), value=f.origin, inline=False)
embed.add_field(name="Result [ {} ]:".format(destlang), value=f.text)
embed.set_footer(text="Using the google translate API", icon_url=bot.user.avatar_url)
await ctx.send(embed=embed)
except asyncio.TimeoutError:
await ctx.send(
embed=discord.Embed(title="Error", description="You haven't filled up necessary data! Try again!",
colour=discord.Colour.red()))
class Images:
'''commands dedicated to sending some image'''
@commands.command()
async def hug(self, ctx, member: discord.Member = None):
'''Need a hug? Quantum Bot to the rescue!'''
embed = discord.Embed(colour=discord.Colour.from_rgb(245, 245, 14))
embed.set_footer(text="Credits to Google Image Search Results",
icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/1000px-Google_%22G%22_Logo.svg.png")
with open("Images/hugs.txt") as hugs:
image = random.choice(hugs.readlines())
embed.set_image(url=image)
if member == None:
embed.title = "Hey {}, here yougo, a hug!".format(ctx.author)
elif member == bot.user:
embed.title = "Thank you {} for the hug! I appreaciate your love! :)".format(ctx.author)
else:
embed.title = "Hey {}, {} has hugged you!".format(member, ctx.author)
await ctx.send(embed=embed)
@commands.command(aliases=["cat", "kitten", "kitty"])
async def cats(self, ctx):
'''Who doesn't love images of these furries? Let's see a picture of them!'''
embed = discord.Embed(title="{}, here's your cute furball".format(ctx.author), colour=discord.Colour.teal())
embed.set_footer(text="Credits to Google Image Search Results",
icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/1000px-Google_%22G%22_Logo.svg.png")
embed.description = random.choice(
["Awww, how cute!", "These cuties melt my heart!", "So adorable!", "Meowr!", "Kittens for life!", "Purrr!"])
with open("Images/cats.txt") as cats:
embed.set_image(url=random.choice(cats.readlines()))
await ctx.send(embed=embed)
class Data:
'''these commands store data'''
@commands.cooldown(rate=1, per=5)
@commands.command()
async def customprefix(self, ctx, prefix: str = None):
'''sets the custom bot prefix for your guild, sets the prefix if you specified any, provided no spaces'''
bot.db.set_collection("guilds")
async with ctx.typing():
res = await bot.db.find(length=1, id=ctx.guild.id)
if res:
res = res[0]
if prefix == None:
try:
customprefix = res["prefix"]
except KeyError:
embed = discord.Embed(title="This guild's custom prefix", description="Not set yet",
colour=discord.Colour.dark_gold())
else:embed = discord.Embed(title="This guild's custom prefix", description=customprefix,
colour=discord.Colour.dark_gold())
else:
if ctx.author.guild_permissions.manage_guild or ctx.author.id == info["hierarchy"]["owner"]:
m=Guild()
res["prefix"]=prefix
m.load(res)
await m.send()
embed = discord.Embed(title="Successfully set this guild's custom prefix!",
colour=discord.Colour.dark_green())
else:
embed = discord.Embed(title="Operation failed!",
description="You couldn't change this guild's custom prefix!",
colour=discord.Colour.red())
else:
if prefix == None:
customprefix = "None set yet"
embed = discord.Embed(title="This guild's custom prefix", description=customprefix,
colour=discord.Colour.dark_gold())
else:
if ctx.author.guild_permissions.manage_guild or ctx.author.id == info["hierarchy"]["owner"]:
m=Guild()
m.load({"id":res["id"],"prefix":prefix})
await m.send()
embed = discord.Embed(title="Successfully set this guild's custom prefix!",
description="This is the first time you're setting my custom prefix!!",
colour=discord.Colour.dark_green())
else:
embed = discord.Embed(title="Operation failed!",
description="You couldn't change this guild's custom prefix!",
colour=discord.Colour.red())
await ctx.send(embed=embed)
class Beta:
'''for commands in testing'''
@commands.group(invoke_without_command=True)
async def autorole(self,ctx):
'''allows owner to automatically give role to members'''
await ctx.send(embed=discord.Embed(title="Available Subcommands", description="""
**set**: sets the current guild's autorole
**get**: gets the current guild's autorole
""", colour=discord.Colour.blurple()))
@commands.cooldown(rate=1,per=5,type=commands.BucketType.guild)
@autorole.command(name="set")
async def autorole_set(self,ctx,*,rolename:str=None):
'''sets the autorole of this guild, case sensitivity does not matter'''
bot.db.set_collection("guilds")
serverroles=ctx.guild.role_hierarchy[:-1]
rolenames=list(map(lambda x:x.name,serverroles))
serveroles=list(map(lambda x:x.lower(),rolenames))
if rolename in serveroles:
role=rolenames[serveroles.index(rolename)]
guild=Guild()
currguild=await bot.db.find(length=1,id=ctx.guild.id)
if currguild:
guild.load(currguild[0])
else:
guild.load({"id":ctx.guild.id})
guild.change("autorole",role)
await guild.send()
await ctx.send(embed=discord.Embed(title="Autorole configured",description='Your autorole is set as: {}'.format(role),colour=discord.Colour.green()))
else:
await ctx.send(embed=discord.Embed(title="Autorole configuration failed",description="The role specified is either not found, or you have no permissions to modify.",colour=discord.Colour.red()))
@commands.cooldown(rate=1,per=5,type=commands.BucketType.guild)
@autorole.command(name="get")
async def autorole_get(self,ctx):
'''gets the autorole of this guild'''
currguild=await bot.db.find(length=1,id=ctx.guild.id)
if currguild:name=currguild[0]["autorole"]
else:name="Not set yet"
await ctx.send(embed=discord.Embed(title="The autorole of this server",description=name))
@commands.cooldown(rate=1,per=5,type=commands.BucketType.guild)
@autorole.command(name="remove")
async def autorole_remove(self,ctx):