Last active 1639361745

Revision 237c938cd5707e53309ede6d1874e5a62aed0c6d

searchbot.py Raw
1#!/usr/bin/env python3
2import discord
3import asyncio
4import aiohttp
5from urllib.parse import quote_plus, urlencode
6import os.path
7from os import getcwd
8from urllib.parse import unquote
9from mutagen import File
10client = discord.Client()
11
12if not discord.opus.is_loaded():
13 discord.opus.load_opus("libopus.so.0")
14
15def is_safe_path(basedir, path, follow_symlinks=True):
16 # resolves symbolic links
17 if follow_symlinks:
18 return os.path.realpath(path).startswith(basedir)
19 return os.path.abspath(path).startswith(basedir)
20
21lastresults = []
22player = None
23
24@client.event
25async def on_message(message):
26 def after():
27 coro = client.voice_client_in(message.server).disconnect()
28 fut = asyncio.run_coroutine_threadsafe(coro, client.loop)
29 try:
30 fut.result()
31 except:
32 pass
33 global lastresults
34 global player
35 if message.content.startswith("!search "):
36 with aiohttp.ClientSession() as session:
37 async with session.get("http://tallyall.club/search.php", params={"q": message.content[8:], "json": ""}) as resp:
38 data = await resp.json()
39 if len(data["results"]) < 1:
40 await client.send_message(message.channel, ":sos: No results")
41 return
42 out = ["Search results:"]
43 lastresults = data["results"]
44 numbers = [":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:"]
45 for n,r in enumerate(data["results"][:8]):
46 out.append("{} {}".format(numbers[n], os.path.basename(r)))
47 out.append(":signal_strength: !play <number>")
48 if len(data["results"]) > 8:
49 out.append(":arrow_right: Full results at http://tallyall.club/search.php?" + urlencode({"q": message.content[8:]}))
50 await client.send_message(message.channel, "\n".join(out))
51 if message.content.startswith("!play "):
52 if player:
53 player.stop()
54 msg = message.content[6:]
55 if msg.isdigit():
56 if int(msg) <= len(lastresults) and int(msg) > 0:
57 msg = lastresults[int(msg)-1]
58 else:
59 await client.send_message(message.channel, "Invalid result number")
60 return
61 path = "/var/www/html/" + unquote(msg.strip().replace("http://tallyall.club/", ""))
62 if is_safe_path("/var/www/html", path) and os.path.isfile(path) and File(path):
63 voice = client.voice_client_in(message.server)
64 if voice:
65 await voice.disconnect()
66 voice = await client.join_voice_channel(client.get_channel("386339345914920980"))
67 player = voice.create_ffmpeg_player(path, after=after)
68 player.start()
69 else:
70 await client.send_message(message.channel, "Invalid path")
71 if message.content.startswith("!stop "):
72 if player:
73 player.stop()
74 voice = client.voice_client_in(message.server)
75 await voice.disconnect()
76
77@client.event
78async def on_ready():
79 print("Logged in as {} ({})".format(client.user.name, client.user.id))
80 print(discord.utils.oauth_url(client.user.id, permissions=discord.Permissions(3072)))
81
82with open(".bottoken") as f:
83 creds = f.read()
84 if " " in creds:
85 client.run(*creds.split(None, 1))
86 else:
87 client.run(creds.strip())