diff --git "a/Mikobot/plugins/anime.py" "b/Mikobot/plugins/anime.py"
deleted file mode 100644--- "a/Mikobot/plugins/anime.py"
+++ /dev/null
@@ -1,5138 +0,0 @@
-# <============================================== IMPORTS =========================================================>
-import asyncio
-import json
-import logging
-import os
-import random
-import re
-import shlex
-import time
-from datetime import datetime
-from os.path import basename
-from time import time
-from traceback import format_exc as err
-from typing import Optional, Tuple
-from urllib.parse import quote
-from uuid import uuid4
-
-import requests
-import urllib3
-from bs4 import BeautifulSoup
-from motor.core import AgnosticClient, AgnosticCollection, AgnosticDatabase
-from motor.motor_asyncio import AsyncIOMotorClient
-from pyrogram import Client, filters
-from pyrogram.enums import ChatMemberStatus, ChatType
-from pyrogram.errors import (
- FloodWait,
- MessageNotModified,
- UserNotParticipant,
- WebpageCurlFailed,
- WebpageMediaEmpty,
-)
-from pyrogram.types import (
- CallbackQuery,
- InlineKeyboardButton,
- InlineKeyboardMarkup,
- InputMediaPhoto,
- Message,
-)
-
-from Mikobot import BOT_USERNAME, MESSAGE_DUMP, MONGO_DB_URI, app
-from Mikobot.utils.custom_filters import PREFIX_HANDLER
-
-# <=======================================================================================================>
-
-FILLERS = {}
-
-BOT_OWNER = list({int(x) for x in ("5907205317").split()})
-
-_MGCLIENT: AgnosticClient = AsyncIOMotorClient(MONGO_DB_URI)
-
-_DATABASE: AgnosticDatabase = _MGCLIENT["MikobotAnime"]
-
-
-def get_collection(name: str) -> AgnosticCollection:
- """Create or Get Collection from your database"""
- return _DATABASE[name]
-
-
-def _close_db() -> None:
- _MGCLIENT.close()
-
-
-GROUPS = get_collection("GROUPS")
-SFW_GRPS = get_collection("SFW_GROUPS")
-DC = get_collection("DISABLED_CMDS")
-AG = get_collection("AIRING_GROUPS")
-CG = get_collection("CRUNCHY_GROUPS")
-SG = get_collection("SUBSPLEASE_GROUPS")
-HD = get_collection("HEADLINES_GROUPS")
-MHD = get_collection("MAL_HEADLINES_GROUPS")
-CHAT_OWNER = ChatMemberStatus.OWNER
-MEMBER = ChatMemberStatus.MEMBER
-ADMINISTRATOR = ChatMemberStatus.ADMINISTRATOR
-
-failed_pic = "https://telegra.ph/file/09733b49f3a9d5b147d21.png"
-no_pic = [
- "https://telegra.ph/file/0d2097f442e816ba3f946.jpg",
- "https://telegra.ph/file/5a152016056308ef63226.jpg",
- "https://telegra.ph/file/d2bf913b18688c59828e9.jpg",
- "https://telegra.ph/file/d53083ea69e84e3b54735.jpg",
- "https://telegra.ph/file/b5eb1e3606b7d2f1b491f.jpg",
-]
-
-
-DOWN_PATH = "Mikobot/downloads/"
-
-AUTH_USERS = get_collection("AUTH_USERS")
-IGNORE = get_collection("IGNORED_USERS")
-PIC_DB = get_collection("PIC_DB")
-GROUPS = get_collection("GROUPS")
-CC = get_collection("CONNECTED_CHANNELS")
-USER_JSON = {}
-USER_WC = {}
-
-LANGUAGES = {
- "af": "afrikaans",
- "sq": "albanian",
- "am": "amharic",
- "ar": "arabic",
- "hy": "armenian",
- "az": "azerbaijani",
- "eu": "basque",
- "be": "belarusian",
- "bn": "bengali",
- "bs": "bosnian",
- "bg": "bulgarian",
- "ca": "catalan",
- "ceb": "cebuano",
- "ny": "chichewa",
- "zh-cn": "chinese (simplified)",
- "zh-tw": "chinese (traditional)",
- "co": "corsican",
- "hr": "croatian",
- "cs": "czech",
- "da": "danish",
- "nl": "dutch",
- "en": "english",
- "eo": "esperanto",
- "et": "estonian",
- "tl": "filipino",
- "fi": "finnish",
- "fr": "french",
- "fy": "frisian",
- "gl": "galician",
- "ka": "georgian",
- "de": "german",
- "el": "greek",
- "gu": "gujarati",
- "ht": "haitian creole",
- "ha": "hausa",
- "haw": "hawaiian",
- "iw": "hebrew",
- "he": "hebrew",
- "hi": "hindi",
- "hmn": "hmong",
- "hu": "hungarian",
- "is": "icelandic",
- "ig": "igbo",
- "id": "indonesian",
- "ga": "irish",
- "it": "italian",
- "ja": "japanese",
- "jw": "javanese",
- "kn": "kannada",
- "kk": "kazakh",
- "km": "khmer",
- "ko": "korean",
- "ku": "kurdish (kurmanji)",
- "ky": "kyrgyz",
- "lo": "lao",
- "la": "latin",
- "lv": "latvian",
- "lt": "lithuanian",
- "lb": "luxembourgish",
- "mk": "macedonian",
- "mg": "malagasy",
- "ms": "malay",
- "ml": "malayalam",
- "mt": "maltese",
- "mi": "maori",
- "mr": "marathi",
- "mn": "mongolian",
- "my": "myanmar (burmese)",
- "ne": "nepali",
- "no": "norwegian",
- "or": "odia",
- "ps": "pashto",
- "fa": "persian",
- "pl": "polish",
- "pt": "portuguese",
- "pa": "punjabi",
- "ro": "romanian",
- "ru": "russian",
- "sm": "samoan",
- "gd": "scots gaelic",
- "sr": "serbian",
- "st": "sesotho",
- "sn": "shona",
- "sd": "sindhi",
- "si": "sinhala",
- "sk": "slovak",
- "sl": "slovenian",
- "so": "somali",
- "es": "spanish",
- "su": "sundanese",
- "sw": "swahili",
- "sv": "swedish",
- "tg": "tajik",
- "ta": "tamil",
- "tt": "tatar",
- "te": "telugu",
- "th": "thai",
- "tr": "turkish",
- "tk": "turkmen",
- "uk": "ukrainian",
- "ur": "urdu",
- "ug": "uyghur",
- "uz": "uzbek",
- "vi": "vietnamese",
- "cy": "welsh",
- "xh": "xhosa",
- "yi": "yiddish",
- "yo": "yoruba",
- "zu": "zulu",
-}
-
-DEFAULT_SERVICE_URLS = (
- "translate.google.ac",
- "translate.google.ad",
- "translate.google.ae",
- "translate.google.al",
- "translate.google.am",
- "translate.google.as",
- "translate.google.at",
- "translate.google.az",
- "translate.google.ba",
- "translate.google.be",
- "translate.google.bf",
- "translate.google.bg",
- "translate.google.bi",
- "translate.google.bj",
- "translate.google.bs",
- "translate.google.bt",
- "translate.google.by",
- "translate.google.ca",
- "translate.google.cat",
- "translate.google.cc",
- "translate.google.cd",
- "translate.google.cf",
- "translate.google.cg",
- "translate.google.ch",
- "translate.google.ci",
- "translate.google.cl",
- "translate.google.cm",
- "translate.google.cn",
- "translate.google.co.ao",
- "translate.google.co.bw",
- "translate.google.co.ck",
- "translate.google.co.cr",
- "translate.google.co.id",
- "translate.google.co.il",
- "translate.google.co.in",
- "translate.google.co.jp",
- "translate.google.co.ke",
- "translate.google.co.kr",
- "translate.google.co.ls",
- "translate.google.co.ma",
- "translate.google.co.mz",
- "translate.google.co.nz",
- "translate.google.co.th",
- "translate.google.co.tz",
- "translate.google.co.ug",
- "translate.google.co.uk",
- "translate.google.co.uz",
- "translate.google.co.ve",
- "translate.google.co.vi",
- "translate.google.co.za",
- "translate.google.co.zm",
- "translate.google.co.zw",
- "translate.google.co",
- "translate.google.com.af",
- "translate.google.com.ag",
- "translate.google.com.ai",
- "translate.google.com.ar",
- "translate.google.com.au",
- "translate.google.com.bd",
- "translate.google.com.bh",
- "translate.google.com.bn",
- "translate.google.com.bo",
- "translate.google.com.br",
- "translate.google.com.bz",
- "translate.google.com.co",
- "translate.google.com.cu",
- "translate.google.com.cy",
- "translate.google.com.do",
- "translate.google.com.ec",
- "translate.google.com.eg",
- "translate.google.com.et",
- "translate.google.com.fj",
- "translate.google.com.gh",
- "translate.google.com.gi",
- "translate.google.com.gt",
- "translate.google.com.hk",
- "translate.google.com.jm",
- "translate.google.com.kh",
- "translate.google.com.kw",
- "translate.google.com.lb",
- "translate.google.com.lc",
- "translate.google.com.ly",
- "translate.google.com.mm",
- "translate.google.com.mt",
- "translate.google.com.mx",
- "translate.google.com.my",
- "translate.google.com.na",
- "translate.google.com.ng",
- "translate.google.com.ni",
- "translate.google.com.np",
- "translate.google.com.om",
- "translate.google.com.pa",
- "translate.google.com.pe",
- "translate.google.com.pg",
- "translate.google.com.ph",
- "translate.google.com.pk",
- "translate.google.com.pr",
- "translate.google.com.py",
- "translate.google.com.qa",
- "translate.google.com.sa",
- "translate.google.com.sb",
- "translate.google.com.sg",
- "translate.google.com.sl",
- "translate.google.com.sv",
- "translate.google.com.tj",
- "translate.google.com.tr",
- "translate.google.com.tw",
- "translate.google.com.ua",
- "translate.google.com.uy",
- "translate.google.com.vc",
- "translate.google.com.vn",
- "translate.google.com",
- "translate.google.cv",
- "translate.google.cx",
- "translate.google.cz",
- "translate.google.de",
- "translate.google.dj",
- "translate.google.dk",
- "translate.google.dm",
- "translate.google.dz",
- "translate.google.ee",
- "translate.google.es",
- "translate.google.eu",
- "translate.google.fi",
- "translate.google.fm",
- "translate.google.fr",
- "translate.google.ga",
- "translate.google.ge",
- "translate.google.gf",
- "translate.google.gg",
- "translate.google.gl",
- "translate.google.gm",
- "translate.google.gp",
- "translate.google.gr",
- "translate.google.gy",
- "translate.google.hn",
- "translate.google.hr",
- "translate.google.ht",
- "translate.google.hu",
- "translate.google.ie",
- "translate.google.im",
- "translate.google.io",
- "translate.google.iq",
- "translate.google.is",
- "translate.google.it",
- "translate.google.je",
- "translate.google.jo",
- "translate.google.kg",
- "translate.google.ki",
- "translate.google.kz",
- "translate.google.la",
- "translate.google.li",
- "translate.google.lk",
- "translate.google.lt",
- "translate.google.lu",
- "translate.google.lv",
- "translate.google.md",
- "translate.google.me",
- "translate.google.mg",
- "translate.google.mk",
- "translate.google.ml",
- "translate.google.mn",
- "translate.google.ms",
- "translate.google.mu",
- "translate.google.mv",
- "translate.google.mw",
- "translate.google.ne",
- "translate.google.nf",
- "translate.google.nl",
- "translate.google.no",
- "translate.google.nr",
- "translate.google.nu",
- "translate.google.pl",
- "translate.google.pn",
- "translate.google.ps",
- "translate.google.pt",
- "translate.google.ro",
- "translate.google.rs",
- "translate.google.ru",
- "translate.google.rw",
- "translate.google.sc",
- "translate.google.se",
- "translate.google.sh",
- "translate.google.si",
- "translate.google.sk",
- "translate.google.sm",
- "translate.google.sn",
- "translate.google.so",
- "translate.google.sr",
- "translate.google.st",
- "translate.google.td",
- "translate.google.tg",
- "translate.google.tk",
- "translate.google.tl",
- "translate.google.tm",
- "translate.google.tn",
- "translate.google.to",
- "translate.google.tt",
- "translate.google.us",
- "translate.google.vg",
- "translate.google.vu",
- "translate.google.ws",
-)
-log = logging.getLogger(__name__)
-log.addHandler(logging.NullHandler())
-
-urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
-
-URLS_SUFFIX = [
- re.search("translate.google.(.*)", url.strip()).group(1)
- for url in DEFAULT_SERVICE_URLS
-]
-URL_SUFFIX_DEFAULT = "cn"
-
-
-def rand_key():
- return str(uuid4())[:8]
-
-
-def control_user(func):
- async def wrapper(_, message: Message):
- msg = json.loads(str(message))
- gid = msg["chat"]["id"]
- gidtype = msg["chat"]["type"]
- if gidtype in [ChatType.SUPERGROUP, ChatType.GROUP] and not (
- await GROUPS.find_one({"_id": gid})
- ):
- try:
- gidtitle = msg["chat"]["username"]
- except KeyError:
- gidtitle = msg["chat"]["title"]
- await GROUPS.insert_one({"_id": gid, "grp": gidtitle})
- await clog(
- "Mikobot",
- f"Bot added to a new group\n\n{gidtitle}\nID: `{gid}`",
- "NEW_GROUP",
- )
- try:
- user = msg["from_user"]["id"]
- except KeyError:
- user = msg["chat"]["id"]
- if await IGNORE.find_one({"_id": user}):
- return
- nut = time()
- if user not in BOT_OWNER:
- try:
- out = USER_JSON[user]
- if nut - out < 1.2:
- USER_WC[user] += 1
- if USER_WC[user] == 3:
- await message.reply_text(
- ("Stop spamming bot!!!" + "\nElse you will be blacklisted"),
- )
- await clog("Mikobot", f"UserID: {user}", "SPAM")
- if USER_WC[user] == 5:
- await IGNORE.insert_one({"_id": user})
- await message.reply_text(
- (
- "You have been exempted from using this bot "
- + "now due to spamming 5 times consecutively!!!"
- + "\nTo remove restriction plead to "
- + "@ProjectCodeXSupport"
- )
- )
- await clog("Mikobot", f"UserID: {user}", "BAN")
- return
- await asyncio.sleep(USER_WC[user])
- else:
- USER_WC[user] = 0
- except KeyError:
- pass
- USER_JSON[user] = nut
- try:
- await func(_, message, msg)
- except FloodWait as e:
- await asyncio.sleep(e.x + 5)
- except MessageNotModified:
- pass
- except Exception:
- e = err()
- reply_msg = None
- if func.__name__ == "trace_bek":
- reply_msg = message.reply_to_message
- try:
- await clog(
- "Mikobot",
- "Message:\n" + msg["text"] + "\n\n" + "```" + e + "```",
- "COMMAND",
- msg=message,
- replied=reply_msg,
- )
- except Exception:
- await clog("Mikobot", e, "FAILURE", msg=message)
-
- return wrapper
-
-
-def check_user(func):
- async def wrapper(_, c_q: CallbackQuery):
- cq = json.loads(str(c_q))
- user = cq["from_user"]["id"]
- if await IGNORE.find_one({"_id": user}):
- return
- cqowner_is_ch = False
- cqowner = cq["data"].split("_").pop()
- if "-100" in cqowner:
- cqowner_is_ch = True
- ccdata = await CC.find_one({"_id": cqowner})
- if ccdata and ccdata["usr"] == user:
- user_valid = True
- else:
- user_valid = False
- if user in BOT_OWNER or user == int(cqowner):
- if user not in BOT_OWNER:
- nt = time()
- try:
- ot = USER_JSON[user]
- if nt - ot < 1.4:
- await c_q.answer(
- ("Stop spamming bot!!!\n" + "Else you will be blacklisted"),
- show_alert=True,
- )
- await clog("Mikobot", f"UserID: {user}", "SPAM")
- except KeyError:
- pass
- USER_JSON[user] = nt
- try:
- await func(_, c_q, cq)
- except FloodWait as e:
- await asyncio.sleep(e.x + 5)
- except MessageNotModified:
- pass
- except Exception:
- e = err()
- reply_msg = None
- if func.__name__ == "tracemoe_btn":
- reply_msg = c_q.message.reply_to_message
- try:
- await clog(
- "Mikobot",
- "Callback:\n" + cq["data"] + "\n\n" + "```" + e + "```",
- "CALLBACK",
- cq=c_q,
- replied=reply_msg,
- )
- except Exception:
- await clog("Mikobot", e, "FAILURE", cq=c_q)
- else:
- if cqowner_is_ch:
- if user_valid:
- try:
- await func(_, c_q, cq)
- except FloodWait as e:
- await asyncio.sleep(e.x + 5)
- except MessageNotModified:
- pass
- except Exception:
- e = err()
- reply_msg = None
- if func.__name__ == "tracemoe_btn":
- reply_msg = c_q.message.reply_to_message
- try:
- await clog(
- "Mikobot",
- "Callback:\n" + cq["data"] + "\n\n" + "```" + e + "```",
- "CALLBACK_ANON",
- cq=c_q,
- replied=reply_msg,
- )
- except Exception:
- await clog("Mikobot", e, "FAILURE", cq=c_q)
- else:
- await c_q.answer(
- (
- "No one can click buttons on queries made by "
- + "channels unless connected with /aniconnect!!!"
- ),
- show_alert=True,
- )
- else:
- await c_q.answer(
- "Not your query!!!",
- show_alert=True,
- )
-
- return wrapper
-
-
-async def media_to_image(client: app, message: Message, x: Message, replied: Message):
- if not (replied.photo or replied.sticker or replied.animation or replied.video):
- await x.edit_text("Media Type Is Invalid !")
- await asyncio.sleep(5)
- await x.delete()
- return
- media = replied.photo or replied.sticker or replied.animation or replied.video
- if not os.path.isdir(DOWN_PATH):
- os.makedirs(DOWN_PATH)
- dls = await client.download_media(
- media,
- file_name=DOWN_PATH + rand_key(),
- )
- dls_loc = os.path.join(DOWN_PATH, os.path.basename(dls))
- if replied.sticker and replied.sticker.file_name.endswith(".tgs"):
- png_file = os.path.join(DOWN_PATH, f"{rand_key()}.png")
- cmd = (
- f"lottie_convert.py --frame 0 -if lottie " + f"-of png {dls_loc} {png_file}"
- )
- stdout, stderr = (await runcmd(cmd))[:2]
- os.remove(dls_loc)
- if not os.path.lexists(png_file):
- await x.edit_text("This sticker is Gey, Task Failed Successfully ≧ω≦")
- await asyncio.sleep(5)
- await x.delete()
- raise Exception(stdout + stderr)
- dls_loc = png_file
- elif replied.sticker and replied.sticker.file_name.endswith(".webp"):
- stkr_file = os.path.join(DOWN_PATH, f"{rand_key()}.png")
- os.rename(dls_loc, stkr_file)
- if not os.path.lexists(stkr_file):
- await x.edit_text("```Sticker not found...```")
- await asyncio.sleep(5)
- await x.delete()
- return
- dls_loc = stkr_file
- elif replied.animation or replied.video:
- await x.edit_text("`Converting Media To Image ...`")
- jpg_file = os.path.join(DOWN_PATH, f"{rand_key()}.jpg")
- await take_screen_shot(dls_loc, 0, jpg_file)
- os.remove(dls_loc)
- if not os.path.lexists(jpg_file):
- await x.edit_text("This Gif is Gey (。ì _ í。), Task Failed Successfully !")
- await asyncio.sleep(5)
- await x.delete()
- return
- dls_loc = jpg_file
- return dls_loc
-
-
-async def runcmd(cmd: str) -> Tuple[str, str, int, int]:
- """run command in terminal"""
- args = shlex.split(cmd)
- process = await asyncio.create_subprocess_exec(
- *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
- )
- stdout, stderr = await process.communicate()
- return (
- stdout.decode("utf-8", "replace").strip(),
- stderr.decode("utf-8", "replace").strip(),
- process.returncode,
- process.pid,
- )
-
-
-async def take_screen_shot(
- video_file: str, duration: int, path: str = ""
-) -> Optional[str]:
- """take a screenshot"""
- print(
- "[[[Extracting a frame from %s ||| Video duration => %s]]]",
- video_file,
- duration,
- )
- thumb_image_path = path or os.path.join(DOWN_PATH, f"{basename(video_file)}.jpg")
- command = (
- f"ffmpeg -ss {duration} " + f'-i "{video_file}" -vframes 1 "{thumb_image_path}"'
- )
- err = (await runcmd(command))[1]
- if err:
- print(err)
- return thumb_image_path if os.path.exists(thumb_image_path) else None
-
-
-async def get_user_from_channel(cid):
- try:
- k = (await CC.find_one({"_id": str(cid)}))["usr"]
- return k
- except TypeError:
- return None
-
-
-async def return_json_senpai(
- query: str, vars_: dict, auth: bool = False, user: int = None
-):
- url = "https://graphql.anilist.co"
- headers = None
- if auth:
- headers = {
- "Authorization": (
- "Bearer " + str((await AUTH_USERS.find_one({"id": int(user)}))["token"])
- ),
- "Content-Type": "application/json",
- "Accept": "application/json",
- }
- return requests.post(
- url, json={"query": query, "variables": vars_}, headers=headers
- ).json()
-
-
-def cflag(country):
- if country == "JP":
- return "\U0001F1EF\U0001F1F5"
- if country == "CN":
- return "\U0001F1E8\U0001F1F3"
- if country == "KR":
- return "\U0001F1F0\U0001F1F7"
- if country == "TW":
- return "\U0001F1F9\U0001F1FC"
-
-
-def pos_no(no):
- ep_ = list(str(no))
- x = ep_.pop()
- if ep_ != [] and ep_.pop() == "1":
- return "th"
- th = "st" if x == "1" else "nd" if x == "2" else "rd" if x == "3" else "th"
- return th
-
-
-def make_it_rw(time_stamp):
- """Converting Time Stamp to Readable Format"""
- seconds, milliseconds = divmod(int(time_stamp), 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]
-
-
-async def clog(
- name: str,
- text: str,
- tag: str,
- msg: Message = None,
- cq: CallbackQuery = None,
- replied: Message = None,
- file: str = None,
- send_as_file: str = None,
-):
- log = f"#{name.upper()} #{tag.upper()}\n\n{text}"
- data = ""
- if msg:
- data += str(msg)
- data += "\n\n\n\n"
- if cq:
- data += str(cq)
- data += "\n\n\n\n"
- await app.send_message(chat_id=MESSAGE_DUMP, text=log)
- if msg or cq:
- with open("query_data.txt", "x") as output:
- output.write(data)
- await app.send_document(MESSAGE_DUMP, "query_data.txt")
- os.remove("query_data.txt")
- if replied:
- media = replied.photo or replied.sticker or replied.animation or replied.video
- media_path = await app.download_media(media)
- await app.send_document(MESSAGE_DUMP, media_path)
- if file:
- await app.send_document(MESSAGE_DUMP, file)
- if send_as_file:
- with open("dataInQuestio.txt", "x") as text_file:
- text_file.write()
- await app.send_document(MESSAGE_DUMP, "dataInQuestio.txt")
- os.remove("dataInQuestio.txt")
-
-
-def get_btns(
- media,
- user: int,
- result: list,
- lsqry: str = None,
- lspage: int = None,
- auth: bool = False,
- sfw: str = "False",
-):
- buttons = []
- qry = f"_{lsqry}" if lsqry is not None else ""
- pg = f"_{lspage}" if lspage is not None else ""
- if media == "ANIME" and sfw == "False":
- buttons.append(
- [
- InlineKeyboardButton(
- text="Characters",
- callback_data=(
- f"char_{result[2][0]}_ANI" + f"{qry}{pg}_{str(auth)}_1_{user}"
- ),
- ),
- InlineKeyboardButton(
- text="Description",
- callback_data=(
- f"desc_{result[2][0]}_ANI" + f"{qry}{pg}_{str(auth)}_{user}"
- ),
- ),
- InlineKeyboardButton(
- text="List Series",
- callback_data=(
- f"ls_{result[2][0]}_ANI" + f"{qry}{pg}_{str(auth)}_{user}"
- ),
- ),
- ]
- )
- if media == "CHARACTER":
- buttons.append(
- [
- InlineKeyboardButton(
- "Description",
- callback_data=(
- f"desc_{result[2][0]}_CHAR" + f"{qry}{pg}_{str(auth)}_{user}"
- ),
- )
- ]
- )
- buttons.append(
- [
- InlineKeyboardButton(
- "List Series",
- callback_data=f"lsc_{result[2][0]}{qry}{pg}_{str(auth)}_{user}",
- )
- ]
- )
- if media == "SCHEDULED":
- if result[0] != 0 and result[0] != 6:
- buttons.append(
- [
- InlineKeyboardButton(
- str(day_(result[0] - 1)),
- callback_data=f"sched_{result[0]-1}_{user}",
- ),
- InlineKeyboardButton(
- str(day_(result[0] + 1)),
- callback_data=f"sched_{result[0]+1}_{user}",
- ),
- ]
- )
- if result[0] == 0:
- buttons.append(
- [
- InlineKeyboardButton(
- str(day_(result[0] + 1)),
- callback_data=f"sched_{result[0]+1}_{user}",
- )
- ]
- )
- if result[0] == 6:
- buttons.append(
- [
- InlineKeyboardButton(
- str(day_(result[0] - 1)),
- callback_data=f"sched_{result[0]-1}_{user}",
- )
- ]
- )
- if media == "MANGA" and sfw == "False":
- buttons.append([InlineKeyboardButton("More Info", url=result[1][2])])
- if media == "AIRING" and sfw == "False":
- buttons.append([InlineKeyboardButton("More Info", url=result[1][0])])
- if auth is True and media != "SCHEDULED" and sfw == "False":
- auth_btns = get_auth_btns(media, user, result[2], lspage=lspage, lsqry=lsqry)
- buttons.append(auth_btns)
- if len(result) > 3:
- if result[3] == "None":
- if result[4] != "None":
- buttons.append(
- [
- InlineKeyboardButton(
- text="Sequel",
- callback_data=f"btn_{result[4]}_{str(auth)}_{user}",
- )
- ]
- )
- else:
- if result[4] != "None":
- buttons.append(
- [
- InlineKeyboardButton(
- text="Prequel",
- callback_data=f"btn_{result[3]}_{str(auth)}_{user}",
- ),
- InlineKeyboardButton(
- text="Sequel",
- callback_data=f"btn_{result[4]}_{str(auth)}_{user}",
- ),
- ]
- )
- else:
- buttons.append(
- [
- InlineKeyboardButton(
- text="Prequel",
- callback_data=f"btn_{result[3]}_{str(auth)}_{user}",
- )
- ]
- )
- if (lsqry is not None) and (len(result) != 1):
- if lspage == 1:
- if result[1][1] is True:
- buttons.append(
- [
- InlineKeyboardButton(
- text="Next",
- callback_data=(
- f"page_{media}{qry}_{int(lspage)+1}_{str(auth)}_{user}"
- ),
- )
- ]
- )
- else:
- pass
- elif lspage != 1:
- if result[1][1] is False:
- buttons.append(
- [
- InlineKeyboardButton(
- text="Prev",
- callback_data=(
- f"page_{media}{qry}_{int(lspage)-1}_{str(auth)}_{user}"
- ),
- )
- ]
- )
- else:
- buttons.append(
- [
- InlineKeyboardButton(
- text="Prev",
- callback_data=(
- f"page_{media}{qry}_{int(lspage)-1}_{str(auth)}_{user}"
- ),
- ),
- InlineKeyboardButton(
- text="Next",
- callback_data=(
- f"page_{media}{qry}_{int(lspage)+1}_{str(auth)}_{user}"
- ),
- ),
- ]
- )
- return InlineKeyboardMarkup(buttons)
-
-
-def get_auth_btns(media, user, data, lsqry: str = None, lspage: int = None):
- btn = []
- qry = f"_{lsqry}" if lsqry is not None else ""
- pg = f"_{lspage}" if lspage is not None else ""
- if media == "CHARACTER":
- btn.append(
- InlineKeyboardButton(
- text=("Add to Favs" if data[1] is not True else "Remove from Favs"),
- callback_data=f"fav_{media}_{data[0]}{qry}{pg}_{user}",
- )
- )
- else:
- btn.append(
- InlineKeyboardButton(
- text=("Add to Favs" if data[3] is not True else "Remove from Favs"),
- callback_data=f"fav_{media}_{data[0]}{qry}{pg}_{user}",
- )
- )
- btn.append(
- InlineKeyboardButton(
- text="Add to List" if data[1] is False else "Update in List",
- callback_data=(
- f"lsadd_{media}_{data[0]}{qry}{pg}_{user}"
- if data[1] is False
- else f"lsupdt_{media}_{data[0]}_{data[2]}{qry}{pg}_{user}"
- ),
- )
- )
- return btn
-
-
-def day_(x: int):
- if x == 0:
- return "Monday"
- if x == 1:
- return "Tuesday"
- if x == 2:
- return "Wednesday"
- if x == 3:
- return "Thursday"
- if x == 4:
- return "Friday"
- if x == 5:
- return "Saturday"
- if x == 6:
- return "Sunday"
-
-
-def season_(future: bool = False):
- k = datetime.now()
- m = k.month
- if future:
- m = m + 3
- y = k.year
- if m > 12:
- y = y + 1
- if m in [1, 2, 3] or m > 12:
- return "WINTER", y
- if m in [4, 5, 6]:
- return "SPRING", y
- if m in [7, 8, 9]:
- return "SUMMER", y
- if m in [10, 11, 12]:
- return "FALL", y
-
-
-class google_new_transError(Exception):
- """Exception that uses context to present a meaningful error message"""
-
- def __init__(self, msg=None, **kwargs):
- self.tts = kwargs.pop("tts", None)
- self.rsp = kwargs.pop("response", None)
- if msg:
- self.msg = msg
- elif self.tts is not None:
- self.msg = self.infer_msg(self.tts, self.rsp)
- else:
- self.msg = None
- super(google_new_transError, self).__init__(self.msg)
-
- def infer_msg(self, tts, rsp=None):
- cause = "Unknown"
-
- if rsp is None:
- premise = "Failed to connect"
-
- return "{}. Probable cause: {}".format(premise, "timeout")
- # if tts.tld != 'com':
- # host = _translate_url(tld=tts.tld)
- # cause = "Host '{}' is not reachable".format(host)
-
- else:
- status = rsp.status_code
- reason = rsp.reason
-
- premise = "{:d} ({}) from TTS API".format(status, reason)
-
- if status == 403:
- cause = "Bad token or upstream API changes"
- elif status == 200 and not tts.lang_check:
- cause = (
- "No audio stream in response. Unsupported language '%s'"
- % self.tts.lang
- )
- elif status >= 500:
- cause = "Uptream API error. Try again later."
-
- return "{}. Probable cause: {}".format(premise, cause)
-
-
-class google_translator:
- """
- You can use 108 language in target and source,details view LANGUAGES.
- Target language: like 'en'、'zh'、'th'...
- :param url_suffix: The source text(s) to be translated. Batch translation is supported via sequence input.
- The value should be one of the url_suffix listed in : `DEFAULT_SERVICE_URLS`
- :type url_suffix: UTF-8 :class:`str`; :class:`unicode`; string sequence (list, tuple, iterator, generator)
- :param text: The source text(s) to be translated.
- :type text: UTF-8 :class:`str`; :class:`unicode`;
- :param lang_tgt: The language to translate the source text into.
- The value should be one of the language codes listed in : `LANGUAGES`
- :type lang_tgt: :class:`str`; :class:`unicode`
- :param lang_src: The language of the source text.
- The value should be one of the language codes listed in :const:`googletrans.LANGUAGES`
- If a language is not specified,
- the system will attempt to identify the source language automatically.
- :type lang_src: :class:`str`; :class:`unicode`
- :param timeout: Timeout Will be used for every request.
- :type timeout: number or a double of numbers
- :param proxies: proxies Will be used for every request.
- :type proxies: class : dict; like: {'http': 'http:171.112.169.47:19934/', 'https': 'https:171.112.169.47:19934/'}
- """
-
- def __init__(self, url_suffix="cn", timeout=5, proxies=None):
- self.proxies = proxies
- if url_suffix not in URLS_SUFFIX:
- self.url_suffix = URL_SUFFIX_DEFAULT
- else:
- self.url_suffix = url_suffix
- url_base = "https://translate.google.{}".format(self.url_suffix)
- self.url = url_base + "/_/TranslateWebserverUi/data/batchexecute"
- self.timeout = timeout
-
- def _package_rpc(self, text, lang_src="auto", lang_tgt="auto"):
- GOOGLE_TTS_RPC = ["MkEWBc"]
- parameter = [[text.strip(), lang_src, lang_tgt, True], [1]]
- escaped_parameter = json.dumps(parameter, separators=(",", ":"))
- rpc = [[[random.choice(GOOGLE_TTS_RPC), escaped_parameter, None, "generic"]]]
- espaced_rpc = json.dumps(rpc, separators=(",", ":"))
- # text_urldecode = quote(text.strip())
- freq_initial = "f.req={}&".format(quote(espaced_rpc))
- freq = freq_initial
- return freq
-
- def translate(self, text, lang_tgt="auto", lang_src="auto", pronounce=False):
- try:
- lang = LANGUAGES[lang_src]
- except Exception:
- lang_src = "auto"
- try:
- lang = LANGUAGES[lang_tgt]
- except Exception:
- lang_src = "auto"
- text = str(text)
- if len(text) >= 5000:
- return "Warning: Can only detect less than 5000 characters"
- if len(text) == 0:
- return ""
- headers = {
- "Referer": "http://translate.google.{}/".format(self.url_suffix),
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) "
- "AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/47.0.2526.106 Safari/537.36",
- "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
- }
- freq = self._package_rpc(text, lang_src, lang_tgt)
- response = requests.Request(
- method="POST",
- url=self.url,
- data=freq,
- headers=headers,
- )
- try:
- if self.proxies is None or type(self.proxies) != dict:
- self.proxies = {}
- with requests.Session() as s:
- s.proxies = self.proxies
- r = s.send(
- request=response.prepare(), verify=False, timeout=self.timeout
- )
- for line in r.iter_lines(chunk_size=1024):
- decoded_line = line.decode("utf-8")
- if "MkEWBc" in decoded_line:
- try:
- response = decoded_line
- response = json.loads(response)
- response = list(response)
- response = json.loads(response[0][2])
- response_ = list(response)
- response = response_[1][0]
- if len(response) == 1:
- if len(response[0]) > 5:
- sentences = response[0][5]
- else: ## only url
- sentences = response[0][0]
- if pronounce is False:
- return sentences
- elif pronounce == True:
- return [sentences, None, None]
- translate_text = ""
- for sentence in sentences:
- sentence = sentence[0]
- translate_text += sentence.strip() + " "
- translate_text = translate_text
- if pronounce is False:
- return translate_text
- elif pronounce == True:
- pronounce_src = response_[0][0]
- pronounce_tgt = response_[1][0][0][1]
- return [translate_text, pronounce_src, pronounce_tgt]
- elif len(response) == 2:
- sentences = []
- for i in response:
- sentences.append(i[0])
- if pronounce is False:
- return sentences
- elif pronounce == True:
- pronounce_src = response_[0][0]
- pronounce_tgt = response_[1][0][0][1]
- return [sentences, pronounce_src, pronounce_tgt]
- except Exception as e:
- raise e
- r.raise_for_status()
- except requests.exceptions.ConnectTimeout as e:
- raise e
- except requests.exceptions.HTTPError as e:
- # Request successful, bad response
- raise google_new_transError(tts=self, response=r)
- except requests.exceptions.RequestException as e:
- # Request failed
- raise google_new_transError(tts=self)
-
- def detect(self, text):
- text = str(text)
- if len(text) >= 5000:
- return log.debug("Warning: Can only detect less than 5000 characters")
- if len(text) == 0:
- return ""
- headers = {
- "Referer": "http://translate.google.{}/".format(self.url_suffix),
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) "
- "AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/47.0.2526.106 Safari/537.36",
- "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
- }
- freq = self._package_rpc(text)
- response = requests.Request(
- method="POST", url=self.url, data=freq, headers=headers
- )
- try:
- if self.proxies is None or type(self.proxies) != dict:
- self.proxies = {}
- with requests.Session() as s:
- s.proxies = self.proxies
- r = s.send(
- request=response.prepare(), verify=False, timeout=self.timeout
- )
-
- for line in r.iter_lines(chunk_size=1024):
- decoded_line = line.decode("utf-8")
- if "MkEWBc" in decoded_line:
- # regex_str = r"\[\[\"wrb.fr\",\"MkEWBc\",\"\[\[(.*).*?,\[\[\["
- try:
- # data_got = re.search(regex_str,decoded_line).group(1)
- response = decoded_line
- response = json.loads(response)
- response = list(response)
- response = json.loads(response[0][2])
- response = list(response)
- detect_lang = response[0][2]
- except Exception:
- raise Exception
- # data_got = data_got.split('\\\"]')[0]
- return [detect_lang, LANGUAGES[detect_lang.lower()]]
- r.raise_for_status()
- except requests.exceptions.HTTPError as e:
- # Request successful, bad response
- log.debug(str(e))
- raise google_new_transError(tts=self, response=r)
- except requests.exceptions.RequestException as e:
- # Request failed
- log.debug(str(e))
- raise google_new_transError(tts=self)
-
-
-async def uidata(id_):
- data = await GUI.find_one({"_id": str(id_)})
- if data is not None:
- bullet = str(data["bl"]) + " "
- if data["bl"] is None:
- bullet = ""
- return bullet, data["cs"]
- return ["➤ ", "UPPER"]
-
-
-async def get_ui_text(case):
- if case == "UPPER":
- return [
- "SOURCE",
- "TYPE",
- "SCORE",
- "DURATION",
- "USER DATA",
- "ADULT RATED",
- "STATUS",
- "GENRES",
- "TAGS",
- "SEQUEL",
- "PREQUEL",
- "NEXT AIRING",
- "DESCRIPTION",
- "VOLUMES",
- "CHAPTERS",
- ]
- else:
- return [
- "Source",
- "Type",
- "Score",
- "Duration",
- "User Data",
- "Adult Rated",
- "Status",
- "Genres",
- "Tags",
- "Sequel",
- "Prequel",
- "Next Airing",
- "Description",
- "Volumes",
- "Chapters",
- ]
-
-
-tr = google_translator()
-ANIME_DB, MANGA_DB, CHAR_DB, STUDIO_DB, AIRING_DB = {}, {}, {}, {}, {}
-GUI = get_collection("GROUP_UI")
-
-#### Anilist part ####
-
-ANIME_TEMPLATE = """{name}
-
-**ID | MAL ID:** `{idm}` | `{idmal}`
-{bl}**{psrc}:** `{source}`
-{bl}**{ptype}:** `{formats}`{avscd}{dura}{user_data}
-{status_air}{gnrs_}{tags_}
-
-🎬 {trailer_link}
-📖 Official Site
-
-{additional}"""
-
-
-# GraphQL Queries.
-ANIME_QUERY = """
-query ($id: Int, $idMal:Int, $search: String) {
- Media (id: $id, idMal: $idMal, search: $search, type: ANIME) {
- id
- idMal
- title {
- romaji
- english
- native
- }
- format
- status
- episodes
- duration
- countryOfOrigin
- source (version: 2)
- trailer {
- id
- site
- }
- genres
- tags {
- name
- }
- averageScore
- relations {
- edges {
- node {
- title {
- romaji
- english
- }
- id
- type
- }
- relationType
- }
- }
- nextAiringEpisode {
- timeUntilAiring
- episode
- }
- isAdult
- isFavourite
- mediaListEntry {
- status
- score
- id
- }
- siteUrl
- }
-}
-"""
-
-ISADULT = """
-query ($id: Int) {
- Media (id: $id) {
- isAdult
- }
-}
-"""
-
-BROWSE_QUERY = """
-query ($s: MediaSeason, $y: Int, $sort: [MediaSort]) {
- Page {
- media (season: $s, seasonYear: $y, sort: $sort) {
- title {
- romaji
- }
- format
- }
- }
-}
-"""
-
-FAV_ANI_QUERY = """
-query ($id: Int, $page: Int) {
- User (id: $id) {
- favourites {
- anime (page: $page, perPage: 10) {
- pageInfo {
- lastPage
- hasNextPage
- }
- edges {
- node {
- title {
- romaji
- }
- siteUrl
- }
- }
- }
- }
- }
-}
-"""
-
-FAV_MANGA_QUERY = """
-query ($id: Int, $page: Int) {
- User (id: $id) {
- favourites {
- manga (page: $page, perPage: 10) {
- pageInfo {
- lastPage
- hasNextPage
- }
- edges {
- node {
- title {
- romaji
- }
- siteUrl
- }
- }
- }
- }
- }
-}
-"""
-
-FAV_CHAR_QUERY = """
-query ($id: Int, $page: Int) {
- User (id: $id) {
- favourites {
- characters (page: $page, perPage: 10) {
- pageInfo {
- lastPage
- hasNextPage
- }
- edges {
- node {
- name {
- full
- }
- siteUrl
- }
- }
- }
- }
- }
-}
-"""
-
-VIEWER_QRY = """
-query {
- Viewer {
- id
- name
- siteUrl
- statistics {
- anime {
- count
- minutesWatched
- episodesWatched
- meanScore
- }
- manga {
- count
- chaptersRead
- volumesRead
- meanScore
- }
- }
- }
-}
-"""
-
-USER_QRY = """
-query ($search: String) {
- User (name: $search) {
- id
- name
- siteUrl
- statistics {
- anime {
- count
- minutesWatched
- episodesWatched
- meanScore
- }
- manga {
- count
- chaptersRead
- volumesRead
- meanScore
- }
- }
- }
-}
-"""
-
-ANIME_MUTATION = """
-mutation ($id: Int) {
- ToggleFavourite (animeId: $id) {
- anime {
- pageInfo {
- total
- }
- }
- }
-}
-"""
-
-MANGA_MUTATION = """
-mutation ($id: Int) {
- ToggleFavourite (mangaId: $id) {
- manga {
- pageInfo {
- total
- }
- }
- }
-}
-"""
-
-STUDIO_MUTATION = """
-mutation ($id: Int) {
- ToggleFavourite (studioId: $id) {
- studios {
- pageInfo {
- total
- }
- }
- }
-}
-"""
-
-CHAR_MUTATION = """
-mutation ($id: Int) {
- ToggleFavourite (characterId: $id) {
- characters {
- pageInfo {
- total
- }
- }
- }
-}
-"""
-
-ANILIST_MUTATION = """
-mutation ($id: Int, $status: MediaListStatus) {
- SaveMediaListEntry (mediaId: $id, status: $status) {
- media {
- title {
- romaji
- }
- }
- }
-}
-"""
-
-ANILIST_MUTATION_UP = """
-mutation ($id: [Int], $status: MediaListStatus) {
- UpdateMediaListEntries (ids: $id, status: $status) {
- media {
- title {
- romaji
- }
- }
- }
-}
-"""
-
-ANILIST_MUTATION_DEL = """
-mutation ($id: Int) {
- DeleteMediaListEntry (id: $id) {
- deleted
- }
-}
-"""
-
-AIR_QUERY = """
-query ($search: String, $page: Int) {
- Page (perPage: 1, page: $page) {
- pageInfo {
- total
- hasNextPage
- }
- media (search: $search, type: ANIME) {
- id
- title {
- romaji
- english
- }
- status
- countryOfOrigin
- nextAiringEpisode {
- timeUntilAiring
- episode
- }
- siteUrl
- isFavourite
- isAdult
- mediaListEntry {
- status
- id
- }
- }
- }
-}
-"""
-
-DES_INFO_QUERY = """
-query ($id: Int) {
- Media (id: $id) {
- id
- description (asHtml: false)
- }
-}
-"""
-
-CHA_INFO_QUERY = """
-query ($id: Int, $page: Int) {
- Media (id: $id, type: ANIME) {
- id
- characters (page: $page, perPage: 25, sort: ROLE) {
- pageInfo {
- hasNextPage
- lastPage
- total
- }
- edges {
- node {
- name {
- full
- }
- }
- role
- }
- }
- }
-}
-"""
-
-REL_INFO_QUERY = """
-query ($id: Int) {
- Media (id: $id, type: ANIME) {
- id
- relations {
- edges {
- node {
- title {
- romaji
- }
- type
- }
- relationType
- }
- }
- }
-}
-"""
-
-PAGE_QUERY = """
-query ($search: String, $page: Int) {
- Page (perPage: 1, page: $page) {
- pageInfo {
- total
- hasNextPage
- }
- media (search: $search, type: ANIME) {
- id
- idMal
- title {
- romaji
- english
- native
- }
- format
- status
- episodes
- duration
- countryOfOrigin
- source (version: 2)
- trailer {
- id
- site
- }
- genres
- tags {
- name
- }
- averageScore
- relations {
- edges {
- node {
- title {
- romaji
- english
- }
- type
- }
- relationType
- }
- }
- nextAiringEpisode {
- timeUntilAiring
- episode
- }
- isAdult
- isFavourite
- mediaListEntry {
- status
- score
- id
- }
- siteUrl
- }
- }
-}
-"""
-
-CHARACTER_QUERY = """
-query ($id: Int, $search: String, $page: Int) {
- Page (perPage: 1, page: $page) {
- pageInfo {
- total
- hasNextPage
- }
- characters (id: $id, search: $search) {
- id
- name {
- full
- native
- }
- image {
- large
- }
- media (type: ANIME) {
- edges {
- node {
- title {
- romaji
- }
- type
- }
- voiceActors (language: JAPANESE) {
- name {
- full
- }
- siteUrl
- }
- }
- }
- isFavourite
- siteUrl
- }
- }
-}
-"""
-
-MANGA_QUERY = """
-query ($search: String, $page: Int) {
- Page (perPage: 1, page: $page) {
- pageInfo {
- total
- hasNextPage
- }
- media (search: $search, type: MANGA) {
- id
- title {
- romaji
- english
- native
- }
- format
- countryOfOrigin
- source (version: 2)
- status
- description(asHtml: true)
- chapters
- isFavourite
- mediaListEntry {
- status
- score
- id
- }
- volumes
- averageScore
- siteUrl
- isAdult
- }
- }
-}
-"""
-
-
-DESC_INFO_QUERY = """
-query ($id: Int) {
- Character (id: $id) {
- image {
- large
- }
- description(asHtml: false)
- }
-}
-"""
-
-LS_INFO_QUERY = """
-query ($id: Int) {
- Character (id: $id) {
- image {
- large
- }
- media (page: 1, perPage: 25) {
- nodes {
- title {
- romaji
- english
- }
- type
- }
- }
- }
-}
-"""
-
-ACTIVITY_QUERY = """
-query ($id: Int) {
- Page (perPage: 12) {
- activities (userId: $id, type: MEDIA_LIST, sort: ID_DESC) {
- ...kek
- }
- }
-}
-fragment kek on ListActivity {
- type
- media {
- title {
- romaji
- }
- siteUrl
- }
- progress
- status
-}
-"""
-
-TOP_QUERY = """
-query ($gnr: String, $page: Int) {
- Page (perPage: 15, page: $page) {
- pageInfo {
- lastPage
- total
- hasNextPage
- }
- media (genre: $gnr, sort: SCORE_DESC, type: ANIME) {
- title {
- romaji
- }
- }
- }
-}
-"""
-
-TOPT_QUERY = """
-query ($gnr: String, $page: Int) {
- Page (perPage: 15, page: $page) {
- pageInfo {
- lastPage
- total
- hasNextPage
- }
- media (tag: $gnr, sort: SCORE_DESC, type: ANIME) {
- title {
- romaji
- }
- }
- }
-}
-"""
-
-ALLTOP_QUERY = """
-query ($page: Int) {
- Page (perPage: 15, page: $page) {
- pageInfo {
- lastPage
- total
- hasNextPage
- }
- media (sort: SCORE_DESC, type: ANIME) {
- title {
- romaji
- }
- }
- }
-}
-"""
-
-GET_GENRES = """
-query {
- GenreCollection
-}
-"""
-
-GET_TAGS = """
-query{
- MediaTagCollection {
- name
- isAdult
- }
-}
-"""
-
-RECOMMENDTIONS_QUERY = """
-query ($id: Int) {
- Media (id: $id) {
- recommendations (perPage: 25) {
- edges {
- node {
- mediaRecommendation {
- title {
- romaji
- }
- id
- siteUrl
- }
- }
- }
- }
- }
-}
-"""
-
-STUDIO_QUERY = """
-query ($search: String, $page: Int) {
- Page (page: $page, perPage: 1) {
- pageInfo {
- total
- hasNextPage
- }
- studios (search: $search) {
- id
- name
- siteUrl
- isFavourite
- }
- }
-}
-"""
-
-STUDIO_ANI_QUERY = """
-query ($id: Int, $page: Int) {
- Studio (id: $id) {
- name
- media (page: $page) {
- pageInfo {
- total
- lastPage
- hasNextPage
- }
- edges {
- node {
- title {
- romaji
- }
- seasonYear
- }
- }
- }
- }
-}
-"""
-
-
-async def get_studios(qry, page, user, duser=None, auth: bool = False):
- page = int(page)
- vars_ = {"search": STUDIO_DB[qry], "page": int(page)}
- result = await return_json_senpai(STUDIO_QUERY, vars_, auth, user)
- if result["data"]["Page"]["studios"] == []:
- return ["Not Found"]
- data = result["data"]["Page"]["studios"][0]
- isFav = data["isFavourite"]
- msg = (
- f"**{data['name']}**{', ♥️' if isFav is True else ''}"
- + f"\n\n**ID:** {data['id']}\n[Website]({data['siteUrl']})"
- )
- if not duser:
- duser = user
- btns = []
- btns.append(
- [
- InlineKeyboardButton(
- "List Animes",
- callback_data=f"stuani_1_{data['id']}_{page}_{qry}_{auth}_{duser}",
- )
- ]
- )
- if auth:
- btns.append(
- [
- InlineKeyboardButton(
- "Remove from Favs" if isFav else "Add To Favs",
- callback_data=f"fav_STUDIO_{data['id']}_{qry}_{page}_{duser}",
- )
- ]
- )
- pi = result["data"]["Page"]["pageInfo"]["hasNextPage"]
- if pi is False:
- if int(page) == 1:
- return msg, btns
- else:
- btns.append(
- [
- InlineKeyboardButton(
- "Prev", callback_data=f"pgstudio_{page-1}_{qry}_{auth}_{duser}"
- )
- ]
- )
- else:
- if int(page) == 1:
- btns.append(
- [
- InlineKeyboardButton(
- "Next", callback_data=f"pgstudio_2_{qry}_{auth}_{duser}"
- )
- ]
- )
- else:
- btns.append(
- [
- InlineKeyboardButton(
- "Prev", callback_data=f"pgstudio_{page-1}_{qry}_{auth}_{duser}"
- ),
- InlineKeyboardButton(
- "Next", callback_data=f"pgstudio_{page+1}_{qry}_{auth}_{duser}"
- ),
- ]
- )
- return msg, InlineKeyboardMarkup(btns)
-
-
-async def get_studio_animes(id_, page, qry, rp, user, duser=None, auth: bool = False):
- vars_ = {"id": id_, "page": int(page)}
- result = await return_json_senpai(STUDIO_ANI_QUERY, vars_, auth, user)
- data = result["data"]["Studio"]["media"]["edges"]
- if data == []:
- return ["No results found"]
- msg = f"List of animes by {result['data']['Studio']['name']} studio\n"
- for i in data:
- msg += (
- f"\n⚬ `{i['node']['title']['romaji']}`"
- + f" __({i['node']['seasonYear']})__"
- )
- btns = []
- if not duser:
- duser = user
- pi = result["data"]["Studio"]["media"]["pageInfo"]
- if pi["hasNextPage"] is False:
- if int(page) == 1:
- btns.append(
- [
- InlineKeyboardButton(
- "Back", callback_data=f"pgstudio_{rp}_{qry}_{auth}_{duser}"
- )
- ]
- )
- return msg, btns
- else:
- btns.append(
- [
- InlineKeyboardButton(
- "Prev",
- callback_data=f"stuani_{int(page)-1}_{id_}_{rp}_{qry}_{auth}_{duser}",
- )
- ]
- )
- else:
- if int(page) == 1:
- btns.append(
- [
- InlineKeyboardButton(
- "Next",
- callback_data=f"stuani_2_{id_}_{rp}_{qry}_{auth}_{duser}",
- )
- ]
- )
- else:
- btns.append(
- [
- InlineKeyboardButton(
- "Prev",
- callback_data=f"stuani_{int(page)-1}_{id_}_{rp}_{qry}_{auth}_{duser}",
- ),
- InlineKeyboardButton(
- "Next",
- callback_data=f"stuani_{int(page)+1}_{id_}_{rp}_{qry}_{auth}_{duser}",
- ),
- ]
- )
- btns.append(
- [
- InlineKeyboardButton(
- "Back", callback_data=f"pgstudio_{rp}_{qry}_{auth}_{duser}"
- )
- ]
- )
- return msg, InlineKeyboardMarkup(btns)
-
-
-async def get_all_tags(text: str = None):
- vars_ = {}
- result = await return_json_senpai(GET_TAGS, vars_, auth=False, user=None)
- msg = "**Tags List:**\n\n`"
- kek = []
- for i in result["data"]["MediaTagCollection"]:
- if text is not None and "nsfw" in text:
- if str(i["isAdult"]) != "False":
- kek.append(i["name"])
- else:
- if str(i["isAdult"]) == "False":
- kek.append(i["name"])
- msg += ", ".join(kek)
- msg += "`"
- return msg
-
-
-async def get_all_genres():
- vars_ = {}
- result = await return_json_senpai(GET_GENRES, vars_, auth=False)
- msg = "**Genres List:**\n\n"
- for i in result["data"]["GenreCollection"]:
- msg += f"`{i}`\n"
- return msg
-
-
-async def get_user_activity(id_, user, duser=None):
- vars_ = {"id": id_}
- result = await return_json_senpai(ACTIVITY_QUERY, vars_, auth=True, user=user)
- data = result["data"]["Page"]["activities"]
- msg = ""
- for i in data:
- try:
- name = f"[{i['media']['title']['romaji']}]" + f"({i['media']['siteUrl']})"
- if i["status"] in ["watched episode", "read chapter"]:
- msg += (
- f"⚬ {str(i['status']).capitalize()} "
- + f"{i['progress']} of {name}\n"
- )
- else:
- progress = i["progress"]
- of = "of"
- if i["status"] == "dropped":
- of = "at"
- msg += (
- f"⚬ {str(i['status']).capitalize()}"
- + f"{f'{progress} {of} ' if progress is not None else ' '}"
- + f"{name}\n"
- )
- except KeyError:
- pass
- if duser is None:
- duser = user
- btn = [[InlineKeyboardButton("Back", callback_data=f"getusrbc_{duser}")]]
- return [
- f"https://img.anili.st/user/{id_}?a={time.time()}",
- msg,
- InlineKeyboardMarkup(btn),
- ]
-
-
-async def get_recommendations(id_):
- vars_ = {"id": int(id_)}
- result = await return_json_senpai(RECOMMENDTIONS_QUERY, vars_)
- data = result["data"]["Media"]["recommendations"]["edges"]
- rc_ls = []
- for i in data:
- ii = i["node"]["mediaRecommendation"]
- rc_ls.append([ii["title"]["romaji"], ii["id"], ii["siteUrl"]])
- if rc_ls == []:
- return "No Recommendations available related to given anime!!!"
- outstr = "Recommended animes:\n\n"
- for i in rc_ls:
- outstr += (
- f"**{i[0]}**\n ➥[Synopsis]"
- + f"(https://t.me/{BOT_USERNAME}?astart=anime_{i[1]})"
- + f"\n ➥[Official Site]({i[2]})\n\n"
- )
- return outstr
-
-
-async def get_top_animes(gnr: str, page, user):
- vars_ = {"gnr": gnr.lower(), "page": int(page)}
- query = TOP_QUERY
- msg = f"Top animes for genre `{gnr.capitalize()}`:\n\n"
- if gnr == "None":
- query = ALLTOP_QUERY
- vars_ = {"page": int(page)}
- msg = f"Top animes:\n\n"
- nsfw = False
- result = await return_json_senpai(query, vars_, auth=False, user=user)
- if len(result["data"]["Page"]["media"]) == 0:
- query = TOPT_QUERY
- msg = f"Top animes for tag `{gnr.capitalize()}`:\n\n"
- result = await return_json_senpai(query, vars_, auth=False, user=user)
- if len(result["data"]["Page"]["media"]) == 0:
- return [f"No results Found"]
- nsls = await get_all_tags("nsfw")
- nsfw = True if gnr.lower() in nsls.lower() else False
- data = result["data"]["Page"]
- for i in data["media"]:
- msg += f"⚬ `{i['title']['romaji']}`\n"
- msg += f"\nTotal available animes: `{data['pageInfo']['total']}`"
- btn = []
- if int(page) == 1:
- if int(data["pageInfo"]["lastPage"]) != 1:
- btn.append(
- [
- InlineKeyboardButton(
- "Next", callback_data=f"topanimu_{gnr}_{int(page)+1}_{user}"
- )
- ]
- )
- elif int(page) == int(data["pageInfo"]["lastPage"]):
- btn.append(
- [
- InlineKeyboardButton(
- "Prev", callback_data=f"topanimu_{gnr}_{int(page)-1}_{user}"
- )
- ]
- )
- else:
- btn.append(
- [
- InlineKeyboardButton(
- "Prev", callback_data=f"topanimu_{gnr}_{int(page)-1}_{user}"
- ),
- InlineKeyboardButton(
- "Next", callback_data=f"topanimu_{gnr}_{int(page)+1}_{user}"
- ),
- ]
- )
- return [msg, nsfw], InlineKeyboardMarkup(btn) if len(btn) != 0 else ""
-
-
-async def get_user_favourites(id_, user, req, page, sighs, duser=None):
- vars_ = {"id": int(id_), "page": int(page)}
- result = await return_json_senpai(
- FAV_ANI_QUERY
- if req == "ANIME"
- else FAV_CHAR_QUERY
- if req == "CHAR"
- else FAV_MANGA_QUERY,
- vars_,
- auth=True,
- user=int(user),
- )
- data = result["data"]["User"]["favourites"][
- "anime" if req == "ANIME" else "characters" if req == "CHAR" else "manga"
- ]
- msg = (
- "Favourite Animes:\n\n"
- if req == "ANIME"
- else "Favourite Characters:\n\n"
- if req == "CHAR"
- else "Favourite Manga:\n\n"
- )
- for i in data["edges"]:
- node_name = (
- i["node"]["title"]["romaji"] if req != "CHAR" else i["node"]["name"]["full"]
- )
- msg += f"⚬ [{node_name}]({i['node']['siteUrl']})\n"
- btn = []
- if duser is None:
- duser = user
- if int(page) == 1:
- if int(data["pageInfo"]["lastPage"]) != 1:
- btn.append(
- [
- InlineKeyboardButton(
- "Next",
- callback_data=(
- f"myfavqry_{req}_{id_}_{str(int(page)+1)}"
- + f"_{sighs}_{duser}"
- ),
- )
- ]
- )
- elif int(page) == int(data["pageInfo"]["lastPage"]):
- btn.append(
- [
- InlineKeyboardButton(
- "Prev",
- callback_data=(
- f"myfavqry_{req}_{id_}_{str(int(page)-1)}_{sighs}_{duser}"
- ),
- )
- ]
- )
- else:
- btn.append(
- [
- InlineKeyboardButton(
- "Prev",
- callback_data=(
- f"myfavqry_{req}_{id_}_{str(int(page)-1)}_{sighs}_{duser}"
- ),
- ),
- InlineKeyboardButton(
- "Next",
- callback_data=(
- f"myfavqry_{req}_{id_}_{str(int(page)+1)}_{sighs}_{duser}"
- ),
- ),
- ]
- )
- btn.append(
- [InlineKeyboardButton("Back", callback_data=f"myfavs_{id_}_{sighs}_{user}")]
- )
- return [
- f"https://img.anili.st/user/{id_}?a=({time.time()})",
- msg,
- InlineKeyboardMarkup(btn),
- ]
-
-
-async def get_featured_in_lists(
- idm, req, auth: bool = False, user: int = None, page: int = 0
-):
- vars_ = {"id": int(idm)}
- result = await return_json_senpai(LS_INFO_QUERY, vars_, auth=auth, user=user)
- data = result["data"]["Character"]["media"]["nodes"]
- if req == "ANI":
- out = "ANIMES:\n\n"
- out_ = []
- for ani in data:
- k = ani["title"]["english"] or ani["title"]["romaji"]
- kk = ani["type"]
- if kk == "ANIME":
- out_.append(f"• __{k}__\n")
- else:
- out = "MANGAS:\n\n"
- out_ = []
- for ani in data:
- k = ani["title"]["english"] or ani["title"]["romaji"]
- kk = ani["type"]
- if kk == "MANGA":
- out_.append(f"• __{k}__\n")
- total = len(out_)
- for _ in range(15 * page):
- out_.pop(0)
- out_ = "".join(out_[:15])
- return ([out + out_, total] if len(out_) != 0 else False), result["data"][
- "Character"
- ]["image"]["large"]
-
-
-async def get_additional_info(
- idm, ctgry, req=None, auth: bool = False, user: int = None, page: int = 0
-):
- vars_ = {"id": int(idm)}
- if req == "char":
- vars_["page"] = page
- result = await return_json_senpai(
- (
- (
- DES_INFO_QUERY
- if req == "desc"
- else CHA_INFO_QUERY
- if req == "char"
- else REL_INFO_QUERY
- )
- if ctgry == "ANI"
- else DESC_INFO_QUERY
- ),
- vars_,
- )
- data = result["data"]["Media"] if ctgry == "ANI" else result["data"]["Character"]
- pic = f"https://img.anili.st/media/{idm}"
- if req == "desc":
- synopsis = data.get("description")
- if os.environ.get("PREFERRED_LANGUAGE"):
- synopsis = tr.translate(
- synopsis, lang_tgt=os.environ.get("PREFERRED_LANGUAGE")
- )
- return (pic if ctgry == "ANI" else data["image"]["large"]), synopsis
- elif req == "char":
- charlist = []
- for char in data["characters"]["edges"]:
- charlist.append(f"• `{char['node']['name']['full']}` ({char['role']})")
- chrctrs = ("\n").join(charlist)
- charls = f"{chrctrs}" if len(charlist) != 0 else ""
- return pic, charls, data["characters"]["pageInfo"]
- else:
- prqlsql = data.get("relations").get("edges")
- ps = ""
- for i in prqlsql:
- ps += (
- f'• {i["node"]["title"]["romaji"]} '
- + f'({i["node"]["type"]}) `{i["relationType"]}`\n'
- )
- return pic, ps
-
-
-async def get_anime(vars_, auth: bool = False, user: int = None, cid: int = None):
- result = await return_json_senpai(ANIME_QUERY, vars_, auth=auth, user=user)
-
- error = result.get("errors")
- if error:
- error_sts = error[0].get("message")
- return [f"[{error_sts}]"]
-
- data = result["data"]["Media"]
-
- # Data of all fields in returned json
- # pylint: disable=possibly-unused-variable
- idm = data.get("id")
- idmal = data.get("idMal")
- romaji = data["title"]["romaji"]
- english = data["title"]["english"]
- native = data["title"]["native"]
- formats = data.get("format")
- status = data.get("status")
- episodes = data.get("episodes")
- duration = data.get("duration")
- country = data.get("countryOfOrigin")
- c_flag = cflag(country)
- source = data.get("source")
- prqlsql = data.get("relations").get("edges")
- adult = data.get("isAdult")
- url = data.get("siteUrl")
- trailer_link = "N/A"
- gnrs = ", ".join(data["genres"])
- score = data["averageScore"]
- bl, cs = await uidata(cid)
- text = await get_ui_text(cs)
- psrc, ptype = text[0], text[1]
- avscd = f"\n{bl}**{text[2]}:** `{score}%` 🌟" if score is not None else ""
- tags = []
- for i in data["tags"]:
- tags.append(i["name"])
- tags_ = f"\n{bl}**{text[8]}:** `{', '.join(tags[:5])}`" if tags != [] else ""
- bot = BOT_USERNAME.replace("@", "")
- gnrs_ = ""
- if len(gnrs) != 0:
- gnrs_ = f"\n{bl}**{text[7]}:** `{gnrs}`"
- isfav = data.get("isFavourite")
- fav = ", in Favourites" if isfav is True else ""
- user_data = ""
- in_ls = False
- in_ls_id = ""
- if auth is True:
- in_list = data.get("mediaListEntry")
- if in_list is not None:
- in_ls = True
- in_ls_id = in_list["id"]
- in_ls_stts = in_list["status"]
- in_ls_score = (
- f" and scored {in_list['score']}" if in_list["score"] != 0 else ""
- )
- user_data = f"\n{bl}**{text[4]}:** `{in_ls_stts}{fav}{in_ls_score}`"
- if data["title"]["english"] is not None:
- name = f"""[{c_flag}]**{romaji}** | {native}"""
- else:
- name = f"""[{c_flag}]**{romaji}** | {native}"""
- prql, prql_id, sql, sql_id = "", "None", "", "None"
- for i in prqlsql:
- if i["relationType"] == "PREQUEL" and i["node"]["type"] == "ANIME":
- pname = (
- i["node"]["title"]["english"]
- if i["node"]["title"]["english"] is not None
- else i["node"]["title"]["romaji"]
- )
- prql += f"**{text[10]}:** `{pname}`\n"
- prql_id = i["node"]["id"]
- break
- for i in prqlsql:
- if i["relationType"] == "SEQUEL" and i["node"]["type"] == "ANIME":
- sname = (
- i["node"]["title"]["english"]
- if i["node"]["title"]["english"] is not None
- else i["node"]["title"]["romaji"]
- )
- sql += f"**{text[9]}:** `{sname}`\n"
- sql_id = i["node"]["id"]
- break
- additional = f"{prql}{sql}"
- surl = f"https://t.me/{bot}/?astart=des_ANI_{idm}_desc"
- dura = f"\n{bl}**{text[3]}:** `{duration} min/ep`" if duration is not None else ""
- air_on = None
- if data["nextAiringEpisode"]:
- nextAir = data["nextAiringEpisode"]["timeUntilAiring"]
- air_on = make_it_rw(nextAir * 1000)
- eps = data["nextAiringEpisode"]["episode"]
- th = pos_no(str(eps))
- air_on += f" | {eps}{th} eps"
- if air_on is None:
- eps_ = f"` | `{episodes} eps" if episodes is not None else ""
- status_air = f"{bl}**{text[6]}:** `{status}{eps_}`"
- else:
- status_air = f"{bl}**{text[6]}:** `{status}`\n{bl}**{text[11]}:** `{air_on}`"
- if data["trailer"] and data["trailer"]["site"] == "youtube":
- trailer_link = f"Trailer"
- title_img = f"https://img.anili.st/media/{idm}"
- try:
- finals_ = ANIME_TEMPLATE.format(**locals())
- except KeyError as kys:
- return [f"{kys}"]
- return (
- title_img,
- finals_,
- [idm, in_ls, in_ls_id, isfav, str(adult)],
- prql_id,
- sql_id,
- )
-
-
-async def get_anilist(qdb, page, auth: bool = False, user: int = None, cid: int = None):
- vars_ = {"search": ANIME_DB[qdb], "page": page}
- result = await return_json_senpai(PAGE_QUERY, vars_, auth=auth, user=user)
-
- if len(result["data"]["Page"]["media"]) == 0:
- return [f"No results Found"]
-
- data = result["data"]["Page"]["media"][0]
- # Data of all fields in returned json
- # pylint: disable=possibly-unused-variable
- idm = data.get("id")
- bot = BOT_USERNAME.replace("@", "")
- idmal = data.get("idMal")
- romaji = data["title"]["romaji"]
- english = data["title"]["english"]
- native = data["title"]["native"]
- formats = data.get("format")
- status = data.get("status")
- episodes = data.get("episodes")
- duration = data.get("duration")
- country = data.get("countryOfOrigin")
- c_flag = cflag(country)
- source = data.get("source")
- prqlsql = data.get("relations").get("edges")
- adult = data.get("isAdult")
- trailer_link = "N/A"
- isfav = data.get("isFavourite")
- gnrs = ", ".join(data["genres"])
- gnrs_ = ""
- bl, cs = await uidata(cid)
- text = await get_ui_text(cs)
- psrc, ptype = text[0], text[1]
- if len(gnrs) != 0:
- gnrs_ = f"\n{bl}**{text[7]}:** `{gnrs}`"
- fav = ", in Favourites" if isfav is True else ""
- score = data["averageScore"]
- avscd = f"\n{bl}**{text[2]}:** `{score}%` 🌟" if score is not None else ""
- tags = []
- for i in data["tags"]:
- tags.append(i["name"])
- tags_ = f"\n{bl}**{text[8]}:** `{', '.join(tags[:5])}`" if tags != [] else ""
- in_ls = False
- in_ls_id = ""
- user_data = ""
- if auth is True:
- in_list = data.get("mediaListEntry")
- if in_list is not None:
- in_ls = True
- in_ls_id = in_list["id"]
- in_ls_stts = in_list["status"]
- in_ls_score = (
- f" and scored {in_list['score']}" if in_list["score"] != 0 else ""
- )
- user_data = f"\n{bl}**{text[4]}:** `{in_ls_stts}{fav}{in_ls_score}`"
- if data["title"]["english"] is not None:
- name = f"[{c_flag}]**{english}** (`{native}`)"
- else:
- name = f"[{c_flag}]**{romaji}** (`{native}`)"
- prql, sql = "", ""
- for i in prqlsql:
- if i["relationType"] == "PREQUEL" and i["node"]["type"] == "ANIME":
- pname = (
- i["node"]["title"]["english"]
- if i["node"]["title"]["english"] is not None
- else i["node"]["title"]["romaji"]
- )
- prql += f"**{text[10]}:** `{pname}`\n"
- break
- for i in prqlsql:
- if i["relationType"] == "SEQUEL" and i["node"]["type"] == "ANIME":
- sname = (
- i["node"]["title"]["english"]
- if i["node"]["title"]["english"] is not None
- else i["node"]["title"]["romaji"]
- )
- sql += f"**{text[9]}:** `{sname}`\n"
- break
- additional = f"{prql}{sql}"
- additional.replace("-", "")
- dura = f"\n{bl}**{text[3]}:** `{duration} min/ep`" if duration is not None else ""
- air_on = None
- if data["nextAiringEpisode"]:
- nextAir = data["nextAiringEpisode"]["timeUntilAiring"]
- air_on = make_it_rw(nextAir * 1000)
- eps = data["nextAiringEpisode"]["episode"]
- th = pos_no(str(eps))
- air_on += f" | {eps}{th} eps"
- if air_on is None:
- eps_ = f"` | `{episodes} eps" if episodes is not None else ""
- status_air = f"{bl}**{text[6]}:** `{status}{eps_}`"
- else:
- status_air = f"{bl}**{text[6]}:** `{status}`\n{bl}**{text[11]}:** `{air_on}`"
- if data["trailer"] and data["trailer"]["site"] == "youtube":
- trailer_link = f"Trailer"
- url = data.get("siteUrl")
- title_img = f"https://img.anili.st/media/{idm}"
- surl = f"https://t.me/{bot}/?astart=des_ANI_{idm}_desc"
- hasNextPage = result["data"]["Page"]["pageInfo"]["hasNextPage"]
- try:
- finals_ = ANIME_TEMPLATE.format(**locals())
- except KeyError as kys:
- return [f"{kys}"]
- return title_img, [finals_, hasNextPage], [idm, in_ls, in_ls_id, isfav, str(adult)]
-
-
-async def get_character(query, page, auth: bool = False, user: int = None):
- var = {"search": CHAR_DB[query], "page": int(page)}
- result = await return_json_senpai(CHARACTER_QUERY, var, auth=auth, user=user)
- if len(result["data"]["Page"]["characters"]) == 0:
- return [f"No results Found"]
- data = result["data"]["Page"]["characters"][0]
- # Character Data
- id_ = data["id"]
- name = data["name"]["full"]
- native = data["name"]["native"]
- img = data["image"]["large"]
- site_url = data["siteUrl"]
- isfav = data.get("isFavourite")
- va = []
- for i in data["media"]["edges"]:
- for ii in i["voiceActors"]:
- if f"[{ii['name']['full']}]({ii['siteUrl']})" not in va:
- va.append(f"[{ii['name']['full']}]({ii['siteUrl']})")
- lva = None
- if len(va) > 1:
- lva = va.pop()
- sva = (
- f"\n**Voice Actors:** {', '.join(va)}"
- + f"{' and '+lva if lva is not None else ''}\n"
- if va != []
- else ""
- )
- cap_text = f"""
-__{native}__
-(`{name}`)
-**ID:** {id_}
-{sva}
-Visit Website"""
- hasNextPage = result["data"]["Page"]["pageInfo"]["hasNextPage"]
- return img, [cap_text, hasNextPage], [id_, isfav]
-
-
-async def browse_(qry: str):
- s, y = season_()
- sort = "POPULARITY_DESC"
- if qry == "upcoming":
- s, y = season_(True)
- if qry == "trending":
- sort = "TRENDING_DESC"
- vars_ = {"s": s, "y": y, "sort": sort}
- result = await return_json_senpai(BROWSE_QUERY, vars_)
- data = result["data"]["Page"]["media"]
- ls = []
- for i in data:
- if i["format"] in ["TV", "MOVIE", "ONA"]:
- ls.append("• `" + i["title"]["romaji"] + "`")
- out = f"{qry.capitalize()} animes in {s} {y}:\n\n"
- return out + "\n".join(ls[:20])
-
-
-async def get_manga(qdb, page, auth: bool = False, user: int = None, cid: int = None):
- vars_ = {"search": MANGA_DB[qdb], "asHtml": True, "page": page}
- result = await return_json_senpai(MANGA_QUERY, vars_, auth=auth, user=user)
- if len(result["data"]["Page"]["media"]) == 0:
- return [f"No results Found"]
- data = result["data"]["Page"]["media"][0]
-
- # Data of all fields in returned json
- # pylint: disable=possibly-unused-variable
- idm = data.get("id")
- romaji = data["title"]["romaji"]
- english = data["title"]["english"]
- native = data["title"]["native"]
- status = data.get("status")
- synopsis = data.get("description")
- description = synopsis[:500]
- description_s = ""
- if len(synopsis) > 500:
- description += f"..."
- description_s = (
- f"[Click for more info](https://t.me/{BOT_USERNAME}"
- + f"/?astart=des_ANI_{idm}_desc)"
- )
- volumes = data.get("volumes")
- chapters = data.get("chapters")
- score = data.get("averageScore")
- url = data.get("siteUrl")
- format_ = data.get("format")
- country = data.get("countryOfOrigin")
- source = data.get("source")
- c_flag = cflag(country)
- isfav = data.get("isFavourite")
- adult = data.get("isAdult")
- fav = ", in Favourites" if isfav is True else ""
- in_ls = False
- in_ls_id = ""
- bl, cs = await uidata(cid)
- text = await get_ui_text(cs)
- user_data = ""
- if auth is True:
- in_list = data.get("mediaListEntry")
- if in_list is not None:
- in_ls = True
- in_ls_id = in_list["id"]
- in_ls_stts = in_list["status"]
- in_ls_score = (
- f" and scored {in_list['score']}" if in_list["score"] != 0 else ""
- )
- user_data = f"{bl}**{text[4]}:** `{in_ls_stts}{fav}{in_ls_score}`\n"
- name = f"""[{c_flag}]**{romaji}**
- __{english}__
- {native}"""
- if english is None:
- name = f"""[{c_flag}]**{romaji}**
- {native}"""
- finals_ = f"{name}\n\n"
- finals_ += f"{bl}**ID:** `{idm}`\n"
- finals_ += f"{bl}**{text[6]}:** `{status}`\n"
- finals_ += f"{bl}**{text[13]}:** `{volumes}`\n"
- finals_ += f"{bl}**{text[14]}:** `{chapters}`\n"
- finals_ += f"{bl}**{text[2]}:** `{score}`\n"
- finals_ += f"{bl}**{text[1]}:** `{format_}`\n"
- finals_ += f"{bl}**{text[0]}:** `{source}`\n"
- finals_ += user_data
- if os.environ.get("PREFERRED_LANGUAGE"):
- description = tr.translate(
- description, lang_tgt=os.environ.get("PREFERRED_LANGUAGE")
- )
- findesc = "" if description == "" else f"`{description}`"
- finals_ += f"\n**{text[12]}**: {findesc}\n\n{description_s}"
- pic = f"https://img.anili.st/media/{idm}"
- return (
- pic,
- [finals_, result["data"]["Page"]["pageInfo"]["hasNextPage"], url],
- [idm, in_ls, in_ls_id, isfav, str(adult)],
- )
-
-
-async def get_airing(qry, ind: int, auth: bool = False, user: int = None):
- vars_ = {"search": AIRING_DB[qry], "page": int(ind)}
- result = await return_json_senpai(AIR_QUERY, vars_, auth=auth, user=user)
- error = result.get("errors")
- if error:
- error_sts = error[0].get("message")
- return [f"{error_sts}"]
- try:
- data = result["data"]["Page"]["media"][0]
- except IndexError:
- return ["No results Found"]
- # Airing Details
- mid = data.get("id")
- romaji = data["title"]["romaji"]
- english = data["title"]["english"]
- status = data.get("status")
- country = data.get("countryOfOrigin")
- c_flag = cflag(country)
- coverImg = f"https://img.anili.st/media/{mid}"
- isfav = data.get("isFavourite")
- adult = data.get("isAdult")
- in_ls = False
- in_ls_id = ""
- user_data = ""
- if auth is True:
- in_list = data.get("mediaListEntry")
- if in_list is not None:
- in_ls = True
- in_ls_id = in_list["id"]
- in_ls_stts = in_list["status"]
- user_data = f"**USER DATA:** `{in_ls_stts}`\n"
- air_on = None
- if data["nextAiringEpisode"]:
- nextAir = data["nextAiringEpisode"]["timeUntilAiring"]
- episode = data["nextAiringEpisode"]["episode"]
- th = pos_no(episode)
- air_on = make_it_rw(nextAir * 1000)
- title_ = english or romaji
- out = f"[{c_flag}] **{title_}**"
- out += f"\n\n**ID:** `{mid}`"
- out += f"\n**Status:** `{status}`\n"
- out += user_data
- if air_on:
- out += f"Airing Episode `{episode}{th}` in `{air_on}`"
- site = data["siteUrl"]
- return (
- [coverImg, out],
- [site, result["data"]["Page"]["pageInfo"]["hasNextPage"]],
- [mid, in_ls, in_ls_id, isfav, str(adult)],
- )
-
-
-async def toggle_favourites(id_: int, media: str, user: int):
- vars_ = {"id": int(id_)}
- query = (
- ANIME_MUTATION
- if media == "ANIME" or media == "AIRING"
- else CHAR_MUTATION
- if media == "CHARACTER"
- else MANGA_MUTATION
- if media == "MANGA"
- else STUDIO_MUTATION
- )
- k = await return_json_senpai(query=query, vars_=vars_, auth=True, user=int(user))
- try:
- kek = k["data"]["ToggleFavourite"]
- return "ok"
- except KeyError:
- return "failed"
-
-
-async def get_user(vars_, req, user, display_user=None):
- query = USER_QRY if "user" in req else VIEWER_QRY
- k = await return_json_senpai(
- query=query, vars_=vars_, auth=False if "user" in req else True, user=int(user)
- )
- error = k.get("errors")
- if error:
- error_sts = error[0].get("message")
- return [f"{error_sts}"]
-
- data = k["data"]["User" if "user" in req else "Viewer"]
- anime = data["statistics"]["anime"]
- manga = data["statistics"]["manga"]
- stats = f"""
-**Anime Stats**:
-
-Total Anime Watched: `{anime['count']}`
-Total Episode Watched: `{anime['episodesWatched']}`
-Total Time Spent: `{anime['minutesWatched']}`
-Average Score: `{anime['meanScore']}`
-
-**Manga Stats**:
-
-Total Manga Read: `{manga['count']}`
-Total Chapters Read: `{manga['chaptersRead']}`
-Total Volumes Read: `{manga['volumesRead']}`
-Average Score: `{manga['meanScore']}`
-"""
- btn = []
- if not "user" in req:
- btn.append(
- [
- InlineKeyboardButton(
- "Favourites",
- callback_data=f"myfavs_{data['id']}_yes_{display_user}",
- ),
- InlineKeyboardButton(
- "Activity", callback_data=f"myacc_{data['id']}_{display_user}"
- ),
- ]
- )
- btn.append([InlineKeyboardButton("Profile", url=str(data["siteUrl"]))])
- return [
- f'https://img.anili.st/user/{data["id"]}?a={time.time()}',
- stats,
- InlineKeyboardMarkup(btn),
- ]
-
-
-async def update_anilist(id_, req, user, eid: int = None, status: str = None):
- vars_ = {"id": int(id_), "status": status}
- if req == "lsus":
- vars_ = {"id": int(eid), "status": status}
- if req == "dlt":
- vars_ = {"id": int(eid)}
- k = await return_json_senpai(
- query=(
- ANILIST_MUTATION
- if req == "lsas"
- else ANILIST_MUTATION_UP
- if req == "lsus"
- else ANILIST_MUTATION_DEL
- ),
- vars_=vars_,
- auth=True,
- user=int(user),
- )
- try:
- (
- k["data"]["SaveMediaListEntry"]
- if req == "lsas"
- else k["data"]["UpdateMediaListEntries"]
- if req == "lsus"
- else k["data"]["DeleteMediaListEntry"]
- )
- return "ok"
- except KeyError:
- return "failed"
-
-
-async def check_if_adult(id_):
- vars_ = {"id": int(id_)}
- k = await return_json_senpai(query=ISADULT, vars_=vars_, auth=False)
- if str(k["data"]["Media"]["isAdult"]) == "True":
- return "True"
- else:
- return "False"
-
-
-#### END ####
-
-#### Jikanpy part ####
-
-
-async def get_scheduled(x: int = 9):
- base_url = "https://api.jikan.moe/v4/schedules/"
- day = str(day_(x if x != 9 else datetime.now().weekday())).lower()
- out = f"Scheduled animes for {day.capitalize()}\n\n"
- data = requests.get(base_url + day).json()
- sched_ls = data["data"]
- for i in sched_ls:
- try:
- title = i["titles"][0]["title"]
- except IndexError:
- title = i["title"]
- out += f"• `{title}`\n"
- return out, x if x != 9 else datetime.now().weekday()
-
-
-#### END ####
-
-#### chiaki part ####
-
-
-def get_wols(x: str):
- data = requests.get(f"https://chiaki.vercel.app/search2?query={x}").json()
- ls = []
- for i in data:
- sls = [data[i], i]
- ls.append(sls)
- return ls
-
-
-def get_wo(x: int, page: int):
- data = requests.get(f"https://chiaki.vercel.app/get2?group_id={x}").json()
- msg = "Watch order for the given query is:\n\n"
- out = []
- for i in data:
- out.append(f"{i['index']}. `{i['name']}`\n")
- total = len(out)
- for _ in range(50 * page):
- out.pop(0)
- out_ = "".join(out[:50])
- return msg + out_, total
-
-
-#### END ####
-
-##### Anime Fillers Part #####
-
-
-def search_filler(query):
- html = requests.get("https://www.animefillerlist.com/shows").text
- soup = BeautifulSoup(html, "html.parser")
- div = soup.findAll("div", attrs={"class": "Group"})
- index = {}
- for i in div:
- li = i.findAll("li")
- for jk in li:
- yum = jk.a["href"].split("/")[-1]
- cum = jk.text
- index[cum] = yum
- ret = {}
- keys = list(index.keys())
- for i in range(len(keys)):
- if query.lower() in keys[i].lower():
- ret[keys[i]] = index[keys[i]]
- return ret
-
-
-def parse_filler(filler_id):
- url = "https://www.animefillerlist.com/shows/" + filler_id
- html = requests.get(url).text
- soup = BeautifulSoup(html, "html.parser")
- div = soup.find("div", attrs={"id": "Condensed"})
- all_ep = div.find_all("span", attrs={"class": "Episodes"})
- if len(all_ep) == 1:
- ttl_ep = all_ep[0].findAll("a")
- total_ep = []
- mix_ep = None
- filler_ep = None
- ac_ep = None
- for tol in ttl_ep:
- total_ep.append(tol.text)
- dict_ = {
- "filler_id": filler_id,
- "total_ep": ", ".join(total_ep),
- "mixed_ep": mix_ep,
- "filler_ep": filler_ep,
- "ac_ep": ac_ep,
- }
- return dict_
- if len(all_ep) == 2:
- ttl_ep = all_ep[0].findAll("a")
- fl_ep = all_ep[1].findAll("a")
- total_ep = []
- mix_ep = None
- ac_ep = None
- filler_ep = []
- for tol in ttl_ep:
- total_ep.append(tol.text)
- for fol in fl_ep:
- filler_ep.append(fol.text)
- dict_ = {
- "filler_id": filler_id,
- "total_ep": ", ".join(total_ep),
- "mixed_ep": mix_ep,
- "filler_ep": ", ".join(filler_ep),
- "ac_ep": ac_ep,
- }
- return dict_
- if len(all_ep) == 3:
- ttl_ep = all_ep[0].findAll("a")
- mxl_ep = all_ep[1].findAll("a")
- fl_ep = all_ep[2].findAll("a")
- total_ep = []
- mix_ep = []
- filler_ep = []
- ac_ep = None
- for tol in ttl_ep:
- total_ep.append(tol.text)
- for fol in fl_ep:
- filler_ep.append(fol.text)
- for mol in mxl_ep:
- mix_ep.append(mol.text)
- dict_ = {
- "filler_id": filler_id,
- "total_ep": ", ".join(total_ep),
- "mixed_ep": ", ".join(mix_ep),
- "filler_ep": ", ".join(filler_ep),
- "ac_ep": ac_ep,
- }
- return dict_
- if len(all_ep) == 4:
- ttl_ep = all_ep[0].findAll("a")
- mxl_ep = all_ep[1].findAll("a")
- fl_ep = all_ep[2].findAll("a")
- al_ep = all_ep[3].findAll("a")
- total_ep = []
- mix_ep = []
- filler_ep = []
- ac_ep = []
- for tol in ttl_ep:
- total_ep.append(tol.text)
- for fol in fl_ep:
- filler_ep.append(fol.text)
- for mol in mxl_ep:
- mix_ep.append(mol.text)
- for aol in al_ep:
- ac_ep.append(aol.text)
- dict_ = {
- "filler_id": filler_id,
- "total_ep": ", ".join(total_ep),
- "mixed_ep": ", ".join(mix_ep),
- "filler_ep": ", ".join(filler_ep),
- "ac_ep": ", ".join(ac_ep),
- }
- return dict_
-
-
-@app.on_message(
- filters.command(["anime", f"anime{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def anime_cmd(client: Client, message: Message, mdata: dict):
- """Search Anime Info"""
- text = mdata["text"].split(" ", 1)
- gid = mdata["chat"]["id"]
- try:
- user = mdata["from_user"]["id"]
- auser = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- ufc = await gcc(user)
- if ufc is not None:
- auser = ufc
- else:
- auser = user
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "anime" in find_gc["cmd_list"].split():
- return
- if len(text) == 1:
- k = await message.reply_text(
- """Please give a query to search about
-
-example: /anime Sword Art Online"""
- )
- await asyncio.sleep(5)
- return await k.delete()
- query = text[1]
- auth = False
- vars_ = {"search": query}
- if query.isdigit():
- vars_ = {"id": int(query)}
- if await AUTH_USERS.find_one({"id": auser}):
- auth = True
- result = await get_anime(
- vars_, user=auser, auth=auth, cid=gid if gid != user else None
- )
- if len(result) != 1:
- title_img, finals_ = result[0], result[1]
- else:
- k = await message.reply_text(result[0])
- await asyncio.sleep(5)
- return await k.delete()
- buttons = get_btns("ANIME", result=result, user=user, auth=auth)
- if await SFW_GRPS.find_one({"id": gid}) and result[2].pop() == "True":
- await client.send_photo(
- gid,
- no_pic[random.randint(0, 4)],
- caption="This anime is marked 18+ and not allowed in this group",
- )
- return
- try:
- await client.send_photo(gid, title_img, caption=finals_, reply_markup=buttons)
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", title_img, "LINK", msg=message)
- await client.send_photo(gid, failed_pic, caption=finals_, reply_markup=buttons)
-
-
-@app.on_message(
- filters.command(["manga", f"manga{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def manga_cmd(client: Client, message: Message, mdata: dict):
- """Search Manga Info"""
- text = mdata["text"].split(" ", 1)
- gid = mdata["chat"]["id"]
- try:
- user = mdata["from_user"]["id"]
- auser = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- ufc = await gcc(user)
- if ufc is not None:
- auser = ufc
- else:
- auser = user
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "manga" in find_gc["cmd_list"].split():
- return
- if len(text) == 1:
- k = await message.reply_text(
- """Please give a query to search about
-
-example: /manga Sword Art Online"""
- )
- await asyncio.sleep(5)
- return await k.delete()
- query = text[1]
- qdb = rand_key()
- MANGA_DB[qdb] = query
- auth = False
- if await AUTH_USERS.find_one({"id": auser}):
- auth = True
- result = await get_manga(
- qdb, 1, auth=auth, user=auser, cid=gid if gid != user else None
- )
- if len(result) == 1:
- k = await message.reply_text(result[0])
- await asyncio.sleep(5)
- return await k.delete()
- pic, finals_ = result[0], result[1][0]
- buttons = get_btns(
- "MANGA", lsqry=qdb, lspage=1, user=user, result=result, auth=auth
- )
- if await SFW_GRPS.find_one({"id": gid}) and result[2].pop() == "True":
- buttons = get_btns(
- "MANGA",
- lsqry=qdb,
- lspage=1,
- user=user,
- result=result,
- auth=auth,
- sfw="True",
- )
- await client.send_photo(
- gid,
- no_pic[random.randint(0, 4)],
- caption="This manga is marked 18+ and not allowed in this group",
- reply_markup=buttons,
- )
- return
- try:
- await client.send_photo(gid, pic, caption=finals_, reply_markup=buttons)
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=message)
- await client.send_photo(gid, failed_pic, caption=finals_, reply_markup=buttons)
-
-
-@app.on_message(
- filters.command(["character", f"character{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def character_cmd(client: Client, message: Message, mdata: dict):
- """Get Info about a Character"""
- text = mdata["text"].split(" ", 1)
- gid = mdata["chat"]["id"]
- try:
- user = mdata["from_user"]["id"]
- auser = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- ufc = await gcc(user)
- if ufc is not None:
- auser = ufc
- else:
- auser = user
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "character" in find_gc["cmd_list"].split():
- return
- if len(text) == 1:
- k = await message.reply_text(
- "Please give a query to search about\nexample: /character Luffy"
- )
- await asyncio.sleep(5)
- return await k.delete()
- query = text[1]
- qdb = rand_key()
- CHAR_DB[qdb] = query
- auth = False
- if await AUTH_USERS.find_one({"id": auser}):
- auth = True
- result = await get_character(qdb, 1, auth=auth, user=auser)
- if len(result) == 1:
- k = await message.reply_text(result[0])
- await asyncio.sleep(5)
- return await k.delete()
- img = result[0]
- cap_text = result[1][0]
- buttons = get_btns(
- "CHARACTER", user=user, lsqry=qdb, lspage=1, result=result, auth=auth
- )
- try:
- await client.send_photo(gid, img, caption=cap_text, reply_markup=buttons)
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", img, "LINK", msg=message)
- await client.send_photo(gid, failed_pic, caption=cap_text, reply_markup=buttons)
-
-
-@app.on_message(
- filters.command(["anilist", f"anilist{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def anilist_cmd(client: Client, message: Message, mdata: dict):
- text = mdata["text"].split(" ", 1)
- gid = mdata["chat"]["id"]
- try:
- user = mdata["from_user"]["id"]
- auser = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- ufc = await gcc(user)
- if ufc is not None:
- auser = ufc
- else:
- auser = user
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "anilist" in find_gc["cmd_list"].split():
- return
- if len(text) == 1:
- k = await message.reply_text(
- "Please give a query to search about\nexample: /anilist Sword Art Online"
- )
- await asyncio.sleep(5)
- return await k.delete()
- query = text[1]
- qdb = rand_key()
- ANIME_DB[qdb] = query
- auth = False
- if await AUTH_USERS.find_one({"id": auser}):
- auth = True
- result = await get_anilist(
- qdb, 1, auth=auth, user=auser, cid=gid if gid != user else None
- )
- if len(result) == 1:
- k = await message.reply_text(result[0])
- await asyncio.sleep(5)
- return await k.delete()
- pic, msg = result[0], result[1][0]
- buttons = get_btns(
- "ANIME", lsqry=qdb, lspage=1, result=result, user=user, auth=auth
- )
- if await SFW_GRPS.find_one({"id": gid}) and result[2].pop() == "True":
- buttons = get_btns(
- "ANIME",
- lsqry=qdb,
- lspage=1,
- result=result,
- user=user,
- auth=auth,
- sfw="True",
- )
- await client.send_photo(
- gid,
- no_pic[random.randint(0, 4)],
- caption="This anime is marked 18+ and not allowed in this group",
- reply_markup=buttons,
- )
- return
- try:
- await client.send_photo(gid, pic, caption=msg, reply_markup=buttons)
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=message)
- await client.send_photo(gid, failed_pic, caption=msg, reply_markup=buttons)
-
-
-@app.on_message(filters.command(["top", f"top{BOT_USERNAME}"], prefixes=PREFIX_HANDLER))
-@control_user
-async def top_tags_cmd(client: Client, message: Message, mdata: dict):
- query = mdata["text"].split(" ", 1)
- gid = mdata["chat"]["id"]
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "top" in find_gc["cmd_list"].split():
- return
- get_tag = "None"
- if len(query) == 2:
- get_tag = query[1]
- try:
- user = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- result = await get_top_animes(get_tag, 1, user)
- if len(result) == 1:
- k = await message.reply_text(result[0])
- await asyncio.sleep(5)
- return await k.delete()
- if await SFW_GRPS.find_one({"id": gid}) and str(result[0][1]) == "True":
- return await message.reply_text("No nsfw stuff allowed in this group!!!")
- msg, buttons = result
- await client.send_message(
- gid, msg[0], reply_markup=buttons if buttons != "" else None
- )
-
-
-@app.on_message(
- filters.command(["studio", f"studio{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def studio_cmd(client: Client, message: Message, mdata: dict):
- text = mdata["text"].split(" ", 1)
- gid = mdata["chat"]["id"]
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "studio" in find_gc["cmd_list"].split():
- return
- if len(text) == 1:
- x = await message.reply_text(
- "Please give a query to search about!!!\nExample: /studio ufotable"
- )
- await asyncio.sleep(5)
- await x.delete()
- return
- query = text[1]
- qdb = rand_key()
- STUDIO_DB[qdb] = query
- auth = False
- try:
- user = mdata["from_user"]["id"]
- auser = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- ufc = await gcc(user)
- if ufc is not None:
- auser = ufc
- else:
- auser = user
- if await AUTH_USERS.find_one({"id": auser}):
- auth = True
- result = await get_studios(qdb, 1, user=auser, duser=user, auth=auth)
- if len(result) == 1:
- x = await message.reply_text("No results found!!!")
- await asyncio.sleep(5)
- return await x.delete()
- msg, buttons = result[0], result[1]
- await client.send_message(gid, msg, reply_markup=buttons if buttons != "" else None)
-
-
-@app.on_message(
- filters.command(["airing", f"airing{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def airing_cmd(client: Client, message: Message, mdata: dict):
- """Get Airing Detail of Anime"""
- text = mdata["text"].split(" ", 1)
- gid = mdata["chat"]["id"]
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "airing" in find_gc["cmd_list"].split():
- return
- if len(text) == 1:
- k = await message.reply_text(
- """Please give a query to search about
-
-example: /airing Sword Art Online"""
- )
- await asyncio.sleep(5)
- return await k.delete()
- query = text[1]
- qdb = rand_key()
- AIRING_DB[qdb] = query
- auth = False
- try:
- user = mdata["from_user"]["id"]
- auser = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- ufc = await gcc(user)
- if ufc is not None:
- auser = ufc
- else:
- auser = user
- if await AUTH_USERS.find_one({"id": auser}):
- auth = True
- result = await get_airing(qdb, 1, auth=auth, user=auser)
- if len(result) == 1:
- k = await message.reply_text(result[0])
- await asyncio.sleep(5)
- return await k.delete()
- coverImg, out = result[0]
- btn = get_btns("AIRING", user=user, result=result, auth=auth, lsqry=qdb, lspage=1)
- if await SFW_GRPS.find_one({"id": gid}) and result[2].pop() == "True":
- btn = get_btns(
- "AIRING",
- user=user,
- result=result,
- auth=auth,
- lsqry=qdb,
- lspage=1,
- sfw="True",
- )
- await client.send_photo(
- gid,
- no_pic[random.randint(0, 4)],
- caption="This anime is marked 18+ and not allowed in this group",
- reply_markup=btn,
- )
- return
- try:
- await client.send_photo(gid, coverImg, caption=out, reply_markup=btn)
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", coverImg, "LINK", msg=message)
- await client.send_photo(gid, failed_pic, caption=out, reply_markup=btn)
-
-
-setting_text = """
-This allows you to change group settings
-
-NSFW toggle switches on filtering of 18+ marked content
-
-Airing notifications notifies about airing of anime in recent
-
-Crunchyroll updates will toggle notifications about release of animes on crunchyroll site
-
-Subsplease updates will toggle notifications about release of animes on subsplease site
-
-Click Headlines button to enable headlines. You can choose from given sources"""
-
-
-@app.on_message(
- ~filters.private
- & filters.command(
- ["anisettings", f"anisettings{BOT_USERNAME}"], prefixes=PREFIX_HANDLER
- )
-)
-@control_user
-async def settings_cmd(client: Client, message: Message, mdata: dict):
- cid = mdata["chat"]["id"]
- try:
- user = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- type_ = mdata["chat"]["type"]
- try:
- status = (await app.get_chat_member(cid, user)).status
- except UserNotParticipant:
- status = None
- if (
- user in BOT_OWNER
- or status in [ADMINISTRATOR, CHAT_OWNER]
- or type_ == ChatType.CHANNEL
- or user == cid
- ):
- sfw = "NSFW: Allowed"
- if await SFW_GRPS.find_one({"id": cid}):
- sfw = "NSFW: Not Allowed"
- notif = "Airing notifications: OFF"
- if await AG.find_one({"_id": cid}):
- notif = "Airing notifications: ON"
- cr = "Crunchyroll Updates: OFF"
- if await CG.find_one({"_id": cid}):
- cr = "Crunchyroll Updates: ON"
- sp = "Subsplease Updates: OFF"
- if await SG.find_one({"_id": cid}):
- sp = "Subsplease Updates: ON"
- await message.reply_text(
- text=setting_text,
- reply_markup=InlineKeyboardMarkup(
- [
- [
- InlineKeyboardButton(
- text=sfw, callback_data=f"settogl_sfw_{cid}"
- )
- ],
- [
- InlineKeyboardButton(
- text=notif, callback_data=f"settogl_notif_{cid}"
- )
- ],
- [InlineKeyboardButton(text=cr, callback_data=f"settogl_cr_{cid}")],
- [InlineKeyboardButton(text=sp, callback_data=f"settogl_sp_{cid}")],
- [
- InlineKeyboardButton(
- text="Headlines", callback_data=f"headlines_call_{cid}"
- )
- ],
- [
- InlineKeyboardButton(
- text="Change UI", callback_data=f"cui_call_{cid}"
- )
- ],
- ]
- ),
- )
-
-
-@app.on_message(
- filters.command(["browse", f"browse{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def browse_cmd(client: Client, message: Message, mdata: dict):
- try:
- user = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- gid = mdata["chat"]["id"]
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "browse" in find_gc["cmd_list"].split():
- return
- up = "Upcoming"
- tr = "• Trending •"
- pp = "Popular"
- btns = [
- [
- InlineKeyboardButton(tr, callback_data=f"browse_{tr.lower()}_{user}"),
- InlineKeyboardButton(pp, callback_data=f"browse_{pp.lower()}_{user}"),
- InlineKeyboardButton(up, callback_data=f"browse_{up.lower()}_{user}"),
- ]
- ]
- msg = await browse_("trending")
- await client.send_message(gid, msg, reply_markup=InlineKeyboardMarkup(btns))
-
-
-@app.on_message(
- filters.command(
- ["gettags", f"gettags{BOT_USERNAME}", "getgenres", f"getgenres{BOT_USERNAME}"],
- prefixes=PREFIX_HANDLER,
- )
-)
-@control_user
-async def list_tags_genres_cmd(client, message: Message, mdata: dict):
- gid = mdata["chat"]["id"]
- text = mdata["text"]
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "gettags" in (
- text.split()[0] and find_gc["cmd_list"].split()
- ):
- return
- if find_gc is not None and "getgenres" in (
- text.split()[0] and find_gc["cmd_list"].split()
- ):
- return
- if await SFW_GRPS.find_one({"id": gid}) and "nsfw" in text:
- return await message.reply_text("No nsfw allowed here!!!")
- msg = (
- (await get_all_tags(text))
- if "gettags" in text.split()[0]
- else (await get_all_genres())
- )
- await message.reply_text(msg)
-
-
-@app.on_callback_query(filters.regex(pattern=r"page_(.*)"))
-@check_user
-async def page_btn(client: Client, cq: CallbackQuery, cdata: dict):
- kek, media, query, page, auth, user = cq.data.split("_")
- gid = cdata["message"]["chat"]["id"]
- if media == "ANIME":
- try:
- ANIME_DB[query]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- if media == "MANGA":
- try:
- MANGA_DB[query]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- if media == "CHARACTER":
- try:
- CHAR_DB[query]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- if media == "AIRING":
- try:
- AIRING_DB[query]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- authbool = bool(1) if auth == "True" else bool(0)
- if "-100" in str(user):
- auser = await gcc(user)
- else:
- auser = user
- if media in ["ANIME", "MANGA"]:
- result = await (get_anilist if media == "ANIME" else get_manga)(
- query,
- int(page),
- auth=authbool,
- user=int(auser),
- cid=gid if gid != user else None,
- )
- else:
- result = await (get_character if media == "CHARACTER" else get_airing)(
- query, int(page), auth=authbool, user=int(auser)
- )
- if "No results Found" in result:
- await cq.answer("No more results available!!!", show_alert=True)
- return
- pic, msg = result[0], result[1][0]
- if media == "AIRING":
- pic, msg = result[0][0], result[0][1]
- button = get_btns(
- media, lsqry=query, lspage=int(page), result=result, user=user, auth=authbool
- )
- if (
- await SFW_GRPS.find_one({"id": gid})
- and media != "CHARACTER"
- and result[2].pop() == "True"
- ):
- button = get_btns(
- media,
- lsqry=query,
- lspage=int(page),
- result=result,
- user=user,
- auth=authbool,
- sfw="True",
- )
- await cq.edit_message_media(
- InputMediaPhoto(
- no_pic[random.randint(0, 4)],
- caption="""
-This material is marked 18+ and not allowed in this group""",
- ),
- reply_markup=button,
- )
- return
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=button
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg), reply_markup=button
- )
- await cq.answer()
-
-
-@app.on_callback_query(filters.regex(pattern=r"pgstudio_(.*)"))
-@check_user
-async def studio_pg_btn(client: Client, cq: CallbackQuery, cdata: dict):
- kek, page, qry, auth, user = cdata["data"].split("_")
- authbool = bool(1) if auth == "True" else bool(0)
- try:
- STUDIO_DB[qry]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- if "-100" in str(user):
- auser = await gcc(user)
- else:
- auser = user
- result = await get_studios(qry, page=page, user=auser, duser=user, auth=authbool)
- if len(result) == 1:
- return await cq.answer("No more results available!!!", show_alert=True)
- msg, buttons = result[0], result[1]
- await cq.edit_message_text(msg, reply_markup=buttons)
-
-
-@app.on_callback_query(filters.regex(pattern=r"stuani_(.*)"))
-@check_user
-async def studio_ani_btn(client: Client, cq: CallbackQuery, cdata: dict):
- kek, page, id_, rp, qry, auth, user = cdata["data"].split("_")
- authbool = bool(1) if auth == "True" else bool(0)
- if "-100" in str(user):
- auser = await gcc(user)
- else:
- auser = user
- result = await get_studio_animes(id_, page, qry, rp, auser, user, authbool)
- if len(result) == 1:
- return await cq.answer("No results available!!!", show_alert=True)
- msg, buttons = result[0], result[1]
- await cq.edit_message_text(msg, reply_markup=buttons)
-
-
-@app.on_callback_query(filters.regex(pattern=r"btn_(.*)"))
-@check_user
-async def anime_btn(client: Client, cq: CallbackQuery, cdata: dict):
- await cq.answer()
- query = cdata["data"].split("_")
- idm = query[1]
- user = int(query.pop())
- if "-100" in str(user):
- auser = await gcc(user)
- else:
- auser = user
- authbool = bool(1) if query[2] == "True" else bool(0)
- vars_ = {"id": int(idm)}
- cid = cdata["message"]["chat"]["id"]
- result = await get_anime(
- vars_, auth=authbool, user=auser, cid=cid if cid != user else None
- )
- pic, msg = result[0], result[1]
- btns = get_btns("ANIME", result=result, user=user, auth=authbool)
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=btns
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg), reply_markup=btns
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"topanimu_(.*)"))
-@check_user
-async def top_tags_btn(client: Client, cq: CallbackQuery, cdata: dict):
- await cq.answer()
- kek, gnr, page, user = cdata["data"].split("_")
- result = await get_top_animes(gnr, page=page, user=user)
- msg, buttons = result[0][0], result[1]
- await cq.edit_message_text(msg, reply_markup=buttons)
-
-
-@app.on_callback_query(filters.regex(pattern=r"settogl_(.*)"))
-async def nsfw_toggle_btn(client: Client, cq: CallbackQuery):
- cus = cq.from_user.id
- gid = cq.data.split("_").pop()
- try:
- k = (await client.get_chat_member(gid, cus)).status
- except UserNotParticipant:
- await cq.answer()
- return
- if cus not in BOT_OWNER and k == MEMBER:
- await cq.answer(
- "You don't have enough permissions to change this!!!", show_alert=True
- )
- return
- query = cq.data.split("_")
- if await SFW_GRPS.find_one({"id": int(query[2])}):
- sfw = "NSFW: Not Allowed"
- else:
- sfw = "NSFW: Allowed"
- if await AG.find_one({"_id": int(query[2])}):
- notif = "Airing notifications: ON"
- else:
- notif = "Airing notifications: OFF"
- if await CG.find_one({"_id": int(query[2])}):
- cr = "Crunchyroll Updates: ON"
- else:
- cr = "Crunchyroll Updates: OFF"
- if await SG.find_one({"_id": int(query[2])}):
- sp = "Subsplease Updates: ON"
- else:
- sp = "Subsplease Updates: OFF"
- if query[1] == "sfw":
- if await SFW_GRPS.find_one({"id": int(query[2])}):
- await SFW_GRPS.find_one_and_delete({"id": int(query[2])})
- sfw = "NSFW: Allowed"
- else:
- await SFW_GRPS.insert_one({"id": int(query[2])})
- sfw = "NSFW: Not Allowed"
- if query[1] == "notif":
- if await AG.find_one({"_id": int(query[2])}):
- await AG.find_one_and_delete({"_id": int(query[2])})
- notif = "Airing notifications: OFF"
- else:
- await AG.insert_one({"_id": int(query[2])})
- notif = "Airing notifications: ON"
- if query[1] == "cr":
- if await CG.find_one({"_id": int(query[2])}):
- await CG.find_one_and_delete({"_id": int(query[2])})
- cr = "Crunchyroll Updates: OFF"
- else:
- await CG.insert_one({"_id": int(query[2])})
- cr = "Crunchyroll Updates: ON"
- if query[1] == "sp":
- if await SG.find_one({"_id": int(query[2])}):
- await SG.find_one_and_delete({"_id": int(query[2])})
- sp = "Subsplease Updates: OFF"
- else:
- await SG.insert_one({"_id": int(query[2])})
- sp = "Subsplease Updates: ON"
- btns = InlineKeyboardMarkup(
- [
- [InlineKeyboardButton(text=sfw, callback_data=f"settogl_sfw_{query[2]}")],
- [
- InlineKeyboardButton(
- text=notif, callback_data=f"settogl_notif_{query[2]}"
- )
- ],
- [InlineKeyboardButton(text=cr, callback_data=f"settogl_cr_{query[2]}")],
- [InlineKeyboardButton(text=sp, callback_data=f"settogl_sp_{query[2]}")],
- [
- InlineKeyboardButton(
- text="Headlines", callback_data=f"headlines_call_{query[2]}"
- )
- ],
- [
- InlineKeyboardButton(
- text="Change UI", callback_data=f"cui_call_{query[2]}"
- )
- ],
- ]
- )
- await cq.answer()
- if query[1] == "call":
- await cq.edit_message_text(text=setting_text, reply_markup=btns)
- await cq.edit_message_reply_markup(reply_markup=btns)
-
-
-@app.on_callback_query(filters.regex(pattern=r"myacc_(.*)"))
-@check_user
-async def flex_btn(client: Client, cq: CallbackQuery, cdata: dict):
- await cq.answer()
- query = cdata["data"].split("_")[1]
- user = cdata["data"].split("_").pop()
- if "-100" in str(user):
- auser = await gcc(user)
- else:
- auser = user
- result = await get_user_activity(int(query), user=int(auser), duser=int(user))
- pic, msg, btns = result
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=btns
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg), reply_markup=btns
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"myfavs_(.*)"))
-@check_user
-async def list_favourites_btn(client: Client, cq: CallbackQuery, cdata: dict):
- await cq.answer()
- q = cdata["data"].split("_")
- btn = [
- [
- InlineKeyboardButton(
- "ANIME", callback_data=f"myfavqry_ANIME_{q[1]}_1_{q[2]}_{q[3]}"
- ),
- InlineKeyboardButton(
- "CHARACTER", callback_data=f"myfavqry_CHAR_{q[1]}_1_{q[2]}_{q[3]}"
- ),
- InlineKeyboardButton(
- "MANGA", callback_data=f"myfavqry_MANGA_{q[1]}_1_{q[2]}_{q[3]}"
- ),
- ]
- ]
- if q[2] == "yes":
- btn.append([InlineKeyboardButton("BACK", callback_data=f"getusrbc_{q[3]}")])
- else:
- btn.append(
- [InlineKeyboardButton("PROFILE", url=f"https://anilist.co/user/{q[1]}")]
- )
- try:
- await cq.edit_message_media(
- InputMediaPhoto(
- f"https://img.anili.st/user/{q[1]}?a={time.time()}",
- caption="Choose one of the below options",
- ),
- reply_markup=InlineKeyboardMarkup(btn),
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog(
- "Mikobot",
- f"https://img.anili.st/user/{q[1]}?a={time.time()}",
- "LINK",
- msg=cq,
- )
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption="Choose one of the below options"),
- reply_markup=InlineKeyboardMarkup(btn),
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"myfavqry_(.*)"))
-@check_user
-async def favourites_btn(client: Client, cq: CallbackQuery, cdata: dict):
- await cq.answer()
- q = cdata["data"].split("_")
- if "-100" in str(q[5]):
- auser = await gcc(q[5])
- else:
- auser = q[5]
- pic, msg, btns = await get_user_favourites(
- q[2], int(auser), q[1], q[3], q[4], duser=int(q[5])
- )
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=btns
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg), reply_markup=btns
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"getusrbc_(.*)"))
-@check_user
-async def get_user_back_btn(client: Client, cq: CallbackQuery, cdata: dict):
- await cq.answer()
- query = cdata["data"].split("_")[1]
- if "-100" in str(query):
- auser = await gcc(query)
- else:
- auser = query
- result = await get_user(None, "flex", user=int(auser), display_user=query)
- pic, msg, btns = result
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=btns
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg), creply_markup=btns
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"fav_(.*)"))
-@check_user
-async def toggle_favourites_btn(client: Client, cq: CallbackQuery, cdata: dict):
- query = cdata["data"].split("_")
- if query[1] == "ANIME" and len(query) > 4:
- try:
- ANIME_DB[query[3]]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- if query[1] == "MANGA":
- try:
- MANGA_DB[query[3]]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- if query[1] == "CHARACTER":
- try:
- CHAR_DB[query[3]]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- if query[1] == "STUDIO":
- try:
- STUDIO_DB[query[3]]
- except KeyError:
- return await cq.answer("Query Expired!!!\nCreate new one", show_alert=True)
- idm = int(query[2])
- user = int(query.pop())
- if "-100" in str(user):
- auser = await gcc(user)
- else:
- auser = user
- gid = cdata["message"]["chat"]["id"]
- rslt = await toggle_favourites(id_=idm, media=query[1], user=auser)
- if rslt == "ok":
- await cq.answer("Updated", show_alert=True)
- else:
- return await cq.answer("Failed to update!!!", show_alert=True)
- result = (
- (
- await get_anime(
- {"id": idm}, auth=True, user=auser, cid=gid if gid != user else None
- )
- )
- if query[1] == "ANIME" and len(query) == 3
- else (
- await get_anilist(
- query[3],
- page=int(query[4]),
- auth=True,
- user=auser,
- cid=gid if gid != user else None,
- )
- )
- if query[1] == "ANIME" and len(query) != 3
- else (
- await get_manga(
- query[3],
- page=int(query[4]),
- auth=True,
- user=auser,
- cid=gid if gid != user else None,
- )
- )
- if query[1] == "MANGA"
- else (await get_airing(query[3], auth=True, user=auser, ind=int(query[4])))
- if query[1] == "AIRING"
- else (await get_character(query[3], int(query[4]), auth=True, user=auser))
- if query[1] == "CHARACTER"
- else (
- await get_studios(
- query[3], int(query[4]), user=auser, auth=True, duser=user
- )
- )
- )
- if query[1] == "STUDIO":
- return await cq.edit_message_text(result[0], reply_markup=result[1])
- pic, msg = (
- (result[0], result[1])
- if query[1] == "ANIME" and len(query) == 3
- else (result[0])
- if query[1] == "AIRING"
- else (result[0], result[1][0])
- )
- btns = get_btns(
- query[1],
- result=result,
- user=user,
- auth=True,
- lsqry=query[3] if len(query) != 3 else None,
- lspage=int(query[4]) if len(query) != 3 else None,
- )
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=btns
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg), reply_markup=btns
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"(lsadd|lsupdt)_(.*)"))
-@check_user
-async def list_update_anilist_btn(client: Client, cq: CallbackQuery, cdata: dict):
- stts_ls = ["COMPLETED", "CURRENT", "PLANNING", "DROPPED", "PAUSED", "REPEATING"]
- query = cdata["data"].split("_")
- btns = []
- row = []
- for i in stts_ls:
- row.append(
- InlineKeyboardButton(
- text=i,
- callback_data=cq.data.replace("lsadd", f"lsas_{i}")
- if query[0] == "lsadd"
- else cq.data.replace("lsupdt", f"lsus_{i}"),
- )
- )
- if len(row) == 3:
- btns.append(row)
- row = []
- if query[0] == "lsupdt":
- btns.append(
- [
- InlineKeyboardButton(
- "DELETE", callback_data=cq.data.replace("lsupdt", f"dlt_{i}")
- )
- ]
- )
- await cq.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btns))
-
-
-@app.on_callback_query(
- filters.regex(pattern=r"browse_(upcoming|trending|popular)_(.*)")
-)
-@check_user
-async def browse_btn(client: Client, cq: CallbackQuery, cdata: dict):
- query = cdata["data"].split("_")
- if "•" in query[1]:
- return
- msg = await browse_(query[1])
- up = "Upcoming" if query[1] != "upcoming" else "• Upcoming •"
- tr = "Trending" if query[1] != "trending" else "• Trending •"
- pp = "Popular" if query[1] != "popular" else "• Popular •"
- btns = [
- [
- InlineKeyboardButton(tr, callback_data=f"browse_{tr.lower()}_{query[2]}"),
- InlineKeyboardButton(pp, callback_data=f"browse_{pp.lower()}_{query[2]}"),
- InlineKeyboardButton(up, callback_data=f"browse_{up.lower()}_{query[2]}"),
- ]
- ]
- await cq.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(btns))
-
-
-@app.on_callback_query(filters.regex(pattern=r"(lsas|lsus|dlt)_(.*)"))
-@check_user
-async def update_anilist_btn(client: Client, cq: CallbackQuery, cdata: dict):
- query = cdata["data"].split("_")
- if query[2] == "ANIME":
- if len(query) == 7:
- try:
- ANIME_DB[query[4]]
- except KeyError:
- return await cq.answer(
- "Query Expired!!!\nCreate new one", show_alert=True
- )
- if len(query) == 8:
- try:
- ANIME_DB[query[5]]
- except KeyError:
- return await cq.answer(
- "Query Expired!!!\nCreate new one", show_alert=True
- )
- if query[2] == "MANGA":
- if len(query) == 7:
- try:
- MANGA_DB[query[4]]
- except KeyError:
- return await cq.answer(
- "Query Expired!!!\nCreate new one", show_alert=True
- )
- if len(query) == 8:
- try:
- MANGA_DB[query[5]]
- except KeyError:
- return await cq.answer(
- "Query Expired!!!\nCreate new one", show_alert=True
- )
- idm = int(query[3])
- user = int(query.pop())
- if "-100" in str(user):
- auser = await gcc(user)
- else:
- auser = user
- gid = cdata["message"]["chat"]["id"]
- eid = None
- if query[0] != "lsas":
- eid = int(query[4])
- rslt = await update_anilist(
- id_=idm, req=query[0], status=query[1], user=auser, eid=eid
- )
- if rslt == "ok":
- await cq.answer("Updated", show_alert=True)
- else:
- await cq.answer(
- "Something unexpected happened and operation failed successfully",
- show_alert=True,
- )
- return
- result = (
- (
- await get_anime(
- {"id": idm}, auth=True, user=auser, cid=gid if gid != user else None
- )
- )
- if query[2] == "ANIME" and (len(query) == 4 or len(query) == 5)
- else (
- await get_anilist(
- query[4],
- page=int(query[5]),
- auth=True,
- user=auser,
- cid=gid if gid != user else None,
- )
- )
- if query[2] == "ANIME" and len(query) == 6
- else (
- await get_anilist(
- query[5],
- page=int(query[6]),
- auth=True,
- user=auser,
- cid=gid if gid != user else None,
- )
- )
- if query[2] == "ANIME" and len(query) == 7
- else (
- await get_manga(
- query[4],
- page=int(query[5]),
- auth=True,
- user=auser,
- cid=gid if gid != user else None,
- )
- )
- if query[2] == "MANGA" and len(query) == 6
- else (
- await get_manga(
- query[5],
- page=int(query[6]),
- auth=True,
- user=auser,
- cid=gid if gid != user else None,
- )
- )
- if query[2] == "MANGA" and len(query) == 7
- else (
- await get_airing(
- query[4] if eid is None else query[5],
- auth=True,
- user=auser,
- ind=int(query[5] if eid is None else query[6]),
- )
- )
- )
- pic, msg = (
- (result[0], result[1])
- if query[2] == "ANIME" and (len(query) == 4 or len(query) == 5)
- else (result[0])
- if query[2] == "AIRING"
- else (result[0], result[1][0])
- )
- btns = get_btns(
- query[2],
- result=result,
- user=user,
- auth=True,
- lsqry=query[4] if len(query) == 6 else query[5] if len(query) == 7 else None,
- lspage=int(query[5])
- if len(query) == 6
- else int(query[6])
- if len(query) == 7
- else None,
- )
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=btns
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg), reply_markup=btns
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"(desc|ls|char)_(.*)"))
-@check_user
-async def additional_info_btn(client: Client, cq: CallbackQuery, cdata: dict):
- q = cdata["data"].split("_")
- kek, qry, ctgry = q[0], q[1], q[2]
- info = (
- "Description"
- if kek == "desc"
- else "Series List"
- if kek == "ls"
- else "Characters List"
- )
- page = 0
- lsqry = f"_{q[3]}" if len(q) > 6 else ""
- lspg = f"_{q[4]}" if len(q) > 6 else ""
- if kek == "char":
- page = q[6] if len(q) > 6 else q[4]
- rjsdata = await get_additional_info(qry, ctgry, kek, page=int(page))
- pic, result = rjsdata[0], rjsdata[1]
- button = []
- spoiler = False
- bot = BOT_USERNAME
- if result is None:
- await cq.answer("No description available!!!", show_alert=True)
- return
- if "~!" in result and "!~" in result:
- result = re.sub(r"~!.*!~", "[Spoiler]", result)
- spoiler = True
- button.append(
- [
- InlineKeyboardButton(
- text="VIEW SPOILER",
- url=f"https://t.me/{bot}/?astart=des_{ctgry}_{qry}_desc",
- )
- ]
- )
- if len(result) > 1000:
- result = result[:940] + "..."
- if spoiler is False:
- result += "\n\nFor more info click below given button"
- button.append(
- [
- InlineKeyboardButton(
- text="MORE INFO",
- url=f"https://t.me/{bot}/?astart=des_{ctgry}_{qry}_{kek}",
- )
- ]
- )
- add_ = ""
- user = q.pop()
- if kek == "char":
- btndata = rjsdata[2]
- if btndata["lastPage"] != 1:
- qs = q[5] if len(q) != 5 else q[3]
- pre = f"{kek}_{qry}_{ctgry}{lsqry}{lspg}_{qs}_{int(page)-1}_{user}"
- nex = f"{kek}_{qry}_{ctgry}{lsqry}{lspg}_{qs}_{int(page)+1}_{user}"
- if page == "1":
- button.append([InlineKeyboardButton(text="NEXT", callback_data=nex)])
- elif btndata["lastPage"] == int(page):
- button.append([InlineKeyboardButton(text="PREV", callback_data=pre)])
- else:
- button.append(
- [
- InlineKeyboardButton(text="PREV", callback_data=pre),
- InlineKeyboardButton(text="NEXT", callback_data=nex),
- ]
- )
- add_ = f"\n\nTotal Characters: {btndata['total']}"
- msg = f"{info}:\n\n{result+add_}"
- cbd = (
- f"btn_{qry}_{q[3]}_{user}"
- if len(q) <= 5
- else f"page_ANIME{lsqry}{lspg}_{q[5]}_{user}"
- if ctgry == "ANI"
- else f"page_CHARACTER{lsqry}{lspg}_{q[5]}_{user}"
- )
- button.append([InlineKeyboardButton(text="BACK", callback_data=cbd)])
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=InlineKeyboardMarkup(button)
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg),
- reply_markup=InlineKeyboardMarkup(button),
- )
- await cq.answer()
-
-
-@app.on_callback_query(filters.regex(pattern=r"lsc_(.*)"))
-@check_user
-async def featured_in_btn(client: Client, cq: CallbackQuery, cdata: dict):
- kek, idm, qry, pg, auth, usr = cdata["data"].split("_")
- result = await get_featured_in_lists(int(idm), "ANI")
- req = "lscm"
- if result[0] is False:
- result = await get_featured_in_lists(int(idm), "MAN")
- req = None
- if result[0] is False:
- await cq.answer("No Data Available!!!", show_alert=True)
- return
- [msg, total], pic = result
- button = []
- totalpg, kek = divmod(total, 15)
- if kek != 0:
- totalpg + 1
- if total > 15:
- button.append(
- [
- InlineKeyboardButton(
- text="NEXT", callback_data=f"lsca_{idm}_1_{qry}_{pg}_{auth}_{usr}"
- )
- ]
- )
- if req is not None:
- button.append(
- [
- InlineKeyboardButton(
- text="MANGA", callback_data=f"lscm_{idm}_0_{qry}_{pg}_{auth}_{usr}"
- )
- ]
- )
- button.append(
- [
- InlineKeyboardButton(
- text="BACK", callback_data=f"page_CHARACTER_{qry}_{pg}_{auth}_{usr}"
- )
- ]
- )
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=InlineKeyboardMarkup(button)
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg),
- reply_markup=InlineKeyboardMarkup(button),
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"lsc(a|m)_(.*)"))
-@check_user
-async def featured_in_switch_btn(client: Client, cq: CallbackQuery, cdata: dict):
- req, idm, reqpg, qry, pg, auth, user = cdata["data"].split("_")
- result = await get_featured_in_lists(
- int(idm), "MAN" if req == "lscm" else "ANI", page=int(reqpg)
- )
- reqb = "lsca" if req == "lscm" else "lscm"
- bt = "Anime" if req == "lscm" else "Manga"
- if result[0] is False:
- await cq.answer("No Data Available!!!", show_alert=True)
- return
- [msg, total], pic = result
- totalpg, kek = divmod(total, 15)
- if kek != 0:
- totalpg + 1
- button = []
- if total > 15:
- nex = f"{req}_{idm}_{int(reqpg)+1}_{qry}_{pg}_{auth}_{user}"
- bac = f"{req}_{idm}_{int(reqpg)-1}_{qry}_{pg}_{auth}_{user}"
- if int(reqpg) == 0:
- button.append([InlineKeyboardButton(text="NEXT", callback_data=nex)])
- elif int(reqpg) == totalpg:
- button.append([InlineKeyboardButton(text="BACK", callback_data=bac)])
- else:
- button.append(
- [
- InlineKeyboardButton(text="BACK", callback_data=bac),
- InlineKeyboardButton(text="NEXT", callback_data=nex),
- ]
- )
- button.append(
- [
- InlineKeyboardButton(
- text=f"{bt}", callback_data=f"{reqb}_{idm}_0_{qry}_{pg}_{auth}_{user}"
- )
- ]
- )
- button.append(
- [
- InlineKeyboardButton(
- text="BACK", callback_data=f"page_CHARACTER_{qry}_{pg}_{auth}_{user}"
- )
- ]
- )
- try:
- await cq.edit_message_media(
- InputMediaPhoto(pic, caption=msg), reply_markup=InlineKeyboardMarkup(button)
- )
- except (WebpageMediaEmpty, WebpageCurlFailed):
- await clog("Mikobot", pic, "LINK", msg=cq)
- await cq.edit_message_media(
- InputMediaPhoto(failed_pic, caption=msg),
- reply_markup=InlineKeyboardMarkup(button),
- )
-
-
-headlines_text = """
-Turn LiveChart option on to get news feeds from livechart.me
-Turn MyAnimeList option on to get news feeds from myanimelist.net
-
-For Auto Pin and Auto Unpin features, give the bot "Pin Message" and "Delete Message" perms
-Auto Unpin can be customized, click on the button to see available options
-"""
-
-
-@app.on_callback_query(filters.regex(pattern=r"headlines_(.*)"))
-async def headlines_btn(client: Client, cq: CallbackQuery):
- cus = cq.from_user.id
- qry = cq.data.split("_")[1]
- gid = int(cq.data.split("_")[2])
- try:
- k = (await client.get_chat_member(gid, cus)).status
- except UserNotParticipant:
- await cq.answer()
- return
- if cus not in BOT_OWNER and k == MEMBER:
- await cq.answer(
- "You don't have enough permissions to change this!!!", show_alert=True
- )
- return
- lcdata = await HD.find_one({"_id": gid})
- maldata = await MHD.find_one({"_id": gid})
- lchd = "LiveChart: OFF"
- malhd = "MyAnimeList: OFF"
- malhdpin = lchdpin = "Auto Pin: OFF"
- malpin = lcpin = None
- if lcdata:
- lchd = "LiveChart: ON"
- try:
- lcpin = lcdata["pin"]
- lchdpin = f"Auto Pin: {lcpin}"
- except KeyError:
- pass
- if maldata:
- malhd = "MyAnimeList: ON"
- try:
- malpin = maldata["pin"]
- malhdpin = f"Auto Pin: {malpin}"
- except KeyError:
- pass
- if "mal" in qry:
- data = maldata
- pin = malpin
- pin_msg = malhdpin
- collection = MHD
- src_status = malhd
- srcname = "MyAnimeList"
- else:
- data = lcdata
- pin = lcpin
- pin_msg = lchdpin
- collection = HD
- src_status = lchd
- srcname = "LiveChart"
- if re.match(r"^(mal|lc)hd$", qry):
- if data:
- await collection.find_one_and_delete(data)
- src_status = f"{srcname}: OFF"
- pin_msg = f"Auto Pin: OFF"
- else:
- await collection.insert_one({"_id": gid})
- src_status = f"{srcname}: ON"
- pin_msg = f"Auto Pin: OFF"
- if re.match(r"^(mal|lc)hdpin$", qry):
- if data:
- if pin:
- switch = "ON" if pin == "OFF" else "OFF"
- await collection.find_one_and_update(
- data, {"$set": {"pin": switch, "unpin": None}}, upsert=True
- )
- pin_msg = f"Auto Pin: {switch}"
- else:
- await collection.find_one_and_update(
- data, {"$set": {"pin": "ON"}}, upsert=True
- )
- pin_msg = f"Auto Pin: ON"
- else:
- await cq.answer(f"Please enable {srcname} first!!!", show_alert=True)
- if "mal" in qry:
- malhdpin = pin_msg
- malhd = src_status
- else:
- lchdpin = pin_msg
- lchd = src_status
- btn = InlineKeyboardMarkup(
- [
- [InlineKeyboardButton(text=lchd, callback_data=f"headlines_lchd_{gid}")],
- [
- InlineKeyboardButton(
- text=lchdpin, callback_data=f"headlines_lchdpin_{gid}"
- ),
- InlineKeyboardButton(
- text="Auto Unpin (LC)", callback_data=f"anpin_call_lc_{gid}"
- ),
- ],
- [InlineKeyboardButton(text=malhd, callback_data=f"headlines_malhd_{gid}")],
- [
- InlineKeyboardButton(
- text=malhdpin, callback_data=f"headlines_malhdpin_{gid}"
- ),
- InlineKeyboardButton(
- text="Auto Unpin (MAL)", callback_data=f"anpin_call_mal_{gid}"
- ),
- ],
- [InlineKeyboardButton(text="BACK", callback_data=f"settogl_call_{gid}")],
- ]
- )
- await cq.edit_message_text(headlines_text, reply_markup=btn)
- await cq.answer()
-
-
-TIMES = {
- "1 day": 86400,
- "5 days": 432000,
- "1 week": 604800,
- "2 week": 1209600,
- "1 month": 2592000,
- "New Feed": 0,
- "OFF": None,
-}
-
-
-@app.on_callback_query(filters.regex(pattern=r"anpin_(.*)"))
-async def auto_unpin(client: Client, cq: CallbackQuery):
- cus = cq.from_user.id
- qry = cq.data.split("_")[1]
- src = cq.data.split("_")[2]
- gid = int(cq.data.split("_")[3])
- try:
- k = (await client.get_chat_member(gid, cus)).status
- except UserNotParticipant:
- await cq.answer()
- return
- if cus not in BOT_OWNER and k == MEMBER:
- await cq.answer(
- "You don't have enough permissions to change this!!!", show_alert=True
- )
- return
- cancel = False
- if src == "lc":
- srcname = "LiveChart"
- collection = HD
- else:
- srcname = "MyAnimeList"
- collection = MHD
- data = await collection.find_one({"_id": gid})
- if data:
- try:
- data["pin"]
- try:
- unpin = data["unpin"]
- except KeyError:
- unpin = None
- except KeyError:
- cancel = True
- else:
- cancel = True
- if cancel:
- return await cq.answer(
- f"Please enable {srcname} and Auto Pin option for them!!!", show_alert=True
- )
- setting = None
- if qry == "call":
- pass
- elif qry == "None":
- setting = {"unpin": None}
- elif qry.isdigit():
- if int(qry) == 0:
- unpin = int(qry)
- setting = {"unpin": 0}
- else:
- now = round(time.time(), -2)
- unpin = int(qry)
- setting = {"unpin": int(qry), "next_unpin": int(qry) + int(now)}
- if setting:
- await collection.find_one_and_update(data, {"$set": setting})
- btn = []
- row = []
- count = 0
- for i in TIMES.keys():
- count = count + 1
- row.append(
- InlineKeyboardButton(i, callback_data=f"unpin_{TIMES[i]}_{src}_{gid}")
- )
- if count == 3:
- btn.append(row)
- count = 0
- row = []
- if len(row) != 0:
- btn.append(row)
- btn.append([InlineKeyboardButton("BACK", callback_data=f"headlines_call_{gid}")])
- if type(unpin) is int:
- if unpin == 0:
- unpindata = "after Next Feed"
- else:
- unpindata = "after " + list(TIMES.keys())[list(TIMES.values()).index(unpin)]
- else:
- unpindata = "OFF"
- await cq.edit_message_text(
- f"Auto Unpin options for {srcname}\nCurrently set to: {unpindata}",
- reply_markup=InlineKeyboardMarkup(btn),
- )
- await cq.answer()
-
-
-BULLETS = ["➤", "•", "⚬", "▲", "▸", "△", "⋟", "»", "None"]
-
-
-@app.on_callback_query(filters.regex(pattern=r"cui_(.*)"))
-async def change_ui_btn(client: Client, cq: CallbackQuery):
- cus = cq.from_user.id
- qry = cq.data.split("_")[1]
- gid = cq.data.split("_")[2]
- try:
- k = (await client.get_chat_member(gid, cus)).status
- except UserNotParticipant:
- await cq.answer()
- return
- if cus not in BOT_OWNER and k == MEMBER:
- await cq.answer(
- "You don't have enough permissions to change this!!!", show_alert=True
- )
- return
- await cq.answer()
- row, btn = [], []
- for i in BULLETS:
- row.append(InlineKeyboardButton(text=i, callback_data=f"cui_{i}_{gid}"))
- if len(row) == 3:
- btn.append(row)
- row = []
- btn.append(row)
- btn.append(
- [
- InlineKeyboardButton(text="CAPS", callback_data=f"cui_Caps_{gid}"),
- InlineKeyboardButton(text="UPPER", callback_data=f"cui_UPPER_{gid}"),
- ]
- )
- btn.append([InlineKeyboardButton(text="BACK", callback_data=f"settogl_call_{gid}")])
- if qry in ["Caps", "UPPER"]:
- if await GUI.find_one({"_id": gid}):
- await GUI.update_one({"_id": gid}, {"$set": {"cs": qry}})
- else:
- await GUI.insert_one({"_id": gid, "bl": "➤", "cs": qry})
- elif qry != "call":
- bullet = qry
- if qry == "None":
- bullet = None
- if await GUI.find_one({"_id": gid}):
- await GUI.update_one({"_id": gid}, {"$set": {"bl": bullet}})
- else:
- await GUI.insert_one({"_id": gid, "bl": bullet, "cs": "UPPER"})
- bl = "➤"
- cs = "UPPER"
- if await GUI.find_one({"_id": gid}):
- data = await GUI.find_one({"_id": gid})
- bl = data["bl"]
- cs = data["cs"]
- text = f"""Selected bullet in this group: {bl}
-Selected text case in this group: {cs}"""
- await cq.edit_message_text(text, reply_markup=InlineKeyboardMarkup(btn))
-
-
-## For accepting commands from edited messages
-
-
-@app.on_edited_message(
- filters.command(["anime", f"anime{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def anime_edit_cmd(client: app, message: Message):
- await anime_cmd(client, message)
-
-
-@app.on_edited_message(
- filters.command(["manga", f"manga{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def manga_edit_cmd(client: app, message: Message):
- await manga_cmd(client, message)
-
-
-@app.on_edited_message(
- filters.command(["character", f"character{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def character_edit_cmd(client: app, message: Message):
- await character_cmd(client, message)
-
-
-@app.on_edited_message(
- filters.command(["anilist", f"anilist{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def anilist_edit_cmd(client: app, message: Message):
- await anilist_cmd(client, message)
-
-
-@app.on_edited_message(
- filters.command(["top", f"top{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def top_edit_cmd(client: app, message: Message):
- await top_tags_cmd(client, message)
-
-
-@app.on_edited_message(
- filters.command(["airing", f"airing{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def airing_edit_cmd(client: app, message: Message):
- await airing_cmd(client, message)
-
-
-@app.on_edited_message(
- ~filters.private
- & filters.command(
- ["anisettings", f"anisettings{BOT_USERNAME}"], prefixes=PREFIX_HANDLER
- )
-)
-async def settings_edit_cmd(client: app, message: Message):
- await settings_cmd(client, message)
-
-
-@app.on_edited_message(
- filters.command(["browse", f"browse{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def browse_edit_cmd(client: app, message: Message):
- await browse_cmd(client, message)
-
-
-@app.on_edited_message(
- filters.command(
- ["gettags", f"gettags{BOT_USERNAME}", "getgenres", f"getgenres{BOT_USERNAME}"],
- prefixes=PREFIX_HANDLER,
- )
-)
-async def tags_genres_edit_cmd(client: app, message: Message):
- await list_tags_genres_cmd(client, message)
-
-
-@app.on_message(
- filters.command(["studio", f"studio{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def studio_edit_cmd(client: Client, message: Message):
- await studio_cmd(client, message)
-
-
-@app.on_message(
- filters.command(["schedule", f"schedule{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def get_schuled(client: Client, message: Message, mdata: dict):
- """Get List of Scheduled Anime"""
- gid = mdata["chat"]["id"]
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "schedule" in find_gc["cmd_list"].split():
- return
- x = await client.send_message(gid, "Fetching Scheduled Animes
")
- try:
- user = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- msg = await get_scheduled()
- buttons = get_btns("SCHEDULED", result=[msg[1]], user=user)
- await x.edit_text(msg[0], reply_markup=buttons)
-
-
-@app.on_callback_query(filters.regex(pattern=r"sched_(.*)"))
-@check_user
-async def ns_(client: app, cq: CallbackQuery, cdata: dict):
- kek, day, user = cdata["data"].split("_")
- msg = await get_scheduled(int(day))
- buttons = get_btns("SCHEDULED", result=[int(day)], user=user)
- await cq.edit_message_text(msg[0], reply_markup=buttons)
-
-
-@app.on_edited_message(
- filters.command(["schedule", f"schedule{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def get_schuled_edit(client: Client, message: Message):
- await get_schuled(client, message)
-
-
-@app.on_message(
- filters.command(["watch", f"watch{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def get_watch_order(client: Client, message: Message, mdata: dict):
- """Get List of Scheduled Anime"""
- gid = mdata["chat"]["id"]
- find_gc = await DC.find_one({"_id": gid})
- if find_gc is not None and "watch" in find_gc["cmd_list"].split():
- return
- x = message.text.split(" ", 1)
- if len(x) == 1:
- await message.reply_text("Nothing given to search for!!!")
- return
- try:
- user = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- data = get_wols(x[1])
- msg = f"Found related animes for the query {x[1]}"
- buttons = []
- if data == []:
- await client.send_message(gid, "No results found!!!")
- return
- for i in data:
- buttons.append(
- [
- InlineKeyboardButton(
- str(i[1]), callback_data=f"watch_{i[0]}_{x[1]}_0_{user}"
- )
- ]
- )
- await client.send_message(gid, msg, reply_markup=InlineKeyboardMarkup(buttons))
-
-
-@app.on_callback_query(filters.regex(pattern=r"watch_(.*)"))
-@check_user
-async def watch_(client: app, cq: CallbackQuery, cdata: dict):
- kek, id_, qry, req, user = cdata["data"].split("_")
- msg, total = get_wo(int(id_), int(req))
- totalpg, lol = divmod(total, 50)
- button = []
- if lol != 0:
- totalpg + 1
- if total > 50:
- if int(req) == 0:
- button.append(
- [
- InlineKeyboardButton(
- text="NEXT",
- callback_data=f"{kek}_{id_}_{qry}_{int(req)+1}_{user}",
- )
- ]
- )
- elif int(req) == totalpg:
- button.append(
- [
- InlineKeyboardButton(
- text="PREV",
- callback_data=f"{kek}_{id_}_{qry}_{int(req)-1}_{user}",
- )
- ]
- )
- else:
- button.append(
- [
- InlineKeyboardButton(
- text="PREV",
- callback_data=f"{kek}_{id_}_{qry}_{int(req)-1}_{user}",
- ),
- InlineKeyboardButton(
- text="NEXT",
- callback_data=f"{kek}_{id_}_{qry}_{int(req)+1}_{user}",
- ),
- ]
- )
- button.append([InlineKeyboardButton("Back", callback_data=f"wol_{qry}_{user}")])
- await cq.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(button))
-
-
-@app.on_callback_query(filters.regex(pattern=r"wol_(.*)"))
-@check_user
-async def wls(client: app, cq: CallbackQuery, cdata: dict):
- kek, qry, user = cdata["data"].split("_")
- data = get_wols(qry)
- msg = f"Found related animes for the query {qry}"
- buttons = []
- for i in data:
- buttons.append(
- [
- InlineKeyboardButton(
- str(i[1]), callback_data=f"watch_{i[0]}_{qry}_0_{user}"
- )
- ]
- )
- await cq.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(buttons))
-
-
-@app.on_edited_message(
- filters.command(["watch", f"watch{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def get_watch_order_edit(client: Client, message: Message):
- await get_watch_order(client, message)
-
-
-@app.on_message(
- filters.command(["fillers", f"fillers{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-@control_user
-async def fillers_cmd(client: app, message: Message, mdata: dict):
- find_gc = await DC.find_one({"_id": mdata["chat"]["id"]})
- try:
- user = mdata["from_user"]["id"]
- except KeyError:
- user = mdata["sender_chat"]["id"]
- if find_gc is not None and "watch" in find_gc["cmd_list"].split():
- return
- qry = mdata["text"].split(" ", 1)
- if len(qry) == 1:
- return await message.reply_text(
- """Give some anime name to search fillers for
-example: /fillers Detective Conan"""
- )
- k = search_filler(qry[1])
- if k == {}:
- await message.reply_text("No fillers found for the given anime...")
- return
- button = []
- list_ = list(k.keys())
- if len(list_) == 1:
- result = parse_filler(k.get(list_[0]))
- msg = ""
- msg += f"Fillers for anime `{list_[0]}`\n\nManga Canon episodes:\n"
- msg += str(result.get("total_ep"))
- msg += "\n\nMixed/Canon fillers:\n"
- msg += str(result.get("mixed_ep"))
- msg += "\n\nFillers:\n"
- msg += str(result.get("filler_ep"))
- if result.get("ac_ep") is not None:
- msg += "\n\nAnime Canon episodes:\n"
- msg += str(result.get("ac_ep"))
- await message.reply_text(msg)
- return
- for i in list_:
- fl_js = rand_key()
- FILLERS[fl_js] = [k.get(i), i]
- button.append([InlineKeyboardButton(i, callback_data=f"fill_{fl_js}_{user}")])
- await message.reply_text(
- "Pick anime you want to see fillers list for:",
- reply_markup=InlineKeyboardMarkup(button),
- )
-
-
-@app.on_callback_query(filters.regex(pattern=r"fill_(.*)"))
-@check_user
-async def filler_btn(client: app, cq: CallbackQuery, cdata: dict):
- kek, req, user = cdata["data"].split("_")
- result = parse_filler((FILLERS.get(req))[0])
- msg = ""
- msg += f"**Fillers for anime** `{(FILLERS.get(req))[1]}`"
- msg += "\n\n**Manga Canon episodes:**\n"
- msg += str(result.get("total_ep"))
- msg += "\n\n**Mixed/Canon fillers:**\n"
- msg += str(result.get("mixed_ep"))
- msg += "\n\n**Fillers:**\n"
- msg += str(result.get("filler_ep"))
- if result.get("ac_ep") is not None:
- msg += "\n\n**Anime Canon episodes:**\n"
- msg += str(result.get("ac_ep"))
- await cq.edit_message_text(msg)
-
-
-@app.on_message(
- filters.command(["fillers", f"fillers{BOT_USERNAME}"], prefixes=PREFIX_HANDLER)
-)
-async def fillers_cmd(client: app, message: Message):
- await fillers_cmd(client, message)
-
-
-@app.on_message(filters.command("animequotes"))
-async def animequotes(client, message):
- name = (
- message.reply_to_message.from_user.first_name
- if message.reply_to_message
- else message.from_user.first_name
- )
- keyboard = [[InlineKeyboardButton(text="CHANGE", callback_data="changek_quote")]]
- await message.reply_photo(
- photo=random.choice(QUOTES_IMG),
- reply_markup=InlineKeyboardMarkup(keyboard),
- )
-
-
-@app.on_callback_query(filters.regex("changek_quote"))
-async def changek_quote(client, callback_query):
- keyboard = [[InlineKeyboardButton(text="CHANGE", callback_data="changek_quote")]]
- await callback_query.edit_message_media(
- media=InputMediaPhoto(media=random.choice(QUOTES_IMG)),
- reply_markup=InlineKeyboardMarkup(keyboard),
- )
-
-
-QUOTES_IMG = [
- "https://i.imgur.com/Iub4RYj.jpg",
- "https://i.imgur.com/uvNMdIl.jpg",
- "https://i.imgur.com/YOBOntg.jpg",
- "https://i.imgur.com/fFpO2ZQ.jpg",
- "https://i.imgur.com/f0xZceK.jpg",
- "https://i.imgur.com/RlVcCip.jpg",
- "https://i.imgur.com/CjpqLRF.jpg",
- "https://i.imgur.com/8BHZDk6.jpg",
- "https://i.imgur.com/8bHeMgy.jpg",
- "https://i.imgur.com/5K3lMvr.jpg",
- "https://i.imgur.com/NTzw4RN.jpg",
- "https://i.imgur.com/wJxryAn.jpg",
- "https://i.imgur.com/9L0DWzC.jpg",
- "https://i.imgur.com/sBe8TTs.jpg",
- "https://i.imgur.com/1Au8gdf.jpg",
- "https://i.imgur.com/28hFQeU.jpg",
- "https://i.imgur.com/Qvc03JY.jpg",
- "https://i.imgur.com/gSX6Xlf.jpg",
- "https://i.imgur.com/iP26Hwa.jpg",
- "https://i.imgur.com/uSsJoX8.jpg",
- "https://i.imgur.com/OvX3oHB.jpg",
- "https://i.imgur.com/JMWuksm.jpg",
- "https://i.imgur.com/lhM3fib.jpg",
- "https://i.imgur.com/64IYKkw.jpg",
- "https://i.imgur.com/nMbyA3J.jpg",
- "https://i.imgur.com/7KFQhY3.jpg",
- "https://i.imgur.com/mlKb7zt.jpg",
- "https://i.imgur.com/JCQGJVw.jpg",
- "https://i.imgur.com/hSFYDEz.jpg",
- "https://i.imgur.com/PQRjAgl.jpg",
- "https://i.imgur.com/ot9624U.jpg",
- "https://i.imgur.com/iXmqN9y.jpg",
- "https://i.imgur.com/RhNBeGr.jpg",
- "https://i.imgur.com/tcMVNa8.jpg",
- "https://i.imgur.com/LrVg810.jpg",
- "https://i.imgur.com/TcWfQlz.jpg",
- "https://i.imgur.com/muAUdvJ.jpg",
- "https://i.imgur.com/AtC7ZRV.jpg",
- "https://i.imgur.com/sCObQCQ.jpg",
- "https://i.imgur.com/AJFDI1r.jpg",
- "https://i.imgur.com/TCgmRrH.jpg",
- "https://i.imgur.com/LMdmhJU.jpg",
- "https://i.imgur.com/eyyax0N.jpg",
- "https://i.imgur.com/YtYxV66.jpg",
- "https://i.imgur.com/292w4ye.jpg",
- "https://i.imgur.com/6Fm1vdw.jpg",
- "https://i.imgur.com/2vnBOZd.jpg",
- "https://i.imgur.com/j5hI9Eb.jpg",
- "https://i.imgur.com/cAv7pJB.jpg",
- "https://i.imgur.com/jvI7Vil.jpg",
- "https://i.imgur.com/fANpjsg.jpg",
- "https://i.imgur.com/5o1SJyo.jpg",
- "https://i.imgur.com/dSVxmh8.jpg",
- "https://i.imgur.com/02dXlAD.jpg",
- "https://i.imgur.com/htvIoGY.jpg",
- "https://i.imgur.com/hy6BXOj.jpg",
- "https://i.imgur.com/OuwzNYu.jpg",
- "https://i.imgur.com/L8vwvc2.jpg",
- "https://i.imgur.com/3VMVF9y.jpg",
- "https://i.imgur.com/yzjq2n2.jpg",
- "https://i.imgur.com/0qK7TAN.jpg",
- "https://i.imgur.com/zvcxSOX.jpg",
- "https://i.imgur.com/FO7bApW.jpg",
- "https://i.imgur.com/KK06gwg.jpg",
- "https://i.imgur.com/6lG4tsO.jpg",
-]
-
-
-# <================================================= HELP ======================================================>
-__help__ = """
-⛩ *Anime:*
-
-➠ *Mikobot provides you the best anime-based commands including anime news and much more!*
-
-➠ *Commands:*
-
-» /anime: fetches info on single anime (includes buttons to look up for prequels and sequels)
-» /character: fetches info on multiple possible characters related to query
-» /manga: fetches info on multiple possible mangas related to query
-» /airing: fetches info on airing data for anime
-» /studio: fetches info on multiple possible studios related to query
-» /schedule: fetches scheduled animes
-» /browse: get popular, trending or upcoming animes
-
-➠ /animequotes: get random anime quotes
-
-» /anisettings: to toggle NSFW lock and airing notifications and other settings in groups (anime news)
-» /top: to retrieve top animes for a genre or tag
-» /watch: fetches watch order for anime series
-» /fillers: to get a list of anime fillers
-» /gettags: get a list of available tags
-» /getgenres - Get list of available Genres
-"""
-
-__mod_name__ = "ANIME"
-# <================================================== END =====================================================>