#!/usr/bin/env python3 import discord import asyncio import aiohttp from urllib.parse import quote_plus, urlencode import os.path from os import getcwd from urllib.parse import unquote from mutagen import File 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): def after(): coro = client.voice_client_in(message.server).disconnect() fut = asyncio.run_coroutine_threadsafe(coro, client.loop) try: fut.result() except: pass global lastresults global player 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))) out.append(":signal_strength: !play ") if len(data["results"]) > 8: 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, after=after) 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() @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(3072))) with open(".bottoken") as f: creds = f.read() if " " in creds: client.run(*creds.split(None, 1)) else: client.run(creds.strip())