reworking a bunch of stuff

This commit is contained in:
Nikolaj
2024-10-28 13:05:06 +01:00
parent f21cbba726
commit bc59bf9b05
142 changed files with 1385 additions and 845 deletions

View File

@ -0,0 +1,5 @@
"""Misc. functions for Gwendolyn."""
__all__ = ["Other"]
from .other import Other

View File

@ -0,0 +1,94 @@
import random
class Generators():
def __init__(self, bot):
self.bot = bot
# Returns a list of all letter pairs in the text
def make_pairs(self, corpus):
for i in range(len(corpus)-1):
yield (corpus[i], corpus[i+1])
# Returns a list of all letter triplets in the text
def make_triplets(self, corpus):
for i in range(len(corpus)-2):
yield (corpus[i], corpus[i+1], corpus[i+2])
# Generates a random name
async def name_gen(self, ctx):
# Makes a list of all names from "names.txt"
with open("gwendolyn/resources/names.txt", "r", encoding='utf8') as file_pointer:
names = file_pointer.read()
corpus = list(names)
# Makes a list of pairs
pairs = self.make_pairs(corpus)
triplets = self.make_triplets(corpus)
letter_dict = {}
# Makes a dictionary of all letters that come after all other letters
for letter_1, letter_2 in pairs:
if letter_1 in letter_dict:
letter_dict[letter_1].append(letter_2)
else:
letter_dict[letter_1] = [letter_2]
for letter_1, letter_2, letter_3 in triplets:
if letter_1+letter_2 in letter_dict:
letter_dict[letter_1+letter_2].append(letter_3)
else:
letter_dict[letter_1+letter_2] = [letter_3]
# Choses a random first letter
first_letter = random.choice(corpus)
# Makes sure the first letter is not something a name can't start with.
while first_letter.islower() or first_letter == " " or first_letter == "-" or first_letter == "\n":
first_letter = random.choice(corpus)
# Starts the name
chain = [first_letter]
# Picks second letter
second_letter = random.choice(letter_dict[chain[-1]])
while second_letter == "\n":
second_letter = random.choice(letter_dict[chain[-1]])
chain.append(second_letter)
done = False
# Creates the name one letter at a time
while not done:
if random.randint(1,10) > 1:
try:
new_letter = random.choice(letter_dict[chain[-2]+chain[-1]])
except KeyError():
new_letter = random.choice(letter_dict[chain[-1]])
else:
new_letter = random.choice(letter_dict[chain[-1]])
chain.append(new_letter)
# Ends name if the name ends
if new_letter == "\n":
done = True
gen_name = "".join(chain)
self.bot.log("Generated "+gen_name[:-1])
# Returns the name
await ctx.send(gen_name)
# Generates a random tavern name
async def tavern_gen(self, ctx):
# _lists first parts, second parts and third parts of tavern names
first_part = ["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"]
second_part = ["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"]
third_part = [" Tavern"," Inn","","","","","","","","",""]
# Picks one of each
gen_tav = random.choice(first_part)+" "+random.choice(second_part)+random.choice(third_part)
self.bot.log("Generated "+gen_tav)
# Return the name
await ctx.send(gen_tav)

View File

@ -0,0 +1,85 @@
import os
import requests
import discord
import wolframalpha
from PIL import Image, ImageDraw, ImageFont
class NerdShit():
def __init__(self, bot):
"""Runs misc commands."""
self.bot = bot
async def wolf_search(self,ctx,content):
await self.bot.defer(ctx)
font = ImageFont.truetype('gwendolyn/resources/fonts/times-new-roman.ttf', 20)
self.bot.log("Requesting data")
bot = wolframalpha.Client(self.bot.credentials["wolfram_alpha_key"])
res = bot.query(content)
self.bot.log("Processing data")
titles = []
pods = []
if int(res.numpods) > 0:
for pod in res.pods:
titles += [pod.title]
for i, sub in enumerate(pod.subpods):
pods += [sub]
if i > 0:
titles += [""]
pod_chunks = [pods[x:x+2] for x in range(0, len(pods), 2)]
title_chunks = [titles[x:x+2] for x in range(0, len(titles), 2)]
await ctx.send(f"Response for \"{content}\"")
for i, chunk in enumerate(pod_chunks):
width = 0
for title in title_chunks[i]:
width = max(width,font.getsize(title)[0])
height = 5
heights = []
for count, pod in enumerate(chunk):
heights += [height]
width = max(width,int(pod.img['@width']))
if title_chunks[i][count] == "":
place_for_text = 0
else:
place_for_text = 30
height += int(pod.img["@height"]) + 10 + place_for_text
width += 10
height += 5
wolf_image = Image.new("RGB",(width,height),color=(255,255,255))
for count, pod in enumerate(chunk):
response = requests.get(pod.img["@src"])
file = open("gwendolyn/resources/wolfTemp.png", "wb")
file.write(response.content)
file.close()
old_image = Image.open("gwendolyn/resources/wolfTemp.png")
old_size = old_image.size
if title_chunks[i][count] == "":
place_for_text = 0
else:
place_for_text = 30
new_size = (width,int(old_size[1]+10+place_for_text))
new_image = Image.new("RGB",new_size,color=(255,255,255))
new_image.paste(old_image, (int((int(old_size[0]+10)-old_size[0])/2),int(((new_size[1]-place_for_text)-old_size[1])/2)+place_for_text))
if title_chunks[i][count] != "":
drawer = ImageDraw.Draw(new_image,"RGB")
drawer.text((5,7),title_chunks[i][count],font=font,fill=(150,150,150))
wolf_image.paste(new_image,(0,heights[count]))
new_image.close()
old_image.close()
count += 1
wolf_image.save("gwendolyn/resources/wolf.png")
wolf_image.close()
await ctx.channel.send(file = discord.File("gwendolyn/resources/wolf.png"))
os.remove("gwendolyn/resources/wolf.png")
os.remove("gwendolyn/resources/wolfTemp.png")
else:
self.bot.log("No returned data")
await ctx.send("Could not find anything relating to your search")

View File

@ -0,0 +1,192 @@
import random # Used in movie_func
import datetime # Used in hello_func
import urllib # Used in image_func
import ast
import imdb # Used in movie_func
import discord # Used in movie_func
import lxml # Used in image_func
import fandom # Used in find_wiki_page
import d20 # Used in roll_dice
from .plex import Plex
from .nerd_shit import NerdShit
from .generators import Generators
fandom.set_lang("da")
fandom.set_wiki("senkulpa")
class MyStringifier(d20.MarkdownStringifier):
def _str_expression(self, node):
if node.comment is None:
result_text = "Result"
else:
result_text = node.comment.capitalize()
return f"**{result_text}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}"
class Other():
def __init__(self, bot):
self.bot = bot
self.plex = Plex(self.bot)
self.nerd_shit = NerdShit(self.bot)
self.generators = Generators(self.bot)
# Picks a random movie and returns information about it
async def movie_func(self, ctx):
await self.bot.defer(ctx)
self.bot.log("Creating IMDb object")
imdb_client = imdb.IMDb()
self.bot.log("Picking a movie")
with open("gwendolyn/resources/movies.txt", "r") as file_pointer:
movie_list = file_pointer.read().split("\n")
movie_name = random.choice(movie_list)
self.bot.log(f"Searching for {movie_name}")
search_result = imdb_client.search_movie(movie_name)
self.bot.log("Getting the data")
movie = search_result[0]
imdb_client.update(movie)
self.bot.log("Successfully ran /movie")
title = movie["title"]
plot = movie['plot'][0].split("::")[0]
cover = movie['cover url'].replace("150","600").replace("101","404")
cast = ", ".join([i["name"] for i in movie['cast'][:5]])
embed = discord.Embed(title=title, description=plot, color=0x24ec19)
embed.set_thumbnail(url=cover)
embed.add_field(name="Cast", value=cast,inline = True)
await ctx.send(embed = embed)
# Responds with a greeting of a time-appropriate maner
async def hello_func(self, ctx):
def time_in_range(start, end, i):
# Return true if i is in the range [start, end]
if start <= end:
return start <= i <= end
else:
return start <= i or i <= end
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):
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):
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):
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):
send_message = "Good night, "+str(author)
else:
send_message = "Hello, "+str(author)
await ctx.send(send_message)
# Finds a random picture online
async def image_func(self, ctx):
# Picks a type of camera, which decides the naming scheme
cams = ("one","two","three","four")
cam = random.choice(cams)
self.bot.log("Chose cam type "+cam)
if cam == "one":
search = "img_" + ''.join(
[str(random.randint(0,9)) for _ in range(4)]
)
elif cam == "two":
year = str(random.randint(2012,2016))
month = str(random.randint(1,12)).zfill(2)
day = str(random.randint(1,29)).zfill(2)
search = f"IMG_{year}{month}{day}"
elif cam == "three":
search = f"IMAG_{str(random.randint(1,500)).zfill(4)}"
elif cam == "four":
search = "DSC_" + ''.join(
[str(random.randint(0,9)) for _ in range(4)]
)
self.bot.log("Searching for "+search)
# Searches for the image and reads the resulting web page
page = urllib.request.urlopen("https://www.bing.com/images/search?q="+search+"&safesearch=off")
read = page.read()
tree = lxml.etree.HTML(read)
images = tree.xpath('//a[@class = "iusc"]/@m')
if len(images) == 0:
await ctx.send("Found no images")
else:
# Picks an image
number = random.randint(1,len(images))-1
image = ast.literal_eval(str(images[number]))
image_url = image["murl"]
self.bot.log("Picked image number "+str(number))
# Returns the image
self.bot.log("Successfully returned an image")
await ctx.send(image_url)
# Finds a page from the Senkulpa Wikia
async def find_wiki_page(self, ctx, search : str):
await self.bot.defer(ctx)
found_page = False
if search != "":
self.bot.log("Trying to find wiki page for "+search)
search_results = fandom.search(search)
if len(search_results) > 0:
found_page = True
search_result = search_results[0]
else:
self.bot.log("Couldn't find the page")
await ctx.send("Couldn't find page")
else:
found_page = True
self.bot.log("Searching for a random page")
search_result = fandom.random()
if found_page:
self.bot.log(f"Found page \"{search_result[0]}\"")
page = fandom.page(pageid = search_result[1])
content = page.summary
images = page.images
if len(images) > 0:
image = images[0]
else:
image = ""
self.bot.log("Sending the embedded message",str(ctx.channel_id))
content += f"\n[Læs mere]({page.url})"
embed = discord.Embed(title = page.title, description = content, colour=0xDEADBF)
if image != "":
embed.set_thumbnail(url=image)
await ctx.send(embed = embed)
async def roll_dice(self, ctx, roll_string):
user = ctx.author.display_name
while len(roll_string) > 1 and roll_string[0] == " ":
roll_string = roll_string[1:]
roll = d20.roll(roll_string, allow_comments=True, stringifier=MyStringifier())
await ctx.send(f"{user} :game_die:\n{roll}")
async def help_func(self, ctx, command):
if command == "":
with open("gwendolyn/resources/help/help.txt",encoding="utf-8") as file_pointer:
text = file_pointer.read()
embed = discord.Embed(title = "Help", description = text,colour = 0x59f442)
await ctx.send(embed = embed)
else:
self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id))
with open(f"gwendolyn/resources/help/help-{command}.txt",encoding="utf-8") as file_pointer:
text = file_pointer.read()
embed = discord.Embed(title = command.capitalize(), description = text,colour = 0x59f442)
await ctx.send(embed = embed)

View File

@ -0,0 +1,600 @@
"""Plex integration with the bot."""
from math import floor, ceil
import time
import asyncio
import requests
import imdb
import discord
import xmltodict
from interactions.utils.manage_components import (create_button,
create_actionrow)
from interactions.model import ButtonStyle
from gwendolyn_old.utils import encode_id
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
)
buttons = []
if len(movies) == 1:
buttons.append(create_button(
style=ButtonStyle.green,
label="",
custom_id=encode_id(["plex", "movie", str(imdb_ids[0])])
)
)
else:
for i in range(len(movies)):
buttons.append(
create_button(
style=ButtonStyle.blue,
label=str(i+1),
custom_id=encode_id(["plex", "movie", str(imdb_ids[i])])
)
)
buttons.append(create_button(
style=ButtonStyle.red,
label="X",
custom_id=encode_id(["plex", "movie", "x"])
)
)
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_movie(self, message, imdb_id, edit_message = True):
"""Add a movie to Plex server."""
if not edit_message:
await message.delete()
if imdb_id == "X":
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 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,
"rootFolderPath" : self.movie_path,
"monitored" : 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:
self.bot.log("Added "+post_data["title"]+" to Plex")
message_text = "{} successfully added to Plex".format(
post_data["title"]
)
elif response.status_code == 400:
self.bot.log("The movie was already on plex")
message_text = self.long_strings["Already on Plex"].format(
post_data['title']
)
else:
self.bot.log(str(response.status_code)+" "+response.reason)
message_text = "Something went wrong",
if edit_message:
await message.edit(
embed = None,
content = message_text,
components = []
)
else:
await message.channel.send(message_text)
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_ids = []
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_ids.append(show.movieID)
self.bot.log(
f"Returning a list of {len(shows)} possible shows: {imdb_ids}"
)
embed = discord.Embed(
title=message_title,
description=message_text,
colour=0x00FF00
)
buttons = []
if len(shows) == 1:
buttons.append(create_button(
style=ButtonStyle.green,
label="",
custom_id=encode_id(["plex", "show", str(imdb_ids[0])])
)
)
else:
for i in range(len(shows)):
buttons.append(
create_button(
style=ButtonStyle.blue,
label=str(i+1),
custom_id=encode_id(["plex", "show", str(imdb_ids[i])])
)
)
buttons.append(create_button(
style=ButtonStyle.red,
label="X",
custom_id=encode_id(["plex", "show", "x"])
)
)
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 == "X":
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 += 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,
"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]})
# 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:
self.bot.log("Added a "+post_data["title"]+" to Plex")
message_text = post_data["title"]+" successfully added to Plex"
elif response.status_code == 400:
message_text = self.long_strings["Already on Plex"].format(
post_data['title']
)
else:
self.bot.log(str(response.status_code)+" "+response.reason)
message_text = "Something went wrong"
if edit_message:
await message.edit(
embed = None,
content = message_text,
components = []
)
else:
await message.channel.send(message_text)
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
)
login_url = self.qbittorrent_url+"auth/login"
username = self.credentials["qbittorrent_username"]
password = self.credentials["qbittorrent_password"]
login_url += f"?username={username}&password={password}"
cookie = {"SID": requests.get(login_url).cookies.values()[0]}
response = requests.get(
self.qbittorrent_url+"torrents/info",
cookies=cookie
)
torrent_list = response.json()
if len(torrent_list) > 0:
for torrent in torrent_list:
if torrent['category'] not in ["radarr", "tv-sonarr"]:
break
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?apiKey="+self.credentials["radarr_key"]
).json()
print(
self.radarr_url+"movie?apiKey="+self.credentials["radarr_key"]
)
movie_queue = requests.get(
self.radarr_url+"queue?apiKey="+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?apiKey="+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)