🧹 More refactoring
This commit is contained in:
@ -2,4 +2,4 @@
|
||||
|
||||
__all__ = ["Other"]
|
||||
|
||||
from .other import Other
|
||||
from .other import Other
|
||||
|
@ -1,413 +0,0 @@
|
||||
import requests, imdb, discord, json, math, time, asyncio
|
||||
|
||||
class BedreNetflix():
|
||||
def __init__(self,bot):
|
||||
self.bot = bot
|
||||
ip = ["localhost", "192.168.0.40"][self.bot.options["testing"]]
|
||||
|
||||
self.radarrURL = "http://"+ip+":7878/api/v3/"
|
||||
self.sonarrURL = "http://"+ip+":8989/api/"
|
||||
self.qbittorrentURL = "http://"+ip+":8080/api/v2/"
|
||||
self.moviePath = "/media/plex/Server/movies/"
|
||||
self.showPath = "/media/plex/Server/Shows/"
|
||||
|
||||
#Returns a list of no more than 5 options when user requests a movie
|
||||
async def requestMovie(self, ctx, movieName):
|
||||
await self.bot.defer(ctx)
|
||||
|
||||
self.bot.log("Searching for "+movieName)
|
||||
movieList = imdb.IMDb().search_movie(movieName)
|
||||
movies = []
|
||||
for movie in movieList:
|
||||
if movie["kind"] == "movie":
|
||||
movies.append(movie)
|
||||
if len(movies) > 5:
|
||||
movies = movies[:5]
|
||||
|
||||
if len(movies) == 1:
|
||||
messageTitle = "**Is it this movie?**"
|
||||
else:
|
||||
messageTitle = "**Is it any of these movies?**"
|
||||
|
||||
messageText = ""
|
||||
imdb_ids = []
|
||||
|
||||
for x, movie in enumerate(movies):
|
||||
try:
|
||||
messageText += "\n"+str(x+1)+") "+movie["title"]+" ("+str(movie["year"])+")"
|
||||
except:
|
||||
try:
|
||||
messageText += "\n"+str(x+1)+") "+movie["title"]
|
||||
except:
|
||||
messageText += "Error"
|
||||
imdb_ids.append(movie.movieID)
|
||||
|
||||
self.bot.log("Returning a list of "+str(len(movies))+" possible movies: "+str(imdb_ids))
|
||||
|
||||
em = discord.Embed(title=messageTitle,description=messageText,colour=0x00FF00)
|
||||
|
||||
message = await ctx.send(embed=em)
|
||||
|
||||
messageData = {"message_id":message.id,"imdb_ids":imdb_ids}
|
||||
|
||||
with open("gwendolyn/resources/bedre_netflix/old_message"+str(ctx.channel.id),"w") as f:
|
||||
json.dump(messageData,f)
|
||||
|
||||
if len(movies) == 1:
|
||||
await message.add_reaction("✔️")
|
||||
else:
|
||||
for x in range(len(movies)):
|
||||
await message.add_reaction(["1️⃣","2️⃣","3️⃣","4️⃣","5️⃣"][x])
|
||||
|
||||
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()
|
||||
|
||||
#Adds the requested movie to Bedre Netflix
|
||||
async def add_movie(self, message, imdbId, editMessage = True):
|
||||
if imdbId == None:
|
||||
self.bot.log("Did not find what the user was searching for")
|
||||
if editMessage:
|
||||
await message.edit(embed = None, content = "Try searching for the IMDB id")
|
||||
else:
|
||||
await message.channel.send("Try searching for the IMDB id")
|
||||
else:
|
||||
self.bot.log("Trying to add movie "+str(imdbId))
|
||||
apiKey = self.bot.credentials["radarr_key"]
|
||||
response = requests.get(self.radarrURL+"movie/lookup/imdb?imdbId=tt"+imdbId+"&apiKey="+apiKey)
|
||||
lookupData = response.json()
|
||||
postData = {"qualityProfileId": 1,
|
||||
"rootFolderPath" : self.moviePath,
|
||||
"monitored" : True,
|
||||
"addOptions": {"searchForMovie": True}}
|
||||
for key in ["tmdbId","title","titleSlug","images","year"]:
|
||||
postData.update({key : lookupData[key]})
|
||||
|
||||
r = requests.post(url= self.radarrURL+"movie?apikey="+apiKey,json = postData)
|
||||
|
||||
if r.status_code == 201:
|
||||
if editMessage:
|
||||
await message.edit(embed = None, content = postData["title"]+" successfully added to Bedre Netflix")
|
||||
else:
|
||||
await message.channel.send(postData["title"]+" successfully added to Bedre Netflix")
|
||||
|
||||
self.bot.log("Added "+postData["title"]+" to Bedre Netflix")
|
||||
elif r.status_code == 400:
|
||||
text = f"{postData['title']} is either already on Bedre Netflix, downloading, or not available"
|
||||
if editMessage:
|
||||
await message.edit(embed = None, content = text)
|
||||
else:
|
||||
await message.channel.send(text)
|
||||
else:
|
||||
if editMessage:
|
||||
await message.edit(embed = None, content = "Something went wrong")
|
||||
else:
|
||||
await message.channel.send("Something went wrong")
|
||||
self.bot.log(str(r.status_code)+" "+r.reason)
|
||||
|
||||
#Returns a list of no more than 5 options when user requests a show
|
||||
async def requestShow(self, ctx, showName):
|
||||
await self.bot.defer(ctx)
|
||||
|
||||
self.bot.log("Searching for "+showName)
|
||||
movies = imdb.IMDb().search_movie(showName) #Replace with tvdb
|
||||
shows = []
|
||||
for movie in movies:
|
||||
if movie["kind"] in ["tv series","tv miniseries"]:
|
||||
shows.append(movie)
|
||||
if len(shows) > 5:
|
||||
shows = shows[:5]
|
||||
|
||||
if len(shows) == 1:
|
||||
messageTitle = "**Is it this show?**"
|
||||
else:
|
||||
messageTitle = "**Is it any of these shows?**"
|
||||
|
||||
messageText = ""
|
||||
imdb_names = []
|
||||
|
||||
for x, show in enumerate(shows):
|
||||
try:
|
||||
messageText += "\n"+str(x+1)+") "+show["title"]+" ("+str(show["year"])+")"
|
||||
except:
|
||||
try:
|
||||
messageText += "\n"+str(x+1)+") "+show["title"]
|
||||
except:
|
||||
messageText += "Error"
|
||||
imdb_names.append(show["title"])
|
||||
|
||||
self.bot.log("Returning a list of "+str(len(shows))+" possible shows: "+str(imdb_names))
|
||||
|
||||
em = discord.Embed(title=messageTitle,description=messageText,colour=0x00FF00)
|
||||
|
||||
message = await ctx.send(embed=em)
|
||||
|
||||
messageData = {"message_id":message.id,"imdb_names":imdb_names}
|
||||
|
||||
with open("gwendolyn/resources/bedre_netflix/old_message"+str(ctx.channel.id),"w") as f:
|
||||
json.dump(messageData,f)
|
||||
|
||||
if len(shows) == 1:
|
||||
await message.add_reaction("✔️")
|
||||
else:
|
||||
for x in range(len(shows)):
|
||||
await message.add_reaction(["1️⃣","2️⃣","3️⃣","4️⃣","5️⃣"][x])
|
||||
|
||||
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()
|
||||
|
||||
#Adds the requested show to Bedre Netflix
|
||||
async def add_show(self, message, imdb_name):
|
||||
if imdb_name == 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")
|
||||
else:
|
||||
self.bot.log("Trying to add show "+str(imdb_name))
|
||||
apiKey = self.bot.credentials["sonarr_key"]
|
||||
response = requests.get(self.sonarrURL+"series/lookup?term="+imdb_name.replace(" ","%20")+"&apiKey="+apiKey)
|
||||
lookupData = response.json()[0]
|
||||
postData = {"ProfileId" : 1,
|
||||
"rootFolderPath" : self.showPath,
|
||||
"monitored" : True,
|
||||
"addOptions" : {"searchForMissingEpisodes" : True}}
|
||||
for key in ["tvdbId","title","titleSlug","images","seasons"]:
|
||||
postData.update({key : lookupData[key]})
|
||||
|
||||
r = requests.post(url= self.sonarrURL+"series?apikey="+apiKey,json = postData)
|
||||
|
||||
if r.status_code == 201:
|
||||
await message.edit(embed = None, content = postData["title"]+" successfully added to Bedre Netflix")
|
||||
self.bot.log("Added a "+postData["title"]+" to Bedre Netflix")
|
||||
elif r.status_code == 400:
|
||||
text = f"{postData['title']} is either already on Bedre Netflix, downloading, or not available"
|
||||
await message.edit(embed = None, content = text)
|
||||
else:
|
||||
await message.edit(embed = None, content = "Something went wrong")
|
||||
self.bot.log(str(r.status_code)+" "+r.reason)
|
||||
|
||||
#Generates a list of all torrents and returns formatted list and whether all torrents are downloaded
|
||||
async def genDownloadList(self, showDM, showMovies, showShows, episodes):
|
||||
self.bot.log("Generating torrent list")
|
||||
titleWidth = 100
|
||||
message = []
|
||||
allDownloaded = True
|
||||
|
||||
if showDM:
|
||||
message.append("")
|
||||
DMSectionTitle = "*Torrent Downloads*"
|
||||
DMSectionTitleLine = "-"*((titleWidth-len(DMSectionTitle))//2)
|
||||
message.append(DMSectionTitleLine+DMSectionTitle+DMSectionTitleLine)
|
||||
response = requests.get(self.qbittorrentURL+"torrents/info")
|
||||
torrentList = response.json()
|
||||
|
||||
if len(torrentList) > 0:
|
||||
for torrent in torrentList:
|
||||
torrentName = torrent["name"]
|
||||
if len(torrentName) > 30:
|
||||
if torrentName[26] == " ":
|
||||
torrentName = torrentName[:26]+"...."
|
||||
else:
|
||||
torrentName = torrentName[:27]+"..."
|
||||
while len(torrentName) < 30:
|
||||
torrentName += " "
|
||||
|
||||
if torrent["size"] == 0:
|
||||
downloadedRatio = 0
|
||||
elif torrent["amount_left"] == 0:
|
||||
downloadedRatio = 1
|
||||
else:
|
||||
downloadedRatio = min(torrent["downloaded"]/torrent["size"],1)
|
||||
progressBar = "|"+("█"*math.floor(downloadedRatio*20))
|
||||
while len(progressBar) < 21:
|
||||
progressBar += " "
|
||||
|
||||
progressBar += "| "+str(math.floor(downloadedRatio*100))+"%"
|
||||
|
||||
while len(progressBar) < 27:
|
||||
progressBar += " "
|
||||
|
||||
etaInSeconds = torrent["eta"]
|
||||
|
||||
if etaInSeconds >= 8640000:
|
||||
eta = "∞"
|
||||
else:
|
||||
eta = ""
|
||||
if etaInSeconds >= 86400:
|
||||
eta += str(math.floor(etaInSeconds/86400))+"d "
|
||||
if etaInSeconds >= 3600:
|
||||
eta += str(math.floor((etaInSeconds%86400)/3600))+"h "
|
||||
if etaInSeconds >= 60:
|
||||
eta += str(math.floor((etaInSeconds%3600)/60))+"m "
|
||||
|
||||
eta += str(etaInSeconds%60)+"s"
|
||||
|
||||
torrentInfo = torrentName+" "+progressBar+" (Eta: "+eta+")"
|
||||
|
||||
if torrent["state"] == "stalledDL":
|
||||
torrentInfo += " (Stalled)"
|
||||
|
||||
if not (downloadedRatio == 1 and torrent["last_activity"] < time.time()-7200):
|
||||
message.append(torrentInfo)
|
||||
|
||||
if downloadedRatio < 1 and torrent["state"] != "stalledDL":
|
||||
allDownloaded = False
|
||||
else:
|
||||
message.append("No torrents currently downloading")
|
||||
|
||||
if showMovies:
|
||||
message.append("")
|
||||
movieSectionTitle = "*Missing movies not downloading*"
|
||||
movieSectionTitleLine = "-"*((titleWidth-len(movieSectionTitle))//2)
|
||||
message.append(movieSectionTitleLine+movieSectionTitle+movieSectionTitleLine)
|
||||
movieList = requests.get(self.radarrURL+"movie?apiKey="+self.bot.credentials["radarr_key"]).json()
|
||||
movieQueue = requests.get(self.radarrURL+"queue?apiKey="+self.bot.credentials["radarr_key"]).json()
|
||||
movieQueueIDs = []
|
||||
|
||||
for queueItem in movieQueue["records"]:
|
||||
movieQueueIDs.append(queueItem["movieId"])
|
||||
|
||||
for movie in movieList:
|
||||
if not movie["hasFile"]:
|
||||
if movie["id"] not in movieQueueIDs:
|
||||
movieName = movie["title"]
|
||||
if len(movieName) > 40:
|
||||
if movieName[36] == " ":
|
||||
movieName = movieName[:36]+"...."
|
||||
else:
|
||||
movieName = movieName[:37]+"..."
|
||||
|
||||
while len(movieName) < 41:
|
||||
movieName += " "
|
||||
|
||||
if movie["monitored"]:
|
||||
movieInfo = movieName+"Could not find a torrent"
|
||||
else:
|
||||
movieInfo = movieName+"No torrent exists. Likely because the movie is not yet released on DVD"
|
||||
|
||||
message.append(movieInfo)
|
||||
|
||||
if showShows:
|
||||
message.append("")
|
||||
showSectionTitle = "*Missing shows not downloading*"
|
||||
showSectionTitleLine = "-"*((titleWidth-len(showSectionTitle))//2)
|
||||
message.append(showSectionTitleLine+showSectionTitle+showSectionTitleLine)
|
||||
|
||||
showList = requests.get(self.sonarrURL+"series?apiKey="+self.bot.credentials["sonarr_key"]).json()
|
||||
|
||||
for show in showList:
|
||||
if show["seasons"][0]["seasonNumber"] == 0:
|
||||
seasons = show["seasons"][1:]
|
||||
else:
|
||||
seasons = show["seasons"]
|
||||
if any(i["statistics"]["episodeCount"] != i["statistics"]["totalEpisodeCount"] for i in seasons):
|
||||
if all(i["statistics"]["episodeCount"] == 0 for i in seasons):
|
||||
message.append(show["title"] + " (all episodes)")
|
||||
else:
|
||||
if episodes:
|
||||
missingEpisodes = sum(i["statistics"]["totalEpisodeCount"] - i["statistics"]["episodeCount"] for i in seasons)
|
||||
message.append(show["title"] + f" ({missingEpisodes} episodes)")
|
||||
|
||||
message.append("-"*titleWidth)
|
||||
|
||||
messageText = "```"+"\n".join(message[1:])+"```"
|
||||
if messageText == "``````":
|
||||
messageText = "There are no torrents downloading right. If the torrent you're looking for was added more than 24 hours ago, it might already be on Bedre Netflix."
|
||||
return messageText, allDownloaded
|
||||
|
||||
async def downloading(self, ctx, content):
|
||||
async def SendLongMessage(ctx,messageText):
|
||||
if len(messageText) <= 1994:
|
||||
await ctx.send("```"+messageText+"```")
|
||||
else:
|
||||
cutOffIndex = messageText[:1994].rfind("\n")
|
||||
await ctx.send("```"+messageText[:cutOffIndex]+"```")
|
||||
await SendLongMessage(ctx,messageText[cutOffIndex+1:])
|
||||
|
||||
await self.bot.defer(ctx)
|
||||
|
||||
# showDM, showMovies, showShows, episodes
|
||||
params = [False, False, False, False]
|
||||
showDMArgs = ["d", "dm", "downloading", "downloadmanager"]
|
||||
showMoviesArgs = ["m", "movies"]
|
||||
showShowsArgs = ["s", "shows", "series"]
|
||||
episodesArgs = ["e", "episodes"]
|
||||
argList = [showDMArgs, showMoviesArgs, showShowsArgs, episodesArgs]
|
||||
inputArgs = []
|
||||
validArguments = True
|
||||
|
||||
while content != "" and validArguments:
|
||||
if content[0] == " ":
|
||||
content = content[1:]
|
||||
elif content[0] == "-":
|
||||
if content[1] == "-":
|
||||
argStart = 2
|
||||
if " " in content:
|
||||
argStop = content.find(" ")
|
||||
else:
|
||||
argStop = None
|
||||
else:
|
||||
argStart = 1
|
||||
argStop = 2
|
||||
|
||||
inputArgs.append(content[argStart:argStop])
|
||||
if argStop is None:
|
||||
content = ""
|
||||
else:
|
||||
content = content[argStop:]
|
||||
else:
|
||||
validArguments = False
|
||||
|
||||
if validArguments:
|
||||
for x, argAliases in enumerate(argList):
|
||||
argInInput = [i in inputArgs for i in argAliases]
|
||||
if any(argInInput):
|
||||
inputArgs.remove(argAliases[argInInput.index(True)])
|
||||
params[x] = True
|
||||
|
||||
if len(inputArgs) != 0 or (params[2] == False and params[3] == True):
|
||||
validArguments = False
|
||||
|
||||
showAnything = any(i for i in params)
|
||||
if validArguments and showAnything:
|
||||
messageText, allDownloaded = await self.genDownloadList(*params)
|
||||
if messageText.startswith("```"):
|
||||
|
||||
if len(messageText) <= 2000:
|
||||
if not allDownloaded:
|
||||
updatesLeft = 60
|
||||
messageText = messageText[:-3]+"\nThis message will update every 10 seconds for "+str(math.ceil(updatesLeft/6))+" more minutes\n```"
|
||||
old_message = await ctx.send(messageText)
|
||||
|
||||
while ((not allDownloaded) and updatesLeft > 0):
|
||||
await asyncio.sleep(10)
|
||||
updatesLeft -= 1
|
||||
messageText, allDownloaded = await self.genDownloadList(*params)
|
||||
messageText = messageText[:-3]+"\nThis message will update every 10 seconds for "+str(math.ceil(updatesLeft/6))+" more minutes\n```"
|
||||
await old_message.edit(content = messageText)
|
||||
|
||||
messageText, allDownloaded = await self.genDownloadList(*params)
|
||||
|
||||
if messageText.startswith("```"):
|
||||
if allDownloaded:
|
||||
self.bot.log("All torrents are downloaded")
|
||||
else:
|
||||
messageText = messageText[:-3]+"\nThis message will not update anymore\n```"
|
||||
self.bot.log("The message updated 20 times")
|
||||
|
||||
await old_message.edit(content = messageText)
|
||||
|
||||
else:
|
||||
await ctx.send(messageText)
|
||||
else:
|
||||
messageText = messageText[3:-3]
|
||||
await SendLongMessage(ctx,messageText)
|
||||
else:
|
||||
await ctx.send(messageText)
|
||||
else:
|
||||
await ctx.send("Invalid or repeated parameters. Use '/help downloading' to see valid parameters.")
|
||||
|
@ -72,15 +72,15 @@ class Generators():
|
||||
# Ends name if the name ends
|
||||
if new_letter == "\n":
|
||||
done = True
|
||||
genName = "".join(chain)
|
||||
self.bot.log("Generated "+genName[:-1])
|
||||
gen_name = "".join(chain)
|
||||
self.bot.log("Generated "+gen_name[:-1])
|
||||
|
||||
# Returns the name
|
||||
await ctx.send(genName)
|
||||
await ctx.send(gen_name)
|
||||
|
||||
# Generates a random tavern name
|
||||
async def tavernGen(self, ctx):
|
||||
# Lists first parts, second parts and third parts of tavern names
|
||||
# _lists first parts, second parts and third parts of tavern names
|
||||
fp = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic","The Trusty","The Busty"]
|
||||
sp = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","Arsonist"]
|
||||
tp = [" Tavern"," Inn","","","","","","","","",""]
|
||||
|
@ -38,10 +38,10 @@ class NerdShit():
|
||||
heights += [height]
|
||||
width = max(width,int(pod.img['@width']))
|
||||
if titleChucks[x][count] == "":
|
||||
placeForText = 0
|
||||
placeFor_text = 0
|
||||
else:
|
||||
placeForText = 30
|
||||
height += int(pod.img["@height"]) + 10 + placeForText
|
||||
placeFor_text = 30
|
||||
height += int(pod.img["@height"]) + 10 + placeFor_text
|
||||
|
||||
width += 10
|
||||
height += 5
|
||||
@ -55,18 +55,18 @@ class NerdShit():
|
||||
old_image = Image.open("gwendolyn/resources/wolfTemp.png")
|
||||
oldSize = old_image.size
|
||||
if titleChucks[x][count] == "":
|
||||
placeForText = 0
|
||||
placeFor_text = 0
|
||||
else:
|
||||
placeForText = 30
|
||||
newSize = (width,int(oldSize[1]+10+placeForText))
|
||||
newImage = Image.new("RGB",newSize,color=(255,255,255))
|
||||
newImage.paste(old_image, (int((int(oldSize[0]+10)-oldSize[0])/2),int(((newSize[1]-placeForText)-oldSize[1])/2)+placeForText))
|
||||
placeFor_text = 30
|
||||
newSize = (width,int(oldSize[1]+10+placeFor_text))
|
||||
new_image = Image.new("RGB",newSize,color=(255,255,255))
|
||||
new_image.paste(old_image, (int((int(oldSize[0]+10)-oldSize[0])/2),int(((newSize[1]-placeFor_text)-oldSize[1])/2)+placeFor_text))
|
||||
if titleChucks[x][count] != "":
|
||||
d = ImageDraw.Draw(newImage,"RGB")
|
||||
d = ImageDraw.Draw(new_image,"RGB")
|
||||
d.text((5,7),titleChucks[x][count],font=fnt,fill=(150,150,150))
|
||||
|
||||
wolfImage.paste(newImage,(0,heights[count]))
|
||||
newImage.close()
|
||||
wolfImage.paste(new_image,(0,heights[count]))
|
||||
new_image.close()
|
||||
old_image.close()
|
||||
count += 1
|
||||
|
||||
|
@ -7,7 +7,7 @@ import lxml # Used in imageFunc
|
||||
import fandom # Used in findWikiPage
|
||||
import d20 # Used in rollDice
|
||||
import ast
|
||||
from .bedre_netflix import BedreNetflix
|
||||
from .plex import Plex
|
||||
from .nerd_shit import NerdShit
|
||||
from .generators import Generators
|
||||
|
||||
@ -19,16 +19,16 @@ fandom.set_wiki("senkulpa")
|
||||
class MyStringifier(d20.MarkdownStringifier):
|
||||
def _str_expression(self, node):
|
||||
if node.comment == None:
|
||||
resultText = "Result"
|
||||
result_text = "Result"
|
||||
else:
|
||||
resultText = node.comment.capitalize()
|
||||
result_text = node.comment.capitalize()
|
||||
|
||||
return f"**{resultText}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}"
|
||||
return f"**{result_text}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}"
|
||||
|
||||
class Other():
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.bedre_netflix = BedreNetflix(self.bot)
|
||||
self.plex = Plex(self.bot)
|
||||
self.nerd_shit = NerdShit(self.bot)
|
||||
self.generators = Generators(self.bot)
|
||||
|
||||
@ -41,11 +41,11 @@ class Other():
|
||||
|
||||
self.bot.log("Picking a movie")
|
||||
with open("gwendolyn/resources/movies.txt", "r") as f:
|
||||
movieList = f.read().split("\n")
|
||||
movieName = random.choice(movieList)
|
||||
movie_list = f.read().split("\n")
|
||||
movie_name = random.choice(movie_list)
|
||||
|
||||
self.bot.log(f"Searching for {movieName}")
|
||||
searchResult = imdbClient.search_movie(movieName)
|
||||
self.bot.log(f"Searching for {movie_name}")
|
||||
searchResult = imdbClient.search_movie(movie_name)
|
||||
|
||||
self.bot.log("Getting the data")
|
||||
movie = searchResult[0]
|
||||
@ -74,17 +74,17 @@ class Other():
|
||||
author = ctx.author.display_name
|
||||
now = datetime.datetime.now()
|
||||
if time_in_range(now.replace(hour=5, minute=0, second=0, microsecond=0),now.replace(hour=10, minute=0, second=0, microsecond=0), now):
|
||||
sendMessage = "Good morning, "+str(author)
|
||||
send_message = "Good morning, "+str(author)
|
||||
elif time_in_range(now.replace(hour=13, minute=0, second=0, microsecond=0),now.replace(hour=18, minute=0, second=0, microsecond=0), now):
|
||||
sendMessage = "Good afternoon, "+str(author)
|
||||
send_message = "Good afternoon, "+str(author)
|
||||
elif time_in_range(now.replace(hour=18, minute=0, second=0, microsecond=0),now.replace(hour=22, minute=0, second=0, microsecond=0), now):
|
||||
sendMessage = "Good evening, "+str(author)
|
||||
send_message = "Good evening, "+str(author)
|
||||
elif time_in_range(now.replace(hour=22, minute=0, second=0, microsecond=0),now.replace(hour=23, minute=59, second=59, microsecond=0), now):
|
||||
sendMessage = "Good night, "+str(author)
|
||||
send_message = "Good night, "+str(author)
|
||||
else:
|
||||
sendMessage = "Hello, "+str(author)
|
||||
send_message = "Hello, "+str(author)
|
||||
|
||||
await ctx.send(sendMessage)
|
||||
await ctx.send(send_message)
|
||||
|
||||
# Finds a random picture online
|
||||
async def imageFunc(self, ctx):
|
||||
|
536
gwendolyn/funcs/other/plex.py
Normal file
536
gwendolyn/funcs/other/plex.py
Normal file
@ -0,0 +1,536 @@
|
||||
"""Plex integration with the bot."""
|
||||
from math import floor, ceil
|
||||
import time
|
||||
import json
|
||||
import asyncio
|
||||
import requests
|
||||
import imdb
|
||||
import discord
|
||||
|
||||
class Plex():
|
||||
"""Container for Plex functions and commands."""
|
||||
def __init__(self,bot):
|
||||
self.bot = bot
|
||||
self.credentials = self.bot.credentials
|
||||
self.long_strings = self.bot.long_strings
|
||||
server_ip = ["localhost", "192.168.0.40"][self.bot.options["testing"]]
|
||||
|
||||
self.radarr_url = "http://"+server_ip+":7878/api/v3/"
|
||||
self.sonarr_url = "http://"+server_ip+":8989/api/"
|
||||
self.qbittorrent_url = "http://"+server_ip+":8080/api/v2/"
|
||||
self.movie_path = "/media/plex/Server/movies/"
|
||||
self.show_path = "/media/plex/Server/Shows/"
|
||||
|
||||
|
||||
async def request_movie(self, ctx, movie_name):
|
||||
"""Request a movie for the Plex Server"""
|
||||
await self.bot.defer(ctx)
|
||||
|
||||
self.bot.log("Searching for "+movie_name)
|
||||
movie_list = imdb.IMDb().search_movie(movie_name)
|
||||
movies = []
|
||||
for movie in movie_list:
|
||||
if movie["kind"] == "movie":
|
||||
movies.append(movie)
|
||||
if len(movies) > 5:
|
||||
movies = movies[:5]
|
||||
|
||||
if len(movies) == 1:
|
||||
message_title = "**Is it this movie?**"
|
||||
else:
|
||||
message_title = "**Is it any of these movies?**"
|
||||
|
||||
message_text = ""
|
||||
imdb_ids = []
|
||||
|
||||
for i, movie in enumerate(movies):
|
||||
try:
|
||||
message_text += "\n"+str(i+1)+") "+movie["title"]
|
||||
try:
|
||||
message_text += " ("+str(movie["year"])+")"
|
||||
except KeyError:
|
||||
self.bot.log(f"{movie['title']} has no year.")
|
||||
except KeyError:
|
||||
message_text += "Error"
|
||||
imdb_ids.append(movie.movieID)
|
||||
|
||||
self.bot.log(
|
||||
f"Returning a list of {len(movies)} possible movies: {imdb_ids}"
|
||||
)
|
||||
|
||||
embed = discord.Embed(
|
||||
title=message_title,
|
||||
description=message_text,
|
||||
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)
|
||||
|
||||
if len(movies) == 1:
|
||||
await message.add_reaction("✔️")
|
||||
else:
|
||||
for i in range(len(movies)):
|
||||
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 != "" 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:
|
||||
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")
|
||||
else:
|
||||
self.bot.log("Trying to add movie "+str(imdb_id))
|
||||
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)
|
||||
lookup_data = response.json()
|
||||
post_data = {"qualityProfileId": 1,
|
||||
"rootFolder_path" : self.movie_path,
|
||||
"monitored" : True,
|
||||
"addOptions": {"searchForMovie": True}}
|
||||
for key in ["tmdbId","title","titleSlug","images","year"]:
|
||||
post_data.update({key : lookup_data[key]})
|
||||
|
||||
response = requests.post(
|
||||
url= self.radarr_url+"movie?apikey="+api_key,
|
||||
json = post_data
|
||||
)
|
||||
|
||||
if response.status_code == 201:
|
||||
success_message = "{} 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(
|
||||
post_data['title']
|
||||
)
|
||||
if edit_message:
|
||||
await message.edit(embed = None, content = fail_text)
|
||||
else:
|
||||
await message.channel.send(fail_text)
|
||||
else:
|
||||
if edit_message:
|
||||
await message.edit(
|
||||
embed = None,
|
||||
content = "Something went wrong"
|
||||
)
|
||||
else:
|
||||
await message.channel.send("Something went wrong")
|
||||
self.bot.log(str(response.status_code)+" "+response.reason)
|
||||
|
||||
async def request_show(self, ctx, show_name):
|
||||
"""Request a show for the Plex server."""
|
||||
await self.bot.defer(ctx)
|
||||
|
||||
self.bot.log("Searching for "+show_name)
|
||||
movies = imdb.IMDb().search_movie(show_name) # Replace with tvdb
|
||||
shows = []
|
||||
for movie in movies:
|
||||
if movie["kind"] in ["tv series","tv miniseries"]:
|
||||
shows.append(movie)
|
||||
if len(shows) > 5:
|
||||
shows = shows[:5]
|
||||
|
||||
if len(shows) == 1:
|
||||
message_title = "**Is it this show?**"
|
||||
else:
|
||||
message_title = "**Is it any of these shows?**"
|
||||
|
||||
message_text = ""
|
||||
imdb_names = []
|
||||
|
||||
for i, show in enumerate(shows):
|
||||
try:
|
||||
message_text += f"\n{i+1}) {show['title']} ({show['year']})"
|
||||
except KeyError:
|
||||
try:
|
||||
message_text += "\n"+str(i+1)+") "+show["title"]
|
||||
except KeyError:
|
||||
message_text += "Error"
|
||||
imdb_names.append(show["title"])
|
||||
|
||||
self.bot.log(
|
||||
f"Returning a list of {len(shows)} possible shows: {imdb_names}"
|
||||
)
|
||||
|
||||
embed = discord.Embed(
|
||||
title=message_title,
|
||||
description=message_text,
|
||||
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)
|
||||
|
||||
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"
|
||||
)
|
||||
else:
|
||||
self.bot.log("Trying to add show "+str(imdb_name))
|
||||
api_key = self.credentials["sonarr_key"]
|
||||
request_url = self.sonarr_url+"series/lookup?term="
|
||||
request_url += imdb_name.replace(" ","%20")
|
||||
request_url += "&apiKey="+api_key
|
||||
response = requests.get(request_url)
|
||||
lookup_data = response.json()[0]
|
||||
post_data = {
|
||||
"ProfileId" : 1,
|
||||
"rootFolder_path" : self.show_path,
|
||||
"monitored" : True,
|
||||
"addOptions" : {"searchForMissingEpisodes" : True}
|
||||
}
|
||||
for key in ["tvdbId","title","titleSlug","images","seasons"]:
|
||||
post_data.update({key : lookup_data[key]})
|
||||
|
||||
|
||||
response = requests.post(
|
||||
url= self.sonarr_url+"series?apikey="+api_key,
|
||||
json = post_data
|
||||
)
|
||||
|
||||
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")
|
||||
elif response.status_code == 400:
|
||||
text = self.long_strings["Already on Plex"].format(
|
||||
post_data['title']
|
||||
)
|
||||
await message.edit(embed = None, content = text)
|
||||
else:
|
||||
await message.edit(
|
||||
embed = None,
|
||||
content = "Something went wrong"
|
||||
)
|
||||
self.bot.log(str(response.status_code)+" "+response.reason)
|
||||
|
||||
async def __generate_download_list(self, show_dm, show_movies, show_shows,
|
||||
episodes):
|
||||
"""Generate a list of all torrents.
|
||||
|
||||
*Returns*
|
||||
message_text: str
|
||||
A formatted list of all torrents
|
||||
|
||||
all_downloaded: bool
|
||||
Whether all torrents are downloaded
|
||||
"""
|
||||
self.bot.log("Generating torrent list")
|
||||
title_width = 100
|
||||
message = []
|
||||
all_downloaded = True
|
||||
|
||||
if show_dm:
|
||||
message.append("")
|
||||
dm_section_title = "*Torrent Downloads*"
|
||||
dm_section_title_line = "-"*((title_width-len(dm_section_title))//2)
|
||||
message.append(
|
||||
dm_section_title_line+dm_section_title+dm_section_title_line
|
||||
)
|
||||
response = requests.get(self.qbittorrent_url+"torrents/info")
|
||||
torrent_list = response.json()
|
||||
|
||||
if len(torrent_list) > 0:
|
||||
for torrent in torrent_list:
|
||||
torrent_name = torrent["name"]
|
||||
if len(torrent_name) > 30:
|
||||
if torrent_name[26] == " ":
|
||||
torrent_name = torrent_name[:26]+"...."
|
||||
else:
|
||||
torrent_name = torrent_name[:27]+"..."
|
||||
while len(torrent_name) < 30:
|
||||
torrent_name += " "
|
||||
|
||||
if torrent["size"] == 0:
|
||||
download_ratio = 0
|
||||
elif torrent["amount_left"] == 0:
|
||||
download_ratio = 1
|
||||
else:
|
||||
download_ratio = min(
|
||||
torrent["downloaded"]/torrent["size"],
|
||||
1
|
||||
)
|
||||
progress_bar = "|"+("█"*floor(download_ratio*20))
|
||||
while len(progress_bar) < 21:
|
||||
progress_bar += " "
|
||||
|
||||
progress_bar += "| "+str(floor(download_ratio*100))+"%"
|
||||
|
||||
while len(progress_bar) < 27:
|
||||
progress_bar += " "
|
||||
|
||||
eta_in_seconds = torrent["eta"]
|
||||
|
||||
if eta_in_seconds >= 8640000:
|
||||
eta = "∞"
|
||||
else:
|
||||
eta = ""
|
||||
if eta_in_seconds >= 86400:
|
||||
eta += str(floor(eta_in_seconds/86400))+"d "
|
||||
if eta_in_seconds >= 3600:
|
||||
eta += str(floor((eta_in_seconds%86400)/3600))+"h "
|
||||
if eta_in_seconds >= 60:
|
||||
eta += str(floor((eta_in_seconds%3600)/60))+"m "
|
||||
|
||||
eta += str(eta_in_seconds%60)+"s"
|
||||
|
||||
torrent_info = f"{torrent_name} {progress_bar} "
|
||||
torrent_info += f"(Eta: {eta})"
|
||||
|
||||
if torrent["state"] == "stalledDL":
|
||||
torrent_info += " (Stalled)"
|
||||
|
||||
if not (download_ratio == 1 and
|
||||
torrent["last_activity"] < time.time()-7200):
|
||||
message.append(torrent_info)
|
||||
|
||||
if download_ratio < 1 and torrent["state"] != "stalledDL":
|
||||
all_downloaded = False
|
||||
else:
|
||||
message.append("No torrents currently downloading")
|
||||
|
||||
if show_movies:
|
||||
message.append("")
|
||||
movies_section_title = "*Missing movies not downloading*"
|
||||
movies_section_line = (
|
||||
"-"*((title_width-len(movies_section_title))//2)
|
||||
)
|
||||
message.append(
|
||||
movies_section_line+movies_section_title+movies_section_line
|
||||
)
|
||||
movie_list = requests.get(
|
||||
self.radarr_url+"movie?api_key="+self.credentials["radarr_key"]
|
||||
).json()
|
||||
movie_queue = requests.get(
|
||||
self.radarr_url+"queue?api_key="+self.credentials["radarr_key"]
|
||||
).json()
|
||||
movie_queue_ids = []
|
||||
|
||||
for queue_item in movie_queue["records"]:
|
||||
movie_queue_ids.append(queue_item["movieId"])
|
||||
|
||||
for movie in movie_list:
|
||||
if (not movie["hasFile"] and
|
||||
movie["id"] not in movie_queue_ids):
|
||||
movie_name = movie["title"]
|
||||
if len(movie_name) > 40:
|
||||
if movie_name[36] == " ":
|
||||
movie_name = movie_name[:36]+"...."
|
||||
else:
|
||||
movie_name = movie_name[:37]+"..."
|
||||
|
||||
while len(movie_name) < 41:
|
||||
movie_name += " "
|
||||
|
||||
if movie["monitored"]:
|
||||
movie_info = movie_name+"Could not find a torrent"
|
||||
else:
|
||||
movie_info = self.long_strings["No torrent"].format(
|
||||
movie_name
|
||||
)
|
||||
|
||||
message.append(movie_info)
|
||||
|
||||
if show_shows:
|
||||
message.append("")
|
||||
show_section_title = "*Missing shows not downloading*"
|
||||
show_section_line = "-"*((title_width-len(show_section_title))//2)
|
||||
message.append(
|
||||
show_section_line+show_section_title+show_section_line
|
||||
)
|
||||
|
||||
show_list = requests.get(
|
||||
self.sonarr_url+"series?api_key="+self.credentials["sonarr_key"]
|
||||
).json()
|
||||
|
||||
for show in show_list:
|
||||
if show["seasons"][0]["seasonNumber"] == 0:
|
||||
seasons = show["seasons"][1:]
|
||||
else:
|
||||
seasons = show["seasons"]
|
||||
if any(
|
||||
(
|
||||
i["statistics"]["episodeCount"] !=
|
||||
i["statistics"]["totalEpisodeCount"]
|
||||
) for i in seasons):
|
||||
if all(
|
||||
i["statistics"]["episodeCount"] == 0 for i in seasons
|
||||
):
|
||||
message.append(show["title"] + " (all episodes)")
|
||||
else:
|
||||
if episodes:
|
||||
missing_episodes = sum(
|
||||
(i["statistics"]["totalEpisodeCount"] -
|
||||
i["statistics"]["episodeCount"])
|
||||
for i in seasons)
|
||||
message.append(
|
||||
f"{show['title']} ({missing_episodes} episodes)"
|
||||
)
|
||||
|
||||
message.append("-"*title_width)
|
||||
|
||||
message_text = "```"+"\n".join(message[1:])+"```"
|
||||
if message_text == "``````":
|
||||
message_text = self.long_strings["No torrents downloading"]
|
||||
return message_text, all_downloaded
|
||||
|
||||
async def downloading(self, ctx, content):
|
||||
"""Send message with list of all downloading torrents."""
|
||||
async def send_long_message(ctx,message_text):
|
||||
if len(message_text) <= 1994:
|
||||
await ctx.send("```"+message_text+"```")
|
||||
else:
|
||||
cut_off_index = message_text[:1994].rfind("\n")
|
||||
await ctx.send("```"+message_text[:cut_off_index]+"```")
|
||||
await send_long_message(ctx,message_text[cut_off_index+1:])
|
||||
|
||||
await self.bot.defer(ctx)
|
||||
|
||||
# showDM, showMovies, showShows, episodes
|
||||
parameters = [False, False, False, False]
|
||||
show_dm_args = ["d", "dm", "downloading", "downloadmanager"]
|
||||
show_movies_args = ["m", "movies"]
|
||||
show_shows_args = ["s", "shows", "series"]
|
||||
show_episode_args = ["e", "episodes"]
|
||||
arg_list = [
|
||||
show_dm_args, show_movies_args, show_shows_args, show_episode_args
|
||||
]
|
||||
input_args = []
|
||||
valid_arguments = True
|
||||
|
||||
while content != "" and valid_arguments:
|
||||
if content[0] == " ":
|
||||
content = content[1:]
|
||||
elif content[0] == "-":
|
||||
if content[1] == "-":
|
||||
arg_start = 2
|
||||
if " " in content:
|
||||
arg_stop = content.find(" ")
|
||||
else:
|
||||
arg_stop = None
|
||||
else:
|
||||
arg_start = 1
|
||||
arg_stop = 2
|
||||
|
||||
input_args.append(content[arg_start:arg_stop])
|
||||
if arg_stop is None:
|
||||
content = ""
|
||||
else:
|
||||
content = content[arg_stop:]
|
||||
else:
|
||||
valid_arguments = False
|
||||
|
||||
if valid_arguments:
|
||||
for arg_index, arg_aliases in enumerate(arg_list):
|
||||
arg_in_input = [i in input_args for i in arg_aliases]
|
||||
if any(arg_in_input):
|
||||
input_args.remove(arg_aliases[arg_in_input.index(True)])
|
||||
parameters[arg_index] = True
|
||||
|
||||
if len(input_args) != 0 or (not parameters[2] and parameters[3]):
|
||||
valid_arguments = False
|
||||
|
||||
show_anything = any(i for i in parameters)
|
||||
if not (valid_arguments and show_anything):
|
||||
await ctx.send(self.long_strings["Invalid parameters"])
|
||||
else:
|
||||
message_text, all_downloaded = await self.__generate_download_list(
|
||||
*parameters
|
||||
)
|
||||
if not message_text.startswith("```"):
|
||||
await ctx.send(message_text)
|
||||
|
||||
elif len(message_text) > 2000:
|
||||
message_text = message_text[3:-3]
|
||||
await send_long_message(ctx,message_text)
|
||||
|
||||
elif all_downloaded:
|
||||
await ctx.send(message_text)
|
||||
|
||||
else:
|
||||
updates_left = 60
|
||||
message_text = self.long_strings["Update"].format(
|
||||
message_text[:-3], ceil(updates_left/6)
|
||||
)
|
||||
old_message = await ctx.send(message_text)
|
||||
|
||||
while ((not all_downloaded) and updates_left > 0):
|
||||
await asyncio.sleep(10)
|
||||
updates_left -= 1
|
||||
message_text, all_downloaded = await (
|
||||
self.__generate_download_list(*parameters)
|
||||
)
|
||||
message_text = self.long_strings["Update"].format(
|
||||
message_text[:-3],
|
||||
ceil(updates_left/6)
|
||||
)
|
||||
await old_message.edit(content = message_text)
|
||||
|
||||
message_text, all_downloaded = await (
|
||||
self.__generate_download_list(*parameters)
|
||||
)
|
||||
|
||||
if message_text.startswith("```"):
|
||||
if all_downloaded:
|
||||
self.bot.log("All torrents are downloaded")
|
||||
else:
|
||||
message_text = self.long_strings["No updates"].format(
|
||||
message_text[:-3]
|
||||
)
|
||||
self.bot.log("The message updated 20 times")
|
||||
|
||||
await old_message.edit(content = message_text)
|
Reference in New Issue
Block a user