Plex-Bot-Music/PlexBot/bot.py

140 lines
4.3 KiB
Python
Raw Normal View History

import logging
from queue import Queue
2020-07-23 06:21:41 +02:00
import discord
from discord import FFmpegPCMAudio
2020-07-23 06:21:41 +02:00
from discord.ext import commands
from discord.ext.commands import command
from fuzzywuzzy import fuzz
from plexapi.exceptions import Unauthorized
2020-07-23 06:21:41 +02:00
from plexapi.server import PlexServer
2020-07-27 06:08:00 +02:00
logger = logging.getLogger("PlexBot")
2020-07-23 06:21:41 +02:00
class General(commands.Cog):
def __init__(self, bot):
self.bot = bot
@command()
async def kill(self, ctx):
2020-07-23 06:21:41 +02:00
await ctx.send(f"Stopping upon the request of {ctx.author.mention}")
await self.bot.close()
2020-07-27 06:08:00 +02:00
logger.info(f"Stopping upon the request of {ctx.author.mention}")
2020-07-23 06:21:41 +02:00
class Plex(commands.Cog):
def __init__(self, bot, base_url, plex_token, lib_name) -> None:
self.bot = bot
self.base_url = base_url
self.plex_token = plex_token
self.library_name = lib_name
try:
self.pms = PlexServer(self.base_url, self.plex_token)
except Unauthorized:
logger.fatal("Invalid Plex token, stopping...")
raise Unauthorized("Invalid Plex token")
2020-07-23 06:21:41 +02:00
self.music = self.pms.library.section(self.library_name)
self.vc = None
2020-07-27 06:08:00 +02:00
self.current_track = None
self.play_queue = Queue()
2020-07-27 06:08:00 +02:00
logger.info("Started bot successfully")
2020-07-23 06:21:41 +02:00
def _search_tracks(self, title):
tracks = self.music.searchTracks()
score = [None, -1]
2020-07-23 06:21:41 +02:00
for i in tracks:
s = fuzz.ratio(title.lower(), i.title.lower())
if s > score[1]:
score[0] = i
2020-07-23 06:21:41 +02:00
score[1] = s
elif s == score[1]:
score[0] = i
2020-07-23 06:21:41 +02:00
return score[0]
2020-07-23 06:21:41 +02:00
@command()
async def hello(self, ctx, *, member: discord.member = None):
member = member or ctx.author
await ctx.send(f"Hello {member}")
async def _after_callback(self, error=None):
logger.debug("After callbacked")
2020-07-27 06:08:00 +02:00
if self.play_queue.empty():
self.current_track = None
logger.debug("No tracks left in queue, returning")
2020-07-27 06:08:00 +02:00
else:
track = self.play_queue.get()
audio_stream = FFmpegPCMAudio(track.getStreamURL())
self.current_track = track
logger.debug(f"Started playing next song in queue: {track.title}")
self.vc.play(audio_stream)
2020-07-27 06:08:00 +02:00
await self.callback_ctx.send(f"Playing {track.title}")
2020-07-23 06:21:41 +02:00
@command()
async def play(self, ctx, *args):
if not len(args):
await ctx.send(f"Usage: {BOT_PREFIX}play TITLE_OF_SONG")
return
2020-07-23 06:21:41 +02:00
title = " ".join(args)
track = self._search_tracks(title)
if track:
track_url = track.getStreamURL()
if not ctx.author.voice:
await ctx.send("Join a voice channel first!")
return
if not self.vc:
self.vc = await ctx.author.voice.channel.connect()
logger.debug("Connected to vc.")
if self.vc.is_playing():
self.play_queue.put(track)
self.callback_ctx = ctx
await ctx.send(f"Added {track.title} to queue.")
2020-07-27 06:08:00 +02:00
logger.debug(f"Added {track.title} to queue.")
else:
audio_stream = FFmpegPCMAudio(track_url)
self.vc.play(audio_stream, after=self._after_callback)
2020-07-27 06:08:00 +02:00
self.current_track = track
logger.debug(f"Playing {track.title}")
await ctx.send(f"Playing {track.title}")
2020-07-23 06:21:41 +02:00
else:
2020-07-27 06:08:00 +02:00
logger.debug(f"{title} was not found.")
await ctx.send(f"{title} was not found.")
@command()
async def stop(self, ctx):
if self.vc:
self.vc.stop()
await self.vc.disconnect()
self.vc = None
await ctx.send("Stopped")
@command()
async def pause(self, ctx):
if self.vc:
await self.vc.pause()
await ctx.send("Paused")
@command()
async def resume(self, ctx):
if self.vc:
await self.vc.resume()
await ctx.send("Resumed")
@command()
async def skip(self, ctx):
logger.debug("Skip")
if self.vc:
self.vc.stop()
await self._after_callback()
2020-07-27 06:08:00 +02:00
@command()
async def np(self, ctx):
await ctx.send(f"Currently playing: {self.current_track.title}")