Last active
January 29, 2021 22:14
-
-
Save twilight-sparkle-irl/dfa864e823aa482d904d6bfd1f5b43b8 to your computer and use it in GitHub Desktop.
simple LiquidSoap Discord bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import client | |
import discord | |
from discord.ext import commands | |
# TODO: Automatic updates on the statuses of tracks | |
# TODO: Make %info command make more sense and only let you view the status of requested tracks | |
# TODO: Make %queue and %info possible for non-DJs by ensuring safe commands — currently it's a security risk(?) | |
description = '''What's up, fresh meat. It's Vinyl Scratch, bringing you the tunes YOU want and letting you know what's under the needle.''' | |
bot = commands.Bot(command_prefix='%', description=description) | |
print("and 1") | |
cli = client.LiqClient('localhost',1234, "root","request") | |
print("and 2") | |
@bot.event | |
async def on_ready(): | |
print('Logged in as') | |
print(bot.user.name) | |
print(bot.user.id) | |
print('------') | |
@bot.command() | |
@commands.has_role("DJ") | |
async def skip(ctx): | |
skipped = cli.skip() | |
if skipped: | |
await ctx.send("Skipped that song.") | |
else: await ctx.send("Something went wrong.") | |
@bot.command() | |
@commands.has_role("DJ") | |
async def queue(ctx, uri): | |
x = cli.queue(uri) | |
await ctx.send("Your number is {0}. Do `%info {0}` to check your track's status.".format(x)) | |
@bot.command() | |
@commands.has_role("DJ") | |
async def info(ctx, number): | |
i = cli.info(number) | |
if not i or len(i) > 1: | |
await ctx.send("No such number?") | |
return | |
i = i[0] | |
title = i['title'] if 'title' in i else i['initial_uri'] | |
if i['status'] == "destroyed": | |
description = "Status is 'destroyed'. Did you input a valid URL?" | |
elif i['status'] == "resolving": | |
description = "Downloading this track right now! Wait warmly!" | |
elif i['status'] == "ready": | |
description = "Track is ready! Wait for it..." | |
elif i['status'] == "playing": | |
description = "Song's playing." | |
else: description = "Song is {}.".format(i['status']) | |
embed = discord.Embed(title=title, description=description, color=0x3167CC) | |
await ctx.send(embed=embed) | |
@bot.command() | |
async def np(ctx): | |
playing = cli.np() | |
title = playing['title'] if 'title' in playing else playing['filename'] | |
if 'purl' in playing: | |
orig = playing['purl'] | |
elif 'initial_uri' in playing: | |
orig = playing['initial_uri'].replace('youtube-dl:','') | |
else: | |
orig = "(unknown original URL)" | |
embed = discord.Embed(title=title, description=orig, color=0x3167CC) | |
await ctx.send(embed=embed) | |
if __name__ == "__main__": | |
print("startin") | |
bot.run("INSERT TOKEN HERE") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
from telnetlib import Telnet | |
import re | |
import pprint | |
class LiqBaseClient: | |
def __init__(self,host,port): | |
self.host = host | |
self.port = port | |
self.tel = Telnet(host,port) | |
def command(self,s,annoyance=0): | |
try: | |
cmd = bytes(s,"utf-8") | |
self.tel.write(cmd+b"\n") | |
ans = self.tel.read_until(b"END") | |
ans = ans.decode('utf-8') | |
ans = re.sub("[\r\n]*END$","",ans) | |
ans = re.sub("^[\r\n]*","",ans) | |
# liquidsoap will time you out even if you're actively using the connection | |
# compensate by just reconnecting and doing it again since it's also stateless, lol | |
if ans == 'Connection timed out.. Bye!\r\n': | |
if annoyance > 6: | |
raise RuntimeError("BaseClient got annoyed, is the server down?") | |
self.tel.open(self.host,self.port) | |
return self.command(s,annoyance=annoyance+1) | |
else: | |
return ans | |
except OSError: # connection closed | |
if annoyance > 6: | |
raise RuntimeError("BaseClient got annoyed, is the server down?") | |
self.tel.open(self.host,self.port) | |
return self.command(s,annoyance=annoyance+1) | |
def parse_metadata(self,s): | |
def dohash(a): | |
h={} | |
a=list(a) | |
for i in range(int(len(a)/2)): | |
a[2*i+1] = re.sub('^"','',re.sub('"$','',a[2*i+1])) | |
if a[2*i] in ('2nd_queue_pos','rid','source_id'): | |
h[a[2*i]]=int(a[2*i+1]) | |
else: | |
if a[2*i] in ('skip'): | |
if a[2*i+1]=='true': | |
h[a[2*i]]=True | |
else: | |
h[a[2*i]]=False | |
else: | |
h[a[2*i]]=a[2*i+1] | |
return h | |
def noblank(a): | |
return filter(lambda x: x!='',a) | |
# Avoid empty matched groups, otherwise there will be no element in | |
# the array. To do so, we include the ", and remove them later. | |
return [ dohash(noblank(re.compile('(.+)=(".*")\n').split(e))) for e in | |
noblank(re.compile('--- \d+ ---\n').split(self.command(s))) ] | |
class LiqClient(LiqBaseClient): | |
def __init__(self, host, port, main, request): | |
self.main = main | |
self.request = request | |
super().__init__(host, port) | |
def skip(self): | |
return (self.command(self.main+".skip") == "Done") | |
def queue(self, url): | |
item = self.command("{}.push {}".format(self.request, url)) | |
return int(item) | |
def info(self, item=None): | |
if item: | |
return self.parse_metadata("{}.metadata {}".format(self.request, item)) | |
else: | |
return self.parse_metadata("{}.metadata".format(self.main)) | |
def np(self): | |
i = self.info() | |
i.reverse() | |
return [x for x in i if x['status'] == "playing"][0] | |
if __name__ == "__main__": | |
c = LiqClient('localhost',1234, "root","request") | |
print("Has been running for "+c.command("uptime")) | |
pprint.pprint(c.info()) | |
import pdb; pdb.set_trace() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set("server.telnet",true) | |
set("server.telnet.bind_addr","127.0.0.1") | |
set("server.socket",true) | |
set("server.socket.path","/tmp/liquidsoap.sock") | |
normal = playlist(mode='randomize', reload=60, "./tracks/") | |
out = fallback([ request.queue(id="request", timeout=180.), normal ]) | |
add_skip_command(out) | |
out = mksafe(out) | |
out = nrj(out) | |
ice = output.icecast(%vorbis, id="root", | |
host = "127.0.0.1", port = 8000, | |
password = "insert icecast password here lol", mount = "radio.ogg", | |
out) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment