Compare commits
2 Commits
update-sub
...
update-sub
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63975a968f | ||
|
|
a23affc8fb |
3
AmoreForever/amoremods/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|

|
||||||
|
# amoremods
|
||||||
|
My mods for userbot
|
||||||
53
AmoreForever/amoremods/abstract.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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)
|
||||||
33
AmoreForever/amoremods/activity.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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)
|
||||||
287
AmoreForever/amoremods/aeconv.py
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
225
AmoreForever/amoremods/alarm.py
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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("Не найдено!")
|
||||||
118
AmoreForever/amoremods/amethyste.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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}")
|
||||||
258
AmoreForever/amoremods/amoreinfo.py
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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"]},
|
||||||
|
)
|
||||||
473
AmoreForever/amoremods/animevoices.py
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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
|
||||||
283
AmoreForever/amoremods/autoprofile.py
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
# 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"
|
||||||
|
),
|
||||||
|
)
|
||||||
124
AmoreForever/amoremods/besafe.py
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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)
|
||||||
|
|
||||||
|
|
||||||
229
AmoreForever/amoremods/birthdaywish.py
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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"))
|
||||||
100
AmoreForever/amoremods/bull.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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}],
|
||||||
|
]
|
||||||
|
)
|
||||||
158
AmoreForever/amoremods/createlinks.py
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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))
|
||||||
73
AmoreForever/amoremods/dtwr.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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,
|
||||||
|
)
|
||||||
48
AmoreForever/amoremods/facts.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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,
|
||||||
|
)
|
||||||
67
AmoreForever/amoremods/figlet.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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)
|
||||||
48
AmoreForever/amoremods/fileext.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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"))
|
||||||
37
AmoreForever/amoremods/fragment_checker.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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>")
|
||||||
|
|
||||||
|
|
||||||
40
AmoreForever/amoremods/full.txt
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
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
|
||||||
91
AmoreForever/amoremods/funquotes.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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()
|
||||||
69
AmoreForever/amoremods/hacker.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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()
|
||||||
129
AmoreForever/amoremods/imgbb.py
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
# ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
# ⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠟⠛⠛⠛⠛⠛
|
||||||
|
# ⣶⣦⣤⣤⣤⣤⣤⣤⣬⣭⣭⣍⣉⡙⠛⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⣋⣩⣭⣥⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣶
|
||||||
|
# ⣆⠀⠀⠀⢡⠁⠀⡀⠀⢸⠟⠻⣯⠙⠛⠷⣶⣬⡙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢉⣥⣶⡟⠻⣙⡉⠀⢰⡆⠀⠀⣡⠀⣧⠀⠀⠀⢨
|
||||||
|
# ⠻⣦⠀⠀⠈⣇⣀⣧⣴⣿⣶⣶⣿⣷⠀⢀⡇⠉⠻⢶⣌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣡⡶⠟⠉⠀⢣⠀⣿⠷⠀⠀⠀⠀⣿⡷⢀⠇⠀⠀⢠⣿
|
||||||
|
# ⣦⡈⢧⡀⠀⠘⢮⡙⠛⠉⠀⠄⠙⢿⣀⠞⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠈⠳⣄⠉⠓⠒⠚⠋⢀⡠⠋⠀⢀⣴⣏⣿
|
||||||
|
# ⣿⣿⣿⣛⣦⣀⠀⠙⠓⠦⠤⣤⠔⠛⠁⠀⠀⠀⠀⠀⢀⣀⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣤⣤⣤⣤⣤⣀⣀⣀⣀⢙⢓⣒⡒⠚⠋⢠⣤⢶⣟⣽⣿⣿
|
||||||
|
# ⣿⣿⣿⣿⣿⣿⣷⣦⠀⠀⣴⣿⣷⣶⣶⣶⣾⡖⢰⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣾⣿⣿⣶⣾⣿⣿⣿⣿⣿⣿
|
||||||
|
# ⣿⣿⣿⣿⣿⣿⣿⣿⠀⢀⣿⣿⣿⣿⣿⣿⣿⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
# ⣿⣿⣿⣿⣿⣿⣿⡏⠀⢸⣿⣿⣿⣿⣿⣿⣿⠁⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
# ⣿⣿⣿⣿⣿⣿⣿⣷⠀⢸⣿⣿⣿⣿⣿⣿⣿⠀⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
|
||||||
|
# 🔒 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>")
|
||||||
83
AmoreForever/amoremods/inlineping.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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,
|
||||||
|
}
|
||||||
57
AmoreForever/amoremods/instsave.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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)
|
||||||
355
AmoreForever/amoremods/jutsu.py
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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_,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
],
|
||||||
|
)
|
||||||
155
AmoreForever/amoremods/leta.py
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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",
|
||||||
|
)
|
||||||
249
AmoreForever/amoremods/lexiwiz.py
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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))
|
||||||
|
)
|
||||||
27
AmoreForever/amoremods/my_usernames.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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]}")
|
||||||
296
AmoreForever/amoremods/mydiary.py
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
__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"]},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
31
AmoreForever/amoremods/nytimer.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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)
|
||||||
62
AmoreForever/amoremods/phsticker.py
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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)
|
||||||
88
AmoreForever/amoremods/poststealer.py
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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
|
||||||
80
AmoreForever/amoremods/recognition.py
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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")
|
||||||
34
AmoreForever/amoremods/searchpic.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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}"}
|
||||||
|
),
|
||||||
|
)
|
||||||
94
AmoreForever/amoremods/speech.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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)
|
||||||
|
|
||||||
70
AmoreForever/amoremods/telegraphup.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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
|
||||||
98
AmoreForever/amoremods/universaltime.py
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
# ⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠟⠛⠛⠛⠛⠛
|
||||||
|
# ⣶⣦⣤⣤⣤⣤⣤⣤⣬⣭⣭⣍⣉⡙⠛⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⣋⣩⣭⣥⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣶
|
||||||
|
# ⣆⠀⠀⠀⢡⠁⠀⡀⠀⢸⠟⠻⣯⠙⠛⠷⣶⣬⡙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢉⣥⣶⡟⠻⣙⡉⠀⢰⡆⠀⠀⣡⠀⣧⠀⠀⠀⢨
|
||||||
|
# ⠻⣦⠀⠀⠈⣇⣀⣧⣴⣿⣶⣶⣿⣷⠀⢀⡇⠉⠻⢶⣌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣡⡶⠟⠉⠀⢣⠀⣿⠷⠀⠀⠀⠀⣿⡷⢀⠇⠀⠀⢠⣿
|
||||||
|
# ⣦⡈⢧⡀⠀⠘⢮⡙⠛⠉⠀⠄⠙⢿⣀⠞⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠈⠳⣄⠉⠓⠒⠚⠋⢀⡠⠋⠀⢀⣴⣏⣿
|
||||||
|
# ⣿⣿⣿⣛⣦⣀⠀⠙⠓⠦⠤⣤⠔⠛⠁⠀⠀⠀⠀⠀⢀⣀⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣤⣤⣤⣤⣤⣀⣀⣀⣀⢙⢓⣒⡒⠚⠋⢠⣤⢶⣟⣽⣿⣿
|
||||||
|
# ⣿⣿⣿⣿⣿⣿⣷⣦⠀⠀⣴⣿⣷⣶⣶⣶⣾⡖⢰⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣾⣿⣿⣶⣾⣿⣿⣿⣿⣿⣿
|
||||||
|
# ⣿⣿⣿⣿⣿⣿⣿⣿⠀⢀⣿⣿⣿⣿⣿⣿⣿⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
# ⣿⣿⣿⣿⣿⣿⣿⡏⠀⢸⣿⣿⣿⣿⣿⣿⣿⠁⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
# ⣿⣿⣿⣿⣿⣿⣿⣷⠀⢸⣿⣿⣿⣿⣿⣿⣿⠀⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
|
||||||
|
# 🔒 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 ✨")
|
||||||
214
AmoreForever/amoremods/usernamestealer.py
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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()
|
||||||
|
|
||||||
134
AmoreForever/amoremods/wakatime.py
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# █ █ █ █▄▀ ▄▀█ █▀▄▀█ █▀█ █▀█ █ █
|
||||||
|
# █▀█ █ █ █ █▀█ █ ▀ █ █▄█ █▀▄ █▄█
|
||||||
|
|
||||||
|
# 🔒 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,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -37,7 +37,7 @@ from .. import utils, loader
|
|||||||
from ..types import BotInlineCall, InlineCall
|
from ..types import BotInlineCall, InlineCall
|
||||||
|
|
||||||
logger = logging.getLogger("Limoka")
|
logger = logging.getLogger("Limoka")
|
||||||
__version__ = (1, 5, 6)
|
__version__ = (1, 5, 5)
|
||||||
|
|
||||||
|
|
||||||
def _parse_version_from_source(source: str):
|
def _parse_version_from_source(source: str):
|
||||||
@@ -879,9 +879,6 @@ class Limoka(loader.Module):
|
|||||||
except (aiohttp.ClientError, asyncio.TimeoutError) as head_error:
|
except (aiohttp.ClientError, asyncio.TimeoutError) as head_error:
|
||||||
logger.debug(f"_validate_url: HEAD failed ({type(head_error).__name__}), will try GET for {url}")
|
logger.debug(f"_validate_url: HEAD failed ({type(head_error).__name__}), will try GET for {url}")
|
||||||
|
|
||||||
def _is_supported_media(content_type: str) -> bool:
|
|
||||||
return content_type.startswith("image/") or content_type.startswith("video/mp4")
|
|
||||||
|
|
||||||
# If HEAD didn't work or returned non-200, try GET
|
# If HEAD didn't work or returned non-200, try GET
|
||||||
if ct is None:
|
if ct is None:
|
||||||
max_retries = 2
|
max_retries = 2
|
||||||
@@ -900,7 +897,7 @@ class Limoka(loader.Module):
|
|||||||
try:
|
try:
|
||||||
data = await response.content.read(2048)
|
data = await response.content.read(2048)
|
||||||
mime = filetype.guess_mime(data, mime=True)
|
mime = filetype.guess_mime(data, mime=True)
|
||||||
if mime and _is_supported_media(mime):
|
if mime and mime.startswith("image/"):
|
||||||
return url
|
return url
|
||||||
else:
|
else:
|
||||||
self._invalid_banners.add(url)
|
self._invalid_banners.add(url)
|
||||||
@@ -916,7 +913,7 @@ class Limoka(loader.Module):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# Check Content-Type from successful request
|
# Check Content-Type from successful request
|
||||||
if ct and _is_supported_media(ct):
|
if ct and ct.startswith("image/"):
|
||||||
return url
|
return url
|
||||||
elif ct:
|
elif ct:
|
||||||
self._invalid_banners.add(url)
|
self._invalid_banners.add(url)
|
||||||
|
|||||||
@@ -523,10 +523,6 @@ class Limoka(loader.Module):
|
|||||||
async def _validate_url(self, url: str) -> Optional[str]:
|
async def _validate_url(self, url: str) -> Optional[str]:
|
||||||
if not url or url in self._invalid_banners:
|
if not url or url in self._invalid_banners:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _is_supported_media(content_type: str) -> bool:
|
|
||||||
return content_type.startswith("image/") or content_type.startswith("video/mp4")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.head(
|
async with session.head(
|
||||||
@@ -536,7 +532,7 @@ class Limoka(loader.Module):
|
|||||||
self._invalid_banners.add(url)
|
self._invalid_banners.add(url)
|
||||||
return None
|
return None
|
||||||
ct = response.headers.get("Content-Type", "").lower()
|
ct = response.headers.get("Content-Type", "").lower()
|
||||||
if not _is_supported_media(ct):
|
if not ct.startswith("image/"):
|
||||||
self._invalid_banners.add(url)
|
self._invalid_banners.add(url)
|
||||||
return None
|
return None
|
||||||
return url
|
return url
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
# requires: Pillow numpy
|
|
||||||
# meta developer: @SunnexGB
|
|
||||||
# meta banner: https://i.pinimg.com/control1/1200x/24/8d/40/248d40b6afa5bd3c3764556b50635691.jpg
|
|
||||||
__version__ = (1, 0, 0)
|
|
||||||
|
|
||||||
import io
|
|
||||||
import logging
|
|
||||||
from herokutl.types import Message
|
|
||||||
from .. import loader, utils
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
@loader.tds
|
|
||||||
class ASCII(loader.Module):
|
|
||||||
"""Convert images to braille ASCII"""
|
|
||||||
|
|
||||||
strings = {
|
|
||||||
"name": "ASCII",
|
|
||||||
"no_lib": "<tg-emoji emoji-id=5447385112612208213>🚫</tg-emoji> | <b>Library not loaded</b>",
|
|
||||||
"no_image": "<tg-emoji emoji-id=5447381715293074599>⚠️</tg-emoji> | <b>Reply to image</b>",
|
|
||||||
"processing": "<tg-emoji emoji-id=5445373981290952548>®️</tg-emoji> | <b>Processing...</b>",
|
|
||||||
"empty": "<tg-emoji emoji-id=5287613115180006030>🤬</tg-emoji> | <b>Empty result</b>",
|
|
||||||
"result": "<pre>{art}</pre>",
|
|
||||||
"Failed_to_load_library": "Failed to load library",
|
|
||||||
"Conversion_error": "Conversion error",
|
|
||||||
}
|
|
||||||
|
|
||||||
strings_ru = {
|
|
||||||
"_cls_doc": "Конвертирует картинку в braille ASCII",
|
|
||||||
"no_lib": "<tg-emoji emoji-id=5447385112612208213>🚫</tg-emoji> | <b>Библиотека не была загружена</b>",
|
|
||||||
"no_image": "<tg-emoji emoji-id=5447381715293074599>⚠️</tg-emoji> | <b>Ответьте на картинку</b>",
|
|
||||||
"processing": "<tg-emoji emoji-id=5445373981290952548>®️</tg-emoji> | <b>Обработка...</b>",
|
|
||||||
"empty": "<tg-emoji emoji-id=5287613115180006030>🤬</tg-emoji> | <b>Пустой результат</b>",
|
|
||||||
"result": "<pre>{art}</pre>",
|
|
||||||
"Failed_to_load_library": "Не удалось загрузить библиотеку",
|
|
||||||
"Conversion_error": "Ошибка конвертации",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = loader.ModuleConfig(
|
|
||||||
loader.ConfigValue("width", 50),
|
|
||||||
loader.ConfigValue("threshold", 0.65),
|
|
||||||
loader.ConfigValue("contrast", 2.0),
|
|
||||||
loader.ConfigValue("chars", 464),
|
|
||||||
loader.ConfigValue("invert", False),
|
|
||||||
)
|
|
||||||
self.lib = None
|
|
||||||
|
|
||||||
async def client_ready(self):
|
|
||||||
try:
|
|
||||||
self.lib = await self.import_lib("https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/refs/heads/main/Assets/ASCII/ascii-lib.py", suspend_on_error=True)
|
|
||||||
except Exception:
|
|
||||||
logger.exception(self.strings["Failed_to_load_library"])
|
|
||||||
self.lib = None
|
|
||||||
|
|
||||||
@loader.command(ru_doc="- Отрисовать ASCII-ART (аргумент -f, отправляет файлом)")
|
|
||||||
async def dotcmd(self, message: Message):
|
|
||||||
"""- Draw ASCII-ART (argument -f, sends as a file)"""
|
|
||||||
if not self.lib:
|
|
||||||
return await utils.answer(message, self.strings["no_lib"])
|
|
||||||
args = utils.get_args_raw(message)
|
|
||||||
force_file = "-f" in args.lower()
|
|
||||||
reply = await message.get_reply_message() or message
|
|
||||||
if not reply or not (
|
|
||||||
reply.photo
|
|
||||||
or (
|
|
||||||
reply.document
|
|
||||||
and str(getattr(reply.document, "mime_type", "")).startswith("image/")
|
|
||||||
)
|
|
||||||
):
|
|
||||||
return await utils.answer(message, self.strings["no_image"])
|
|
||||||
msg = await utils.answer(message, self.strings["processing"])
|
|
||||||
|
|
||||||
try:
|
|
||||||
image_bytes = await reply.download_media(bytes)
|
|
||||||
art = self.lib.convert(
|
|
||||||
image_bytes,
|
|
||||||
width=self.config["width"],
|
|
||||||
threshold=self.config["threshold"],
|
|
||||||
contrast_boost=self.config["contrast"],
|
|
||||||
invert=self.config["invert"],
|
|
||||||
target_chars=self.config["chars"],
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception(self.strings["Conversion_error"])
|
|
||||||
return await utils.answer(msg, f"<pre>{e}</pre>")
|
|
||||||
if not art or not art.strip():
|
|
||||||
return await utils.answer(msg, self.strings["empty"])
|
|
||||||
formatted_art = self.strings("result").format(art=art)
|
|
||||||
if force_file or len(formatted_art) > 4096:
|
|
||||||
file = io.BytesIO(art.encode("utf-8"))
|
|
||||||
file.name = "ascii.txt"
|
|
||||||
await message.client.send_file(message.peer_id, file)
|
|
||||||
await msg.delete()
|
|
||||||
else:
|
|
||||||
await utils.answer(msg, formatted_art)
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
# requires: Pillow numpy
|
|
||||||
# Дикие оправдания по поводу именно этого ассета а точнее кода в нем,честно я не знаю что сказать была попытка переписать JS на Py и как бы особых проблем не было,
|
|
||||||
# до момента пост-обработки на помощь я позвал Claude и он не решил мою проблему от слова совсем,так как в целом я своего рода призираю пилоу,а модуль мне хотелось
|
|
||||||
# написать я примерно вайб-кодил около 50 минут и я уверен из за этого будет возможно много проблем,в итоге благодаря немного копанию в коде,я нашел проблему и уже
|
|
||||||
# начал ее решать,НО я опять же вообще не понимал как сделать то что мне нужно,в интернете были сюрсы но будто бы тот или иной мне не подходили? Я не знаю почему я
|
|
||||||
# дропнул эту идею. Потом я стал искать в JS-е что там вообще можно сделать,в итоге я там импортировал модель какую то блядскую не нужную и опять впустую время
|
|
||||||
# потратил,думал что тут определено есть решение и снова пошел к ии,вывод опятьь 0 помощи,я не знаю почему я так вцепился лишь в 1 идею.Как бы я мог упростить все,
|
|
||||||
# даже наверное просто попросив какую то флагмен ии написать модуль и переписать его,но я уже на тот момент по моему мнению сделал много и не хотел ни каким образом
|
|
||||||
# оставлять это,поэтому через время я нашел сайты которые в целом давали возможность настраивать фильтр,была переделана логика(в целом ее переделал на 60 процентов
|
|
||||||
# клод,я просто убирал мусор который он испражнял.И вот дальше точно бред я убил более дня на решение проблем которые были решены мной,но результат мне не нравился
|
|
||||||
# И ОПЯТЬ я пошел просить помощи у гугла,потом понял что возможно даже будет легко(по факту легко,но я ленивый) пока искал,мне перехотелось и я уже потом пытался
|
|
||||||
# сделать режимы в модуле,что оказалось ужасом ведь они работали,но при возможности гармонично вписать их в код были конфликты И Я В ОЧЕРЕДНОЙ РАЗ ПОШЕЛ К ИИ,спойлер
|
|
||||||
# он не смог написать лучше чем я,в итоге я отбросил эту идею и думаю в целом никак больше не апдейтать модуль по крупному.
|
|
||||||
# Да это были оправдания,но зато какие!
|
|
||||||
import io
|
|
||||||
import numpy as np
|
|
||||||
from PIL import Image, ImageFilter, ImageEnhance, ImageOps
|
|
||||||
from .. import loader
|
|
||||||
|
|
||||||
BASE = 0x2800
|
|
||||||
INVERT_MAP = {chr(BASE + c): chr(BASE + (c ^ 0xFF)) for c in range(256)}
|
|
||||||
|
|
||||||
|
|
||||||
class AsciiLib(loader.Library):
|
|
||||||
developer = "@SunnexGB"
|
|
||||||
|
|
||||||
def resize(self, img):
|
|
||||||
if img.width > 768:
|
|
||||||
img = img.resize((768, int(img.height * 768 / img.width)), Image.LANCZOS)
|
|
||||||
w = img.width - img.width % 4
|
|
||||||
h = img.height - img.height % 4
|
|
||||||
if w != img.width or h != img.height:
|
|
||||||
img = img.resize((w, h), Image.LANCZOS)
|
|
||||||
return img
|
|
||||||
|
|
||||||
def mode(self, img, threshold, contrast):
|
|
||||||
gray = img.convert("L")
|
|
||||||
edges = ImageOps.invert(gray.filter(ImageFilter.FIND_EDGES))
|
|
||||||
contrast_img = ImageEnhance.Contrast(img).enhance(contrast).convert("L")
|
|
||||||
e = np.array(edges, dtype=np.float32) / 255.0
|
|
||||||
c = np.array(contrast_img, dtype=np.float32) / 255.0
|
|
||||||
blended = Image.fromarray((e * c * 255).astype(np.uint8), "L")
|
|
||||||
t = int(threshold * 255)
|
|
||||||
processed = blended.point(lambda p: 255 if p > t else 0, "L")
|
|
||||||
return processed, t
|
|
||||||
|
|
||||||
def braille(self, img, threshold, width):
|
|
||||||
cw = width * 2
|
|
||||||
o = -(-round(cw * img.height / img.width) // 4)
|
|
||||||
ch = 4 * o
|
|
||||||
px = np.array(img.resize((cw, ch), Image.LANCZOS).convert("L"))
|
|
||||||
order = [(0,0),(1,0),(2,0),(0,1),(1,1),(2,1),(3,0),(3,1)]
|
|
||||||
rows = []
|
|
||||||
for rs in range(0, ch, 4):
|
|
||||||
line = []
|
|
||||||
for cs in range(0, cw, 2):
|
|
||||||
grays = [
|
|
||||||
int(px[rs+dy, cs+dx]) if (rs+dy < ch and cs+dx < cw) else 255
|
|
||||||
for dy, dx in order
|
|
||||||
]
|
|
||||||
bits = list(reversed([1 if g < threshold else 0 for g in grays]))
|
|
||||||
code = int("".join(str(b) for b in bits), 2)
|
|
||||||
line.append(chr(BASE + code))
|
|
||||||
rows.append("".join(line))
|
|
||||||
return rows
|
|
||||||
|
|
||||||
def trim(self, lines):
|
|
||||||
blank = "\u2800"
|
|
||||||
while lines and all(c == blank for c in lines[0]):
|
|
||||||
lines = lines[1:]
|
|
||||||
while lines and all(c == blank for c in lines[-1]):
|
|
||||||
lines = lines[:-1]
|
|
||||||
if not lines:
|
|
||||||
return lines
|
|
||||||
left = min(next((i for i,c in enumerate(r) if c!=blank), len(r)) for r in lines)
|
|
||||||
right = min(next((i for i,c in enumerate(reversed(r)) if c!=blank), len(r)) for r in lines)
|
|
||||||
return [r[left: len(r)-right if right else len(r)] for r in lines]
|
|
||||||
|
|
||||||
def invert(self, lines):
|
|
||||||
return ["".join(INVERT_MAP.get(c,c) for c in l) for l in lines]
|
|
||||||
|
|
||||||
def fit(self, img, threshold, chars, width):
|
|
||||||
lo, hi = 5, 200
|
|
||||||
best = ""
|
|
||||||
for _ in range(14):
|
|
||||||
mid = (lo + hi)//2
|
|
||||||
lines = self.trim(self.braille(img, threshold, mid))
|
|
||||||
art = "\n".join(lines)
|
|
||||||
if len(art) <= chars:
|
|
||||||
best = art
|
|
||||||
lo = mid + 1
|
|
||||||
else:
|
|
||||||
hi = mid - 1
|
|
||||||
return best
|
|
||||||
|
|
||||||
def convert(self, data, width=50, threshold=0.65, contrast_boost=2.0, invert=False, target_chars=0):
|
|
||||||
buf = io.BytesIO(data)
|
|
||||||
img = Image.open(buf)
|
|
||||||
img.load()
|
|
||||||
buf.close()
|
|
||||||
img = img.convert("RGB")
|
|
||||||
img = self.resize(img)
|
|
||||||
processed, t = self.mode(img, threshold, contrast_boost)
|
|
||||||
if target_chars > 0:
|
|
||||||
art = self.fit(processed, t, target_chars, width)
|
|
||||||
else:
|
|
||||||
art = "\n".join(self.trim(self.braille(processed, t, width)))
|
|
||||||
if invert and art:
|
|
||||||
art = "\n".join(self.invert(art.split("\n")))
|
|
||||||
return art
|
|
||||||
@@ -1,832 +0,0 @@
|
|||||||
{
|
|
||||||
"prologue": [
|
|
||||||
{
|
|
||||||
"type": "label",
|
|
||||||
"name": "prologue"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_1",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_1",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_1.jpg?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Мне опять снился сон."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "<i>Этот</i> сон..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Каждую ночь одно и то же."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Но наутро, как обычно, всё забудется."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Может быть, оно и к лучшему..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Останутся только туманные воспоминания о приоткрытых, словно приглашающих куда-то воротах, рядом с которыми в камне застыли два пионера."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "А ещё странная девочка...{w} которая постоянно спрашивает:"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "bg",
|
|
||||||
"name": "anim_prolog1_off",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/anim_prolog1_off",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/anim_prolog1_off.gif?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "dialogue",
|
|
||||||
"char_id": "dreamgirl",
|
|
||||||
"character": "...",
|
|
||||||
"text": "Ты пойдёшь со мной?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Пойду?.."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Но куда?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "И зачем?.."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Да и где я вообще нахожусь?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Конечно, случись всё на самом деле, наяву, стоило бы непременно испугаться."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Как же иначе!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Но это – всего лишь сон.{w} Тот самый, который я вижу каждую ночь."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "А ведь всё это неспроста!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Необязательно знать <i>где</i> и <i>почему</i>, чтобы понять – что-то происходит."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Нечто, отчаянно требующее моего внимания."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Ведь всё окружающее меня здесь – реально!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Реально настолько, насколько реальны вещи в моей квартире; я бы мог открыть ворота, услышать скрип петель, смахнуть рукой осыпающуюся ржавчину, потянуть носом свежий прохладный воздух и поёжиться от холода."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Мог бы, но для этого надо сдвинуться с места, сделать шаг, пошевелить рукой..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "А ведь это сон – я понимаю, но что дальше, что изменит моё <i>понимание</i>?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Ведь здесь – словно по ту сторону потрескавшегося экрана старого телевизора, который из последних сил борется с помехами и силится показать зрителям всё, не упустив ни малейшей детали."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Но вот картинка теряет чёткость...{w} Наверное, скоро просыпаться."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Может быть, спросить у неё что-то?{w} У девочки."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Как же её зовут..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Например про звёзды..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Хотя почему про звёзды?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Можно же спросить про ворота!{w} Да, про ворота!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Вот она удивится."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Или лучше про букву <i>ё</i>."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Хорошая была буква..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Как будто её больше нет!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "И какое отношение буквы, ворота и звёзды имеют к этому месту?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Ведь если мне каждую ночь снится <i>этот</i> сон, который потом всё равно забудется, надо искать разгадку здесь и сейчас!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "А вот, если присмотреться, можно увидеть Магелланово Облако..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Словно попал в южное полушарие!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Во сне всегда больше волнуют мелочи: неестественный цвет травы, невозможная кривизна прямых или своё перекошенное отражение – а реальная опасность, готовая оборвать всё здесь и сейчас, кажется пустяком."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Естественно, ведь <i>здесь</i> нельзя умереть."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Я точно знаю – я делал это сотни раз."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Но если нельзя умереть, нет смысла жить?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Надо будет спросить у девочки: она местная – должна знать!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Да, именно!{w} Спросить, например, про сову."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Больно уж птица странная..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "А впрочем, неважно..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "dialogue",
|
|
||||||
"char_id": "dreamgirl",
|
|
||||||
"character": "...",
|
|
||||||
"text": "Ты пойдёшь со мной?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "И каждый раз надо отвечать."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Иначе никак, иначе сон не закончится, а я – не проснусь."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "route",
|
|
||||||
"id": "prologue_choice_1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Каждый раз так сложно решить, что же ответить."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Где я, что я здесь делаю, кто она такая?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "И почему от ответа на этот вопрос зависит так много в моей жизни?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Или не зависит?.."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Ведь это просто сон..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Просто сон..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "bg",
|
|
||||||
"name": "black",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "bg/black",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/bg/black.png?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "1_prologue",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "cg/p_kb_1",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/cg/p_kb_1.png?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "2_prologue",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "cg/p_kb_2",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/cg/p_kb_2.png?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "3_prologue",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "cg/p_kb_3",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/cg/p_kb_3.png?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "4_prologue",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "cg/p_kb_4",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/cg/p_kb_4.png?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "5_prologue",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "cg/p_kb_5",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/cg/p_kb_5.png?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Экран монитора смотрел на меня словно живой."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Иногда мне правда казалось, что он обладает сознанием, своими мыслями и желаниями, стремлениями; умеет чувствовать, любить и страдать."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Словно в наших отношениях инструмент не он – неодушевлённый кусок пластика и текстолита, – а я."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Наверное, в этом есть доля правды, ведь компьютер на 90% обеспечивает моё общение с внешним миром."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Анонимные имиджборды, иногда какие-то чаты, редко – аська или джаббер, ещё реже – форумы."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "А людей, сидящих по ту сторону сетевого кабеля, попросту не существует!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Все они – всего лишь плод его больной фантазии, ошибка в программном коде или баг ядра, зажившего собственной жизнью."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_15",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_15",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_15.png?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_3",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_3",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_3.png?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_4",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_4",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_4.png?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Если посмотреть со стороны на моё существование, то такие мысли покажутся не столь уж бредовыми, а какой-нибудь психолог наверняка поставит мне кучу заумных диагнозов и, возможно, выпишет направление в жёлтый дом."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_5",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_5",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_5.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_14",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_14",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_14.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_11",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_11",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_11.jpg?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Маленькая квартирка без следов какого бы то ни было ремонта или даже подобия порядка, и вечно одинаковый вид из окна на серый, день и ночь куда-то бегущий мегаполис, – вот условия моей жизни."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_2",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_2",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_2.jpg?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Конечно, всё начиналось не так..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Я родился, пошёл в школу, закончил её – всё как у людей."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Поступил в институт, где кое-как промучился полтора курса."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Работал на паре-тройке разных работ.{w} Иногда даже и неплохо, иногда даже получая за это достойные деньги."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Однако всё это казалось чужим, словно списанным с биографии другого человека."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Я не ощущал полноту жизни – она словно зациклилась и продолжала идти по кругу.{w} Как в фильме «День сурка»."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Только у меня не было выбора, как именно провести этот день, и каждый раз всё повторялось по одной и той же схеме.{w} Схеме пустоты, уныния и отчаяния."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Последние несколько лет я просто целыми днями сидел за компьютером."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Иногда подворачивались какие-то халтурки, иногда помогали родители."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "В общем, на жизнь хватало."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Это и немудрено, ведь потребности у меня небольшие."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "На улицу я практически не выхожу, а всё моё общение с людьми сводится к интернет-переписке с <i>анонимами</i>, у которых нет ни реального имени, ни пола, ни возраста."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Короче говоря, достаточно типичная жизнь достаточно типичного асоциального человека своего времени.{w} Этакий Обломов XXI века."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Может быть, маститый писатель напишет обо мне роман, который станет классикой современной литературы.{w} Или напишу я сам…"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Впрочем нет, что себя обманывать – уже не раз пытался, но меня не хватало даже на короткий рассказ."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Изучал я и множество других вещей."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Рисовать – не дано от природы.{w} Программирование – надоело.{w} Иностранные языки – долго и скучно…"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Любил я разве что читать, но даже при этом никогда бы не назвал себя эрудированным человеком."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Возможно, я был асом в просмотре аниме и гроссмейстером неумелых шуточек в интернете."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Плати мне за это деньги, я бы обрадовался (да и заработал неплохо), но вряд ли так просто можно заполнить пустоту в душе."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "bg",
|
|
||||||
"name": "semen_room_window",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "bg/semen_room_window",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/bg/semen_room_window.jpg?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Сегодня очередной типичный день моей типичной жизни типичного неудачника."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "И именно сегодня мне нужно ехать на встречу институтских товарищей."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "По правде говоря, совершенно не хотелось."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Да и какой смысл, если вместе с ними я отучился всего ничего?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Однако меня всё же уговорил друг, бывший одногруппник, один из немногих, с кем я поддерживал контакт не только в интернете."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_1",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_1",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_1.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_2",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_2",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_2.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_3",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_3",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_3.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_4",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_4",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_4.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_5",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_5",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_5.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_6",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_6",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_6.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_8",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_8",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_8.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_7",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_7",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_7.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "bg",
|
|
||||||
"name": "bus_stop",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "bg/bus_stop",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/bg/bus_stop.jpg?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Вечер. Мороз.{w} Остановка и ожидание автобуса."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Я никогда не любил зиму.{w} Впрочем, и жаркое лето – тоже не моя стихия."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Просто не вижу смысла выделять какое-то одно время года – не столь важно, какая погода на улице, если ты целыми днями сидишь дома."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Автобус сегодня задерживался так сильно, что я уже был готов плюнуть на всё и потратить последнюю пару сотен на такси (совсем не ехать мне почему-то в голову не пришло)."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "В мозгу, как всегда, роились миллионы мыслей, из которых совершенно невозможно выудить хотя бы одну стоящую."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Такую, которую можно закончить, привести в порядок, облечь в форму идеи и претворить в жизнь."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Может быть, заняться бизнесом?{w} Но откуда я возьму деньги?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Или пойти опять работать в офис?{w} Нет уж!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Может, стоит попробовать фриланс?{w} Да что я умею, и кому я нужен…"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "prolog_2",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/prolog_2",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/prolog_2.jpg?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Вдруг мне вспомнилось детство…{w} Или скорее юношество – 15-17 лет."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Почему именно это время?{w} Не знаю."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Наверное, потому что тогда всё было проще."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Было проще принимать такие сложные сейчас и такие простые тогда решения."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Проснувшись с утра, я чётко знал, как пройдёт мой день, а выходных ждал с нетерпением – смогу отдохнуть, заняться любимыми делами: компьютер, футбол, встречи с друзьями."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "А потом, когда наступит новая неделя, вновь примусь за учёбу."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Ведь раньше не возникало этих мучительных вопросов «зачем», «кому это надо», «что изменится, если я это сделаю» или «что не изменится»."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Простой поток жизни, такой привычный для любого нормального человека и такой чуждый для меня теперешнего."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Время беззаботного детства…{w} Тогда же я и встретил свою первую любовь."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Стёрлись из памяти её внешность, характер."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Как строчка из профиля в социальной сети осталось лишь имя, да те чувства, которые захлёстывали меня, когда я был с ней.{w} Теплота, нежность, желание заботиться, защитить…"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Жаль, что это продолжалось так недолго."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Сейчас я уже с трудом могу себе представить что-то подобное."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Наверное, и хочется познакомиться с девушкой, только не знаю, как начать диалог, о чём вообще с ней говорить, чем её заинтересовать."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Да и подходящих девушек я давно не встречал.{w} Хотя где мне их встретить…"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_9",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_9",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_9.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Звук работающего двигателя вернул меня к реальности."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Подъехал автобус."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "«Какой-то он не такой» – мелькнула мысль."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Впрочем, какая разница – по этому маршруту ходит только 410-ый."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_10",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_10",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_10.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_11",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_11",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_11.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "anim",
|
|
||||||
"name": "intro_13",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "anim/intro_13",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/anim/intro_13.jpg?raw=true",
|
|
||||||
"duration": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "bg",
|
|
||||||
"name": "intro_xx",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "bg/intro_xx",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/bg/intro_xx.jpg?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Огни пролетают мимо, их холодный свет словно зажигает внутри давно погасшие чувства."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Или не зажигает, а просто пробуждает…"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Ведь «они» уже давно живут во мне, то затихая, то просыпаясь вновь."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Какая-то очень известная мелодия играла в радиоприёмнике у водителя.{w} Но я её не слушал."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Я смотрел в запотевшее окно автобуса на проезжающие мимо машины."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Ведь люди куда-то спешат, ведь им что-то нужно, и, погружённые в свои дела, они не задумываются о вопросах, мучающих меня."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Наверное, у них тоже есть свои серьёзные проблемы, а может, им живётся куда легче."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Знать наверняка нельзя, так как все люди разные.{w} Или не разные?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Бывает, поступки человека легко предсказуемы, но, пытаясь заглянуть к нему в душу, видишь лишь непроглядную тьму."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "..."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Автобус приближался к центру, и мои мысли прервал яркий свет огней большого города."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Сотни рекламных вывесок, тысячи машин, миллионы людей."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Я смотрел на это светопреставление, и мне почему-то безумно захотелось спать."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "narration",
|
|
||||||
"text": "Глаза закрылись всего на полсекунды и…"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "scene",
|
|
||||||
"kind": "bg",
|
|
||||||
"name": "black",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "bg/black",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/images/1920/bg/int_bus_black.jpg?raw=true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opening",
|
|
||||||
"kind": "opening",
|
|
||||||
"name": "opening",
|
|
||||||
"action": "load_asset",
|
|
||||||
"location": "opening/opening",
|
|
||||||
"raw_url": "https://raw.githubusercontent.com/SunnexGB/Heroku-Modules/main/Assets/Everlasting_Summer/opening/opening.mp4?raw=true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
{
|
|
||||||
"prologue_choice_1": {
|
|
||||||
"question": "Иначе никак, иначе сон не закончится, а я – не проснусь. — что выбрать?",
|
|
||||||
"chapter": "prologue",
|
|
||||||
"options": {
|
|
||||||
"Да, я пойду с тобой": {
|
|
||||||
"effects": {}
|
|
||||||
},
|
|
||||||
"Нет, я останусь здесь": {
|
|
||||||
"effects": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"endings": {
|
|
||||||
"labels": [
|
|
||||||
"main_good_ending",
|
|
||||||
"main_bad_ending",
|
|
||||||
"sl_good_ending",
|
|
||||||
"sl_bad_ending",
|
|
||||||
"dv_good_ending",
|
|
||||||
"dv_bad_ending",
|
|
||||||
"un_good_ending",
|
|
||||||
"un_bad_ending",
|
|
||||||
"us_good_ending",
|
|
||||||
"us_bad_ending",
|
|
||||||
"mi_ending",
|
|
||||||
"uv_ending",
|
|
||||||
"harem_ending"
|
|
||||||
],
|
|
||||||
"routes": {
|
|
||||||
"sl": {
|
|
||||||
"good": "sl_good_ending",
|
|
||||||
"bad": "sl_bad_ending",
|
|
||||||
"point_key": "sl_points"
|
|
||||||
},
|
|
||||||
"dv": {
|
|
||||||
"good": "dv_good_ending",
|
|
||||||
"bad": "dv_bad_ending",
|
|
||||||
"point_key": "dv_points"
|
|
||||||
},
|
|
||||||
"un": {
|
|
||||||
"good": "un_good_ending",
|
|
||||||
"bad": "un_bad_ending",
|
|
||||||
"point_key": "un_points"
|
|
||||||
},
|
|
||||||
"us": {
|
|
||||||
"good": "us_good_ending",
|
|
||||||
"bad": "us_bad_ending",
|
|
||||||
"point_key": "us_points"
|
|
||||||
},
|
|
||||||
"mi": {
|
|
||||||
"single": "mi_ending",
|
|
||||||
"point_key": "mi_points"
|
|
||||||
},
|
|
||||||
"uv": {
|
|
||||||
"single": "uv_ending",
|
|
||||||
"point_key": "uv_points"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fallback": "main_bad_ending"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 5.2 MiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 267 KiB |
|
Before Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 341 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 288 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 394 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 240 KiB |
|
Before Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 519 KiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 569 KiB |
|
Before Width: | Height: | Size: 436 KiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 268 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 290 KiB |
|
Before Width: | Height: | Size: 317 KiB |
|
Before Width: | Height: | Size: 294 KiB |
|
Before Width: | Height: | Size: 297 KiB |
|
Before Width: | Height: | Size: 301 KiB |
|
Before Width: | Height: | Size: 302 KiB |
|
Before Width: | Height: | Size: 305 KiB |
|
Before Width: | Height: | Size: 307 KiB |
|
Before Width: | Height: | Size: 309 KiB |
|
Before Width: | Height: | Size: 313 KiB |
|
Before Width: | Height: | Size: 281 KiB |
@@ -1,400 +0,0 @@
|
|||||||
2g1c
|
|
||||||
2 girls 1 cup
|
|
||||||
acrotomophilia
|
|
||||||
alabama hot pocket
|
|
||||||
alaskan pipeline
|
|
||||||
anal
|
|
||||||
anilingus
|
|
||||||
anus
|
|
||||||
apeshit
|
|
||||||
arsehole
|
|
||||||
ass
|
|
||||||
asshole
|
|
||||||
assmunch
|
|
||||||
auto erotic
|
|
||||||
autoerotic
|
|
||||||
babeland
|
|
||||||
baby batter
|
|
||||||
baby juice
|
|
||||||
ball gag
|
|
||||||
ball gravy
|
|
||||||
ball kicking
|
|
||||||
ball licking
|
|
||||||
ball sack
|
|
||||||
ball sucking
|
|
||||||
bangbros
|
|
||||||
bangbus
|
|
||||||
bareback
|
|
||||||
barely legal
|
|
||||||
barenaked
|
|
||||||
bastard
|
|
||||||
bastardo
|
|
||||||
bastinado
|
|
||||||
bbw
|
|
||||||
bdsm
|
|
||||||
beaner
|
|
||||||
beaners
|
|
||||||
beaver cleaver
|
|
||||||
beaver lips
|
|
||||||
beastiality
|
|
||||||
bestiality
|
|
||||||
big black
|
|
||||||
big breasts
|
|
||||||
big knockers
|
|
||||||
big tits
|
|
||||||
bimbos
|
|
||||||
birdlock
|
|
||||||
bitch
|
|
||||||
bitches
|
|
||||||
black cock
|
|
||||||
blonde action
|
|
||||||
blonde on blonde action
|
|
||||||
blowjob
|
|
||||||
blow job
|
|
||||||
blow your load
|
|
||||||
blue waffle
|
|
||||||
blumpkin
|
|
||||||
bollocks
|
|
||||||
bondage
|
|
||||||
boner
|
|
||||||
boob
|
|
||||||
boobs
|
|
||||||
booty call
|
|
||||||
brown showers
|
|
||||||
brunette action
|
|
||||||
bukkake
|
|
||||||
bulldyke
|
|
||||||
bullet vibe
|
|
||||||
bullshit
|
|
||||||
bung hole
|
|
||||||
bunghole
|
|
||||||
busty
|
|
||||||
butt
|
|
||||||
buttcheeks
|
|
||||||
butthole
|
|
||||||
camel toe
|
|
||||||
camgirl
|
|
||||||
camslut
|
|
||||||
camwhore
|
|
||||||
carpet muncher
|
|
||||||
carpetmuncher
|
|
||||||
chocolate rosebuds
|
|
||||||
cialis
|
|
||||||
circlejerk
|
|
||||||
cleveland steamer
|
|
||||||
clit
|
|
||||||
clitoris
|
|
||||||
clover clamps
|
|
||||||
clusterfuck
|
|
||||||
cock
|
|
||||||
cocks
|
|
||||||
coprolagnia
|
|
||||||
coprophilia
|
|
||||||
cornhole
|
|
||||||
coon
|
|
||||||
coons
|
|
||||||
creampie
|
|
||||||
cum
|
|
||||||
cumming
|
|
||||||
cumshot
|
|
||||||
cumshots
|
|
||||||
cunnilingus
|
|
||||||
cunt
|
|
||||||
darkie
|
|
||||||
date rape
|
|
||||||
daterape
|
|
||||||
deep throat
|
|
||||||
deepthroat
|
|
||||||
dendrophilia
|
|
||||||
dick
|
|
||||||
dildo
|
|
||||||
dingleberry
|
|
||||||
dingleberries
|
|
||||||
dirty pillows
|
|
||||||
dirty sanchez
|
|
||||||
doggie style
|
|
||||||
doggiestyle
|
|
||||||
doggy style
|
|
||||||
doggystyle
|
|
||||||
dog style
|
|
||||||
dolcett
|
|
||||||
domination
|
|
||||||
dominatrix
|
|
||||||
dommes
|
|
||||||
donkey punch
|
|
||||||
double dong
|
|
||||||
double penetration
|
|
||||||
dp action
|
|
||||||
dry hump
|
|
||||||
dvda
|
|
||||||
eat my ass
|
|
||||||
ecchi
|
|
||||||
ejaculation
|
|
||||||
erotic
|
|
||||||
erotism
|
|
||||||
escort
|
|
||||||
eunuch
|
|
||||||
fag
|
|
||||||
faggot
|
|
||||||
fecal
|
|
||||||
felch
|
|
||||||
fellatio
|
|
||||||
feltch
|
|
||||||
female squirting
|
|
||||||
femdom
|
|
||||||
figging
|
|
||||||
fingerbang
|
|
||||||
fingering
|
|
||||||
fisting
|
|
||||||
foot fetish
|
|
||||||
footjob
|
|
||||||
frotting
|
|
||||||
fuck
|
|
||||||
fuck buttons
|
|
||||||
fuckin
|
|
||||||
fucking
|
|
||||||
fucktards
|
|
||||||
fudge packer
|
|
||||||
fudgepacker
|
|
||||||
futanari
|
|
||||||
gangbang
|
|
||||||
gang bang
|
|
||||||
gay sex
|
|
||||||
genitals
|
|
||||||
giant cock
|
|
||||||
girl on
|
|
||||||
girl on top
|
|
||||||
girls gone wild
|
|
||||||
goatcx
|
|
||||||
goatse
|
|
||||||
god damn
|
|
||||||
gokkun
|
|
||||||
golden shower
|
|
||||||
goodpoop
|
|
||||||
goo girl
|
|
||||||
goregasm
|
|
||||||
grope
|
|
||||||
group sex
|
|
||||||
g-spot
|
|
||||||
guro
|
|
||||||
hand job
|
|
||||||
handjob
|
|
||||||
hard core
|
|
||||||
hardcore
|
|
||||||
hentai
|
|
||||||
homoerotic
|
|
||||||
honkey
|
|
||||||
hooker
|
|
||||||
horny
|
|
||||||
hot carl
|
|
||||||
hot chick
|
|
||||||
how to kill
|
|
||||||
how to murder
|
|
||||||
huge fat
|
|
||||||
humping
|
|
||||||
incest
|
|
||||||
intercourse
|
|
||||||
jack off
|
|
||||||
jail bait
|
|
||||||
jailbait
|
|
||||||
jelly donut
|
|
||||||
jerk off
|
|
||||||
jigaboo
|
|
||||||
jiggaboo
|
|
||||||
jiggerboo
|
|
||||||
jizz
|
|
||||||
juggs
|
|
||||||
kike
|
|
||||||
kinbaku
|
|
||||||
kinkster
|
|
||||||
kinky
|
|
||||||
knobbing
|
|
||||||
leather restraint
|
|
||||||
leather straight jacket
|
|
||||||
lemon party
|
|
||||||
livesex
|
|
||||||
lolita
|
|
||||||
lovemaking
|
|
||||||
make me come
|
|
||||||
male squirting
|
|
||||||
masturbate
|
|
||||||
masturbating
|
|
||||||
masturbation
|
|
||||||
menage a trois
|
|
||||||
milf
|
|
||||||
missionary position
|
|
||||||
mong
|
|
||||||
motherfucker
|
|
||||||
mound of venus
|
|
||||||
mr hands
|
|
||||||
muff diver
|
|
||||||
muffdiving
|
|
||||||
nambla
|
|
||||||
nawashi
|
|
||||||
negro
|
|
||||||
neonazi
|
|
||||||
nigga
|
|
||||||
nigger
|
|
||||||
nig nog
|
|
||||||
nimphomania
|
|
||||||
nipple
|
|
||||||
nipples
|
|
||||||
nsfw
|
|
||||||
nsfw images
|
|
||||||
nude
|
|
||||||
nudity
|
|
||||||
nutten
|
|
||||||
nympho
|
|
||||||
nymphomania
|
|
||||||
octopussy
|
|
||||||
omorashi
|
|
||||||
one cup two girls
|
|
||||||
one guy one jar
|
|
||||||
orgasm
|
|
||||||
orgy
|
|
||||||
paedophile
|
|
||||||
paki
|
|
||||||
panties
|
|
||||||
panty
|
|
||||||
pedobear
|
|
||||||
pedophile
|
|
||||||
pegging
|
|
||||||
penis
|
|
||||||
phone sex
|
|
||||||
piece of shit
|
|
||||||
pikey
|
|
||||||
pissing
|
|
||||||
piss pig
|
|
||||||
pisspig
|
|
||||||
playboy
|
|
||||||
pleasure chest
|
|
||||||
pole smoker
|
|
||||||
ponyplay
|
|
||||||
poof
|
|
||||||
poon
|
|
||||||
poontang
|
|
||||||
punany
|
|
||||||
poop chute
|
|
||||||
poopchute
|
|
||||||
porn
|
|
||||||
porno
|
|
||||||
pornography
|
|
||||||
prince albert piercing
|
|
||||||
pthc
|
|
||||||
pubes
|
|
||||||
pussy
|
|
||||||
queaf
|
|
||||||
queef
|
|
||||||
quim
|
|
||||||
raghead
|
|
||||||
raging boner
|
|
||||||
rape
|
|
||||||
raping
|
|
||||||
rapist
|
|
||||||
rectum
|
|
||||||
reverse cowgirl
|
|
||||||
rimjob
|
|
||||||
rimming
|
|
||||||
rosy palm
|
|
||||||
rosy palm and her 5 sisters
|
|
||||||
rusty trombone
|
|
||||||
sadism
|
|
||||||
santorum
|
|
||||||
scat
|
|
||||||
schlong
|
|
||||||
scissoring
|
|
||||||
semen
|
|
||||||
sex
|
|
||||||
sexcam
|
|
||||||
sexo
|
|
||||||
sexy
|
|
||||||
sexual
|
|
||||||
sexually
|
|
||||||
sexuality
|
|
||||||
shaved beaver
|
|
||||||
shaved pussy
|
|
||||||
shemale
|
|
||||||
shibari
|
|
||||||
shit
|
|
||||||
shitblimp
|
|
||||||
shitty
|
|
||||||
shota
|
|
||||||
shrimping
|
|
||||||
skeet
|
|
||||||
slanteye
|
|
||||||
slut
|
|
||||||
s&m
|
|
||||||
smut
|
|
||||||
snatch
|
|
||||||
snowballing
|
|
||||||
sodomize
|
|
||||||
sodomy
|
|
||||||
spastic
|
|
||||||
spic
|
|
||||||
splooge
|
|
||||||
splooge moose
|
|
||||||
spooge
|
|
||||||
spread legs
|
|
||||||
spunk
|
|
||||||
strap on
|
|
||||||
strapon
|
|
||||||
strappado
|
|
||||||
strip club
|
|
||||||
style doggy
|
|
||||||
suck
|
|
||||||
sucks
|
|
||||||
suicide girls
|
|
||||||
sultry women
|
|
||||||
swastika
|
|
||||||
swinger
|
|
||||||
tainted love
|
|
||||||
taste my
|
|
||||||
tea bagging
|
|
||||||
threesome
|
|
||||||
throating
|
|
||||||
thumbzilla
|
|
||||||
tied up
|
|
||||||
tight white
|
|
||||||
tit
|
|
||||||
tits
|
|
||||||
titties
|
|
||||||
titty
|
|
||||||
tongue in a
|
|
||||||
topless
|
|
||||||
tosser
|
|
||||||
towelhead
|
|
||||||
tranny
|
|
||||||
tribadism
|
|
||||||
tub girl
|
|
||||||
tubgirl
|
|
||||||
tushy
|
|
||||||
twat
|
|
||||||
twink
|
|
||||||
twinkie
|
|
||||||
two girls one cup
|
|
||||||
undressing
|
|
||||||
upskirt
|
|
||||||
urethra play
|
|
||||||
urophilia
|
|
||||||
vagina
|
|
||||||
venus mound
|
|
||||||
viagra
|
|
||||||
vibrator
|
|
||||||
violet wand
|
|
||||||
vorarephilia
|
|
||||||
voyeur
|
|
||||||
voyeurweb
|
|
||||||
voyuer
|
|
||||||
vulva
|
|
||||||
wank
|
|
||||||
wetback
|
|
||||||
wet dream
|
|
||||||
white power
|
|
||||||
whore
|
|
||||||
worldsex
|
|
||||||
wrapping men
|
|
||||||
wrinkled starfish
|
|
||||||
yaoi
|
|
||||||
yellow showers
|
|
||||||
yiffy
|
|
||||||
zoophilia
|
|
||||||
|
Before Width: | Height: | Size: 609 B |
|
Before Width: | Height: | Size: 609 B |
@@ -1,3 +0,0 @@
|
|||||||
<svg width="30" height="22" viewBox="0 0 30 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M24.5455 5.5L19.0909 11H23.1818C23.1818 15.5512 19.5136 19.25 15 19.25C13.6227 19.25 12.3136 18.9062 11.1818 18.2875L9.19091 20.295C10.8682 21.3675 12.8591 22 15 22C21.0273 22 25.9091 17.0775 25.9091 11H30L24.5455 5.5ZM6.81818 11C6.81818 6.44875 10.4864 2.75 15 2.75C16.3773 2.75 17.6864 3.09375 18.8182 3.7125L20.8091 1.705C19.1318 0.6325 17.1409 0 15 0C8.97273 0 4.09091 4.9225 4.09091 11H0L5.45455 16.5L10.9091 11H6.81818Z" fill="white"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 554 B |
@@ -1,3 +0,0 @@
|
|||||||
<svg width="23" height="25" viewBox="0 0 23 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M12.6389 10.05H17.3611M7.91667 5.65H17.3611M21.25 17.75V6.75C21.25 3.45 19.5833 1.25 15.6944 1.25H6.80555C2.91667 1.25 1.25 3.45 1.25 6.75V17.75C1.25 21.05 2.91667 23.25 6.80555 23.25H15.6944C19.5833 23.25 21.25 21.05 21.25 17.75ZM15.1389 23.25V14.604C15.1389 14.12 14.5611 13.878 14.2056 14.197L11.6278 16.551C11.4167 16.749 11.0833 16.749 10.8722 16.551L8.29448 14.197C7.93893 13.878 7.36112 14.12 7.36112 14.604V23.25H15.1389Z" stroke="white" stroke-width="2.5"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 579 B |
@@ -1,3 +0,0 @@
|
|||||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M18.3333 7.33333C16.2381 7.33333 14.6667 5.76191 14.6667 3.66667C14.6667 1.57143 16.2381 0 18.3333 0C20.4286 0 22 1.57143 22 3.66667C22 5.76191 20.4286 7.33333 18.3333 7.33333ZM3.66667 14.6667C1.57143 14.6667 0 13.0952 0 11C0 8.90476 1.57143 7.33333 3.66667 7.33333C5.76191 7.33333 7.33333 8.90476 7.33333 11C7.33333 13.0952 5.76191 14.6667 3.66667 14.6667ZM18.3333 22C16.2381 22 14.6667 20.4286 14.6667 18.3333C14.6667 16.2381 16.2381 14.6667 18.3333 14.6667C20.4286 14.6667 22 16.2381 22 18.3333C22 20.4286 20.4286 22 18.3333 22ZM4.1381 10.0676L18.8048 17.401L17.8724 19.2762L3.20571 11.9429L4.1381 10.0676ZM18.8048 4.59905L4.1381 11.9324L3.20571 10.0571L17.8724 2.72381L18.8048 4.59905Z" fill="white"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 817 B |
|
Before Width: | Height: | Size: 539 B |