mirror of
https://github.com/jarulsamy/Plex-Bot.git
synced 2024-08-19 15:01:55 +02:00
✨ Add lyrics command
Optionally grab lyrics of a song using the lyrics command. Required LyricsGenius API token.
This commit is contained in:
parent
a6be6eac37
commit
545654f9a7
@ -56,4 +56,7 @@ def load_config(filename: str) -> Dict[str, str]:
|
|||||||
config["plex"]["log_level"] = levels[config["plex"]["log_level"].upper()]
|
config["plex"]["log_level"] = levels[config["plex"]["log_level"].upper()]
|
||||||
config["discord"]["log_level"] = levels[config["discord"]["log_level"].upper()]
|
config["discord"]["log_level"] = levels[config["discord"]["log_level"].upper()]
|
||||||
|
|
||||||
|
if config["lyrics"]["token"].lower() == "none":
|
||||||
|
config["lyrics"]["token"] = None
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
@ -20,6 +20,8 @@ BASE_URL = config["plex"]["base_url"]
|
|||||||
PLEX_TOKEN = config["plex"]["token"]
|
PLEX_TOKEN = config["plex"]["token"]
|
||||||
LIBRARY_NAME = config["plex"]["library_name"]
|
LIBRARY_NAME = config["plex"]["library_name"]
|
||||||
|
|
||||||
|
LYRICS_TOKEN = config["lyrics"]["token"]
|
||||||
|
|
||||||
# Set appropiate log level
|
# Set appropiate log level
|
||||||
root_log = logging.getLogger()
|
root_log = logging.getLogger()
|
||||||
plex_log = logging.getLogger("Plex")
|
plex_log = logging.getLogger("Plex")
|
||||||
@ -28,9 +30,16 @@ bot_log = logging.getLogger("Bot")
|
|||||||
plex_log.setLevel(config["plex"]["log_level"])
|
plex_log.setLevel(config["plex"]["log_level"])
|
||||||
bot_log.setLevel(config["discord"]["log_level"])
|
bot_log.setLevel(config["discord"]["log_level"])
|
||||||
|
|
||||||
|
plex_args = {
|
||||||
|
"base_url": BASE_URL,
|
||||||
|
"plex_token": PLEX_TOKEN,
|
||||||
|
"lib_name": LIBRARY_NAME,
|
||||||
|
"lyrics_token": LYRICS_TOKEN,
|
||||||
|
}
|
||||||
|
|
||||||
bot = Bot(command_prefix=BOT_PREFIX)
|
bot = Bot(command_prefix=BOT_PREFIX)
|
||||||
# Remove help command, we have our own custom one.
|
# Remove help command, we have our own custom one.
|
||||||
bot.remove_command("help")
|
bot.remove_command("help")
|
||||||
bot.add_cog(General(bot))
|
bot.add_cog(General(bot))
|
||||||
bot.add_cog(Plex(bot, BASE_URL, PLEX_TOKEN, LIBRARY_NAME, BOT_PREFIX))
|
bot.add_cog(Plex(bot, **plex_args))
|
||||||
bot.run(TOKEN)
|
bot.run(TOKEN)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""Track version number of package."""
|
"""Track version number of package."""
|
||||||
VERSION = "1.0.1"
|
VERSION = "1.0.2"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print(VERSION)
|
print(VERSION)
|
||||||
|
@ -5,6 +5,7 @@ import logging
|
|||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
import lyricsgenius
|
||||||
from async_timeout import timeout
|
from async_timeout import timeout
|
||||||
from discord import FFmpegPCMAudio
|
from discord import FFmpegPCMAudio
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
@ -28,6 +29,7 @@ General:
|
|||||||
Plex:
|
Plex:
|
||||||
play <SONG_NAME> - Play a song from the plex server.
|
play <SONG_NAME> - Play a song from the plex server.
|
||||||
album <ALBUM_NAME> - Queue an entire album to play.
|
album <ALBUM_NAME> - Queue an entire album to play.
|
||||||
|
lyrics - Print the lyrics of the song (Requires Genius API)
|
||||||
np - Print the current playing song.
|
np - Print the current playing song.
|
||||||
stop - Halt playback and leave vc.
|
stop - Halt playback and leave vc.
|
||||||
pause - Pause playback.
|
pause - Pause playback.
|
||||||
@ -119,6 +121,15 @@ class General(commands.Cog):
|
|||||||
except (discord.Forbidden, discord.NotFound, discord.HTTPException):
|
except (discord.Forbidden, discord.NotFound, discord.HTTPException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async for i in channel.history(limit=limit):
|
||||||
|
if i.author == ctx.message.author and i.content.startswith(
|
||||||
|
self.bot.command_prefix
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
await i.delete()
|
||||||
|
except (discord.Forbidden, discord.NotFound, discord.HTTPException):
|
||||||
|
pass
|
||||||
|
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
bot_log.info("Unable to delete messages, insufficient permissions.")
|
bot_log.info("Unable to delete messages, insufficient permissions.")
|
||||||
await ctx.send("I don't have the necessary permissions to delete messages.")
|
await ctx.send("I don't have the necessary permissions to delete messages.")
|
||||||
@ -136,9 +147,7 @@ class Plex(commands.Cog):
|
|||||||
# All are necessary to detect global interactions
|
# All are necessary to detect global interactions
|
||||||
# within the bot.
|
# within the bot.
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, bot, **kwargs):
|
||||||
self, bot, base_url: str, plex_token: str, lib_name: str, bot_prefix: str
|
|
||||||
):
|
|
||||||
"""Initializes Plex resources
|
"""Initializes Plex resources
|
||||||
|
|
||||||
Connects to Plex library and sets up
|
Connects to Plex library and sets up
|
||||||
@ -149,7 +158,6 @@ class Plex(commands.Cog):
|
|||||||
base_url: str url to Plex server
|
base_url: str url to Plex server
|
||||||
plex_token: str X-Token of Plex server
|
plex_token: str X-Token of Plex server
|
||||||
lib_name: str name of Plex library to search through
|
lib_name: str name of Plex library to search through
|
||||||
bot_prefix: str prefix used to interact with bots
|
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
plexapi.exceptions.Unauthorized: Invalid Plex token
|
plexapi.exceptions.Unauthorized: Invalid Plex token
|
||||||
@ -159,10 +167,16 @@ class Plex(commands.Cog):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.base_url = base_url
|
self.base_url = kwargs["base_url"]
|
||||||
self.plex_token = plex_token
|
self.plex_token = kwargs["plex_token"]
|
||||||
self.library_name = lib_name
|
self.library_name = kwargs["lib_name"]
|
||||||
self.bot_prefix = bot_prefix
|
self.bot_prefix = bot.command_prefix
|
||||||
|
|
||||||
|
if kwargs["lyrics_token"]:
|
||||||
|
self.genius = lyricsgenius.Genius(kwargs["lyrics_token"])
|
||||||
|
else:
|
||||||
|
plex_log.warning("No lyrics token specified, lyrics disabled")
|
||||||
|
self.genius = None
|
||||||
|
|
||||||
# Log fatal invalid plex token
|
# Log fatal invalid plex token
|
||||||
try:
|
try:
|
||||||
@ -618,3 +632,54 @@ class Plex(commands.Cog):
|
|||||||
self.play_queue = asyncio.Queue()
|
self.play_queue = asyncio.Queue()
|
||||||
bot_log.debug("Cleared queue")
|
bot_log.debug("Cleared queue")
|
||||||
await ctx.send(":boom: Queue cleared.")
|
await ctx.send(":boom: Queue cleared.")
|
||||||
|
|
||||||
|
@command()
|
||||||
|
async def lyrics(self, ctx):
|
||||||
|
"""User command to get lyrics of a song.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ctx: discord.ext.commands.Context message context from command
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
if not self.current_track:
|
||||||
|
plex_log.info("No song currently playing")
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.genius:
|
||||||
|
plex_log.info(
|
||||||
|
"Searching for %s, %s",
|
||||||
|
self.current_track.title,
|
||||||
|
self.current_track.artist().title,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
song = self.genius.search_song(
|
||||||
|
self.current_track.title, self.current_track.artist().title
|
||||||
|
)
|
||||||
|
except TypeError:
|
||||||
|
self.genius = None
|
||||||
|
plex_log.error("Invalid genius token, disabling lyrics")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
lyrics = song.lyrics
|
||||||
|
# Split into 1950 char chunks
|
||||||
|
# Discord max message length is 2000
|
||||||
|
lines = [(lyrics[i : i + 1950]) for i in range(0, len(lyrics), 1950)]
|
||||||
|
|
||||||
|
for i in lines:
|
||||||
|
if i == "":
|
||||||
|
continue
|
||||||
|
# Apply code block format
|
||||||
|
i = f"```{i}```"
|
||||||
|
await ctx.send(i)
|
||||||
|
|
||||||
|
except (IndexError, TypeError):
|
||||||
|
plex_log.info("Could not find lyrics")
|
||||||
|
await ctx.send("Can't find lyrics for this song.")
|
||||||
|
else:
|
||||||
|
plex_log.warning("Attempted lyrics without valid token")
|
||||||
|
@ -4,3 +4,4 @@ fuzzywuzzy==0.18.0
|
|||||||
pynacl==1.4.0
|
pynacl==1.4.0
|
||||||
ffmpeg==1.4
|
ffmpeg==1.4
|
||||||
PyYAML==5.3.1
|
PyYAML==5.3.1
|
||||||
|
lyricsgenius==2.0.0
|
||||||
|
@ -11,3 +11,6 @@ plex:
|
|||||||
token: "<PLEX_TOKEN>"
|
token: "<PLEX_TOKEN>"
|
||||||
library_name: "<LIBRARY_NAME>"
|
library_name: "<LIBRARY_NAME>"
|
||||||
log_level: "debug"
|
log_level: "debug"
|
||||||
|
|
||||||
|
lyrics:
|
||||||
|
token: <CLIENT_ACCESS_TOKEN>
|
||||||
|
Loading…
Reference in New Issue
Block a user