anime.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. # Part of Pull Req #2 by @MaskedVirus | github.com/swatv3nub
  2. import time
  3. from datetime import timedelta
  4. import requests
  5. from pyrogram import filters
  6. from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
  7. from wbb import app
  8. from wbb.core.decorators.errors import capture_err
  9. __MODULE__ = "Anime"
  10. __HELP__ = """
  11. /anime - search anime on AniList
  12. /manga - search manga on Anilist
  13. /char - search character on Anilist
  14. """
  15. def shorten(description, info="anilist.co"):
  16. ms_g = ""
  17. if len(description) > 700:
  18. description = description[0:500] + "...."
  19. ms_g += (
  20. f"\n**Description**: __{description}__[More here]({info})"
  21. )
  22. else:
  23. ms_g += f"\n**Description**: __{description}__"
  24. return (
  25. ms_g.replace("<br>", "")
  26. .replace("</br>", "")
  27. .replace("<i>", "")
  28. .replace("</i>", "")
  29. )
  30. def t(milliseconds: int) -> str:
  31. """Inputs time in milliseconds, to get beautified time,
  32. as string"""
  33. seconds, milliseconds = divmod(int(milliseconds), 1000)
  34. minutes, seconds = divmod(seconds, 60)
  35. hours, minutes = divmod(minutes, 60)
  36. days, hours = divmod(hours, 24)
  37. tmp = (
  38. ((str(days) + " Days, ") if days else "")
  39. + ((str(hours) + " Hours, ") if hours else "")
  40. + ((str(minutes) + " Minutes, ") if minutes else "")
  41. + ((str(seconds) + " Seconds, ") if seconds else "")
  42. + ((str(milliseconds) + " ms, ") if milliseconds else "")
  43. )
  44. return tmp[:-2]
  45. airing_query = """
  46. query ($id: Int,$search: String) {
  47. Media (id: $id, type: ANIME,search: $search) {
  48. id
  49. episodes
  50. title {
  51. romaji
  52. english
  53. native
  54. }
  55. siteUrl
  56. nextAiringEpisode {
  57. airingAt
  58. timeUntilAiring
  59. episode
  60. }
  61. }
  62. }
  63. """
  64. fav_query = """
  65. query ($id: Int) {
  66. Media (id: $id, type: ANIME) {
  67. id
  68. title {
  69. romaji
  70. english
  71. native
  72. }
  73. }
  74. }
  75. """
  76. anime_query = """
  77. query ($id: Int,$search: String) {
  78. Media (id: $id, type: ANIME,search: $search) {
  79. id
  80. idMal
  81. title {
  82. romaji
  83. english
  84. native
  85. }
  86. description (asHtml: false)
  87. startDate{
  88. year
  89. }
  90. episodes
  91. season
  92. type
  93. format
  94. status
  95. duration
  96. siteUrl
  97. studios{
  98. nodes{
  99. name
  100. }
  101. }
  102. trailer{
  103. id
  104. site
  105. thumbnail
  106. }
  107. averageScore
  108. genres
  109. bannerImage
  110. }
  111. }
  112. """
  113. character_query = """
  114. query ($query: String) {
  115. Character (search: $query) {
  116. id
  117. name {
  118. first
  119. last
  120. full
  121. }
  122. siteUrl
  123. favourites
  124. image {
  125. large
  126. }
  127. description
  128. }
  129. }
  130. """
  131. manga_query = """
  132. query ($id: Int,$search: String) {
  133. Media (id: $id, type: MANGA,search: $search) {
  134. id
  135. title {
  136. romaji
  137. english
  138. native
  139. }
  140. description (asHtml: false)
  141. startDate{
  142. year
  143. }
  144. type
  145. format
  146. status
  147. siteUrl
  148. averageScore
  149. genres
  150. bannerImage
  151. }
  152. }
  153. """
  154. def format_bytes(size):
  155. size = int(size)
  156. power = 1024
  157. n = 0
  158. power_labels = {0: "", 1: "K", 2: "M", 3: "G", 4: "T"}
  159. while size > power:
  160. size /= power
  161. n += 1
  162. return f"{size:.2f} {power_labels[n]+'B'}"
  163. def return_progress_string(current, total):
  164. filled_length = int(30 * current // total)
  165. return (
  166. "[" + "=" * filled_length + " " * (30 - filled_length) + "]"
  167. )
  168. def calculate_eta(current, total, start_time):
  169. if not current:
  170. return "00:00:00"
  171. end_time = time.time()
  172. elapsed_time = end_time - start_time
  173. seconds = (elapsed_time * (total / current)) - elapsed_time
  174. thing = "".join(
  175. str(timedelta(seconds=seconds)).split(".")[:-1]
  176. ).split(", ")
  177. thing[-1] = thing[-1].rjust(8, "0")
  178. return ", ".join(thing)
  179. url = "https://graphql.anilist.co"
  180. @app.on_message(filters.command("anime"))
  181. @capture_err
  182. async def anime_search(_, message):
  183. if len(message.command) < 2:
  184. await message.delete()
  185. return
  186. search = message.text.split(None, 1)[1]
  187. variables = {"search": search}
  188. json = (
  189. requests.post(
  190. url, json={"query": anime_query, "variables": variables}
  191. )
  192. .json()["data"]
  193. .get("Media", None)
  194. )
  195. if json:
  196. msg = f"**{json['title']['romaji']}**(`{json['title']['native']}`)\n**Type**: {json['format']}\n**Status**: {json['status']}\n**Episodes**: {json.get('episodes', 'N/A')}\n**Duration**: {json.get('duration', 'N/A')} Per Ep.\n**Score**: {json['averageScore']}\n**Genres**: `"
  197. for x in json["genres"]:
  198. msg += f"{x}, "
  199. msg = msg[:-2] + "`\n"
  200. msg += "**Studios**: `"
  201. for x in json["studios"]["nodes"]:
  202. msg += f"{x['name']}, "
  203. msg = msg[:-2] + "`\n"
  204. info = json.get("siteUrl")
  205. trailer = json.get("trailer", None)
  206. if trailer:
  207. trailer_id = trailer.get("id", None)
  208. site = trailer.get("site", None)
  209. if site == "youtube":
  210. trailer = "https://youtu.be/" + trailer_id
  211. description = (
  212. json.get("description", "N/A")
  213. .replace("<i>", "")
  214. .replace("</i>", "")
  215. .replace("<br>", "")
  216. )
  217. msg += shorten(description, info)
  218. image = info.replace(
  219. "anilist.co/anime/", "img.anili.st/media/"
  220. )
  221. if trailer:
  222. buttons = [
  223. [
  224. InlineKeyboardButton("More Info", url=info),
  225. InlineKeyboardButton("Trailer", url=trailer),
  226. ]
  227. ]
  228. else:
  229. buttons = [[InlineKeyboardButton("More Info", url=info)]]
  230. if image:
  231. try:
  232. await message.reply_photo(
  233. image,
  234. caption=msg,
  235. reply_markup=InlineKeyboardMarkup(buttons),
  236. )
  237. except Exception:
  238. msg += f" [✔️️]({image})"
  239. await message.edit(msg)
  240. else:
  241. await message.edit(msg)
  242. @app.on_message(filters.command("manga"))
  243. @capture_err
  244. async def manga_search(_, message):
  245. if len(message.command) < 2:
  246. await message.delete()
  247. return
  248. search = message.text.split(None, 1)[1]
  249. variables = {"search": search}
  250. json = (
  251. requests.post(
  252. url, json={"query": manga_query, "variables": variables}
  253. )
  254. .json()["data"]
  255. .get("Media", None)
  256. )
  257. ms_g = ""
  258. if json:
  259. title, title_native = json["title"].get(
  260. "romaji", False
  261. ), json["title"].get("native", False)
  262. start_date, status, score = (
  263. json["startDate"].get("year", False),
  264. json.get("status", False),
  265. json.get("averageScore", False),
  266. )
  267. if title:
  268. ms_g += f"**{title}**"
  269. if title_native:
  270. ms_g += f"(`{title_native}`)"
  271. if start_date:
  272. ms_g += f"\n**Start Date** - `{start_date}`"
  273. if status:
  274. ms_g += f"\n**Status** - `{status}`"
  275. if score:
  276. ms_g += f"\n**Score** - `{score}`"
  277. ms_g += "\n**Genres** - "
  278. for x in json.get("genres", []):
  279. ms_g += f"{x}, "
  280. ms_g = ms_g[:-2]
  281. image = json.get("bannerImage", False)
  282. ms_g += f"_{json.get('description', None)}_"
  283. if image:
  284. try:
  285. await message.reply_photo(image, caption=ms_g)
  286. except Exception:
  287. ms_g += f" [✔️️]({image})"
  288. await message.reply(ms_g)
  289. else:
  290. await message.reply(ms_g)
  291. @app.on_message(filters.command("char"))
  292. @capture_err
  293. async def character_search(_, message):
  294. if len(message.command) < 2:
  295. await message.delete()
  296. return
  297. search = message.text.split(None, 1)[1]
  298. variables = {"query": search}
  299. json = (
  300. requests.post(
  301. url,
  302. json={"query": character_query, "variables": variables},
  303. )
  304. .json()["data"]
  305. .get("Character", None)
  306. )
  307. if json:
  308. ms_g = f"**{json.get('name').get('full')}**(`{json.get('name').get('native')}`)\n"
  309. description = f"{json['description']}"
  310. site_url = json.get("siteUrl")
  311. ms_g += shorten(description, site_url)
  312. image = json.get("image", None)
  313. if image:
  314. image = image.get("large")
  315. await message.reply_photo(image, caption=ms_g)
  316. else:
  317. await message.reply(ms_g)