# Ultroid - UserBot
# Copyright (C) 2021-2024 TeamUltroid
#
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
# PLease read the GNU Affero General Public License in
# .
import hashlib
import json
import re
import requests
from bs4 import BeautifulSoup
from telethon import Button
try:
from PIL import Image
except ImportError:
Image = None
from telethon.tl.types import InputWebDocument as wb
from . import LOGS, callback, in_pattern, udB, async_searcher, asst
__doc__ = f"""
✘ Commands Available -
• `@{asst.username} imdb `
Searches for the movie on IMDb and returns the results.
• `@{asst.username} imdb y=`
Searches for the movie on IMDb by year and returns the results.
"""
# Define your OMDB API key
OMDB_API_KEY = udB.get_key("OMDb_API") #OpenMovies Database get free key from http://www.omdbapi.com/ with 1000 dailiy uses
imdbp = "https://graph.org/file/3b45a9ed4868167954300.jpg"
LIST = {}
hash_to_url = {}
def generate_unique_id(url):
hashed_id = hashlib.sha256(url.encode()).hexdigest()[:8]
hash_to_url[hashed_id] = url
return hashed_id
def get_original_url(hashed_id):
return hash_to_url.get(hashed_id)
async def get_movie_data(search_term, full_plot=False):
if "y=" in search_term:
parts = search_term.split("y=")
if parts:
LOGS.info(f"YEAR_prts: {parts}")
movie_name = parts[0].strip()
if movie_name:
year = parts[1].strip() if len(parts) > 1 else None
if year:
SBY = True
else:
SBY = False
else:
SBY = False
movie_name = search_term
else:
SBY = False
movie_name = search_term
else:
SBY = False
movie_name = search_term
url = f"http://www.omdbapi.com/?apikey={OMDB_API_KEY}&t={movie_name}"
if SBY is True:
url += f"&y={year}"
if full_plot is True:
url += "&plot=full"
data = await async_searcher(url, re_json=True)
if data.get("Response") == "True":
return data
else:
LOGS.info("Error: Unable to fetch movie data")
return None
def get_trailer(imdbID):
url = f"https://www.imdb.com/title/{imdbID}/"
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers)
if response.status_code == 200:
soup = BeautifulSoup(response.content, "html.parser")
script = soup.find("script", type="application/ld+json")
data = json.loads(script.string)
trailer_url = data.get("trailer", {}).get("embedUrl")
if trailer_url:
LOGS.info(f"Trailer URL: {trailer_url}")
return f"{trailer_url}"
else:
LOGS.info("Could not find trailer link")
return None
else:
LOGS.info("Error: Unable to fetch IMDb page")
return None
@in_pattern("imdb", owner=False)
async def inline_imdb_command(event):
try:
movie_name = event.text.split(" ", maxsplit=1)[1]
LOGS.info(f"QUERY\n{movie_name}")
except IndexError:
indexarticle = event.builder.article(
title="Sᴇᴀʀᴄʜ Sᴏᴍᴇᴛʜɪɴɢ",
thumb=wb(imdbp, 0, "image/jpeg", []),
text="**Iᴍᴅʙ Sᴇᴀʀᴄʜ**\n\nʏᴏᴜ ᴅɪᴅɴ'ᴛ sᴇᴀʀᴄʜ ᴀɴʏᴛʜɪɴɢ",
buttons=[
Button.switch_inline(
"Sᴇᴀʀᴄʜ Aɢᴀɪɴ",
query="imdb ",
same_peer=True,
),
Button.switch_inline(
"Sᴇᴀʀᴄʜ Bʏ Yᴇᴀʀ",
query="imdb IF y= 2024 ",
same_peer=True,
),
],
)
await event.answer([indexarticle])
return
try:
movie_data = await get_movie_data(movie_name)
if movie_data:
title = movie_data.get("Title", "")
year = movie_data.get("Year", "")
rated = movie_data.get("Rated", "")
released = movie_data.get("Released", "")
runtime = movie_data.get("Runtime", "")
ratings = movie_data.get("Ratings", "")
ratings_str = ", ".join(
[f"{rating['Source']}: `{rating['Value']}`" for rating in ratings]
)
genre = movie_data.get("Genre", "")
director = movie_data.get("Director", "")
actors = movie_data.get("Actors", "")
plot = movie_data.get("Plot", "")
language = movie_data.get("Language", "")
country = movie_data.get("Country", "")
awards = movie_data.get("Awards", "")
poster_url = movie_data.get("Poster", "")
imdbRating = movie_data.get("imdbRating", "")
imdbVotes = movie_data.get("imdbVotes", "")
BoxOffice = movie_data.get("BoxOffice", "")
imdbID = movie_data.get("imdbID", "")
movie_details = (
f"**Tɪᴛʟᴇ:** {title}\n"
f"**Yᴇᴀʀ:** `{year}`\n"
f"**Rᴀᴛᴇᴅ:** `{rated}`\n"
f"**Rᴇʟᴇᴀsᴇᴅ:** {released}\n"
f"**Rᴜɴᴛɪᴍᴇ:** `{runtime}`\n"
f"**Gᴇɴʀᴇ:** {genre}\n"
f"**Dɪʀᴇᴄᴛᴏʀ:** {director}\n"
f"**Aᴄᴛᴏʀs:** {actors}\n"
f"**Pʟᴏᴛ:** {plot}\n"
f"**Lᴀɴɢᴜᴀɢᴇ:** `{language}`\n"
f"**Cᴏᴜɴᴛʀʏ:** {country}\n"
f"**Aᴡᴀʀᴅs:** {awards}\n"
f"**Rᴀᴛɪɴɢs:** {ratings_str}\n"
f"**IMDʙ Rᴀᴛɪɴɢ:** `{imdbRating}`\n"
f"**IMDʙ Lɪɴᴋ:** https://www.imdb.com/title/{imdbID}\n"
f"**ɪᴍᴅʙVᴏᴛᴇs:** `{imdbVotes}`\n"
f"**BᴏxOғғɪᴄᴇ:** `{BoxOffice}`"
)
except Exception as er:
LOGS.info(f"Exception: {er}")
try:
plot_id = generate_unique_id(movie_details)
except UnboundLocalError:
if " y= " in movie_name:
noresult = movie_name.replace(" y= ", " ")
elif "y= " in movie_name:
noresult = movie_name.replace("y= ", "")
elif "y=" in movie_name:
noresult = movie_name.replace("y=", "")
else:
noresult = movie_name
return await event.answer(
[
await event.builder.article(
title="Nᴏ ʀᴇsᴜʟᴛs ғᴏᴜɴᴅ",
text=f"**IMDʙ**\nTʀʏ ᴀɴᴏᴛʜᴇʀ sᴇᴀʀᴄʜ",
thumb=wb(imdbp, 0, "image/jpeg", []),
buttons=[
Button.switch_inline(
"Sᴇᴀʀᴄʜ Aɢᴀɪɴ",
query="imdb ",
same_peer=True,
),
Button.switch_inline(
"Sᴇᴀʀᴄʜ Bʏ Yᴇᴀʀ",
query=f"imdb {movie_name} y= ",
same_peer=True,
),
],
)
],
switch_pm=f"{noresult}",
switch_pm_param="start",
)
except Exception as er:
LOGS.info(f"Exception: {er}")
return
txt = f"**Tɪᴛʟᴇ:** {title}\n**Rᴇʟᴇᴀsᴇᴅ:** {released}\n**Cᴏᴜɴᴛʀʏ:** {country}"
button = [
[Button.inline("Fᴜʟʟ Dᴇᴛᴀɪʟs", data=f"plot_button:{plot_id}")],
[Button.switch_inline("Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="imdb ", same_peer=True)],
]
article = await event.builder.article(
type="photo",
text=txt,
title=f"{title}",
include_media=True,
description=f"{released}\nɪᴍᴅʙ: {imdbRating}\nLᴀɴɢᴜᴀɢᴇ: {language}",
link_preview=False,
thumb=wb(poster_url, 0, "image/jpeg", []),
content=wb(poster_url, 0, "image/jpeg", []),
buttons=button,
)
LIST.update(
{
plot_id: {
"text": txt,
"buttons": button,
"imdbID": imdbID,
"movie_name": movie_name,
"plot": plot,
}
}
)
await event.answer([article])
@callback(re.compile("plot_button:(.*)"), owner=False)
async def plot_button_clicked(event):
plot_id = event.data.decode().split(":", 1)[1]
details = get_original_url(plot_id)
plot = LIST[plot_id]["plot"]
imdbID = LIST[plot_id]["imdbID"]
trailer_url = get_trailer(imdbID)
btns = [
[Button.inline("Back", data=f"imdb_back_button:{plot_id}")],
]
if trailer_url:
btns.insert(0, [Button.url("Trailer", url=trailer_url)])
if plot.endswith("..."):
btns.insert(
0, [Button.inline("Extended Plot", data=f"extended_plot:{plot_id}")]
)
await event.edit(details, buttons=btns)
@callback(re.compile("imdb_back_button:(.*)"), owner=False)
async def back_button_clicked(event):
plot_id = event.data.decode().split(":", 1)[1]
if not LIST.get(plot_id):
return await event.answer("Query Expired! Search again 🔍")
text = LIST[plot_id]["text"]
buttons = LIST[plot_id]["buttons"]
await event.edit(text, buttons=buttons)
@callback(re.compile("extended_plot:(.*)"), owner=False)
async def extended_plot_button_clicked(event):
plot_id = event.data.decode().split(":", 1)[1]
if not LIST.get(plot_id):
return await event.answer("Query Expired! Search again 🔍")
movie_name = LIST[plot_id]["movie_name"]
ext_plot = await get_movie_data(movie_name, full_plot=True)
fullplot = ext_plot.get("Plot", "")
if fullplot:
extended_plot = f"**Exᴛᴇɴᴅᴇᴅ Pʟᴏᴛ:** {fullplot}"
btns = [
[Button.inline("Back", data=f"imdb_back_button:{plot_id}")],
]
await event.edit(extended_plot, buttons=btns)