# Part of Pull Req #2 by @MaskedVirus | github.com/swatv3nub
import time
import requests
from datetime import timedelta
from pyrogram import filters
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from wbb import app, telegraph
from wbb.core.decorators.errors import capture_err
__MODULE__ = "Anime"
__HELP__ = "•Anime uwu•\n\n/anime - search anime on AniList\n /manga - search manga on Anilist\n /char - search character on Anilist\n /nhentai ID - returns the nhentai in telegraph instant preview format."
def shorten(description, info='anilist.co'):
ms_g = ""
if len(description) > 700:
description = description[0:500] + '....'
ms_g += f"\n**Description**: __{description}__[More here]({info})"
else:
ms_g += f"\n**Description**: __{description}__"
return (
ms_g.replace("
", "")
.replace("", "")
.replace("", "")
.replace("", "")
)
def t(milliseconds: int) -> str:
"""Inputs time in milliseconds, to get beautified time,
as string"""
seconds, milliseconds = divmod(int(milliseconds), 1000)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
tmp = ((str(days) + " Days, ") if days else "") + \
((str(hours) + " Hours, ") if hours else "") + \
((str(minutes) + " Minutes, ") if minutes else "") + \
((str(seconds) + " Seconds, ") if seconds else "") + \
((str(milliseconds) + " ms, ") if milliseconds else "")
return tmp[:-2]
airing_query = '''
query ($id: Int,$search: String) {
Media (id: $id, type: ANIME,search: $search) {
id
episodes
title {
romaji
english
native
}
siteUrl
nextAiringEpisode {
airingAt
timeUntilAiring
episode
}
}
}
'''
fav_query = """
query ($id: Int) {
Media (id: $id, type: ANIME) {
id
title {
romaji
english
native
}
}
}
"""
anime_query = '''
query ($id: Int,$search: String) {
Media (id: $id, type: ANIME,search: $search) {
id
idMal
title {
romaji
english
native
}
description (asHtml: false)
startDate{
year
}
episodes
season
type
format
status
duration
siteUrl
studios{
nodes{
name
}
}
trailer{
id
site
thumbnail
}
averageScore
genres
bannerImage
}
}
'''
character_query = """
query ($query: String) {
Character (search: $query) {
id
name {
first
last
full
}
siteUrl
favourites
image {
large
}
description
}
}
"""
manga_query = """
query ($id: Int,$search: String) {
Media (id: $id, type: MANGA,search: $search) {
id
title {
romaji
english
native
}
description (asHtml: false)
startDate{
year
}
type
format
status
siteUrl
averageScore
genres
bannerImage
}
}
"""
def format_bytes(size):
size = int(size)
power = 1024
n = 0
power_labels = {0 : '', 1: 'K', 2: 'M', 3: 'G', 4: 'T'}
while size > power:
size /= power
n += 1
return f"{size:.2f} {power_labels[n]+'B'}"
def return_progress_string(current, total):
filled_length = int(30 * current // total)
return '[' + '=' * filled_length + ' ' * (30 - filled_length) + ']'
def calculate_eta(current, total, start_time):
if not current:
return '00:00:00'
end_time = time.time()
elapsed_time = end_time - start_time
seconds = (elapsed_time * (total / current)) - elapsed_time
thing = ''.join(str(timedelta(seconds=seconds)).split('.')[:-1]).split(', ')
thing[-1] = thing[-1].rjust(8, '0')
return ', '.join(thing)
url = 'https://graphql.anilist.co'
@app.on_message(filters.command("anime"))
@capture_err
async def anime_search(_, message):
if len(message.command) < 2:
await message.delete()
return
search = message.text.split(None, 1)[1]
variables = {'search': search}
json = requests.post(url, json={'query': anime_query, 'variables': variables}).json()[
'data'].get('Media', None)
if json:
msg = f"**{json['title']['romaji']}**(`{json['title']['native']}`)\n**Type**: {json['format']}\n**Status**: {json['status']}\n**Episodes**: {json.get('episodes', 'N/A')}\n**Duration**: {json.get('duration', 'N/A')} Per Ep.\n**Score**: {json['averageScore']}\n**Genres**: `"
for x in json['genres']:
msg += f"{x}, "
msg = msg[:-2] + '`\n'
msg += "**Studios**: `"
for x in json['studios']['nodes']:
msg += f"{x['name']}, "
msg = msg[:-2] + '`\n'
info = json.get('siteUrl')
trailer = json.get('trailer', None)
if trailer:
trailer_id = trailer.get('id', None)
site = trailer.get('site', None)
if site == "youtube":
trailer = 'https://youtu.be/' + trailer_id
description = json.get(
'description', 'N/A').replace('', '').replace('', '').replace('
', '')
msg += shorten(description, info)
image = info.replace('anilist.co/anime/', 'img.anili.st/media/')
if trailer:
buttons = [
[InlineKeyboardButton("More Info", url=info),
InlineKeyboardButton("Trailer", url=trailer)]
]
else:
buttons = [
[InlineKeyboardButton("More Info", url=info)]
]
if image:
try:
await message.reply_photo(image, caption=msg, reply_markup=InlineKeyboardMarkup(buttons))
except:
msg += f" [✔️️]({image})"
await message.edit(msg)
else:
await message.edit(msg)
@app.on_message(filters.command("manga"))
@capture_err
async def manga_search(_, message):
if len(message.command) < 2:
await message.delete()
return
search = message.text.split(None, 1)[1]
variables = {'search': search}
json = requests.post(url, json={'query': manga_query, 'variables': variables}).json()[
'data'].get('Media', None)
ms_g = ''
if json:
title, title_native = json['title'].get(
'romaji', False), json['title'].get('native', False)
start_date, status, score = json['startDate'].get('year', False), json.get(
'status', False), json.get('averageScore', False)
if title:
ms_g += f"**{title}**"
if title_native:
ms_g += f"(`{title_native}`)"
if start_date:
ms_g += f"\n**Start Date** - `{start_date}`"
if status:
ms_g += f"\n**Status** - `{status}`"
if score:
ms_g += f"\n**Score** - `{score}`"
ms_g += '\n**Genres** - '
for x in json.get('genres', []):
ms_g += f"{x}, "
ms_g = ms_g[:-2]
image = json.get("bannerImage", False)
ms_g += f"_{json.get('description', None)}_"
if image:
try:
await message.reply_photo(image, caption=ms_g)
except:
ms_g += f" [✔️️]({image})"
await message.reply(ms_g)
else:
await message.reply(ms_g)
@app.on_message(filters.command("char"))
@capture_err
async def character_search(_, message):
if len(message.command) < 2:
await message.delete()
return
search = message.text.split(None, 1)[1]
variables = {'query': search}
json = requests.post(url, json={'query': character_query, 'variables': variables}).json()[
'data'].get('Character', None)
if json:
ms_g = f"**{json.get('name').get('full')}**(`{json.get('name').get('native')}`)\n"
description = f"{json['description']}"
site_url = json.get('siteUrl')
ms_g += shorten(description, site_url)
image = json.get('image', None)
if image:
image = image.get('large')
await message.reply_photo(image, caption=ms_g)
else:
await message.reply(ms_g)
@app.on_message(filters.command("nhentai"))
@capture_err
async def nhentai(_, message):
if len(message.command) < 2:
await message.delete()
return
query = message.text.split(None, 1)[1]
title, tags, artist, total_pages, post_url, cover_image = nhentai_data(query)
await message.reply_text(
f"{title}\n\nTags:\n{tags}\nArtists:\n{artist}\nPages:\n{total_pages}",
reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
"Read Here",
url=post_url
)
]
]
)
)
def nhentai_data(noombers):
url = f"https://nhentai.net/api/gallery/{noombers}"
res = requests.get(url).json()
pages = res["images"]["pages"]
info = res["tags"]
title = res["title"]["english"]
links = []
tags = ""
artist = ''
total_pages = res['num_pages']
extensions = {
'j':'jpg',
'p':'png',
'g':'gif'
}
for i, x in enumerate(pages):
media_id = res["media_id"]
temp = x['t']
file = f"{i+1}.{extensions[temp]}"
link = f"https://i.nhentai.net/galleries/{media_id}/{file}"
links.append(link)
for i in info:
if i["type"]=="tag":
tag = i['name']
tag = tag.split(" ")
tag = "_".join(tag)
tags+=f"#{tag} "
if i["type"]=="artist":
artist=f"{i['name']} "
post_content = "".join(f"
" for link in links)
post = telegraph.create_page(
f"{title}",
html_content=post_content,
author_name="@WilliamButcherBot",
author_url="https://t.me/WilliamButcherBot"
)
return title,tags,artist,total_pages,post['url'],links[0]