async def help_m(c: Korone, m: Message): module = m.matches[0]["module"] if m.chat.type == "private": if module in COMMANDS_HELP.keys() or module in [ "commands", "filters", "start", ]: await help_module(c, m, module) else: await m.reply_text( f"Desculpe! Não encontrei o módulo <code>{module}</code>, " "verifique sua pesquisa e tente novamente.") elif module in COMMANDS_HELP.keys(): keyboard = [[( "Ir ao PV", f"https://t.me/{c.me.username}/?start=help_{module}", "url", )]] await m.reply_text(text="Para ver isso, vá ao meu PV.", reply_markup=c.ikb(keyboard)) else: keyboard = [[("Ir ao PV", f"https://t.me/{c.me.username}/?start", "url")]] await m.reply_text( "Este módulo não existe, vá ao meu PV para ver os módulos que possuo!", reply_markup=c.ikb(keyboard), )
async def anilist_character(c: Korone, m: Message): query = m.matches[0]["search"] if query.isdecimal(): character_id = int(query) else: try: async with anilist.AsyncClient() as client: results = await client.search(query, "char", page=1, limit=1) character_id = results[0].id except IndexError: return await m.reply_text( "Algo deu errado, verifique sua pesquisa e tente novamente!" ) async with anilist.AsyncClient() as client: character = await client.get(character_id, "char") if not character: return await m.reply_text( f"Desculpe! Nenhum <b>personagem</b> com o ID <code>{character_id}</code> foi encontrado..." ) if hasattr(character, "description"): description = character.description description = description.replace("__", "**") description = description.replace("~", "~~") if len(character.description) > 700: description = f"{description[0:500]}[...]" text = f"<b>{character.name.full}</b> (<code>{character.name.native}</code>)" text += f"\n<b>ID:</b> <code>{character.id}</code>" if hasattr(character, "favorites"): text += f"\n<b>Favoritos:</b> <code>{character.favorites}</code>" if hasattr(character, "description"): text += f"\n\n<b>Sobre:</b>\n{html.escape(description)}" keyboard = [[("Mais informações", character.url, "url")]] if hasattr(character, "image"): if hasattr(character.image, "large"): photo = character.image.large elif hasattr(character.image, "medium"): photo = character.image.medium await m.reply_photo( photo=photo, caption=text, reply_markup=c.ikb(keyboard), parse_mode="combined", ) else: await m.reply_text( text, reply_markup=c.ikb(keyboard), parse_mode="combined", )
async def cleanup(c: Korone, m: Message): if m.chat.type == "private": await m.reply_text("Este comando é para ser usado em grupos!") return member = await c.get_chat_member(chat_id=m.chat.id, user_id=m.from_user.id) if member.status in ["administrator", "creator"]: deleted = [] sent = await m.reply_text("Iniciando limpeza...") async for t in c.iter_chat_members(chat_id=m.chat.id, filter="all"): if t.user.is_deleted: try: await c.ban_chat_member(m.chat.id, t.user.id) await m.chat.unban_member(t.user.id) deleted.append(t) except BadRequest: pass except Forbidden as e: await m.reply_text( f"Eu estou impedido de executar este comando! >-<\n<b>Erro:</b> <code>{e}</code>" ) return if deleted: await sent.edit_text( f"Removi todas as {len(deleted)} contas excluídas do grupo!" ) else: await sent.edit_text("Não há contas excluídas no grupo!") else: await m.reply_text("Bakayarou! Você não é um administrador...")
async def upgrade(c: Korone, m: Message): sm = await m.reply_text("Verificando...") await (await asyncio.create_subprocess_shell("git fetch origin")).communicate() proc = await asyncio.create_subprocess_shell( "git log HEAD..origin/main", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT, ) stdout = (await proc.communicate())[0].decode() if proc.returncode == 0: if len(stdout) <= 0: return await sm.edit_text("Não há nada para atualizar.") changelog = "<b>Changelog</b>:\n" commits = parse_commits(stdout) for hash, commit in commits.items(): changelog += f" - [<code>{hash[:7]}</code>] {commit['title']}\n" changelog += f"\n<b>New commits count</b>: <code>{len(commits)}</code>." keyboard = [[("🆕 Atualizar", "upgrade")]] await sm.edit_text(changelog, reply_markup=c.ikb(keyboard)) else: lines = stdout.split("\n") error = "".join(f"<code>{line}</code>\n" for line in lines) await sm.edit_text( f"Falha na atualização (process exited with {proc.returncode}):\n{error}" )
async def start(c: Korone, m: Union[Message, CallbackQuery]): if isinstance(m, Message): query = m.text.split() if len(query) > 1: field = query[1] query = field.split("_") if query[0] == "help": module = query[1] await help_module(c, m, module) else: keyboard = [] text = (start_text).format( m.from_user.first_name, c.me.first_name, korone.__version__, c.version_code, ) if m.chat.type == "private": keyboard.append([("📚 Ajuda", "help_cb"), ("ℹ️ Sobre", "about")]) keyboard.append([("👥 Grupo Off-Topic", "https://t.me/SpamTherapy", "url")]) else: keyboard.append([( "Clique aqui para obter ajuda!", f"http://t.me/{c.me.username}?start", "url", )]) text += "\nVocê pode ver tudo que eu posso fazer clicando no botão abaixo..." await m.reply_text( text, reply_markup=c.ikb(keyboard), ) if isinstance(m, CallbackQuery): text = (start_text).format( m.from_user.first_name, c.me.first_name, korone.__version__, c.version_code, ) keyboard = [ [("📚 Ajuda", "help_cb"), ("ℹ️ Sobre", "about")], [("👥 Grupo Off-Topic", "https://t.me/SpamTherapy", "url")], ] with suppress(MessageNotModified): await m.message.edit_text(text, reply_markup=c.ikb(keyboard))
async def help_c(c: Korone, m: Union[Message, CallbackQuery]): if isinstance(m, Message) and m.chat.type in ["supergroup", "group"]: keyboard = [[("Ir ao PV", f"https://t.me/{c.me.username}/?start", "url")]] await m.reply_text("Para obter ajuda vá ao meu PV!", reply_markup=c.ikb(keyboard)) elif isinstance(m, (Message, CallbackQuery)): await help_module(c, m)
async def mcserver(c: Korone, m: Union[Message, CallbackQuery]): args = m.matches[0]["ip"] time = datetime.datetime.now() if isinstance(m, CallbackQuery): reply = m.message else: reply = await m.reply_text("Obtendo informações...") try: r = await http.get(f"https://api.mcsrvstat.us/2/{args}") except TimeoutException: await reply.edit("Desculpe, não consegui me conectar a API!") return if r.status_code in [500, 504, 505]: await reply.edit("A API está indisponível ou com instabilidade!") return keyboard = [[("🔄️ Atualizar", f"mcserver_{args}")]] a = r.json() if a["online"]: text = "<b>Minecraft Server:</b>" text += f"\n<b>IP:</b> {a['hostname'] if 'hostname' in a else a['ip']} (<code>{a['ip']}</code>)" text += f"\n<b>Port:</b> <code>{a['port']}</code>" text += f"\n<b>Online:</b> <code>{a['online']}</code>" text += f"\n<b>Mods:</b> <code>{len(a['mods']['names']) if 'mods' in a else 'N/A'}</code>" text += f"\n<b>Players:</b> <code>{a['players']['online']}/{a['players']['max']}</code>" if "list" in a["players"]: text += "\n<b>Players list:</b> {}".format( ", ".join( f"<a href='https://namemc.com/profile/{name}'>{name}</a>" for name in a["players"]["list"] ) ) text += f"\n<b>Version:</b> <code>{a['version']}</code>" try: text += f"\n<b>Software:</b> <code>{a['software']}</code>" except KeyError: pass text += f"\n<b>MOTD:</b> <i>{a['motd']['clean'][0]}</i>" text += f"\n\n<b>UPDATED:</b> <i>{time.strftime('%d/%m/%Y %H:%M:%S')}</i>" elif not a["ip"] or a["ip"] == "127.0.0.1": return await reply.edit("Isso não é um IP/domínio válido!") else: text = ( "<b>Minecraft Server</b>:" f"\n<b>IP:</b> {a['hostname'] if 'hostname' in a else a['ip']} (<code>{a['ip']}</code>)" f"\n<b>Port:</b> <code>{a['port']}</code>" f"\n<b>Online:</b> <code>{a['online']}</code>" f"\n\n<b>UPDATED:</b> <i>{time.strftime('%d/%m/%Y %H:%M:%S')}</i>" ) await reply.edit_text( text, disable_web_page_preview=True, reply_markup=c.ikb(keyboard) )
async def anilist_manga(c: Korone, m: Message): query = m.matches[0]["search"] if query.isdecimal(): manga_id = int(query) else: try: async with anilist.AsyncClient() as client: results = await client.search(query, "manga", page=1, limit=1) manga_id = results[0].id except IndexError: return await m.reply_text( "Algo deu errado, verifique sua pesquisa e tente novamente!" ) async with anilist.AsyncClient() as client: manga = await client.get(manga_id, "manga") if not manga: return await m.reply_text( f"Desculpe! Nenhum <b>mangá</b> com o ID <code>{manga_id}</code> foi encontrado..." ) if hasattr(manga, "description"): if len(manga.description) > 700: desc = f"<b>Descrição curta:</b> <i>{manga.description_short}</i>[...]" else: desc = f"<b>Descrição:</b> <i>{manga.description}</i>" text = f"<b>{manga.title.romaji}</b> {f'(<code>{manga.title.native}</code>)' if hasattr(manga.title, 'native') else ''}\n" text += f"<b>ID:</b> <code>{manga.id}</code>\n" if hasattr(manga, "status"): text += f"<b>Estado:</b> <code>{manga.status}</code>\n" if hasattr(manga, "chapters"): text += f"<b>Capítulos:</b> <code>{manga.chapters}</code>\n" if hasattr(manga, "volumes"): text += f"<b>Volumes:</b> <code>{manga.volumes}</code>\n" if hasattr(manga.score, "average"): text += f"<b>Pontuação:</b> <code>{manga.score.average}</code>\n" if hasattr(manga, "genres"): text += ( f"<b>Gêneros:</b> <code>{', '.join(str(x) for x in manga.genres)}</code>\n" ) if manga.status.lower() != "not_yet_released": text += f"<b>Início:</b> <code>{manga.start_date.day if hasattr(manga.start_date, 'day') else 0}/{manga.start_date.month if hasattr(manga.start_date, 'month') else 0}/{manga.start_date.year if hasattr(manga.start_date, 'year') else 0}</code>\n" if manga.status.lower() not in ["not_yet_released", "releasing"]: text += f"<b>Finalização:</b> <code>{manga.end_date.day if hasattr(manga.end_date, 'day') else 0}/{manga.end_date.month if hasattr(manga.end_date, 'month') else 0}/{manga.end_date.year if hasattr(manga.end_date, 'year') else 0}</code>\n" if hasattr(manga, "description"): text += f"\n{desc}" keyboard = [[("Mais informações", manga.url, "url")]] await m.reply_photo( photo=f"https://img.anili.st/media/{manga.id}", caption=text, reply_markup=c.ikb(keyboard), )
async def about_c(c: Korone, m: Union[Message, CallbackQuery]): is_callback = isinstance(m, CallbackQuery) about = about_text.format( c.me.first_name, korone.__source__, korone.__community__, ) keyboard = c.ikb([[("⬅️ Voltar", "start_back")]]) with suppress(MessageNotModified): await (m.message.edit_text if is_callback else m.reply_text)( about, reply_markup=(keyboard if is_callback else None), disable_web_page_preview=True, )
async def pypi(c: Korone, m: Message): text = m.matches[0]["search"] r = await http.get(f"https://pypi.org/pypi/{text}/json") if r.status_code == 200: json = r.json() pypi_info = escape_definition(json["info"]) message = ( "<b>%s</b> Por <i>%s %s</i>\n" "Plataforma: <b>%s</b>\n" "Versão: <b>%s</b>\n" "Licença: <b>%s</b>\n" "Resumo: <b>%s</b>\n" % ( pypi_info["name"], pypi_info["author"], f"<{pypi_info['author_email']}>" if pypi_info["author_email"] else "", pypi_info["platform"] or "Não especificado", pypi_info["version"], pypi_info["license"] or "Nenhuma", pypi_info["summary"], ) ) keyboard = None if pypi_info["home_page"] and pypi_info["home_page"] != "UNKNOWN": keyboard = c.ikb( [[("Página inicial do pacote", pypi_info["home_page"], "url")]] ) await m.reply_text( message, disable_web_page_preview=True, reply_markup=keyboard, ) else: await m.reply_text( f"Não consegui encontrar <b>{text}</b> no PyPi (<b>Error:</b> <code>{r.status_code}</code>)", disable_web_page_preview=True, ) return
async def spacex_wiki(c: Korone, m: Message): r = await http.get("https://api.spacexdata.com/v4/company") if r.status_code == 200: sx = r.json() else: await m.reply_text(f"<b>Erro!</b> <code>{r.status_code}</code>") return text = f"<u><b>{sx['name']}</b></u> 🚀" text += f"\n<b>Endereço:</b> {sx['headquarters']['address']}, {sx['headquarters']['city']}, {sx['headquarters']['state']}" text += f"\n<b>Fundador:</b> {sx['founder']}" text += f"\n<b>Fundada em:</b> {sx['founded']}" text += ("\n<b>Funcionários:</b> <code>{:,}</code>").format( sx["employees"]) text += f"\n<b>Plataformas de testes:</b> <code>{sx['test_sites']}</code>" text += f"\n<b>Plataformas de lançamentos:</b> <code>{sx['launch_sites']}</code>" text += f"\n<b>VeÃculos de lançamento:</b> <code>{sx['vehicles']}</code>" text += ("\n<b>Avaliada em:</b> <code>${:,}</code>").format( sx["valuation"]) text += f"\n<b>CEO:</b> {sx['ceo']}" text += f", <b>CTO:</b> {sx['cto']}" text += f", <b>COO:</b> {sx['coo']}" text += f", <b>CTO de Propulsão:</b> {sx['cto_propulsion']}" text += f"\n\n<b>Resumo:</b> {sx['summary']}" keyboard = [ [ ("Twitter", f"{sx['links']['twitter']}", "url"), ("Flickr", f"{sx['links']['flickr']}", "url"), ], [("Website", f"{sx['links']['website']}", "url")], ] await m.reply_text( text=text, reply_markup=c.ikb(keyboard), disable_web_page_preview=True, )
async def nyaasi(c: Korone, m: Message): search = m.matches[0]["text"] try: nyaa = Nyaa.search(keyword=search, category=0)[0] text = f"<b>Nome:</b> {html.escape(nyaa['name'])}\n" text += f"<b>ID:</b> <code>{nyaa['id']}</code>\n" text += f"<b>Data:</b> <code>{nyaa['date']}</code>\n" text += f"<b>Categoria:</b> <i>{nyaa['category']}</i>\n" text += f"<b>Tamanho:</b> <code>{nyaa['size']}</code>\n" text += f"<b>Leechers:</b> <code>{nyaa['leechers']}</code>\n" text += f"<b>Seeders:</b> <code>{nyaa['seeders']}</code>\n" text += ( f"<b>Downloads concluídos:</b> <code>{nyaa['completed_downloads']}</code>" ) filehash = nyaa["magnet"].split("xt=")[1].split("&")[0] keyboard = c.ikb( [ [ ("Torrent", nyaa["download_url"], "url"), ( "Magnet", f"https://nyaasi.herokuapp.com/nyaamagnet/{filehash}", "url", ), ], [("Mais Informações", nyaa["url"], "url")], ] ) except IndexError: text = "Sua pesquisa não encontrou nenhum torrent correspondente!" keyboard = None await m.reply_text(text, disable_web_page_preview=True, reply_markup=keyboard)
async def spacex_launch(c: Korone, m: Message): arg = m.matches[0]["args"] args_list: Iterable[str] = ("latest", "next") if arg not in args_list: await m.reply_text( f"<code>{arg}</code> não é um argumento válido! " f"Argumentos disponÃveis: <code>{', '.join(str(x) for x in args_list)}</code>." ) return r = await http.get(f"https://api.spacexdata.com/v4/launches/{arg}") if r.status_code == 200: sx = r.json() else: await m.reply_text(f"<b>Erro!</b> <code>{r.status_code}</code>") return dt = datetime.utcfromtimestamp( sx["date_unix"]).strftime("%d-%m-%Y %H:%M:%S") images = sx["links"]["flickr"]["original"] res = await http.get( f"https://api.spacexdata.com/v4/rockets/{sx['rocket']}") rocket = res.json() if res.status_code == 200 else None res = await http.get( f"https://api.spacexdata.com/v4/launchpads/{sx['launchpad']}") launchpad = res.json() if res.status_code == 200 else None text = f"<b>Nome da missão:</b> {sx['name']}\n" text += f"<b>Voo Nº:</b> {sx['flight_number']}\n" if rocket: text += f"<b>Nome do foguete:</b> {rocket['name']}\n" if launchpad: text += f"<b>Palataforma de lançamento:</b> {launchpad['name']}\n" if sx["success"]: text += f"<b>Sucesso:</b> {sx['success']}\n" if sx["failures"]: text += f"<b>Falhas:</b> {sx['failures']}\n" text += f"<b>Data de lançamento:</b> <code>{dt}</code>\n\n" if sx["details"]: text += f"<b>Detalhes:</b>\n{sx['details']}" keyboard = None if sx["links"]["reddit"]["campaign"]: keyboard = [[("Reddit", sx["links"]["reddit"]["campaign"], "url")]] if sx["links"]["webcast"]: keyboard[0].append(("YouTube", sx["links"]["webcast"], "url")) if keyboard: keyboard = c.ikb(keyboard) if images: await m.reply_photo( photo=images[0], caption=text, reply_markup=keyboard, ) else: await m.reply_text( text=text, reply_markup=keyboard, disable_web_page_preview=True, )
async def anilist_anime(c: Korone, m: Message): query = m.matches[0]["search"] if query.isdecimal(): anime_id = int(query) else: try: async with anilist.AsyncClient() as client: results = await client.search(query, "anime", page=1, limit=1) anime_id = results[0].id except IndexError: return await m.reply_text( "Algo deu errado, verifique sua pesquisa e tente novamente!" ) async with anilist.AsyncClient() as client: anime = await client.get(anime_id) if not anime: return await m.reply_text( f"Desculpe! Nenhum <b>anime</b> com o ID <code>{anime_id}</code> foi encontrado..." ) if hasattr(anime, "description"): if len(anime.description) > 700: desc = f"<b>Descrição curta:</b> <i>{anime.description_short}</i>[...]" else: desc = f"<b>Descrição:</b> <i>{anime.description}</i>" text = f"<b>{anime.title.romaji}</b> {f'(<code>{anime.title.native}</code>)' if hasattr(anime.title, 'native') else ''}\n" text += f"<b>ID:</b> <code>{anime.id}</code>\n" text += f"<b>Tipo:</b> <code>{anime.format}</code>\n" if hasattr(anime, "status"): text += f"<b>Estado:</b> <code>{anime.status}</code>\n" if hasattr(anime, "episodes"): text += f"<b>Episódios:</b> <code>{anime.episodes}</code>\n" if hasattr(anime, "duration"): text += f"<b>Duração:</b> <code>{anime.duration}</code> Por Ep.\n" if hasattr(anime.score, "average"): text += f"<b>Pontuação:</b> <code>{anime.score.average}</code>\n" if hasattr(anime, "genres"): text += ( f"<b>Gêneros:</b> <code>{', '.join(str(x) for x in anime.genres)}</code>\n" ) if hasattr(anime, "studios"): text += f"<b>Estúdios:</b> <code>{', '.join(str(x) for x in anime.studios)}</code>\n" if anime.status.lower() != "not_yet_released": text += f"<b>Inicio:</b> <code>{anime.start_date.day if hasattr(anime.start_date, 'day') else 0}/{anime.start_date.month if hasattr(anime.start_date, 'month') else 0}/{anime.start_date.year if hasattr(anime.start_date, 'year') else 0}</code>\n" if anime.status.lower() not in ["not_yet_released", "releasing"]: text += f"<b>Finalização:</b> <code>{anime.end_date.day if hasattr(anime.end_date, 'day') else 0}/{anime.end_date.month if hasattr(anime.end_date, 'month') else 0}/{anime.end_date.year if hasattr(anime.end_date, 'year') else 0}</code>\n" if hasattr(anime, "description"): text += f"\n{desc}" keyboard = [[("Mais informações", anime.url, "url")]] if hasattr(anime, "trailer"): keyboard[0].append(("Trailer 🎬", anime.trailer.url, "url")) await m.reply_photo( photo=f"https://img.anili.st/media/{anime.id}", caption=text, reply_markup=c.ikb(keyboard), )
async def inline_manga(c: Korone, q: InlineQuery): results: List[InlineQueryResultPhoto] = [] query = q.query.split() if len(query) != 0 and query[0] == "manga": search = " ".join(query[1:]) async with anilist.AsyncClient() as client: results_search = await client.search(search, "manga", page=1, limit=10) for result in results_search: manga = await client.get(result.id, "manga") if hasattr(manga, "description"): if len(manga.description) > 700: desc = f"<b>Descrição curta:</b> <i>{manga.description_short}</i>[...]" else: desc = f"<b>Descrição:</b> <i>{manga.description}</i>" text = f"<b>{manga.title.romaji}</b> {f'(<code>{manga.title.native}</code>)' if hasattr(manga.title, 'native') else ''}\n" text += f"<b>ID:</b> <code>{manga.id}</code>\n" if hasattr(manga, "status"): text += f"<b>Estado:</b> <code>{manga.status}</code>\n" if hasattr(manga, "chapters"): text += f"<b>Capítulos:</b> <code>{manga.chapters}</code>\n" if hasattr(manga, "volumes"): text += f"<b>Volumes:</b> <code>{manga.volumes}</code>\n" if hasattr(manga.score, "average"): text += f"<b>Pontuação:</b> <code>{manga.score.average}</code>\n" if hasattr(manga, "genres"): text += f"<b>Gêneros:</b> <code>{', '.join(str(x) for x in manga.genres)}</code>\n" if not manga.status.lower() == "not_yet_released": text += f"<b>Início:</b> <code>{manga.start_date.day if hasattr(manga.start_date, 'day') else 0}/{manga.start_date.month if hasattr(manga.start_date, 'month') else 0}/{manga.start_date.year if hasattr(manga.start_date, 'year') else 0}</code>\n" if not manga.status.lower() in [ "not_yet_released", "releasing", ]: text += f"<b>Finalização:</b> <code>{manga.end_date.day if hasattr(manga.end_date, 'day') else 0}/{manga.end_date.month if hasattr(manga.end_date, 'month') else 0}/{manga.end_date.year if hasattr(manga.end_date, 'year') else 0}</code>\n" if hasattr(manga, "description"): text += f"\n{desc}" keyboard = [ [ ("Mais Info", manga.url, "url"), ( "Pesquisar mais", "manga", "switch_inline_query_current_chat", ), ] ] photo = f"https://img.anili.st/media/{manga.id}" results.append( InlineQueryResultPhoto( photo_url=photo, title=manga.title.romaji, description=cleanhtml(desc), caption=text, reply_markup=c.ikb(keyboard), ) ) try: if len(results) > 0: await q.answer( results=results, cache_time=0, ) except QueryIdInvalid: pass
async def inline_anime(c: Korone, q: InlineQuery): results: List[InlineQueryResultPhoto] = [] query = q.query.split() if len(query) != 0 and query[0] == "anime": search = " ".join(query[1:]) async with anilist.AsyncClient() as client: results_search = await client.search(search, "anime", page=1, limit=10) for result in results_search: anime = await client.get(result.id, "anime") if hasattr(anime, "description"): if len(anime.description) > 700: desc = f"<b>Descrição curta:</b> <i>{anime.description_short}</i>[...]" else: desc = f"<b>Descrição:</b> <i>{anime.description}</i>" text = f"<b>{anime.title.romaji}</b> {f'(<code>{anime.title.native}</code>)' if hasattr(anime.title, 'native') else ''}\n" text += f"<b>ID:</b> <code>{anime.id}</code>\n" text += f"<b>Tipo:</b> <code>{anime.format}</code>\n" if hasattr(anime, "status"): text += f"<b>Estado:</b> <code>{anime.status}</code>\n" if hasattr(anime, "episodes"): text += f"<b>Episódios:</b> <code>{anime.episodes}</code>\n" if hasattr(anime, "duration"): text += f"<b>Duração:</b> <code>{anime.duration}</code> Por Ep.\n" if hasattr(anime.score, "average"): text += f"<b>Pontuação:</b> <code>{anime.score.average}</code>\n" if hasattr(anime, "genres"): text += f"<b>Gêneros:</b> <code>{', '.join(str(x) for x in anime.genres)}</code>\n" if hasattr(anime, "studios"): text += f"<b>Estúdios:</b> <code>{', '.join(str(x) for x in anime.studios)}</code>\n" if not anime.status.lower() == "not_yet_released": text += f"<b>Inicio:</b> <code>{anime.start_date.day if hasattr(anime.start_date, 'day') else 0}/{anime.start_date.month if hasattr(anime.start_date, 'month') else 0}/{anime.start_date.year if hasattr(anime.start_date, 'year') else 0}</code>\n" if not anime.status.lower() in [ "not_yet_released", "releasing", ]: text += f"<b>Finalização:</b> <code>{anime.end_date.day if hasattr(anime.end_date, 'day') else 0}/{anime.end_date.month if hasattr(anime.end_date, 'month') else 0}/{anime.end_date.year if hasattr(anime.end_date, 'year') else 0}</code>\n" if hasattr(anime, "description"): text += f"\n{desc}" keyboard = [[("Mais informações", anime.url, "url")]] if hasattr(anime, "trailer"): keyboard[0].append(("Trailer 🎬", anime.trailer.url, "url")) keyboard.append( [ ( "Pesquisar mais", "anime", "switch_inline_query_current_chat", ) ] ) title = f"{anime.title.romaji} | {anime.format}" photo = f"https://img.anili.st/media/{anime.id}" results.append( InlineQueryResultPhoto( photo_url=photo, title=title, description=cleanhtml(desc), caption=text, reply_markup=c.ikb(keyboard), ) ) try: if len(results) > 0: await q.answer( results=results, cache_time=0, ) except QueryIdInvalid: pass
async def whatanime(c: Korone, m: Message): if not m.reply_to_message.media: await m.reply_text("Nenhuma mídia encontrada!") return media = ( m.reply_to_message.photo or m.reply_to_message.sticker or m.reply_to_message.animation or m.reply_to_message.video or m.reply_to_message.document ) if isinstance(media, (Document, Video)): if bool(media.thumbs) and len(media.thumbs) > 0: media = media.thumbs[0] elif ( isinstance(media, Video) and bool(media.duration) and ((media.duration) > (1 * 60 + 30)) ): return sent = await m.reply_photo( "https://telegra.ph/file/4b479327f02d097a23344.png", caption="Procurando informações no AniList...", ) tempdir = tempfile.mkdtemp() path = await c.download_media(media, file_name=os.path.join(tempdir, "whatanime")) try: r = await http.post( "https://api.trace.moe/search?anilistInfo&cutBorders", files={"image": open(path, "rb")}, ) except TimeoutException: shutil.rmtree(tempdir) await sent.edit("A pesquisa excedeu o tempo limite...") return shutil.rmtree(tempdir) if r.status_code != 200: await sent.edit( f"<b>Error:</b> <code>{r.status_code}</code>! Tente novamente mais tarde." ) return results = r.json()["result"] if len(results) == 0: await sent.edit("Nenhum resultado foi encontrado!") return result = results[0] anilist_id = result["anilist"]["id"] title_native = result["anilist"]["title"]["native"] title_romaji = result["anilist"]["title"]["romaji"] is_adult = result["anilist"]["isAdult"] synonyms = result["anilist"]["synonyms"] episode = result["episode"] text = f"<b>{title_romaji}</b>" if bool(title_native): text += f" (<code>{title_native}</code>)" text += "\n" text += f"<b>ID:</b> <code>{anilist_id}</code>\n" if bool(episode): text += f"\n<b>Episódio:</b> <code>{episode}</code>" if bool(synonyms): text += f"\n<b>Sinônimos:</b> {', '.join(str(x) for x in synonyms)}" if bool(is_adult): text += "\n<b>Adulto:</b> <code>Sim</code>" percent = round(result["similarity"] * 100, 2) text += f"\n<b>Similaridade:</b> <code>{percent}%</code>" keyboard = [[("Mais informações", f"https://anilist.co/anime/{anilist_id}", "url")]] await sent.edit_media( InputMediaPhoto( f"https://img.anili.st/media/{anilist_id}", text, ), reply_markup=c.ikb(keyboard), ) video = result["video"] from_time = str(timedelta(seconds=result["from"])).split(".", 1)[0].rjust(8, "0") to_time = str(timedelta(seconds=result["to"])).split(".", 1)[0].rjust(8, "0") if video is not None: file_name = result["filename"] try: await c.send_video( chat_id=m.chat.id, video=video + "&size=l", width=1280, height=720, caption=( f"<code>{file_name}</code>\n\n" f"<code>{from_time}</code> - <code>{to_time}</code>" ), reply_to_message_id=m.message_id, ) except BadRequest: return
async def help_module(c: Korone, m: Message, module: str = None): is_query = isinstance(m, CallbackQuery) text = "" keyboard = [] success = False if not module or module == "start": keyboard.append([("Comandos", "help_commands"), ("Filtros", "help_filters")]) keyboard.append([("⬅️ Voltar", "start_back")]) text = "Por favor, selecione uma categoria para obter ajuda!" success = True elif module in {"commands", "filters"}: text = "Escolha um módulo ou use <code>/help <módulo></code>.\n" keyboard = [[]] index = 0 for key, value in COMMANDS_HELP.items(): if module in value and "help" in value and value["help"]: if len(keyboard[index]) == 3: index += 1 keyboard.append([]) keyboard[index].append(( value["name"] if "name" in value else key.capitalize(), f"help_{key}", )) success = True keyboard.append([("⬅️ Voltar", "help_start")]) elif module in COMMANDS_HELP.keys(): text = f"<b>Módulo</b>: <code>{module}</code>\n" module = COMMANDS_HELP[module] text += f'\n{module["text"]}\n' m_type = "commands" if "commands" in module else "filters" if len(module[m_type]) > 0: text += f'\n<b>{"Comandos" if m_type == "commands" else "Filtros"}</b>:' for key, value in module[m_type].items(): action = value["action"] if len(action) > 0: regex = "" if m_type == "commands": key = key.replace("$", "") regex = key.split()[0] if "<" in key and ">" in key: left = key[len(regex):].split("<")[1:] for field in left: regex += " <" + field.split(">")[0] + ">" else: regex = key else: regex = key if action == " " and m_type == "filters": text += f"\n - <code>{html.escape(regex)}</code>" elif action not in [" ", ""] and m_type == "filters": text += f"\n - <code>{html.escape(regex)}</code>: {action}" else: text += f'\n - <b>{"/" if m_type == "commands" else ""}{html.escape(regex)}</b>: <i>{action}</i>' success = True keyboard.append([("⬅️ Voltar", f"help_{m_type}")]) kwargs = {} if keyboard: kwargs["reply_markup"] = c.ikb(keyboard) if success: with suppress(MessageNotModified): await (m.edit_message_text if is_query else m.reply_text)(text, **kwargs)
async def on_ttdl(c: Korone, m: Message): args = m.matches[0]["text"] if m.reply_to_message and m.reply_to_message.text: url = m.reply_to_message.text elif m.text and args: url = args else: await m.reply_text("Por favor, responda a um link de um vídeo do Twitter.") return rege = re.match( r"https?://(?:(?:www|m(?:obile)?)\.)?twitter\.com/(?:(?:i/web|[^/]+)/status|statuses)/(?P<id>\d+)", url, re.M, ) if not rege: await m.reply_text("Isso não é um link válido!") return sent = await m.reply_text("Baixando...") with tempfile.TemporaryDirectory() as tempdir: path = os.path.join(tempdir, "ttdl") tdl = yt_dlp.YoutubeDL( { "outtmpl": f"{path}/{m.from_user.id}-%(id)s.%(ext)s", "format": "mp4", } ) tt = await extract_info(tdl, rege.group(), download=False) for f in tt["formats"]: if f["ext"] == "mp4": try: vwidth = f["width"] vheight = f["height"] except KeyError: pass vformat = f["format_id"] vheaders = f["http_headers"] tdl = yt_dlp.YoutubeDL( { "outtmpl": f"{path}/{m.from_user.id}-%(id)s.%(ext)s", "format": vformat, } ) try: tt = await extract_info(tdl, url, download=True) except BaseException as e: await sent.edit(f"<b>Error!</b>\n<code>{e}</code>") return filename = tdl.prepare_filename(tt) thumb = io.BytesIO((await http.get(tt["thumbnail"], headers=vheaders)).content) thumb.name = "thumbnail.jpeg" await sent.edit("Enviando...") keyboard = [[("🔗 Tweet", tt["webpage_url"], "url")]] await c.send_chat_action(m.chat.id, "upload_video") try: await c.send_chat_action(m.chat.id, "upload_video") if tt["duration"] and vwidth and vheight: await m.reply_video( video=filename, thumb=thumb, duration=int(tt["duration"]), width=int(vwidth), height=int(vheight), reply_markup=c.ikb(keyboard), ) else: await m.reply_video( video=filename, thumb=thumb, reply_markup=c.ikb(keyboard), ) except BadRequest as e: await m.reply_text( text=( "Desculpe! Não consegui enviar o " "vídeo por causa de um erro.\n" f"<b>Erro:</b> <code>{e}</code>" ) ) await sent.delete() shutil.rmtree(tempdir, ignore_errors=True)
async def on_ytdl(c: Korone, m: Message): args = m.matches[0]["text"] user = m.from_user.id if m.reply_to_message and m.reply_to_message.text: url = m.reply_to_message.text elif m.text and args: url = args else: await m.reply_text("Por favor, responda a um link do YouTube ou texto.") return ydl = yt_dlp.YoutubeDL( { "outtmpl": "dls/%(title)s-%(id)s.%(ext)s", "format": "mp4", "noplaylist": True, } ) rege = re.match( r"http(?:s?):\/\/(?:www\.)?(?:music\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?[\w\?=]*)?", url, re.M, ) temp = url.split("t=")[1].split("&")[0] if "t=" in url else "0" if not rege: yt = await extract_info(ydl, "ytsearch:" + url, download=False) yt = yt["entries"][0] else: try: yt = await extract_info(ydl, rege.group(), download=False) except DownloadError as e: await m.reply_text(f"<b>Error!</b>\n<code>{e}</code>") return if not temp.isnumeric(): temp = "0" for f in yt["formats"]: if f["format_id"] == "140": afsize = f["filesize"] or 0 if f["ext"] == "mp4" and f["filesize"] is not None: vfsize = f["filesize"] or 0 vformat = f["format_id"] keyboard = [ [ ( "💿 Áudio", f"_aud.{yt['id']}|{afsize}|{vformat}|{temp}|{user}|{m.message_id}", ), ( "🎬 Vídeo", f"_vid.{yt['id']}|{vfsize}|{vformat}|{temp}|{user}|{m.message_id}", ), ] ] if " - " in yt["title"]: performer, title = yt["title"].rsplit(" - ", 1) else: performer = yt.get("creator") or yt.get("uploader") title = yt["title"] text = f"🎧 <b>{performer}</b> - <i>{title}</i>\n" text += f"💾 <code>{pretty_size(afsize)}</code> (áudio) / <code>{pretty_size(int(vfsize))}</code> (vídeo)\n" text += f"⏳ <code>{datetime.timedelta(seconds=yt.get('duration'))}</code>" await m.reply_text(text, reply_markup=c.ikb(keyboard))
# Beautiful init with rich text = ":rocket: [bold green]PyKorone Running...[/bold green] :rocket:" text += f"\nKorone v{korone.__version__}" text += f"\nPyrogram v{pyrogram.__version__}" text += f"\n{korone.__license__}" text += f"\n{korone.__copyright__}" rprint(Panel.fit(text, border_style="blue", box=box.ASCII)) # Disable ugly pyrogram notice print Session.notice_displayed = True async def close_http() -> None: # Closing the aiohttp session use by some packages. await aiohttp.ClientSession().close() # Closing the httpx session use by the bot. await http.aclose() if __name__ == "__main__": try: Korone().run() except KeyboardInterrupt: log.warning("Forced stop... Bye!") finally: event_policy = asyncio.get_event_loop_policy() event_loop = event_policy.new_event_loop() event_loop.run_until_complete(close_http())