import os, re
import aiohttp
from bs4 import BeautifulSoup
import json
import traceback
from pyrogram import Client, filters
from deep_translator import GoogleTranslator
from gtts import gTTS
from pyrogram.errors import (
MediaEmpty,
MessageNotModified,
PhotoInvalidDimensions,
UserNotParticipant,
WebpageMediaEmpty,
MessageTooLong,
)
from misskaty.vars import COMMAND_HANDLER
from utils import extract_user, get_file_id, demoji
import time
from datetime import datetime
from logging import getLogger
from pykeyboard import InlineKeyboard
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
from misskaty.core.decorator.errors import capture_err
from misskaty.helper.tools import rentry, GENRES_EMOJI
from misskaty.helper.http import http
from misskaty import app
LOGGER = getLogger(__name__)
__MODULE__ = "Misc"
__HELP__ = """
/sof [query] - Search your problem in StackOverflow.
/google [query] - Search using Google Search.
(/tr, /trans, /translate) [lang code] - Translate text using Google Translate.
/tts - Convert Text to Voice.
/imdb [query] - Find Movie Details From IMDB.com in Indonesian Language.
/imdb_en [query] - Find Movie Details From IMDB.com in English Language.
"""
def remove_html_tags(text):
"""Remove html tags from a string"""
import re
clean = re.compile("<.*?>")
return re.sub(clean, "", text)
@app.on_message(filters.command(["sof"], COMMAND_HANDLER))
@capture_err
async def stackoverflow(client, message):
if len(message.command) == 1:
return await message.reply("Give a query to search in StackOverflow!")
r = (
await http.get(
f"https://api.stackexchange.com/2.3/search/excerpts?order=asc&sort=relevance&q={message.command[1]}&accepted=True&migrated=False¬ice=False&wiki=False&site=stackoverflow"
)
).json()
hasil = ""
for count, data in enumerate(r["items"], start=1):
question = data["question_id"]
title = data["title"]
snippet = (
remove_html_tags(data["excerpt"])[:80].replace("\n", "").replace(" ", "")
if len(remove_html_tags(data["excerpt"])) > 80
else remove_html_tags(data["excerpt"]).replace("\n", "").replace(" ", "")
)
hasil += f"{count}. {title}\n{snippet}\n"
try:
await message.reply(hasil)
except MessageTooLong:
url = await rentry(hasil)
await r.edit(f"Your text pasted to rentry because has long text:\n{url}")
except Exception as e:
await message.reply(e)
@app.on_message(filters.command(["google"], COMMAND_HANDLER))
@capture_err
async def gsearch(client, message):
if len(message.command) == 1:
return await message.reply("Give a query to search in Google!")
query = message.text.split(" ", maxsplit=1)[1]
msg = await message.reply_text(f"**Googling** for `{query}` ...")
try:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/61.0.3163.100 Safari/537.36"
}
html = await http.get(
f"https://www.google.com/search?q={query}&gl=id&hl=id&num=17",
headers=headers,
)
soup = BeautifulSoup(html.text, "lxml")
# collect data
data = []
for result in soup.select(".tF2Cxc"):
title = result.select_one(".DKV0Md").text
link = result.select_one(".yuRUbf a")["href"]
try:
snippet = result.select_one("#rso .lyLwlc").text
except:
snippet = "-"
# appending data to an array
data.append(
{
"title": title,
"link": link,
"snippet": snippet,
}
)
arr = json.dumps(data, indent=2, ensure_ascii=False)
parse = json.loads(arr)
total = len(parse)
res = "".join(
f"{i['title']}\n{i['snippet']}\n\n" for i in parse
)
except Exception:
exc = traceback.format_exc()
return await msg.edit(exc)
await msg.edit(
text=f"Ada {total} Hasil Pencarian dari {query}:\n{res}Scraped by @{app.me.username}",
disable_web_page_preview=True,
)
@app.on_message(filters.command(["tr", "trans", "translate"], COMMAND_HANDLER))
@capture_err
async def translate(client, message):
if message.reply_to_message and (
message.reply_to_message.text or message.reply_to_message.caption
):
target_lang = "id" if len(message.command) == 1 else message.text.split()[1]
text = message.reply_to_message.text or message.reply_to_message.caption
else:
if len(message.command) == 1:
return await message.reply_text(
"Berikan Kode bahasa yang valid.\n[Available options](https://telegra.ph/Lang-Codes-11-08).\nUsage: /tr en",
)
target_lang = message.text.split(None, 2)[1]
text = message.text.split(None, 2)[2]
msg = await message.reply("Menerjemahkan...")
try:
tekstr = (
await http.get(
f"https://script.google.com/macros/s/AKfycbyhNk6uVgrtJLEFRUT6y5B2pxETQugCZ9pKvu01-bE1gKkDRsw/exec?q={text}&target={target_lang}"
)
).json()["text"]
except Exception as err:
return await msg.edit(f"Error: {str(err)}")
try:
await msg.edit(f"{tekstr}")
except MessageTooLong:
url = await rentry(tekstr.text)
await msg.edit(
f"Your translated text pasted to rentry because has long text:\n{url}"
)
@app.on_message(filters.command(["tts"], COMMAND_HANDLER))
@capture_err
async def tts(_, message):
if message.reply_to_message and (
message.reply_to_message.text or message.reply_to_message.caption
):
if len(message.text.split()) == 1:
target_lang = "id"
else:
target_lang = message.text.split()[1]
text = message.reply_to_message.text or message.reply_to_message.caption
else:
if len(message.text.split()) <= 2:
await message.reply_text(
"Berikan Kode bahasa yang valid.\n[Available options](https://telegra.ph/Lang-Codes-11-08).\nUsage: /tts en ",
)
return
target_lang = message.text.split(None, 2)[1]
text = message.text.split(None, 2)[2]
msg = await message.reply("Converting to voice...")
try:
tts = gTTS(text, lang=target_lang)
tts.save(f"tts_{message.from_user.id}.mp3")
except ValueError as err:
await msg.edit(f"Error: {str(err)}")
return
await msg.delete()
await msg.reply_audio(f"tts_{message.from_user.id}.mp3")
try:
os.remove(f"tts_{message.from_user.id}.mp3")
except:
pass
@app.on_message(filters.command(["tosticker"], COMMAND_HANDLER))
@capture_err
async def tostick(client, message):
try:
if not message.reply_to_message or not message.reply_to_message.photo:
return await message.reply_text("Reply ke foto untuk mengubah ke sticker")
sticker = await client.download_media(
message.reply_to_message.photo.file_id,
f"tostick_{message.from_user.id}.webp",
)
await message.reply_sticker(sticker)
os.remove(sticker)
except Exception as e:
await message.reply_text(str(e))
@app.on_message(filters.command(["toimage"], COMMAND_HANDLER))
@capture_err
async def topho(client, message):
try:
if not message.reply_to_message or not message.reply_to_message.sticker:
return await message.reply_text("Reply ke sticker untuk mengubah ke foto")
if message.reply_to_message.sticker.is_animated:
return await message.reply_text(
"Ini sticker animasi, command ini hanya untuk sticker biasa."
)
photo = await client.download_media(
message.reply_to_message.sticker.file_id,
f"tostick_{message.from_user.id}.jpg",
)
await message.reply_photo(
photo=photo, caption=f"Sticker -> Image\n@{app.me.username}"
)
os.remove(photo)
except Exception as e:
await message.reply_text(str(e))
@app.on_message(filters.command(["id"], COMMAND_HANDLER))
async def showid(client, message):
chat_type = message.chat.type
if chat_type == "private":
user_id = message.chat.id
first = message.from_user.first_name
last = message.from_user.last_name or ""
username = message.from_user.username
dc_id = message.from_user.dc_id or ""
await message.reply_text(
f"➲ First Name: {first}\n➲ Last Name: {last}\n➲ Username: {username}\n➲ Telegram ID: {user_id}\n➲ Data Centre: {dc_id}",
quote=True,
)
elif chat_type in ["group", "supergroup"]:
_id = ""
_id += "➲ Chat ID: " f"{message.chat.id}\n"
if message.reply_to_message:
_id += (
"➲ User ID: "
f"{message.from_user.id if message.from_user else 'Anonymous'}\n"
"➲ Replied User ID: "
f"{message.reply_to_message.from_user.id if message.reply_to_message.from_user else 'Anonymous'}\n"
)
file_info = get_file_id(message.reply_to_message)
else:
_id += (
"➲ User ID: "
f"{message.from_user.id if message.from_user else 'Anonymous'}\n"
)
file_info = get_file_id(message)
if file_info:
_id += (
f"{file_info.message_type}: "
f"{file_info.file_id}\n"
)
await message.reply_text(_id, quote=True)
@app.on_message(filters.command(["info"], COMMAND_HANDLER))
async def who_is(client, message):
# https://github.com/SpEcHiDe/PyroGramBot/blob/master/pyrobot/plugins/admemes/whois.py#L19
status_message = await message.reply_text("`Fetching user info...`")
await status_message.edit("`Processing user info...`")
from_user = None
from_user_id, _ = extract_user(message)
try:
from_user = await client.get_users(from_user_id)
except Exception as error:
await status_message.edit(str(error))
return
if from_user is None:
return await status_message.edit("no valid user_id / message specified")
message_out_str = ""
message_out_str += f"➲First Name: {from_user.first_name}\n"
last_name = from_user.last_name or "None"
message_out_str += f"➲Last Name: {last_name}\n"
message_out_str += f"➲Telegram ID: {from_user.id}\n"
username = from_user.username or "None"
dc_id = from_user.dc_id or "[User Doesnt Have A Valid DP]"
message_out_str += f"➲Data Centre: {dc_id}\n"
message_out_str += f"➲User Name: @{username}\n"
message_out_str += f"➲User 𝖫𝗂𝗇𝗄: Click Here\n"
if message.chat.type in (("supergroup", "channel")):
try:
chat_member_p = await message.chat.get_member(from_user.id)
joined_date = datetime.fromtimestamp(
chat_member_p.joined_date or time.time()
).strftime("%Y.%m.%d %H:%M:%S")
message_out_str += (
"➲Joined this Chat on: " f"{joined_date}" "\n"
)
except UserNotParticipant:
pass
if chat_photo := from_user.photo:
local_user_photo = await client.download_media(message=chat_photo.big_file_id)
buttons = [[InlineKeyboardButton("🔐 Close", callback_data="close_data")]]
reply_markup = InlineKeyboardMarkup(buttons)
await message.reply_photo(
photo=local_user_photo,
quote=True,
reply_markup=reply_markup,
caption=message_out_str,
disable_notification=True,
)
os.remove(local_user_photo)
else:
buttons = [[InlineKeyboardButton("🔐 Close", callback_data="close_data")]]
reply_markup = InlineKeyboardMarkup(buttons)
await message.reply_text(
text=message_out_str,
reply_markup=reply_markup,
quote=True,
disable_notification=True,
)
await status_message.delete()
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10"
}
async def get_content(url):
async with aiohttp.ClientSession() as session:
r = await session.get(url, headers=headers)
return await r.read()
async def mdlapi(title):
link = f"https://kuryana.vercel.app/search/q/{title}"
async with aiohttp.ClientSession() as ses:
async with ses.get(link) as result:
return await result.json()
@app.on_message(filters.command(["mdl"], COMMAND_HANDLER))
@capture_err
async def mdlsearch(client, message):
if " " in message.text:
r, title = message.text.split(None, 1)
k = await message.reply("Sedang mencari di Database MyDramaList.. 😴")
movies = await mdlapi(title)
res = movies["results"]["dramas"]
if not movies:
return await k.edit("Tidak ada hasil ditemukan.. 😕")
btn = [
[
InlineKeyboardButton(
text=f"{movie.get('title')} ({movie.get('year')})",
callback_data=f"mdls_{message.from_user.id}_{message.id}_{movie['slug']}",
)
]
for movie in res
]
await k.edit(
f"Ditemukan {len(movies)} query dari {title}",
reply_markup=InlineKeyboardMarkup(btn),
)
else:
await message.reply("Berikan aku nama drama yang ingin dicari. 🤷🏻♂️")
@app.on_callback_query(filters.regex("^mdls"))
@capture_err
async def mdl_callback(bot: Client, query: CallbackQuery):
i, user, msg_id, slug = query.data.split("_")
if user == f"{query.from_user.id}":
await query.message.edit_text("Permintaan kamu sedang diproses.. ")
result = ""
try:
res = (await http.get(f"https://kuryana.vercel.app/id/{slug}")).json()
result += f"Title: {res['data']['title']}\n"
result += (
f"AKA: {res['data']['others']['also_known_as']}\n\n"
)
result += f"Rating: {res['data']['details']['score']}\n"
result += f"Content Rating: {res['data']['details']['content_rating']}\n"
result += f"Type: {res['data']['details']['type']}\n"
result += (
f"Country: {res['data']['details']['country']}\n"
)
if res["data"]["details"]["type"] == "Movie":
result += f"Release Date: {res['data']['details']['release_date']}\n"
elif res["data"]["details"]["type"] == "Drama":
result += f"Episode: {res['data']['details']['episodes']}\n"
result += (
f"Aired: {res['data']['details']['aired']}\n"
)
try:
result += f"Aired on: {res['data']['details']['aired_on']}\n"
except:
pass
try:
result += f"Original Network: {res['data']['details']['original_network']}\n"
except:
pass
result += (
f"Duration: {res['data']['details']['duration']}\n"
)
result += (
f"Genre: {res['data']['others']['genres']}\n\n"
)
result += f"Synopsis: {res['data']['synopsis']}\n"
result += f"Tags: {res['data']['others']['tags']}\n"
btn = InlineKeyboardMarkup(
[[InlineKeyboardButton("🎬 Open MyDramaList", url=res["data"]["link"])]]
)
await query.message.edit_text(result, reply_markup=btn)
except Exception as e:
await query.message.edit_text(f"ERROR:\n{e}")
else:
await query.answer("Tombol ini bukan untukmu", show_alert=True)
# IMDB Versi Indonesia v1
@app.on_message(filters.command(["imdb"], COMMAND_HANDLER))
@capture_err
async def imdb1_search(client, message):
BTN = []
if message.sender_chat:
return await message.reply(
"Mohon maaf fitur tidak tersedia untuk akun channel, harap ganti ke akun biasa.."
)
if len(message.command) == 1:
return await message.reply(
"Berikan aku nama series atau movie yang ingin dicari. 🤷🏻♂️", quote=True
)
r, judul = message.text.split(None, 1)
k = await message.reply("🔎 Sedang mencari di Database IMDB..", quote=True)
msg = ""
buttons = InlineKeyboard(row_width=4)
try:
r = await get_content(f"https://yasirapi.eu.org/imdb-search?q={judul}")
res = json.loads(r).get("result")
if not res:
return await k.edit("Tidak ada hasil ditemukan.. 😕")
msg += f"Ditemukan {len(res)} query dari {judul} ~ {message.from_user.mention}\n\n"
for count, movie in enumerate(res, start=1):
title = movie.get("l")
year = f"({movie.get('y')})" if movie.get("y") else ""
type = movie.get("q").replace("feature", "movie").capitalize()
movieID = re.findall(r"tt(\d+)", movie.get("id"))[0]
msg += f"{count}. {title} {year} ~ {type}\n"
BTN.append(
InlineKeyboardButton(
text=count, callback_data=f"imdbid#{message.from_user.id}#{movieID}"
)
)
buttons.add(*BTN)
await k.edit(msg, reply_markup=buttons)
except Exception as err:
await k.edit(f"Ooppss, gagal mendapatkan daftar judul di IMDb.\n\nERROR: {err}")
@app.on_callback_query(filters.regex("^imdbid"))
async def imdbcb_backup(bot: Client, query: CallbackQuery):
usr = query.message.reply_to_message
i, userid, movie = query.data.split("#")
if query.from_user.id != int(userid):
return await query.answer("⚠️ Akses Ditolak!", True)
try:
await query.message.edit_text("Permintaan kamu sedang diproses.. ")
url = f"https://www.imdb.com/title/tt{movie}/"
resp = await get_content(url)
sop = BeautifulSoup(resp, "lxml")
r_json = json.loads(
sop.find("script", attrs={"type": "application/ld+json"}).contents[0]
)
res_str = ""
type = f"{r_json['@type']}" if r_json.get("@type") else ""
if r_json.get("name"):
try:
tahun = (
sop.select('ul[data-testid="hero-title-block__metadata"]')[0]
.find(class_="sc-8c396aa2-2 itZqyK")
.text
)
except:
tahun = "-"
res_str += f"📹 Judul: {r_json['name']} [{tahun}] ({type})\n"
if r_json.get("alternateName"):
res_str += f"📢 AKA: {r_json.get('alternateName')}\n\n"
else:
res_str += "\n"
if sop.select('li[data-testid="title-techspec_runtime"]'):
durasi = (
sop.select('li[data-testid="title-techspec_runtime"]')[0]
.find(class_="ipc-metadata-list-item__content-container")
.text
)
res_str += f"Durasi: {GoogleTranslator('auto', 'id').translate(durasi)}\n"
if r_json.get("contentRating"):
res_str += f"Kategori: {r_json['contentRating']} \n"
if r_json.get("aggregateRating"):
res_str += f"Peringkat: {r_json['aggregateRating']['ratingValue']}⭐️ dari {r_json['aggregateRating']['ratingCount']} pengguna \n"
if sop.select('li[data-testid="title-details-releasedate"]'):
rilis = (
sop.select('li[data-testid="title-details-releasedate"]')[0]
.find(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
.text
)
rilis_url = sop.select('li[data-testid="title-details-releasedate"]')[
0
].find(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)[
"href"
]
res_str += (
f"Rilis: {rilis}\n"
)
if r_json.get("genre"):
genre = "".join(
f"{GENRES_EMOJI[i]} #{i.replace('-', '_').replace(' ', '_')}, "
if i in GENRES_EMOJI
else f"#{i.replace('-', '_').replace(' ', '_')}, "
for i in r_json["genre"]
)
genre = genre[:-2]
res_str += f"Genre: {genre}\n"
if sop.select('li[data-testid="title-details-origin"]'):
country = "".join(
f"{demoji(country.text)} #{country.text.replace(' ', '_').replace('-', '_')}, "
for country in sop.select('li[data-testid="title-details-origin"]')[
0
].findAll(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
)
country = country[:-2]
res_str += f"Negara: {country}\n"
if sop.select('li[data-testid="title-details-languages"]'):
language = "".join(
f"#{lang.text.replace(' ', '_').replace('-', '_')}, "
for lang in sop.select('li[data-testid="title-details-languages"]')[
0
].findAll(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
)
language = language[:-2]
res_str += f"Bahasa: {language}\n"
res_str += "\n🙎 Info Cast:\n"
if r_json.get("director"):
director = ""
for i in r_json["director"]:
name = i["name"]
url = i["url"]
director += f"{name}, "
director = director[:-2]
res_str += f"Sutradara: {director}\n"
if r_json.get("creator"):
creator = ""
for i in r_json["creator"]:
if i["@type"] == "Person":
name = i["name"]
url = i["url"]
creator += f"{name}, "
creator = creator[:-2]
res_str += f"Penulis: {creator}\n"
if r_json.get("actor"):
actors = ""
for i in r_json["actor"]:
name = i["name"]
url = i["url"]
actors += f"{name}, "
actors = actors[:-2]
res_str += f"Pemeran: {actors}\n\n"
if r_json.get("description"):
summary = GoogleTranslator("auto", "id").translate(
r_json.get("description")
)
res_str += f"📜 Plot: {summary}\n\n"
if r_json.get("keywords"):
keywords = r_json["keywords"].split(",")
key_ = ""
for i in keywords:
i = i.replace(" ", "_").replace("-", "_")
key_ += f"#{i}, "
key_ = key_[:-2]
res_str += f"🔥 Kata Kunci: {key_} \n"
if sop.select('li[data-testid="award_information"]'):
awards = (
sop.select('li[data-testid="award_information"]')[0]
.find(class_="ipc-metadata-list-item__list-content-item")
.text
)
res_str += f"🏆 Penghargaan: {GoogleTranslator('auto', 'id').translate(awards)}\n\n"
else:
res_str += "\n"
res_str += f"©️ IMDb by @{app.me.username}"
if r_json.get("trailer"):
trailer_url = r_json["trailer"]["url"]
markup = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
"🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}"
),
InlineKeyboardButton("▶️ Trailer", url=trailer_url),
]
]
)
else:
markup = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
"🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}"
)
]
]
)
if thumb := r_json.get("image"):
try:
await query.message.reply_photo(
photo=thumb,
quote=True,
caption=res_str,
reply_to_message_id=usr.id,
reply_markup=markup,
)
except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty):
poster = thumb.replace(".jpg", "._V1_UX360.jpg")
await query.message.reply_photo(
photo=poster,
caption=res_str,
reply_to_message_id=usr.id,
reply_markup=markup,
)
except Exception:
await query.message.reply(
res_str,
reply_markup=markup,
disable_web_page_preview=False,
reply_to_message_id=usr.id,
)
await query.message.delete()
else:
await query.message.edit(
res_str, reply_markup=markup, disable_web_page_preview=False
)
await query.answer()
except MessageNotModified:
pass
except Exception:
exc = traceback.format_exc()
await query.message.edit_text(f"ERROR:\n{exc}")
# IMDB Versi English
@app.on_message(filters.command(["imdb_en"], COMMAND_HANDLER))
@capture_err
async def imdb_en_search(client, message):
BTN = []
if message.sender_chat:
return await message.reply("This feature not available for channel.")
if len(message.command) == 1:
return await message.reply(
"Give movie name or series. Ex: /imdb_en soul. 🤷🏻♂️",
quote=True,
)
r, title = message.text.split(None, 1)
k = await message.reply("Searching Movie/Series in IMDB Database.. 😴", quote=True)
msg = ""
buttons = InlineKeyboard(row_width=4)
try:
r = await get_content(f"https://yasirapi.eu.org/imdb-search?q={title}")
res = json.loads(r).get("result")
if not res:
return await k.edit("Sad, No Result.. 😕")
msg = f"Found {len(res)} result from {title} ~ {message.from_user.mention}\n\n"
for count, movie in enumerate(res, start=1):
titles = movie.get("l")
year = f"({movie.get('y')})" if movie.get("y") else ""
type = movie.get("qid").replace("feature", "movie").capitalize()
movieID = re.findall(r"tt(\d+)", movie.get("id"))[0]
msg += f"{count}. {titles} {year} ~ {type}\n"
BTN.append(
InlineKeyboardButton(
text=count, callback_data=f"imdben#{message.from_user.id}#{movieID}"
)
)
buttons.add(*BTN)
await k.edit(msg, reply_markup=buttons)
except Exception as err:
await k.edit(f"Ooppss, failed get movie list from IMDb.\n\nERROR: {err}")
@app.on_callback_query(filters.regex("^imdben"))
@capture_err
async def imdb_en_callback(bot: Client, query: CallbackQuery):
usr = query.message.reply_to_message
i, userid, movie = query.data.split("#")
if query.from_user.id != int(userid):
return await query.answer("⚠️ Access Denied!", True)
await query.message.edit_text("⏳ Processing your request..")
try:
url = f"https://www.imdb.com/title/tt{movie}/"
resp = await get_content(url)
sop = BeautifulSoup(resp, "lxml")
r_json = json.loads(
sop.find("script", attrs={"type": "application/ld+json"}).contents[0]
)
res_str = ""
type = f"{r_json['@type']}" if r_json.get("@type") else ""
if r_json.get("name"):
try:
tahun = (
sop.select('ul[data-testid="hero-title-block__metadata"]')[0]
.find(class_="sc-8c396aa2-2 itZqyK")
.text
)
except:
tahun = "-"
res_str += f"📹 Title: {r_json['name']} [{tahun}] ({type})\n"
if r_json.get("alternateName"):
res_str += f"📢 AKA: {r_json.get('alternateName')}\n\n"
else:
res_str += "\n"
if sop.select('li[data-testid="title-techspec_runtime"]'):
durasi = (
sop.select('li[data-testid="title-techspec_runtime"]')[0]
.find(class_="ipc-metadata-list-item__content-container")
.text
)
res_str += f"Duration: {durasi}\n"
if r_json.get("contentRating"):
res_str += f"Category: {r_json['contentRating']} \n"
if r_json.get("aggregateRating"):
res_str += f"Rating: {r_json['aggregateRating']['ratingValue']}⭐️ from {r_json['aggregateRating']['ratingCount']} user \n"
if sop.select('li[data-testid="title-details-releasedate"]'):
rilis = (
sop.select('li[data-testid="title-details-releasedate"]')[0]
.find(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
.text
)
rilis_url = sop.select('li[data-testid="title-details-releasedate"]')[
0
].find(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)[
"href"
]
res_str += f"Release Data: {rilis}\n"
if r_json.get("genre"):
genre = "".join(
f"{GENRES_EMOJI[i]} #{i.replace('-', '_').replace(' ', '_')}, "
if i in GENRES_EMOJI
else f"#{i.replace('-', '_').replace(' ', '_')}, "
for i in r_json["genre"]
)
genre = genre[:-2]
res_str += f"Genre: {genre}\n"
if sop.select('li[data-testid="title-details-origin"]'):
country = "".join(
f"{demoji(country.text)} #{country.text.replace(' ', '_').replace('-', '_')}, "
for country in sop.select('li[data-testid="title-details-origin"]')[
0
].findAll(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
)
country = country[:-2]
res_str += f"Country: {country}\n"
if sop.select('li[data-testid="title-details-languages"]'):
language = "".join(
f"#{lang.text.replace(' ', '_').replace('-', '_')}, "
for lang in sop.select('li[data-testid="title-details-languages"]')[
0
].findAll(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
)
language = language[:-2]
res_str += f"Language: {language}\n"
res_str += "\n🙎 Cast Info:\n"
if r_json.get("director"):
director = ""
for i in r_json["director"]:
name = i["name"]
url = i["url"]
director += f"{name}, "
director = director[:-2]
res_str += f"Director: {director}\n"
if r_json.get("creator"):
creator = ""
for i in r_json["creator"]:
if i["@type"] == "Person":
name = i["name"]
url = i["url"]
creator += f"{name}, "
creator = creator[:-2]
res_str += f"Penulis: {creator}\n"
if r_json.get("actor"):
actors = ""
for i in r_json["actor"]:
name = i["name"]
url = i["url"]
actors += f"{name}, "
actors = actors[:-2]
res_str += f"Stars: {actors}\n\n"
if r_json.get("description"):
res_str += f"📜 Summary: {r_json['description'].replace(' ', ' ')}\n\n"
if r_json.get("keywords"):
keywords = r_json["keywords"].split(",")
key_ = ""
for i in keywords:
i = i.replace(" ", "_").replace("-", "_")
key_ += f"#{i}, "
key_ = key_[:-2]
res_str += f"🔥 Keywords: {key_} \n"
if sop.select('li[data-testid="award_information"]'):
awards = (
sop.select('li[data-testid="award_information"]')[0]
.find(class_="ipc-metadata-list-item__list-content-item")
.text
)
res_str += f"🏆 Awards: {awards}\n\n"
else:
res_str += "\n"
res_str += f"©️ IMDb by @{app.me.username}"
if r_json.get("trailer"):
trailer_url = r_json["trailer"]["url"]
markup = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
"🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}"
),
InlineKeyboardButton("▶️ Trailer", url=trailer_url),
]
]
)
else:
markup = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
"🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}"
)
]
]
)
if thumb := r_json.get("image"):
try:
await query.message.reply_photo(
photo=thumb,
quote=True,
caption=res_str,
reply_to_message_id=usr.id,
reply_markup=markup,
)
except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty):
poster = thumb.replace(".jpg", "._V1_UX360.jpg")
await query.message.reply_photo(
photo=poster,
caption=res_str,
reply_to_message_id=usr.id,
reply_markup=markup,
)
except Exception:
await query.message.reply(
res_str,
reply_markup=markup,
disable_web_page_preview=False,
reply_to_message_id=usr.id,
)
await query.message.delete()
else:
await query.message.edit(
res_str, reply_markup=markup, disable_web_page_preview=False
)
await query.answer()
except Exception:
exc = traceback.format_exc()
await query.message.edit_text(f"ERROR:\n{exc}")