Made the plex functions use buttons

This commit is contained in:
NikolajDanger
2021-08-18 21:12:32 +02:00
parent ae71ff631d
commit 3819e56cd6
6 changed files with 305 additions and 307 deletions

View File

@ -34,6 +34,11 @@ class EventCog(commands.Cog):
"""Handle when someone reacts to a message."""
await self.bot.event_handler.on_reaction_add(reaction, user)
@commands.Cog.listener()
async def on_component(self, ctx):
"""Handle when someone reacts to a message."""
await self.bot.event_handler.on_component(ctx)
def setup(bot):
"""Add the eventcog to the bot."""

View File

@ -1,11 +1,15 @@
"""Plex integration with the bot."""
from math import floor, ceil
import time
import json
import asyncio
import requests
import imdb
import discord
import xmltodict
from discord_slash.utils.manage_components import (create_button,
create_actionrow)
from discord_slash.model import ButtonStyle
class Plex():
"""Container for Plex functions and commands."""
@ -64,88 +68,102 @@ class Plex():
colour=0x00FF00
)
message = await ctx.send(embed=embed)
message_data = {"message_id":message.id,"imdb_ids":imdb_ids}
file_path = f"gwendolyn/resources/plex/old_message{ctx.channel.id}"
with open(file_path,"w") as file_pointer:
json.dump(message_data, file_pointer)
buttons = []
if len(movies) == 1:
await message.add_reaction("✔️")
buttons.append(create_button(
style=ButtonStyle.green,
label="",
custom_id=f"plex:movie:{imdb_ids[0]}"
)
)
else:
for i in range(len(movies)):
await message.add_reaction(["1","2","3","4","5"][i])
buttons.append(
create_button(
style=ButtonStyle.blue,
label=str(i+1),
custom_id=f"plex:movie:{imdb_ids[i]}"
)
)
buttons.append(create_button(
style=ButtonStyle.red,
label="X",
custom_id="plex:movie:"
)
)
action_rows = []
for i in range(((len(buttons)-1)//5)+1):
action_rows.append(
create_actionrow(
*buttons[(i*5):(min(len(buttons),i*5+5))]
)
)
await ctx.send(embed=embed, components=action_rows)
await message.add_reaction("")
message = await ctx.channel.fetch_message(message.id)
if (message.content != "" and
not isinstance(ctx.channel, discord.DMChannel)):
await message.clear_reactions()
async def add_movie(self, message, imdb_id, edit_message = True):
"""Add a movie to Plex server."""
if imdb_id is None:
if not edit_message:
await message.delete()
if imdb_id == "":
self.bot.log("Did not find what the user was searching for")
if edit_message:
await message.edit(
embed = None,
content = "Try searching for the IMDB id"
)
else:
await message.channel.send("Try searching for the IMDB id")
message_text = "Try searching for the IMDB id"
else:
self.bot.log("Trying to add movie "+str(imdb_id))
# Searches for the movie using the imdb id through Radarr
api_key = self.credentials["radarr_key"]
request_url = self.radarr_url+"movie/lookup/imdb?imdbId=tt"+imdb_id
request_url += "&apiKey="+api_key
response = requests.get(request_url)
# Makes the dict used for the post request
lookup_data = response.json()
post_data = {"qualityProfileId": 1,
"rootFolder_path" : self.movie_path,
post_data = {
"qualityProfileId": 1,
"rootFolderPath" : self.movie_path,
"monitored" : True,
"addOptions": {"searchForMovie": True}}
"addOptions": {"searchForMovie": True}
}
for key in ["tmdbId","title","titleSlug","images","year"]:
post_data.update({key : lookup_data[key]})
# Makes the post request
response = requests.post(
url = self.radarr_url+"movie?apikey="+api_key,
json = post_data
)
# Deciphers the response
if response.status_code == 201:
success_message = "{} successfully added to Plex".format(
self.bot.log("Added "+post_data["title"]+" to Plex")
message_text = "{} successfully added to Plex".format(
post_data["title"]
)
if edit_message:
await message.edit(
embed = None,
content = success_message
)
else:
await message.channel.send(success_message)
self.bot.log("Added "+post_data["title"]+" to Plex")
elif response.status_code == 400:
fail_text = self.long_strings["Already on Plex"].format(
self.bot.log("The movie was already on plex")
message_text = self.long_strings["Already on Plex"].format(
post_data['title']
)
if edit_message:
await message.edit(embed = None, content = fail_text)
else:
await message.channel.send(fail_text)
else:
self.bot.log(str(response.status_code)+" "+response.reason)
message_text = "Something went wrong",
if edit_message:
await message.edit(
embed = None,
content = "Something went wrong"
content = message_text,
components = []
)
else:
await message.channel.send("Something went wrong")
self.bot.log(str(response.status_code)+" "+response.reason)
await message.channel.send(message_text)
async def request_show(self, ctx, show_name):
"""Request a show for the Plex server."""
@ -166,7 +184,7 @@ class Plex():
message_title = "**Is it any of these shows?**"
message_text = ""
imdb_names = []
imdb_ids = []
for i, show in enumerate(shows):
try:
@ -176,10 +194,10 @@ class Plex():
message_text += "\n"+str(i+1)+") "+show["title"]
except KeyError:
message_text += "Error"
imdb_names.append(show["title"])
imdb_ids.append(show.movieID)
self.bot.log(
f"Returning a list of {len(shows)} possible shows: {imdb_names}"
f"Returning a list of {len(shows)} possible shows: {imdb_ids}"
)
embed = discord.Embed(
@ -188,42 +206,69 @@ class Plex():
colour=0x00FF00
)
message = await ctx.send(embed=embed)
message_data = {"message_id":message.id,"imdb_names":imdb_names}
file_path = "gwendolyn/resources/plex/old_message"+str(ctx.channel.id)
with open(file_path,"w") as file_pointer:
json.dump(message_data, file_pointer)
buttons = []
if len(shows) == 1:
await message.add_reaction("✔️")
else:
for i in range(len(shows)):
await message.add_reaction(["1","2","3","4","5"][i])
await message.add_reaction("")
message = await ctx.channel.fetch_message(message.id)
if message.content != "":
if not isinstance(ctx.channel, discord.DMChannel):
await message.clear_reactions()
async def add_show(self, message, imdb_name):
"""Add the requested show to Plex."""
if imdb_name is None:
self.bot.log("Did not find what the user was searching for")
await message.edit(
embed = None,
content = "Try searching for the IMDB id"
buttons.append(create_button(
style=ButtonStyle.green,
label="",
custom_id=f"plex:show:{imdb_ids[0]}"
)
)
else:
self.bot.log("Trying to add show "+str(imdb_name))
for i in range(len(shows)):
buttons.append(
create_button(
style=ButtonStyle.blue,
label=str(i+1),
custom_id=f"plex:show:{imdb_ids[i]}"
)
)
buttons.append(create_button(
style=ButtonStyle.red,
label="X",
custom_id="plex:show:"
)
)
action_rows = []
for i in range(((len(buttons)-1)//5)+1):
action_rows.append(
create_actionrow(
*buttons[(i*5):(min(len(buttons),i*5+5))]
)
)
await ctx.send(embed=embed, components=action_rows)
async def add_show(self, message, imdb_id, edit_message = True):
"""Add the requested show to Plex."""
if imdb_id == "":
self.bot.log("Did not find what the user was searching for")
message_text = "Try searching for the IMDB id"
else:
self.bot.log("Trying to add show "+str(imdb_id))
# Finds the tvdb id
tvdb_api_url = "https://thetvdb.com/api/"
tvdb_method = "GetSeriesByRemoteID.php"
tvdb_request_url = f"{tvdb_api_url}{tvdb_method}"
tvdb_id = xmltodict.parse(
requests.get(
tvdb_request_url+f"?imdbid=tt{imdb_id}",
headers = {"ContentType" : "application/json"}
).text
)['Data']['Series']['seriesid']
# Finds the rest of the information using Sonarr
api_key = self.credentials["sonarr_key"]
request_url = self.sonarr_url+"series/lookup?term="
request_url += imdb_name.replace(" ","%20")
request_url += f"tvdb:{tvdb_id}"
request_url += "&apiKey="+api_key
response = requests.get(request_url)
# Makes the dict used for the post request
lookup_data = response.json()[0]
post_data = {
"ProfileId" : 1,
@ -234,29 +279,32 @@ class Plex():
for key in ["tvdbId","title","titleSlug","images","seasons"]:
post_data.update({key : lookup_data[key]})
# Makes the post request
response = requests.post(
url= self.sonarr_url+"series?apikey="+api_key,
json = post_data
)
# Deciphers the response
if response.status_code == 201:
await message.edit(
embed = None,
content = post_data["title"]+" successfully added to Plex"
)
self.bot.log("Added a "+post_data["title"]+" to Plex")
message_text = post_data["title"]+" successfully added to Plex"
elif response.status_code == 400:
text = self.long_strings["Already on Plex"].format(
message_text = self.long_strings["Already on Plex"].format(
post_data['title']
)
await message.edit(embed = None, content = text)
else:
self.bot.log(str(response.status_code)+" "+response.reason)
message_text = "Something went wrong"
if edit_message:
await message.edit(
embed = None,
content = "Something went wrong"
content = message_text,
components = []
)
self.bot.log(str(response.status_code)+" "+response.reason)
else:
await message.channel.send(message_text)
async def __generate_download_list(self, show_dm, show_movies, show_shows,
episodes):
@ -364,7 +412,9 @@ class Plex():
movie_list = requests.get(
self.radarr_url+"movie?apiKey="+self.credentials["radarr_key"]
).json()
print(self.radarr_url+"movie?apiKey="+self.credentials["radarr_key"])
print(
self.radarr_url+"movie?apiKey="+self.credentials["radarr_key"]
)
movie_queue = requests.get(
self.radarr_url+"queue?apiKey="+self.credentials["radarr_key"]
).json()

View File

@ -15,7 +15,7 @@ import discord # Used to init discord.Game and discord.Status, as well
from discord.ext import commands # Used to compare errors with command
# errors
from discord_slash.context import SlashContext
from discord_slash.context import SlashContext, ComponentContext
from gwendolyn.utils.util_functions import emoji_to_command
@ -72,13 +72,6 @@ class EventHandler():
channel = message.channel
reacted_message = f"{user.display_name} reacted to a message"
self.bot.log(reacted_message, str(channel.id))
plex_data = tests.plex_reaction_test(message)
# plex_data is a list containing 3 elements: whether it was
# the add_show/add_movie command message the reaction was to
# (bool), whether it's a movie (bool) (if false, it's a
# show), and the imdb ids/names for the for the movies or
# shows listed in the message (list).
reaction_test_parameters = [message, f"#{str(user.id)}"]
if tests.connect_four_reaction_test(*reaction_test_parameters):
@ -86,34 +79,6 @@ class EventHandler():
params = [message, f"#{user.id}", column-1]
await self.bot.games.connect_four.place_piece(*params)
if plex_data[0]:
plex_functions = self.bot.other.plex
if plex_data[1]:
movie_pick = emoji_to_command(reaction.emoji)
if movie_pick == "none":
imdb_id = None
else:
imdb_id = plex_data[2][movie_pick-1]
if isinstance(channel, discord.DMChannel):
await message.delete()
await plex_functions.add_movie(message, imdb_id, False)
else:
await message.clear_reactions()
await plex_functions.add_movie(message, imdb_id)
else:
show_pick = emoji_to_command(reaction.emoji)
if show_pick == "none":
imdb_name = None
else:
imdb_name = plex_data[2][show_pick-1]
if isinstance(channel, discord.DMChannel):
await message.delete()
await plex_functions.add_show(message, imdb_name, False)
else:
await message.clear_reactions()
await plex_functions.add_show(message, imdb_name)
elif tests.hangman_reaction_test(*reaction_test_parameters):
self.bot.log("They reacted to the hangman message")
@ -126,6 +91,25 @@ class EventHandler():
else:
self.bot.log("Bot they didn't react with a valid guess")
async def on_component(self, ctx: ComponentContext):
info = ctx.custom_id.split(":")
channel = ctx.origin_message.channel
if info[0] == "plex":
if info[1] == "movie":
await self.bot.other.plex.add_movie(
ctx.origin_message,
info[2],
not isinstance(channel, discord.DMChannel)
)
if info[1] == "show":
await self.bot.other.plex.add_show(
ctx.origin_message,
info[2],
not isinstance(channel, discord.DMChannel)
)
class ErrorHandler():
"""

View File

@ -6,7 +6,6 @@ Contains classes used for utilities.
DatabaseFuncs()
"""
import os # Used to test if files exist
import json # Used to read the data about add_movie/add_show
import time # Used to test how long it's been since commands were synced
import re # Used in get_id
@ -206,45 +205,6 @@ class DatabaseFuncs():
return game_message
def plex_reaction_test(self, message: discord.Message):
"""
Test if the given message is the response to a plex request.
*Parameters*
------------
message: discord.Message
The message to test.
*Returns*
---------
: bool
Whether the message is the response to a plex request.
: bool
Whether it was a movie request (false for a show
request)
: list
A list of ids or names of the shows or movies that
Gwendolyn presented after the request.
"""
channel = message.channel
old_messages_path = "gwendolyn/resources/plex/"
file_path = old_messages_path + f"old_message{str(channel.id)}"
if os.path.isfile(file_path):
with open(file_path, "r") as file_pointer:
data = json.load(file_pointer)
else:
return (False, None, None)
if data["message_id"] != message.id:
return (False, None, None)
if "imdb_ids" in data:
return_data = (True, True, data["imdb_ids"])
else:
return_data = (True, False, data["imdb_names"])
return return_data
async def imdb_commands(self):
"""Sync the slash commands with the discord API."""
collection = self.bot.database["last synced"]

View File

@ -23,7 +23,6 @@ lxml==4.6.3
more-itertools==8.8.0
multidict==5.1.0
Pillow==8.3.1
pip==21.2.3
pymongo==3.12.0
requests==2.26.0
setuptools==57.4.0