#!/usr/bin/env python3 import discord import asyncio import aiohttp from urllib.parse import quote_plus, urlencode import os.path from os import getcwd, chdir from urllib.parse import unquote from mutagen import File import youtube_dl client = discord.Client() if not discord.opus.is_loaded(): discord.opus.load_opus("libopus.so.0") def is_safe_path(basedir, path, follow_symlinks=True): # resolves symbolic links if follow_symlinks: return os.path.realpath(path).startswith(basedir) return os.path.abspath(path).startswith(basedir) lastresults = [] player = None @client.event async def on_message(message): global lastresults global player if message.content.startswith("!upload ") and any(role.name == "Uploader" for role in message.author.roles): url, path = message.content[8:].split(" ", 1) opts = {} if path[-2:] == " v": opts["format"] = "bestvideo" opts["outtmpl"] = os.path.join("/var/www/html/", "vid", path[:-2], "%(title)s.%(ext)s") else: opts["postprocessors"] = [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': "mp3", 'preferredquality': "5", 'nopostoverwrites': False, }] opts["outtmpl"] = os.path.join("/var/www/html/", path, "%(title)s.%(ext)s") if not url or not path: await client.send_message(message.channel, "Usage: !upload ") return resp = await client.send_message(message.channel, "On it, just a second") await client.send_typing(message.channel) with youtube_dl.YoutubeDL(opts) as ydl: ydl.download([url]) await client.edit_message(resp, "Job done!") if message.content.startswith("!search "): with aiohttp.ClientSession() as session: async with session.get("http://tallyall.club/search.php", params={"q": message.content[8:], "json": ""}) as resp: data = await resp.json() if len(data["results"]) < 1: await client.send_message(message.channel, ":sos: No results") return out = ["Search results:"] lastresults = data["results"] numbers = [":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:"] for n,r in enumerate(data["results"][:8]): out.append("{} **{}** ({})".format(numbers[n], os.path.basename(r),os.path.dirname(r).split("/")[-1])) out.append(":signal_strength: !play ") out.append(":arrow_right: Full results at http://tallyall.club/search.php?" + urlencode({"q": message.content[8:]})) await client.send_message(message.channel, "\n".join(out)) if message.content.startswith("!play "): if player: player.stop() msg = message.content[6:] if msg.isdigit(): if int(msg) <= len(lastresults) and int(msg) > 0: msg = lastresults[int(msg)-1] else: await client.send_message(message.channel, "Invalid result number") return path = "/var/www/html/" + unquote(msg.strip().replace("http://tallyall.club/", "")) if is_safe_path("/var/www/html", path) and os.path.isfile(path) and File(path): voice = client.voice_client_in(message.server) if voice: await voice.disconnect() voice = await client.join_voice_channel(client.get_channel("386339345914920980")) player = voice.create_ffmpeg_player(path) player.start() else: await client.send_message(message.channel, "Invalid path") if message.content.startswith("!stop"): if player: player.stop() voice = client.voice_client_in(message.server) await voice.disconnect() if message.content.startswith("!link "): msg = message.content[6:] if msg.isdigit(): if int(msg) <= len(lastresults) and int(msg) > 0: msg = lastresults[int(msg)-1] else: await client.send_message(message.channel, "Invalid result number") return path = "/var/www/html/" + unquote(msg.strip().replace("http://tallyall.club/", "")) if is_safe_path("/var/www/html", path) and os.path.isfile(path): with open(path, "rb") as f: await client.send_file(message.channel, f, filename=os.path.basename(path)) else: await client.send_message(message.channel, "Something went wrong") @client.event async def on_ready(): print("Logged in as {} ({})".format(client.user.name, client.user.id)) print(discord.utils.oauth_url(client.user.id, permissions=discord.Permissions(3197952))) with open(".bottoken") as f: creds = f.read() if " " in creds: client.run(*creds.split(None, 1)) else: client.run(creds.strip())