mirror of
https://github.com/MuRuLOSE/limoka.git
synced 2026-06-18 07:04:19 +02:00
Added and updated repositories 2026-06-18 02:52:50
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||

|
|
||||||
# amoremods
|
|
||||||
My mods for userbot
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta pic: https://te.legra.ph/file/868a280910e7f61f6ab0e.png
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Abstract.jpg
|
|
||||||
|
|
||||||
|
|
||||||
from .. import utils, loader
|
|
||||||
|
|
||||||
chat = "@aeabstractbot"
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractMod(loader.Module):
|
|
||||||
"""Write a beautiful summary on a notebook"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Abstract",
|
|
||||||
"processing": (
|
|
||||||
"<emoji document_id='6318766236746384900'>🕔</emoji> <b>Processing...</b>"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.owner
|
|
||||||
@loader.command(ru_doc="<текст> - Создать конспект")
|
|
||||||
async def konspcmd(self, message):
|
|
||||||
"""<text> - Create summary"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
message = await utils.answer(message, self.strings("processing"))
|
|
||||||
async with self._client.conversation(chat) as conv:
|
|
||||||
msgs = []
|
|
||||||
msgs += [await conv.send_message("/start")]
|
|
||||||
msgs += [await conv.get_response()]
|
|
||||||
msgs += [await conv.send_message(text)]
|
|
||||||
m = await conv.get_response()
|
|
||||||
|
|
||||||
await self._client.send_file(
|
|
||||||
message.peer_id,
|
|
||||||
m.media,
|
|
||||||
reply_to=message.reply_to_msg_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
for msg in msgs + [m]:
|
|
||||||
await msg.delete()
|
|
||||||
|
|
||||||
if message.out:
|
|
||||||
await message.delete()
|
|
||||||
|
|
||||||
await self.client.delete_dialog(chat)
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Activity.jpg
|
|
||||||
# requires: deep_translator
|
|
||||||
|
|
||||||
import requests
|
|
||||||
import deep_translator
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
|
|
||||||
def generate_activity():
|
|
||||||
return requests.get("http://api.farkhodovme.tk/activity/en").json()['activity']
|
|
||||||
|
|
||||||
|
|
||||||
class Activity(loader.Module):
|
|
||||||
"""Generate activity if you're bored"""
|
|
||||||
|
|
||||||
strings = {"name": "Activity", "activity": "⛩ <b>Activity:</b> <code>{}</code>", "lang": "en"}
|
|
||||||
strings_ru = {"activity": "⛩ <b>Занятие:</b> <code>{}</code>", "lang": "ru"}
|
|
||||||
strings_uz = {"activity": "⛩ <b>Harakat:</b> <code>{}</code>", "lang": "uz"}
|
|
||||||
|
|
||||||
@loader.command(ru_doc="Сгенерировать занятие", uz_doc="Harakat yaratish")
|
|
||||||
async def activity(self, message):
|
|
||||||
"""Generate activity"""
|
|
||||||
res = (deep_translator.GoogleTranslator(source="auto", target=self.strings["lang"]).translate(generate_activity()) if self.strings["lang"] != "en" else generate_activity())
|
|
||||||
txt = self.strings['activity'].format(res)
|
|
||||||
await utils.answer(message, txt)
|
|
||||||
@@ -1,287 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://github.com/AmoreForever/assets/blob/master/Aeconv.jpg?raw=true
|
|
||||||
# meta pic: https://cdn-icons-png.flaticon.com/512/5670/5670084.png
|
|
||||||
|
|
||||||
import re
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from bs4 import BeautifulSoup as bs
|
|
||||||
from requests import get
|
|
||||||
from asyncio import sleep
|
|
||||||
from asyncio.exceptions import TimeoutError
|
|
||||||
from hikkatl.tl.types import Message
|
|
||||||
from hikkatl.errors.common import AlreadyInConversationError
|
|
||||||
|
|
||||||
from .. import utils, loader
|
|
||||||
from ..inline.types import InlineCall
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class Aeconv(loader.Module):
|
|
||||||
"""Easy and fast valute converter"""
|
|
||||||
|
|
||||||
bot = "@exchange_rates_vsk_bot"
|
|
||||||
strings = {
|
|
||||||
"name": "Aeconv",
|
|
||||||
"wait": "<emoji document_id=5346192260029489215>💵</emoji> <b>Converting...</b>",
|
|
||||||
"no_args": "<emoji document_id=5343820329980535275>🖕</emoji> <b>Where are the arguments?</b>",
|
|
||||||
"unsupported": "<emoji document_id=5307761055873638139>🚫</emoji> <b>Unsupported currency!</b>",
|
|
||||||
"converted": "<emoji document_id=6037400506823871682>💸</emoji> <b>Converted <code>{}</code></b>\n\n",
|
|
||||||
"already": "<emoji document_id=5348177037431414677>⚠️</emoji> <b>Wait until the bot responds!</b>",
|
|
||||||
"wrong_currency": "<emoji document_id=5345937796102104039>🤷♀️</emoji><b> Wrong currency</b>",
|
|
||||||
"choose_currency": "📉 <b> Choose currency</b>",
|
|
||||||
"processing": "🕔 <b>Processing...</b>",
|
|
||||||
"done": "✅ <b>Done!</b>",
|
|
||||||
"already_in_conv": "⚠️ <b>Already in conversation!</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"wait": "<emoji document_id=5346192260029489215>💵</emoji> <b>Конвертирую...</b>",
|
|
||||||
"no_args": "<emoji document_id=5343820329980535275>🖕</emoji> <b>Где аргументы?</b>",
|
|
||||||
"unsupported": "<emoji document_id=5307761055873638139>🚫</emoji> <b>Валюта не поддерживается!</b>",
|
|
||||||
"converted": "<emoji document_id=6037400506823871682>💸</emoji> <b>Сконвертирован <code>{}</code></b>\n\n",
|
|
||||||
"already": "<emoji document_id=5348177037431414677>⚠️</emoji> <b>Подожди пока бот ответит!</b>",
|
|
||||||
"wrong_currency": "<emoji document_id=5345937796102104039>🤷♀️</emoji><b> Неправильная валюта</b>",
|
|
||||||
"choose_currency": "📉 <b> Выберите валюту</b>",
|
|
||||||
"processing": "🕔 Обрабатываю...",
|
|
||||||
"done": "<code>[Aeconv]</code> ✅ <b> Готово!</b>",
|
|
||||||
"already_in_conv": "⚠️ <b>Жди пока закончится процесс!</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_uz = {
|
|
||||||
"wait": "<emoji document_id=5346192260029489215>💵</emoji> <b>Valyuta konvertatsiyasi...</b>",
|
|
||||||
"no_args": "<emoji document_id=5343820329980535275>🖕</emoji> <b>Argumetlar qayerda?</b>",
|
|
||||||
"unsupported": "<emoji document_id=5307761055873638139>🚫</emoji> <b>Valyuta qo'llab-quvvatlanmaydi!</b>",
|
|
||||||
"converted": "<emoji document_id=6037400506823871682>💸</emoji> <b>Konvertatsiya qilindi <code>{}</code></b>\n\n",
|
|
||||||
"already": "<emoji document_id=5348177037431414677>⚠️</emoji> <b>Bot javob berishini kuting!</b>",
|
|
||||||
"wrong_currency": "<emoji document_id=5345937796102104039>🤷♀️</emoji><b> Noto'g'ri valyuta</b>",
|
|
||||||
"choose_currency": "📉 <b> Valyutani tanlang</b>",
|
|
||||||
"processing": "🕔 Qayta ishlayapman...",
|
|
||||||
"done": "<code>[Aeconv]</code> ✅ <b>Tayyor!</b>",
|
|
||||||
"already_in_conv": "⚠️ <b>Protsess tugaguncha kuting!</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_de = { # i'm really sorry for translations, i'm not good at it
|
|
||||||
"wait": "<emoji document_id=5346192260029489215>💵</emoji> <b>Konvertiere...</b>",
|
|
||||||
"no_args": "<emoji document_id=5343820329980535275>🖕</emoji> <b>Wo sind die Argumente?</b>",
|
|
||||||
"unsupported": "<emoji document_id=5307761055873638139>🚫</emoji> <b>Nicht unterstützte Währung!</b>",
|
|
||||||
"converted": "<emoji document_id=6037400506823871682>💸</emoji> <b>Konvertiert <code>{}</code></b>\n\n",
|
|
||||||
"already": "<emoji document_id=5348177037431414677>⚠️</emoji> <b>Warten Sie, bis der Bot antwortet!</b>",
|
|
||||||
"wrong_currency": "<emoji document_id=5345937796102104039>🤷♀️</emoji><b> Falsche Währung</b>",
|
|
||||||
"choose_currency": "📉 <b> Währung auswählen</b>",
|
|
||||||
"processing": "🕔 Verarbeitung...",
|
|
||||||
"done": "<code>[Aeconv]</code> ✅ <b>Fertig!</b>",
|
|
||||||
"already_in_conv": "⚠️ <b>Warten Sie, bis der Prozess beendet ist!</b>",
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_tr = { # i'm really sorry for translations, i'm not good at it
|
|
||||||
"wait": "<emoji document_id=5346192260029489215>💵</emoji> <b>Dönüştürülüyor...</b>",
|
|
||||||
"no_args": "<emoji document_id=5343820329980535275>🖕</emoji> <b>Argümanlar nerede?</b>",
|
|
||||||
"unsupported": "<emoji document_id=5307761055873638139>🚫</emoji> <b>Desteklenmeyen para birimi!</b>",
|
|
||||||
"converted": "<emoji document_id=6037400506823871682>💸</emoji> <b>Dönüştürüldü <code>{}</code></b>\n\n",
|
|
||||||
"already": "<emoji document_id=5348177037431414677>⚠️</emoji> <b>Bot cevap verene kadar bekleyin!</b>",
|
|
||||||
"wrong_currency": "<emoji document_id=5345937796102104039>🤷♀️</emoji><b> Yanlış para birimi</b>",
|
|
||||||
"choose_currency": "📉 <b> Para birimini seçin</b>",
|
|
||||||
"processing": "🕔 İşleniyor...",
|
|
||||||
"done": "<code>[Aeconv]</code> ✅ <b>Tamam!</b>",
|
|
||||||
"already_in_conv": "⚠️ <b>İşlem bitene kadar bekleyin!</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_kk = { # i'm really sorry for translations, i'm not good at it
|
|
||||||
"wait": "<emoji document_id=5346192260029489215>💵</emoji> <b>Валюта айырбасталуда...</b>",
|
|
||||||
"no_args": "<emoji document_id=5343820329980535275>🖕</emoji> <b>Аргументтер қайда?</b>",
|
|
||||||
"unsupported": "<emoji document_id=5307761055873638139>🚫</emoji> <b>Валюта қолдау көрсетілмейді!</b>",
|
|
||||||
"converted": "<emoji document_id=6037400506823871682>💸</emoji> <b>Айырбасталды <code>{}</code></b>\n\n",
|
|
||||||
"already": "<emoji document_id=5348177037431414677>⚠️</emoji> <b>Бот жауап бергенге дейін күтіңіз!</b>",
|
|
||||||
"wrong_currency": "<emoji document_id=5345937796102104039>🤷♀️</emoji><b> Дұрыс валюта емес</b>",
|
|
||||||
"choose_currency": "📉 <b> Валютаны таңдаңыз</b>",
|
|
||||||
"processing": "🕔 Қайта өңдеу...",
|
|
||||||
"done": "<code>[Aeconv]</code> ✅ <b>Тайық!</b>",
|
|
||||||
"already_in_conv": "⚠️ <b>Процесс аяқталғанда дейін күтіңіз!</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
custom_emojis = {
|
|
||||||
"🇬🇧": "<emoji document_id=6323589145717376403>🇬🇧</emoji>",
|
|
||||||
"🇺🇿": "<emoji document_id=6323430017179059570>🇺🇿</emoji>",
|
|
||||||
"🇺🇸": "<emoji document_id=6323374027985389586>🇺🇸</emoji>",
|
|
||||||
"🇷🇺": "<emoji document_id=6323139226418284334>🇷🇺</emoji>",
|
|
||||||
"🇰🇿": "<emoji document_id=6323135275048371614>🇰🇿</emoji>",
|
|
||||||
"🇪🇺": "<emoji document_id=6323217102765295143>🇪🇺</emoji>",
|
|
||||||
"🇺🇦": "<emoji document_id=6323289850921354919>🇺🇦</emoji>",
|
|
||||||
"🇹🇷": "<emoji document_id=6321003171678259486>🇹🇷</emoji>",
|
|
||||||
"🇵🇱": "<emoji document_id=6323602387101550101>🇵🇱</emoji>",
|
|
||||||
"🇰🇬": "<emoji document_id=6323615997852910673>🇰🇬</emoji>",
|
|
||||||
"bit": "<emoji document_id=6034931909945985955>💰</emoji>",
|
|
||||||
"eth": "<emoji document_id=5280647120607521572>🔹</emoji>",
|
|
||||||
"ton": "<emoji document_id=5863980370340351884>💰</emoji>"
|
|
||||||
}
|
|
||||||
|
|
||||||
currency_mapping = {
|
|
||||||
"EU": ("🇪🇺", "EUR"),
|
|
||||||
"GB": ("🇬🇧", "GBP"),
|
|
||||||
"UZ": ("🇺🇿", "UZS"),
|
|
||||||
"US": ("🇺🇸", "USD"),
|
|
||||||
"RU": ("🇷🇺", "RUB"),
|
|
||||||
"KZ": ("🇰🇿", "KZT"),
|
|
||||||
"UA": ("🇺🇦", "UAH"),
|
|
||||||
"PL": ("🇵🇱", "PLN"),
|
|
||||||
"TR": ("🇹🇷", "TRY"),
|
|
||||||
"KG": ("🇰🇬", "KGS")
|
|
||||||
}
|
|
||||||
|
|
||||||
currencies = [
|
|
||||||
"EUR", "GBP", "UZS", "USD", "RUB", "KZT", "UAH", "PLN", "TRY", "KGS", "TON", "ETH", "BTC"
|
|
||||||
]
|
|
||||||
|
|
||||||
currency_flags = {
|
|
||||||
"EUR": "🇪🇺",
|
|
||||||
"GBP": "🇬🇧",
|
|
||||||
"UZS": "🇺🇿",
|
|
||||||
"USD": "🇺🇸",
|
|
||||||
"RUB": "🇷🇺",
|
|
||||||
"KZT": "🇰🇿",
|
|
||||||
"UAH": "🇺🇦",
|
|
||||||
"PLN": "🇵🇱",
|
|
||||||
"TRY": "🇹🇷",
|
|
||||||
"KGS": "🇰🇬"
|
|
||||||
}
|
|
||||||
|
|
||||||
letters_stashing = {
|
|
||||||
"E": "cur_df",
|
|
||||||
"G": "cur_gh",
|
|
||||||
"P": "cur_nq",
|
|
||||||
"R": "cur_rs",
|
|
||||||
"S": "cur_rs",
|
|
||||||
"T": "cur_tu",
|
|
||||||
"U": "cur_tu",
|
|
||||||
}
|
|
||||||
|
|
||||||
def currencies_markup(self, argument: str = "") -> list:
|
|
||||||
return utils.chunks(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": f"{self.currency_flags[cur]} {cur}",
|
|
||||||
"callback": self.callback_4_currency,
|
|
||||||
"args": (cur,),
|
|
||||||
}
|
|
||||||
for cur in [
|
|
||||||
i
|
|
||||||
for i in self.currency_flags.keys()
|
|
||||||
if i.startswith(argument.upper())
|
|
||||||
]
|
|
||||||
if cur.startswith(argument.upper())
|
|
||||||
],
|
|
||||||
5,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def client_ready(self, client, db):
|
|
||||||
await utils.dnd(client, self.bot, archive=True)
|
|
||||||
|
|
||||||
async def get_ton_in_rub(self, am, what: str = "uzs", cup: bool = False) -> str:
|
|
||||||
r = (
|
|
||||||
get(f"https://coinchefs.com/{what}/ton/{am}/")
|
|
||||||
if cup
|
|
||||||
else get(f"https://coinchefs.com/ton/{what}/{am}/")
|
|
||||||
)
|
|
||||||
soup = bs(r.text, "html.parser")
|
|
||||||
if result_div := soup.find('div', class_='convert-result'):
|
|
||||||
if result_text_div := result_div.find(
|
|
||||||
'div', class_='col-xs-10 col-sm-10 text-center result-text'
|
|
||||||
):
|
|
||||||
if value_element := result_text_div.b:
|
|
||||||
return value_element.get_text(strip=True)
|
|
||||||
else:
|
|
||||||
logger.debug("Value element not found")
|
|
||||||
else:
|
|
||||||
logger.debug("Result text div not found")
|
|
||||||
else:
|
|
||||||
logger.debug("Result div not found")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def callback_4_currency(self, call: InlineCall, currency: str):
|
|
||||||
try:
|
|
||||||
first_letter = currency[0]
|
|
||||||
await call.answer(self.strings["processing"], show_alert=True)
|
|
||||||
await call.delete()
|
|
||||||
async with self.client.conversation(self.bot) as conv:
|
|
||||||
m = await conv.send_message("/settings")
|
|
||||||
r = await conv.get_response()
|
|
||||||
await r.click(data=b'cur_menu')
|
|
||||||
await r.click(data=b'cur_curmenu')
|
|
||||||
await r.click(data=self.letters_stashing[first_letter])
|
|
||||||
await r.click(data=f"cur_{currency.upper()}")
|
|
||||||
await r.delete()
|
|
||||||
await m.delete()
|
|
||||||
await self.inline.bot.send_message(self.tg_id, self.strings["done"])
|
|
||||||
except AlreadyInConversationError:
|
|
||||||
await call.answer(self.strings["already_in_conv"], show_alert=True)
|
|
||||||
|
|
||||||
@loader.command(ru_doc="<количество> [валюта] должны быть разделены пробелом")
|
|
||||||
async def conv(self, message: Message):
|
|
||||||
"""<amount> [currency] should be separated by space"""
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
if not args:
|
|
||||||
await utils.answer(message, self.strings["no_args"])
|
|
||||||
return
|
|
||||||
# if args.split(" ")[1].upper() not in self.currencies:
|
|
||||||
# await utils.answer(message, self.strings["wrong_currency"])
|
|
||||||
# return
|
|
||||||
await utils.answer(message, self.strings["wait"])
|
|
||||||
if "ton".lower() in args.lower():
|
|
||||||
li_args = args.split(" ")
|
|
||||||
ex_ = await self.get_ton_in_rub(li_args[0])
|
|
||||||
try:
|
|
||||||
async with message.client.conversation(self.bot) as conv:
|
|
||||||
msg = await conv.send_message(args) if "ton".lower() not in args.lower() else await conv.send_message(ex_)
|
|
||||||
r = await conv.get_response()
|
|
||||||
res = r.text
|
|
||||||
text_ = ""
|
|
||||||
text_ += (
|
|
||||||
self.strings["converted"].format(args)
|
|
||||||
if "ton".lower() not in args.lower()
|
|
||||||
else self.strings["converted"].format(f"{li_args[0]} TON")
|
|
||||||
)
|
|
||||||
for emoji, currency, *_ in self.currency_mapping.values():
|
|
||||||
if match := re.findall(f"{emoji} ?(.*) {currency}", res):
|
|
||||||
text_ += (
|
|
||||||
f"<b>{self.custom_emojis.get(emoji)} {currency}:</b> "
|
|
||||||
f"<code>{match[0]}</code>\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
if match := re.findall(r"(.*) BTC", res):
|
|
||||||
text_ += f"\n<b>{self.custom_emojis['bit']} BTC:</b> <code>{match[0]}</code>\n"
|
|
||||||
if match := re.findall(r"(.*) ETH", res):
|
|
||||||
text_ += f"<b>{self.custom_emojis['eth']} ETH:</b> <code>{match[0]}</code>\n"
|
|
||||||
|
|
||||||
if ex_ := await self.get_ton_in_rub(args.split(" ")[0], args.split(" ")[1].lower(), True):
|
|
||||||
text_ += f"<b>{self.custom_emojis['ton']} TON:</b> <code>{ex_.split(' = ')[1]}</code>\n"
|
|
||||||
await utils.answer(message, text_)
|
|
||||||
await msg.delete()
|
|
||||||
await r.delete()
|
|
||||||
except AlreadyInConversationError:
|
|
||||||
await utils.answer(message, self.strings["already"])
|
|
||||||
except TimeoutError:
|
|
||||||
await utils.answer(message, self.strings["unsupported"])
|
|
||||||
except IndexError:
|
|
||||||
await utils.answer(message, self.strings["no_args"])
|
|
||||||
|
|
||||||
|
|
||||||
@loader.command(ru_doc="[валюта] | без аргументов покажет список валют для включения/выключения")
|
|
||||||
async def controlvalute(self, message: Message):
|
|
||||||
"""[currency] | without arguments will show list of currencies for enable/disable"""
|
|
||||||
if args := utils.get_args_raw(message):
|
|
||||||
await utils.answer(message, self.strings["choose_currency"], reply_markup=self.currencies_markup(args))
|
|
||||||
else:
|
|
||||||
return await utils.answer(message, self.strings["choose_currency"], reply_markup=self.currencies_markup())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,225 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Alarm.jpg
|
|
||||||
|
|
||||||
import re
|
|
||||||
import pytz
|
|
||||||
import random
|
|
||||||
import logging
|
|
||||||
import asyncio
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from .. import utils, loader
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
day_to_weekday = {
|
|
||||||
"mon": 0,
|
|
||||||
"tue": 1,
|
|
||||||
"wed": 2,
|
|
||||||
"thu": 3,
|
|
||||||
"fri": 4,
|
|
||||||
"sat": 5,
|
|
||||||
"sun": 6,
|
|
||||||
"пн": 0,
|
|
||||||
"вт": 1,
|
|
||||||
"ср": 2,
|
|
||||||
"чт": 3,
|
|
||||||
"пт": 4,
|
|
||||||
"сб": 5,
|
|
||||||
"вс": 6,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class AlarmMod(loader.Module):
|
|
||||||
"""Alarm module for remind you about something"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Alarm",
|
|
||||||
"set": "<emoji document_id=5870729937215819584>⏰</emoji> <b>Alarm set for <code>{}</code>!</b>",
|
|
||||||
"unset": "<emoji document_id=5213107179329953547>⏰</emoji> <b>Alarm for <code>{}</code> unset!</b>",
|
|
||||||
"unset_all": "<emoji document_id=5213107179329953547>⏰</emoji> <b>All alarms unset!</b>",
|
|
||||||
"list_item": (
|
|
||||||
"<emoji document_id=6334603778326529773>⏰</emoji> <b>Alarm for <code>{}</code>!</b> <code>#{}</code>"
|
|
||||||
"\n<emoji document_id=6334699757960693635>🕔</emoji> <b>Time:</b> <code>{}</code>"
|
|
||||||
"\n<emoji document_id=6334388660594542334>🔊</emoji> <b>Message:</b> <code>{}</code>"
|
|
||||||
),
|
|
||||||
"no_alarms": "<emoji document_id=5208549407280078951>🙅♂️</emoji> <b>No alarms!</b>",
|
|
||||||
"off_button": "✋ Off",
|
|
||||||
"notification": "⏰ <b>Alarm!</b>\n\n<code>{}</code>",
|
|
||||||
"turned_off": "✔️ <b>Alarm turned off!</b>",
|
|
||||||
"incorrect_time": "<emoji document_id=5371015453013450536>🖕</emoji> <b>Incorrect time!</b>",
|
|
||||||
"where_args": "<emoji document_id=5371015453013450536>🖕</emoji> <b>Where arguments?</b>",
|
|
||||||
"incorrect_args": "<emoji document_id=5371015453013450536>🖕</emoji> <b>Incorrect arguments! Write like this:</b> <code>.setalarm mon 12:00 text</code>",
|
|
||||||
"interval_doc": "Interval of sending notifications in seconds",
|
|
||||||
"time_zone_doc": "Time zone for alarms (for example, Europe/Moscow)",
|
|
||||||
}
|
|
||||||
strings_ru = {
|
|
||||||
"set": "<emoji document_id=5870729937215819584>⏰</emoji> <b>Напоминание установлено на <code>{}</code>!</b>",
|
|
||||||
"unset": "<emoji document_id=5213107179329953547>⏰</emoji> <b>Напоминание для <code>{}</code> отменено!</b>",
|
|
||||||
"unset_all": "<emoji document_id=5213107179329953547>⏰</emoji> <b>Все напоминания отменены!</b>",
|
|
||||||
"list_item": (
|
|
||||||
"<emoji document_id=6334603778326529773>⏰</emoji> <b>Напоминание для <code>{}</code>!</b> <code>#{}</code>"
|
|
||||||
"\n<emoji document_id=6334699757960693635>🕔</emoji> <b>Время:</b> <code>{}</code>"
|
|
||||||
"\n<emoji document_id=6334388660594542334>🔊</emoji> <b>Сообщение:</b> <code>{}</code>"
|
|
||||||
),
|
|
||||||
"no_alarms": "<emoji document_id=5208549407280078951>🙅♂️</emoji> <b>Нет напоминаний!</b>",
|
|
||||||
"off_button": "✋ Выключить",
|
|
||||||
"notification": "⏰ <b>Напоминание!</b>\n\n<code>{}</code>",
|
|
||||||
"turned_off": "✔️ <b>Напоминание выключено!</b>",
|
|
||||||
"incorrect_time": "<emoji document_id=5371015453013450536>🖕</emoji> <b>Неправильное время!</b>",
|
|
||||||
"where_args": "<emoji document_id=5371015453013450536>🖕</emoji> <b>Где аргументы?</b>",
|
|
||||||
"incorrect_args": "<emoji document_id=5371015453013450536>🖕</emoji> <b>Неправильные аргументы! Пиши так:</b> <code>.setalarm пн 12:00 текст</code>",
|
|
||||||
"interval_doc": "Интервал отправления напоминаний в секундах",
|
|
||||||
"time_zone_doc": "Часовой пояс для напоминаний (например, Europe/Moscow)",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"interval",
|
|
||||||
5,
|
|
||||||
lambda: self.strings("interval_doc"),
|
|
||||||
validator=loader.validators.Integer(minimum=1, maximum=60),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"time_zone",
|
|
||||||
"Europe/Moscow",
|
|
||||||
lambda: self.strings("time_zone_doc"),
|
|
||||||
validator=loader.validators.RegExp(
|
|
||||||
r"^[\w/]+$",
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@loader.command(ru_doc="<день недели> <время> <сообщение> - установить напоминание")
|
|
||||||
async def setalarm(self, message):
|
|
||||||
"""<day of the week> <time> <message> - set alarm"""
|
|
||||||
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
if not args:
|
|
||||||
return await utils.answer(message, self.strings("where_args"))
|
|
||||||
try:
|
|
||||||
re_args = re.match(r"^(.+) (\d{1,2}):(\d{1,2}) (.*)$", args)
|
|
||||||
day = re_args.group(1).lower()
|
|
||||||
hour = int(re_args.group(2))
|
|
||||||
minute = int(re_args.group(3))
|
|
||||||
text = re_args.group(4)
|
|
||||||
except AttributeError:
|
|
||||||
return await utils.answer(message, self.strings("incorrect_args"))
|
|
||||||
|
|
||||||
if not (0 <= hour <= 23 and 0 <= minute <= 59):
|
|
||||||
return await utils.answer(message, self.strings("incorrect_time"))
|
|
||||||
if day not in day_to_weekday.keys():
|
|
||||||
text = f"<b>Wrong day of the week!</b>\n<b>Available days:</b> <code>{', '.join(day_to_weekday.keys())}</code>"
|
|
||||||
return await utils.answer(message, text)
|
|
||||||
|
|
||||||
id_ = random.randint(100, 999)
|
|
||||||
self.set(
|
|
||||||
"alarms",
|
|
||||||
{
|
|
||||||
**self.get("alarms", {}),
|
|
||||||
day: {
|
|
||||||
"hour": hour,
|
|
||||||
"minute": minute,
|
|
||||||
"text": text,
|
|
||||||
"id": id_,
|
|
||||||
"status": "on",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
await utils.answer(message, self.strings("set").format(day))
|
|
||||||
|
|
||||||
@loader.command(ru_doc="получить список напоминаний")
|
|
||||||
async def alarms(self, message):
|
|
||||||
"""get alarms list"""
|
|
||||||
|
|
||||||
alarms = self.get("alarms", {})
|
|
||||||
if not alarms:
|
|
||||||
return await utils.answer(message, self.strings("no_alarms"))
|
|
||||||
|
|
||||||
text = ""
|
|
||||||
for day, alarm in alarms.items():
|
|
||||||
text += self.strings("list_item").format(
|
|
||||||
day,
|
|
||||||
f"{alarm['id']}",
|
|
||||||
f"{alarm['hour']}:{alarm['minute']}",
|
|
||||||
alarm["text"],
|
|
||||||
)
|
|
||||||
text += "\n\n"
|
|
||||||
await utils.answer(message, text)
|
|
||||||
|
|
||||||
@loader.command(ru_doc="<id> - отменить напоминание")
|
|
||||||
async def unsetalarm(self, message):
|
|
||||||
"""<id> - unset alarm"""
|
|
||||||
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
if not args:
|
|
||||||
return await utils.answer(message, self.strings("where_time"))
|
|
||||||
if args.startswith("#"):
|
|
||||||
args = args[1:]
|
|
||||||
|
|
||||||
alarms = self.get("alarms", {})
|
|
||||||
for day, alarm in alarms.items():
|
|
||||||
if str(alarm["id"]) == args:
|
|
||||||
alarms.pop(day)
|
|
||||||
self.set("alarms", alarms)
|
|
||||||
return await utils.answer(
|
|
||||||
message, self.strings("unset").format(day)
|
|
||||||
)
|
|
||||||
await utils.answer(message, self.strings("unset").format(args))
|
|
||||||
|
|
||||||
@loader.command(ru_doc="отменить все напоминания")
|
|
||||||
async def unsetallalarms(self, message):
|
|
||||||
"""unset all alarms"""
|
|
||||||
|
|
||||||
self.set("alarms", {})
|
|
||||||
await utils.answer(message, self.strings("unset_all"))
|
|
||||||
|
|
||||||
@loader.loop(interval=2, autostart=True)
|
|
||||||
async def check_alarms(self):
|
|
||||||
alarms = self.get("alarms", {})
|
|
||||||
if not alarms:
|
|
||||||
return
|
|
||||||
now = datetime.now(tz=pytz.timezone(self.config["time_zone"]))
|
|
||||||
day = now.weekday()
|
|
||||||
hour = now.hour
|
|
||||||
minute = now.minute
|
|
||||||
for day_, alarm in alarms.items():
|
|
||||||
if (
|
|
||||||
day_to_weekday[day_] == day
|
|
||||||
and alarm["hour"] == hour
|
|
||||||
and alarm["minute"] == minute
|
|
||||||
):
|
|
||||||
while alarm["status"] == "on":
|
|
||||||
self._markup = self.inline.generate_markup(
|
|
||||||
{
|
|
||||||
"text": self.strings("off_button"),
|
|
||||||
"callback": self.off_alarm,
|
|
||||||
"args": (alarm["id"],),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await self.inline.bot.send_message(
|
|
||||||
self.tg_id,
|
|
||||||
self.strings("notification").format(alarm["text"]),
|
|
||||||
reply_markup=self._markup,
|
|
||||||
)
|
|
||||||
await asyncio.sleep(self.config["interval"])
|
|
||||||
break
|
|
||||||
|
|
||||||
async def off_alarm(self, call, id_):
|
|
||||||
alarms = self.get("alarms", {})
|
|
||||||
for day, alarm in alarms.items():
|
|
||||||
if alarm["id"] == id_:
|
|
||||||
alarm["status"] = "off"
|
|
||||||
self.set("alarms", alarms)
|
|
||||||
await call.edit(self.strings("turned_off"))
|
|
||||||
return False
|
|
||||||
await call.answer("Не найдено!")
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://github.com/AmoreForever/assets/blob/master/Amethyste.jpg?raw=true
|
|
||||||
|
|
||||||
from .. import utils, loader
|
|
||||||
from hikkatl.errors.common import AlreadyInConversationError
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class Amethyste(loader.Module):
|
|
||||||
"""Generate memes image"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Amethyste",
|
|
||||||
"wait": "<emoji document_id=5328115567314346398>🫥</emoji> <b>Wait...</b>",
|
|
||||||
"already_open": "<emoji document_id=5330241494521487534>😹</emoji> <b>Conversation already opened Please wait.</b>",
|
|
||||||
"r_photo": "<emoji document_id=5298636457982826800>🖼</emoji> <b>Please reply to image.</b>",
|
|
||||||
"no_args": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Pls provide args</b>",
|
|
||||||
"not_found": "<emoji document_id=5345937796102104039>🤷♀️</emoji> <b>Not found</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"wait": "<emoji document_id=5328115567314346398>🫥</emoji> <b>Подождите...</b>",
|
|
||||||
"already_open": "<emoji document_id=5330241494521487534>😹</emoji> <b>Диалог уже открыт. Подождите.</b>",
|
|
||||||
"r_photo": "<emoji document_id=5298636457982826800>🖼</emoji> <b>Ответьте на фото.</b>",
|
|
||||||
"no_args": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Укажите аргументы</b>",
|
|
||||||
"not_found": "<emoji document_id=5345937796102104039>🤷♀️</emoji> <b>Не найдено</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_uz = {
|
|
||||||
"wait": "<emoji document_id=5328115567314346398>🫥</emoji> <b>Kuting...</b>",
|
|
||||||
"already_open": "<emoji document_id=5330241494521487534>😹</emoji> <b>Dialog allaqachon ochilgan. Iltimos, kuting.</b>",
|
|
||||||
"r_photo": "<emoji document_id=5298636457982826800>🖼</emoji> <b>Rasmga javob bering.</b>",
|
|
||||||
"no_args": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Argumetlarni ko'rsating</b>",
|
|
||||||
"not_found": "<emoji document_id=5345937796102104039>🤷♀️</emoji> <b>Topilmadi</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
_list = [
|
|
||||||
"3000years",
|
|
||||||
"approved",
|
|
||||||
"beautiful",
|
|
||||||
"brazzers",
|
|
||||||
"burn",
|
|
||||||
"challenger",
|
|
||||||
"circle",
|
|
||||||
"contrast",
|
|
||||||
"crush",
|
|
||||||
"ddungeon",
|
|
||||||
"dictator",
|
|
||||||
"distort",
|
|
||||||
"emboss",
|
|
||||||
"fire",
|
|
||||||
"frame",
|
|
||||||
"afusion",
|
|
||||||
"glitch",
|
|
||||||
"greyscale",
|
|
||||||
"instagram",
|
|
||||||
"invert",
|
|
||||||
"jail",
|
|
||||||
"magik",
|
|
||||||
"missionpassed",
|
|
||||||
"moustache",
|
|
||||||
"ps4",
|
|
||||||
"posterize",
|
|
||||||
"rejected",
|
|
||||||
"rip",
|
|
||||||
"scary",
|
|
||||||
"scrolloftruth",
|
|
||||||
"sepia",
|
|
||||||
"sharpen",
|
|
||||||
"sniper",
|
|
||||||
"thanos",
|
|
||||||
"trinity",
|
|
||||||
"triggered",
|
|
||||||
"unsharpen",
|
|
||||||
"utatoo",
|
|
||||||
"wanted",
|
|
||||||
"wasted",
|
|
||||||
]
|
|
||||||
|
|
||||||
async def amegencmd(self, message: Message):
|
|
||||||
"""Generate memes image"""
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
await utils.answer(message, self.strings["wait"])
|
|
||||||
if not args:
|
|
||||||
return await utils.answer(message, self.strings["no_args"])
|
|
||||||
elif not reply.photo:
|
|
||||||
return await utils.answer(message, self.strings["r_photo"])
|
|
||||||
elif args not in self._list:
|
|
||||||
return await utils.answer(message, self.strings["not_found"])
|
|
||||||
async with self.client.conversation("@aozoram_bot") as conv:
|
|
||||||
try:
|
|
||||||
msg = await conv.send_message("/start")
|
|
||||||
s = await conv.get_response()
|
|
||||||
f = await conv.send_file(file=reply)
|
|
||||||
m = await f.reply(f"/amegen {args}")
|
|
||||||
await conv.get_response() # wait for response
|
|
||||||
response = await conv.get_response()
|
|
||||||
await utils.answer_file(message, response.media)
|
|
||||||
await s.delete()
|
|
||||||
await msg.delete()
|
|
||||||
await m.delete()
|
|
||||||
except AlreadyInConversationError:
|
|
||||||
await utils.answer(message, self.strings["already_open"])
|
|
||||||
await self.client.delete_dialog("@aozoram_bot")
|
|
||||||
|
|
||||||
async def amelistcmd(self, message: Message):
|
|
||||||
"""List of memes"""
|
|
||||||
spis = "\n".join([f"• <code>{i}</code>" for i in self._list])
|
|
||||||
await utils.answer(message, f"<b>Available memes:</b>\n\n{spis}")
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/AmoreInfo.jpg
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import git
|
|
||||||
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
from telethon.utils import get_display_name
|
|
||||||
|
|
||||||
from .. import loader, main, utils
|
|
||||||
import datetime
|
|
||||||
import time
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class AmoreindoMod(loader.Module):
|
|
||||||
"""Show userbot info"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "AmoreInfo",
|
|
||||||
"owner": "Owner",
|
|
||||||
"version": "Version",
|
|
||||||
"build": "Build",
|
|
||||||
"prefix": "Prefix",
|
|
||||||
"time": "Time",
|
|
||||||
"platform": "Platform",
|
|
||||||
"uptime": "Uptime",
|
|
||||||
"up-to-date": "😌 Actual version",
|
|
||||||
"update_required": "😕 Outdated version </b><code>.update</code><b>",
|
|
||||||
"_cfg_cst_msg": "Custom message for info. May contain {me}, {version}, {build}, {prefix}, {platform}, {upd}, {time}, {uptime} keywords",
|
|
||||||
"_cfg_cst_btn": "Custom button for info. Leave empty to remove button",
|
|
||||||
"_cfg_cst_bnr": "Custom Banner for info.",
|
|
||||||
"_cfg_cst_frmt": "Custom fileformat for Banner info.",
|
|
||||||
"_cfg_banner": "Set `True` in order to disable an image banner",
|
|
||||||
"_cfg_time": "Use 1, -1, -3 etc.",
|
|
||||||
"_cfg_close": "Here you can change close button name",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"owner": "Владелец",
|
|
||||||
"version": "Версия",
|
|
||||||
"build": "Сборка",
|
|
||||||
"prefix": "Префикс",
|
|
||||||
"uptime": "Аптайм",
|
|
||||||
"platform": "Платформа",
|
|
||||||
"time": "Время",
|
|
||||||
"up-to-date": "😌 Актуальная версия",
|
|
||||||
"update_required": "😕 Требуется обновление </b><code>.update</code><b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_uz = {
|
|
||||||
"owner": "Egasi",
|
|
||||||
"version": "Versiya",
|
|
||||||
"build": "Yig'ish",
|
|
||||||
"prefix": "Prefix",
|
|
||||||
"uptime": "Uptime",
|
|
||||||
"platform": "Platforma",
|
|
||||||
"time": "Soat",
|
|
||||||
"up-to-date": "😌 Joriy versiya",
|
|
||||||
"update_required": "😕 Yangilanish talab qilinadi </b><code>.update</code><b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_de = {
|
|
||||||
"owner": "Besitzer",
|
|
||||||
"version": "Version",
|
|
||||||
"build": "Zusammenbau",
|
|
||||||
"prefix": "Präfix",
|
|
||||||
"uptime": "Betriebszeit",
|
|
||||||
"platform": "Plattform",
|
|
||||||
"time": "Die Zeit",
|
|
||||||
"up-to-date": "😌 Aktuelle Version",
|
|
||||||
"update_required": "😕 Aktualisierung erforderlich </b><code>.update</code><b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"custom_message",
|
|
||||||
"no",
|
|
||||||
doc=lambda: self.strings("_cfg_cst_msg"),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"custom_button1",
|
|
||||||
["🏡 Modules", "https://t.me/amoremods"],
|
|
||||||
lambda: self.strings("_cfg_cst_btn"),
|
|
||||||
validator=loader.validators.Series(min_len=0, max_len=2),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"custom_button2",
|
|
||||||
[],
|
|
||||||
lambda: self.strings("_cfg_cst_btn"),
|
|
||||||
validator=loader.validators.Series(min_len=0, max_len=2),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"custom_button3",
|
|
||||||
[],
|
|
||||||
lambda: self.strings("_cfg_cst_btn"),
|
|
||||||
validator=loader.validators.Series(min_len=0, max_len=2),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"custom_banner",
|
|
||||||
"https://te.legra.ph/file/64bde7bf6b8e377521134.mp4",
|
|
||||||
lambda: self.strings("_cfg_cst_bnr"),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"disable_banner",
|
|
||||||
False,
|
|
||||||
lambda: self.strings("_cfg_banner"),
|
|
||||||
validator=loader.validators.Boolean(),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"custom_format",
|
|
||||||
"gif",
|
|
||||||
lambda: self.strings("_cfg_cst_frmt"),
|
|
||||||
validator=loader.validators.Choice(["photo", "video", "gif"]),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"timezone",
|
|
||||||
"+5",
|
|
||||||
lambda: self.strings("_cfg_time"),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"close_btn",
|
|
||||||
"🔻Close",
|
|
||||||
lambda: self.strings("_cfg_close"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
async def client_ready(self, client, db):
|
|
||||||
self._db = db
|
|
||||||
self._client = client
|
|
||||||
self._me = await client.get_me()
|
|
||||||
|
|
||||||
def _render_info(self) -> str:
|
|
||||||
ver = utils.get_git_hash() or "Unknown"
|
|
||||||
|
|
||||||
try:
|
|
||||||
repo = git.Repo()
|
|
||||||
diff = repo.git.log(["HEAD..origin/master", "--oneline"])
|
|
||||||
upd = (
|
|
||||||
self.strings("update_required") if diff else self.strings("up-to-date")
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
upd = ""
|
|
||||||
|
|
||||||
me = f'<b><a href="tg://user?id={self._me.id}">{utils.escape_html(get_display_name(self._me))}</a></b>'
|
|
||||||
version = f'<i>{".".join(list(map(str, list(main.__version__))))}</i>'
|
|
||||||
build = f'<a href="https://github.com/hikariatama/Hikka/commit/{ver}">#{ver[:8]}</a>' # fmt: skip
|
|
||||||
prefix = f"«<code>{utils.escape_html(self.get_prefix())}</code>»"
|
|
||||||
platform = utils.get_named_platform()
|
|
||||||
uptime = utils.formatted_uptime()
|
|
||||||
offset = datetime.timedelta(hours=self.config["timezone"])
|
|
||||||
tz = datetime.timezone(offset)
|
|
||||||
time1 = datetime.datetime.now(tz)
|
|
||||||
time = time1.strftime("%H:%M:%S")
|
|
||||||
|
|
||||||
return (
|
|
||||||
"<b> </b>\n"
|
|
||||||
+ self.config["custom_message"].format(
|
|
||||||
me=me,
|
|
||||||
version=version,
|
|
||||||
build=build,
|
|
||||||
upd=upd,
|
|
||||||
prefix=prefix,
|
|
||||||
platform=platform,
|
|
||||||
uptime=uptime,
|
|
||||||
time=time,
|
|
||||||
)
|
|
||||||
if self.config["custom_message"] != "no"
|
|
||||||
else (
|
|
||||||
"<b>🎢 AmoreInfo </b>\n"
|
|
||||||
f'<b>🤴 {self.strings("owner")}: </b>{me}\n\n'
|
|
||||||
f"<b>🕶 {self.strings('version')}: </b>{version} {build}\n"
|
|
||||||
f"<b>{upd}</b>\n"
|
|
||||||
f"<b>⏳ {self.strings('uptime')}: {uptime}</b>\n\n"
|
|
||||||
f"<b>⌚ {self.strings('time')}: {time}</b>\n"
|
|
||||||
f"<b>📼 {self.strings('prefix')}: </b>{prefix}\n"
|
|
||||||
f"{platform}\n"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def _get_mark(self, int):
|
|
||||||
if int == 1:
|
|
||||||
return (
|
|
||||||
{
|
|
||||||
"text": self.config["custom_button1"][0],
|
|
||||||
"url": self.config["custom_button1"][1],
|
|
||||||
}
|
|
||||||
if self.config["custom_button1"]
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
|
|
||||||
elif int == 2:
|
|
||||||
return (
|
|
||||||
{
|
|
||||||
"text": self.config["custom_button2"][0],
|
|
||||||
"url": self.config["custom_button2"][1],
|
|
||||||
}
|
|
||||||
if self.config["custom_button2"]
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
|
|
||||||
elif int == 3:
|
|
||||||
return (
|
|
||||||
{
|
|
||||||
"text": self.config["custom_button3"][0],
|
|
||||||
"url": self.config["custom_button3"][1],
|
|
||||||
}
|
|
||||||
if self.config["custom_button3"]
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
|
|
||||||
elif int == 4:
|
|
||||||
return (
|
|
||||||
{
|
|
||||||
"text": self.config["close_btn"],
|
|
||||||
"action": "close",
|
|
||||||
}
|
|
||||||
if self.config["close_btn"]
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.owner
|
|
||||||
async def ainfocmd(self, message: Message):
|
|
||||||
"""Send userbot info"""
|
|
||||||
m1 = self._get_mark(1)
|
|
||||||
m2 = self._get_mark(2)
|
|
||||||
m3 = self._get_mark(3)
|
|
||||||
m4 = self._get_mark(4)
|
|
||||||
|
|
||||||
await self.inline.form(
|
|
||||||
message=message,
|
|
||||||
text=self._render_info(),
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
*([m1] if m1 else []),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
*([m2] if m2 else []),
|
|
||||||
*([m3] if m3 else []),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
*([m4] if m4 else []),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
**{}
|
|
||||||
if self.config["disable_banner"]
|
|
||||||
else {self.config["custom_format"]: self.config["custom_banner"]},
|
|
||||||
)
|
|
||||||
@@ -1,473 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/AnimeVoices.jpg
|
|
||||||
|
|
||||||
from .. import loader
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class AnimeVoicesMod(loader.Module):
|
|
||||||
"""🎤 Popular Anime Voices"""
|
|
||||||
|
|
||||||
strings = {"name": "AnimeVoices"}
|
|
||||||
|
|
||||||
async def smexkcmd(self, message):
|
|
||||||
"""Смех Канеки"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/9",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def smexycmd(self, message):
|
|
||||||
"""Смех Ягами"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/7",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def znaycmd(self, message):
|
|
||||||
"""Знай свое место ничтожество"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/35",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def madaracmd(self, message):
|
|
||||||
"""Учиха Мадара"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/24",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def sharingancmd(self, message):
|
|
||||||
"""Итачи Шаринган"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/VoiceAmore/29",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def itachicmd(self, message):
|
|
||||||
"""Учиха Итачи"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/26",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def imsasukecmd(self, message):
|
|
||||||
"""Учиха Саске"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/VoiceAmore/30",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def paincmd(self, message):
|
|
||||||
"""Познайте боль"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/15",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def rascmd(self, message):
|
|
||||||
"""Расширение территории"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/17",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def tenseicmd(self, message):
|
|
||||||
"""Shinra tensei"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/18",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def dazaicmd(self, message):
|
|
||||||
"""Dazai"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/3",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def gaycmd(self, message):
|
|
||||||
"""I'm gay"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/20",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def bankaicmd(self, message):
|
|
||||||
"""Bankai"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/21",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def satecmd(self, message):
|
|
||||||
"""Sate sate sate"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/5",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def yoaimocmd(self, message):
|
|
||||||
"""Yoaimo"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/11",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def ghoulcmd(self, message):
|
|
||||||
"""Я гуль"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/12",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def welawcmd(self, message):
|
|
||||||
"""Мы закон"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/13",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def dattebayocmd(self, message):
|
|
||||||
"""Даттебайо"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/14",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def hardlifecmd(self, message):
|
|
||||||
"""Жизнь такова"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/16",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def hanmacmd(self, message):
|
|
||||||
"""Я Ханма Шужи"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/25",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def surprisecmd(self, message):
|
|
||||||
"""Surprise MxtherFxcker"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/30",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def equalcmd(self, message):
|
|
||||||
"""Мы созданы равными"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/31",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def beautytreecmd(self, message):
|
|
||||||
"""Красота леса"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/32",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def bankaiicmd(self, message):
|
|
||||||
"""Bankai remix"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/33",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def yametecmd(self, message):
|
|
||||||
"""Фулл ямете кудасай"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/47",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def mafiacmd(self, message):
|
|
||||||
"""Просыпается мафия"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/48",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def sharinganncmd(self, message):
|
|
||||||
"""Sharingan remix"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/49",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def smexecmd(self, message):
|
|
||||||
"""Смех Эрен"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/50",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def narutocmd(self, message):
|
|
||||||
"""Naruto heroes"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/51",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def smexrcmd(self, message):
|
|
||||||
"""Смех рюк"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/52",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def ohayocmd(self, message):
|
|
||||||
"""Охаё"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/53",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def iamhungrycmd(self, message):
|
|
||||||
"""Есть хочу"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/54",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def amaterasucmd(self, message):
|
|
||||||
"""Аматерасу remix"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/55",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def owocmd(self, message):
|
|
||||||
"""Full OwO"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/56",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async def ghoulrucmd(self, message):
|
|
||||||
"""Русский Tokyo Ghoul"""
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
"https://t.me/animevoicesbyamore/57",
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
#voices by @dziru
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
# Friendly Telegram (telegram userbot)
|
|
||||||
# Copyright (C) 2018-2019 The Authors
|
|
||||||
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods, FTG
|
|
||||||
__version__ = (1, 1, 0)
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
from telethon.tl import functions
|
|
||||||
from telethon.utils import get_display_name
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class AutoProfileMod(loader.Module):
|
|
||||||
"""Automatic stuff for your profile :P"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "AutoProfile",
|
|
||||||
"invalid_args": (
|
|
||||||
"<b>Missing parameters, please read the <code>.aguide</code> <emoji document_id=5213468029597261187>✔️</emoji></b>"
|
|
||||||
),
|
|
||||||
"missing_time": (
|
|
||||||
"<b>Time was not specified in bio <emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"enabled_bio": (
|
|
||||||
"<b>Enabled bio clock <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"bio_not_enabled": (
|
|
||||||
"<b>Bio clock is not enabled <emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"disabled_bio": (
|
|
||||||
"<b>Disabled bio clock <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"enabled_name": (
|
|
||||||
"<b>Enabled name clock <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"name_not_enabled": (
|
|
||||||
"<b>Name clock is not enabled <emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"disabled_name": (
|
|
||||||
"<b>Name clock disabled <emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"_cfg_time": "Use timezone 1, -1, -3 etc.",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_uz = {
|
|
||||||
"invalid_args": (
|
|
||||||
"<b>to'g'ri argumetlar emas, <code > ni o'qing.aguide</code> <emoji document_id=5213468029597261187>✔️</emoji></b>"
|
|
||||||
),
|
|
||||||
"missing_time": (
|
|
||||||
"<b>vaqt bio-da o'rnatilmagan<emoji document_id=5215273032553078755 > ❎< / emoji></b>"
|
|
||||||
),
|
|
||||||
"enabled_bio": (
|
|
||||||
"<b>Bio soat muvaffaqiyatli o'rnatildi <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"bio_not_enabled": (
|
|
||||||
"<b>soat bio-ga o'rnatilmagan<emoji document_id=5215273032553078755 > ❎< / emoji > </b>"
|
|
||||||
),
|
|
||||||
"disabled_bio": (
|
|
||||||
"<b > Bio-dagi vaqt muvaffaqiyatli o'chirildi <emoji document_id = 5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"enabled_name": (
|
|
||||||
"<b>soat taxallusga muvaffaqiyatli o'rnatildi <emoji document_id = 5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"name_not_enabled": (
|
|
||||||
"<b>soat taxallusga o'rnatilmagan<emoji document_id=5215273032553078755 > ❎< / emoji > </b>"
|
|
||||||
),
|
|
||||||
"disabled_name": (
|
|
||||||
"<b>taxallusdagi vaqt muvaffaqiyatli o'chirildi <emoji document_id = 5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"_cfg_time": "vaqt zonasidan foydalaning 1, -1, -3 va boshqalar.",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"invalid_args": (
|
|
||||||
"<b>Не правильные аргуметы, прочитай <code>.aguide</code> <emoji document_id=5213468029597261187>✔️</emoji></b>"
|
|
||||||
),
|
|
||||||
"missing_time": (
|
|
||||||
"<b>Время не было установлено в био<emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"enabled_bio": (
|
|
||||||
"<b>Био часы успешно установлены <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"bio_not_enabled": (
|
|
||||||
"<b>Часы не установлено в био<emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"disabled_bio": (
|
|
||||||
"<b>Время в био успешно отключен <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"enabled_name": (
|
|
||||||
"<b>Часы в ник успешно установлены <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"name_not_enabled": (
|
|
||||||
"<b>Часы не установлены в ник<emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"disabled_name": (
|
|
||||||
"<b>Время в нике успешно отключен <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"_cfg_time": "Используй таймзону 1, -1, -3 и тд.",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_de = {
|
|
||||||
"invalid_args": (
|
|
||||||
"<b>Sind nicht die richtigen Argumente, lies <code>.aguide</code> <emoji document_id=5213468029597261187>✔️</emoji></b>"
|
|
||||||
),
|
|
||||||
"missing_time": (
|
|
||||||
"<b>Die Zeit wurde nicht auf bio gesetzt<emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"enabled_bio": (
|
|
||||||
"<b>Bio-Uhr wurde erfolgreich installiert <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"bio_not_enabled": (
|
|
||||||
"<b>Die Uhr ist nicht auf bio eingestellt<emoji document_id=5215273032553078755>❎</emoji></b>"
|
|
||||||
),
|
|
||||||
"disabled_bio": (
|
|
||||||
"<b>Zeit in bio erfolgreich deaktiviert <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"enabled_name": (
|
|
||||||
"<b>Die Uhr wurde erfolgreich auf den Nickname gesetzt <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"name_not_enabled": (
|
|
||||||
"<b>Die Uhr ist nicht auf den Spitznamen<emoji document_id=5215273032553078755>❎</emoji></b> eingestellt"
|
|
||||||
),
|
|
||||||
"disabled_name": (
|
|
||||||
"<b>Nickzeit wurde erfolgreich deaktiviert <emoji document_id=5212932275376759608>✅</emoji></b>"
|
|
||||||
),
|
|
||||||
"_cfg_time": "Benutze die Zeitzone 1, -1, -3 usw.",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.bio_enabled = False
|
|
||||||
self.name_enabled = False
|
|
||||||
self.raw_bio = None
|
|
||||||
self.raw_name = None
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"timezone",
|
|
||||||
"+5",
|
|
||||||
lambda: self.strings("_cfg_time"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
async def client_ready(self, client, db):
|
|
||||||
self.client = client
|
|
||||||
self._me = await client.get_me()
|
|
||||||
|
|
||||||
@loader.command(ru_doc="""Что-бы указать таймзону через конфиг""")
|
|
||||||
async def cfautoprofcmd(self, message):
|
|
||||||
"""To specify the timezone via the config"""
|
|
||||||
name = self.strings("name")
|
|
||||||
await self.allmodules.commands["config"](
|
|
||||||
await utils.answer(message,
|
|
||||||
f"{self.get_prefix()}config {name}")
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command(ru_doc="""Автоматически изменяет биографию вашей учетной записи с учетом текущего времени, использования: .autobio 'сообщение, время как {time}'""")
|
|
||||||
async def autobiocmd(self, message):
|
|
||||||
"""Automatically changes your account's bio with current time, usage:
|
|
||||||
.autobio 'message, time as {time}'"""
|
|
||||||
|
|
||||||
msg = utils.get_args(message)
|
|
||||||
if len(msg) != 1:
|
|
||||||
return await utils.answer(message, self.strings("invalid_args", message))
|
|
||||||
raw_bio = msg[0]
|
|
||||||
if "{time}" not in raw_bio:
|
|
||||||
return await utils.answer(message, self.strings("missing_time", message))
|
|
||||||
|
|
||||||
|
|
||||||
self.bio_enabled = True
|
|
||||||
self.raw_bio = raw_bio
|
|
||||||
await self.allmodules.log("start_autobio")
|
|
||||||
await utils.answer(message, self.strings("enabled_bio", message))
|
|
||||||
|
|
||||||
while self.bio_enabled:
|
|
||||||
offset = datetime.timedelta(hours=self.config["timezone"])
|
|
||||||
tz = datetime.timezone(offset)
|
|
||||||
time1 = datetime.datetime.now(tz)
|
|
||||||
current_time = time1.strftime("%H:%M")
|
|
||||||
bio = raw_bio.format(time=current_time)
|
|
||||||
await self.client(functions.account.UpdateProfileRequest(about=bio))
|
|
||||||
await asyncio.sleep(60)
|
|
||||||
|
|
||||||
@loader.command(ru_doc="""Что-бы остановить время в био введи .stopautobio""")
|
|
||||||
async def stopautobiocmd(self, message):
|
|
||||||
"""Stop autobio cmd."""
|
|
||||||
|
|
||||||
if self.bio_enabled is False:
|
|
||||||
return await utils.answer(message, self.strings("bio_not_enabled", message))
|
|
||||||
self.bio_enabled = False
|
|
||||||
|
|
||||||
await self.allmodules.log("stop_autobio")
|
|
||||||
await utils.answer(message, self.strings("disabled_bio", message))
|
|
||||||
await self.client(
|
|
||||||
functions.account.UpdateProfileRequest(about=self.raw_bio.format(time=""))
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command(ru_doc="""Автоматически изменяет имя вашей учетной записи с учетом текущего времени, использования: .autoname 'сообщение, время как {time}'""")
|
|
||||||
async def autonamecmd(self, message):
|
|
||||||
"""Automatically changes your Telegram name with current time, usage:
|
|
||||||
.autoname '<message, time as {time}>'"""
|
|
||||||
|
|
||||||
msg = utils.get_args(message)
|
|
||||||
if len(msg) != 1:
|
|
||||||
return await utils.answer(message, self.strings("invalid_args", message))
|
|
||||||
raw_name = msg[0]
|
|
||||||
if "{time}" not in raw_name:
|
|
||||||
return await utils.answer(message, self.strings("missing_time", message))
|
|
||||||
|
|
||||||
self.name_enabled = True
|
|
||||||
self.raw_name = raw_name
|
|
||||||
await self.allmodules.log("start_autoname")
|
|
||||||
await utils.answer(message, self.strings("enabled_name", message))
|
|
||||||
|
|
||||||
while self.name_enabled:
|
|
||||||
offset = datetime.timedelta(hours=self.config["timezone"])
|
|
||||||
tz = datetime.timezone(offset)
|
|
||||||
time1 = datetime.datetime.now(tz)
|
|
||||||
current_time = time1.strftime("%H:%M")
|
|
||||||
name = raw_name.format(time=current_time)
|
|
||||||
await self.client(functions.account.UpdateProfileRequest(first_name=name))
|
|
||||||
await asyncio.sleep(60)
|
|
||||||
|
|
||||||
@loader.command(ru_doc="""Что-бы остановить время в имени учетной записи введи .stopautoname""")
|
|
||||||
async def stopautonamecmd(self, message):
|
|
||||||
"""just write .stopautoname"""
|
|
||||||
|
|
||||||
if self.name_enabled is False:
|
|
||||||
return await utils.answer(
|
|
||||||
message, self.strings("name_not_enabled", message)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.name_enabled = False
|
|
||||||
await self.allmodules.log("stop_autoname")
|
|
||||||
await utils.answer(message, self.strings("disabled_name", message))
|
|
||||||
await self.client(
|
|
||||||
functions.account.UpdateProfileRequest(
|
|
||||||
first_name=self.raw_name.format(time="")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command(ru_docs="""Доки ru/en""")
|
|
||||||
async def aguide(self, message):
|
|
||||||
"Just guide ru/en"
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
args = args if args in {"en", "ru"} else "en"
|
|
||||||
|
|
||||||
time = "{time}"
|
|
||||||
nick = f'<a href="tg://user?id={self._me.id}">{utils.escape_html(get_display_name(self._me))}</a>'
|
|
||||||
pref = f"{utils.escape_html(self.get_prefix())}"
|
|
||||||
|
|
||||||
await utils.answer(
|
|
||||||
message,
|
|
||||||
f"<emoji document_id=5789581976176430614>💸</emoji> For example:\n\n<emoji document_id=5789667570579672963>💸</emoji> AutoName: <code>{pref}autoname '{nick} | {time}'</code>\n"
|
|
||||||
f"<emoji document_id=5789667570579672963>💸</emoji> AutoBio: <code>{pref}autobio 'smth | {time}'</code>\n"
|
|
||||||
if args == "en"
|
|
||||||
else (
|
|
||||||
f"<emoji document_id=5789581976176430614>💸</emoji> Например:\n\n<emoji document_id=5789667570579672963>💸</emoji> Авто Ник: <code>{pref}autoname '{nick} | {time}'</code>\n"
|
|
||||||
f"<emoji document_id=5789667570579672963>💸</emoji> Авто Био: <code>{pref}autobio 'что-то | {time}'</code>\n"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# If you don't like the module don't use it
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://github.com/AmoreForever/assets/blob/master/besafe.jpg?raw=true
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import requests
|
|
||||||
import ast
|
|
||||||
import re
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
__version__ = (1, 0, 0)
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class BeSafe(loader.Module):
|
|
||||||
"""
|
|
||||||
Check module before loading
|
|
||||||
"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "BeSafe",
|
|
||||||
"no_args_or_reply": "<emoji document_id=5456652110143693064>🤷♂️</emoji> <b>[BeSafe]</b> No link or reply to file",
|
|
||||||
"safe": "<emoji document_id=5203929938024999176>🛡</emoji> <b>Module is safe</b>",
|
|
||||||
"suspicious": "<emoji document_id=5325771498718241219>🔎</emoji> Module is suspicious\n\n<emoji document_id=6334443713485342501>⛩</emoji> <b>Suspicious imports:</b>\n",
|
|
||||||
'sus_keywords': "\n<emoji document_id=6334405093139416847>🔑</emoji> <b>Suspicous keywords:</b>"
|
|
||||||
}
|
|
||||||
strings_ru = {
|
|
||||||
"no_args_or_reply": "<emoji document_id=5456652110143693064>🤷♂️</emoji> <b>[BeSafe]</b> Нет ссылки или реплея на модуль",
|
|
||||||
"safe": "<emoji document_id=5203929938024999176>🛡</emoji> <b>Модуль безопасен</b>",
|
|
||||||
"suspicious": "<emoji documentx_id=5325771498718241219>🔎</emoji> Модуль подозрительный\n\n<emoji document_id=6334443713485342501>⛩</emoji> <b>Подозрительные импорты:</b>\n",
|
|
||||||
'sus_keywords': "\n<emoji document_id=6334405093139416847>🔑</emoji> <b>Подозрительные ключевые слова:</b>"
|
|
||||||
}
|
|
||||||
|
|
||||||
def extract_imports(self, code):
|
|
||||||
code = code.lstrip('\ufeff') # крч удаление символа BOM, если он есть
|
|
||||||
|
|
||||||
try:
|
|
||||||
tree = ast.parse(code)
|
|
||||||
except SyntaxError as e:
|
|
||||||
if "invalid non-printable character" not in str(e):
|
|
||||||
raise
|
|
||||||
code = code.encode('utf-8-sig').decode('utf-8')
|
|
||||||
tree = ast.parse(code)
|
|
||||||
imports = []
|
|
||||||
|
|
||||||
for node in ast.walk(tree):
|
|
||||||
if isinstance(node, ast.Import):
|
|
||||||
imports.extend(name.name for name in node.names)
|
|
||||||
elif isinstance(node, ast.ImportFrom):
|
|
||||||
module_name = node.module
|
|
||||||
imports.extend(f"{module_name}.{name.name}" for name in node.names)
|
|
||||||
return imports
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
suspicious_imports = [
|
|
||||||
'glob',
|
|
||||||
'os',
|
|
||||||
'sys',
|
|
||||||
'telethon.tl.TLRequest',
|
|
||||||
'requests',
|
|
||||||
]
|
|
||||||
suspicious_keywords = [
|
|
||||||
r'0x418d4e0b',
|
|
||||||
r'0xf5b399ac',
|
|
||||||
r'w+z+mm+"A"+nk+u+h+lk',
|
|
||||||
r'b"\x0bN\x8dA"'
|
|
||||||
r'session',
|
|
||||||
r'TestingHikka_BOT' # временно будет тут
|
|
||||||
]
|
|
||||||
|
|
||||||
def extract_keywords(self, code):
|
|
||||||
words = []
|
|
||||||
for word in self.suspicious_keywords:
|
|
||||||
if r := re.findall(word, code):
|
|
||||||
words.append(r[0])
|
|
||||||
return words
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def bs(self, message):
|
|
||||||
"""
|
|
||||||
BeSafe - <reply to module> or <link to module>
|
|
||||||
"""
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
|
|
||||||
if args:
|
|
||||||
r = await utils.run_sync(requests.get, args)
|
|
||||||
string = r.text
|
|
||||||
elif reply:
|
|
||||||
code = (await self._client.download_file(reply.media, bytes)).decode("utf-8")
|
|
||||||
string = code
|
|
||||||
else:
|
|
||||||
await utils.answer(message, self.strings["no_args_or_reply"])
|
|
||||||
|
|
||||||
imports = self.extract_imports(string)
|
|
||||||
sus_imports = [f"▫️ <code>{imp}</code>" for imp in self.suspicious_imports if imp in imports]
|
|
||||||
sus_keywords = []
|
|
||||||
|
|
||||||
if sus_imports:
|
|
||||||
kw = self.extract_keywords(string)
|
|
||||||
sus_keywords = [f"▫️ <code>{k}</code>" for k in self.suspicious_keywords if k in kw]
|
|
||||||
|
|
||||||
if sus_imports or sus_keywords:
|
|
||||||
sus_list = sus_imports + [self.strings["sus_keywords"]] + sus_keywords
|
|
||||||
text = self.strings["suspicious"] + '\n'.join(sus_list)
|
|
||||||
else:
|
|
||||||
text = self.strings["safe"]
|
|
||||||
|
|
||||||
await utils.answer(message, text)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
|
|
||||||
import re
|
|
||||||
import asyncio
|
|
||||||
import random
|
|
||||||
from aiohttp import web
|
|
||||||
from .. import utils, loader
|
|
||||||
|
|
||||||
|
|
||||||
class WebCreator:
|
|
||||||
def __init__(self, name, tg_link, preview_name):
|
|
||||||
self.url = None
|
|
||||||
self.app = web.Application()
|
|
||||||
self.app.router.add_get("/", self.index)
|
|
||||||
self.name = name
|
|
||||||
self.tg_link = tg_link
|
|
||||||
self.preview_name = preview_name
|
|
||||||
|
|
||||||
async def index(self, request):
|
|
||||||
html_content = f"""
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>For {self.name}</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Indie+Flower&display=swap" rel="stylesheet">
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body {{
|
|
||||||
margin: 0;
|
|
||||||
text-align: center;
|
|
||||||
background: #1d1d1d;
|
|
||||||
font: 22px 'Indie Flower', cursive, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
color: #fff;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}}
|
|
||||||
|
|
||||||
#content {{
|
|
||||||
position: relative;
|
|
||||||
max-width: 470px;
|
|
||||||
margin: 0 auto;
|
|
||||||
line-height: 150%;
|
|
||||||
padding: 20px;
|
|
||||||
z-index: 1;
|
|
||||||
}}
|
|
||||||
|
|
||||||
h1 {{
|
|
||||||
font-size: 2.5rem;
|
|
||||||
color: #f7d066;
|
|
||||||
margin-top: 50px;
|
|
||||||
}}
|
|
||||||
|
|
||||||
p {{
|
|
||||||
font-size: 1.2rem;
|
|
||||||
margin-top: 20px;
|
|
||||||
}}
|
|
||||||
|
|
||||||
span {{
|
|
||||||
color: #f7467e;
|
|
||||||
}}
|
|
||||||
|
|
||||||
@media (max-width: 767px) {{
|
|
||||||
#content {{
|
|
||||||
max-width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="content">
|
|
||||||
<h1>Happy Birthday, {self.name}!</h1>
|
|
||||||
<p>Dear {self.name},<br>
|
|
||||||
On this special day, I wish you all the very best, all the joy you can ever have, and may you be blessed
|
|
||||||
abundantly today, tomorrow, and the days to come! May you have a fantastic birthday and many more to come...
|
|
||||||
HAPPY BIRTHDAY!!!!<br>
|
|
||||||
<span>With love, <a href="{self.tg_link}">{self.preview_name}</a></span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function launchConfetti() {{
|
|
||||||
const duration = 2 * 1000;
|
|
||||||
const end = Date.now() + duration;
|
|
||||||
|
|
||||||
(function frame() {{
|
|
||||||
confetti({{
|
|
||||||
particleCount: 5,
|
|
||||||
angle: 60,
|
|
||||||
spread: 55,
|
|
||||||
origin: {{ x: 0 }},
|
|
||||||
colors: ['#f7d066', '#f7467e', '#fff']
|
|
||||||
}});
|
|
||||||
confetti({{
|
|
||||||
particleCount: 5,
|
|
||||||
angle: 120,
|
|
||||||
spread: 55,
|
|
||||||
origin: {{ x: 1 }},
|
|
||||||
colors: ['#f7d066', '#f7467e', '#fff']
|
|
||||||
}});
|
|
||||||
|
|
||||||
if (Date.now() < end) {{
|
|
||||||
requestAnimationFrame(frame);
|
|
||||||
}}
|
|
||||||
}})();
|
|
||||||
}}
|
|
||||||
|
|
||||||
window.onload = launchConfetti;
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
|
|
||||||
return web.Response(text=html_content, content_type="text/html")
|
|
||||||
|
|
||||||
async def open_tunnel(self, port):
|
|
||||||
ssh_command = f"ssh -o StrictHostKeyChecking=no -R 80:localhost:{port} nokey@localhost.run"
|
|
||||||
process = await asyncio.create_subprocess_shell(
|
|
||||||
ssh_command,
|
|
||||||
stdin=asyncio.subprocess.PIPE,
|
|
||||||
stdout=asyncio.subprocess.PIPE,
|
|
||||||
stderr=asyncio.subprocess.PIPE,
|
|
||||||
)
|
|
||||||
|
|
||||||
url = await self._extract_tunnel_url(process.stdout)
|
|
||||||
self.url = url or f"https://localhost:{port}"
|
|
||||||
return self.url
|
|
||||||
|
|
||||||
async def _extract_tunnel_url(self, stdout):
|
|
||||||
event = asyncio.Event()
|
|
||||||
url = None
|
|
||||||
|
|
||||||
async def read_output():
|
|
||||||
nonlocal url
|
|
||||||
while True:
|
|
||||||
line = await stdout.readline()
|
|
||||||
if not line:
|
|
||||||
break
|
|
||||||
decoded_line = line.decode()
|
|
||||||
match = re.search(r"tunneled.*?(https:\/\/.+)", decoded_line)
|
|
||||||
if match:
|
|
||||||
url = match[1]
|
|
||||||
break
|
|
||||||
event.set()
|
|
||||||
|
|
||||||
await read_output()
|
|
||||||
await event.wait()
|
|
||||||
return url
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class BirthdayWish(loader.Module):
|
|
||||||
"""Share warmth with your loved ones and give them this website to make their birthdays even more special and joyful."""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "BirthdayWish",
|
|
||||||
"provide_name": "<emoji document_id=5456652110143693064>🤷♂️</emoji> <b>Please provide a name</b>",
|
|
||||||
"web_url": "<emoji document_id=5334643333488713810>🌐</emoji> <b>URL: {} | Expires in <code>{}</code> seconds</b>",
|
|
||||||
"expired": "<emoji document_id=5981043230160981261>⏱</emoji> <b>Url Expired</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"provide_name": "<emoji document_id=5456652110143693064>🤷♂️</emoji> <b>Пожалуйста, укажите имя</b>",
|
|
||||||
"web_url": "<emoji document_id=5334643333488713810>🌐</emoji> <b>URL: {} | Истекает через <code>{}</code> секунд</b>",
|
|
||||||
"expired": "<emoji document_id=5981043230160981261>⏱</emoji> <b>Url истек</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.wishes = {}
|
|
||||||
|
|
||||||
async def tunnel_handler(self, port):
|
|
||||||
|
|
||||||
creator = WebCreator(
|
|
||||||
name=self.name, tg_link=self.tg_link, preview_name=self.preview_name
|
|
||||||
)
|
|
||||||
|
|
||||||
runner = web.AppRunner(creator.app)
|
|
||||||
await runner.setup()
|
|
||||||
|
|
||||||
global site
|
|
||||||
site = web.TCPSite(runner, "127.0.0.1", port)
|
|
||||||
await site.start()
|
|
||||||
|
|
||||||
url = await creator.open_tunnel(port)
|
|
||||||
return url, runner
|
|
||||||
|
|
||||||
async def wishcmd(self, message):
|
|
||||||
"""Create Birthday web wishes args: <name> <time:seconds default(20)>"""
|
|
||||||
|
|
||||||
args = utils.get_args_raw(message).split(" ")
|
|
||||||
|
|
||||||
if args[0] == "":
|
|
||||||
return await utils.answer(message, self.strings("provide_name"))
|
|
||||||
|
|
||||||
text = args[0]
|
|
||||||
|
|
||||||
expiration_time = int(args[1]) if len(args) > 1 else 20
|
|
||||||
|
|
||||||
me = await message.client.get_me()
|
|
||||||
|
|
||||||
self.tg_link = f"https://t.me/{me.username}" or "https://t.me/Unknown"
|
|
||||||
self.preview_name = me.first_name
|
|
||||||
self.name = text
|
|
||||||
|
|
||||||
port = random.randint(1000, 9999)
|
|
||||||
|
|
||||||
url, runner = await self.tunnel_handler(port)
|
|
||||||
await utils.answer(
|
|
||||||
message, self.strings("web_url").format(url, expiration_time)
|
|
||||||
)
|
|
||||||
|
|
||||||
await asyncio.sleep(expiration_time)
|
|
||||||
|
|
||||||
await site.stop()
|
|
||||||
await runner.cleanup()
|
|
||||||
|
|
||||||
await utils.answer(message, self.strings("expired"))
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta pic: https://te.legra.ph/file/7772a7dae6290f0a612a6.png
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Bull.jpg
|
|
||||||
|
|
||||||
import random
|
|
||||||
from .. import loader, utils
|
|
||||||
from ..inline.types import InlineCall
|
|
||||||
from ..inline.types import InlineQuery
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bullr = (
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я ПИЗДАК В ТЕОЙ МАТРЕИ НА СВОЙ УЙ КАК МАКАРОНИНУ НАМОТАЛ БЛЯДЬ И НАЧАЛ РАСКРУЧИВАТЬ ЕЁ, ПОСЛЕ ЧЕГО ВЫКИНУЛ В КОСМОС, ЧТОБ ЕЁ ТАМ ИНОПЛАНЕТЯНЫ ХУЯМИ РВАЛИ?)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я ТВОЮ МАТЬ ОТПРАВИЛ СО СВОЕГО ЪХУЯ В НЕБО, ЧТОБ ОНА СВОИМ ПИЗДАКОМ ПРИНИМАЛА МИТЕОРИТНУЮ АТАКУ?)",
|
|
||||||
"ЕСЛИ ТЫ СЕЙЧАС ТАК И БУДЕШЬ ПРОДОЛЖАТЬ ПРОТИВОРЕЧИТЬ МОЕМУ ХУЮ, КАК ИМ КАК БЛЯДЬ НА НЛО ЗАХВОЧУ ТВОЁ ОЧКО И НАЧНУ ОПЫТЫ ПРОВОДИТЬ",
|
|
||||||
"ТЫ ПОНИМАЕШЬЧ ТО ВТОЯ МАТЬ МОЙ ХУЙ ЗАВЕРНУЛА В ПАКЕТИК ПОТОМУ ЧТО У ЭТОЙ БОМЖИХИ НЕБЫЛО ДЕНЕГ НА ПРЕЗИКИ, И ПОКЕТИК ПОРВАЛСЯ, И РОДИЛОСЬ ТАКОЕ ХУЙЛО КАК ТЫ",
|
|
||||||
"TЫ ПОНИМАЕШЬ ЧТО Я ТВОЮ МАТЬ СЛУЧАЙНО СВОИМ ХУЁМ СМЁЛ НАХУЙ СО СВОЕГО ПУТИ, И ОНА УЛЕТЕЛА НА РАДИУС ОБСТРЕЛА МОЕЙ ЗАЛУПЫ",
|
|
||||||
"АМЕБА ЕБАНАЯ СУКА) МАМАШКУ ТВОЮ ДЫРЯВИЛ ЧЕТ ) НАХУЙ ТВОЯ МАМАША КРИЧИТ КОГДА Я НАЧИНАЮ ЕБАТЬ ЕЕ)",
|
|
||||||
"АМЕБА ИЛИ ТЫ ОЛЕНЬ?) СЛЫШЬ ЕСЛИ ТЫ ПРОЛЬЕШЬ НА МОЙ ХУЙ СЛЕЗЫ , ТО ТЫ НЕ РАССЧИТЫВАЙ НА ТО , ЧТО ПОТОМ К ТЕБЕ ПРИДЕТ ФЕЯ И ПООБЕЩАЕТ ТЕБЕ ДОЛГУЮ И СЧАСТЛИВУЮ ЖИЗНЬ)",
|
|
||||||
"ОЛЕНЬ ТЫ ЕБАНЫЙ) МАТЬ ТВОЮ ЕБУ ЧЕТ ) ДАВАЙ ТЫ ЩАС ВОЗЬМЕШЬ МОЙ ХУЙ КАК ПЕРО И СЛОВНО КАК ПИСАТЕЛЬ СЕРЕБРЯНОГО ВЕКА НАПИШЕШЬ КАКОЙ НИБУДЬ РОМАН КОТОРЫЙ БУДЕТ ПО РАЗМЕРУ ПРИМЕРНО КАК МАСТЕР И МАРГАРИТА )",
|
|
||||||
"твоя мамка блядоебская кобыла и лезби",
|
|
||||||
"у тебя мать сраная шлюха",
|
|
||||||
"Я ТОВЮ МАМАШУ СВОИМ ХУЁМ РАСПЛЮЩИЛ, И ТЕПЕРЬ ОНА КАК ХОЯЧАЮ ПРУЖИТНКА БЛЯДЬ, ОТ СЕБЯ ВСЕ ХУИ ОТТАЛКИВАЕТ КРОМЕ МОЕГО, ДЛЯ МОЕГО ХУЯ ВСЕГДА ОТКРЫТ ДОСТУП В ЕЁ ПИЗДАК",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я ТВОЮ МАТЬ БЛЯДЬ НАТЯНУЛ ПИЗДАКОМ НА ВЫСОКОВОЛЬТНУЮ ЭЛЕКТРО ВЫШКУ, И ОНА В СЕБЯ НАХУЙ ВЕСЬ ТОК ВТЯНУЛА, ТЕПЕРЬ ОНА БЛЯДЬ КАК ЭЛЕКТРО",
|
|
||||||
"Я КОГДА ВЫЕБАЛ ТВОЮ МАТЬ Я СВОЙ ХУЙ ПОСТАВИЛ К ЕЁ УХУ, ЧТОБ ОНА СЛЫШАЛА ПРИБОЯ СПЕРМЫ, А ПОТОМ ОНА ШИРОКО РАСКРЫЛА РОТ МЫ В ЕЁ ЕБЛЯТНИКЕ УСТРОИЛИ ОКЕАН",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я В ПИЗДАК ТВОЕЙ МАТРЕИ СВОЙ ХУЙ ЗАСУНУ КАК БЛЯДЬ ШТТЕККЕР И ЕЁ ЗАРЯД ПОВЫСИЛСЯ КАК ОТ ЭНЕРГЕТИКА)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО ТВОЯ МАТЬ НА МОЁМ ХУЮ УСТРОИЛА БЛЯДЬ ТАНЦПОЛ, И НАЧАЛА СВОИМ ПОДРУГАМ ПРОДАВАТЬ НА НЕГО БИЛЕТЫ",
|
|
||||||
" ЕСЛИ ТЫ СЕЙЧАС НЕ НАЧНЁШЬ МНЕ ОТВЕЧАТЬ, Я ТЕБЕ НАХУЙ ХЁМ ПАЛЬЦЫ ПЕРЕЛОМАЮ, ОБРАЗИНА ТЫ ЕБАНАЯ)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО ВТОЯ МАМАШКА КАШЁЛКА ЕБАНАЯ, НА МОЙ ХУЙ ВЕШАЕТСЯ СВОИМ ПИЗДАКОМ КАК МАГНИТИК НА ХОЛОДИЛЬНИК, ПИДОПР ТЫ БЛЯДЬ ЕБАНЫЙ",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я ТВОЕЙ МАТЕРИ ГОЛОВУ ХУЁМ КАК КОПЬЁМ ПРОБИЛ БЛЯДЬ И ЕЁ КУРИНЫЙ МОЗГ УМЕР НАХУЙ)) ИЗ-ЗА ЭТОГО ОНА ТЕБЯ ДАЖЕ И НЕ ВСПОМИНАЕТ)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я ВЫСТАВИЛ СВОЙ ХУЙ НА АВИТО, А ТВОЯ МАТЬ ПРОШЛА БЛЯДЬ БЕЗ ОЧЕРЕДИ И ККУПИЛА ЕГО, ОТДАВ СВОЮ ГНИЛУЮ ПОЧКУ?)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО ТВОЯ МАТЬ МОЙ ХУЙ НА НОЧЬ СЕБЕ В ПИЗДАК СУЁТ КАК ОБОГРЕВАТЕЛЬ НАХУЙ?)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я ПОКА ЧТО ЕБАЛ ТВОЮ МАМАШУ В СРАКУ, У НЕЁ ТАМ ЗАСОР СПЕРМЫ БЛЯДЬ ОБРАЗОВАЛСЯ И ЗАСОХ, ТЕПЕРЬ ОНА СРАТЬ НОРМАЛЬНО НЕ МОЖЕТ, ИДИ НАХУЙ СПАСАЙ ЭТУ ШЛЮХУ",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО КОГДА Я ЕБУ ТВОЮ МАТЬ ЧТОБЫ ОНА НЕ ОРАЛА Я ЕЙ КЛЯП В РОТ СУЮ, НО ОДИН РАЗ СЛУЧИЛОСЬ ТАКОЕ, ЧТО КОГДА Я СВОИМ ХУЁМ ДАЛ ЕЙ ПО ПИЗДЕ ОНА ЭТОТ КЛЯП ПРОГЛАТИЛА, И НАЧАЛА ЗАДЫХАТЬСЯ, СПАСИ СВОЮ ШЛЮХА МАМКУ)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО МОЙ ХУЙ ВЗЛАМЫВАЕТ ОЧКО ТВОЕЙ МАТЕРИ КАК СЕЙФ НАХУЙ, И ОТ ТУДА НАЧИНАЮТ ВАЛИТЬСЯ САМОРОДКИ СПЕРМЫ?)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я В ПИЗДАКЕ ТВОЕЙ МАТЕРИ УСТРОИЛ ИЗВЕРЖЕНИЕ СВОЕГО ХУЯ НАХУЙ?",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я ХУЁМ НАЧАЛ МОТАТЬ ПЕРЕД ТВОИМ ЕБАЛОИ И ТЕБЯ СЛУЧАЙНО НАХУЙ ЗАГИПНОТЕЗИРОВАЛ, И ТЫ ОБ ХУИ СТАЛ ГОЛОВОЙ БИТЬСЯ?)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО КОГДА Я ТВОЮ МАТЬ ОНА КАК ШЛЮХА ЛОЖИТСЯ НА СПИНКУ И НАЧИНАЕТ ПОСАСЫВАТЬ МОИ ЯЙЦА",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я В ПИЗДАКЕ ТВОЕЙ МАТЕРИ ИЗ ЕЁ КЛИТОРНЫЙ СТЕН ВЫРЕЗАЮ РАКЕТНИЦУ СВОИМ ХУЁМ?",
|
|
||||||
"Я СЕЙЧАС СВОЕЙ СПЕРМОЙ ОБОЛЬЮ ТВОЙ ПИЗДАК КАК КЕРАСИНОМ, И ПУЩУ НА НЕГО ИСКРУ, ДОБЫТАЯ КОТОРАЯ БУДЕТ О ТВОИ ГНИЛЫЕ ЗУБКИ, И ТЫ СГОРИШЬ НАХУЙ)",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО ТЫ ОТ МОЕЙ ЗАЛУПЫ ПРЯЧШЬСЯ В ПИЗДАКЕ СВОЕЙ МАТЕРИ КАК НАХУЙ В БУНКЕРЕ, А Я СВОИМ ХУЁМ ЕГО НА СКВОЗЬ ПРОШИЛ И ТЕБЕ В ЕБАЛО ПОПАЛ)) ",
|
|
||||||
"ТЫ ПОНИМАЕШЬ ЧТО Я ХУЁМ СТАЛ КАТАЛИЗИРОВАТЬ ПИЗДАК ТВОЕЙ МАТЕРИ НА РАЗДВИЖЕНИЕ ЕЁ ЖИРНЫХ НОГ?)",
|
|
||||||
)
|
|
||||||
|
|
||||||
def bullme():
|
|
||||||
iwfy = random.choice(bullr)
|
|
||||||
return iwfy
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class BullMod(loader.Module):
|
|
||||||
"""Bull пиз#а собеседнику"""
|
|
||||||
|
|
||||||
strings = {"name": "BullMod"}
|
|
||||||
|
|
||||||
@loader.inline_everyone
|
|
||||||
async def bull_inline_handler(self, query: InlineQuery):
|
|
||||||
"""Забулить кого-то жесткими матами про мать"""
|
|
||||||
aoa = bullme()
|
|
||||||
|
|
||||||
btn_a = [{"text": "🌀 Random", "callback": self.bulls}]
|
|
||||||
|
|
||||||
return {
|
|
||||||
"title": "Пошутить про маму",
|
|
||||||
"thumb": "https://te.legra.ph/file/b2a6c8d20e0034a534ac4.jpg",
|
|
||||||
"description": "Отправить...",
|
|
||||||
"message": f"<i>{aoa}</i>",
|
|
||||||
"reply_markup": btn_a,
|
|
||||||
}
|
|
||||||
|
|
||||||
async def bullcmd(self, message):
|
|
||||||
"""Забулить кого-то жесткими матами про мать"""
|
|
||||||
aoa = bullme()
|
|
||||||
await utils.answer(message, aoa)
|
|
||||||
|
|
||||||
async def bullicmd(self, message):
|
|
||||||
"""Забулить кого-то жесткими матами про мать (inline)"""
|
|
||||||
aoa = bullme()
|
|
||||||
await self.inline.form(
|
|
||||||
message=message,
|
|
||||||
text=aoa,
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "🌀 Random", "callback": self.bulls}],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
async def bulls(self, call: InlineCall):
|
|
||||||
aoa = bullme()
|
|
||||||
await call.edit(
|
|
||||||
text=aoa,
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "🌀 Random", "callback": self.bulls}],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta pic: https://te.legra.ph/file/388e1b26a46a8c439e479.png
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Createlinks.jpg
|
|
||||||
|
|
||||||
|
|
||||||
from .. import loader, utils, security
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class AmorelinksMod(loader.Module):
|
|
||||||
"""Create links"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "AmoreLinks",
|
|
||||||
"youtube": "🫂 <b>YouTube link special for you.</b>\n\n",
|
|
||||||
"google": "🫂 <b>Google link special for you.</b>\n\n",
|
|
||||||
"github": "🫂 <b>Github link special for you.</b>\n\n",
|
|
||||||
"pornhub": "🫂 <b>Pornhub link special for you.</b>\n\n",
|
|
||||||
"telegram": "🫂 <b>Telegram link special for you.</b>\n\n",
|
|
||||||
"4pda": "🫂 <b>4pda link special for you.</b>\n\n",
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async def ytcmd(self, message):
|
|
||||||
"""<text> create YouTube link"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
s = f"<b>✏ Input word: <code>{text}</code></b>"
|
|
||||||
if await self.allmodules.check_security(
|
|
||||||
message,
|
|
||||||
security.OWNER | security.SUDO,
|
|
||||||
):
|
|
||||||
|
|
||||||
try:
|
|
||||||
await self.inline.form(
|
|
||||||
self.strings("youtube", message) + s,
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "♨️ Link", "url": f"https://m.youtube.com/results?sp=mAEA&search_query={text}"}],
|
|
||||||
[{"text": "🔻 Close", "action": f"close"}],
|
|
||||||
|
|
||||||
],
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
await utils.answer(message, self.strings("join", message))
|
|
||||||
|
|
||||||
|
|
||||||
async def gugcmd(self, message):
|
|
||||||
"""<text> create Google link"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
s = f"<b>✏ Input word: <code>{text}</code></b>"
|
|
||||||
if await self.allmodules.check_security(
|
|
||||||
message,
|
|
||||||
security.OWNER | security.SUDO,
|
|
||||||
):
|
|
||||||
|
|
||||||
try:
|
|
||||||
await self.inline.form(
|
|
||||||
self.strings("google", message) + s,
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "🛰 Link", "url": f"https://www.google.com/search?q={text}"}],
|
|
||||||
[{"text": "🔻 Close", "action": f"close"}],
|
|
||||||
],
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
await utils.answer(message, self.strings("join", message))
|
|
||||||
|
|
||||||
async def ghcmd(self, message):
|
|
||||||
"""<text> create Github link"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
s = f"<b>✏ Input word: <code>{text}</code></b>"
|
|
||||||
if await self.allmodules.check_security(
|
|
||||||
message,
|
|
||||||
security.OWNER | security.SUDO,
|
|
||||||
):
|
|
||||||
|
|
||||||
try:
|
|
||||||
await self.inline.form(
|
|
||||||
self.strings("github", message) + s,
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "🛰 Link", "url": f"https://github.com/search?q={text}"}],
|
|
||||||
[{"text": "🔻 Close", "action": f"close"}],
|
|
||||||
],
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
await utils.answer(message, self.strings("join", message))
|
|
||||||
|
|
||||||
async def phcmd(self, message):
|
|
||||||
"""<text> create PornHub link"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
s = f"<b>✏ Input word: <code>{text}</code></b>"
|
|
||||||
if await self.allmodules.check_security(
|
|
||||||
message,
|
|
||||||
security.OWNER | security.SUDO,
|
|
||||||
):
|
|
||||||
|
|
||||||
try:
|
|
||||||
await self.inline.form(
|
|
||||||
self.strings("pornhub", message) + s,
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "🛰 Link", "url": f"https://rt.pornhub.com/video/search?search={text}"}],
|
|
||||||
[{"text": "🔻 Close", "action": f"close"}],
|
|
||||||
],
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
await utils.answer(message, self.strings("join", message))
|
|
||||||
|
|
||||||
async def tgcmd(self, message):
|
|
||||||
"""<text> create Telegram link"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
s = f"<b>✏ Input word: <code>{text}</code></b>"
|
|
||||||
if await self.allmodules.check_security(
|
|
||||||
message,
|
|
||||||
security.OWNER | security.SUDO,
|
|
||||||
):
|
|
||||||
|
|
||||||
try:
|
|
||||||
await self.inline.form(
|
|
||||||
self.strings("telegram", message) + s,
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "🛰 Link", "url": f"tg://search?query={text}"}],
|
|
||||||
[{"text": "🔻 Close", "action": f"close"}],
|
|
||||||
],
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
await utils.answer(message, self.strings("join", message))
|
|
||||||
|
|
||||||
async def pdacmd(self, message):
|
|
||||||
"""<text> create 4pda link"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
s = f"<b>✏ Input word: <code>{text}</code></b>"
|
|
||||||
if await self.allmodules.check_security(
|
|
||||||
message,
|
|
||||||
security.OWNER | security.SUDO,
|
|
||||||
):
|
|
||||||
|
|
||||||
try:
|
|
||||||
await self.inline.form(
|
|
||||||
self.strings("4pda", message) + s,
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "🛰 Link", "url": f"https://4pda.to/forum/index.php?act=search&source=all&forums=316&subforums=1&query={text}"}],
|
|
||||||
[{"text": "🔻 Close", "action": f"close"}],
|
|
||||||
],
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
await utils.answer(message, self.strings("join", message))
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/DTWR.jpg
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class DTWRMod(loader.Module):
|
|
||||||
"""Module Don't tag wihout reason"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "DTWR",
|
|
||||||
"text": "Your custom text",
|
|
||||||
"username": "Input you username without '@'",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"text": "Кастомный текст",
|
|
||||||
"username": "Введи свой юзернэйм без '@'",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_uz = {
|
|
||||||
"text": "Kastom text",
|
|
||||||
"username": "Usernameingizni kiriting, '@' siz"
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"Username",
|
|
||||||
"username",
|
|
||||||
doc=lambda: self.strings("username"),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"custom_text",
|
|
||||||
"😫 Please don't tag me without reason",
|
|
||||||
doc=lambda: self.strings("text"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command(ru_docs="Конфиг этого модуля")
|
|
||||||
async def cfgdtwrcmd(self, message):
|
|
||||||
"""This module config"""
|
|
||||||
name = self.strings("name")
|
|
||||||
await self.allmodules.commands["config"](
|
|
||||||
await utils.answer(message, f"{self.get_prefix()}config {name}")
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.tag("only_messages", "only_groups", "in")
|
|
||||||
async def watcher(self, message: Message):
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
|
|
||||||
tag = self.config['Username']
|
|
||||||
if tag.startswith('@') is False:
|
|
||||||
tag = f"@{tag}"
|
|
||||||
|
|
||||||
if reply:
|
|
||||||
return False
|
|
||||||
if message.text.lower() == tag:
|
|
||||||
await message.reply(self.config["custom_text"])
|
|
||||||
await self._client.send_read_acknowledge(
|
|
||||||
message.chat_id,
|
|
||||||
clear_mentions=True,
|
|
||||||
)
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Facts.jpg
|
|
||||||
# channel @facti_p
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
from telethon import functions
|
|
||||||
from asyncio import sleep
|
|
||||||
import random
|
|
||||||
import datetime
|
|
||||||
chat = "@faktiru"
|
|
||||||
|
|
||||||
|
|
||||||
class FactsMod(loader.Module):
|
|
||||||
"""More Interesting Facts"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Facts",
|
|
||||||
"wait": "<emoji document_id=5472146462362048818>💡</emoji> Searching..."
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"wait": "<emoji document_id=5472146462362048818>💡</emoji> Поиск..."
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.command(ru_docs="Интересные Факты")
|
|
||||||
async def afactscmd(self, message):
|
|
||||||
"""Intersting Facts"""
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
await utils.answer(message, self.strings["wait"])
|
|
||||||
result = await message.client(
|
|
||||||
functions.messages.GetHistoryRequest(
|
|
||||||
peer=chat, offset_id=0, offset_date=datetime.datetime.now(), add_offset=random.randint(0, 1000), limit=1, max_id=0, min_id=0, hash=0,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
await sleep(0.30)
|
|
||||||
await message.delete()
|
|
||||||
await message.client.send_message(
|
|
||||||
message.to_id,
|
|
||||||
result.messages[0],
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://github.com/AmoreForever/assets/blob/master/Figlet.jpg?raw=true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import pyfiglet
|
|
||||||
import functools
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
|
|
||||||
class Figlet(loader.Module):
|
|
||||||
"""Creates Figlet Text"""
|
|
||||||
|
|
||||||
strings = {"name": "Figlet"}
|
|
||||||
style_to_font = {
|
|
||||||
"slant": "slant",
|
|
||||||
"3d": "3-d",
|
|
||||||
"5line": "5lineoblique",
|
|
||||||
"alpha": "alphabet",
|
|
||||||
"banner": "banner3-D",
|
|
||||||
"doh": "doh",
|
|
||||||
"iso": "isometric1",
|
|
||||||
"letter": "letters",
|
|
||||||
"allig": "alligator",
|
|
||||||
"dotm": "dotmatrix",
|
|
||||||
"bubble": "bubble",
|
|
||||||
"bulb": "bulbhead",
|
|
||||||
"digi": "digital"
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def listfig(self, message):
|
|
||||||
"""List of figlet styles"""
|
|
||||||
keys_list = " , ".join(list(self.style_to_font.keys()))
|
|
||||||
await utils.answer(message, f"🚩 Available styles: {keys_list}")
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def figlet(self, message):
|
|
||||||
"""Create figlet text, <style> | <args>"""
|
|
||||||
args = utils.get_args_raw(message).split(" | ")
|
|
||||||
if len(args) < 2:
|
|
||||||
await utils.answer(message, "Not enough arguments")
|
|
||||||
return
|
|
||||||
|
|
||||||
font = self.style_to_font.get(args[0], None)
|
|
||||||
if font is None:
|
|
||||||
await utils.answer(message, "There is no such style")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not args[1]:
|
|
||||||
await utils.answer(message, "Text argument is empty")
|
|
||||||
return
|
|
||||||
|
|
||||||
result = await self.figlet_format_cached(args[1], font)
|
|
||||||
await utils.answer(message, f"<code>{result}<code>")
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@functools.lru_cache(maxsize=None)
|
|
||||||
async def figlet_format_cached(text, font):
|
|
||||||
return pyfiglet.figlet_format(text, font=font)
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/fileext.jpg
|
|
||||||
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
async def search_extention(ext):
|
|
||||||
sample_url = "https://www.fileext.com/file-extension/{}.html"
|
|
||||||
response_api = requests.get(sample_url.format(ext))
|
|
||||||
if not response_api.ok:
|
|
||||||
return (
|
|
||||||
f"Error fetching details for {ext}. Status code: {response_api.status_code}"
|
|
||||||
)
|
|
||||||
soup = BeautifulSoup(response_api.content, "html.parser")
|
|
||||||
return soup.find_all("td", {"colspan": "3"})[-1].text
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class FileExtMod(loader.Module):
|
|
||||||
"""Get file extention details"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "FileExt",
|
|
||||||
"no_args": "<emoji document_id=5456652110143693064>🤷♂️</emoji> <b>No args passed</b>",
|
|
||||||
"response": "<emoji document_id=5467732133629926938>🔍</emoji> <b>File Extension</b>: <code>{}</code>\n<emoji document_id=5467919175160705819>🔍</emoji> <b>Description</b>: <code>{}</code>",
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def fileext(self, message: Message):
|
|
||||||
"""Get file extention details"""
|
|
||||||
if args := utils.get_args_raw(message):
|
|
||||||
await utils.answer(
|
|
||||||
message,
|
|
||||||
self.strings("response").format(args, await search_extention(args)),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
await utils.answer(message, self.strings("no_args"))
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://github.com/AmoreForever/assets/blob/master/fragment_checker.jpg?raw=true
|
|
||||||
# requires: bs4
|
|
||||||
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
class Fragment(loader.Module):
|
|
||||||
"""Show how much is the username in the Fragment.com"""
|
|
||||||
|
|
||||||
strings = {"name": "FragmentChecker"}
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def fcheck(self, message):
|
|
||||||
"""check username in the Fragment.com"""
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
response = requests.get(f"https://fragment.com/username/{args}")
|
|
||||||
|
|
||||||
if response.status_code == 200:
|
|
||||||
soup = BeautifulSoup(response.content, "html.parser")
|
|
||||||
elements = soup.select(".table-cell-value.tm-value.icon-before.icon-ton")
|
|
||||||
if elements:
|
|
||||||
text = elements[0].text.strip()
|
|
||||||
await utils.answer(message, f"<emoji document_id=5215219508670638513>💎</emoji> <b>Username Found!</b>\n<emoji document_id=5467626799556992380>✈️</emoji> <b>Username:</b> <code>{args}</code>\n<emoji document_id=5460720028288557729>🪙</emoji> <b>Cost:</b> <code>{text}</code> TON")
|
|
||||||
if not elements:
|
|
||||||
await utils.answer(message, f"<emoji document_id=5212926868012935693>❌</emoji> <b>Username <code>{args}</code> not found!</b>")
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
autoprofile
|
|
||||||
animevoices
|
|
||||||
aeconv
|
|
||||||
amethyste
|
|
||||||
activity
|
|
||||||
phsticker
|
|
||||||
amoreinfo
|
|
||||||
abstract
|
|
||||||
dtwr
|
|
||||||
bull
|
|
||||||
meowvoices
|
|
||||||
mydiary
|
|
||||||
createlinks
|
|
||||||
imgbb
|
|
||||||
instsave
|
|
||||||
telegraphup
|
|
||||||
inlineping
|
|
||||||
poststealer
|
|
||||||
searchpic
|
|
||||||
funquotes
|
|
||||||
facts
|
|
||||||
hacker
|
|
||||||
premiuminfo
|
|
||||||
cartoonimg
|
|
||||||
trigger
|
|
||||||
recognition
|
|
||||||
universaltime
|
|
||||||
nytimer
|
|
||||||
figlet
|
|
||||||
fileext
|
|
||||||
my_usernames
|
|
||||||
fragment_checker
|
|
||||||
alarm
|
|
||||||
leta
|
|
||||||
speech
|
|
||||||
jutsu
|
|
||||||
usernamestealer
|
|
||||||
lexiwiz
|
|
||||||
birthdaywish
|
|
||||||
wakatime
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Funquotes.jpg
|
|
||||||
__version__ = (1, 0, 0)
|
|
||||||
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class InlineFunMod(loader.Module):
|
|
||||||
"""Create Fun quotes"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "FunQuotes",
|
|
||||||
"where_text": "<emoji document_id='6041914500272098262'>🚫</emoji> <b>Provide a text to create sticker with</b>",
|
|
||||||
"processing": (
|
|
||||||
"<emoji document_id='6318766236746384900'>🕔</emoji> <b>Processing...</b>"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"where_text": "<emoji document_id='6041914500272098262'>🚫</emoji> <b>Укажи текст для создания стикера</b>",
|
|
||||||
"processing": (
|
|
||||||
"<emoji document_id='6318766236746384900'>🕔</emoji> <b>Обработка...</b>"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
async def glaxcmd(self, message: Message):
|
|
||||||
"""<text> - Create Google search quote"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
if not text:
|
|
||||||
await message.edit(self.strings("where_text"))
|
|
||||||
return
|
|
||||||
|
|
||||||
await message.edit(self.strings("processing"))
|
|
||||||
|
|
||||||
try:
|
|
||||||
query = await self._client.inline_query("@googlaxbot", text)
|
|
||||||
await message.respond(file=query[0].document)
|
|
||||||
except Exception as e:
|
|
||||||
await utils.answer(message, str(e))
|
|
||||||
return
|
|
||||||
|
|
||||||
if message.out:
|
|
||||||
await message.delete()
|
|
||||||
|
|
||||||
async def twitcmd(self, message: Message):
|
|
||||||
"""<text> - Create Twitter message quote"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
if not text:
|
|
||||||
await message.edit(self.strings("where_text"))
|
|
||||||
return
|
|
||||||
|
|
||||||
await message.edit(self.strings("processing"))
|
|
||||||
|
|
||||||
try:
|
|
||||||
query = await self._client.inline_query("@TwitterStatusBot", text)
|
|
||||||
await message.respond(file=query[0].document)
|
|
||||||
except Exception as e:
|
|
||||||
await utils.answer(message, str(e))
|
|
||||||
return
|
|
||||||
|
|
||||||
if message.out:
|
|
||||||
await message.delete()
|
|
||||||
|
|
||||||
async def frogcmd(self, message: Message):
|
|
||||||
"""<text> - Create Frog text quote"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
if not text:
|
|
||||||
await message.edit(self.strings("where_text"))
|
|
||||||
return
|
|
||||||
|
|
||||||
await message.edit(self.strings("processing"))
|
|
||||||
|
|
||||||
try:
|
|
||||||
query = await self._client.inline_query("@honka_says_bot", text + ".")
|
|
||||||
await message.respond(file=query[0].document)
|
|
||||||
except Exception as e:
|
|
||||||
await utils.answer(message, str(e))
|
|
||||||
return
|
|
||||||
|
|
||||||
if message.out:
|
|
||||||
await message.delete()
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Hacker.jpg
|
|
||||||
__version__ = (1, 0, 0)
|
|
||||||
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
import requests
|
|
||||||
from PIL import Image,ImageFont,ImageDraw
|
|
||||||
import io
|
|
||||||
from textwrap import wrap
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class HackerMod(loader.Module):
|
|
||||||
"""Create hacker message stickers"""
|
|
||||||
strings = {
|
|
||||||
'name': 'Hacker',
|
|
||||||
'what': 'Reply to text or write text <emoji document_id="5467928559664242360">❗️</emoji>',
|
|
||||||
'processing': 'Processing <emoji document_id="6334710044407368265">🚀</emoji>'
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.owner
|
|
||||||
async def hackercmd(self, message):
|
|
||||||
"""Reply to text or write text"""
|
|
||||||
|
|
||||||
ufr = requests.get("https://0x0.st/opzq.ttf")
|
|
||||||
f = ufr.content
|
|
||||||
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
if not args:
|
|
||||||
if not reply:
|
|
||||||
await message.edit(self.strings('what', message))
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
txt = reply.raw_text
|
|
||||||
else:
|
|
||||||
txt = utils.get_args_raw(message)
|
|
||||||
await message.edit(self.strings("processing"))
|
|
||||||
pic = requests.get("https://0x0.st/opzN.jpg")
|
|
||||||
pic.raw.decode_content = True
|
|
||||||
img = Image.open(io.BytesIO(pic.content)).convert("RGB")
|
|
||||||
|
|
||||||
W, H = img.size
|
|
||||||
txt = txt.replace("\n", "𓃐")
|
|
||||||
text = "\n".join(wrap(txt, 19))
|
|
||||||
t = text + "\n"
|
|
||||||
t = t.replace("𓃐","\n")
|
|
||||||
draw = ImageDraw.Draw(img)
|
|
||||||
font = ImageFont.truetype(io.BytesIO(f), 32, encoding='UTF-8')
|
|
||||||
w, h = draw.multiline_textsize(t, font=font)
|
|
||||||
imtext = Image.new("RGBA", (w+10, h+10), (255, 250, 250, 1))
|
|
||||||
draw = ImageDraw.Draw(imtext)
|
|
||||||
draw.multiline_text((10, 10),t,(255, 255, 255),font=font, align='left')
|
|
||||||
imtext.thumbnail((339, 181))
|
|
||||||
w, h = 339, 181
|
|
||||||
img.paste(imtext, (10,10), imtext)
|
|
||||||
out = io.BytesIO()
|
|
||||||
out.name = "amore.webp"
|
|
||||||
img.save(out)
|
|
||||||
out.seek(0)
|
|
||||||
await message.client.send_file(message.to_id, out, reply_to=reply)
|
|
||||||
await message.delete()
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
# ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
||||||
# ⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠟⠛⠛⠛⠛⠛
|
|
||||||
# ⣶⣦⣤⣤⣤⣤⣤⣤⣬⣭⣭⣍⣉⡙⠛⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⣋⣩⣭⣥⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣶
|
|
||||||
# ⣆⠀⠀⠀⢡⠁⠀⡀⠀⢸⠟⠻⣯⠙⠛⠷⣶⣬⡙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢉⣥⣶⡟⠻⣙⡉⠀⢰⡆⠀⠀⣡⠀⣧⠀⠀⠀⢨
|
|
||||||
# ⠻⣦⠀⠀⠈⣇⣀⣧⣴⣿⣶⣶⣿⣷⠀⢀⡇⠉⠻⢶⣌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣡⡶⠟⠉⠀⢣⠀⣿⠷⠀⠀⠀⠀⣿⡷⢀⠇⠀⠀⢠⣿
|
|
||||||
# ⣦⡈⢧⡀⠀⠘⢮⡙⠛⠉⠀⠄⠙⢿⣀⠞⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠈⠳⣄⠉⠓⠒⠚⠋⢀⡠⠋⠀⢀⣴⣏⣿
|
|
||||||
# ⣿⣿⣿⣛⣦⣀⠀⠙⠓⠦⠤⣤⠔⠛⠁⠀⠀⠀⠀⠀⢀⣀⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣤⣤⣤⣤⣤⣀⣀⣀⣀⢙⢓⣒⡒⠚⠋⢠⣤⢶⣟⣽⣿⣿
|
|
||||||
# ⣿⣿⣿⣿⣿⣿⣷⣦⠀⠀⣴⣿⣷⣶⣶⣶⣾⡖⢰⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣾⣿⣿⣶⣾⣿⣿⣿⣿⣿⣿
|
|
||||||
# ⣿⣿⣿⣿⣿⣿⣿⣿⠀⢀⣿⣿⣿⣿⣿⣿⣿⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
||||||
# ⣿⣿⣿⣿⣿⣿⣿⡏⠀⢸⣿⣿⣿⣿⣿⣿⣿⠁⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
||||||
# ⣿⣿⣿⣿⣿⣿⣿⣷⠀⢸⣿⣿⣿⣿⣿⣿⣿⠀⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# https://t.me/amorescam
|
|
||||||
|
|
||||||
#
|
|
||||||
# █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
|
|
||||||
# █▀█ █ █ █ █▀█ █▀▄ █
|
|
||||||
# © Copyright 2022
|
|
||||||
#
|
|
||||||
# https://t.me/hikariatama
|
|
||||||
#
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
|
|
||||||
# meta developer: @amoremods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Imgbb.jpg
|
|
||||||
|
|
||||||
|
|
||||||
import imghdr
|
|
||||||
import io
|
|
||||||
import random
|
|
||||||
import re
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from telethon.errors.rpcerrorlist import YouBlockedUserError
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class ImgbbUploader(loader.Module):
|
|
||||||
"""Upload you photo/video/gif to https://ibb.co"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Imgbb",
|
|
||||||
"noargs": "🚫 <b>File not specified</b>",
|
|
||||||
"err": "🚫 <b>Error uploading</b>",
|
|
||||||
"ban": "🎒 @Imgbb_com_bot pls unblock this bot",
|
|
||||||
"not_an_image": "🚫 <b>This platform only supports images </b>",
|
|
||||||
"uploading": "📤 <b>Uploading...</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_media(self, message: Message):
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
m = None
|
|
||||||
if reply and reply.media:
|
|
||||||
m = reply
|
|
||||||
elif message.media:
|
|
||||||
m = message
|
|
||||||
elif not reply:
|
|
||||||
await utils.answer(message, self.strings("noargs"))
|
|
||||||
return False
|
|
||||||
|
|
||||||
if not m:
|
|
||||||
file = io.BytesIO(bytes(reply.raw_text, "utf-8"))
|
|
||||||
file.name = "file.txt"
|
|
||||||
else:
|
|
||||||
file = io.BytesIO(await self._client.download_media(m, bytes))
|
|
||||||
file.name = (
|
|
||||||
m.file.name
|
|
||||||
or (
|
|
||||||
"".join(
|
|
||||||
[
|
|
||||||
random.choice("abcdefghijklmnopqrstuvwxyz1234567890")
|
|
||||||
for _ in range(16)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
+ m.file.ext
|
|
||||||
)
|
|
||||||
|
|
||||||
return file
|
|
||||||
|
|
||||||
async def get_image(self, message: Message):
|
|
||||||
file = await self.get_media(message)
|
|
||||||
if not file:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if imghdr.what(file) not in ["gif", "png", "jpg", "jpeg", "tiff", "bmp"]:
|
|
||||||
await utils.answer(message, self.strings("not_an_image"))
|
|
||||||
return False
|
|
||||||
|
|
||||||
return file
|
|
||||||
|
|
||||||
async def imgbbcmd(self, message: Message):
|
|
||||||
"""imgbb uploader"""
|
|
||||||
message = await utils.answer(message, self.strings("uploading"))
|
|
||||||
file = await self.get_image(message)
|
|
||||||
if not file:
|
|
||||||
return
|
|
||||||
|
|
||||||
chat = "@Imgbb_com_bot"
|
|
||||||
|
|
||||||
async with self._client.conversation(chat) as conv:
|
|
||||||
try:
|
|
||||||
m = await conv.send_message(file=file)
|
|
||||||
response = await conv.get_response()
|
|
||||||
except YouBlockedUserError:
|
|
||||||
await utils.answer(message, self.strings("ban"))
|
|
||||||
return
|
|
||||||
|
|
||||||
await m.delete()
|
|
||||||
await response.delete()
|
|
||||||
|
|
||||||
try:
|
|
||||||
url = (
|
|
||||||
re.search(
|
|
||||||
r'<meta property="og:image" data-react-helmet="true"'
|
|
||||||
r' content="(.*?)"',
|
|
||||||
(await utils.run_sync(requests.get, response.raw_text)).text,
|
|
||||||
)
|
|
||||||
.group(1)
|
|
||||||
.split("?")[0]
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
url = response.raw_text
|
|
||||||
await utils.answer(message, f"😸 Your file uploaded: <code>{url}</code>")
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Inlineping.jpg
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import time
|
|
||||||
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
from ..inline.types import InlineCall, InlineQuery
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class PingerMod(loader.Module):
|
|
||||||
"""Inline Pinger For Test"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "InlinePing",
|
|
||||||
"results_ping": "✨ <b>Telegram ping:</b> <code>{}</code> <b>ms</b>"
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {"results_ping": "✨ <b>Телеграм пинг:</b> <code>{}</code> <b>ms</b>"}
|
|
||||||
|
|
||||||
strings_uz = {"results_ping": "✨ <b>Telegram ping:</b> <code>{}</code> <b>ms</b>"}
|
|
||||||
|
|
||||||
strings_de = {"results_ping": "✨ <b>Telegramm Ping:</b> <code>{}</code> <b>ms</b>"}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
strings_ru = {"results_ping": "✨ <b>Скорость отклика Telegram:</b> <code>{}</code> <b>ms</b>"}
|
|
||||||
|
|
||||||
@loader.command(ru_doc="Проверить скорость отклика юзербота")
|
|
||||||
async def iping(self, message: Message):
|
|
||||||
"""Test your userbot ping"""
|
|
||||||
start = time.perf_counter_ns()
|
|
||||||
ping = self.strings("results_ping").format(
|
|
||||||
round((time.perf_counter_ns() - start) / 10**3, 3),
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.inline.form(
|
|
||||||
ping,
|
|
||||||
reply_markup=[[{"text": "⏱️ PePing", "callback": self.ladno}]],
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def ladno(self, call: InlineCall):
|
|
||||||
start = time.perf_counter_ns()
|
|
||||||
ping = self.strings("results_ping").format(
|
|
||||||
round((time.perf_counter_ns() - start) / 10**3, 3),
|
|
||||||
)
|
|
||||||
await call.edit(
|
|
||||||
ping,
|
|
||||||
reply_markup=[[{"text": "⏱️ PePing", "callback": self.ladno,}],]
|
|
||||||
)
|
|
||||||
|
|
||||||
async def ping_inline_handler(self, query: InlineQuery):
|
|
||||||
"""Test your userbot ping"""
|
|
||||||
start = time.perf_counter_ns()
|
|
||||||
ping = self.strings("results_ping").format(
|
|
||||||
round((time.perf_counter_ns() - start) / 10**3, 3),
|
|
||||||
)
|
|
||||||
button = [{
|
|
||||||
"text": "⏱️ PePing",
|
|
||||||
"callback": self.ladno
|
|
||||||
}]
|
|
||||||
return {
|
|
||||||
"title": "Ping",
|
|
||||||
"description": "Tap here",
|
|
||||||
"thumb": "https://te.legra.ph/file/5d8c7f1960a3e126d916a.jpg",
|
|
||||||
"message": ping,
|
|
||||||
"reply_markup": button,
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta pic: https://te.legra.ph/file/0251f5d602a8f32cd7368.png
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Instsave.jpg
|
|
||||||
__version__ = (1, 0, 0)
|
|
||||||
|
|
||||||
from .. import utils, loader
|
|
||||||
|
|
||||||
chat = "@SaveAsBot"
|
|
||||||
|
|
||||||
|
|
||||||
class InstagramMod(loader.Module):
|
|
||||||
"""Download video from instagram without watermark"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "InstSave",
|
|
||||||
"processing": (
|
|
||||||
"<emoji document_id='6318766236746384900'>🕔</emoji> <b>Processing...</b>"
|
|
||||||
),
|
|
||||||
"mods": (
|
|
||||||
"<b>Successfuly downloaded</b> <emoji document_id='6320882302708614449'>🚀</emoji></b>"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.group_member
|
|
||||||
@loader.command(ru_doc="<линк> - Скачать видео из инстаграм")
|
|
||||||
async def instascmd(self, message):
|
|
||||||
"""instagram video/reels/photo url"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
message = await utils.answer(message, self.strings("processing"))
|
|
||||||
async with self._client.conversation(chat) as conv:
|
|
||||||
msgs = []
|
|
||||||
msgs += [await conv.send_message("/start")]
|
|
||||||
msgs += [await conv.get_response()]
|
|
||||||
msgs += [await conv.send_message(text)]
|
|
||||||
m = await conv.get_response()
|
|
||||||
|
|
||||||
await self._client.send_file(
|
|
||||||
message.peer_id,
|
|
||||||
m.media,
|
|
||||||
caption=self.strings("mods"),
|
|
||||||
reply_to=message.reply_to_msg_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
for msg in msgs + [m]:
|
|
||||||
await msg.delete()
|
|
||||||
|
|
||||||
if message.out:
|
|
||||||
await message.delete()
|
|
||||||
|
|
||||||
await self.client.delete_dialog(chat)
|
|
||||||
@@ -1,355 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# requires: bs4 cloudscraper loguru tqdm lxml
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
import pathlib
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
import string
|
|
||||||
import random
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from tqdm import tqdm
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from cloudscraper import create_scraper, CloudScraper
|
|
||||||
from telethon.tl.types import DocumentAttributeVideo
|
|
||||||
|
|
||||||
from aiogram.types import CallbackQuery
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
HEADERS = {
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Season:
|
|
||||||
title: str
|
|
||||||
episodes_urls: list[str]
|
|
||||||
|
|
||||||
|
|
||||||
def download_video(url: str, path, scraper: CloudScraper):
|
|
||||||
with scraper.get(url, stream=True) as r:
|
|
||||||
total_length = int(r.headers.get("Content-Length"))
|
|
||||||
with tqdm.wrapattr(r.raw, "read", total=total_length, desc="") as raw:
|
|
||||||
with open(path, "wb") as file:
|
|
||||||
shutil.copyfileobj(raw, file)
|
|
||||||
|
|
||||||
|
|
||||||
def remove_symbols(filename: str) -> str:
|
|
||||||
if not filename:
|
|
||||||
return filename
|
|
||||||
|
|
||||||
forbidden = '\\/*:?|"<>'
|
|
||||||
for symbol in forbidden:
|
|
||||||
filename.replace(symbol, "")
|
|
||||||
return filename
|
|
||||||
|
|
||||||
|
|
||||||
class JutSuD:
|
|
||||||
def loader(self, anime_url, season_from, episode_from, season_to, episode_to):
|
|
||||||
scraper = create_scraper(
|
|
||||||
delay=1,
|
|
||||||
browser={
|
|
||||||
"custom": "ScraperBot/1.0",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
response = scraper.get(anime_url)
|
|
||||||
soup = BeautifulSoup(response.text, "lxml")
|
|
||||||
|
|
||||||
anime_title = soup.find("h1", {"class": "anime_padding_for_title"}).text
|
|
||||||
anime_title = (
|
|
||||||
anime_title.replace("Смотреть", "")
|
|
||||||
.replace("все серии", "")
|
|
||||||
.replace("и сезоны", "")
|
|
||||||
.strip()
|
|
||||||
)
|
|
||||||
|
|
||||||
seasons = [
|
|
||||||
Season(
|
|
||||||
title=season_title.text,
|
|
||||||
episodes_urls=[],
|
|
||||||
)
|
|
||||||
for season_title in soup.find_all("h2", class_=["the-anime-season"])
|
|
||||||
]
|
|
||||||
|
|
||||||
if not seasons:
|
|
||||||
seasons.append(
|
|
||||||
Season(
|
|
||||||
title=anime_title,
|
|
||||||
episodes_urls=[],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
episodes_soup = soup.find_all(
|
|
||||||
"a",
|
|
||||||
class_=[
|
|
||||||
"short-btn black video the_hildi",
|
|
||||||
"short-btn green video the_hildi",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
current_season_index = -1
|
|
||||||
current_episode_class = None
|
|
||||||
|
|
||||||
for ep in episodes_soup:
|
|
||||||
if ep["class"] != current_episode_class:
|
|
||||||
current_episode_class = ep["class"]
|
|
||||||
|
|
||||||
current_season_index += 1
|
|
||||||
|
|
||||||
url = "https://jut.su" + ep["href"]
|
|
||||||
seasons[current_season_index].episodes_urls.append(url)
|
|
||||||
|
|
||||||
for i, season in enumerate(seasons):
|
|
||||||
season_number = i + 1
|
|
||||||
|
|
||||||
if season_number < season_from or season_number > season_to:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for j, episode_url in enumerate(season.episodes_urls):
|
|
||||||
episode_number = j + 1
|
|
||||||
|
|
||||||
if (season_number == season_from and episode_number < episode_from) or (
|
|
||||||
(season_number == season_to or season_number == len(seasons))
|
|
||||||
and episode_number > episode_to
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
response = scraper.get(episode_url)
|
|
||||||
soup = BeautifulSoup(response.content, "lxml")
|
|
||||||
|
|
||||||
try:
|
|
||||||
episode_title = (
|
|
||||||
soup.find("div", {"class": "video_plate_title"}).find("h2").text
|
|
||||||
)
|
|
||||||
|
|
||||||
except AttributeError:
|
|
||||||
episode_title = soup.find("span", {"itemprop": "name"}).text
|
|
||||||
episode_title = (
|
|
||||||
episode_title.replace("Смотреть", "")
|
|
||||||
.replace(anime_title, "")
|
|
||||||
.strip()
|
|
||||||
)
|
|
||||||
|
|
||||||
video_url = soup.find("source")["src"]
|
|
||||||
|
|
||||||
name_video = random.choices("".join(string.ascii_letters), k=10)
|
|
||||||
video_path = pathlib.Path(f"{''.join(name_video)}.mp4")
|
|
||||||
episode_slug = f"{season.title} - {episode_title} [#{episode_number}]"
|
|
||||||
try:
|
|
||||||
download_video(url=video_url, path=video_path, scraper=scraper)
|
|
||||||
return video_path, episode_slug
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception(e)
|
|
||||||
return False, False
|
|
||||||
|
|
||||||
def get_info(self, url):
|
|
||||||
scraper = create_scraper()
|
|
||||||
response = scraper.get(url, headers=HEADERS)
|
|
||||||
soup = BeautifulSoup(response.text, "lxml")
|
|
||||||
|
|
||||||
anime_title = soup.find("h1", {"class": "anime_padding_for_title"}).text
|
|
||||||
|
|
||||||
anime_title = (
|
|
||||||
anime_title.replace("Смотреть", "")
|
|
||||||
.replace("все серии", "")
|
|
||||||
.replace("и сезоны", "")
|
|
||||||
.strip()
|
|
||||||
)
|
|
||||||
|
|
||||||
seasons = [
|
|
||||||
Season(
|
|
||||||
title=season_title,
|
|
||||||
episodes_urls=[],
|
|
||||||
)
|
|
||||||
for season_title in soup.find_all("h2", class_=["the-anime-season"])
|
|
||||||
]
|
|
||||||
|
|
||||||
if not seasons:
|
|
||||||
seasons.append(
|
|
||||||
Season(
|
|
||||||
title=anime_title,
|
|
||||||
episodes_urls=[],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
episodes_soup = soup.find_all(
|
|
||||||
"a",
|
|
||||||
class_=[
|
|
||||||
"short-btn black video the_hildi",
|
|
||||||
"short-btn green video the_hildi",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
return anime_title, seasons, episodes_soup
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class Jutsu(loader.Module):
|
|
||||||
"""Download and get info about anime from jut.su"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Jutsu",
|
|
||||||
"info": (
|
|
||||||
"📺 <b>Anime info</b>\n\n"
|
|
||||||
"<b>Title:</b> {}\n"
|
|
||||||
"<b>Seasons:</b> {}\n"
|
|
||||||
"<b>Total episodes:</b> {}\n"
|
|
||||||
"<b>Link:</b> {}"
|
|
||||||
),
|
|
||||||
"download_button": "📥 Download",
|
|
||||||
"done": "✅ Download completed!",
|
|
||||||
"choose_season": "📺 <b>Choose season</b>",
|
|
||||||
"choose_episode": "🪶 <b>Choose episode</b>",
|
|
||||||
"wrong_url": "❌ Wrong url!",
|
|
||||||
"no_args": "❌ No args!",
|
|
||||||
"download": "📥 Downloading episode {}... (speed depends on your internet connection)",
|
|
||||||
"close": "❌ Close",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"info": (
|
|
||||||
"📺 <b>Информация о аниме</b>\n\n"
|
|
||||||
"<b>Название:</b> {}\n"
|
|
||||||
"<b>Сезонов:</b> {}\n"
|
|
||||||
"<b>Всего серий:</b> {}\n"
|
|
||||||
"<b>Ссылка:</b> {}"
|
|
||||||
),
|
|
||||||
"download_button": "📥 Скачать",
|
|
||||||
"done": "✅ Скачивание завершено!",
|
|
||||||
"choose_season": "📺 <b>Выберите сезон</b>",
|
|
||||||
"choose_episode": "🪶 <b>Выберите серию</b>",
|
|
||||||
"wrong_url": "❌ Неверная ссылка!",
|
|
||||||
"no_args": "❌ Нет аргументов!",
|
|
||||||
"download": "📥 Скачиваем серию {}... (скорость скачивание зависит от вашего интернета)",
|
|
||||||
"close": "❌ Закрыть",
|
|
||||||
}
|
|
||||||
|
|
||||||
async def client_ready(self, client, db):
|
|
||||||
asset_ch, _ = await utils.asset_channel(
|
|
||||||
self._client,
|
|
||||||
"JutSu downloads",
|
|
||||||
"Downloaded anime from JutSu will be sent here. (Hikamoru back?)",
|
|
||||||
avatar="https://i.pinimg.com/564x/0a/da/0b/0ada0bb575146736679f5ea7a78971b8.jpg",
|
|
||||||
)
|
|
||||||
self.chid = int(f"-100{asset_ch.id}")
|
|
||||||
|
|
||||||
|
|
||||||
async def download_(self, call, url, seasons, episodes_soup):
|
|
||||||
seasons = [season for season in range(1, len(seasons) + 1)]
|
|
||||||
|
|
||||||
kb = []
|
|
||||||
|
|
||||||
for mod_row in utils.chunks(seasons, 3):
|
|
||||||
row = [
|
|
||||||
{
|
|
||||||
"text": f"• {season} •",
|
|
||||||
"callback": self.season_,
|
|
||||||
"args": (season, episodes_soup, url),
|
|
||||||
}
|
|
||||||
for season in mod_row
|
|
||||||
]
|
|
||||||
|
|
||||||
kb += [row]
|
|
||||||
|
|
||||||
await call.edit(self.strings["choose_season"], reply_markup=kb)
|
|
||||||
|
|
||||||
async def season_(self, call, season, eps, url):
|
|
||||||
episodes = [episode for episode in range(1, len(eps) + 1)]
|
|
||||||
|
|
||||||
kb = []
|
|
||||||
|
|
||||||
for mod_row in utils.chunks(episodes, 3):
|
|
||||||
row = [
|
|
||||||
{
|
|
||||||
"text": f"• {episode} •",
|
|
||||||
"callback": self.episod_,
|
|
||||||
"args": (episode, season, url),
|
|
||||||
}
|
|
||||||
for episode in mod_row
|
|
||||||
]
|
|
||||||
|
|
||||||
kb += [row]
|
|
||||||
|
|
||||||
await call.edit(self.strings["choose_episode"], reply_markup=kb)
|
|
||||||
|
|
||||||
async def episod_(self, call: CallbackQuery, episode, episode_number, url):
|
|
||||||
await call.edit(self.strings["download"].format(episode_number))
|
|
||||||
|
|
||||||
try:
|
|
||||||
name, title = JutSuD().loader(
|
|
||||||
url, episode_number, episode, episode_number, episode
|
|
||||||
)
|
|
||||||
except TypeError:
|
|
||||||
await call.edit("There is not such a episode (This bug with button will be fixed soon)")
|
|
||||||
|
|
||||||
await self.client.send_file(
|
|
||||||
self.chid,
|
|
||||||
open(name, "rb"),
|
|
||||||
caption=self.strings["done"] + f"\n\n{title}",
|
|
||||||
filetype="video",
|
|
||||||
attributes=(DocumentAttributeVideo(0, 0, 0),),
|
|
||||||
)
|
|
||||||
|
|
||||||
await call.edit(self.strings["done"])
|
|
||||||
|
|
||||||
os.remove(name)
|
|
||||||
|
|
||||||
async def close_(self, call):
|
|
||||||
await call.delete()
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def jutsud(self, message):
|
|
||||||
"""Download anime from jutsu - [url]"""
|
|
||||||
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
|
|
||||||
if not args:
|
|
||||||
await utils.answer(message, self.strings["no_args"])
|
|
||||||
return
|
|
||||||
|
|
||||||
if not args.startswith("https://jut.su"):
|
|
||||||
await utils.answer(message, self.strings["wrong_url"])
|
|
||||||
return
|
|
||||||
|
|
||||||
anime_title, seasons, episodes_soup = JutSuD().get_info(args)
|
|
||||||
|
|
||||||
await utils.answer(
|
|
||||||
message,
|
|
||||||
self.strings["info"].format(
|
|
||||||
anime_title, len(seasons), len(episodes_soup), args
|
|
||||||
),
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": self.strings["download_button"],
|
|
||||||
"callback": self.download_,
|
|
||||||
"kwargs": {
|
|
||||||
"url": args,
|
|
||||||
"seasons": seasons,
|
|
||||||
"episodes_soup": episodes_soup,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": self.strings["close"],
|
|
||||||
"callback": self.close_,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/leta.jpg
|
|
||||||
|
|
||||||
# I don't care about other people's opinions, if you don't like it, don't use it. i will update this module in the future, if i have time.
|
|
||||||
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
from .. import loader, utils
|
|
||||||
from telethon.errors import ChatAdminRequiredError
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class Leta(loader.Module):
|
|
||||||
"""Customizable nightmode [Leta] for your group"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Leta",
|
|
||||||
"info": (
|
|
||||||
"🐈⬛ Heeey! I'm <b>Leta</b>! I'm a module for nightmode in your group.\n"
|
|
||||||
"📫 You can get acquainted with my settings using the command <code>.help Leta</code>."
|
|
||||||
),
|
|
||||||
"wrong_format": "<emoji document_id=5258419835922030550>🕔</emoji> <b>Enter the time in the format HH:MM</b>",
|
|
||||||
"day": "<emoji document_id=6332496306593859160>🌅</emoji> <b>Good morning!</b>\n<b>Night mode is disabled.</b>",
|
|
||||||
"night": "<emoji document_id=6334806423473489632>🌚</emoji> <b>Good night!</b>\n<b>Night mode is enabled.</b>",
|
|
||||||
"rm": "<emoji document_id=5021905410089550576>✅</emoji> <b>Removed nightmode.</b>",
|
|
||||||
"rm_notfound": "<emoji document_id=5456652110143693064>🤷♂️</emoji> <b>Nightmode is not set.</b>",
|
|
||||||
"set": "<emoji document_id=5980930633298350051>✅</emoji> Time set to\n<emoji document_id=6334361735444563461>🌃</emoji>🌙</emoji> Night: <code>{}</code>\n<emoji document_id=6332496306593859160>🌅</emoji> Day: <code>{}</code>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"info": (
|
|
||||||
"🐈⬛ Привет! Я <b>Leta</b>! Я модуль для ночного режима в вашей группе.\n"
|
|
||||||
"📫 Ознакомиться с моими настройками можно с помощью команды <code>.help Leta</code>."
|
|
||||||
),
|
|
||||||
"wrong_format": "<emoji document_id=5258419835922030550>🕔</emoji> <b>Введите время в формате HH:MM</b>",
|
|
||||||
"day": "<emoji document_id=6332496306593859160>🌅</emoji> <b>Доброе утро!</b>\n<b>Ночной режим отключен.</b>",
|
|
||||||
"night": "<emoji document_id=6334806423473489632>🌚</emoji> <b>Доброй ночи!</b>\n<b>Ночной режим включен.</b>",
|
|
||||||
"rm": "<emoji document_id=5021905410089550576>✅</emoji> <b>Удален ночной режим.</b>",
|
|
||||||
"rm_notfound": "<emoji document_id=5456652110143693064>🤷♂️</emoji> <b>Ночной режим не установлен.</b>",
|
|
||||||
"set": "<emoji document_id=5980930633298350051>✅</emoji> Время установлено на\n<emoji document_id=6334361735444563461>🌃</emoji>🌙</emoji> Ночь: <code>{}</code>\n<emoji document_id=6332496306593859160>🌅</emoji> День: <code>{}</code>",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def resolve_id(self, marked_id):
|
|
||||||
if marked_id >= 0:
|
|
||||||
return "user"
|
|
||||||
marked_id = -marked_id
|
|
||||||
marked_id -= 1000000000000
|
|
||||||
return "chat"
|
|
||||||
|
|
||||||
async def client_ready(self, client, db):
|
|
||||||
if not self.get("info", False):
|
|
||||||
await self.inline.bot.send_animation(
|
|
||||||
self._tg_id,
|
|
||||||
"https://0x0.st/Hpqm.mp4",
|
|
||||||
caption=self.strings("info"),
|
|
||||||
parse_mode="HTML",
|
|
||||||
)
|
|
||||||
self.set("info", True)
|
|
||||||
|
|
||||||
|
|
||||||
async def lettimecmd(self, message):
|
|
||||||
"""Set time - morning [HH:MM] evening [HH:MM]"""
|
|
||||||
args = utils.get_args_raw(message).split(" ")
|
|
||||||
resolving = self.resolve_id(message.chat_id)
|
|
||||||
if resolving != "chat":
|
|
||||||
return await utils.answer(message, "<b>Use this command in group</b>")
|
|
||||||
if not args:
|
|
||||||
return await utils.answer(message, self.strings("wrong_format"))
|
|
||||||
try:
|
|
||||||
dh, dm = args[0].split(":")
|
|
||||||
eh, em = args[1].split(":")
|
|
||||||
if int(dh) > 23 or int(dh) < 0 or int(dm) > 59 or int(dm) < 0 or int(eh) > 23 or int(eh) < 0 or int(em) > 59 or int(em) < 0:
|
|
||||||
return await utils.answer(message, self.strings("wrong_format"))
|
|
||||||
except Exception:
|
|
||||||
return await utils.answer(message, self.strings('wrong_format'))
|
|
||||||
day = args[0]
|
|
||||||
night = args[1]
|
|
||||||
self.set(
|
|
||||||
"ngs",
|
|
||||||
{
|
|
||||||
message.chat_id: {
|
|
||||||
"time": night,
|
|
||||||
"day": day,
|
|
||||||
"chat": message.chat_id
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await utils.answer(message, self.strings("set").format(night, day))
|
|
||||||
|
|
||||||
async def letrmchatcmd(self, message):
|
|
||||||
"""Remove nightmode - chat-id"""
|
|
||||||
try:
|
|
||||||
args = int(utils.get_args_raw(message))
|
|
||||||
d = self.get("ngs", {})
|
|
||||||
logging.info(d)
|
|
||||||
if not args:
|
|
||||||
return await utils.answer(message, self.strings("rm_notfound"))
|
|
||||||
if args not in d:
|
|
||||||
return await utils.answer(message, self.strings("rm_notfound"))
|
|
||||||
del d[args]
|
|
||||||
self.set("ngs", d)
|
|
||||||
await utils.answer(message, self.strings("rm"))
|
|
||||||
except ValueError:
|
|
||||||
await utils.answer(message, self.strings("rm_notfound"))
|
|
||||||
|
|
||||||
@loader.loop(interval=60, autostart=True)
|
|
||||||
async def checker_loop_night(self):
|
|
||||||
"""Check time"""
|
|
||||||
ngs = self.get("ngs", {})
|
|
||||||
for i in ngs:
|
|
||||||
if ngs[i]["time"] == time.strftime("%H:%M"):
|
|
||||||
try:
|
|
||||||
await self.client.send_message(ngs[i]["chat"], self.strings("night"))
|
|
||||||
await self.client.edit_permissions(ngs[i]['chat'], send_messages=False)
|
|
||||||
except ChatAdminRequiredError:
|
|
||||||
await self.inline.bot.send_message(
|
|
||||||
self._tg_id,
|
|
||||||
f"👎 You don't have enough rights to change permissions in <code>{i['chat']}</code>",
|
|
||||||
parse_mode="HTML",
|
|
||||||
)
|
|
||||||
|
|
||||||
async def letchatscmd(self, message):
|
|
||||||
"""Get all chats with nightmode"""
|
|
||||||
ngs = self.get("ngs", {})
|
|
||||||
if not ngs:
|
|
||||||
return await utils.answer(message, "<b>There are no chats with nightmode</b>")
|
|
||||||
msg = "<b>Chats with nightmode:</b>\n"
|
|
||||||
for i in ngs:
|
|
||||||
msg += f"\n<code>{i}</code>"
|
|
||||||
await utils.answer(message, msg + "\n")
|
|
||||||
|
|
||||||
@loader.loop(interval=60, autostart=True)
|
|
||||||
async def checker_loop_day(self):
|
|
||||||
"""Check time"""
|
|
||||||
ngs = self.get("ngs", {})
|
|
||||||
for i in ngs:
|
|
||||||
if ngs[i]["day"] == time.strftime("%H:%M"):
|
|
||||||
try:
|
|
||||||
await self.client.edit_permissions(ngs[i]['chat'], send_messages=True)
|
|
||||||
await self.client.send_message(ngs[i]["chat"], self.strings("day"))
|
|
||||||
except ChatAdminRequiredError:
|
|
||||||
await self.inline.bot.send_message(
|
|
||||||
self._tg_id,
|
|
||||||
f"👎 You don't have enough rights to change permissions in <code>{i['chat']}</code>",
|
|
||||||
parse_mode="HTML",
|
|
||||||
)
|
|
||||||
@@ -1,249 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# requires: bs4 aiohttp
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
|
|
||||||
import aiohttp
|
|
||||||
from bs4 import BeautifulSoup as bs
|
|
||||||
|
|
||||||
from .. import utils, loader
|
|
||||||
|
|
||||||
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
||||||
|
|
||||||
|
|
||||||
class English:
|
|
||||||
|
|
||||||
async def definition_get(self, word: str):
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
headers = {"User-Agent": user_agent}
|
|
||||||
async with session.get(
|
|
||||||
f"https://dictionary.cambridge.org/us/dictionary/english/{word}/",
|
|
||||||
headers=headers,
|
|
||||||
) as resp:
|
|
||||||
if resp.status != 200:
|
|
||||||
return f"Failed to retrieve data. Status code: {resp.status}"
|
|
||||||
|
|
||||||
soup = bs(await resp.text(), "html.parser")
|
|
||||||
if not (div_element := soup.find("div", class_="def ddef_d db")):
|
|
||||||
return "Definition not found"
|
|
||||||
text = div_element.get_text()
|
|
||||||
example_spans = soup.find_all("span", class_="eg deg")
|
|
||||||
examples = []
|
|
||||||
for ex in example_spans:
|
|
||||||
example_text = ex.get_text()
|
|
||||||
examples.append(example_text)
|
|
||||||
|
|
||||||
return {"definition": text.replace(":", ""), "examples": examples}
|
|
||||||
|
|
||||||
async def get_word_pronunciation_uk(self, word: str):
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.get(
|
|
||||||
f"https://dictionary.cambridge.org/dictionary/english/{word}",
|
|
||||||
headers={"User-Agent": user_agent},
|
|
||||||
) as resp:
|
|
||||||
if resp.status == 200:
|
|
||||||
soup = bs(await resp.text(), "html.parser")
|
|
||||||
try:
|
|
||||||
audio_tag = soup.find_all("audio", class_="hdn")[0]
|
|
||||||
pron_tag = soup.find_all("span", class_="ipa dipa lpr-2 lpl-1")[
|
|
||||||
0
|
|
||||||
]
|
|
||||||
audio_src = audio_tag.find("source", type="audio/mpeg")["src"]
|
|
||||||
|
|
||||||
return {
|
|
||||||
"audio": f"https://dictionary.cambridge.org/us{audio_src}",
|
|
||||||
"pron": pron_tag.get_text(),
|
|
||||||
}
|
|
||||||
except IndexError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_word_pronunciation_us(self, word: str):
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.get(
|
|
||||||
f"https://dictionary.cambridge.org/dictionary/english/{word}",
|
|
||||||
headers={"User-Agent": user_agent},
|
|
||||||
) as resp:
|
|
||||||
if resp.status == 200:
|
|
||||||
soup = bs(await resp.text(), "html.parser")
|
|
||||||
try:
|
|
||||||
audio_tag = soup.find_all("audio", class_="hdn")[1]
|
|
||||||
audio_src = audio_tag.find("source")["src"]
|
|
||||||
pron_tag = soup.find_all("span", class_="ipa dipa lpr-2 lpl-1")[
|
|
||||||
1
|
|
||||||
]
|
|
||||||
|
|
||||||
return {
|
|
||||||
"audio": f"https://dictionary.cambridge.org{audio_src}",
|
|
||||||
"pron": pron_tag.get_text(),
|
|
||||||
}
|
|
||||||
|
|
||||||
except IndexError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def thesaurus_synonyms(self, word: str):
|
|
||||||
url = f"https://thesaurus.plus/thesaurus/{word}"
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.get(url, headers={"User-Agent": user_agent}) as resp:
|
|
||||||
if resp.status == 200:
|
|
||||||
soup = bs(await resp.text(), "html.parser")
|
|
||||||
synonyms_list = []
|
|
||||||
synonyms_ul = soup.find_all("ul", class_="list")[1]
|
|
||||||
list_terms = synonyms_ul.find_all("li", class_="list_term")
|
|
||||||
for term in list_terms:
|
|
||||||
synonym = term.find("div", class_="p-2").get_text(strip=True)
|
|
||||||
synonyms_list.append(synonym)
|
|
||||||
return synonyms_list
|
|
||||||
|
|
||||||
async def thesaurus_antonyms(self, word: str):
|
|
||||||
url = f"https://thesaurus.plus/thesaurus/{word}"
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.get(url, headers={"User-Agent": user_agent}) as resp:
|
|
||||||
if resp.status == 200:
|
|
||||||
soup = bs(await resp.text(), "html.parser")
|
|
||||||
antonyms_list = []
|
|
||||||
antonyms_ul = soup.find_all("ul", class_="list")[0]
|
|
||||||
list_terms = antonyms_ul.find_all("li", class_="list_term")
|
|
||||||
for term in list_terms:
|
|
||||||
antonym = term.find("div", class_="p-2").get_text(strip=True)
|
|
||||||
antonyms_list.append(antonym)
|
|
||||||
return antonyms_list
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class LexiwizMod(loader.Module, English):
|
|
||||||
"""Lexical wizard - your english companion"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Lexiwiz",
|
|
||||||
"no_word": "🤷♂️ <b>No word provided</b>",
|
|
||||||
"no_definition": "😖 <b>Unfortunately, I couldn't find the definition of this word.</b>",
|
|
||||||
"definition": "📝 <b>Word:</b> <code>{}</code>\n\n🔆 <b>Definition:</b> <code>{}</code>\n\n📦 <b>Examples:</b>\n{}",
|
|
||||||
"Pronunciation": "{} <b>{} Pronunciation:</b> <code>{}</code>\n🔊 <a href='{}'>Listen</a>",
|
|
||||||
"no_synonyms": "😓 <b>Sorry, I couldn't find synonyms for this word.</b>",
|
|
||||||
"synonyms": "📝 <b>Synonyms for the word:</b> <code>{}</code>\n\n🔆 <b>Synonyms:</b> <code>{}</code>",
|
|
||||||
"no_antonyms": "😓 <b>Sorry, I couldn't find antonyms for this word.</b>",
|
|
||||||
"antonyms": "📝 <b>Antonyms for the word:</b> <code>{}</code>\n\n🔆 <b>Antonyms:</b> <code>{}</code>",
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def getdef(self, message):
|
|
||||||
"""Get definition of a word"""
|
|
||||||
|
|
||||||
word = utils.get_args_raw(message)
|
|
||||||
|
|
||||||
if not word:
|
|
||||||
await utils.answer(message, self.strings("no_word"))
|
|
||||||
return
|
|
||||||
|
|
||||||
definition = await self.definition_get(word)
|
|
||||||
|
|
||||||
if definition == "Definition not found":
|
|
||||||
await utils.answer(message, self.strings("no_definition"))
|
|
||||||
|
|
||||||
if isinstance(definition, dict):
|
|
||||||
text = ""
|
|
||||||
|
|
||||||
_definition = definition["definition"]
|
|
||||||
_examples = definition["examples"]
|
|
||||||
|
|
||||||
for index, example in enumerate(_examples):
|
|
||||||
text += f"<b>{index}</b>. <i>{example}</i>\n"
|
|
||||||
|
|
||||||
await utils.answer(
|
|
||||||
message, self.strings("definition").format(word, _definition, text)
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await utils.answer(
|
|
||||||
message, self.strings("definiotion").format(word, definition, " ")
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def getpron(self, message):
|
|
||||||
"""Get pronunciation of a word"""
|
|
||||||
word = utils.get_args_raw(message)
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
|
|
||||||
if not word:
|
|
||||||
await utils.answer(message, self.strings("no_word"))
|
|
||||||
return
|
|
||||||
|
|
||||||
uk = await self.get_word_pronunciation_uk(word)
|
|
||||||
us = await self.get_word_pronunciation_us(word)
|
|
||||||
|
|
||||||
if uk:
|
|
||||||
await message.delete()
|
|
||||||
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
uk["audio"],
|
|
||||||
caption=self.strings("Pronunciation").format(
|
|
||||||
"🇬🇧",
|
|
||||||
"UK",
|
|
||||||
uk["pron"],
|
|
||||||
uk["audio"],
|
|
||||||
),
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
|
|
||||||
if us:
|
|
||||||
await message.delete()
|
|
||||||
|
|
||||||
await message.client.send_file(
|
|
||||||
message.to_id,
|
|
||||||
us["audio"],
|
|
||||||
caption=self.strings("Pronunciation").format(
|
|
||||||
"🇺🇸",
|
|
||||||
"US",
|
|
||||||
us["pron"],
|
|
||||||
us["audio"],
|
|
||||||
),
|
|
||||||
voice_note=True,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def getsyn(self, message):
|
|
||||||
"""Get synonyms of a word"""
|
|
||||||
word = utils.get_args_raw(message)
|
|
||||||
|
|
||||||
if not word:
|
|
||||||
await utils.answer(message, self.strings("no_word"))
|
|
||||||
return
|
|
||||||
|
|
||||||
synonyms = await self.thesaurus_synonyms(word)
|
|
||||||
|
|
||||||
if not synonyms:
|
|
||||||
await utils.answer(message, self.strings("no_synonyms"))
|
|
||||||
return
|
|
||||||
|
|
||||||
await utils.answer(
|
|
||||||
message, self.strings("synonyms").format(word, ", ".join(synonyms))
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def getant(self, message):
|
|
||||||
"""Get antonyms of a word"""
|
|
||||||
word = utils.get_args_raw(message)
|
|
||||||
|
|
||||||
if not word:
|
|
||||||
await utils.answer(message, self.strings("no_word"))
|
|
||||||
return
|
|
||||||
|
|
||||||
antonyms = await self.thesaurus_antonyms(word)
|
|
||||||
|
|
||||||
if not antonyms:
|
|
||||||
await utils.answer(message, self.strings("no_antonyms"))
|
|
||||||
return
|
|
||||||
|
|
||||||
await utils.answer(
|
|
||||||
message, self.strings("antonyms").format(word, ", ".join(antonyms))
|
|
||||||
)
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://github.com/AmoreForever/assets/blob/master/my_usernames.jpg?raw=true
|
|
||||||
from telethon import functions
|
|
||||||
from telethon.tl.types import Channel
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class MyUsernames(loader.Module):
|
|
||||||
"""The usernames I own"""
|
|
||||||
|
|
||||||
strings = {"name": "My Usernames"}
|
|
||||||
@loader.command()
|
|
||||||
async def myusern(self, message):
|
|
||||||
"""A list of usernames that were created by me"""
|
|
||||||
result = await self.client(functions.channels.GetAdminedPublicChannelsRequest())
|
|
||||||
output_str = "• "
|
|
||||||
for channel_obj in result.chats:
|
|
||||||
if isinstance(channel_obj, Channel) and channel_obj.username is not None:
|
|
||||||
output_str += f"<code>{channel_obj.title}</code> | <b>@{channel_obj.username}</b>\n• "
|
|
||||||
await utils.answer(message, f"<b>💼 List usernames reserved by me</b>\n\n{output_str[:-3]}")
|
|
||||||
@@ -1,296 +0,0 @@
|
|||||||
__version__ = (1, 0, 0)
|
|
||||||
# ▀█▀ █ █ █▀█ █▀▄▀█ ▄▀█ █▀
|
|
||||||
# █ █▀█ █▄█ █ ▀ █ █▀█ ▄█
|
|
||||||
# https://t.me/netuzb
|
|
||||||
#
|
|
||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# meta pic: https://te.legra.ph/file/4c1b4581de961df145a70.png
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Mydiary.jpg
|
|
||||||
|
|
||||||
# meta developer: @hikamoru & @wilsonmods
|
|
||||||
# scope: hikka_min 1.4.0
|
|
||||||
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
|
|
||||||
from ..inline.types import InlineQuery
|
|
||||||
from ..inline.types import InlineCall
|
|
||||||
|
|
||||||
emoji_close = "🔻 "
|
|
||||||
emoji_back = "↙️ "
|
|
||||||
emoji_open = "💌 "
|
|
||||||
emoji_about = "🚨 "
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class PagesMod(loader.Module):
|
|
||||||
"""Diary page"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Diary",
|
|
||||||
"_about_module": "What does this module do? - here you can write about your day and write notes",
|
|
||||||
"_cfg_inline_banner": "Set `True` in order to disable an inline media banner.",
|
|
||||||
"_cfdiary_open_text": "enter a diary name or information about it",
|
|
||||||
"_cfdiary_second_text": "here you can write on dairy «text2»",
|
|
||||||
"_cfdiary_three_text": "here you can write on dairy «text3»",
|
|
||||||
"_cfdiary_four_text": "here you can write on dairy «text4»",
|
|
||||||
"_cfdiary_first_text": "here you can write on dairy «text1»",
|
|
||||||
"_cfdiary_second_text": "here you can write on dairy «text2»",
|
|
||||||
"_cfdiary_three_text": "here you can write on dairy «text3»",
|
|
||||||
"_cfdiary_four_text": "here you can write on dairy «text4»",
|
|
||||||
"_cfg_button_1_": "here you can change button name «day1»",
|
|
||||||
"_cfg_button_2_": "here you can change button name «day2»",
|
|
||||||
"_cfg_button_3_": "here you can change button name «day3»",
|
|
||||||
"_cfg_button_4_": "here you can change button name «day4»",
|
|
||||||
"x": emoji_close + "Close",
|
|
||||||
"back": emoji_back + "Back",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"_about_module": "Что делает этот модуль? - Ты ты можешь писать свои заметки или что делал сегодня",
|
|
||||||
"_cfg_inline_banner": "Установите `True`, чтобы отключить встроенный медиа-баннер",
|
|
||||||
"_cfdiary_open_text": "Введите название дневника или информацию о нем",
|
|
||||||
"_cfdiary_first_text": "здесь ты можешь написать написать дневник на «text1»",
|
|
||||||
"_cfdiary_second_text": "здесь ты можешь написать написать дневник на «text2»",
|
|
||||||
"_cfdiary_three_text": "здесь ты можешь написать написать дневник на «text3»",
|
|
||||||
"_cfdiary_four_text": "здесь ты можешь написать написать дневник на «text4»",
|
|
||||||
"_cfg_button_1_": "здесь ты можешь поменять название кнопки «day1»",
|
|
||||||
"_cfg_button_2_": "здесь ты можешь поменять название кнопки «day2»",
|
|
||||||
"_cfg_button_3_": "здесь ты можешь поменять название кнопки «day3»",
|
|
||||||
"_cfg_button_4_": "здесь ты можешь поменять название кнопки «day4»",
|
|
||||||
"x": emoji_close + "Закрыть",
|
|
||||||
"back": emoji_back + "Назад",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_uz = {
|
|
||||||
"_about_module": "Modul vazifasi nima?\n- Siz modul orqali bugungi kun rejangiz yoki eslatmani saqlab qoʻyishingiz mumkin.",
|
|
||||||
"_cfg_inline_banner": "Media-bannerni yopish uchun `True` rejimini yoqing",
|
|
||||||
"_cfdiary_open_text": "Kundalik nomini yoki unga bogʻliq maʼlumotni yozing",
|
|
||||||
"_cfdiary_first_text": "Bu yerda siz «text_numb_1» sozlashingiz mumkin",
|
|
||||||
"_cfdiary_second_text": "Bu yerda siz «text_numb_2» sozlashingiz mumkin",
|
|
||||||
"_cfdiary_three_text": "Bu yerda siz «text_numb_3» sozlashingiz mumkin",
|
|
||||||
"_cfdiary_four_text": "Bu yerda siz «text_numb_4» sozlashingiz mumkin",
|
|
||||||
"_cfg_button_1_": "Bu yerda siz «button_numb_1» tugmasini sozlashingiz mumkin",
|
|
||||||
"_cfg_button_2_": "Bu yerda siz «button_numb_2» tugmasini sozlashingiz mumkin",
|
|
||||||
"_cfg_button_3_": "Bu yerda siz «button_numb_3» tugmasini sozlashingiz mumkin",
|
|
||||||
"_cfg_button_4_": "Bu yerda siz «button_numb_4» tugmasini sozlashingiz mumkin",
|
|
||||||
"x": emoji_close + "Yopish",
|
|
||||||
"back": emoji_back + "Orqaga",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"open_text",
|
|
||||||
"Here is a caption for my diary",
|
|
||||||
doc=lambda: self.strings('_cfdiary_open_text'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"off_inline_banner",
|
|
||||||
False,
|
|
||||||
lambda: self.strings("_cfg_inline_banner"),
|
|
||||||
validator=loader.validators.Boolean(),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"button_numb_1",
|
|
||||||
"Day 1",
|
|
||||||
doc=lambda: self.strings('_cfg_button_1_'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"button_numb_2",
|
|
||||||
"Day 2",
|
|
||||||
doc=lambda: self.strings('_cfg_button_2_'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"button_numb_3",
|
|
||||||
"Day 3",
|
|
||||||
doc=lambda: self.strings('_cfg_button_3_'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"button_numb_4",
|
|
||||||
"Day 4",
|
|
||||||
doc=lambda: self.strings('_cfg_button_4_'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"text_numb_1",
|
|
||||||
"Today i played football with my friends then i fall,",
|
|
||||||
doc=lambda: self.strings('_cfdiary_first_text'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"text_numb_2",
|
|
||||||
"Today i walked with my friends and i saw my best friend who was drawer",
|
|
||||||
doc=lambda: self.strings('_cfdiary_second_text'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"text_numb_3",
|
|
||||||
"What are you did today?",
|
|
||||||
doc=lambda: self.strings('_cfdiary_three_text'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"text_numb_4",
|
|
||||||
"What are you did today?",
|
|
||||||
doc=lambda: self.strings('_cfdiary_four_text'),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"banner_numb_1",
|
|
||||||
"https://imgur.com/NqNGNOb",
|
|
||||||
lambda: f"here you can write on dairy photo1",
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"banner_numb_2",
|
|
||||||
"https://ibb.co/ZJ9hnfL",
|
|
||||||
lambda: f"here you can write on dairy photo2",
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"banner_numb_3",
|
|
||||||
"https://imgur.com/kITkUry",
|
|
||||||
lambda: f"here you can write on dairy photo3",
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"banner_numb_4",
|
|
||||||
"https://imgur.com/TOzh9u1",
|
|
||||||
lambda: f"here you can write on dairy photo3",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
async def cfdiarycmd(self, message):
|
|
||||||
"""> Set up buttons for the module"""
|
|
||||||
name = self.strings("name")
|
|
||||||
await self.allmodules.commands["config"](
|
|
||||||
await utils.answer(message,
|
|
||||||
f"{self.get_prefix()}config {name}")
|
|
||||||
)
|
|
||||||
|
|
||||||
async def mydiarycmd(self, message: Message):
|
|
||||||
"""> Main the diary section"""
|
|
||||||
await self.inline.form(
|
|
||||||
text = self.config["open_text"],
|
|
||||||
message=message,
|
|
||||||
reply_markup=[
|
|
||||||
[{
|
|
||||||
"text": f"{emoji_open}Open diary",
|
|
||||||
"callback": self.page_one
|
|
||||||
}],
|
|
||||||
[{
|
|
||||||
"text": f"{emoji_about}About modules",
|
|
||||||
"callback": self._about_us
|
|
||||||
}]],
|
|
||||||
**{"photo": "https://te.legra.ph/file/64bb29a68030e118dfa21.jpg"},
|
|
||||||
)
|
|
||||||
|
|
||||||
async def mydiary_inline_handler(self, query: InlineQuery):
|
|
||||||
"""> Main the diary section"""
|
|
||||||
btn_a = [{
|
|
||||||
"text": f"{emoji_open}Open diary",
|
|
||||||
"callback": self.page_one
|
|
||||||
}],
|
|
||||||
btn_b = [{
|
|
||||||
"text": f"{emoji_about}About modules",
|
|
||||||
"callback": self._about_us
|
|
||||||
}],
|
|
||||||
msg_type = "message" if self.config["off_inline_banner"] else "caption"
|
|
||||||
return {
|
|
||||||
"title": "open diary",
|
|
||||||
"description": "open my own diary page",
|
|
||||||
msg_type: self.config['open_text'],
|
|
||||||
"photo": "https://te.legra.ph/file/64bb29a68030e118dfa21.jpg",
|
|
||||||
"thumb": (
|
|
||||||
"https://te.legra.ph/file/4c1b4581de961df145a70.png"
|
|
||||||
),
|
|
||||||
"reply_markup": btn_a + btn_b,
|
|
||||||
}
|
|
||||||
|
|
||||||
async def _back(self, call: InlineCall):
|
|
||||||
await call.edit(
|
|
||||||
text = self.config["open_text"],
|
|
||||||
reply_markup=[
|
|
||||||
[{
|
|
||||||
"text": f"{emoji_open}Open diary",
|
|
||||||
"callback": self.page_one
|
|
||||||
}],
|
|
||||||
[{
|
|
||||||
"text": f"{emoji_about}About modules",
|
|
||||||
"callback": self._about_us
|
|
||||||
}]
|
|
||||||
],
|
|
||||||
**{"photo": "https://te.legra.ph/file/64bb29a68030e118dfa21.jpg"},
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _about_us(self, call: InlineCall):
|
|
||||||
await call.edit(
|
|
||||||
text = self.strings('_about_module'),
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": self.strings("back"),
|
|
||||||
"callback": self._back
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": self.strings("x"),
|
|
||||||
"action": "close"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
async def page_one(self, call: InlineCall):
|
|
||||||
await call.edit(
|
|
||||||
text = self.config["text_numb_1"],
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": self.config["button_numb_1"], "callback": self.page_one}, {"text": self.config["button_numb_2"], "callback": self.page_two}],
|
|
||||||
[{"text": self.config["button_numb_3"], "callback": self.page_three}, {"text": self.config["button_numb_4"], "callback": self.page_four}],
|
|
||||||
[{
|
|
||||||
"text": self.strings("x"),
|
|
||||||
"action": "close"
|
|
||||||
}]],
|
|
||||||
**{"photo": self.config["banner_numb_1"]},
|
|
||||||
)
|
|
||||||
|
|
||||||
async def page_two(self, call: InlineCall):
|
|
||||||
await call.edit(
|
|
||||||
text = self.config["text_numb_2"],
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": self.config["button_numb_1"], "callback": self.page_one}, {"text": self.config["button_numb_2"], "callback": self.page_two}],
|
|
||||||
[{"text": self.config["button_numb_3"], "callback": self.page_three}, {"text": self.config["button_numb_4"], "callback": self.page_four}],
|
|
||||||
[{
|
|
||||||
"text": self.strings("x"),
|
|
||||||
"action": "close"
|
|
||||||
}]],
|
|
||||||
**{"photo": self.config["banner_numb_2"]},
|
|
||||||
)
|
|
||||||
|
|
||||||
async def page_three(self, call: InlineCall):
|
|
||||||
await call.edit(
|
|
||||||
text = self.config["text_numb_3"],
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": self.config["button_numb_1"], "callback": self.page_one}, {"text": self.config["button_numb_2"], "callback": self.page_two}],
|
|
||||||
[{"text": self.config["button_numb_3"], "callback": self.page_three}, {"text": self.config["button_numb_4"], "callback": self.page_four}],
|
|
||||||
[{
|
|
||||||
"text": self.strings("x"),
|
|
||||||
"action": "close"
|
|
||||||
}]],
|
|
||||||
**{"photo": self.config["banner_numb_3"]},
|
|
||||||
)
|
|
||||||
|
|
||||||
async def page_four(self, call: InlineCall):
|
|
||||||
await call.edit(
|
|
||||||
text = self.config["text_numb_4"],
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": self.config["button_numb_1"], "callback": self.page_one}, {"text": self.config["button_numb_2"], "callback": self.page_two}],
|
|
||||||
[{"text": self.config["button_numb_3"], "callback": self.page_three}, {"text": self.config["button_numb_4"], "callback": self.page_four}],
|
|
||||||
[{
|
|
||||||
"text": self.strings("x"),
|
|
||||||
"action": "close"
|
|
||||||
}]],
|
|
||||||
**{"photo": self.config["banner_numb_4"]},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Nytimer.jpg
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
import datetime
|
|
||||||
from time import strftime
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class NYMod(loader.Module):
|
|
||||||
"""Check how much is left until the new year"""
|
|
||||||
|
|
||||||
strings = {'name': 'NewYearTimer'}
|
|
||||||
|
|
||||||
async def nycmd(self, message):
|
|
||||||
"""Check date"""
|
|
||||||
now = datetime.datetime.today()
|
|
||||||
ng = datetime.datetime(int(strftime('%Y')) + 1, 1, 1)
|
|
||||||
d = ng - now
|
|
||||||
mm, ss = divmod(d.seconds, 60)
|
|
||||||
hh, mm = divmod(mm, 60)
|
|
||||||
soon = '<b><emoji document_id=6334530007968253960>☃️</emoji> Until the <u>New Year</u>: {} d. {} h. {} m. {} s.</b>\n<b><emoji document_id=5393226077520798225>🥰</emoji> Wait for the new year together <u>Family</u></b>'.format(
|
|
||||||
d.days, hh, mm, ss)
|
|
||||||
await utils.answer(message, soon)
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/phstiker.jpg
|
|
||||||
# requires: phlogo
|
|
||||||
|
|
||||||
import os
|
|
||||||
from .. import loader, utils
|
|
||||||
from phlogo import generate
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class PhLogo(loader.Module):
|
|
||||||
"""Make Pornhub logo sticker"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Phlogo",
|
|
||||||
"only_two": "Something's wrong. Try giving two words only like `Hello world`",
|
|
||||||
"none_args": "Give some text bruh, e.g.: `Hello world`"
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"only_two": "Что-то не так. Попробуйте указать только два аргумента, например «Hello world».",
|
|
||||||
"none_args": "Дай какой-нибудь текст, например: `Hello world`."
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_uz = {
|
|
||||||
"only_two": "Xatolik bor. `Hello world` kabi faqat ikkita matn keltirishga harakat qiling.",
|
|
||||||
"none_args": "Bir oz matn bering, masalan: `Salom dunyo`."
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def phl(self, message):
|
|
||||||
"Makes PHub style logo sticker."
|
|
||||||
args = utils.get_args_raw(message).split(' ')
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
if args == " ":
|
|
||||||
await utils.answer(message, self.strings('none_args'))
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
p = args[0]
|
|
||||||
h = args[1]
|
|
||||||
except:
|
|
||||||
await utils.answer(message, self.strings('only_two'))
|
|
||||||
return
|
|
||||||
result = generate(f"{p}",f"{h}")
|
|
||||||
result.save("ph.webp")
|
|
||||||
path = os.getcwd()
|
|
||||||
stc = f"{path}/ph.webp"
|
|
||||||
await message.delete()
|
|
||||||
await self._client.send_file(
|
|
||||||
message.peer_id,
|
|
||||||
stc,
|
|
||||||
caption=f"{p} {h}",
|
|
||||||
link_preview=False,
|
|
||||||
reply_to=reply.id if reply else None,
|
|
||||||
)
|
|
||||||
os.remove(stc)
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/poststeal.jpg
|
|
||||||
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class PostStealer(loader.Module):
|
|
||||||
"Steal post from another channel to your channel"
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
'name': 'PostStealler',
|
|
||||||
'enable': '<b>Steal mode enabled.</b>',
|
|
||||||
'disable': '<b>Steal mode disabled.</b>',
|
|
||||||
'channel': 'channel id where ub will steal messages',
|
|
||||||
'my_channel': 'channel id where ub will send messages'
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
'enable': '<b>StealMod включен.</b>',
|
|
||||||
'disable': '<b>StealMod отключен.</b>',
|
|
||||||
'channel': 'айди канала откуда юб будет пересылать сообщения',
|
|
||||||
'my_channel': 'айди канала куда юб будет пересылать сообщения'
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"my_channel",
|
|
||||||
None,
|
|
||||||
lambda: self.strings("my_channel"),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"channel",
|
|
||||||
None,
|
|
||||||
lambda: self.strings("channel"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
async def client_ready(self, client, db):
|
|
||||||
self.client = client
|
|
||||||
self.db = db
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def smode(self, message):
|
|
||||||
"""- off/on steal mode"""
|
|
||||||
|
|
||||||
status = self.db.get(
|
|
||||||
"steal_status",
|
|
||||||
"status",
|
|
||||||
)
|
|
||||||
if status == "":
|
|
||||||
self.db.set("steal_status", "status", True)
|
|
||||||
if status == False:
|
|
||||||
self.db.set("steal_status", "status", True)
|
|
||||||
await utils.answer(message, self.strings("enable"))
|
|
||||||
else:
|
|
||||||
self.db.set("steal_status", "status", False)
|
|
||||||
await utils.answer(message, self.strings("disable"))
|
|
||||||
|
|
||||||
async def watcher(self, message):
|
|
||||||
"""Лень писать описание"""
|
|
||||||
status = self.db.get("steal_status", "status")
|
|
||||||
if status == False:
|
|
||||||
return False
|
|
||||||
if status == True:
|
|
||||||
steal = self.config['channel']
|
|
||||||
chatid = int(message.chat_id)
|
|
||||||
text = message.text
|
|
||||||
if chatid == steal:
|
|
||||||
if message.photo:
|
|
||||||
await self._client.send_file(int(self.config['my_channel']), message.photo, caption=message.text if text else None, link_preview=False)
|
|
||||||
elif message.video:
|
|
||||||
await self._client.send_file(int(self.config['my_channel']), message.video, caption=message.text if text else None, link_preview=False)
|
|
||||||
elif message.document:
|
|
||||||
await self._client.send_file(int(self.config['my_channel']), message.document, caption=message.text if text else None, link_preview=False)
|
|
||||||
elif message.text:
|
|
||||||
await message.client.send_message(int(self.config['my_channel']), message.text)
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/recognition.jpg
|
|
||||||
|
|
||||||
from .. import utils, loader
|
|
||||||
import imghdr
|
|
||||||
import io
|
|
||||||
import random
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class RecognitionMod(loader.Module):
|
|
||||||
"""Recognition from photo"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
'name': 'Recognition',
|
|
||||||
'args': "No args!"
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_media(self, message: Message):
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
m = None
|
|
||||||
if reply and reply.media:
|
|
||||||
m = reply
|
|
||||||
elif message.media:
|
|
||||||
m = message
|
|
||||||
elif not reply:
|
|
||||||
await utils.answer(message, self.strings('args'))
|
|
||||||
return False
|
|
||||||
|
|
||||||
if not m:
|
|
||||||
file = io.BytesIO(bytes(reply.raw_text, "utf-8"))
|
|
||||||
file.name = "file.txt"
|
|
||||||
else:
|
|
||||||
file = io.BytesIO(await self._client.download_media(m, bytes))
|
|
||||||
file.name = (
|
|
||||||
m.file.name
|
|
||||||
or (
|
|
||||||
"".join(
|
|
||||||
[
|
|
||||||
random.choice(
|
|
||||||
"abcdefghijklmnopqrstuvwxyz1234567890")
|
|
||||||
for _ in range(16)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
+ m.file.ext
|
|
||||||
)
|
|
||||||
|
|
||||||
return file
|
|
||||||
|
|
||||||
async def get_image(self, message: Message):
|
|
||||||
file = await self.get_media(message)
|
|
||||||
if not file:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if imghdr.what(file) not in ["gif", "png", "jpg", "jpeg", "tiff", "bmp"]:
|
|
||||||
return False
|
|
||||||
return file
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def reco(self, message: Message):
|
|
||||||
"""recognize from photo <reply to photo>"""
|
|
||||||
file = await self.get_image(message)
|
|
||||||
if not file:
|
|
||||||
return False
|
|
||||||
async with self._client.conversation("@Rekognition_Bot") as conv:
|
|
||||||
await conv.send_message(file=file) # upload step
|
|
||||||
await conv.get_response() # ignore message
|
|
||||||
cp = await conv.get_response() # get message
|
|
||||||
|
|
||||||
await utils.answer(message, cp)
|
|
||||||
await self.client.delete_dialog("@Rekognition_Bot")
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Searchpic.jpg
|
|
||||||
# meta developer: @amoremods
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class SearchPic(loader.Module):
|
|
||||||
|
|
||||||
strings = {"name": "SearchPic"}
|
|
||||||
|
|
||||||
@loader.unrestricted
|
|
||||||
async def spiccmd(self, message: Message):
|
|
||||||
"""Search picture"""
|
|
||||||
text = utils.get_args_raw(message)
|
|
||||||
await self.inline.form(
|
|
||||||
message=message,
|
|
||||||
text = f"🎑 Your pic found\n✍ Input argument: {text}",
|
|
||||||
reply_markup=[
|
|
||||||
[{"text": "Pic here", "url": f"https://yandex.uz/images/touch/search/?text={text}",}],
|
|
||||||
[{"text": "Close", "action": "close"}],
|
|
||||||
],
|
|
||||||
**(
|
|
||||||
{"photo": f"https://yandex.uz/images/touch/search/?text={text}"}
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# scope: ffmpeg
|
|
||||||
# requires: pydub speechrecognition python-ffmpeg
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta banner: https://github.com/AmoreForever/assets/blob/master/Speech.jpg?raw=true
|
|
||||||
|
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
import speech_recognition as sr
|
|
||||||
from pydub import AudioSegment
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
recognizer = sr.Recognizer()
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class SpeechMod(loader.Module):
|
|
||||||
"""Simple speech recognition module."""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Speech",
|
|
||||||
"only_voice": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Reply to a voice message!</b>",
|
|
||||||
"downloading": "<emoji document_id=5213251580425414358>🔽</emoji> <b>Downloading...</b>",
|
|
||||||
"recognizing": "<emoji document_id=5472199711366584503>👂</emoji> <b>Recognizing...</b>",
|
|
||||||
"not_recognized": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Not recognized</b>",
|
|
||||||
"request_error": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Request error occured.\n{}</b>",
|
|
||||||
"recognized": "<emoji document_id=5267468588985363056>🚛</emoji> <b>Recognized:</b> <code>{}</code>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"only_voice": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Ответь на голосовое сообщение!</b>",
|
|
||||||
"downloading": "<emoji document_id=5213251580425414358>🔽</emoji> <b>Загрузка...</b>",
|
|
||||||
"recognizing": "<emoji document_id=5472199711366584503>👂</emoji> <b>Распознавание...</b>",
|
|
||||||
"not_recognized": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Не распознано</b>",
|
|
||||||
"request_error": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Произошла ошибка запроса.\n{}</b>",
|
|
||||||
"recognized": "<emoji document_id=5267468588985363056>🚛</emoji> <b>Распознано:</b> <code>{}</code>",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_uz = {
|
|
||||||
"only_voice": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Ovozli xabarga javob bering!</b>",
|
|
||||||
"downloading": "<emoji document_id=5213251580425414358>🔽</emoji> <b>Yuklanmoqda...</b>",
|
|
||||||
"recognizing": "<emoji document_id=5472199711366584503>👂</emoji> <b>Eshitilmoqda...</b>",
|
|
||||||
"not_recognized": "<emoji document_id=5877477244938489129>🚫</emoji> <b>Tanilmadi</b>",
|
|
||||||
"request_error": "<emoji document_id=5877477244938489129>🚫</emoji> <b>So'rovda xatolik yuz berdi.\n{}</b>",
|
|
||||||
"recognized": "<emoji document_id=5267468588985363056>🚛</emoji> <b>Text:</b> <code>{}</code>",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"language",
|
|
||||||
"ru-RU",
|
|
||||||
lambda: "Language for recognition.",
|
|
||||||
validator=loader.validators.RegExp(r"^[a-z]{2}-[A-Z]{2}$"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def spech(self, message):
|
|
||||||
"""Recognize voice message. Usage: .spech <reply to voice message>"""
|
|
||||||
reply = await message.get_reply_message()
|
|
||||||
if not reply or not reply.voice:
|
|
||||||
await utils.answer(message, self.strings("only_voice"))
|
|
||||||
return
|
|
||||||
await utils.answer(message, self.strings("downloading"))
|
|
||||||
voice = await message.client.download_media(reply.voice)
|
|
||||||
wav_voice = voice.replace(voice.split(".")[-1], "wav")
|
|
||||||
ogg_audio = AudioSegment.from_ogg(voice)
|
|
||||||
ogg_audio.export(wav_voice, format="wav")
|
|
||||||
audio = sr.AudioFile(wav_voice)
|
|
||||||
with audio as source:
|
|
||||||
try:
|
|
||||||
audio = recognizer.record(source)
|
|
||||||
await utils.answer(message, self.strings("recognizing"))
|
|
||||||
recognized = recognizer.recognize_google(audio, language=self.config["language"])
|
|
||||||
except sr.UnknownValueError:
|
|
||||||
await utils.answer(message, self.strings("not_recognized"))
|
|
||||||
return
|
|
||||||
except sr.RequestError as e:
|
|
||||||
await utils.answer(message, self.strings("request_error").format(e))
|
|
||||||
return
|
|
||||||
await utils.answer(message, self.strings("recognized").format(recognized))
|
|
||||||
os.remove(voice)
|
|
||||||
os.remove(wav_voice)
|
|
||||||
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
# meta pic: https://te.legra.ph/file/5ef64ee0466032d8a4687.png
|
|
||||||
# meta banner: hhttps://raw.githubusercontent.com/AmoreForever/assets/master/Telegraphup.jpg
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
import requests
|
|
||||||
from telethon.tl.types import DocumentAttributeFilename
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class Telegraphup(loader.Module):
|
|
||||||
"""Upload video and photo to telegraph"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Telegraph",
|
|
||||||
"pls_reply": "⚠️ Reply to photo or video/gif",
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.sudo
|
|
||||||
async def thupcmd(self, message):
|
|
||||||
"""<reply photo or video>"""
|
|
||||||
if message.is_reply:
|
|
||||||
reply_message = await message.get_reply_message()
|
|
||||||
data = await check_media(reply_message)
|
|
||||||
if isinstance(data, bool):
|
|
||||||
await message.edit(self.strings("pls_reply"))
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
await message.edit(self.strings("pls_reply"))
|
|
||||||
return
|
|
||||||
|
|
||||||
file = await message.client.download_media(data, bytes)
|
|
||||||
path = requests.post(
|
|
||||||
"https://te.legra.ph/upload", files={"file": ("file", file, None)}
|
|
||||||
).json()
|
|
||||||
try:
|
|
||||||
amore = "https://te.legra.ph" + path[0]["src"]
|
|
||||||
except KeyError:
|
|
||||||
amore = path["error"]
|
|
||||||
await utils.answer(message, f"😸 Your file uploaded: <code>{amore}</code>")
|
|
||||||
|
|
||||||
|
|
||||||
async def check_media(reply_message):
|
|
||||||
if reply_message and reply_message.media:
|
|
||||||
if reply_message.photo:
|
|
||||||
data = reply_message.photo
|
|
||||||
elif reply_message.document:
|
|
||||||
if (
|
|
||||||
DocumentAttributeFilename(file_name="AnimatedSticker.tgs")
|
|
||||||
in reply_message.media.document.attributes
|
|
||||||
):
|
|
||||||
return False
|
|
||||||
if reply_message.audio or reply_message.voice:
|
|
||||||
return False
|
|
||||||
data = reply_message.media.document
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
if not data or data is None:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return data
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
# ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
||||||
# ⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠟⠛⠛⠛⠛⠛
|
|
||||||
# ⣶⣦⣤⣤⣤⣤⣤⣤⣬⣭⣭⣍⣉⡙⠛⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⣋⣩⣭⣥⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣶
|
|
||||||
# ⣆⠀⠀⠀⢡⠁⠀⡀⠀⢸⠟⠻⣯⠙⠛⠷⣶⣬⡙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢉⣥⣶⡟⠻⣙⡉⠀⢰⡆⠀⠀⣡⠀⣧⠀⠀⠀⢨
|
|
||||||
# ⠻⣦⠀⠀⠈⣇⣀⣧⣴⣿⣶⣶⣿⣷⠀⢀⡇⠉⠻⢶⣌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣡⡶⠟⠉⠀⢣⠀⣿⠷⠀⠀⠀⠀⣿⡷⢀⠇⠀⠀⢠⣿
|
|
||||||
# ⣦⡈⢧⡀⠀⠘⢮⡙⠛⠉⠀⠄⠙⢿⣀⠞⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠈⠳⣄⠉⠓⠒⠚⠋⢀⡠⠋⠀⢀⣴⣏⣿
|
|
||||||
# ⣿⣿⣿⣛⣦⣀⠀⠙⠓⠦⠤⣤⠔⠛⠁⠀⠀⠀⠀⠀⢀⣀⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣤⣤⣤⣤⣤⣀⣀⣀⣀⢙⢓⣒⡒⠚⠋⢠⣤⢶⣟⣽⣿⣿
|
|
||||||
# ⣿⣿⣿⣿⣿⣿⣷⣦⠀⠀⣴⣿⣷⣶⣶⣶⣾⡖⢰⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣾⣿⣿⣶⣾⣿⣿⣿⣿⣿⣿
|
|
||||||
# ⣿⣿⣿⣿⣿⣿⣿⣿⠀⢀⣿⣿⣿⣿⣿⣿⣿⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
||||||
# ⣿⣿⣿⣿⣿⣿⣿⡏⠀⢸⣿⣿⣿⣿⣿⣿⣿⠁⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
||||||
# ⣿⣿⣿⣿⣿⣿⣿⣷⠀⢸⣿⣿⣿⣿⣿⣿⣿⠀⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# https://t.me/amorescam
|
|
||||||
|
|
||||||
# meta developer: @amoremods
|
|
||||||
# meta banner: https://raw.githubusercontent.com/AmoreForever/assets/master/Universaltime.jpg
|
|
||||||
# @Den4ikSuperOstryyPer4ik: I Love AmoreMods :)
|
|
||||||
|
|
||||||
|
|
||||||
from .. import loader, utils
|
|
||||||
import datetime
|
|
||||||
from ..inline.types import InlineCall
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def check_time():
|
|
||||||
offsets = [3, 5, 4, 2, 1, -7, 6, 9, 5.30, 9, 8, -8, -4]
|
|
||||||
hrs = []
|
|
||||||
for x in offsets:
|
|
||||||
offset = datetime.timedelta(hours=x)
|
|
||||||
not_tz = datetime.timezone(offset)
|
|
||||||
time = datetime.datetime.now(not_tz)
|
|
||||||
format_ = time.strftime("%d.%m.%y | %H:%M")
|
|
||||||
hrs.append(format_)
|
|
||||||
return f"<emoji document_id=4920662486778119009>🌐</emoji> <b>Universal time</b>\n\n<emoji document_id=6323139226418284334>🇷🇺</emoji> Russia ➪ {hrs[0]}\n<emoji document_id=6323430017179059570>🇺🇿</emoji> Uzbekistan ➪ {hrs[1]}\n<emoji document_id=6323289850921354919>🇺🇦</emoji> Ukraine ➪ {hrs[3]}\n<emoji document_id=6323575251498174463>🇦🇿</emoji> Azerbaijan ➪ {hrs[2]}\n<emoji document_id=6320817337033295141>🇩🇪</emoji> German ➪ {hrs[3]}\n<emoji document_id=6323589145717376403>🇬🇧</emoji> UK ➪ {hrs[4]}\n<emoji document_id=6323602387101550101>🇵🇱</emoji> Poland ➪ {hrs[3]}\n<emoji document_id=6323374027985389586>🇺🇸</emoji> USA ➪ {hrs[5]}\n<emoji document_id=6323615997852910673>🇰🇬</emoji> Kyrgyzstan ➪ {hrs[6]}\n<emoji document_id=6323135275048371614>🇰🇿</emoji> Kazakhstan ➪ {hrs[6]}\n<emoji document_id=6323555846835930376>🇮🇶</emoji> Iraq ➪ {hrs[0]}\n<emoji document_id=6323356796576597627>🇯🇵</emoji> Japan ➪ {hrs[7]}\n<emoji document_id=6323152716910561397>🇰🇷</emoji> South KR ➪ {hrs[7]}\n<emoji document_id=6323181871148566277>🇮🇳</emoji> India ➪ {hrs[8]}\n<emoji document_id=6323570711717742330>🇫🇷</emoji> France ➪ {hrs[3]}\n<emoji document_id=6323453751168337485>🇨🇳</emoji> China ➪ {hrs[9]}\n<emoji document_id=6321003171678259486>🇹🇷</emoji> Turkey ➪ {hrs[0]}\n<emoji document_id=6323602322677040561>🇨🇱</emoji> Mongolia ➪ {hrs[10]}\n<emoji document_id=6323325327351219831>🇨🇦</emoji> Canada ➪ {hrs[11]}\n<emoji document_id=6323471399188957082>🇮🇹</emoji> Italia ➪ {hrs[2]}\n<emoji document_id=6323516260122363644>🇪🇬</emoji> Egypt ➪ {hrs[3]}\n<emoji document_id=6323236391463421376>🇦🇲</emoji> Armenia ➪ {hrs[12]}\n\n<emoji document_id=5188216117272780281>🍙</emoji> #whyamore"
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class UniversalTimeMod(loader.Module):
|
|
||||||
"""See the time of other countries"""
|
|
||||||
|
|
||||||
strings = {"name": "UnivTime"}
|
|
||||||
|
|
||||||
@loader.command(ru_docs="Смотреть мировое время")
|
|
||||||
async def atimecmd(self, message):
|
|
||||||
"""See time"""
|
|
||||||
kk = check_time()
|
|
||||||
await utils.answer(message, kk)
|
|
||||||
|
|
||||||
@loader.command(ru_docs="Смотреть мировое время в инлайн режиме")
|
|
||||||
async def atimeicmd(self, message):
|
|
||||||
"""See time on inline mode"""
|
|
||||||
kk = check_time()
|
|
||||||
await self.inline.form(
|
|
||||||
text=kk,
|
|
||||||
message=message,
|
|
||||||
gif="https://te.legra.ph/file/2ab9b131ceceb9b020583.mp4",
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": "🍃 Refresh",
|
|
||||||
"callback": self.refresh,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": "🔻 Close",
|
|
||||||
"action": "close",
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
async def refresh(self, call: InlineCall): # thanks @Den4ikSuperOstryyPer4ik
|
|
||||||
kk = check_time()
|
|
||||||
await call.edit(
|
|
||||||
text=kk,
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": "🍃 Refresh",
|
|
||||||
"callback": self.refresh,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": "🔻 Close",
|
|
||||||
"action": "close",
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
await call.answer("Refreshed ✨")
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
|
|
||||||
# pusechka @saint_players thanks for the idea
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import requests
|
|
||||||
from telethon.tl.types import Message
|
|
||||||
from telethon.tl.functions.channels import CreateChannelRequest, UpdateUsernameRequest
|
|
||||||
from telethon.tl.types import InputPeerChannel
|
|
||||||
from .. import loader, utils
|
|
||||||
from ..inline.types import InlineCall
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class UserStealer(loader.Module):
|
|
||||||
"""
|
|
||||||
Username tracking module.
|
|
||||||
"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "UsernameChecker",
|
|
||||||
"create_channel": "📂 Create channel",
|
|
||||||
"user_free": "⚡️ Username @{} is free, quickly take it.",
|
|
||||||
"user_busy": "😥 Username @{} is busy. Do you want to enable tracking?",
|
|
||||||
"yes": "🛟 Yes",
|
|
||||||
"nope": "🧰 No",
|
|
||||||
"free_now": "🌟 Username {} is free, do you want to create a channel?",
|
|
||||||
"not_args": "🚫 Enter the user for check",
|
|
||||||
"status": "🆔 Username @{} is being tracked\n🟢 Status: free",
|
|
||||||
"status_busy": "🆔 Username @{} is being tracked\n🟡 Status: busy",
|
|
||||||
"none": "❌ No username is being tracked.",
|
|
||||||
"done": "🦉 Done, wait till username will be free",
|
|
||||||
"created": "🌟 Channel created, go to username @{}",
|
|
||||||
"tg_bug": "🐞 Telegram has bugs, if the channel is not created, try to create it manually",
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"create_channel": "📂 Создать канал",
|
|
||||||
"user_free": "⚡️ Юзернейм @{} свободен, быстро забирай его.",
|
|
||||||
"user_busy": "😥 Юзернейм @{} занят. Хотите включить отслеживание?",
|
|
||||||
"yes": "🛟 Да",
|
|
||||||
"nope": "🧰 Нет",
|
|
||||||
"free_now": "🌟 Юзернейм {} свободен, хотите создать канал?",
|
|
||||||
"not_args": "🚫 Укажи юзернейм для проверки",
|
|
||||||
"status": "🆔 Юзернейм @{} отслеживается\n🟢 Статус: свободен",
|
|
||||||
"status_busy": "🆔 Юзернейм @{} отслеживается\n🟡 Статус: занят",
|
|
||||||
"none": "❌ Ни один юзернейм не отслеживается.",
|
|
||||||
"done": "🦉 Готово, жди пока юзернейм освободится",
|
|
||||||
"created": "🌟 Канал создан, переходи по юзернейму @{}",
|
|
||||||
"tg_bug": "🐞 У телеграма баги, если канал не создан, попробуй создать его вручную",
|
|
||||||
}
|
|
||||||
|
|
||||||
@loader.loop(interval=30, autostart=True)
|
|
||||||
async def _steal(self):
|
|
||||||
user = self.db.get("usernames_to_check", "username")
|
|
||||||
if user == "none":
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
r = requests.get(url=f"https://t.me/{user}")
|
|
||||||
if (
|
|
||||||
r.text.find(
|
|
||||||
'If you have <strong>Telegram</strong>, you can contact <a class="tgme_username_link"'
|
|
||||||
)
|
|
||||||
>= 0
|
|
||||||
):
|
|
||||||
self._markup = lambda: self.inline.generate_markup(
|
|
||||||
[
|
|
||||||
{"text": self.strings("create_channel"), "callback": self.create_inline, "args": (user,),},
|
|
||||||
{"text": "Отмена", "callback": self.delete, },
|
|
||||||
]
|
|
||||||
)
|
|
||||||
await self.inline.bot.send_message(
|
|
||||||
self._client.tg_id,
|
|
||||||
self.strings("user_free").format(user),
|
|
||||||
disable_web_page_preview=True,
|
|
||||||
reply_markup=self._markup()
|
|
||||||
)
|
|
||||||
|
|
||||||
self.db.set("usernames_to_check", "username", "none")
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def ucheckcmd(self, message: Message):
|
|
||||||
"""> Enter the user for check (without @)"""
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
r = requests.get(url=f"https://t.me/{args}")
|
|
||||||
|
|
||||||
if args.startswith('@'):
|
|
||||||
args = args[1:]
|
|
||||||
|
|
||||||
if not args:
|
|
||||||
return await utils.answer(message, self.strings("not_args"))
|
|
||||||
|
|
||||||
if (
|
|
||||||
r.text.find(
|
|
||||||
'If you have <strong>Telegram</strong>, you can contact <a class="tgme_username_link"'
|
|
||||||
)
|
|
||||||
>= 0
|
|
||||||
):
|
|
||||||
await self.inline.form(
|
|
||||||
text=self.strings("free_now").format(args),
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": self.strings("yes"),
|
|
||||||
"callback": self.create,
|
|
||||||
"args": (args,),
|
|
||||||
},
|
|
||||||
{"text": self.strings("nope"), "action": "close"},
|
|
||||||
],
|
|
||||||
], **{'video': 'https://te.legra.ph/file/a14a9ff4071d079272171.mp4'},
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await self.inline.form(
|
|
||||||
text=self.strings("user_busy").format(args),
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": self.strings("yes"),
|
|
||||||
"callback": self.owo,
|
|
||||||
"args": (args,),
|
|
||||||
},
|
|
||||||
{"text": self.strings("nope"), "action": "close"},
|
|
||||||
],
|
|
||||||
], **{"video": "https://te.legra.ph/file/90fbbd0deabfc5e740eb3.mp4"},
|
|
||||||
message=message,
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def myus(self, message: Message):
|
|
||||||
"""> Check status of the user being tracked"""
|
|
||||||
proc = self.db.get("usernames_to_check", "username")
|
|
||||||
if proc == 'none':
|
|
||||||
await utils.answer(message, self.strings("none"))
|
|
||||||
else:
|
|
||||||
r = requests.get(url=f"https://t.me/{proc}")
|
|
||||||
if (
|
|
||||||
r.text.find(
|
|
||||||
'If you have <strong>Telegram</strong>, you can contact <a class="tgme_username_link"'
|
|
||||||
)
|
|
||||||
>= 0
|
|
||||||
):
|
|
||||||
await utils.answer(message, self.strings("status").format(proc))
|
|
||||||
|
|
||||||
else:
|
|
||||||
await utils.answer(message, self.strings("status_busy").format(proc))
|
|
||||||
|
|
||||||
async def owo(self, call: InlineCall, text: str):
|
|
||||||
self.db.set("usernames_to_check", "username", text)
|
|
||||||
await call.edit(self.strings("done"))
|
|
||||||
|
|
||||||
async def create(self, call: InlineCall, text: str):
|
|
||||||
channel = await self.client(
|
|
||||||
CreateChannelRequest(f"{text}", f"{text}", megagroup=False)
|
|
||||||
)
|
|
||||||
channel_id = channel.__dict__["chats"][0].__dict__["id"]
|
|
||||||
channel_hash = channel.__dict__["chats"][0].__dict__["access_hash"]
|
|
||||||
try:
|
|
||||||
await self.client(
|
|
||||||
UpdateUsernameRequest(
|
|
||||||
InputPeerChannel(channel_id=channel_id,
|
|
||||||
access_hash=channel_hash),
|
|
||||||
text,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
await call.edit(self.strings("created").format(text))
|
|
||||||
except:
|
|
||||||
await call.edit(
|
|
||||||
self.strings("tg_bug"),
|
|
||||||
)
|
|
||||||
await self.client.delete_dialog(channel_id)
|
|
||||||
|
|
||||||
async def create_inline(self, call: InlineCall, text: str):
|
|
||||||
channel = await self.client(
|
|
||||||
CreateChannelRequest(f"{text}", f"{text}", megagroup=False)
|
|
||||||
)
|
|
||||||
channel_id = channel.__dict__["chats"][0].__dict__["id"]
|
|
||||||
channel_hash = channel.__dict__["chats"][0].__dict__["access_hash"]
|
|
||||||
try:
|
|
||||||
await self.client(
|
|
||||||
UpdateUsernameRequest(
|
|
||||||
InputPeerChannel(channel_id=channel_id,
|
|
||||||
access_hash=channel_hash),
|
|
||||||
text,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
await call.answer(self.strings("created").format(text))
|
|
||||||
await call.delete()
|
|
||||||
except:
|
|
||||||
await call.answer(
|
|
||||||
self.strings("tg_bug"),
|
|
||||||
show_alert=True
|
|
||||||
)
|
|
||||||
await self.client.delete_dialog(channel_id)
|
|
||||||
await call.delete()
|
|
||||||
|
|
||||||
async def delete(self, call: InlineCall):
|
|
||||||
await call.delete()
|
|
||||||
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
|
||||||
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
|
||||||
|
|
||||||
# 🔒 Licensed under the GNU GPLv3
|
|
||||||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
|
||||||
# 👤 https://t.me/hikamoru
|
|
||||||
|
|
||||||
|
|
||||||
# required: aiohttp
|
|
||||||
# meta banner: https://github.com/AmoreForever/shizuassets/blob/master/wakatime.jpg?raw=true
|
|
||||||
|
|
||||||
# meta developer: @hikamorumods
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
|
||||||
|
|
||||||
from .. import utils, loader
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class Wakatime(loader.Module):
|
|
||||||
"""Show your Wakatime stats"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "Wakatime",
|
|
||||||
"set_waka": "Set your Wakatime token",
|
|
||||||
"no_token": "🚫 <b>You don't have a token</b>",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
"WAKATIME_TOKEN",
|
|
||||||
None,
|
|
||||||
lambda: self.strings["set_waka"],
|
|
||||||
)
|
|
||||||
|
|
||||||
@loader.command()
|
|
||||||
async def waka(self, message):
|
|
||||||
"""See your stat"""
|
|
||||||
token = self.config["WAKATIME_TOKEN"]
|
|
||||||
|
|
||||||
if token is None:
|
|
||||||
return await utils.answer(message, self.strings("no_token"))
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
endpoints = [
|
|
||||||
"status_bar/today",
|
|
||||||
"stats/all_time",
|
|
||||||
"stats/all_time",
|
|
||||||
"all_time_since_today",
|
|
||||||
]
|
|
||||||
tasks = [
|
|
||||||
session.get(
|
|
||||||
f"https://wakatime.com/api/v1/users/current/{endpoint}?api_key={token}"
|
|
||||||
)
|
|
||||||
for endpoint in endpoints
|
|
||||||
]
|
|
||||||
responses = await asyncio.gather(*tasks)
|
|
||||||
results = await asyncio.gather(*[response.json() for response in responses])
|
|
||||||
|
|
||||||
result_t, result, result_s, result_w = results
|
|
||||||
|
|
||||||
all_time = result_w["data"]["text"]
|
|
||||||
username = result["data"]["username"]
|
|
||||||
languages = result["data"]["languages"]
|
|
||||||
today = result_t["data"]["categories"]
|
|
||||||
os = result["data"]["operating_systems"]
|
|
||||||
editor = result["data"]["editors"]
|
|
||||||
|
|
||||||
OS = ", ".join(f"<code>{stat['name']}</code>" for stat in os if stat["text"] != "0 secs")
|
|
||||||
EDITOR = ", ".join(f"<code>{stat['name']}</code>" for stat in editor if stat["text"] != "0 secs")
|
|
||||||
LANG = "\n".join(f"▫️ <b>{stat['name']}</b>: <i>{stat['text']}</i>" for stat in languages if stat["text"] != "0 secs")
|
|
||||||
TODAY = "\n".join(stat["text"] for stat in today if stat["text"] != "0 secs")
|
|
||||||
|
|
||||||
await utils.answer(
|
|
||||||
message,
|
|
||||||
f"👤 <b>Username:</b> <code>{username}</code>\n🖥 <b>OS:</b> {OS}\n🌀 <b>Editor:</b> {EDITOR}\n⏳ <b>All time</b>: <code>{all_time}</code>\n💼 <b>Today</b>: <code>{TODAY}</code>\n\n🧬 LANGUAGES\n\n{LANG}\n",
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": "🔄 Update",
|
|
||||||
"callback": self.update_waka,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
async def update_waka(self, call):
|
|
||||||
await call.edit("🔄 <b>Updating...</b>")
|
|
||||||
token = self.config["WAKATIME_TOKEN"]
|
|
||||||
if token is None:
|
|
||||||
return await call.edit(self.strings("no_token"))
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
endpoints = [
|
|
||||||
"status_bar/today",
|
|
||||||
"stats/all_time",
|
|
||||||
"stats/all_time",
|
|
||||||
"all_time_since_today",
|
|
||||||
]
|
|
||||||
tasks = [
|
|
||||||
session.get(
|
|
||||||
f"https://wakatime.com/api/v1/users/current/{endpoint}?api_key={token}"
|
|
||||||
)
|
|
||||||
for endpoint in endpoints
|
|
||||||
]
|
|
||||||
responses = await asyncio.gather(*tasks)
|
|
||||||
results = await asyncio.gather(*[response.json() for response in responses])
|
|
||||||
|
|
||||||
result_t, result, result_s, result_w = results
|
|
||||||
|
|
||||||
all_time = result_w["data"]["text"]
|
|
||||||
username = result["data"]["username"]
|
|
||||||
languages = result["data"]["languages"]
|
|
||||||
today = result_t["data"]["categories"]
|
|
||||||
os = result["data"]["operating_systems"]
|
|
||||||
editor = result["data"]["editors"]
|
|
||||||
|
|
||||||
OS = ", ".join(f"<code>{stat['name']}</code>" for stat in os if stat["text"] != "0 secs")
|
|
||||||
EDITOR = ", ".join(f"<code>{stat['name']}</code>" for stat in editor if stat["text"] != "0 secs")
|
|
||||||
LANG = "\n".join(f"▫️ <b>{stat['name']}</b>: <i>{stat['text']}</i>" for stat in languages if stat["text"] != "0 secs")
|
|
||||||
TODAY = "\n".join(stat["text"] for stat in today if stat["text"] != "0 secs")
|
|
||||||
|
|
||||||
await call.edit(
|
|
||||||
f"👤 <b>Username:</b> <code>{username}</code>\n🖥 <b>OS:</b> {OS}\n🌀 <b>Editor:</b> {EDITOR}\n⏳ <b>All time</b>: <code>{all_time}</code>\n💼 <b>Today</b>: <code>{TODAY}</code>\n\n🧬 LANGUAGES\n\n{LANG}\n",
|
|
||||||
reply_markup=[
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"text": "🔄 Update",
|
|
||||||
"callback": self.update_waka,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
)
|
|
||||||
370
SunnexGB/Heroku-Modules/LiveLyrics.py
Normal file
370
SunnexGB/Heroku-Modules/LiveLyrics.py
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
# meta developer: @SunnexGB
|
||||||
|
# requires: aiohttp
|
||||||
|
# meta pic: https://r2.fakecrime.bio/uploads/6725e5a0-0c9e-48ed-be85-dfd857c2aa5f.jpg
|
||||||
|
# meta banner: https://r2.fakecrime.bio/uploads/6725e5a0-0c9e-48ed-be85-dfd857c2aa5f.jpg
|
||||||
|
# meta fhsdesc: Spotify, YaMusic, music, музыка, Lyrics, слова, текст, трек, песня
|
||||||
|
|
||||||
|
__version__ = (1, 0, 0)
|
||||||
|
|
||||||
|
from herokutl.types import Message
|
||||||
|
from .. import loader, utils
|
||||||
|
from ..types import InlineCall
|
||||||
|
import aiohttp
|
||||||
|
import asyncio
|
||||||
|
import re
|
||||||
|
|
||||||
|
@loader.tds
|
||||||
|
class LiveLyrics(loader.Module):
|
||||||
|
"""life lyrics current song"""
|
||||||
|
|
||||||
|
strings = {
|
||||||
|
"name": "LiveLyrics",
|
||||||
|
"no_spotifymod": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>SpotifyMod not found,but u can install it. You can also support developer: </b> @ke_mods",
|
||||||
|
"no_yamusic": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>YaMusicMod not found,but u can install it. You can also support developer: </b> @codrago_m",
|
||||||
|
"no_auth_spotify": "<tg-emoji emoji-id=5429225166250984904>⁉️</tg-emoji><b> You not authorized in SpotifyMod, visit you Saved Messages.</b>",
|
||||||
|
"no_auth_yamusic": "<tg-emoji emoji-id=5429225166250984904>⁉️</tg-emoji><b> You not authorized in SpotifyMod, visit you Saved Messages and setup token to continue.</b>",
|
||||||
|
"no_spotify": "<tg-emoji emoji-id=5429164207780152924>😅</tg-emoji> <b>Nothing is playing on Spotify.</b>",
|
||||||
|
"no_ym": "<tg-emoji emoji-id=5429164207780152924>😅</tg-emoji> <b>Nothing is playing on YaMusic.</b>",
|
||||||
|
"no_lyrics": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>Lyrics not found for:</b> <code>{}</code>",
|
||||||
|
"not_synced": "<i><tg-emoji emoji-id=5431445849026611010>⚠️</tg-emoji> Lyrics are not synchronized.</i>\n\n",
|
||||||
|
"TrackEnded": "<tg-emoji emoji-id=5429638011392377649>‼️</tg-emoji> Playback ended or track changed.",
|
||||||
|
"header": "<tg-emoji emoji-id=5429413328768224565>🎤</tg-emoji> <b>{} - {}</b>\n\n",
|
||||||
|
"timeout": "<b><tg-emoji emoji-id=5429455831764584284>⏳</tg-emoji></b><b> Oopsi, looks like we've got a timeout here</b>.",
|
||||||
|
"yamusic_installed": "YaMusic installed!",
|
||||||
|
"spotify_installed": "SpotifyMod installed!",
|
||||||
|
"song_link": "🔗 song.link",
|
||||||
|
"close": "❌ Close",
|
||||||
|
"ok": "OK",
|
||||||
|
}
|
||||||
|
|
||||||
|
strings_ru = {
|
||||||
|
"_cls_doc": "Лайв слова текущей песни.",
|
||||||
|
"no_spotifymod": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>SpotifyMod не найден,но его можно установить. Вы также можете поддержать разработчика: </b> @ke_mods",
|
||||||
|
"no_yamusic": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>YaMusicMod не найден, но его можно установить. Вы также можете поддержать разработчика: </b> @codrago_m",
|
||||||
|
"no_auth_spotify": "<tg-emoji emoji-id=5429225166250984904>⁉️</tg-emoji> <b>Вы не авторизованы в SpotifyMod. Перейдите в Избранное.</b>",
|
||||||
|
"no_auth_yamusic": "<tg-emoji emoji-id=5429225166250984904>⁉️</tg-emoji><b> Вы не авторизированы в YaMusicMod, перейдите в Избранное и установите токен для продолжения работы.</b>",
|
||||||
|
"no_spotify": "<tg-emoji emoji-id=5429164207780152924>😅</tg-emoji> <b>В Spotify ничего не играет.</b>",
|
||||||
|
"no_ym": "<tg-emoji emoji-id=5429164207780152924>😅</tg-emoji> <b>В YaMusic ничего не играет.</b>",
|
||||||
|
"no_lyrics": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>Текст не найден для:</b> <code>{}</code>",
|
||||||
|
"not_synced": "<i><tg-emoji emoji-id=5431445849026611010>⚠️</tg-emoji> Текст не синхронизирован.</i>\n\n",
|
||||||
|
"TrackEnded": "<tg-emoji emoji-id=5429638011392377649>‼️</tg-emoji> Воспроизведение завершено или трек сменился.",
|
||||||
|
"header": "<tg-emoji emoji-id=5429413328768224565>🎤</tg-emoji> <b>{} - {}</b>\n\n",
|
||||||
|
"timeout": "<b><tg-emoji emoji-id=5429455831764584284>⏳</tg-emoji></b><b> Упси, похоже кто то словил таймаут.</b>.",
|
||||||
|
"yamusic_installed": "YaMusic Установлен!",
|
||||||
|
"spotify_installed": "SpotifyMod Установлен!",
|
||||||
|
"song_link": "🔗 song.link",
|
||||||
|
"close": "❌ Закрыть",
|
||||||
|
"ok": "OK",
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._active_tasks: dict = {}
|
||||||
|
self.config = loader.ModuleConfig(
|
||||||
|
loader.ConfigValue(
|
||||||
|
"emoji_current",
|
||||||
|
"<tg-emoji emoji-id='5215679757366089921'>🤯</tg-emoji>",
|
||||||
|
"Emoji for the current line",
|
||||||
|
validator=loader.validators.String(),
|
||||||
|
),
|
||||||
|
loader.ConfigValue(
|
||||||
|
"dot",
|
||||||
|
"♪",
|
||||||
|
"instrumental_emoji or text",
|
||||||
|
validator=loader.validators.String(),
|
||||||
|
),
|
||||||
|
loader.ConfigValue(
|
||||||
|
"text_lines",
|
||||||
|
"6",
|
||||||
|
"Count lines in message, with synchronized text",
|
||||||
|
validator=loader.validators.Integer(),
|
||||||
|
),
|
||||||
|
loader.ConfigValue(
|
||||||
|
"lyrics_delay",
|
||||||
|
0.5,
|
||||||
|
"delay in switching to a new timing sector with words",
|
||||||
|
),
|
||||||
|
loader.ConfigValue(
|
||||||
|
"request_timeout",
|
||||||
|
12,
|
||||||
|
"timeout value",
|
||||||
|
validator=loader.validators.Integer(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
async def install_mod(self, call: InlineCall, heroku_module: str):
|
||||||
|
if heroku_module == "SpotifyMod":
|
||||||
|
download_url = "https://raw.githubusercontent.com/radiocycle/Modules/refs/heads/master/SpotifyMod.py"
|
||||||
|
module_name = "SpotifyMod"
|
||||||
|
installed_btn = self.strings["spotify_installed"]
|
||||||
|
no_auth_str = self.strings["no_auth_spotify"]
|
||||||
|
auth_command = "sauth"
|
||||||
|
else:
|
||||||
|
download_url = "https://raw.githubusercontent.com/coddrago/modules/main/YaMusic.py"
|
||||||
|
module_name = "YaMusic"
|
||||||
|
installed_btn = self.strings["yamusic_installed"]
|
||||||
|
no_auth_str = self.strings["no_auth_yamusic"]
|
||||||
|
auth_command = "yguide"
|
||||||
|
try:
|
||||||
|
m = self.lookup("loader")
|
||||||
|
await m.download_and_install(download_url)
|
||||||
|
await call.answer(installed_btn, show_alert=True)
|
||||||
|
mod = self.lookup(module_name)
|
||||||
|
if heroku_module == "SpotifyMod":
|
||||||
|
authorized = mod and mod.get("acs_tkn")
|
||||||
|
else:
|
||||||
|
authorized = mod and mod.get("__config__")["token"]
|
||||||
|
if not authorized:
|
||||||
|
await self.invoke(auth_command, " ", "me")
|
||||||
|
await call.edit(
|
||||||
|
no_auth_str,
|
||||||
|
reply_markup=[
|
||||||
|
[
|
||||||
|
{"text": self.strings["ok"], "callback": self.close}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await call.delete()
|
||||||
|
except Exception as e:
|
||||||
|
await call.answer(f"Error: {e}", show_alert=True)
|
||||||
|
|
||||||
|
def close(self, call: InlineCall):
|
||||||
|
return call.delete()
|
||||||
|
|
||||||
|
async def get_lyrics(self, artist: str, track: str):
|
||||||
|
ClearTimeSections = re.sub(r"\(.*?\)|\[.*?\]", "", track).strip()
|
||||||
|
try:
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(
|
||||||
|
"https://lrclib.net/api/search",
|
||||||
|
params={"track_name": ClearTimeSections, "artist_name": artist},
|
||||||
|
timeout=aiohttp.ClientTimeout(total=self.config["request_timeout"]),
|
||||||
|
) as resp:
|
||||||
|
if resp.status == 200:
|
||||||
|
result = await resp.json()
|
||||||
|
return result[0] if result else None
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
return {"timeout": True}
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
def parse_synced(self, synced_text: str) -> list:
|
||||||
|
lines = []
|
||||||
|
for line in synced_text.split("\n"):
|
||||||
|
m = re.search(r"\[(\d+):(\d+\.\d+)\](.*)", line)
|
||||||
|
if m:
|
||||||
|
mins, secs, text = m.groups()
|
||||||
|
lines.append({
|
||||||
|
"time": (int(mins) * 60 + float(secs)) * 1000,
|
||||||
|
"text": text.strip(),
|
||||||
|
})
|
||||||
|
return lines
|
||||||
|
|
||||||
|
def build_lyrics(self, artist, track, lines, plain, progress_ms, not_synced_str):
|
||||||
|
header = self.strings["header"].format(
|
||||||
|
utils.escape_html(artist),
|
||||||
|
utils.escape_html(track),
|
||||||
|
)
|
||||||
|
if lines:
|
||||||
|
curr_idx = 0
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if progress_ms >= line["time"]:
|
||||||
|
curr_idx = i
|
||||||
|
l_start = max(0, curr_idx - 1)
|
||||||
|
l_end = min(len(lines), l_start + self.config["text_lines"])
|
||||||
|
rows = []
|
||||||
|
for i in range(l_start, l_end):
|
||||||
|
t = lines[i]["text"] or self.config["dot"]
|
||||||
|
if i == curr_idx:
|
||||||
|
rows.append(f"<b>{self.config['emoji_current']} {utils.escape_html(t)}</b>")
|
||||||
|
else:
|
||||||
|
rows.append(f"<code>{utils.escape_html(t)}</code>")
|
||||||
|
return header + "\n".join(rows)
|
||||||
|
return header + not_synced_str + f"<blockquote expandable>{utils.escape_html((plain or '')[:4000])}</blockquote>"
|
||||||
|
|
||||||
|
def build_keyboard(self, song_url):
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
{"text": self.strings["song_link"], "url": song_url}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{"text": self.strings["close"], "callback": self.close_cb}
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
async def close_cb(self, call: InlineCall):
|
||||||
|
for track_id, task in list(self._active_tasks.items()):
|
||||||
|
task.cancel()
|
||||||
|
self._active_tasks.pop(track_id, None)
|
||||||
|
try:
|
||||||
|
await call.answer()
|
||||||
|
await call.delete()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def za_loop_a(self, form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str, heroku_module: str):
|
||||||
|
buffer_clipboard = ""
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
if heroku_module == "SpotifyMod":
|
||||||
|
pb = mod.sp.current_playback()
|
||||||
|
TrackEnded = not pb or not pb.get("item") or pb["item"]["id"] != track_id
|
||||||
|
else:
|
||||||
|
pb = await mod._YaMusicMod__get_now_playing()
|
||||||
|
TrackEnded = not pb or not pb.get("track") or pb["track"]["track_id"] != track_id
|
||||||
|
if TrackEnded:
|
||||||
|
try:
|
||||||
|
await form.edit(
|
||||||
|
self.strings["TrackEnded"],
|
||||||
|
reply_markup=[[{"text": self.strings["close"], "callback": self.close_cb}]],
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
break
|
||||||
|
prog = pb.get("progress_ms", 0)
|
||||||
|
content = self.build_lyrics(artist_name, track_name, lines, plain, prog, not_synced_str)
|
||||||
|
if content != buffer_clipboard:
|
||||||
|
try:
|
||||||
|
await form.edit(content, reply_markup=self.build_keyboard(song_url))
|
||||||
|
buffer_clipboard = content
|
||||||
|
except Exception:
|
||||||
|
break
|
||||||
|
if not lines:
|
||||||
|
break
|
||||||
|
await asyncio.sleep(self.config["lyrics_delay"])
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
self._active_tasks.pop(track_id, None)
|
||||||
|
|
||||||
|
@loader.command(ru_doc="- показать синхронизированный текст песни")
|
||||||
|
async def snowlcmd(self, message: Message):
|
||||||
|
"""- show synchronized lyrics for current track"""
|
||||||
|
mod = self.lookup("SpotifyMod")
|
||||||
|
if not mod:
|
||||||
|
form = await self.inline.form("⏳", message=message)
|
||||||
|
await form.edit(
|
||||||
|
self.strings["no_spotifymod"],
|
||||||
|
reply_markup=[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"text": self.strings["spotify_installed"],
|
||||||
|
"callback": self.install_mod,
|
||||||
|
"kwargs": {"heroku_module": "SpotifyMod"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if not mod.get("acs_tkn"):
|
||||||
|
await self.invoke("sauth", " ", "me")
|
||||||
|
form = await self.inline.form("⏳", message=message)
|
||||||
|
await form.edit(
|
||||||
|
self.strings["no_auth_spotify"],
|
||||||
|
reply_markup=[[{"text": self.strings["ok"], "callback": self.close}]],
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
playback = mod.sp.current_playback()
|
||||||
|
if not playback or not playback.get("item"):
|
||||||
|
return await utils.answer(message, self.strings["no_spotify"])
|
||||||
|
track = playback["item"]
|
||||||
|
track_id = track["id"]
|
||||||
|
artist_name = track["artists"][0]["name"]
|
||||||
|
track_name = track["name"]
|
||||||
|
song_url = f"https://song.link/s/{track_id}"
|
||||||
|
|
||||||
|
old = self._active_tasks.pop(track_id, None)
|
||||||
|
if old:
|
||||||
|
old.cancel()
|
||||||
|
|
||||||
|
data = await self.get_lyrics(artist_name, track_name)
|
||||||
|
if data and data.get("timeout"):
|
||||||
|
return await utils.answer(message, self.strings["timeout"])
|
||||||
|
if not data or data.get("instrumental"):
|
||||||
|
return await utils.answer(
|
||||||
|
message,
|
||||||
|
self.strings["no_lyrics"].format(f"{utils.escape_html(track_name)} - {utils.escape_html(artist_name)}"),
|
||||||
|
)
|
||||||
|
|
||||||
|
synced_raw = data.get("syncedLyrics")
|
||||||
|
plain = data.get("plainLyrics", "")
|
||||||
|
lines = self.parse_synced(synced_raw) if synced_raw else []
|
||||||
|
not_synced_str = self.strings["not_synced"]
|
||||||
|
form = await self.inline.form(
|
||||||
|
text=self.build_lyrics(artist_name, track_name, lines, plain, playback.get("progress_ms", 0), not_synced_str),
|
||||||
|
message=message,
|
||||||
|
reply_markup=self.build_keyboard(song_url),
|
||||||
|
)
|
||||||
|
|
||||||
|
self._active_tasks[track_id] = asyncio.ensure_future(
|
||||||
|
self.za_loop_a(form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str, heroku_module="SpotifyMod")
|
||||||
|
)
|
||||||
|
|
||||||
|
@loader.command(ru_doc="- показать синхронизированный текст песни")
|
||||||
|
async def ynowlcmd(self, message: Message):
|
||||||
|
"""- show synchronized lyrics for current track"""
|
||||||
|
mod = self.lookup("YaMusic")
|
||||||
|
if not mod:
|
||||||
|
form = await self.inline.form("⏳", message=message)
|
||||||
|
await form.edit(
|
||||||
|
self.strings["no_yamusic"],
|
||||||
|
reply_markup=[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "Install YaMusicMod",
|
||||||
|
"callback": self.install_mod,
|
||||||
|
"kwargs": {"heroku_module": "YaMusic"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if not mod.get("__config__")["token"]:
|
||||||
|
await self.invoke("yguide", " ", "me")
|
||||||
|
form = await self.inline.form("⏳", message=message)
|
||||||
|
await form.edit(
|
||||||
|
self.strings["no_auth_yamusic"],
|
||||||
|
reply_markup=[[{"text": self.strings["ok"], "callback": self.close}]],
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
playback = await mod._YaMusicMod__get_now_playing()
|
||||||
|
if not playback or not playback.get("track"):
|
||||||
|
return await utils.answer(message, self.strings["no_ym"])
|
||||||
|
track = playback["track"]
|
||||||
|
track_id = track["track_id"]
|
||||||
|
artist_name = ", ".join(track["artist"])
|
||||||
|
track_name = track["title"]
|
||||||
|
song_url = f"https://song.link/s/{track_id}"
|
||||||
|
|
||||||
|
old = self._active_tasks.pop(track_id, None)
|
||||||
|
if old:
|
||||||
|
old.cancel()
|
||||||
|
|
||||||
|
data = await self.get_lyrics(artist_name, track_name)
|
||||||
|
if data and data.get("timeout"):
|
||||||
|
return await utils.answer(message, self.strings["timeout"])
|
||||||
|
if not data or data.get("instrumental"):
|
||||||
|
return await utils.answer(
|
||||||
|
message,
|
||||||
|
self.strings["no_lyrics"].format(f"{utils.escape_html(track_name)} - {utils.escape_html(artist_name)}"),
|
||||||
|
)
|
||||||
|
|
||||||
|
synced_raw = data.get("syncedLyrics")
|
||||||
|
plain = data.get("plainLyrics", "")
|
||||||
|
lines = self.parse_synced(synced_raw) if synced_raw else []
|
||||||
|
not_synced_str = self.strings["not_synced"]
|
||||||
|
|
||||||
|
form = await self.inline.form(
|
||||||
|
text=self.build_lyrics(artist_name, track_name, lines, plain, playback.get("progress_ms", 0), not_synced_str),
|
||||||
|
message=message,
|
||||||
|
reply_markup=self.build_keyboard(song_url),
|
||||||
|
)
|
||||||
|
|
||||||
|
self._active_tasks[track_id] = asyncio.ensure_future(
|
||||||
|
self.za_loop_a(form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str, heroku_module="YaMusic")
|
||||||
|
)
|
||||||
@@ -1,285 +0,0 @@
|
|||||||
# meta developer: @SunnexGB
|
|
||||||
# requires: aiohttp
|
|
||||||
# meta pic: https://r2.fakecrime.bio/uploads/f49a9294-36ad-4fc4-801f-48cb049111d6.jpg
|
|
||||||
# meta banner: https://r2.fakecrime.bio/uploads/f49a9294-36ad-4fc4-801f-48cb049111d6.jpg
|
|
||||||
# meta fhsdesc: Spotify, music, музыка, спотифай,Lyrics, слова, текст, трек, песня
|
|
||||||
# все же я не знаю трек или сонг, так что пусть будет трек, а не сонг потому что интуитивнее поняттнее,наверное?
|
|
||||||
# крутой баннер да?
|
|
||||||
#current version
|
|
||||||
__version__ = (1, 1, 2)
|
|
||||||
|
|
||||||
from herokutl.types import Message
|
|
||||||
from .. import loader, utils
|
|
||||||
from ..types import InlineCall
|
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class SpotifyLyrics(loader.Module):
|
|
||||||
"""life lyrics current song"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "SpotifyLyrics",
|
|
||||||
"no_spotifymod": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>SpotifyMod not found,but u can install it. You can also support developer: </b> @ke_mods",
|
|
||||||
"no_auth": "<tg-emoji emoji-id=5429225166250984904>⁉️</tg-emoji><b> You not authorized in SpotifyMod, visit you Saved Messages.</b>",
|
|
||||||
"no_spotify": "<tg-emoji emoji-id=5429164207780152924>😅</tg-emoji> <b>Nothing is playing on Spotify.</b>",
|
|
||||||
"no_lyrics": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>Lyrics not found for:</b> <code>{}</code>",
|
|
||||||
"not_synced": "<i><tg-emoji emoji-id=5431445849026611010>⚠️</tg-emoji> Lyrics are not synchronized.</i>\n\n",
|
|
||||||
"finished": "<tg-emoji emoji-id=5429638011392377649>‼️</tg-emoji> Playback ended or track changed.",
|
|
||||||
"header": "<tg-emoji emoji-id=5429413328768224565>🎤</tg-emoji> <b>{} - {}</b>\n\n",
|
|
||||||
"timeout": "<b><tg-emoji emoji-id=5429455831764584284>⏳</tg-emoji></b><b> Oopsi, looks like we've got a timeout here</b>.",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"cls_doc": "Лайв слова текущей песни.",
|
|
||||||
"no_spotifymod": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>SpotifyMod не найден,но его можно установить. Вы также можете поддержать разработчика: </b> @ke_mods",
|
|
||||||
"no_auth": "<tg-emoji emoji-id=5429225166250984904>⁉️</tg-emoji><b> Вы не авторизированы в SpotifyMod, перейдите в Избранное.</b>",
|
|
||||||
"no_spotify": "<tg-emoji emoji-id=5429164207780152924>😅</tg-emoji> <b>В Spotify ничего не играет.</b>",
|
|
||||||
"no_lyrics": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>Текст не найден для:</b> <code>{}</code>",
|
|
||||||
"not_synced": "<i><tg-emoji emoji-id=5431445849026611010>⚠️</tg-emoji> Текст не синхронизирован.</i>\n\n",
|
|
||||||
"finished": "<tg-emoji emoji-id=5429638011392377649>‼️</tg-emoji> Воспроизведение завершено или трек сменился.",
|
|
||||||
"header": "<tg-emoji emoji-id=5429413328768224565>🎤</tg-emoji> <b>{} - {}</b>\n\n",
|
|
||||||
"timeout": "<b><tg-emoji emoji-id=5429455831764584284>⏳</tg-emoji></b><b> Упси, похоже кто то словил таймаут.</b>.",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self._active_tasks: dict = {}
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"emoji_current",
|
|
||||||
"<tg-emoji emoji-id='5215679757366089921'>🤯</tg-emoji>",
|
|
||||||
"Emoji for current line",
|
|
||||||
validator=loader.validators.String(),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"dot",
|
|
||||||
"♪",
|
|
||||||
"instrumental_emoji or text",
|
|
||||||
validator=loader.validators.String(),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"lyrics_delay",
|
|
||||||
0.5,
|
|
||||||
"delay in switching to a new timing sector with words",
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"request_timeout",
|
|
||||||
12,
|
|
||||||
"timeout value",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
async def install_spotifymod(self, call: InlineCall):
|
|
||||||
mod_url = "https://raw.githubusercontent.com/radiocycle/Modules/refs/heads/master/SpotifyMod.py"
|
|
||||||
try:
|
|
||||||
m = self.lookup("Modules") or self.lookup("loader")
|
|
||||||
await m.download_and_install(mod_url)
|
|
||||||
await call.answer("SpotifyMod installed!", show_alert=True)
|
|
||||||
mod = self.lookup("SpotifyMod")
|
|
||||||
acs_tkn = mod.get("acs_tkn") if mod else None
|
|
||||||
if not acs_tkn:
|
|
||||||
await self.invoke("sauth", " ", "me")
|
|
||||||
await call.edit(
|
|
||||||
self.strings("no_auth"),
|
|
||||||
reply_markup=[[{"text": "Хорошо", "callback": self.close}]],
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
await call.delete()
|
|
||||||
except Exception as e:
|
|
||||||
await call.answer(f"Error! Check logs.\n{e}", show_alert=True)
|
|
||||||
|
|
||||||
def close(self, call: InlineCall):
|
|
||||||
return call.delete()
|
|
||||||
|
|
||||||
async def _get_lyrics(self, artist: str, track: str):
|
|
||||||
clean_track = re.sub(r"\(.*?\)|\[.*?\]", "", track).strip()
|
|
||||||
try:
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.get(
|
|
||||||
"https://lrclib.net/api/search",
|
|
||||||
params={"track_name": clean_track, "artist_name": artist},
|
|
||||||
timeout=aiohttp.ClientTimeout(total=(self.config["request_timeout"])),
|
|
||||||
) as resp:
|
|
||||||
if resp.status == 200:
|
|
||||||
res = await resp.json()
|
|
||||||
return res[0] if res else None
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
return {"timeout": True}
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _parse_synced(self, synced_text: str) -> list:
|
|
||||||
lines = []
|
|
||||||
for line in synced_text.split("\n"):
|
|
||||||
m = re.search(r"\[(\d+):(\d+\.\d+)\](.*)", line)
|
|
||||||
if m:
|
|
||||||
mins, secs, text = m.groups()
|
|
||||||
lines.append({
|
|
||||||
"time": (int(mins) * 60 + float(secs)) * 1000,
|
|
||||||
"text": text.strip(),
|
|
||||||
})
|
|
||||||
return lines
|
|
||||||
|
|
||||||
def _build_content(self, artist, track, lines, plain, progress_ms, not_synced_str):
|
|
||||||
header = self.strings("header").format(
|
|
||||||
utils.escape_html(artist),
|
|
||||||
utils.escape_html(track),
|
|
||||||
)
|
|
||||||
if lines:
|
|
||||||
curr_idx = 0
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
if progress_ms >= line["time"]:
|
|
||||||
curr_idx = i
|
|
||||||
win_start = max(0, curr_idx - 1)
|
|
||||||
win_end = min(len(lines), curr_idx + 6)
|
|
||||||
rows = []
|
|
||||||
for i in range(win_start, win_end):
|
|
||||||
t = lines[i]["text"] or self.config["dot"]
|
|
||||||
if i == curr_idx:
|
|
||||||
rows.append(
|
|
||||||
f"<b>{self.config['emoji_current']} {utils.escape_html(t)}</b>"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
rows.append(f"<code>{utils.escape_html(t)}</code>")
|
|
||||||
return header + "\n".join(rows)
|
|
||||||
else:
|
|
||||||
return header + not_synced_str + f"<blockquote expandable>{utils.escape_html((plain or '')[:4000])}</blockquote>"
|
|
||||||
|
|
||||||
def _markup(self, song_url):
|
|
||||||
return [
|
|
||||||
[{"text": "🔗 song.link", "url": song_url}],
|
|
||||||
[{"text": "❌ Close", "callback": self._close_cb}],
|
|
||||||
]
|
|
||||||
|
|
||||||
async def _close_cb(self, call):
|
|
||||||
for track_id, task in list(self._active_tasks.items()):
|
|
||||||
task.cancel()
|
|
||||||
self._active_tasks.pop(track_id, None)
|
|
||||||
try:
|
|
||||||
await call.answer()
|
|
||||||
await call.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def run_loop(self, form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str):
|
|
||||||
last_display = ""
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
pb = mod.sp.current_playback()
|
|
||||||
if not pb or not pb.get("item") or pb["item"]["id"] != track_id:
|
|
||||||
try:
|
|
||||||
await form.edit(
|
|
||||||
self.strings("finished"),
|
|
||||||
reply_markup=[[{"text": "❌ Close", "callback": self._close_cb}]],
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
break
|
|
||||||
|
|
||||||
prog = pb.get("progress_ms", 0)
|
|
||||||
content = self._build_content(
|
|
||||||
artist_name, track_name, lines, plain, prog, not_synced_str
|
|
||||||
)
|
|
||||||
|
|
||||||
if content != last_display:
|
|
||||||
try:
|
|
||||||
await form.edit(content, reply_markup=self._markup(song_url))
|
|
||||||
last_display = content
|
|
||||||
except Exception:
|
|
||||||
break
|
|
||||||
|
|
||||||
if not lines:
|
|
||||||
break
|
|
||||||
|
|
||||||
await asyncio.sleep(self.config["lyrics_delay"])
|
|
||||||
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
raise
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
finally:
|
|
||||||
self._active_tasks.pop(track_id, None)
|
|
||||||
|
|
||||||
@loader.command(ru_doc="- показать синхронизированный текст песни")
|
|
||||||
async def snowlcmd(self, message: Message):
|
|
||||||
"""- show synchronized lyrics for current Spotify track"""
|
|
||||||
mod = self.lookup("SpotifyMod")
|
|
||||||
if not mod:
|
|
||||||
form = await self.inline.form("⏳", message=message)
|
|
||||||
await form.edit(
|
|
||||||
self.strings("no_spotifymod"),
|
|
||||||
reply_markup=[[{"text": "Install SpotifyMod", "callback": self.install_spotifymod}]],
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
acs_tkn = mod.get("acs_tkn")
|
|
||||||
if not acs_tkn:
|
|
||||||
await self.invoke("sauth", " ", "me")
|
|
||||||
form = await self.inline.form("⏳", message=message)
|
|
||||||
await form.edit(
|
|
||||||
self.strings("no_auth"),
|
|
||||||
reply_markup=[[{"text": "Хорошо", "callback": self.close}]],
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
playback = mod.sp.current_playback()
|
|
||||||
if not playback or not playback.get("item"):
|
|
||||||
return await utils.answer(message, self.strings("no_spotify"))
|
|
||||||
|
|
||||||
track = playback["item"]
|
|
||||||
track_id = track["id"]
|
|
||||||
artist_name = track["artists"][0]["name"]
|
|
||||||
track_name = track["name"]
|
|
||||||
song_url = f"https://song.link/s/{track_id}"
|
|
||||||
|
|
||||||
old = self._active_tasks.pop(track_id, None)
|
|
||||||
if old:
|
|
||||||
old.cancel()
|
|
||||||
|
|
||||||
data = await self._get_lyrics(artist_name, track_name)
|
|
||||||
if data and data.get("timeout"):
|
|
||||||
return utils.answer(
|
|
||||||
message,
|
|
||||||
self.strings["timeout"]
|
|
||||||
)
|
|
||||||
if not data or data.get("instrumental"):
|
|
||||||
track_and_artist = f"{utils.escape_html(track_name)} - {utils.escape_html(artist_name)}"
|
|
||||||
return await utils.answer(
|
|
||||||
message,
|
|
||||||
self.strings("no_lyrics").format(track_and_artist),
|
|
||||||
)
|
|
||||||
|
|
||||||
synced_raw = data.get("syncedLyrics")
|
|
||||||
plain = data.get("plainLyrics", "")
|
|
||||||
|
|
||||||
lines = self._parse_synced(synced_raw) if synced_raw else []
|
|
||||||
not_synced_str = self.strings("not_synced")
|
|
||||||
|
|
||||||
prog = playback.get("progress_ms", 0)
|
|
||||||
initial_content = self._build_content(
|
|
||||||
artist_name, track_name, lines, plain, prog, not_synced_str
|
|
||||||
)
|
|
||||||
|
|
||||||
form = await self.inline.form(
|
|
||||||
text=initial_content,
|
|
||||||
message=message,
|
|
||||||
reply_markup=self._markup(song_url),
|
|
||||||
)
|
|
||||||
|
|
||||||
task = asyncio.ensure_future(
|
|
||||||
self.run_loop(
|
|
||||||
form=form,
|
|
||||||
mod=mod,
|
|
||||||
track_id=track_id,
|
|
||||||
artist_name=artist_name,
|
|
||||||
track_name=track_name,
|
|
||||||
song_url=song_url,
|
|
||||||
lines=lines,
|
|
||||||
plain=plain,
|
|
||||||
not_synced_str=not_synced_str,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._active_tasks[track_id] = task
|
|
||||||
@@ -1,352 +0,0 @@
|
|||||||
# meta developer: @SunnexGB
|
|
||||||
# requires: aiohttp
|
|
||||||
# meta pic: https://r2.fakecrime.bio/uploads/ab42b5e2-91f1-4ed1-8002-51b3184e3839.jpg
|
|
||||||
# meta banner: https://r2.fakecrime.bio/uploads/ab42b5e2-91f1-4ed1-8002-51b3184e3839.jpg
|
|
||||||
# meta fhsdesc: YaMusic, music, музыка, яндекс музыка,Lyrics, слова, текст, трек, песня
|
|
||||||
# все же я не знаю трек или сонг, так что пусть будет трек, а не сонг потому что интуитивнее поняттнее,наверное?
|
|
||||||
# крутой баннер да?
|
|
||||||
#current version
|
|
||||||
__version__ = (1, 1, 2)
|
|
||||||
|
|
||||||
from herokutl.types import Message
|
|
||||||
from .. import loader, utils
|
|
||||||
from ..types import InlineCall
|
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class YandexLyrics(loader.Module):
|
|
||||||
"""life lyrics current song"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "YandexLyrics",
|
|
||||||
"no_YaMusicMod": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>YaMusicMod not found,but u can install it. You can also support developer: </b> @codrago_m",
|
|
||||||
"no_auth": "<tg-emoji emoji-id=5429225166250984904>⁉️</tg-emoji><b> You not authorized in SpotifyMod, visit you Saved Messages and setup token to continue.</b>",
|
|
||||||
"no_ym": "<tg-emoji emoji-id=5429164207780152924>😅</tg-emoji> <b>Nothing is playing on YaMusic.</b>",
|
|
||||||
"no_lyrics": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>Lyrics not found for:</b> <code>{}</code>",
|
|
||||||
"not_synced": "<i><tg-emoji emoji-id=5431445849026611010>⚠️</tg-emoji> Lyrics are not synchronized.</i>\n\n",
|
|
||||||
"finished": "<tg-emoji emoji-id=5429638011392377649>‼️</tg-emoji> Playback ended or track changed.",
|
|
||||||
"header": "<tg-emoji emoji-id=5429413328768224565>🎤</tg-emoji> <b>{} - {}</b>\n\n",
|
|
||||||
"timeout": "<b><tg-emoji emoji-id=5429455831764584284>⏳</tg-emoji></b><b> Oopsi, looks like we've got a timeout here</b>.",
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"cls_doc": "Лайв слова текущей песни.",
|
|
||||||
"no_YaMusicMod": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>YaMusicMod не найден,но его можно установить. Вы также можете поддержать разработчика: </b> @codrago_m",
|
|
||||||
"no_auth": "<tg-emoji emoji-id=5429225166250984904>⁉️</tg-emoji><b> Вы не авторизированы в YaMusicMod, перейдите в Избранное и установите токен для продолжения работы.</b>",
|
|
||||||
"no_ym": "<tg-emoji emoji-id=5429164207780152924>😅</tg-emoji> <b>В YaMusic ничего не играет.</b>",
|
|
||||||
"no_lyrics": "<tg-emoji emoji-id=5431402435497181911>💢</tg-emoji> <b>Текст не найден для:</b> <code>{}</code>",
|
|
||||||
"not_synced": "<i><tg-emoji emoji-id=5431445849026611010>⚠️</tg-emoji> Текст не синхронизирован.</i>\n\n",
|
|
||||||
"finished": "<tg-emoji emoji-id=5429638011392377649>‼️</tg-emoji> Воспроизведение завершено или трек сменился.",
|
|
||||||
"header": "<tg-emoji emoji-id=5429413328768224565>🎤</tg-emoji> <b>{} - {}</b>\n\n",
|
|
||||||
"timeout": "<b><tg-emoji emoji-id=5429455831764584284>⏳</tg-emoji></b><b> Упси, похоже кто то словил таймаут.</b>.",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self._active_tasks: dict = {}
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue(
|
|
||||||
"emoji_current",
|
|
||||||
"<tg-emoji emoji-id='5215679757366089921'>🤯</tg-emoji>",
|
|
||||||
"Emoji for current line",
|
|
||||||
validator=loader.validators.String(),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"dot",
|
|
||||||
"♪",
|
|
||||||
"instrumental_emoji or text",
|
|
||||||
validator=loader.validators.String(),
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"lyrics_delay",
|
|
||||||
0.5,
|
|
||||||
"delay in switching to a new timing sector with words",
|
|
||||||
),
|
|
||||||
loader.ConfigValue(
|
|
||||||
"request_timeout",
|
|
||||||
12,
|
|
||||||
"timeout value",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
async def install_yamusic(self, call: InlineCall):
|
|
||||||
mod_url = "https://raw.githubusercontent.com/coddrago/modules/main/YaMusic.py"
|
|
||||||
try:
|
|
||||||
m = self.lookup("Modules") or self.lookup("loader")
|
|
||||||
await m.download_and_install(mod_url)
|
|
||||||
await call.answer("YaMusicMod installed!", show_alert=True)
|
|
||||||
mod = self.lookup("YaMusicMod")
|
|
||||||
acs_tkn = mod.get("__config__")["token"] if mod else "****"
|
|
||||||
if not acs_tkn:
|
|
||||||
await self.invoke("yguide", " ", "me")
|
|
||||||
await call.edit(
|
|
||||||
self.strings("no_auth"),
|
|
||||||
reply_markup=[[{"text": "Хорошо", "callback": self.close}]],
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
await call.delete()
|
|
||||||
except Exception as e:
|
|
||||||
await call.answer(f"Error! Check logs.\n{e}", show_alert=True)
|
|
||||||
|
|
||||||
def close(self, call: InlineCall):
|
|
||||||
return call.delete()
|
|
||||||
|
|
||||||
async def _get_lyrics(self, artist: str, track: str):
|
|
||||||
clean_track = re.sub(r"\(.*?\)|\[.*?\]", "", track).strip()
|
|
||||||
try:
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.get(
|
|
||||||
"https://lrclib.net/api/search",
|
|
||||||
params={"track_name": clean_track, "artist_name": artist},
|
|
||||||
timeout=aiohttp.ClientTimeout(total=(self.config["request_timeout"])),
|
|
||||||
) as resp:
|
|
||||||
if resp.status == 200:
|
|
||||||
res = await resp.json()
|
|
||||||
return res[0] if res else None
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
return {"timeout": True}
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _parse_synced(self, synced_text: str) -> list:
|
|
||||||
lines = []
|
|
||||||
for line in synced_text.split("\n"):
|
|
||||||
m = re.search(r"\[(\d+):(\d+\.\d+)\](.*)", line)
|
|
||||||
if m:
|
|
||||||
mins, secs, text = m.groups()
|
|
||||||
lines.append({
|
|
||||||
"time": (int(mins) * 60 + float(secs)) * 1000,
|
|
||||||
"text": text.strip(),
|
|
||||||
})
|
|
||||||
return lines
|
|
||||||
|
|
||||||
def _build_content(self, artist, track, lines, plain, progress_ms, not_synced_str):
|
|
||||||
header = self.strings("header").format(
|
|
||||||
utils.escape_html(artist),
|
|
||||||
utils.escape_html(track),
|
|
||||||
)
|
|
||||||
if lines:
|
|
||||||
curr_idx = 0
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
if progress_ms >= line["time"]:
|
|
||||||
curr_idx = i
|
|
||||||
win_start = max(0, curr_idx - 1)
|
|
||||||
win_end = min(len(lines), curr_idx + 6)
|
|
||||||
rows = []
|
|
||||||
for i in range(win_start, win_end):
|
|
||||||
t = lines[i]["text"] or self.config["dot"]
|
|
||||||
if i == curr_idx:
|
|
||||||
rows.append(
|
|
||||||
f"<b>{self.config['emoji_current']} {utils.escape_html(t)}</b>"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
rows.append(f"<code>{utils.escape_html(t)}</code>")
|
|
||||||
return header + "\n".join(rows)
|
|
||||||
else:
|
|
||||||
return header + not_synced_str + f"<blockquote expandable>{utils.escape_html((plain or '')[:4000])}</blockquote>"
|
|
||||||
|
|
||||||
def _markup(self, song_url):
|
|
||||||
return [
|
|
||||||
[{"text": "🔗 song.link", "url": song_url}],
|
|
||||||
[{"text": "❌ Close", "callback": self._close_cb}],
|
|
||||||
]
|
|
||||||
|
|
||||||
async def _close_cb(self, call):
|
|
||||||
for track_id, task in list(self._active_tasks.items()):
|
|
||||||
task.cancel()
|
|
||||||
self._active_tasks.pop(track_id, None)
|
|
||||||
try:
|
|
||||||
await call.answer()
|
|
||||||
await call.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def run_loop(self, form, mod, track_id, artist_name, track_name, song_url, lines, plain, not_synced_str):
|
|
||||||
last_display = ""
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
pb = await mod._YaMusicMod__get_now_playing()
|
|
||||||
if not pb or not pb.get("track") or pb["track"]["track_id"] != track_id:
|
|
||||||
try:
|
|
||||||
await form.edit(
|
|
||||||
self.strings("finished"),
|
|
||||||
reply_markup=[[{"text": "❌ Close", "callback": self._close_cb}]],
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
break
|
|
||||||
|
|
||||||
prog = pb.get("progress_ms", 0)
|
|
||||||
content = self._build_content(
|
|
||||||
artist_name, track_name, lines, plain, prog, not_synced_str
|
|
||||||
)
|
|
||||||
|
|
||||||
if content != last_display:
|
|
||||||
try:
|
|
||||||
await form.edit(content, reply_markup=self._markup(song_url))
|
|
||||||
last_display = content
|
|
||||||
except Exception:
|
|
||||||
break
|
|
||||||
|
|
||||||
if not lines:
|
|
||||||
break
|
|
||||||
|
|
||||||
await asyncio.sleep(self.config["lyrics_delay"])
|
|
||||||
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
raise
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
finally:
|
|
||||||
self._active_tasks.pop(track_id, None)
|
|
||||||
|
|
||||||
@loader.command(ru_doc="- показать синхронизированный текст песни")
|
|
||||||
async def ynowlcmd(self, message: Message):
|
|
||||||
"""- show synchronized lyrics for current YaMusic track"""
|
|
||||||
mod = self.lookup("YaMusic")
|
|
||||||
if not mod:
|
|
||||||
form = await self.inline.form("⏳", message=message)
|
|
||||||
await form.edit(
|
|
||||||
self.strings("no_YaMusicMod"),
|
|
||||||
reply_markup=[[{"text": "Install YaMusic", "callback": self.install_yamusic}]],
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
ya_token = mod.get("__config__")["token"]
|
|
||||||
if not ya_token:
|
|
||||||
await self.invoke("yguide", " ", "me")
|
|
||||||
form = await self.inline.form("⏳", message=message)
|
|
||||||
await form.edit(
|
|
||||||
self.strings("no_auth"),
|
|
||||||
reply_markup=[[{"text": "Хорошо", "callback": self.close}]],
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
playback = await mod._YaMusicMod__get_now_playing()
|
|
||||||
if not playback or not playback.get("track"):
|
|
||||||
return await utils.answer(message, self.strings("no_ym"))
|
|
||||||
|
|
||||||
track = playback["track"]
|
|
||||||
track_id = track["track_id"]
|
|
||||||
artist_name = ", ".join(track["artist"])
|
|
||||||
track_name = track["title"]
|
|
||||||
song_url = f"https://song.link/s/{track_id}"
|
|
||||||
|
|
||||||
old = self._active_tasks.pop(track_id, None)
|
|
||||||
if old:
|
|
||||||
old.cancel()
|
|
||||||
|
|
||||||
data = await self._get_lyrics(artist_name, track_name)
|
|
||||||
if data and data.get("timeout"):
|
|
||||||
return utils.answer(
|
|
||||||
message,
|
|
||||||
self.strings["timeout"]
|
|
||||||
)
|
|
||||||
if not data or data.get("instrumental"):
|
|
||||||
track_and_artist = f"{utils.escape_html(track_name)} - {utils.escape_html(artist_name)}"
|
|
||||||
return await utils.answer(
|
|
||||||
message,
|
|
||||||
self.strings("no_lyrics").format(track_and_artist),
|
|
||||||
)
|
|
||||||
|
|
||||||
synced_raw = data.get("syncedLyrics")
|
|
||||||
plain = data.get("plainLyrics", "")
|
|
||||||
|
|
||||||
lines = self._parse_synced(synced_raw) if synced_raw else []
|
|
||||||
not_synced_str = self.strings("not_synced")
|
|
||||||
|
|
||||||
prog = playback.get("progress_ms", 0)
|
|
||||||
initial_content = self._build_content(
|
|
||||||
artist_name, track_name, lines, plain, prog, not_synced_str
|
|
||||||
)
|
|
||||||
|
|
||||||
form = await self.inline.form(
|
|
||||||
text=initial_content,
|
|
||||||
message=message,
|
|
||||||
reply_markup=self._markup(song_url),
|
|
||||||
)
|
|
||||||
|
|
||||||
task = asyncio.create_task(
|
|
||||||
self.run_loop(
|
|
||||||
form=form,
|
|
||||||
mod=mod,
|
|
||||||
track_id=track_id,
|
|
||||||
artist_name=artist_name,
|
|
||||||
track_name=track_name,
|
|
||||||
song_url=song_url,
|
|
||||||
lines=lines,
|
|
||||||
plain=plain,
|
|
||||||
not_synced_str=not_synced_str,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._active_tasks[track_id] = task
|
|
||||||
|
|
||||||
# Fan-fantasizing
|
|
||||||
# Fa-fa-fa-fantasizing
|
|
||||||
# You and I-I-I
|
|
||||||
# When I close my eyes (my eyes)
|
|
||||||
# Nothings real
|
|
||||||
# Fantasizing (fantasizing)
|
|
||||||
# Bout you and I
|
|
||||||
# Cos you only hit my line
|
|
||||||
# When you wanna waste time
|
|
||||||
# I know you're so busy
|
|
||||||
# But trust me baby I'm not blind (blind)
|
|
||||||
# Uh oh, you and I
|
|
||||||
# We could never be
|
|
||||||
# Uh oh you and I
|
|
||||||
# Cos we will never be
|
|
||||||
# Uh oh, you and I
|
|
||||||
# No, we will never be
|
|
||||||
# That pretty picture that I painted in my mind (mind)
|
|
||||||
# So tell me what (tell me, tell me)
|
|
||||||
# The view is like
|
|
||||||
# With your head in the clouds
|
|
||||||
# And tell me what (tell me, tell me)
|
|
||||||
# It feels like to be right all the time
|
|
||||||
# You say that you love me
|
|
||||||
# But you don't even love yourself (no)
|
|
||||||
# Wanna get in my head
|
|
||||||
# But I ain't gonna let you close (no)
|
|
||||||
# Tryna control me
|
|
||||||
# But I ain't gon' play your game
|
|
||||||
# No more
|
|
||||||
# No I won't
|
|
||||||
# When I close (when I close)
|
|
||||||
# My eyes (my eyes)
|
|
||||||
# Nothing's real (no)
|
|
||||||
# Fantasizing (fantasize)
|
|
||||||
# bout you-you-you-you-you
|
|
||||||
# You-you-you-you
|
|
||||||
# You-you-you-you
|
|
||||||
# You-you-you
|
|
||||||
# And I
|
|
||||||
# You-you-you-you-you-you-you
|
|
||||||
# You-you-you-you-you-you-you
|
|
||||||
# You-you-you-you-you
|
|
||||||
# And I
|
|
||||||
# This is the last time I tell you
|
|
||||||
# Don't come round my way if you're just gon' waste my time
|
|
||||||
# And no, I won't be there for the long run
|
|
||||||
# No, not I
|
|
||||||
# But you never get (never get)
|
|
||||||
# The message, do you?
|
|
||||||
# You never seem (never seem)
|
|
||||||
# To grip an understanding
|
|
||||||
# That you emulate a ghost
|
|
||||||
# I pointed out all of your flaws
|
|
||||||
# But you still came up with excuses for em all
|
|
||||||
# So typical (so typical)
|
|
||||||
# You know it all
|
|
||||||
# So of course, I'm the one that's wrong (right?)
|
|
||||||
# When I close my eyes
|
|
||||||
# Nothings real
|
|
||||||
# Fan- fantasize
|
|
||||||
# Fa-fa-fa-fa
|
|
||||||
# Fantasizing
|
|
||||||
# Fa-fantasizing bout you and I
|
|
||||||
Reference in New Issue
Block a user