Skip to content

Commit

Permalink
Fix IMDb links, add /imdb command
Browse files Browse the repository at this point in the history
  • Loading branch information
stekc committed Oct 8, 2024
1 parent d9e67ea commit f00e831
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 12 deletions.
4 changes: 2 additions & 2 deletions cogs/ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from discord import Interaction, app_commands
from discord.ext import commands, tasks
from discord.ext.commands import Context
from openai import OpenAI
from openai import AsyncOpenAI

from utils.colorthief import get_color

Expand All @@ -19,7 +19,7 @@ class AI(commands.Cog, name="AI"):
def __init__(self, bot):
self.bot = bot
self.bot.allowed_mentions = discord.AllowedMentions.none()
self.openai = OpenAI(api_key=os.getenv("OPENAI_TOKEN"))
self.openai = AsyncOpenAI(api_key=os.getenv("OPENAI_TOKEN"))
self.models = ["gpt-4o-mini", "gpt-4o", "o1-mini", "o1-preview"]
self.approved_guilds = [1088982024150323230, 1185004960925098144]
self.approved_users = [1088593923661893703, 275370518008299532]
Expand Down
62 changes: 53 additions & 9 deletions cogs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def __init__(self, bot):
"reddit": 0,
"twitter": 0,
"songs": 0,
"imdb": 0,
}

socials = SocialsJSON().load_json()
Expand Down Expand Up @@ -53,12 +54,24 @@ async def create_tables(self):
instagram INTEGER DEFAULT 0,
reddit INTEGER DEFAULT 0,
twitter INTEGER DEFAULT 0,
songs INTEGER DEFAULT 0
songs INTEGER DEFAULT 0,
imdb INTEGER DEFAULT 0
)
"""
)
await self.db.commit()

async with self.db.execute("PRAGMA table_info(link_fix_counts)") as cursor:
existing_columns = {row[1] for row in await cursor.fetchall()}
expected_columns = set(self.link_fix_counts.keys())

missing_columns = expected_columns - existing_columns
for column in missing_columns:
await self.db.execute(
f"ALTER TABLE link_fix_counts ADD COLUMN {column} INTEGER DEFAULT 0"
)
await self.db.commit()

@tasks.loop(hours=1)
async def sync_db_task(self):
async with self.db.execute(
Expand All @@ -68,25 +81,37 @@ async def sync_db_task(self):
if row:
db_counts = dict(
zip(
["id", "tiktok", "instagram", "reddit", "twitter", "songs"], row
[
"id",
"tiktok",
"instagram",
"reddit",
"twitter",
"songs",
"imdb",
],
row,
)
)
for platform in self.link_fix_counts:
if platform not in db_counts:
db_counts[platform] = 0
db_counts[platform] += self.link_fix_counts[platform]
self.link_fix_counts[platform] = 0
await self.db.execute(
"UPDATE link_fix_counts SET tiktok = ?, instagram = ?, reddit = ?, twitter = ?, songs = ? WHERE id = 1",
"UPDATE link_fix_counts SET tiktok = ?, instagram = ?, reddit = ?, twitter = ?, songs = ?, imdb = ? WHERE id = 1",
(
db_counts["tiktok"],
db_counts["instagram"],
db_counts["reddit"],
db_counts["twitter"],
db_counts["songs"],
db_counts["imdb"],
),
)
else:
await self.db.execute(
"INSERT INTO link_fix_counts (id, tiktok, instagram, reddit, twitter, songs) VALUES (1, ?, ?, ?, ?, ?)",
"INSERT INTO link_fix_counts (id, tiktok, instagram, reddit, twitter, songs, imdb) VALUES (1, ?, ?, ?, ?, ?, ?)",
tuple(self.link_fix_counts.values()),
)
self.link_fix_counts = {k: 0 for k in self.link_fix_counts}
Expand All @@ -103,7 +128,15 @@ async def get_link_fix_counts(self):
if row:
return dict(
zip(
["id", "tiktok", "instagram", "reddit", "twitter", "songs"],
[
"id",
"tiktok",
"instagram",
"reddit",
"twitter",
"songs",
"imdb",
],
row,
)
)
Expand All @@ -114,6 +147,7 @@ async def get_link_fix_counts(self):
"reddit": 0,
"twitter": 0,
"songs": 0,
"imdb": 0,
}

async def get_guild_config(self, guild_id: int):
Expand Down Expand Up @@ -149,7 +183,9 @@ async def make_config_embed(self, guild_id: int):
config = guild_config.get(platform, {"enabled": True})
status = "🟢 Enabled" if config.get("enabled", True) else "🔴 Disabled"
embed.add_field(
name=platform.title().replace("Tiktok", "TikTok"),
name=platform.title()
.replace("Tiktok", "TikTok")
.replace("Imdb", "IMDb"),
value=status,
inline=False,
)
Expand Down Expand Up @@ -177,7 +213,10 @@ async def social_autofix_autocompletion(
if current.lower() in choice.lower():
data.append(
app_commands.Choice(
name=choice.title().replace("Tiktok", "TikTok"), value=choice
name=choice.title()
.replace("Tiktok", "TikTok")
.replace("Imdb", "IMDb"),
value=choice,
)
)
return data
Expand Down Expand Up @@ -234,7 +273,9 @@ async def make_config_embed(self, guild_id: int):
config = guild_config.get(platform, {"enabled": True})
status = "🟢 Enabled" if config.get("enabled", True) else "🔴 Disabled"
embed.add_field(
name=platform.title().replace("Tiktok", "TikTok"),
name=platform.title()
.replace("Tiktok", "TikTok")
.replace("Imdb", "IMDb"),
value=status,
inline=False,
)
Expand Down Expand Up @@ -262,7 +303,10 @@ async def social_autofix_autocompletion(
if current.lower() in choice.lower():
data.append(
app_commands.Choice(
name=choice.title().replace("Tiktok", "TikTok"), value=choice
name=choice.title()
.replace("Tiktok", "TikTok")
.replace("Imdb", "IMDb"),
value=choice,
)
)
return data
Expand Down
187 changes: 187 additions & 0 deletions cogs/movies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import asyncio
import json
import re
from contextlib import suppress
from urllib.parse import quote_plus

import aiohttp
import discord
from aiocache import cached
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
from discord.ui import Button, View

from utils.colorthief import get_color
from utils.jsons import SocialsJSON


class Movies(commands.Cog, name="movies"):
def __init__(self, bot):
self.bot = bot
self.config = SocialsJSON().load_json()
self.config_cog = self.bot.get_cog("Config")
self.pattern = re.compile(r"imdb\.com\/title\/(tt\d+)")

async def check_enabled(self, site: str, config, guild_id: int = None):
if guild_id is None:
if not self.config[site]["enabled"]:
return False
else:
if not await self.config_cog.get_config_value(guild_id, site, "enabled"):
return False
return True

async def process_movie_data(self, movie, context=None):
"""Helper function to process movie data and create embed and buttons."""
mtitle = movie.get("Title", "Unknown Title")
if year := movie.get("Year"):
mtitle += f" ({year})"

genres = ", ".join(movie.get("Genres", []))
overview = movie.get("Overview", "No overview available")
if len(overview) > 500:
overview = overview[:500] + "..."

poster = next(
(img["Url"] for img in movie.get("Images", []) if "Url" in img), None
)
color = await get_color(poster) if poster else discord.Color.default()

trailer_id = movie.get("YoutubeTrailerId")
trailer = f"https://youtu.be/{trailer_id}" if trailer_id else None
mid = movie.get("ImdbId")

recommendations = movie.get("Recommendations", [])
recommended = "\n".join(
[
f"• [{rec['Title']}](https://www.themoviedb.org/movie/{rec['TmdbId']})"
for rec in recommendations
]
)
embed = discord.Embed(description=recommended, color=color)
recommended_embed = embed

class TrailerButton(Button):
def __init__(self, trailer_url):
super().__init__(
style=discord.ButtonStyle.secondary,
label="Trailer",
emoji="<:Music_YouTube:958786388457840700>",
)
self.trailer_url = trailer_url

async def callback(self, interaction: discord.Interaction):
await interaction.response.send_message(
self.trailer_url, ephemeral=True
)

class RecommendedButton(Button):
def __init__(self, recommended_movies):
super().__init__(
style=discord.ButtonStyle.secondary,
label="Discover More",
emoji="🍿",
)
self.recommended_movies = recommended_movies

async def callback(self, interaction: discord.Interaction):
await interaction.response.send_message(
embed=self.recommended_movies, ephemeral=True
)

view = View()
if mid:
view.add_item(
discord.ui.Button(
style=discord.ButtonStyle.link,
emoji="<:imdb:1292962713542332479>",
url=f"https://www.imdb.com/title/{mid}",
)
)
if trailer:
view.add_item(TrailerButton(trailer))
if recommended:
view.add_item(RecommendedButton(recommended_embed))
view.add_item(
discord.ui.Button(
style=discord.ButtonStyle.link,
label="Open in Stremio",
emoji="<:stremio:1292976659829362813>",
url=f"https://keto.boats/stremio?id={movie['ImdbId']}",
)
)

embed = discord.Embed(
title=mtitle,
description=overview,
color=color,
)
if poster:
embed.set_thumbnail(url=poster)

footer_text = genres
embed.set_footer(text=footer_text)

if context:
await context.send(embed=embed, view=view)
else:
return embed, view

@commands.Cog.listener()
async def on_message(self, message: discord.Message):
if not message.guild:
return
if message.author.bot and not message.author.id == 356268235697553409:
return
if not await self.check_enabled("imdb", self.config, message.guild.id):
return
if message.author.bot:
return
if match := self.pattern.search(message.content.strip("<>")):
link = match.group(1)
async with aiohttp.ClientSession() as session:
async with session.get(
f"https://api.radarr.video/v1/movie/imdb/{link}"
) as response:
movie_data = await response.json()

if (
not movie_data
or not isinstance(movie_data, list)
or len(movie_data) == 0
):
return

movie = movie_data[0]
embed, view = await self.process_movie_data(movie)

await message.reply(embed=embed, view=view)
await self.config_cog.increment_link_fix_count("imdb")
await asyncio.sleep(0.75)
await message.edit(suppress=True)

@commands.hybrid_command(
name="imdb",
description="Search for a movie on IMDb.",
)
@app_commands.describe(query="Title of the movie you want to search for.")
@app_commands.allowed_installs(guilds=True, users=True)
@app_commands.allowed_contexts(guilds=True, dms=True, private_channels=True)
async def imdb(self, context: Context, *, query: str):
"""Search for a movie on IMDb"""
async with aiohttp.ClientSession() as session:
async with session.get(
f"https://api.radarr.video/v1/search?q={quote_plus(query)}&year="
) as response:
movie_data = await response.json()

if not movie_data or not isinstance(movie_data, list) or len(movie_data) == 0:
return await context.send("No results found.")

movie = movie_data[0]
await self.process_movie_data(movie, context)


async def setup(bot):
await bot.add_cog(Movies(bot))
2 changes: 1 addition & 1 deletion cogs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ async def info(self, context: Context) -> None:
for k, v in total_counts.items():
formatted_value = await self.format_number_str(v)
link_fix_stats.append(
f"{k.title().replace('Tiktok', 'TikTok')}: {formatted_value}"
f"{k.title().replace('Tiktok', 'TikTok').replace('Imdb', 'IMDb')}: {formatted_value}"
)

link_fix_stats = "\n".join(link_fix_stats)
Expand Down
3 changes: 3 additions & 0 deletions config/socials.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@
},
"songs": {
"enabled": true
},
"imdb": {
"enabled": true
}
}

0 comments on commit f00e831

Please sign in to comment.