160 lines
5.4 KiB
Python
160 lines
5.4 KiB
Python
from requests import get
|
|
from random import choice
|
|
import io
|
|
|
|
from PIL import Image
|
|
from interactions import SlashContext, Embed, EmbedFooter, EmbedAttachment, File
|
|
|
|
from gwendolyn.exceptions import CannotConnectToService
|
|
|
|
class Service():
|
|
def __init__(self, ip: str, port: str, api_key: str) -> None:
|
|
self.ip = ip
|
|
self.port = port
|
|
self.header = {
|
|
"accept": "application/json",
|
|
"X-Api-Key": api_key
|
|
}
|
|
|
|
def test(self):
|
|
return get(f"http://{self.ip}:{self.port}/api", headers=self.header).ok
|
|
|
|
class Radarr(Service):
|
|
def movies(self):
|
|
response = get(f"http://{self.ip}:{self.port}/api/v3/movie", headers=self.header)
|
|
if not response.ok:
|
|
return []
|
|
|
|
return [m for m in response.json() if m["hasFile"]]
|
|
|
|
class Sonarr(Service):
|
|
def shows(self):
|
|
response = get(f"http://{self.ip}:{self.port}/api/v3/series", headers=self.header)
|
|
if not response.ok:
|
|
return []
|
|
|
|
return response.json()
|
|
|
|
class TMDb():
|
|
def __init__(self, api_token: str) -> None:
|
|
self.header = {
|
|
"accept": "application/json",
|
|
"Authorization": "Bearer "+api_token
|
|
}
|
|
|
|
def test(self):
|
|
return get(f"https://api.themoviedb.org/3/account", headers=self.header).ok
|
|
|
|
|
|
class BetterNetflix():
|
|
def __init__(self, radarr: Radarr, sonarr: Sonarr, tmdb: TMDb, bot) -> None:
|
|
self.radarr = radarr
|
|
self.sonarr = sonarr
|
|
self.tmdb = tmdb
|
|
self.bot = bot
|
|
|
|
services = ["radarr","sonarr","tmdb"]
|
|
|
|
for service in services:
|
|
if getattr(self,service).test():
|
|
self.bot.log(f"Connected to {service}")
|
|
else:
|
|
raise CannotConnectToService(service)
|
|
|
|
def _poster_color(self, poster_url: str):
|
|
response = get(poster_url, stream=True)
|
|
img = Image.open(io.BytesIO(response.content))
|
|
img.thumbnail((150, 100))
|
|
|
|
# Reduce colors (uses k-means internally)
|
|
paletted = img.convert('P', palette=Image.ADAPTIVE, colors=6)
|
|
|
|
buf = io.BytesIO()
|
|
img2 = paletted.convert("RGB")
|
|
img2.save("gwendolyn/resources/temp.jpg")
|
|
|
|
# Find the color that occurs most often
|
|
palette = paletted.getpalette()
|
|
color_counts = sorted(paletted.getcolors(), reverse=True)
|
|
palette_index = color_counts[0][1]
|
|
dominant_color = palette[palette_index*3:palette_index*3+3]
|
|
|
|
return dominant_color
|
|
|
|
async def movie(self, ctx: SlashContext):
|
|
msg = await ctx.send("Finding a random movie...")
|
|
movies = self.radarr.movies()
|
|
if len(movies) == 0:
|
|
await msg.edit(content="Unable to find any movies")
|
|
return
|
|
|
|
picked_movie = choice(movies)
|
|
description = ""
|
|
|
|
if "imdb" in picked_movie['ratings']:
|
|
description += f"<:imdb:1301506320603676782> {picked_movie['ratings']['imdb']['value']}"
|
|
description += "\u1CBC\u1CBC"
|
|
|
|
if "rottenTomatoes" in picked_movie['ratings']:
|
|
rt_value = picked_movie['ratings']['rottenTomatoes']['value']
|
|
rt_icon = "<:fresh:1301509701338660894>" if rt_value >= 60 else "<:rotten:1301509685907820607>"
|
|
description += f"{rt_icon} {rt_value}%"
|
|
|
|
if description != "":
|
|
description += "\n\n"
|
|
|
|
year = EmbedFooter(str(picked_movie["year"])) if "year" in picked_movie else None
|
|
has_poster = len(picked_movie["images"]) > 0 and "remoteUrl" in picked_movie["images"][0]
|
|
poster = EmbedAttachment(picked_movie["images"][0]["remoteUrl"]) if has_poster else None
|
|
|
|
color = self._poster_color(picked_movie["images"][0]["remoteUrl"]) if has_poster else "#ff0000"
|
|
|
|
description += picked_movie["overview"]
|
|
embed = Embed(
|
|
picked_movie["title"],
|
|
description,
|
|
color,
|
|
thumbnail=poster,
|
|
footer=year
|
|
)
|
|
await msg.edit(content="",embed=embed)
|
|
|
|
async def show(self, ctx: SlashContext):
|
|
msg = await ctx.send("Finding a random show...")
|
|
shows = self.sonarr.shows()
|
|
if len(shows) == 0:
|
|
await msg.edit(content="Unable to find any shows")
|
|
return
|
|
|
|
picked_show = choice(shows)
|
|
description = ""
|
|
|
|
if "imdb" in picked_show['ratings']:
|
|
description += f"<:imdb:1301506320603676782> {picked_show['ratings']['imdb']['value']}"
|
|
description += "\u1CBC\u1CBC"
|
|
|
|
if "rottenTomatoes" in picked_show['ratings']:
|
|
rt_value = picked_show['ratings']['rottenTomatoes']['value']
|
|
rt_icon = "<:fresh:1301509701338660894>" if rt_value >= 60 else "<:rotten:1301509685907820607>"
|
|
description += f"{rt_icon} {rt_value}%"
|
|
|
|
if description != "":
|
|
description += "\n\n"
|
|
|
|
year = EmbedFooter(str(picked_show["year"])) if "year" in picked_show else None
|
|
images = {i["coverType"]:i for i in picked_show["images"]}
|
|
has_poster = "poster" in images and "remoteUrl" in images["poster"]
|
|
poster = EmbedAttachment(images["poster"]["remoteUrl"]) if has_poster else None
|
|
|
|
color = self._poster_color(images["poster"]["remoteUrl"]) if has_poster else "#ff0000"
|
|
|
|
description += picked_show["overview"]
|
|
embed = Embed(
|
|
picked_show["title"],
|
|
description,
|
|
color,
|
|
thumbnail=poster,
|
|
footer=year
|
|
)
|
|
await msg.edit(content="",embed=embed)
|