# Part of Pull Req #2 by @MaskedVirus | github.com/swatv3nub
import os
import html
import math
import time
import requests
import json
import asyncio
import tempfile
from decimal import Decimal
from datetime import timedelta
from urllib.parse import quote as urlencode
from pyrogram import filters
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from wbb import app, telegraph, session
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):
search = message.text.split(' ', 1)
if len(search) == 1:
await message.delete()
return
else:
search = search[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):
search = message.text.split(' ', 1)
if len(search) == 1:
await message.delete()
return
search = search[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):
search = message.text.split(' ', 1)
if len(search) == 1:
await message.delete()
return
search = search[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):
query = message.text.split(" ")[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]