Advertisement
Guest User

Untitled

a guest
Apr 7th, 2017
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.79 KB | None | 0 0
  1. import discord
  2. import asyncio
  3. import praw
  4. import random
  5. import os
  6. import datetime
  7. import operator
  8. import youtube_dl
  9.  
  10. # https://discordapp.com/oauth2/authorize?client_id=298508884413513729&scope=bot&permissions=0
  11. BOT_TOKEN = 'Mjk4NTA4ODg0NDEzNTEzNzI5.C8QYAA.2RpBhqbrjKDDdSfZje1l1CGLx0c'
  12. CMD_PREFIX = '.'
  13. dex_bot = discord.Client()
  14. audio_playing = None
  15. bot_voice = None
  16.  
  17. can_interact = True
  18. uptime = 0
  19.  
  20. logdata = str(datetime.datetime.utcnow()) + '\n'
  21.  
  22.  
  23. def get_uptime_str():
  24. return 'Days: ' + str(uptime // 1440) + ' Hours: ' + str((uptime // 60) % 24) + ' Minutes: ' + str(uptime % 60)
  25.  
  26.  
  27. class RedditBot:
  28. def __init__(self, subreddit):
  29. self.subreddit = subreddit
  30. self.reddit = None
  31. self.submissions = None
  32. self.images = []
  33. self.update()
  34.  
  35. def update(self):
  36. self.reddit = praw.Reddit(client_id='ghvgnI8MVRgSww', client_secret='nvrnAvkV7HpzrKUO7E05YszSHWg', user_agent='dex-bot by /u/overlysalty', username='d3x-bot', password='opensourcepassword')
  37. self.submissions = self.reddit.subreddit(self.subreddit).hot(limit=50)
  38. self.images = [[s.url, s.id] for s in self.submissions if ('.jpg' in s.url or '.png' in s.url)]
  39.  
  40. def img_with_sub(self):
  41. r = random.randint(0, len(self.images) - 1)
  42. return str(self.images[r][0]), str('www.reddit.com/r/' + self.subreddit + '/comments/' + str(self.images[r][1]))
  43.  
  44. def get_random_image(self, sublink=True):
  45. return self.img_with_sub() if sublink else str(self.images[random.randint(0, len(self.images) - 1)][0])
  46.  
  47.  
  48. reddit_bots = {
  49. 'dankmemes': RedditBot('dankmemes'),
  50. 'imgoingtohellforthis': RedditBot('imgoingtohellforthis')
  51. }
  52.  
  53. data_entries = []
  54.  
  55.  
  56. class DataEntry:
  57. def __init__(self, args):
  58. self.name = args[0]
  59. self.msg_count = 0
  60. self.cmd_count = 0
  61. if len(args) > 1:
  62. self.msg_count = int(args[1])
  63. if len(args) > 2:
  64. self.cmd_count = int(args[2])
  65. self.ls = [self.name, self.msg_count, self.cmd_count]
  66.  
  67. def update(self):
  68. self.ls = [self.name, self.msg_count, self.cmd_count]
  69.  
  70.  
  71. def get_data_entry(s):
  72. for d in data_entries:
  73. if s in d.name or d.name in s:
  74. return d
  75. return None
  76.  
  77.  
  78. directory_str = os.getcwd().replace('\\', '/') + '/data'
  79. if not os.path.exists(directory_str):
  80. os.makedirs(directory_str)
  81. datafile = open('data/stats.dat')
  82. contents = datafile.readlines()
  83. for i in range(len(contents)):
  84. if len(contents[i]) > 1:
  85. data_entries.append(DataEntry(contents[i].rstrip().split(';')))
  86. datafile.close()
  87.  
  88.  
  89. async def save_logs():
  90. global logdata
  91. logfile = open('data/logs.log', 'a')
  92. logfile.write(logdata)
  93. logfile.close()
  94. logdata = ''
  95.  
  96.  
  97. class Command:
  98. def __init__(self, name, description, method, permissions=None, args=-1, params=''):
  99. self.name, self.description, self.method, self.permissions, self.args, self.params = name, description, method, permissions, args, params
  100.  
  101. def help(self):
  102. return '- ' + CMD_PREFIX + self.name + self.params + ' - ' + self.description
  103.  
  104. async def execute(self, message):
  105. if not can_interact:
  106. for r in message.author.roles:
  107. if 'admin' in r.name:
  108. break
  109. else:
  110. await dex_bot.send_message(message.author, 'Shhh. I\'m in monitoring mode and cannot respond. Contact an admin to disable monitoring mode.')
  111. return False
  112. if self.args != -1 and len(message.content.split(' ')[1:]) != self.args:
  113. await dex_bot.send_message(message.channel, '[Error]: Invalid parameters. Usage: "' + self.help() + '"')
  114. return False
  115. else:
  116. if self.permissions is not None:
  117. for r in message.author.roles:
  118. if self.permissions in r.name:
  119. break
  120. else:
  121. await dex_bot.send_message(message.channel, '[Error]: You don\'t have permission to use this command')
  122. return False
  123. await self.method(message)
  124. return True
  125.  
  126. def __str__(self):
  127. return self.name
  128.  
  129. cmds = []
  130.  
  131.  
  132. async def get_voice_channel(message):
  133. ch = None
  134. for c in dex_bot.get_server('168735910559481856').channels:
  135. for n in c.voice_members:
  136. if str(c.type) == 'voice' and message.author.name.lower() in n.name.lower():
  137. ch = c
  138. if not ch:
  139. await dex_bot.send_message(message.channel, '[Error]: You must be in a voice channel to use this command')
  140. return ch
  141.  
  142.  
  143. async def cmd_help(message):
  144. s = ''
  145. for c in cmds:
  146. s += c.help() + '\n'
  147. await dex_bot.send_message(message.channel, s)
  148.  
  149.  
  150. async def cmd_echo(message):
  151. s = ''
  152. for i in message.content.split(' ')[1:]:
  153. s += i + ' '
  154. if len(s) > 0:
  155. await dex_bot.send_message(message.channel, s)
  156.  
  157.  
  158. async def cmd_debug(message):
  159. print('Sender Name: ' + str(message.author))
  160. print('Server ID: ' + str(message.author.server.id))
  161. print('Channel ID: ' + str(message.channel.id))
  162. server = dex_bot.get_server('168735910559481856')
  163. print(server.members)
  164. print(server.channels)
  165.  
  166.  
  167. def cmd_names_within(s):
  168. for c in cmds:
  169. if '.' + c.name in s:
  170. return True
  171. return False
  172.  
  173.  
  174. async def cmd_clean(message):
  175. args = message.content.split(' ')[1:]
  176. lim = 21 if len(args) != 1 else int(args[0]) + 1
  177. async for msg in dex_bot.logs_from(message.channel, limit=lim):
  178. if 'dex-bot' in str(msg.author) or cmd_names_within(msg.content):
  179. await dex_bot.delete_message(msg)
  180. m = await dex_bot.send_message(message.channel, 'Cleaned commands and bot responses from the past ' + str(lim) + ' messages.')
  181. await asyncio.sleep(3)
  182. await dex_bot.delete_message(m)
  183.  
  184.  
  185. async def cmd_wipe(message):
  186. args = message.content.split(' ')[1:]
  187. lim = 11 if len(args) != 1 else int(args[0]) + 1
  188. async for msg in dex_bot.logs_from(message.channel, limit=lim):
  189. await dex_bot.delete_message(msg)
  190. m = await dex_bot.send_message(message.channel, 'Removed the past ' + str(lim - 1) + ' messages.')
  191. await asyncio.sleep(3)
  192. await dex_bot.delete_message(m)
  193.  
  194.  
  195. async def cmd_toucan(message):
  196. await dex_bot.send_message(message.channel, '░░░░░░░░▄▄▄▀▀▀▄▄███▄░░░░░░░░░░░░░░'
  197. + '\n░░░░░▄▀▀░░░░░░░▐░▀██▌░░░░░░░░░░░░░'
  198. + '\n░░░▄▀░░░░▄▄███░▌▀▀░▀█░░░░░░░░░░░░░'
  199. + '\n░░▄█░░▄▀▀▒▒▒▒▒▄▐░░░░█▌░░░░░░░░░░░░'
  200. + '\n░▐█▀▄▀▄▄▄▄▀▀▀▀▌░░░░░▐█▄░░░░░░░░░░░'
  201. + '\n░▌▄▄▀▀░░░░░░░░▌░░░░▄███████▄░░░░░░'
  202. + '\n░░░░░░░░░░░░░▐░░░░▐███████████▄░░░'
  203. + '\n░░░░░le░░░░░░░▐░░░░▐█████████████▄ '
  204. + '\n░░░░toucan░░░░░░▀▄░░░▐█████████████▄'
  205. + '\n░░░░░░has░░░░░░░░▀▄▄███████████████'
  206. + '\n░░░░░arrived░░░░░░░░░░░░█▀██████░░░░')
  207.  
  208.  
  209. async def cmd_speak(message):
  210. await dex_bot.delete_message(message)
  211. s = ''
  212. for i in message.content.split(' ')[1:]:
  213. s += i + ' '
  214. m = await dex_bot.send_message(message.channel, s, tts=True)
  215. await dex_bot.delete_message(m)
  216.  
  217.  
  218. async def cmd_invite(message):
  219. inv = await dex_bot.create_invite(discord.Server(id='168735910559481856'), max_age=10)
  220. await dex_bot.send_message(message.channel, inv)
  221.  
  222.  
  223. async def cmd_jail(message):
  224. await dex_bot.delete_message(message)
  225. args = message.content.split(' ')[1:]
  226. ogchannel = None
  227. for u in dex_bot.get_server('168735910559481856').members:
  228. if args[0].lower() in u.name.lower():
  229. user = u
  230. break
  231. for c in dex_bot.get_server('168735910559481856').channels:
  232. for n in c.voice_members:
  233. if args[0].lower() in n.name.lower():
  234. ogchannel = c
  235. else:
  236. await dex_bot.send_message(message.channel, '[Error]: User not found')
  237. return
  238. m = await dex_bot.send_message(message.channel, 'Jailing User "' + str(user.name) + '" for ' + args[1] + ' seconds')
  239. await dex_bot.move_member(user, dex_bot.get_channel('277258808621924352'))
  240. jailed = None
  241. for r in dex_bot.get_server('168735910559481856').roles:
  242. if r.name == '@jailed':
  243. jailed = r
  244. await dex_bot.add_roles(user, jailed)
  245. await asyncio.sleep(min(600, int(args[1])))
  246. try:
  247. await dex_bot.remove_roles(user, jailed)
  248. await dex_bot.move_member(user, ogchannel)
  249. except:
  250. pass
  251. await dex_bot.delete_message(m)
  252.  
  253.  
  254. async def cmd_uptime(message):
  255. await dex_bot.send_message(message.channel, 'Uptime: [' + get_uptime_str() + ']')
  256.  
  257.  
  258. async def cmd_listen(message):
  259. global can_interact
  260. can_interact = not can_interact
  261. m = await dex_bot.send_message(message.channel, ('Exiting' if can_interact else 'Entering') + ' monitoring mode.')
  262. await asyncio.sleep(5)
  263. await dex_bot.delete_message(m)
  264.  
  265.  
  266. async def cmd_dankmeme(message):
  267. reddit_bots['dankmemes'].update()
  268. em = discord.Embed(title='Meme for ' + message.author.name.split('#')[0], color=int(0xcc00cc))
  269. meme = reddit_bots['dankmemes'].get_random_image()
  270. em.set_image(url=meme[0])
  271. em.set_footer(text='Link: ' + meme[1])
  272. await dex_bot.send_message(message.channel, embed=em)
  273. # await dex_bot.send_message(message.channel, reddit_bots['dankmemes'].get_random_image())
  274.  
  275.  
  276. async def cmd_stop(message):
  277. await dex_bot.send_message(message.channel, 'Shutting down...')
  278. await dex_bot.close()
  279.  
  280.  
  281. async def cmd_nice(message):
  282. global audio_playing, bot_voice
  283. await cmd_audio_stop(message)
  284. channel = await get_voice_channel(message)
  285. if not channel:
  286. return
  287. try:
  288. bot_voice = await dex_bot.join_voice_channel(channel)
  289. audio_playing = await bot_voice.create_ytdl_player('https://www.youtube.com/watch?v=L8ZqSW5j-AQ')
  290. audio_playing.start()
  291. await asyncio.sleep(audio_playing.duration)
  292. await bot_voice.disconnect()
  293. except:
  294. pass
  295.  
  296.  
  297. async def cmd_edge(message):
  298. reddit_bots['imgoingtohellforthis'].update()
  299. em = discord.Embed(title='Edgy Meme for ' + message.author.name.split('#')[0], color=int(0xcc00cc))
  300. meme = reddit_bots['imgoingtohellforthis'].get_random_image()
  301. em.set_image(url=meme[0])
  302. em.set_footer(text='Link: ' + meme[1])
  303. await dex_bot.send_message(message.channel, embed=em)
  304.  
  305.  
  306. async def cmd_youtube(message):
  307. global audio_playing, bot_voice
  308. await cmd_audio_stop(message)
  309. channel = await get_voice_channel(message)
  310. if not channel:
  311. return
  312. try:
  313. args = message.content.split(' ')[1:]
  314. bot_voice = await dex_bot.join_voice_channel(channel)
  315. audio_playing = await bot_voice.create_ytdl_player(args[0])
  316. audio_playing.volume = 0.25
  317. await audio_playing.start()
  318. await asyncio.sleep(audio_playing.duration)
  319. await bot_voice.disconnect()
  320. except:
  321. pass
  322.  
  323.  
  324. def get_yt_link(search):
  325. return youtube_dl.YoutubeDL().extract_info('ytsearch:' + search, download=False)['entries'][0]['webpage_url']
  326.  
  327.  
  328. async def cmd_searchyt(message):
  329. global audio_playing, bot_voice
  330. await cmd_audio_stop(message)
  331. channel = await get_voice_channel(message)
  332. if not channel:
  333. return
  334. try:
  335. args = message.content.split(' ')[1:]
  336. search_query = ''
  337. for i in range(len(args)):
  338. search_query += args[i] + ('' if i + 1 == len(args) else '+')
  339. bot_voice = await dex_bot.join_voice_channel(channel)
  340. m = await dex_bot.send_message(message.channel, 'Attempting to find youtube video from a search of "' + search_query + '"')
  341. link = get_yt_link(search_query)
  342. n = await dex_bot.send_message(message.channel, 'Playing Video: %s' % link)
  343. audio_playing = await bot_voice.create_ytdl_player(link)
  344. audio_playing.volume = 0.25
  345. await dex_bot.delete_message(m)
  346. await audio_playing.start()
  347. await asyncio.sleep(audio_playing.duration)
  348. await dex_bot.delete_message(n)
  349. await bot_voice.disconnect()
  350. except:
  351. pass
  352.  
  353.  
  354. async def cmd_audio_stop(message):
  355. global audio_playing
  356. if audio_playing:
  357. audio_playing.stop()
  358. await bot_voice.disconnect()
  359.  
  360.  
  361. async def cmd_succ(message):
  362. global audio_playing, bot_voice
  363. await cmd_audio_stop(message)
  364. channel = await get_voice_channel(message)
  365. if not channel:
  366. return
  367. try:
  368. bot_voice = await dex_bot.join_voice_channel(channel)
  369. audio_playing = await bot_voice.create_ytdl_player('https://www.youtube.com/watch?v=RLHjpdH6YZk')
  370. audio_playing.volume = 0.25
  371. audio_playing.start()
  372. await asyncio.sleep(audio_playing.duration)
  373. await bot_voice.disconnect()
  374. except:
  375. pass
  376.  
  377.  
  378. async def cmd_reddit_search(message):
  379. args = message.content.split(' ')[1:]
  380. reddit_bots[args[0]].update()
  381. em = discord.Embed(title='Random Image from r/' + args[0] + ' for ' + message.author.name.split('#')[0], color=int(0xcc00cc))
  382. meme = reddit_bots[args[0]].get_random_image()
  383. em.set_image(url=meme[0])
  384. em.set_footer(text='Link: ' + meme[1])
  385. await dex_bot.send_message(message.channel, embed=em)
  386.  
  387.  
  388. @dex_bot.event
  389. async def on_ready():
  390. cmds.append(Command('help', 'prints information on all commands', cmd_help))
  391. cmds.append(Command('echo', 'echos back the provided text', cmd_echo))
  392. cmds.append(Command('debug', 'prints debug information to the bot stdout', cmd_debug, permissions='admin'))
  393. cmds.append(Command('clean', 'cleans commands and bot responses from server', cmd_clean, permissions='salty'))
  394. cmds.append(Command('wipe', 'removes the specified amount of messages from the server', cmd_wipe, permissions='admin'))
  395. cmds.append(Command('speak', 'speaks the provided text', cmd_speak, permissions='admin'))
  396. cmds.append(Command('hush', 'toggles monitoring mode', cmd_listen, permissions='admin'))
  397. cmds.append(Command('close', 'shuts down the bot', cmd_stop, permissions='admin'))
  398. cmds.append(Command('toucan', 'le toucan has arrived', cmd_toucan))
  399. cmds.append(Command('uptime', 'displays how long the bot\'s been running', cmd_uptime))
  400. cmds.append(Command('invite', 'creates invite link', cmd_invite))
  401. cmds.append(Command('meme', '[NSFW] satisfies your meme needs', cmd_dankmeme))
  402. cmds.append(Command('edge', '[NSFW] 2edgy4u', cmd_edge))
  403. cmds.append(Command('nice', 'praises the quality of your dankest meme', cmd_nice))
  404. cmds.append(Command('jail', 'temporarily jails the specified user', cmd_jail, args=2, params=' [username] [duration]', permissions='admin'))
  405. cmds.append(Command('yt', 'plays youtube video from the provided link', cmd_youtube, args=1, params=' [link]'))
  406. cmds.append(Command('syt', 'plays first youtube video found from provided search query', cmd_searchyt))
  407. cmds.append(Command('ar', 'resets the audio status of the bot', cmd_audio_stop))
  408. cmds.append(Command('succ', 'a tribute to joey', cmd_succ))
  409. cmds.append(Command('reddit-img', 'pulls random image from the top 50 posts of the provided subreddit', cmd_reddit_search, args=1, params=' [subreddit name]'))
  410. cmds.sort(key=operator.attrgetter('name'))
  411. print('Bot Successfully Loaded... [Logged in as: ' + str(dex_bot.user.name) + ']')
  412. m = await dex_bot.send_message(discord.Object(id='168735910559481856'), 'Beep Boop.')
  413. await asyncio.sleep(5)
  414. try:
  415. await dex_bot.delete_message(m)
  416. except:
  417. pass
  418.  
  419.  
  420. @dex_bot.event
  421. async def on_message(message):
  422. global logdata
  423. if get_data_entry(str(message.author)):
  424. get_data_entry(str(message.author)).msg_count += 1
  425. elif 'dex-bot' not in str(message.author):
  426. data_entries.append(DataEntry([str(message.author)]))
  427. print('Created data entry for "' + str(message.author) + '"')
  428. if 'dex-bot' not in str(message.author) and message.content.startswith(CMD_PREFIX):
  429. try:
  430. await asyncio.sleep(1)
  431. await dex_bot.delete_message(message)
  432. except:
  433. pass
  434. get_data_entry(str(message.author)).cmd_count += 1
  435. logdata += '[' + message.author.name + ']' + message.content + '\n'
  436. for c in cmds:
  437. if message.content.lower()[1:].startswith(c.name):
  438. try:
  439. await c.execute(message)
  440. except:
  441. pass
  442. break
  443. else:
  444. if can_interact:
  445. await dex_bot.send_message(message.channel, '[Error]: Unknown Command "' + message.content + '"')
  446. else:
  447. await dex_bot.send_message(message.author, 'Shhh. I\'m in monitoring mode and cannot respond. Contact an admin to disable monitoring mode.')
  448.  
  449.  
  450. async def saveuserdata():
  451. f = open('data/stats.dat', 'w+')
  452. for d in data_entries:
  453. d.update()
  454. s = ''
  455. for n in range(len(d.ls)):
  456. s += str(d.ls[n]) + (';' if n + 1 < len(d.ls) else '')
  457. f.write(s + '\n')
  458. f.close()
  459.  
  460.  
  461. async def on_heartbeat():
  462. global uptime, bot_voice, audio_playing
  463. await dex_bot.wait_until_ready()
  464. while not dex_bot.is_closed:
  465. try:
  466. if bot_voice and bot_voice.is_connected() and not audio_playing.is_playing():
  467. await bot_voice.disconnect()
  468. except:
  469. pass
  470. uptime += 1
  471. await saveuserdata()
  472. await save_logs()
  473. await asyncio.sleep(60)
  474.  
  475. dex_bot.loop.create_task(on_heartbeat())
  476. dex_bot.run(BOT_TOKEN)
  477.  
  478. # https://praw.readthedocs.io/en/latest/code_overview/models/subreddit.html#praw.models.Subreddit
  479. # http://discordpy.readthedocs.io/en/latest/api.html#
  480. # http://discordpy.readthedocs.io/en/latest/api.html#voice
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement