Commited backup

This commit is contained in:
2025-07-10 21:02:34 +03:00
parent 952c1001e3
commit da0b80823e
1310 changed files with 254133 additions and 41 deletions

View File

@@ -0,0 +1,129 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

View File

@@ -0,0 +1,132 @@
__version__ = (1, 3, 0)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/AntiMat.jpg
# meta developer: @AstroModules
from telethon.tl.types import Message
from .. import loader, utils
class AntiMatMod(loader.Module):
'''Будьте культурным человеком, не материтесь'''
strings = {
"name": "Анти-Мат",
"am_on": "🤬 <b>Антимат включен.</b>",
"am_off": "🤬 <b>Антимат отключен.</b>",
"action_text": "Какое действие выполнять при обнаружении мата в сообщении?",
"list_txt": "Здесь вы можете добавить свои маты.\np.s.: добавляйте по одному мату",
"added": "<b><emoji document_id=5030749344752468962></emoji> Чат успешно добавлен в антимат систему</b>",
"uadded": "<b><emoji document_id=5033287275287413303>🗑</emoji> Чат успешно удален из системы антимат</b>",
}
async def client_ready(self):
self.chats = self.get("active", [])
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"list",
"хер, хрен, хуй, пизда, бля, пох, еблан, еба, шлюха, сука, уебан, пздц, пиздец, пиздос, хую, долбоеб, пидор, гандон, хуя",
doc=lambda: self.strings("list_txt"),
validator=loader.validators.Series()
),
)
@loader.command()
async def antimat(self, message: Message):
'''- активировать или диактивировать АнтиМат'''
antimat = self.db.get(
"am_status",
"antimat",
)
if antimat == "":
self.db.set("am_status", "antimat", False)
if antimat == False:
self.db.set("am_status", "antimat", True)
await utils.answer(message, self.strings("am_on"))
else:
self.db.set("am_status", "antimat", False)
await utils.answer(message, self.strings("am_off"))
@loader.command()
async def matlist(self, message: Message):
"""- открыть список матов"""
await self.allmodules.commands["config"](
await utils.answer(message, f"{self.get_prefix()}config Анти-Мат")
)
@loader.command()
async def amchatcmd(self, message: Message):
"""- запретить/разрешить чату выражаться нецензурой"""
amc = str(utils.get_chat_id(message))
if amc in self.chats:
self.chats.remove(amc)
await utils.answer(message, self.strings("uadded"))
else:
self.chats += [amc]
await utils.answer(message, self.strings("added"))
self.set("active", self.chats)
@loader.watcher()
async def watcher_out(self, message: Message):
if getattr(message, "out", True):
return
cid = str(utils.get_chat_id(message))
txt = message.text
antimat = self.db.get(
"am_status",
"antimat",
)
mats = self.config['list']
if antimat:
if cid in self.chats:
for mat in mats:
m = txt.lower().find(mat)
if m != -1:
await utils.answer(message, "<emoji document_id=5213285132709929474>🤬</emoji> <b>Не матерись!</b>")
@loader.watcher()
async def watcher_in(self, message: Message):
if not getattr(message, "out", True):
return
txt: str = message.text
antimat = self.db.get(
"am_status",
"antimat",
)
mats = self.config['list']
if antimat:
for mat in mats:
m = txt.lower().find(mat)
if m != -1:
await message.edit("<emoji document_id=5213285132709929474>🤬</emoji> <b>Не матерись!</b>")

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@@ -0,0 +1,351 @@
__version__ = (2, 0, 0)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/Compliments.jpg
import asyncio
import logging
from telethon.tl.types import Message
from .. import loader, main, utils
logger = logging.getLogger(__name__)
class ComplimentsMod(loader.Module):
'''Покажи девушке какая она прекрасная (ну или им, какие они прекрасные)'''
strings = {
"name": "Compliments",
"_cfg_doc_for_one_or_more": (
"Выберите пожалуйста, комплименты будут для 1 человека женского пола, или"
" для всех людей женского пола в чате \nЕсли для 1 человека--> one\nЕсли"
" для всех людей женского пола в чате--> more"
),
"_cfg_doc_command_mode": (
"Выберите пожалуйста режим команды, какая будет анимация: \n Если вы"
" хотите, чтобы печатался список комплиментов --> 1 \n Если вы хотите,"
" чтобы каждую секунду комплимент заменялся на другой и в конце вывелся"
" полный список --> 2"
),
}
def __init__(self):
self._ratelimit = []
self.config = loader.ModuleConfig(
loader.ConfigValue(
"for_one_or_more",
"one",
doc=lambda: self.strings("_cfg_doc_for_one_or_more"),
validator=loader.validators.Choice(["one", "more"]),
),
loader.ConfigValue(
"command_mode",
1,
doc=lambda: self.strings("_cfg_doc_command_mode"),
validator=loader.validators.Choice([1, 2]),
),
)
async def inline_compliments(self, message: Message):
om = self.config["for_one_or_more"]
mode = self.config["command_mode"]
if om == "one":
if mode == 1:
messages = [
"Ты...прекрасная, а еще.... ",
"{♡} красивая 🌺 ",
"🪴заботливая~~ ",
"^0^ добрая 👐 ",
"👩🏻‍🎓умная $>$ ",
"~~трогательная 👉👈 ",
"🙀 изумительная 😍 ",
"🤯 офигенная и офигительная 🤠 ",
"🥵 игривая 😜 ",
"~♡~ прелестная 🌹 ",
"😍 восторженная 🤭 ",
"~~мечтательная ☁️ ",
"💋 особенно понимающая 🫂 ",
"👥 дружелюбная 🗣 ",
"😌 искренняя ♡ ",
"🙈 безупречная ",
"😋 сладенькая) ",
"😊 ласковая ",
"😻 симпатичная ",
"🦄 сказочная ",
"👌 разносторонняя ",
"🤔 креативная ",
"🌚 весёлая ",
"🌸 обалденная ",
"🤜🤛 крутая ",
"✨ яркая ",
"🐱 ангельская ",
"🔮 божественная ",
"💘 шикарная ",
"🙂 незабываемая ",
"😎 неповторимая ",
"🧸 очаровательная ",
"🥺 милая ",
"😍 ахуенная ",
"🍬 привлекательная ",
"И САМАЯ ЛУЧШАЯ НА СВЕТЕ❤️❤️❤️❤️❤️❤️❤️❤️",
]
current = ""
for i in messages:
current += i + "\n"
message = await utils.answer(message, current)
await asyncio.sleep(0.5)
await utils.answer(message, f"<i>{current}</i>")
elif mode == 2:
await utils.answer(message, "<i>Ты......</i>")
await asyncio.sleep(1)
await utils.answer(message, "<i>Ты...прекрасная...</i>")
await asyncio.sleep(1)
await utils.answer(message, "<i>Ты...прекрасная, а еще....</i>")
await asyncio.sleep(1)
messages = [
"{♡} красивая 🌺",
"🪴заботливая~~",
"^0^ добрая 👐",
"👩🏻‍🎓умная $>$",
"~~трогательная 👉👈",
"🙀 изумительная 😍",
"🤯 офигенная и офигительная 🤠",
"🥵 игривая 😜",
"~♡~ прелестная 🌹",
"😍 восторженная 🤭",
"~~мечтательная ☁️",
"💋 особенно понимающая 🫂",
"👥 дружелюбная 🗣",
"😌 искренняя",
"🙈 безупречная",
"😋 сладенькая)",
"😊 ласковая",
"😻 симпатичная",
"🦄 сказочная",
"👌 разносторонняя",
"🤔 креативная",
"🌚 весёлая",
"🌸 обалденная",
"🤜🤛 крутая",
"✨ яркая",
"🐱 ангельская",
"🔮 божественная",
"💘 шикарная",
"🙂 незабываемая",
"😎 неповторимая",
"🧸 очаровательная",
"🥺 милая",
"😍 ахуенная",
"🍬 привлекательная",
]
for m in messages:
message = await utils.answer(
message,
f"<i>Ты...прекрасная, а еще....\n{m}</i>",
)
await asyncio.sleep(1)
all_ = "\n".join(messages)
await utils.answer(
message,
f"<b><i>Ты...прекрасная, а еще.... \n{all_}\nИ САМАЯ ЛУЧШАЯ НА"
" СВЕТЕ❤️❤️❤️❤️❤️❤️❤️❤️</i></b>",
)
else:
await utils.answer(
message,
"К сожалению, произошла ошибка... \nА именно, эта ошибка произошла"
" потому что в конфиге неправильное значение. \nНапишите"
" <code>.complimentscfg</code>",
)
elif om == "more":
if mode == 1:
await utils.answer(message, "<i>Каждая девушка/девочка/женщина...</i>")
await asyncio.sleep(0.5)
await utils.answer(
message, "<i>Каждая девушка/девочка/женщина в этом чате...</i>"
)
await asyncio.sleep(0.5)
await utils.answer(
message,
"<i>ТКаждая девушка/девочка/женщина в этом чате прекрасна...</i>",
)
messages = [
"{♡} красивая 🌺",
"🪴заботливая~~",
"^0^ добрая 👐",
"👩🏻‍🎓умная $>$",
"~~трогательная 👉👈",
"🙀 изумительная 😍",
"🤯 офигенная и офигительная 🤠",
"🥵 игривая 😜",
"~♡~ прелестная 🌹",
"😍 восторженная 🤭",
"~~мечтательная ☁️",
"💋 особенно понимающая 🫂",
"👥 дружелюбная 🗣",
"😌 искренняя ♡",
"🙈 безупречная",
"😋 сладенькая)",
"😊 ласковая",
"😻 симпатичная",
"🦄 сказочная",
"👌 разносторонняя",
"🤔 креативная",
"🌚 весёлая",
"🌸 обалденная",
"🤜🤛 крутая",
"✨ яркая",
"🐱 ангельская",
"🔮 божественная",
"💘 шикарная",
"🙂 незабываемая",
"😎 неповторимая",
"🧸 очаровательная",
"🥺 милая",
"😍 ахуенная",
"🍬 привлекательная",
]
for m in messages:
message = await utils.answer(
message,
"<i>Каждая девушка/девочка/женщина в этом чате прекрасна..."
f" еще, каждая из них...\n{m}</i>",
)
await asyncio.sleep(0.5)
all_ = "\n".join(messages)
await utils.answer(
message,
"<b><i>Каждая девушка/девочка/женщина в этом чате прекрасна.... еще"
f" каждая из них: \n{all_}\nИ САМАЯ ЛУЧШАЯ НА"
" СВЕТЕ❤️❤️❤️❤️❤️❤️❤️❤️</i></b>",
)
elif mode == 2:
await utils.answer(message, "<i>Каждая девушка/девочка/женщина...</i>")
await asyncio.sleep(1)
await utils.answer(
message,
"<i>Каждая девушка/девочка/женщина в этом чате прекрасна...</i>",
)
await asyncio.sleep(1)
await utils.answer(
message,
"<i>Каждая девушка/девочка/женщина в этом чате прекрасна... еще"
" каждая из них:</i>",
)
await asyncio.sleep(1)
messages = [
"{♡} красивая 🌺",
"🪴заботливая~~",
"^0^ добрая 👐",
"👩🏻‍🎓умная $>$",
"~~трогательная 👉👈",
"🙀 изумительная 😍",
"🤯 офигенная и офигительная 🤠",
"🥵 игривая 😜",
"~♡~ прелестная 🌹",
"😍 восторженная 🤭",
"~~мечтательная ☁️",
"💋 особенно понимающая 🫂",
"👥 дружелюбная 🗣",
"😌 искренняя",
"🙈 безупречная",
"😋 сладенькая)",
"😊 ласковая",
"😻 симпатичная",
"🦄 сказочная",
"👌 разносторонняя",
"🤔 креативная",
"🌚 весёлая",
"🌸 обалденная",
"🤜🤛 крутая",
"✨ яркая",
"🐱 ангельская",
"🔮 божественная",
"💘 шикарная",
"🙂 незабываемая",
"😎 неповторимая",
"🧸 очаровательная",
"🥺 милая",
"😍 ахуенная",
"🍬 привлекательная",
]
for m in messages:
message = await utils.answer(
message,
"<i>Каждая девушка/девочка/женщина в этом чате прекрасна..."
f" еще каждая из них:\n{m}</i>",
)
await asyncio.sleep(1)
all_ = "\n".join(messages)
await utils.answer(
message,
"<b><i>Каждая девушка/девочка/женщина в этом чате прекрасна... еще"
f" каждая из них: \n{all_}\nИ САМАЯ ЛУЧШАЯ НА"
" СВЕТЕ❤️❤️❤️❤️❤️❤️❤️❤️</i></b>",
)
else:
await utils.answer(
message,
"К сожалению, произошла ошибка... \nА именно, эта ошибка произошла"
" потому что в конфиге неправильное значение. \nНапишите"
" <code>.complimentscfg</code>",
)
else:
await utils.answer(
message,
"К сожалению, произошла ошибка... \nА именно, эта ошибка произошла"
" потому что в конфиге неправильное значение. \nНапишите"
" <code>.complimentscfg</code>",
)
async def complimentscfgcmd(self, message: Message):
"""—>конфиг этого модуля"""
name = self.strings("name")
await self.allmodules.commands["config"](
await utils.answer(message, f"{self.get_prefix()}config {name}")
)
async def ilikecmd(self, message):
"Инлайн анимация комплиментов(полная настройка в конфиге)"
await self.inline.form(
text="Я должен кое-что сказать...",
reply_markup=[
[{"text": "🥺", "callback": self.inline_compliments}],
[{"text": "🚫", "action": "close"}],
],
message=message,
disable_security=True,
)

View File

@@ -0,0 +1,182 @@
__version__ = (1, 0, 1)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules, @HikariMods
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/Emotions.jpg
import grapheme
from telethon.tl.types import Message
from .. import loader, utils
@loader.tds
class EmotionsMod(loader.Module):
'''Выражение эмоций в чате'''
strings = {
"name": "Emotions",
'delete_msg': "Удалять сообщение которое вызывает эмоцию?",
'on': "<emoji document_id=5373230475022179039>🥺</emoji> Emotions успешно активирован в этом чате.",
'off': "<emoji document_id=5373230475022179039>🥺</emoji> Emotions успешно деактивирован в этом чате",
'ok': "<emoji document_id=5188315103384050849>☑️</emoji>Эмоция успешно добавлена",
'list': "<emoji document_id=5373230475022179039>🥺</emoji> Доступные эмоции:\n\n{}\n\n<emoji document_id=5467928559664242360>❗️</emoji> Для добавления своих эмоций введите команду:\n <code>.emo</code> <символ/слово> <эмоция>",
}
async def client_ready(self):
self.emo = self.get(
"emo",
{
')': '😊 улыбается',
'(': '🙁 грустит',
'😭': '😭 плачет',
'😃': "😃 радуется",
"😏": "😏 думает о кое-чем)))",
"🤔": "🤔 призадумался",
"😂": "😂 смеется",
"🤣": "🤣 ржет",
"😞": "😞 расстроен",
"😔": "😔 сильно расстроен",
"😍": "😍 что-то нравится",
"😤": "😤 зол",
"😡": "😡 сильно зол",
"🤬": "🤬 матерится",
"😎": "😎 типа крутой",
"😳": "😳 шокирован",
"🤢": "🤢 думает что это противно",
"🫠": "🫠 весь течет",
"🥺": "🥺 считает что это мило",
},
)
self.chats = self.get("active", [])
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
'delete',
True,
doc=lambda: self.strings("delete_msg"),
validator=loader.validators.Boolean()
)
)
async def emogocmd(self, message: Message):
"""- вкл/выкл эмоции в данном чате"""
cid = str(utils.get_chat_id(message))
if cid in self.chats:
self.chats.remove(cid)
await utils.answer(message, self.strings("off"))
else:
self.chats += [cid]
await utils.answer(message, self.strings("on"))
self.set("active", self.chats)
async def emoclearcmd(self, message: Message):
"""<y> - сбросить список эмоций"""
args = utils.get_args_raw(message)
if args == "y":
await self.allmodules.commands["e"](
await utils.answer(message, f"{self.get_prefix()}e db.pop('EmotionsMod')")
)
await utils.answer(message, "<emoji document_id=5370842086658546991>☠️</emoji> <b>Список эмоций успешно сброшен до зоводских настроек\nПожалуйста, загрузите модуль еще раз.</b>")
else:
await utils.answer(message, '<emoji document_id=5370842086658546991>☠️</emoji> <b>Вы не подтвердили удаление!</b>')
async def emolistcmd(self, message: Message):
"""- список доступных эмоций"""
await utils.answer(
message,
self.strings("list").format(
"\n".join(
[f" ▪️ {simvol} - {emotion}" for simvol, emotion in self.emo.items()]
)
),
)
async def emocmd(self, message: Message):
"""<символ|слово> <эмоция> - добавить эмоцию в базу модуля"""
args = utils.get_args_raw(message)
try:
simvol = args.split(" ", 1)[0]
emotion = args.split(" ", 1)[1]
except Exception:
if not args or simvol not in self.emo:
await utils.answer(message, '<emoji document_id=5467928559664242360>❗️</emoji> Вы ввели неверное значение. Попробуйте снова')
else:
del self.emo[simvol]
self.set("emo", self.emo)
await utils.answer(message, self.strings("ok"))
return
self.emo[simvol] = emotion
self.set("emo", self.emo)
await utils.answer(message, self.strings("ok"))
async def watcher(self, message: Message):
cid = str(utils.get_chat_id(message))
try:
if (
cid not in self.chats
or not isinstance(message, Message)
or not hasattr(message, "raw_text")
or message.raw_text.split(maxsplit=1)[0].lower() not in self.emo
):
return
except IndexError:
return
try:
cmd = message.raw_text.split(maxsplit=1)[0].lower()
except IndexError:
return
msg = self.emo[cmd]
sender = await self._client.get_entity(message.sender_id)
if utils.emoji_pattern.match(next(grapheme.graphemes(msg))):
msg = list(grapheme.graphemes(msg))
emoji = msg[0]
msg = "".join(msg[1:])
else:
emoji = "<emoji document_id=5373230475022179039>🥺</emoji>"
if self.config['delete']:
if message.out:
pass
else:
await message.delete()
await utils.answer(
message,
f'{emoji} <a href="tg://user?id={sender.id}">{utils.escape_html(sender.first_name)}</a> <b>{utils.escape_html(msg)}</b> {emoji}')

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,8 @@
# ***🦄Astro-Modules🦄***
#
## ***Modules for Telegram-UserBot «Hikka»***
## **Information:**
### *Channel in TG: « https://t.me/AstroModules »*
### *Developers in repository:*
### *Toxyar4ik --> https://t.me/ToXicUse*
### *Den4ikSuperOstryyPer4ik --> https://t.me/Den4ikSuperOstryyPer4ik*

View File

@@ -0,0 +1,198 @@
__version__ = (2, 0, 0)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/PasswordGenerator.jpg
import logging
import random
from telethon.tl.types import Message
from .. import loader, utils
from ..inline.types import InlineCall
logger = logging.getLogger(__name__)
@loader.tds
class PasswordGeneratorMod(loader.Module):
'''Random password/pincode generator'''
strings = {
"name": "RandomPasswordGenerator",
"_cfg_doc_pass_length": "set password length (in number of characters)",
"_cfg_doc_pin_code_length": "set pincode length (in number of characters)",
"_cfg_doc_simbols_in_pass": (
"Will there be additional characters in the generated password"
" (+-*!&$#?=@<>)?"
),
"what_to_generate": "🆗What should be generated?",
"new_random_pass": "🔣 new random password 🆕",
"new_random_pincode": "🔢 new random PIN-code 🆕",
"pass": "<b>🆕 Your new password in {} characters:\n<code>{}</code></b>",
"pincode": "<b>🆕 Your new pincode in {} characters:\n<code>{}</code></b>",
"menu": "💻 Menu",
"close": "🚫 Close",
}
strings_ru = {
"_cls_doc": (
"Генератор рандомного пароля/пин-кода\nНастроить генератор можно через"
" конфиг"
),
"_cfg_doc_pass_length": "выставьте длину пароля(в кол-ве символов)",
"_cfg_doc_pin_code_length": "выставьте длину Пин-Кода(в кол-ве символов)",
"_cfg_doc_simbols_in_pass": (
"Какие символы должны быть в сгенерированном пароле?"
),
"what_to_generate": "🆗 Что надо сгенерировать?",
"new_random_pass": "🔣 Новый рандомный пароль 🆕",
"new_random_pincode": "🔢 Новый рандомный PIN-код 🆕",
"pass": "<b>🆕 Ваш новый пароль в {} символов:\n<code>{}</code></b>",
"pincode": "<b>🆕 Ваш новый пин-код в {} символов:</b>\n<code>{}</code>",
"menu": "💻 Меню",
"close": "🚫 Закрыть",
}
@loader.command(ru_doc="—>конфиг этого модуля")
async def generatorcfgcmd(self, message: Message):
"""—>config for this module"""
name = self.strings("name")
await self.allmodules.commands["config"](
await utils.answer(message, f"{self.get_prefix()}config {name}")
)
def __init__(self):
self._ratelimit = []
self.config = loader.ModuleConfig(
loader.ConfigValue(
"password_length",
10,
doc=lambda: self.strings("_cfg_doc_pass_length"),
validator=loader.validators.Integer(minimum=6),
),
loader.ConfigValue(
"pincode_length",
4,
doc=lambda: self.strings("_cfg_doc_pin_code_length"),
validator=loader.validators.Integer(minimum=4),
),
loader.ConfigValue(
"symbols",
"+-*!&$?=@<>abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
doc=lambda: self.strings("_cfg_doc_simbols_in_pass"),
),
)
@loader.command(ru_doc="—>сгенерировать случайный пароль/пин-код")
async def igeneratorcmd(self, message: Message):
"""—>generate random password/pin"""
await self.inline.form(
self.strings("what_to_generate"),
reply_markup=[
[
{
"text": self.strings("new_random_pass"),
"callback": self.new_random_pass,
}
],
[
{
"text": self.strings("new_random_pincode"),
"callback": self.new_random_pincode,
}
],
[{"text": self.strings("close"), "action": "close"}],
],
message=message,
)
async def igenerator(self, call: InlineCall):
await call.edit(
self.strings("what_to_generate"),
reply_markup=[
[
{
"text": self.strings("new_random_pass"),
"callback": self.new_random_pass,
}
],
[
{
"text": self.strings("new_random_pincode"),
"callback": self.new_random_pincode,
}
],
[{"text": self.strings("close"), "action": "close"}],
],
)
async def new_random_pass(self, call: InlineCall):
symbols = self.config["symbols"]
password_length = self.config["password_length"]
length = int(password_length)
password = ""
for _ in range(length):
password += random.choice(symbols)
await call.edit(
self.strings["pass"].format(password_length, password),
reply_markup=[
[
{
"text": self.strings("menu"),
"callback": self.igenerator
}
],
[
{
"text": self.strings("close"),
"action": "close"
}
],
],
)
async def new_random_pincode(self, call: InlineCall):
pincode_length = self.config["pincode_length"]
chars = "1234567890"
length = int(self.config["pincode_length"])
pincode = ""
for _ in range(length):
pincode += random.choice(chars)
await call.edit(
self.strings["pincode"].format(pincode_length, pincode),
reply_markup=[
[
{
"text": self.strings("menu"),
"callback": self.igenerator
}
],
[
{
"text": self.strings("close"),
"action": "close"
}
],
],
)

View File

@@ -0,0 +1,311 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/RandomStatuses.jpg
import logging
import random
import grapheme
import requests
from bs4 import BeautifulSoup
from telethon.tl.functions.account import UpdateProfileRequest
from telethon.tl.types import Message
from .. import loader
from ..inline.types import InlineCall
logger = logging.getLogger(__name__)
@loader.tds
class RandomStatusesMod(loader.Module):
'''Рандомные статусы для описания аккаунта в ТГ/Вацап/ВК и т.д.'''
strings = {
"name": "RandomStatuses",
"generate_st": "✨ Рандомный статус 🌺",
"support_chat_btn": "🎩 Чат поддержки 🎓",
"more_modules_btn": "🌌 Больше Модулей ✨",
"set_status": "⚙️ Сохранить в био 📥",
}
@loader.command()
async def rstatuscmd(self, message: Message):
"""Рандомный статус на описание аккаунта в ТГ/ВК/Вацап и т.д."""
await self.inline.form(
text="Привет! Нажми кнопку ниже, чтобы получить рандомный статус!",
reply_markup=[
[{"text": self.strings("generate_st"), "callback": self.random_status}],
[
{
"text": self.strings("support_chat_btn"),
"url": "https://t.me/AstroModsChat",
}
],
[
{
"text": self.strings("more_modules_btn"),
"url": "https://t.me/AstroModules",
}
],
[{"text": "🚫 Закрыть", "action": "close"}],
],
message=message,
)
async def client_ready(self, client, db):
logger.info("Привет от t.me/AstroModules :)")
async def random_status(self, call: InlineCall):
q = ["list", "parser"]
rand1 = random.choice(q)
if rand1 == "list":
statuses = [
"Расходовать оптимизм нужно умеренно, чтобы хватило до конца жизни",
"Когда кажется что в жизни все рушится, начинайте думать о том, что"
" построите на освободившемся месте",
"Ребенок — гость в твоем доме - накорми, выучи и отпусти",
"Чем меньше ты будешь задавать вопросов, тем меньше ты услышишь лжи",
"Побеждающий других силен, а побеждающий самого себя могуществен",
"Никогда не знаешь, что придёт завтра — следующее утро или следующая"
" жизнь",
"Дни жизни даже горькие цени, ведь навсегда уходят и они",
"Тот кто хранит молчанье в шумных спорах, мудрее болтунов, на слово"
" скорых",
"Дурак спорит с каждым, умный — с равным, а мудрый — лишь с самим"
" собой",
"Лучше прожить день львом, чем сто лет овцой.",
"Гости, как рыба: через три дня воняют",
"Хорошее употребление времени делает время ещё более драгоценным, будь"
" счастлив в этот миг, этот миг и есть твоя жизнь.",
"Великие дела нужно совершать, а не бесконечно обдумывать",
"Счастье — это когда ты нашёл человека, который искал тебя",
"Преодолевая трудности, мы приобретаем мудрость",
"Не огорчайся по поводу того, чего у тебя нет. Радуйся по поводу того,"
" что у тебя есть",
"Хочешь узнать человека? Тогда задень его. Человек — это сосуд. Чем"
" наполнен, то и начнёт выплёскиваться",
"Нажить много денег — храбрость. Сохранить их — мудрость. Умело"
" расходовать — искусство",
"Слабые мстят, сильные прощают, счастливые забывают",
"Бога мы сердим нашими грехами, людей — достоинствами",
"Пусть о нас говорят плохо. А мы будем делать хорошо.",
"Мудр не тот, кто знает много, а тот, чьи знания полезны",
"Оставь мутную воду в покое — и она станет чистой",
"Шипы из сердца может вытащить только друг",
"Кто после трёх шагов начал жалеть что пошёл в гору, тот не поднимется"
" и на маленький холм",
"Ночь - время дел мировой важности",
"Я как кабриолет, такая классная, а крыши нет…",
"Рай был переполнен… Я вернулся!",
"Не бойся медлить, бойся остановиться",
"То что случается, случается вовремя",
"Тот, кто хорош для всех, для всех и плох",
"Родившийся ослом не умрёт лошадью",
"Никто не спотыкается лёжа в постели",
"Победа над слабым подобна поражению",
"Лучше хранить тот секрет, который никому не раскрыт",
"Неспешная старость — залог долголетия",
"Много обещаний уменьшают доверие",
"Никто не хочет быть одиноким, даже в раю",
"Никто не возвращался из путешествий таким, каким он был раньше",
"Забытая мысль всегда кажется важной",
"Сон не спасёт тебя, если у тебя устала душа",
"Будь словно лотос: он цветёт даже в мутной воде",
"Дающий нищему не обеднеет",
"Заботься о себе, но не забудь оставить что-нибудь потомкам",
"Человек без воли что нож без стали",
"Когда ваши дела идут плохо — не ходите за ними",
"Если хочешь увидеть радугу, будь готов попасть под дождь",
"Хорошие друзья достаются тому кто сам умеет быть хорошим другом",
"Бог дал тебе лицо, но тебе выбирать его выражение",
"Люди не хотят быть богатыми — люди хотят быть богаче других",
"Утром когда восходит солнце позвольте ему взойти и в вас тоже",
"Твой дом там, где спокойны твои мысли",
"Горе, как рваное платье, надо оставлять дома",
"Как басня так и жизнь — ценится не за длину, но за содержание",
"Победа показывает, что человек может, а поражение — чего он стоит",
"Сильный преодолевает преграду. Мудрый — весь путь",
"Если ты ненавидишь — значит тебя победили",
"Если ты не признаешь свою ошибку, значит, ты совершаешь вторую",
"Возлюбите врагов своив и они сойдут с ума, пытаясь понять, что вы"
" задумали",
"Сильные люди говорят в лицо, слабые люди — за спиной",
"Тихие речи мудрых слышнее крика властелина глупцов",
"Когда человеку кажется что все идет наперекосяк, в его жизнь пытается"
" войти нечто чудесное",
"Почему с точки зрения законов аэродинамики шмель летать не способен,"
" но он этого не знает и продолжает летать",
"Человек, который смог сдвинуть гору, начинал с того, что перетаскивал"
" с места на место мелкие камешки",
"Как бы сильно не дул ветер, гора перед ним не склонится",
"Не жалей о своих ошибках, ведь не сделав их, ты никогда не узнаешь,"
" как делать правильно",
"Бриллиант упавший в грязь так и останется бриллиантом, а пыль"
" поднявшаяся до небес, так и остаётся пылью",
"Мудрый человек помнит своих друзей всегда, а глупец — только когда"
" нуждается в них",
"Кто малым недоволен, тот большего не достоин",
"Лучше спросить и выглядеть глупым в течении нескольких минут, чем"
" промолчать и оставаться им всю жизнь",
"Высшая наука: быть мудрым, а высшая мудрость: быть добрым",
"Если не хочешь, чтобы враг раскрыл твою тайну, то не открывай её даже"
" другу",
"Для того, чтобы услышать себя, нужны молчаливые дни",
"Стремись к мудрости, а не к знаниям. Знания — это прошлое, а мудрость"
" — это будущее",
"Ты хозяин своих слов, пока не высказал их. Когда же их высказал то они"
" — твои хозяева",
"Не суди чужое прошлое, не зная своего будущего",
"Враг опасен, когда кажется побеждённым",
"Иди против ветра и пусть тебе плюют в спину",
"Прежде чем любить, научись ходить по снегу, не оставляя следов",
"Хижина, где смеются, богаче дворца, где скучают",
"Если вы уходите и вас никто не зовет обратно — вы идёте в верном"
" направлении",
"Верить людям не сложно, сложно поверить заново",
"Если ты споткнулся и упал, это ещё не значит, что ты идёшь не туда",
"Оскорбить женщину может только униженный судьбой мужчина",
"Чтобы победить противника, не стремись стать сильнее его, а сделай его"
" слабее себя",
"Советы мы принимаем каплями, зато даём вёдрами",
"Хочешь победить врага — воспитай его детей",
"Чтобы получить знания — нужна мудрость. Чтобы получить мудрость —"
" нужно наблюдать",
"Не гонись за счастьем — оно всегда в тебе",
"Помни, что бы ты не делал за спиной у людей, ты делаешь это на глазах"
" у Бога.",
"""Часто мы говорим «Не люблю», а в душе у нас текут слёзы.
Часто мы говорим «Ненавижу» только для того, чтобы мы сами поверили в это.
Часто мы говорим «Прощай» в надежде увидеть человека ещё раз.
Мы говорим «Уйди», чтобы человек не видел наших слёз.
Мы говорим «Никогда», когда знаем, что это случится вновь.
Мы говорим «Разлюбил(а)»когда боимся признаться в своих чувствах.
Мы говорим «Я тебя забыл(а)» когда мысль о человеке не выходит из головы.
Мы говорим «Я удалила его(ее) номер» когда помним его наизусть.
Мы говорим «Между нами все кончено» когда все только начинается.
Иногда мы не можем сказать «Люблю» когда боимся услышать ответ.
Мы просим чтобы нас «Оставили одних», когда нуждаемся в чьей-то поддержке.
Мы «Надеемся», когда нет никаких шансов.
Мы «Ждём», когда знаем, что о нас уже забыли.
Мы «Мечтаем» зная, что это никогда не случится.....""",
"Я буду тянуться туда, где меня ждут, но останусь там, где меня ценят!",
"Когда появляются парни, исчезают подруги… Даже самые лучшие…",
"С некоторыми людьми встреча в этой жизни была лишней.",
"Настоящая подруга — это не телочка, которая вытирает твои сопли, когда"
" тебя бросил мальчик. Настоящая подруга — это та, кто искренне рада"
" видеть тебя красивой!",
"Вернется тот, кто сильно любит. Дождется тот, кто сильно ждет.",
"Я и не стремлюсь быть идеальной,мне нравится всех раздражать.",
"Твоя подруга забыла о тебе и у неё появился парень? Поставь статус"
" «Чёрт! Кажется, я влюбилась в парня лучшей подруги…»",
"лучшая подруга это та которая за тебя заступится! потом отведёт в"
" сторонку и скажет что ты была не права!",
"Иногда так хочется немного вернуть время назад и исправить те ошибки,"
" которые были допущены раньше",
]
self.mn = random.choice(statuses)
elif rand1 == "parser":
urls = [f"https://status69.ru/page/{i}" for i in range(2, 96 + 1)]
url = random.choice(urls)
request = requests.get(url)
soup = BeautifulSoup(request.text, "html.parser")
nm = soup.find_all("div", class_="entry")
f = random.choice(nm)
self.mn = f.find("p").text
emoji = list(grapheme.graphemes("🍇🍉🥝🥑🥥🍓🍍🎆🎇✨🎊🎉🎈🎁🎀🏆🌋📱🆒️🦄🐾🍟🍔🧀🍕🌭🥪🎂🍫🍬🍭🥧🍮🍡🥟🍥☕️🍹🥂🍺🍪"))
emoj = random.choice(emoji)
rst = (
f"<b>{emoj} Ваш новый рандомный статус на"
f' сегодня:</b>\n"<code>{self.mn}</code>"'
)
await call.edit(
rst,
reply_markup=[
[
{
"text": self.strings("generate_st"),
"callback": self.random_status
}
],
[
{
"text": self.strings("set_status"),
"callback": self.set_status
}
],
[
{
"text": self.strings("support_chat_btn"),
"url": "https://t.me/AstroModsChat",
}
],
[
{
"text": self.strings("more_modules_btn"),
"url": "https://t.me/AstroModules",
}
],
[
{
"text": "🚫 Закрыть ",
"action": "close"
}
],
],
)
async def set_status(self, call: InlineCall):
await self.client(UpdateProfileRequest(about=self.mn))
await call.edit(
f"Био(Обо мне в профиле) изменено успешно на:\n«<code>{self.mn}</code>»",
reply_markup=[
[
{
"text": self.strings("generate_st"),
"callback": self.random_status
}
],
[
{
"text": self.strings("support_chat_btn"),
"url": "https://t.me/AstroModsChat",
}
],
[
{
"text": self.strings("more_modules_btn"),
"url": "https://t.me/AstroModules",
}
],
[
{
"text": "🚫 Закрыть ",
"action": "close"
}
],
],
)

View File

@@ -0,0 +1,146 @@
__version__ = (1, 4, 2)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/RandomTrack.jpg
import random
from telethon.tl.types import InputMessagesFilterMusic, Message
from .. import loader, utils
@loader.tds
class RandomTrackMod(loader.Module):
'''Получить рандомный трек.
Используйте категории чтобы сгенерировать трек на свой вкус'''
strings = {"name": "RandomTrack"}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"playlist",
None,
doc=lambda: "Юзер нужного канала с музыкой",
),
loader.ConfigValue(
"fonks",
"AM_fonks",
doc=lambda: "Юзер нужного канала с фонками",
),
loader.ConfigValue(
"remixes",
"AM_rmx",
doc=lambda: "Юзер нужного канала с ремиксами",
),
loader.ConfigValue(
"sad",
"AM_depressive",
doc=lambda: "Юзер нужного канала с грустной музыкой",
),
loader.ConfigValue(
"popular",
"AM_popular",
doc=lambda: "Юзер нужного канала с поп музыкой",
),
loader.ConfigValue(
"hyperpop",
"hyperpopmusicx_x",
doc=lambda: "Юзер нужного канала с хайперпоп музыкой",
),
loader.ConfigValue(
"mems",
"AM_memss",
doc=lambda: "Юзер нужного канала с мемами",
)
)
@loader.command()
async def rt(self, message: Message):
"""- сгенерировать трек.
🫠 Категории:
<f> - фонки
<r> - ремиксы
<m> - мемные звуки
<s> - грустная музыка
<h> - хайперпоп музыка
<p> - популярная музыка
<n> - ностальгические треки
<my> - треки из вашего плейлиста
🤫 По желанию, в конфиге, можно указать свои каналы откуда будет отбираться музыка
"""
args = utils.get_args_raw(message)
limit = 100
if not args:
search_type = "трек"
search_channel = "shyshomuz"
limit = 1000
elif args == "f":
search_type = "фонк"
search_channel = self.config['fonks']
if args == "s":
search_type = "грустный трек"
search_channel = self.config['sad']
if args == "h":
search_type = "хайпер-поп"
search_channel = self.config['hyperpop']
if args == "r":
search_type = "ремикс"
search_channel = self.config['remixes']
if args == "m":
search_type = "мем"
search_channel = self.config['mems']
if args == "p":
search_type = "трек"
search_channel = self.config['popular']
if args == "n":
search_type = "трек"
search_channel = "AM_NSTL"
limit = 200
if args == "my":
search_type = "трек с вашего плейлиста"
search_channel = self.config['playlist']
await utils.answer(message, f"<emoji document_id=5219806684066618617>🫠</emoji> <b>Подбираем {search_type}...</b>")
media = random.choice([
msg
async for msg in self.client.iter_messages(
search_channel,
limit=limit,
filter=InputMessagesFilterMusic if search_type != "мем" else None
)
])
await message.respond(
file=media,
reply_to=utils.get_topic(message),
)
if message.out:
await message.delete()

View File

@@ -0,0 +1,501 @@
__version__ = (1, 6, 0)
# module by:
# █▀ █▄▀ █ █░░ █░░ ▀█
# ▄█ █░█ █ █▄▄ █▄▄ █▄
# /\_/\
# ( o.o )
# > ^ <
# █▀▄▀█ █▀▀ █▀█ █░█░█
# █░▀░█ ██▄ █▄█ ▀▄▀▄▀
#
# and
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/RandomUser.jpg
import logging
import random as r
import grapheme
from telethon.errors import (
BotGroupsBlockedError,
ChannelPrivateError,
ChatAdminRequiredError,
ChatWriteForbiddenError,
InputUserDeactivatedError,
UserAdminInvalidError,
UserAlreadyParticipantError,
UserBlockedError,
UserKickedError,
UserNotMutualContactError,
UserPrivacyRestrictedError,
YouBlockedUserError,
)
from telethon.tl.functions.channels import (
EditAdminRequest,
EditBannedRequest,
InviteToChannelRequest,
)
from telethon.tl.functions.messages import AddChatUserRequest
from telethon.tl.types import ChatAdminRights, ChatBannedRights, Message
from .. import loader
from ..inline.types import InlineCall
logger = logging.getLogger(__name__)
UNMUTE_RIGHTS = ChatBannedRights(
until_date=None,
view_messages=None,
send_messages=False,
send_media=False,
send_stickers=False,
send_gifs=False,
send_games=False,
send_inline=False,
embed_links=False,
)
class RandomUserMod(loader.Module):
'''choose a random user in chat\nAutors: @AstroModules & @smeowcodes'''
emoji_list = list(grapheme.graphemes("🤩🥳🤪😜😝😋😘🤯🤠😈🎃😺👀🙊🙈🙉🐵🐸🐣🌝🌚🌜🌛🌙✨⚡️🌟⭐️💫💥☄️❄️☀️🌪🔥☃️☁️💨💧💦🌊🍓🍉🍋🍊🍐🍎🍌🍇🫐🍈🍒🍑🥭🍍🥝"))
strings = {
"name": "RandomUser",
"astro-modules-btn": "🌌 𝑨𝒔𝒕𝒓𝒐 𝑴𝒐𝒅𝒖𝒍𝒆𝒔",
"meow-modules-btn": "Meow Modules😽",
"inline-text": "<b>👥 Click on the button to select a random user in the chat!</b>",
"rand-user-btn": "🤩 Choose",
"rand-user-2-btn": "🤯 Choose again",
"user": "<b>{} The choice fell on {}!\n{}</b>",
"user-...": "<b>{} The choice fell on {}!\n{}\n\n{}</b>",
"id": "🆔 ID: <code>{}</code>",
"id+username": "{} Username: @{}\n🆔 ID: <code>{}</code>",
"give-adm-btn": "🎩 Give Admin",
"text-adm": "<b>🎩 Was assigned to the administrator\n👨🏻‍💻 Prefix(rank): «{}»</b>",
"mute-btn": "🤫 Mute",
"unmute-btn": "😊 UnMute",
"ban-btn": "👔 Ban",
"unban-btn": "😊 UnBan",
"kick-btn": "👞 Kick",
"invite-btn": " Add back",
"prefix-1": "Cool person :)",
"prefix-2": "Lucky",
"prefix-3": " ",
"prefix-4": "King of Random",
"prefix-5": "GAY",
"not_admin": "I`m not an admin here.",
"no_rights": "I don`t have rights.",
"user-invited": "🚹 The user has been invited successfully!",
"user-kicked": "👞 Was kicked out",
"user-unmuted": "😊 The user unmuted",
"user-muted": "🤫 Muted",
"user-banned": "👔 Banned",
"user-unbanned": "😊 The user unbanned.",
"invite-error-1": "The user's privacy settings do not allow you to invite him.",
"invite-error-2": "I don't have a permission.",
"invite-error-3": "The user is kicked out of the chat, contact the administrators.",
"invite-error-4": "The bot is blocked in the chat, contact the administrators.",
"invite-error-5": "The user is blocked in the chat, contact the administrators.",
"invite-error-6": "The user's account has been deleted.",
"invite-error-7": "The user is already in the group.",
"invite-error-8": "You have blocked this user.",
}
strings_ru = {
"_cls_doc": "Выбрать случайного пользователя в чате\nАвторы: @AstroModules & @smeowcodes",
"inline-text": "<b>👥 Нажмите на кнопку, чтобы выбрать случайного пользователя в чате:</b>",
"rand-user-btn": "🤩 Выбрать",
"rand-user-2-btn": "🤯 Выбрать ещё раз",
"user": "<b>{} Выбор упал на {}!\n{}</b>",
"user-...": "<b>{} Выбор упал на {}!\n{}\n\n{}</b>",
"id+username": "{} Имя пользователя: @{}\n🆔 ID: <code>{}</code>",
"give-adm-btn": "🎩 Назначить на администратора",
"text-adm": "🎩 Был назначен на администратора\n👨🏻‍💻 Префикс: «{}»",
"prefix-1": "Крутой :)",
"prefix-2": "Везучий",
"prefix-3": "Удачливый",
"prefix-4": "Король рандома",
"prefix-5": "Лютейший чел",
"mute-btn": "🤫 Заткнуть",
"unmute-btn": "😊 Снять мут",
"ban-btn": "🚫 Забанить",
"unban-btn": "💥 Разбанить",
"kick-btn": "👞 Выгнать",
"invite-btn": " Добавить обратно",
"not_admin": "Я здесь не администратор.",
"no_rights": "🚫 У Вас нет нужных прав",
"user-invited": "🚹 Пользователь был добавлен обратно!",
"user-kicked": "👞 Был выгнан",
"user-unmuted": "🔔 С пользователя был снят мут",
"user-muted": "🤫 Был заткнут",
"user-banned": "👔 Был забанен",
"user-unbanned": "😊 С пользователя был снят бан.",
"invite-error-1": "Настройки приватности пользователя не позволяют пригласить его.",
"invite-error-2": "🚫 У Вас нет нужных прав",
"invite-error-3": "Пользователь кикнут из чата, обратитесь к администраторам.",
"invite-error-4": "Бот заблокирован в чате, обратитесь к администраторам.",
"invite-error-5": "Пользователь заблокирован в чате, обратитесь к администраторам.",
"invite-error-6": "Аккаунт пользователя удалён.",
"invite-error-7": "Пользователь уже в группе.",
"invite-error-8": "Вы заблокировали этого пользователя.",
}
@loader.command(ru_doc="--> выбрать случайного пользователя в чате | inline-меню с призовыми кнопками")
async def irandusercmd(self, message: Message):
"choose a random user in chat | inline menu with prize buttons"
self.users = [p.id async for p in self.client.iter_participants(message.peer_id)]
self.chat = await message.get_chat()
self.chat_id = message.chat_id
self.message = message
await self.inline.form(
text=self.strings("inline-text"),
reply_markup=[
[
{
"text": self.strings("rand-user-btn"),
"callback": self.rand_user_inline
}
]
],
message=message
)
async def rand_user_inline(self, call: InlineCall):
rand_user = r.choice(self.users)
self.user = await self.client.get_entity(rand_user)
emoji_list = list(grapheme.graphemes("🤩🥳🤪😜😝😋😘🤯🤠😈🎃😺👀🙊🙈🙉🐵🐸🐣🌝🌚🌜🌛🌙✨⚡️🌟⭐️💫💥☄️❄️☀️🌪🔥☃️☁️💨💧💦🌊🍓🍉🍋🍊🍐🍎🍌🍇🫐🍈🍒🍑🥭🍍🥝"))
emoji = r.choice(emoji_list)
if not self.user.username:
self.link = self.user.first_name
self.id_or_username = self.strings("id").format(self.user.id)
else:
self.link = f"<a href='https://t.me/{self.user.username}'>{self.user.first_name}</a>"
emoji_list2 = list(grapheme.graphemes("👤👶👧🧒👦👩🧑👨👩‍🦱🧑‍🦱👨‍🦱👩‍🦰🧑‍🦰👨‍🦰👱‍♀👱👱‍♂👩‍🦳🧑‍🦳👨‍🦳👵🧓👴"))
emoji2 = r.choice(emoji_list2)
self.id_or_username = self.strings("id+username").format(emoji2, self.user.username, self.user.id)
await call.edit(
text=self.strings("user").format(emoji, self.link, self.id_or_username),
reply_markup=[
[
{
"text": self.strings("rand-user-2-btn"),
"callback": self.rand_user_inline
}
],
[
{
"text": self.strings("give-adm-btn"),
"callback": self.add_to_admins_user
}
],
[
{
"text": self.strings("ban-btn"),
"callback": self.ban_user
},
{
"text": self.strings("kick-btn"),
"callback": self.kick_user
},
{
"text": self.strings("mute-btn"),
"callback": self.mute_user
}
],
[
{
"text": self.strings("astro-modules-btn"),
"url": "https://t.me/AstroModules"
},
{
"text": self.strings("meow-modules-btn"),
"url": "https://t.me/smeowcodes"
}
]
]
)
async def add_to_admins_user(self, call: InlineCall):
pref1 = self.strings("prefix-1")
pref2 = self.strings("prefix-2")
pref3 = self.strings("prefix-3")
pref4 = self.strings("prefix-4")
pref5 = self.strings("prefix-5")
prefs = [pref1, pref2, pref3, pref4, pref5]
prefix = r.choice(prefs)
text = self.strings("text-adm").format(prefix)
emoji = r.choice(self.emoji_list)
if not self.chat.admin_rights and not self.chat.creator:
return await call.answer(self.strings("not_admin"), show_alert=True)
try:
await self.client(
EditAdminRequest(
self.chat_id,
self.user.id,
ChatAdminRights(
add_admins=False,
change_info=False,
invite_users=self.chat.admin_rights.invite_users,
ban_users=False,
delete_messages=self.chat.admin_rights.delete_messages,
pin_messages=False,
),
prefix,
)
)
except ChatAdminRequiredError:
return await call.answer(self.strings("no_rights"), show_alert=True)
else:
await call.answer(text, show_alert=True)
return await call.edit(
text=self.strings("user-...").format(emoji, self.link, self.id_or_username, text),
reply_markup=[
[
{
"text": self.strings("rand-user-2-btn"),
"callback": self.rand_user_inline
}
]
]
)
async def mute_user(self, call: InlineCall):
text = self.strings("user-muted")
emoji = r.choice(self.emoji_list)
if not self.chat.admin_rights and not self.chat.creator:
return await call.answer(self.strings("not_admin"), show_alert=True)
if not self.chat.admin_rights.ban_users:
return await call.answer(self.strings("no_rights"), show_alert=True)
try:
tm = ChatBannedRights(until_date=True, send_messages=True)
await self.client(EditBannedRequest(
self.chat_id,
self.user.id,
tm
))
await call.answer(text, show_alert=True)
return await call.edit(
text=self.strings("user-...").format(emoji, self.link, self.id_or_username, text),
reply_markup=[
[
{
"text": self.strings("unmute-btn"),
"callback": self.unmute_user
}
],
[
{
"text": self.strings("rand-user-2-btn"),
"callback": self.rand_user_inline
}
]
]
)
except UserAdminInvalidError:
return await call.answer(self.strings("no_rights"), show_alert=True)
async def unmute_user(self, call: InlineCall):
text = self.strings("user-unmuted")
emoji = r.choice(self.emoji_list)
if not self.chat.admin_rights and not self.chat.creator:
return await call.answer(self.strings("no_rights"), show_alert=True)
if not self.chat.admin_rights.ban_users:
return await call.answer(self.strings("no_rights"), show_alert=True)
await self.client(
EditBannedRequest(self.chat_id, self.user.id, UNMUTE_RIGHTS)
)
await call.answer(text, show_alert=True)
await call.edit(
self.strings("user-...").format(emoji, self.link, self.id_or_username, text),
reply_markup=[
[
{
"text": self.strings("rand-user-2-btn"),
"callback": self.rand_user_inline
}
]
]
)
async def ban_user(self, call: InlineCall):
if not self.chat.admin_rights and not self.chat.creator:
return await call.answer(self.strings("not_admin"), show_alert=True)
if not self.chat.admin_rights.ban_users:
return await call.answer(self.strings("no_rights"), show_alert=True)
try:
await self.client(EditBannedRequest(
self.chat_id,
self.user.id,
ChatBannedRights(until_date=None, view_messages=True)
))
text = self.strings("user-banned")
emoji = r.choice(self.emoji_list)
await call.answer(text, show_alert=True)
await call.edit(
self.strings("user-...").format(emoji, self.link, self.id_or_username, text),
reply_markup=[
[
{
"text": self.strings("unban-btn"),
"callback": self.unban_user
}
],
[
{
"text": self.strings("rand-user-2-btn"),
"callback": self.rand_user_inline
}
]
]
)
except UserAdminInvalidError:
return await call.answer(self.strings("no_rights"), show_alert=True)
async def unban_user(self, call: InlineCall):
text = self.strings("user-unbanned")
emoji = r.choice(self.emoji_list)
if not self.chat.admin_rights and not self.chat.creator:
return await call.answer(self.strings("no_rights"), show_alert=True)
if not self.chat.admin_rights.ban_users:
return await call.answer(self.strings("no_rights"), show_alert=True)
await self.client(
EditBannedRequest(
self.chat_id,
self.user.id,
ChatBannedRights(until_date=None, view_messages=False),
)
)
await call.answer(text, show_alert=True)
await call.edit(
self.strings("user-...").format(emoji, self.link, self.id_or_username, text),
reply_markup=[
[
{
"text": self.strings("rand-user-2-btn"),
"callback": self.rand_user_inline
}
]
]
)
async def kick_user(self, call: InlineCall):
text = self.strings("user-kicked")
emoji = r.choice(self.emoji_list)
if not self.chat.admin_rights and not self.chat.creator:
return await call.answer(self.strings("no_rights"), show_alert=True)
if not self.chat.admin_rights.ban_users:
return await call.answer(self.strings("no_rights"), show_alert=True)
try:
await self.client.kick_participant(self.chat_id, self.user.id)
except UserAdminInvalidError:
return await call.answer(self.strings("no_rights"), show_alert=True)
await call.answer(text, show_alert=True)
return await call.edit(
self.strings("user-...").format(emoji, self.link, self.id_or_username, text),
reply_markup=[
[
{
"text": self.strings("invite-btn"),
"callback": self.invite_user
}
],
[
{
"text": self.strings("rand-user-2-btn"),
"callback": self.rand_user_inline
}
]
]
)
async def invite_user(self, call: InlineCall):
emoji = r.choice(self.emoji_list)
try:
if not self.message.is_channel and self.message.is_group:
await self.client(
AddChatUserRequest(
chat_id=self.chat_id, user_id=self.user.id, fwd_limit=1000000
)
)
else:
await self.client(
InviteToChannelRequest(channel=self.chat_id, users=[self.user.id])
)
await call.answer(self.strings("user-invited"), show_alert=True)
text = self.strings("user-invited")
return await call.edit(
text=self.strings("user-...").format(emoji, self.link, self.id_or_username, text),
reply_markup=[
[
{
"text": self.strings("rand-user-2-btn"),
"callback": self.rand_user_inline
}
]
]
)
except UserPrivacyRestrictedError:
m = self.strings("invite-error-1")
except UserNotMutualContactError:
m = self.strings("invite-error-1")
except ChatAdminRequiredError:
m = self.strings("invite-error-2")
except ChatWriteForbiddenError:
m = self.strings("invite-error-2")
except ChannelPrivateError:
m = self.strings("invite-error-2")
except UserKickedError:
m = self.strings("invite-error-3")
except BotGroupsBlockedError:
m = self.strings("invite-error-4")
except UserBlockedError:
m = self.strings("invite-error-5")
except InputUserDeactivatedError:
m = self.strings("invite-error-6")
except UserAlreadyParticipantError:
m = self.strings("invite-error-7")
except YouBlockedUserError:
m = "Вы заблокировали этого пользователя."
await call.answer(m, show_alert=True)

View File

@@ -0,0 +1,400 @@
__version__ = (1, 0, 0)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta banner:
# meta developer: @AstroModules
# required: steampy
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/AstroSteamNow.png
# Part of the module taken from WakaTime by @hikariatama: 38, 158, 208, 324 lines
import time
import logging
import datetime
import requests
import asyncio
from steampy.client import SteamClient
from .. import loader, utils
from ..inline.types import InlineCall
from telethon.errors.rpcerrorlist import MessageNotModifiedError
logger = logging.getLogger(__name__)
@loader.tds
class Steam(loader.Module):
'''Get now played game'''
strings = {
'name': 'SteamNow',
'_api_key': "Enter your SteamAPI Key. You can get it by following this tutorial:\n\nhttps://t.me/help_code/20", # Tutorial link
'_account_id': "Enter your Steam Account ID. More details in the tutorial: \n\nhttps://t.me/help_code/21", # Tutorial link
'no_api_key_or_id': (
'<b>❌ You did not specify your API_KEY or ACCOUNT_ID in the config.</b>\n'
'<b>🚨 Correct this for further module operation</b>'
),
'noGame': "<b>❌ The game is not running or you do not have access</b>",
'steamNow': (
'💻 <b>At the moment you are playing:</b>\n\n'
'🎮 <b>Title:</b> <code>{}</code>\n'
'🆔 <b>Game ID: {}</b>'
),
'lite_gameInfo': (
'🎮 <b>Game information:</b>\n\n'
'<b>Title: </b>{}\n'
'<b>Price: {}</b>\n'
'<b>Description:</b>\n- <i>{}</i>'
),
'steamMe': (
'<b>🎮 Your account:</b>\n\n'
'<b>Name: </b><i>{}</i> (<i>{}</i>)\n'
'<b>Online: </b><code>{}</code>\n'
'<b>Created: </b><code>{}</code>\n'
'<b>Recent games:</b>\n<i> • {}</i>'
),
'gameNotFound': '<b>🆔 There is no game with such an identifier, try again</b>',
"state": "🙂 <b>Steam widgets: {}</b>\n{}",
"error": "<b>Steam error</b>\n\n{}",
"tutorial": (
" <b>To enable the widget, send this text to any chat:"
" </b><code>{STEAMNOW}</code>"
),
"configuring": "🙂 <b>Steam widget will be ready soon...</b>",
}
strings_ru = {
'_api_key': "Введите ваш SteamAPI Key. Получить его можно по туториалу:\n\n", # Линк на тутор
'_account_id': "Введите ваш Steam Account ID. Подробнее в туториале: \n\n", # Линк на тутор
'no_api_key_or_id': (
'<b>❌ Вы не указали ваш API_KEY или ACCOUNT_ID в конфиге.</b>\n'
'<b>🚨 Исправьте это для дальнейшей работы модуля</b>'
),
'noGame': "<b>❌ Игра не запущена, или у вас нет доступа</b>",
'steamNow': (
'💻 <b>В данный момент вы играете:</b>\n\n'
'🎮 <b>Название:</b> <code>{}</code>\n'
'🆔 <b>ID Игры: {}</b>'
),
'lite_gameInfo': (
'🎮 <b>Информация об игре:</b>\n\n'
'<b>Название: </b>{}\n'
'<b>Цена: {}</b>\n'
'<b>Описание:</b>\n- <i>{}</i>'
),
'steamMe': (
'<b>🎮 Ваш аккаунт:</b>\n\n'
'<b>Имя: </b><i>{}</i> (<i>{}</i>)\n'
'<b>В сети: </b><code>{}</code>\n'
'<b>Создан: </b><code>{}</code>\n'
'<b>Последние игры:</b>\n<i> • {}</i>'
),
'gameNotFound': '<b>🆔 Игры с таким идентификатором нет, попробуйте снова</b>',
"state": "🙂 <b>Steam виджеты: {}</b>\n{}",
"error": "<b>Steam error</b>\n\n{}",
"tutorial": (
" <b>Для включения виджета отправьте данный текст в любой чат:"
" </b><code>{STEAMNOW}</code>"
),
"configuring": "🙂 <b>Steam виджет скоро будет готов...</b>",
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
'API_KEY',
None,
doc=lambda: self.strings('_api_key'),
validator=loader.validators.Hidden(),
),
loader.ConfigValue(
'ACCOUNT_ID',
None,
doc=lambda: self.strings('_account_id')
),
loader.ConfigValue(
"update_interval",
300,
lambda: "Messages update interval. Not recommended < 300 seconds",
validator=loader.validators.Integer(minimum=60),
),
)
async def client_ready(self, client, db):
self.db.set(
"Steam",
"widgets",
list(map(tuple, self.db.get("Steam","widgets", [])))
)
self._task = asyncio.ensure_future(self._parse())
async def steam_requests(self, request, gameId: bool = None):
'''Function for requests to SteamAPI'''
api_key = self.config['API_KEY']
account_id = self.config['ACCOUNT_ID']
steam_client = SteamClient(api_key)
if request == 'SteamNow':
if not api_key or not account_id:
return('TokenError', None)
data = {'key': api_key, 'steamids': account_id}
response = steam_client.api_call('GET', 'ISteamUser', 'GetPlayerSummaries', 'v2', data).json()['response']
try:
gameId = response['players'][0]['gameid']
gameName = response['players'][0]['gameextrainfo']
text = self.strings('steamNow').format(gameName, gameId)
except:
text, gameId = self.strings('noGame'), None
return text, gameId #, photo
elif request == 'profileInfo':
if not api_key or not account_id:
return('TokenError', None, None, None, None, None)
url = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={}&steamids={}'
url2 = 'http://api.steampowered.com/IPlayerService/GetRecentlyPlayedGames/v0001/?key={}&steamid={}&format=json'
response = requests.get(url.format(self.config['API_KEY'], self.config['ACCOUNT_ID'])).json()['response']['players'][0]
recentGameInfo = requests.get(url2.format(self.config['API_KEY'], self.config['ACCOUNT_ID'])).json()['response']['games']
games = []
for game in recentGameInfo:
games.append(f'{game["name"]}: {game["playtime_2weeks"]}м. ({game["playtime_forever"]}м.)')
recentGames = '\n'.join(games)
return(
response['avatarfull'], # Profile photo
response['personaname'], # Name: 'ˢˡ ToxUniҨue,
response['realname'], # Realname: Tox.
datetime.datetime.fromtimestamp(response['lastlogoff']).isoformat().replace('T', ' '), # Последний раз в сети
datetime.datetime.fromtimestamp(response['timecreated']).isoformat().replace('T', ' '), # Дата создания аккаунта
recentGames
)
elif request == 'GameInfo':
if not api_key or not account_id:
return('TokenError', None)
url = f"http://store.steampowered.com/api/appdetails?appids={gameId}"
response = requests.get(url)
data = response.json()
game_data = data[str(gameId)]['data']
capsule_image = game_data.get('header_image', None)
name = game_data.get('name', None)
short_description = game_data.get('short_description', None)
price_overview = game_data.get('price_overview', None)
if price_overview:
initial_formatted_price = price_overview.get('initial_formatted', None)
final_formatted_price = price_overview.get('final_formatted', None)
else:
initial_formatted_price = None
final_formatted_price = None
final_price = f'{initial_formatted_price}' if initial_formatted_price == final_formatted_price else f'{final_formatted_price} (<u>{initial_formatted_price}</u>)'
text = self.strings('lite_gameInfo').format(name, final_price, short_description)
return capsule_image, text
async def game_info_i(
self,
call: InlineCall,
gameId: int,
message
):
_, text = await self.steam_requests('GameInfo', gameId)
if _ == 'TokenError':
return await call.edit(text=self.strings('no_api_key_or_id'))
await call.edit(text=text)
async def _parse(self, do_not_loop: bool = False):
while True:
if self.config["API_KEY"] == None or self.db.get("Steam", "state") == False:
await asyncio.sleep(5)
continue
for widget in self.db.get("Steam", "widgets", []):
now, _ = await self.steam_requests('SteamNow')
if now == 'TokenError':
await self._client.edit_message(*widget[:2], self.strings('no_api_key_or_id'))
elif now == self.strings('noGame'):
self.db.set('steam', 'inGame', None)
await self._client.edit_message(*widget[:2], self.strings('noGame'))
else:
in_game_time = self.db.get('steam', 'inGame')
if in_game_time is None:
self.db.set('steam', 'inGame', time.time())
game_time_minutes = 0
else:
game_time = time.time() - in_game_time
game_time_minutes = round(game_time / 60)
try:
await self._client.edit_message(*widget[:2], now + f'\n\n<b>🕓 В игре: {game_time_minutes} минут.</b>')
except:
return
await asyncio.sleep(int(self.config["update_interval"]))
@loader.command(
ru_doc=' - получить, во что я сейчас играю'
)
async def steamnow(self, message):
"""- get what I'm playing at"""
text, gameid = await self.steam_requests('SteamNow')
if text == self.strings('noGame'):
return await utils.answer(message, text)
elif text == 'TokenError':
return await utils.answer(message, self.strings('no_api_key_or_id'))
capsule_image, _ = await self.steam_requests('GameInfo', gameid)
await self.inline.form(
message=message,
photo=capsule_image,
text=text,
reply_markup=[
{
'text': 'Информация об игре',
'callback': self.game_info_i,
'args': (gameid, message,),
}
]
)
@loader.command(
ru_doc='- открыть аккаунт Steam'
)
async def sme(self, message):
'''- my steam account'''
photo, fullName, name, date1, date2, games = await self.steam_requests('profileInfo')
if photo == 'TokenError':
await utils.answer(message, self.strings('no_api_key_or_id'))
await utils.answer_file(
message,
photo,
caption=self.strings('steamMe').format(
fullName, name, date1, date2, games
)
)
@loader.command(
ru_doc='<id> - получить инфо об игре'
)
async def game(self, message):
'''<id> - get game info'''
args = utils.get_args_raw(message)
try:
capsule_image, text = await self.steam_requests('GameInfo', args)
if capsule_image == 'TokenError':
await utils.answer(message, self.strings('no_api_key_or_id'))
await utils.answer_file(message, capsule_image, text)
except:
await utils.answer(message, self.strings('gameNotFound'))
@loader.command(
ru_doc='- вкл/выкл виджеты SteamNow'
)
async def steamtoggle(self, message):
""" - toggle widgets updates"""
state = self.db.get('Steam', 'state')
state = True if state == False else False
self.db.set('Steam', 'state', state)
await utils.answer(
message,
self.strings("state").format(
"on" if state else "off", self.strings("tutorial") if state else ""
),
)
@loader.watcher()
async def watcher(self, message):
if (
self.db.get('Steam', 'state')
and (await self.client.get_messages(self.db.get('Steam', 'widgets')[0][0], ids=self.db.get('Steam', 'widgets')[0][1])).message == '❌ Вы не во что не играете'
):
now, _ = await self.steam_requests('SteamNow')
if now == self.strings('noGame') or now == 'TokenError':
return
await self._parse(do_not_loop=True)
try:
if "{STEAMNOW}" not in getattr(message, "text", "") or not message.out:
return
chat_id = utils.get_chat_id(message)
message_id = message.id
self.db.set(
"Steam",
"widgets",
self.db.get('steam', "widgets", []) + [(chat_id, message_id, message.text)],
)
await utils.answer(message, self.strings("configuring"))
await self._parse(do_not_loop=True)
except Exception as e:
logger.exception("Can't send widget")
await utils.answer(message, self.strings("error").format(e))

View File

@@ -0,0 +1,441 @@
__version__ = (1, 3, 1)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/TwinkManager.jpg
from telethon.tl.types import Message
from .. import loader, utils
@loader.tds
class TwinkManagerMod(loader.Module):
'''Управление твинками через основной аккаунт.'''
strings = {
"name": "Twink-Manager",
"pref1": "Префикс первого вашего твинка",
"pref2": "Префикс второго вашего твинка (если имеется)",
"pref3": "Префикс третьего вашего твинка (если имеется)",
"all_t": "Выполнять действия также и с вашего основного аккаунта?"
}
async def client_ready(self, client, db):
self._db = db
self._me = await client.get_me()
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"prefix_1",
"!",
doc=lambda: self.strings("pref1"),
),
loader.ConfigValue(
"prefix_2",
None,
doc=lambda: self.strings("pref2"),
),
loader.ConfigValue(
"prefix_3",
None,
doc=lambda: self.strings("pref3"),
),
loader.ConfigValue(
'all',
False,
doc=lambda: self.strings("all_t"),
validator=loader.validators.Boolean(),)
)
@loader.command()
async def trestart(self, message: Message):
"""- перезагрузить аккаунты"""
restart = 'restart --force'
p1 = self.config['prefix_1']
p2 = self.config['prefix_2']
p3 = self.config['prefix_3']
full = self.db.get(__name__, "allAcc")
if full:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{restart}')
await self.allmodules.commands["restart"](
await utils.answer(m, f"{self.get_prefix()}{restart}")
)
else:
m = await utils.answer(message, f'{p1}{restart}')
n = await utils.answer(m, f'{p2}{restart}')
await self.allmodules.commands["restart"](
await utils.answer(n, f"{self.get_prefix()}{restart}")
)
else:
m = await utils.answer(message, f'{p1}{restart}')
n = await utils.answer(m, f'{p2}{restart}')
o = await utils.answer(m, f'{p3}{restart}')
await self.allmodules.commands["restart"](
await utils.answer(o, f"{self.get_prefix()}{restart}")
)
else:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{restart}')
await utils.answer(m, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{restart}')
n = await utils.answer(m, f'{p2}{restart}')
await utils.answer(n, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{restart}')
n = await utils.answer(m, f'{p2}{restart}')
o = await utils.answer(m, f'{p3}{restart}')
await utils.answer(o, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
@loader.command()
async def tping(self, message: Message):
"""- проверить пинг"""
ping = 'ping'
p1 = self.config['prefix_1']
p2 = self.config['prefix_2']
p3 = self.config['prefix_3']
full = self.db.get(__name__, "allAcc")
if full:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{ping}')
await self.allmodules.commands["ping"](
await utils.answer(m, f"{self.get_prefix()}{ping}")
)
else:
m = await utils.answer(message, f'{p1}{ping}')
n = await utils.answer(m, f'{p2}{ping}')
await self.allmodules.commands["ping"](
await utils.answer(n, f"{self.get_prefix()}{ping}")
)
else:
m = await utils.answer(message, f'{p1}{ping}')
n = await utils.answer(m, f'{p2}{ping}')
o = await utils.answer(m, f'{p3}{ping}')
await self.allmodules.commands["ping"](
await utils.answer(o, f"{self.get_prefix()}{ping}")
)
else:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{ping}')
await utils.answer(m, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{ping}')
n = await utils.answer(m, f'{p2}{ping}')
await utils.answer(n, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{ping}')
n = await utils.answer(m, f'{p2}{ping}')
o = await utils.answer(m, f'{p3}{ping}')
await utils.answer(o, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
@loader.command()
async def tdlmod(self, message: Message):
""" <name/link> - загрузить модули на аккаунты"""
args = utils.get_args_raw(message)
dlmod = 'dlmod'
p1 = self.config['prefix_1']
p2 = self.config['prefix_2']
p3 = self.config['prefix_3']
full = self.db.get(__name__, "allAcc")
if full:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{dlmod} {args}')
await self.allmodules.commands["dlmod"](
await utils.answer(m, f"{self.get_prefix()}{dlmod} {args}")
)
else:
m = await utils.answer(message, f'{p1}{dlmod} {args}')
n = await utils.answer(m, f'{p2}{dlmod} {args}')
await self.allmodules.commands["dlmod"](
await utils.answer(n, f"{self.get_prefix()}{dlmod} {args}")
)
else:
m = await utils.answer(message, f'{p1}{dlmod} {args}')
n = await utils.answer(m, f'{p2}{dlmod} {args}')
o = await utils.answer(m, f'{p3}{dlmod} {args}')
await self.allmodules.commands["dlmod"](
await utils.answer(o, f"{self.get_prefix()}{dlmod} {args}")
)
else:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{dlmod} {args}')
await utils.answer(m, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{dlmod} {args}')
n = await utils.answer(m, f'{p2}{dlmod} {args}')
await utils.answer(n, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{dlmod} {args}')
n = await utils.answer(m, f'{p2}{dlmod} {args}')
o = await utils.answer(m, f'{p3}{dlmod} {args}')
await utils.answer(o, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
@loader.command()
async def tterminal(self, message: Message):
""" <command> - выполнить действие в терминале"""
args = utils.get_args_raw(message)
terminal = 'terminal'
p1 = self.config['prefix_1']
p2 = self.config['prefix_2']
p3 = self.config['prefix_3']
full = self.db.get(__name__, "allAcc")
if full:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{terminal} {args}')
await self.allmodules.commands["terminal"](
await utils.answer(m, f"{self.get_prefix()}{terminal} {args}")
)
else:
m = await utils.answer(message, f'{p1}{terminal} {args}')
n = await utils.answer(m, f'{p2}{terminal} {args}')
await self.allmodules.commands["terminal"](
await utils.answer(n, f"{self.get_prefix()}{terminal} {args}")
)
else:
m = await utils.answer(message, f'{p1}{terminal} {args}')
n = await utils.answer(m, f'{p2}{terminal} {args}')
o = await utils.answer(m, f'{p3}{terminal} {args}')
await self.allmodules.commands["terminal"](
await utils.answer(o, f"{self.get_prefix()}{terminal} {args}")
)
else:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{terminal} {args}')
await utils.answer(m, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{terminal} {args}')
n = await utils.answer(m, f'{p2}{terminal} {args}')
await utils.answer(n, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{terminal} {args}')
n = await utils.answer(m, f'{p2}{terminal} {args}')
o = await utils.answer(m, f'{p3}{terminal} {args}')
await utils.answer(o, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
@loader.command()
async def tupdate(self, message: Message):
"""- обновить хикку на аккаунтах"""
update = 'update --force'
p1 = self.config['prefix_1']
p2 = self.config['prefix_2']
p3 = self.config['prefix_3']
full = self.db.get(__name__, "allAcc")
if full:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{update}')
await self.allmodules.commands["update"](
await utils.answer(m, f"{self.get_prefix()}{update}")
)
else:
m = await utils.answer(message, f'{p1}{update}')
n = await utils.answer(m, f'{p2}{update}')
await self.allmodules.commands["update"](
await utils.answer(n, f"{self.get_prefix()}{update}")
)
else:
m = await utils.answer(message, f'{p1}{update}')
n = await utils.answer(m, f'{p2}{update}')
o = await utils.answer(m, f'{p3}{update}')
await self.allmodules.commands["update"](
await utils.answer(o, f"{self.get_prefix()}{update}")
)
else:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{update}')
await utils.answer(m, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{update}')
n = await utils.answer(m, f'{p2}{update}')
await utils.answer(n, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{update}')
n = await utils.answer(m, f'{p2}{update}')
o = await utils.answer(m, f'{p3}{update}')
await utils.answer(o, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
@loader.command()
async def thelp(self, message: Message):
""" <name/-f>- список модулей либо информация о модуле"""
args = utils.get_args_raw(message)
helpp = 'help'
p1 = self.config['prefix_1']
p2 = self.config['prefix_2']
p3 = self.config['prefix_3']
full = self.db.get(__name__, "allAcc")
if full:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{helpp} {args}')
await self.allmodules.commands["helpp"](
await utils.answer(m, f"{self.get_prefix()}{helpp} {args}")
)
else:
m = await utils.answer(message, f'{p1}{helpp} {args}')
n = await utils.answer(m, f'{p2}{helpp} {args}')
await self.allmodules.commands["helpp"](
await utils.answer(n, f"{self.get_prefix()}{helpp} {args}")
)
else:
m = await utils.answer(message, f'{p1}{helpp} {args}')
n = await utils.answer(m, f'{p2}{helpp} {args}')
o = await utils.answer(m, f'{p3}{helpp} {args}')
await self.allmodules.commands["helpp"](
await utils.answer(o, f"{self.get_prefix()}{helpp} {args}")
)
else:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{helpp} {args}')
await utils.answer(m, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{helpp} {args}')
n = await utils.answer(m, f'{p2}{helpp} {args}')
await utils.answer(n, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{helpp} {args}')
n = await utils.answer(m, f'{p2}{helpp} {args}')
o = await utils.answer(m, f'{p3}{helpp} {args}')
await utils.answer(o, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
@loader.command()
async def tloadmod(self, message: Message):
""" <reply> - загрузить файл модуля на аккаунты"""
ld = 'loadmod'
p1 = self.config['prefix_1']
p2 = self.config['prefix_2']
p3 = self.config['prefix_3']
full = self.db.get(__name__, "allAcc")
if full:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{ld}')
await self.allmodules.commands["loadmod"](
await utils.answer(m, f"{self.get_prefix()}{ld}")
)
else:
m = await utils.answer(message, f'{p1}{ld}')
n = await utils.answer(m, f'{p2}{ld}')
await self.allmodules.commands["loadmod"](
await utils.answer(n, f"{self.get_prefix()}{ld}")
)
else:
m = await utils.answer(message, f'{p1}{ld}')
n = await utils.answer(m, f'{p2}{ld}')
o = await utils.answer(m, f'{p3}{ld}')
await self.allmodules.commands["loadmod"](
await utils.answer(o, f"{self.get_prefix()}{ld}")
)
else:
tp2 = self.db.get(__name__, "prefixN2")
tp3 = self.db.get(__name__, "prefixN3")
if not tp3:
if not tp2:
m = await utils.answer(message, f'{p1}{ld}')
await utils.answer(m, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{ld}')
n = await utils.answer(m, f'{p2}{ld}')
await utils.answer(n, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
else:
m = await utils.answer(message, f'{p1}{ld}')
n = await utils.answer(m, f'{p2}{ld}')
o = await utils.answer(m, f'{p3}{ld}')
await utils.answer(o, '<emoji document_id=5213442551851262055>✔️</emoji> <b>Готово</b>')
@loader.watcher()
async def watcher(self, message: Message):
if not self.config['prefix_2']:
self.db.set(__name__, "prefixN2", False)
else:
self.db.set(__name__, "prefixN2", True)
if not self.config['prefix_3']:
self.db.set(__name__, "prefixN3", False)
else:
self.db.set(__name__, "prefixN3", True)
if self.config['all']:
self.db.set(__name__, 'allAcc', True)
else:
self.db.set(__name__, 'allAcc', False)

View File

@@ -0,0 +1,345 @@
__version__ = (1, 4, 2)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
import datetime
import logging
import time
from telethon import types
from telethon.tl.functions.account import UpdateProfileRequest
from telethon.tl.functions.users import GetFullUserRequest
from .. import loader, utils
from ..inline.types import InlineCall
logger = logging.getLogger(__name__)
@loader.tds
class TxAFKMod(loader.Module):
'''Афк модуль от AstroModules с изменением био и имени'''
async def client_ready(self, client, db):
self._db = db
self._me = await client.get_me()
strings = {
"name": "TxAFK",
"lname": "| afk.",
"lname0": " ",
"bt_off_afk": "⚠️ АФК режим отключен",
"bt_on_afk": "💤 АФК режим снова активен",
"_cfg_cst_btn": "Ссылка на чат которая будет отоброжаться вместе с уведомлением. (Чтобы вообще убрать напишите None)",
"standart_bio_text": "Кастомное описание профиля",
"feedback_bot__text": "Юзер вашего фидбэк бота (если имеется)",
"button__text": "Добавить инлайн кнопку отключения АФК режима?",
"custom_text__afk_text": "Кастомный текст афк. Используй {time} для вывода последнего времени нахождения в сети",
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"feedback_bot",
"None",
doc=lambda: self.strings("feedback_bot__text"),
),
loader.ConfigValue(
"custom_text__afk",
"None",
doc=lambda: self.strings("custom_text__afk_text"),
),
loader.ConfigValue(
"standart_bio",
"None",
doc=lambda: self.strings("standart_bio_text"),
),
loader.ConfigValue(
"custom_button",
[
"🦄 AstroModules 🦄",
"https://t.me/AstroModulesChat",
],
lambda: self.strings("_cfg_cst_btn"),
validator=loader.validators.Union(
loader.validators.Series(fixed_len=2),
loader.validators.NoneType(),
),
),
loader.ConfigValue(
"ignore_chats",
[],
lambda: "Чаты, в которых при упоминании TxAFК не будет срабатывать",
validator=loader.validators.Series(
validator=loader.validators.Union(
loader.validators.TelegramID(),
loader.validators.RegExp("[0-9]"),
),
),
),
loader.ConfigValue(
"button",
True,
doc=lambda: self.strings("button__text"),
validator=loader.validators.Boolean(),
)
)
async def txcfgcmd(self, message):
"""- открыть конфиг модуля"""
await self.allmodules.commands["config"](
await utils.answer(message, f"{self.get_prefix()}config TxAFK")
)
async def goafkcmd(self, message):
"""- войти в AFK режим"""
try:
user_id = (
(
(
await self._client.get_entity(
args if not args.isdigit() else int(args)
)
).id
)
if args
else reply.sender_id
)
except Exception:
user_id = self._tg_id
user = await self._client(GetFullUserRequest(user_id))
self._db.set(__name__, "afk", True)
self._db.set(__name__, "gone", time.time())
self._db.set(__name__, "ratelimit", [])
a_afk_bio_nofb = "В афк."
lastname = self.strings("lname")
if self.config['feedback_bot'] == None:
await message.client(UpdateProfileRequest(about=a_afk_bio_nofb, last_name=lastname))
else:
a_afk_bio = 'На данный момент в АФК. Связь только через '
feedback = self.config['feedback_bot']
aaa = a_afk_bio + feedback
await message.client(UpdateProfileRequest(about=aaa))
await self.allmodules.log("goafk")
await utils.answer(message, '<emoji document_id=5215519585150706301>👍</emoji> <b>АФК режим включен!</b>')
await message.client(UpdateProfileRequest(last_name=lastname))
async def ungoafkcmd(self, message):
"""- выйти из режима AFK"""
msg = await utils.answer(message, '<emoji document_id=5213107179329953547>⏰</emoji> <b>Отключаю режим АФК...</b>')
sbio = self.config['standart_bio']
lastname0 = self.strings('lname0')
self._db.set(__name__, "afk", False)
self._db.set(__name__, "gone", None)
self._db.set(__name__, "ratelimit", [])
await self.allmodules.log("unafk")
if sbio == None:
await message.client(UpdateProfileRequest(about='', last_name=lastname0))
else:
await message.client(UpdateProfileRequest(about=sbio, last_name=lastname0))
time.sleep(1)
await utils.answer(msg, '<emoji document_id=5220108512893344933>🆘</emoji> <b>Режим AFK отключен!</b>')
def _afk_custom_text(self) -> str:
now = datetime.datetime.now().replace(microsecond=0)
gone = datetime.datetime.fromtimestamp(
self._db.get(__name__, "gone")
).replace(microsecond=0)
time = now - gone
return (
"<b> </b>\n"
+ self.config["custom_text__afk"].format(
time=time,
)
)
async def watcher(self, message):
if not isinstance(message, types.Message):
return
if utils.get_chat_id(message) in self.config['ignore_chats']:
return
if message.mentioned or getattr(message.to_id, "user_id", None) == self._me.id:
afk_state = self.get_afk()
if not afk_state:
return
logger.debug("tagged!")
ratelimit = self._db.get(__name__, "ratelimit", [])
if utils.get_chat_id(message) in ratelimit:
return
else:
self._db.setdefault(__name__, {}).setdefault("ratelimit", []).append(
utils.get_chat_id(message)
)
self._db.save()
user = await utils.get_user(message)
if user.is_self or user.bot or user.verified:
logger.debug("User is self, bot or verified.")
return
if self.get_afk() is False:
return
now = datetime.datetime.now().replace(microsecond=0)
gone = datetime.datetime.fromtimestamp(
self._db.get(__name__, "gone")
).replace(microsecond=0)
time = now - gone
if self.config['custom_button'] == None:
if self.config["button"] == False:
if self.config["custom_text__afk"] == None:
await self.inline.form(message=message, text=f"<b>🔅 Я сейчас нахожусь в АФК.</b>\n\nПоследний раз был в сети <code>{time}</code> назад.")
else:
await self.inline.form(message=message, text=self._afk_custom_text())
elif self.config['button'] == True:
if self.config["custom_text__afk"] == None:
await self.inline.form(
message=message,
text=f"<b>🔅 Я сейчас нахожусь в АФК.</b>\n\nПоследний раз был в сети <code>{time}</code> назад.",
reply_markup=[
[
{
"text": "🚫 Выйти с афк 🚫",
"callback": self.button_cancel,
}
]
]
)
else:
await self.inline.form(
message=message,
text=self._afk_custom_text(),
reply_markup=[
[
{
"text": "🚫 Выйти с афк 🚫",
"callback": self.button_cancel,
}
]
]
)
else:
if self.config["button"] == False:
if self.config["custom_text__afk"] == None:
await self.inline.form(message=message, text=f"<b>🔅 Я сейчас нахожусь в АФК.</b>\n\nПоследний раз был в сети <code>{time}</code> назад.", reply_markup=[{"text": self.config['custom_button'][0], "url": self.config['custom_button'][1]}])
else:
await self.inline.form(message=message, text=self._afk_custom_text(), reply_markup=[{"text": self.config['custom_button'][0], "url": self.config['custom_button'][1]}])
elif self.config['button'] == True:
if self.config["custom_text__afk"] == None:
await self.inline.form(
message=message,
text=f"<b>🔅 Я сейчас нахожусь в АФК.</b>\n\nПоследний раз был в сети <code>{time}</code> назад.",
reply_markup=[
[
{
"text": self.config['custom_button'][0],
"url": self.config['custom_button'][1],
}
],
[
{
"text": "🚫 Выйти с афк 🚫",
"callback": self.button_cancel,
}
]
]
)
else:
await self.inline.form(
message=message,
text=self._afk_custom_text(),
reply_markup=[
[
{
"text": self.config['custom_button'][0],
"url": self.config['custom_button'][1],
}
],
[
{
"text": "🚫 Выйти с афк 🚫",
"callback": self.button_cancel,
}
]
]
)
async def button_cancel(self, call: InlineCall):
self._db.set(__name__, "afk", False)
self._db.set(__name__, "gone", None)
self._db.set(__name__, "ratelimit", [])
await self.allmodules.log("unafk")
if self.config['standart_bio'] == None:
lastname = self.strings("lname0")
about = self.strings("lname0")
await self._client(UpdateProfileRequest(about=about, last_name=lastname))
else:
aboutt = self.config['standart_bio']
lastname = self.strings("lname0")
await self._client(UpdateProfileRequest(about=aboutt, last_name=lastname))
await call.edit(
self.strings["bt_off_afk"],
reply_markup=[
{
"text": "🔰 Войти в афк 🔰",
"callback": self.button_cancel_on,
}
]
)
async def button_cancel_on(self, call: InlineCall):
self._db.set(__name__, "afk", True)
self._db.set(__name__, "gone", time.time())
self._db.set(__name__, "ratelimit", [])
a_afk_bio_nofb = "В афк."
lastname = self.strings("lname")
if self.config['feedback_bot'] == None:
await self._client(UpdateProfileRequest(about=a_afk_bio_nofb, last_name=lastname))
else:
a_afk_bio = 'На данный момент в АФК. Связь только через '
feedback = self.config['feedback_bot']
aaa = a_afk_bio + feedback
await self._client(UpdateProfileRequest(about=aaa))
await call.edit(
self.strings["bt_on_afk"],
reply_markup=[
{
"text": "🚫 Выйти с афк 🚫",
"callback": self.button_cancel,
}
]
)
def get_afk(self):
return self._db.get(__name__, "afk", False)

View File

@@ -0,0 +1,53 @@
__version__ = (1, 1, 1)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/YaMusic.jpg
from .. import loader, utils
class YaMusicMod(loader.Module):
'''Поиск музыки через музыкального бота от Яндекса'''
strings = {
"name": "YandexMusic",
"na": "😅 <b>А что искать то?</b>",
"searching": "<b>Поиск...</b>",
}
async def ymcmd(self, message):
"""- найти трек по названию"""
args = utils.get_args_raw(message)
bot = '@music_yandex_bot'
if not args:
await utils.answer(message, self.strings("na"))
try:
await utils.answer(message, self.strings("searching"))
music = await message.client.inline_query(bot, args)
await message.delete()
try:
await utils.answer_file(message, music[1].result.document, caption="<b>🎧 Возможно, это тот трек, который вы искали</b>")
except Exception:
await utils.answer_file(message, music[3].result.document, caption="<b>🎧 Возможно, это тот трек, который вы искали</b>")
except Exception:
await utils.answer(message, f"<b>😔 Нам не удалось найти трек с названием <code>{args}</code><b>")

View File

@@ -0,0 +1,290 @@
__version__ = (1, 0, 0)
import json
import random
import string
import logging
import asyncio
import aiohttp
from .. import loader, utils
from yandex_music import ClientAsync
from telethon.tl.types import ChatAdminRights
from telethon.tl.functions.channels import EditAdminRequest
# https://github.com/FozerG/YandexMusicRPC/blob/main/main.py#L133
async def get_current_track(client, token):
device_info = {"app_name": "Chrome","type": 1,}
ws_proto = {
"Ynison-Device-Id": "".join([random.choice(string.ascii_lowercase) for _ in range(16)]),
"Ynison-Device-Info": json.dumps(device_info),
}
timeout = aiohttp.ClientTimeout(total=15, connect=10)
try:
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.ws_connect(
url="wss://ynison.music.yandex.ru/redirector.YnisonRedirectService/GetRedirectToYnison",
headers={
"Sec-WebSocket-Protocol": f"Bearer, v2, {json.dumps(ws_proto)}",
"Origin": "http://music.yandex.ru",
"Authorization": f"OAuth {token}",
},
timeout=10,
) as ws:
recv = await ws.receive()
data = json.loads(recv.data)
if "redirect_ticket" not in data or "host" not in data:
print(f"Invalid response structure: {data}")
return {"success": False}
new_ws_proto = ws_proto.copy()
new_ws_proto["Ynison-Redirect-Ticket"] = data["redirect_ticket"]
to_send = {
"update_full_state": {
"player_state": {
"player_queue": {
"current_playable_index": -1,
"entity_id": "",
"entity_type": "VARIOUS",
"playable_list": [],
"options": {"repeat_mode": "NONE"},
"entity_context": "BASED_ON_ENTITY_BY_DEFAULT",
"version": {
"device_id": ws_proto["Ynison-Device-Id"],
"version": 9021243204784341000,
"timestamp_ms": 0,
},
"from_optional": "",
},
"status": {
"duration_ms": 0,
"paused": True,
"playback_speed": 1,
"progress_ms": 0,
"version": {
"device_id": ws_proto["Ynison-Device-Id"],
"version": 8321822175199937000,
"timestamp_ms": 0,
},
},
},
"device": {
"capabilities": {
"can_be_player": True,
"can_be_remote_controller": False,
"volume_granularity": 16,
},
"info": {
"device_id": ws_proto["Ynison-Device-Id"],
"type": "WEB",
"title": "Chrome Browser",
"app_name": "Chrome",
},
"volume_info": {"volume": 0},
"is_shadow": True,
},
"is_currently_active": False,
},
"rid": "ac281c26-a047-4419-ad00-e4fbfda1cba3",
"player_action_timestamp_ms": 0,
"activity_interception_type": "DO_NOT_INTERCEPT_BY_DEFAULT",
}
async with session.ws_connect(
url=f"wss://{data['host']}/ynison_state.YnisonStateService/PutYnisonState",
headers={
"Sec-WebSocket-Protocol": f"Bearer, v2, {json.dumps(new_ws_proto)}",
"Origin": "http://music.yandex.ru",
"Authorization": f"OAuth {token}",
},
timeout=10,
method="GET",
) as ws:
await ws.send_str(json.dumps(to_send))
recv = await asyncio.wait_for(ws.receive(), timeout=10)
ynison = json.loads(recv.data)
track_index = ynison["player_state"]["player_queue"]["current_playable_index"]
if track_index == -1:
print("No track is currently playing.")
return {"success": False}
track = ynison["player_state"]["player_queue"]["playable_list"][track_index]
await session.close()
info = await client.tracks_download_info(track["playable_id"], True)
track = await client.tracks(track["playable_id"])
res = {
"paused": ynison["player_state"]["status"]["paused"],
"duration_ms": ynison["player_state"]["status"]["duration_ms"],
"progress_ms": ynison["player_state"]["status"]["progress_ms"],
"entity_id": ynison["player_state"]["player_queue"]["entity_id"],
"repeat_mode": ynison["player_state"]["player_queue"]["options"]["repeat_mode"],
"entity_type": ynison["player_state"]["player_queue"]["entity_type"],
"track": track,
"info": info,
"success": True,
}
return res
except Exception as e:
print(f"Failed to get current track: {str(e)}")
return {"success": False}
class YmLive(loader.Module):
'''Модуль для демонстрации играющей песни в Яндекс.Музыке'''
strings = {
"name": "YandexMusicLive",
"_text_token": "Токен аккаунта Яндекс Музыки",
"_text_id": "ID канала, который будет использоваться для показа треков...",
"on/off": "YandexMusicLive теперь {}",
'channel_id_error': "В конфиге не указан ID канала. Исправь это!",
"_from_bot_channel_error": (
"Не найден ID канала в конфиге. Пожалуйста исправь это для "
"дальнейшего использования модуля..."
),
'token_from_YmNow': (
"У вас установлен модуль YmNow и в его конфиге я нашел токен. "
"Для вашего удобства токен автоматически выставлен в конфиг. "
"Приятного использования :)"
),
"tutor": (
"🎉 Добро пожаловать в модуль YandexMusicLive!\n"
"Вы успешно загрузили модуль, который позволяет отображать играющую музыку "
"из Яндекс.Музыки прямо в названии вашего канала!\n\n"
"🌟 Чтобы модуль начал работать, выполните следующие шаги:\n"
"1) <b>Создайте канал:</b> Cоздайте новый канал, в котором будет "
"отображаться играющий сейчас трек, и закрепите этот канал в своем профиле.\n\n"
"2) <b>Настройка токена Яндекс.Музыки:</b> Перейдите в <code>{}config YandexMusicLive</code>"
" -> YandexMusicToken и вставьте ваш токен Яндекс.Музыки. <a href='{}'>(Туториал на получение токена)</a>\n\n"
"3) <b>Настройка ID канала:</b> Перейдите в <code>{}config YandexMusicLive</code> -> channel_id"
" и вставьте ID вашего канала. \n Если вы не знаете, как получить ID канала - Напишите в канал"
" сообщение с текстом <code>{}e m.chat.id</code> и вставьте в конфиг то, что вам выдаст ЮзерБот\n\n"
"4) <b>Переустановите модуль</b> После выполнения всех настроек переустановите модуль, чтобы завершить процесс настройки."
)
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"YandexMusicToken",
None,
lambda: self.strings["_text_token"],
validator=loader.validators.Hidden()
),
loader.ConfigValue(
"channel_id",
None,
lambda: self.strings["_text_id"],
validator=loader.validators.TelegramID()
),
)
async def client_ready(self, client, db):
"""Инициализация клиента и базы данных"""
self.client = client
self.db = db
async def on_dlmod(self):
"""Действия при загрузке модуля"""
if self.get("new_") != False:
await self.inline.bot.send_message(
self.client._tg_id,
self.strings("tutor").format(
self.get_prefix(),
"https://github.com/MarshalX/yandex-music-api/discussions/513#discussioncomment-2729781",
self.get_prefix(),
self.get_prefix()
)
)
self.set("new_", False)
if self.config["YandexMusicToken"] and self.config["YandexMusicToken"].startswith("y0_"):
await self.add_bot_to_channel(self.config["channel_id"])
async def add_bot_to_channel(self, channel_id):
"""Добавление бота в канал и выдача прав администратора"""
try:
await self._client(
EditAdminRequest(
channel=int(channel_id),
user_id=self.inline.bot_username,
admin_rights=ChatAdminRights(change_info=True),
rank="YandexMusicLiveBot"
)
)
self.set("ymlive_bot_added", True)
except Exception as e:
logging.error(f"Не удалось выдать боту права в канале: {e}")
async def get_current_track(self, token):
"""Получение информации о текущем треке из Яндекс.Музыки"""
try:
client = ClientAsync(token)
await client.init()
respond = await get_current_track(client, token)
track = respond.get("track")
if not track:
return None
return {
"title": track[0]["title"],
"artists": [artist["name"] for artist in track[0]["artists"]],
"duration_ms": int(track[0]["duration_ms"])
}
except Exception as e:
logging.error(f"Ошибка при получении трека: {e}")
return None
async def update_channel_title(self, channel_id, track_name):
"""Обновление названия канала, если оно отличается от текущего трека"""
try:
channel_info = await self.client.get_fullchannel(channel_id)
current_title = channel_info.chats[0].title.split(' - ')[0]
new_title = track_name.split(' - ')[0]
if current_title != new_title:
await self.inline.bot.set_chat_title(int(f'-100{channel_id}'), track_name)
messages = await self._client.get_messages(channel_id, limit=1)
if messages and messages[0].action:
await messages[0].delete()
except Exception as e:
logging.error(f"Ошибка при изменении названия канала: {e}")
@loader.command(ru_doc="- включить/выключить YaLive")
async def yalive(self, message):
"""Включение или выключение автоматического обновления названия канала"""
if not self.config["channel_id"]:
await utils.answer(message, self.strings["channel_id_error"])
return
if not self.get("ymlive_bot_added"):
await self.add_bot_to_channel(self.config["channel_id"])
autochannel_status = self.get("autochannel", False)
self.set("autochannel", not autochannel_status)
status_text = "enabled" if not autochannel_status else "disabled"
await utils.answer(message, self.strings["on/off"].format(status_text))
@loader.loop(interval=30, autostart=True)
async def autochannel_loop(self):
"""Цикл для автоматического обновления названия канала каждые 30 секунд"""
if not self.get("autochannel"):
return
if not self.config["channel_id"]:
await self.inline.bot.send_message(self.client._tg_id, self.strings["_from_bot_channel_error"])
self.set("autochannel", False)
return
try:
track_info = await self.get_current_track(self.config["YandexMusicToken"])
if track_info:
artists = ", ".join(track_info["artists"])
track_name = f"{track_info['title']} - {utils.escape_html(artists)}"
await self.update_channel_title(self.config["channel_id"], track_name)
except Exception as e:
logging.error(f"Ошибка в autochannel_loop: {e}")

View File

@@ -0,0 +1,245 @@
__version__ = (1, 0, 0)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/Achievements.jpg
# meta developer: @AstroModules
# requires: pillow
import base64
import io
import os
import re
from typing import Union
import requests
from hikkatl.tl.types import MessageMediaDocument, MessageMediaPhoto
from PIL import Image
from .. import loader, utils
MIME_TYPES = ["webp", "png", "jpeg", "jpg", "bmp", "dds", "dib", "eps", "ico", "tiff"]
def is_hex_color(value: str):
return True if re.match(r'^#(?:[0-9a-fA-F]{1,2}){3}$', value) else False
class HexColorValidator(loader.validators.Validator):
"""#HexColor Validator"""
def __init__(self):
super().__init__(
self._validate,
{
"en": "hex color in format #RRGGBB",
"ru": "цвет в формате #RRGGBB"
}
)
@staticmethod
def _validate(value) -> str:
if not isinstance(value, str):
raise loader.validators.ValidationError("Value must be a string - valid hex color in format #RRGGBB")
try:
if not is_hex_color(value):
raise Exception()
except Exception:
raise loader.validators.ValidationError(f"Passed value ({value}) is not a valid hex color in format #RRGGBB")
return value
class AchievementsMod(loader.Module):
"""Create the achievement from https://minecraft-inside.ru/achievements/
Idea from @Den4ikSOP & @boyhao
"""
strings = {
"name": "Achievements",
"text_color_cfg": "Text color in format #RRGGBB (hex, default #ffffff)",
"title_color_cfg": "Title color in format #RRGGBB (hex, default #ffff00)",
"icon_id_cfg": "Icon ID (1-1099, default 893) from https://minecraft-inside.ru/achievements/ (row number * 15 + icon number in row from 1 to 15)",
"invalid_length": "🚫 The length of the text must be between 1 and 45 characters",
"invalid_icon_id": "🚫 The icon ID must be between 1 and 1099",
"invalid_color": "🚫 The color must be in the format #RRGGBB",
"title_cfg": "Title of achievement (no more than 45 characters)",
}
strings_ru = {
"_cls_doc": "Создает достижение из https://minecraft-inside.ru/achievements/\n\nIdea from @Den4ikSOP & @boyhao",
"text_color_cfg": "Цвет текста в формате #RRGGBB (hex, по умолчанию #ffffff)",
"title_color_cfg": "Цвет заголовка в формате #RRGGBB (hex, по умолчанию #ffff00)",
"icon_id_cfg": "ID иконки (от 1 до 1099) из https://minecraft-inside.ru/achievements/ (номер строки * 15 + номер иконки в строке от 1 до 15)",
"invalid_length": "🚫 Длина текста должна быть между 1 и 45 символами",
"invalid_icon_id": "🚫 ID иконки должен быть между 1 и 1099",
"invalid_color": "🚫 Цвет должен быть в формате #RRGGBB",
"title_cfg": "Заголовок достижения (не более 45 символов)",
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"text_color",
"#ffffff",
lambda: self.strings("text_color_cfg"),
validator=HexColorValidator(),
),
loader.ConfigValue(
"title_color",
"#ffff00",
lambda: self.strings("title_color_cfg"),
validator=HexColorValidator(),
),
loader.ConfigValue(
"icon_id",
893,
lambda: self.strings("icon_id_cfg"),
validator=loader.validators.Integer(minimum=1, maximum=1099),
),
loader.ConfigValue(
"title",
"Новое достижение!",
lambda: self.strings("title_cfg"),
validator=loader.validators.String(min_len=1, max_len=45),
)
)
async def download_media(self, message):
media = None
msg = None
if message.media:
media, msg = message.media, message
elif (reply := await message.get_reply_message()) and reply.media:
media, msg = reply.media, reply
if not (media and msg) or getattr(msg, "sticker") or not isinstance(media, (MessageMediaDocument, MessageMediaPhoto)):
return False
if (isinstance(media, MessageMediaDocument) and media.document) and (not (image := re.match(r"image/(.*)", media.document.mime_type)) or image.group(1) not in MIME_TYPES):
return False
return await msg.download_media()
def generateAchievement(
self,
title: str,
text: str,
icon: Union[str, bytes, io.BytesIO],
title_color: str,
text_color: str,
file_mime_type: str = "png"
):
if len(text) > 45 or len(title) > 45:
raise ValueError(self.strings("invalid_length"))
if isinstance(icon, str) and icon.isdigit() or isinstance(icon, int):
data_icon = f"i{icon}"
elif isinstance(icon, (bytes, io.BytesIO)):
if isinstance(icon, io.BytesIO):
icon = icon.getvalue()
data_icon = f"data:image/{file_mime_type};base64,{base64.b64encode(icon).decode()}"
return requests.post(
"https://den4iksop.org/tg-stickers-api/achievement",
json={
"title": title,
"text": text,
"data_icon": data_icon,
"title_color": title_color,
"text_color": text_color
}
)
async def create_achievement(self, message):
args: list[str] = utils.get_args(message)
title_color = self.config["title_color"]
text_color = self.config["text_color"]
icon = self.config["icon_id"]
for arg in args.copy():
if arg == "-icon":
icon = args[args.index(arg) + 1]
if not icon.isdigit() or not 0 < int(icon) < 1099:
raise ValueError(self.strings("invalid_icon_id"))
args.pop(args.index(icon))
elif arg == "-text-color":
text_color = args[args.index(arg) + 1]
if not is_hex_color(text_color):
raise ValueError(self.strings("invalid_color"))
args.pop(args.index(text_color))
elif arg == "-title-color":
title_color = args[args.index(arg) + 1]
if not is_hex_color(title_color):
raise ValueError(self.strings("invalid_color"))
args.pop(args.index(title_color))
else:
continue
args.pop(args.index(arg))
file_name = await self.download_media(message)
if file_name:
image = Image.open(file_name)
resized_image = image.resize((32, 32))
file = io.BytesIO()
resized_image.save(file, format="PNG")
file.seek(0)
count = len(args)
achievement_response = await utils.run_sync(
self.generateAchievement,
title=args[0] if count == 2 else self.config["title"],
text=args[1] if count == 2 else args[0],
icon=file if file_name else icon,
title_color=title_color,
text_color=text_color
)
if file_name:
os.remove(file_name)
b64file = achievement_response.json()["image"][22:]
return base64.b64decode(b64file)
@loader.command(
ru_doc="[Заголовок] \"<текст>\" [-icon <id>] [-title-color #<цвет>] [-text-color #<цвет>]",
alias="ach",
)
async def achievement(self, message):
"""[title] \"<text>\" [-icon <id>] [-title-color #<color>] [-text-color #<color>]"""
try:
sticker_file = await self.create_achievement(message)
except ValueError as e:
await utils.answer(message, str(e))
return
sticker = await self.client.upload_file(sticker_file)
sticker.name = "achievement.webp"
if not (msg := await message.get_reply_message()):
msg = message
await utils.answer_file(message, sticker, reply_to=msg)

View File

@@ -0,0 +1,237 @@
__version__ = (1, 0, 5)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/Akinator.jpg
# meta developer: @AstroModules
import random
import akinator
import deep_translator
from .. import loader, utils
from ..inline.types import InlineCall
aki_photo = "https://graph.org/file/3cc8825c029fd0cab9edc.jpg"
aki_failed = "https://0x0.st/H1rk.jpg"
emojies = ["😏", "🫢", "🤔", "🫣", "🫤", "😉", "😒"]
@loader.tds
class AkinatorGame(loader.Module):
"""
Akinator will guess any character you have in mind,
You just need to answer a couple of questions)
"""
strings = {
"name": "Akinator",
"child_mode": "Child mode. If enabled, it will be easier to guess 18+ heroes",
"failed": "❌ Failed",
"start": "🔮 Start",
"text": "🔮 <b>Guess any character you have in mind, and click on the Start button</b>",
"target_lang": "Target language",
"yes": "Yes",
"no": "No",
"idk": "I don't know",
"probably": "Probably",
"probably_not": "Probably not",
"this_is": "<b>This is {name}\n{description}</b>",
"not_right": "Not right",
}
strings_ru = {
"_cls_doc": "Акинатор угадает любого вами загаданного персонажа, стоит лишь ответить на пару вопросов)",
"child_mode": "Детский режим. Если включен, то будет сложнее отгадать 18+ героев",
"failed": "🚫 Не удалось угадать персонажа",
"start": "🔮 Начать",
"text": "🔮 <b>Задумайте реального или вымышленного персонажа, и нажмите начать</b>",
"target_lang": "Язык для перевода",
"yes": "Да",
"no": "Нет",
"idk": "Не знаю",
"probably": "Возможно",
"probably_not": "Скорее нет",
"this_is": "<b>Это {name}\n{description}</b>",
"not_right": "Это не он",
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"child_mode",
True,
lambda: self.strings("child_mode"),
validator=loader.validators.Boolean()
),
loader.ConfigValue(
"target_lang",
"en",
lambda: self.strings("target_lang"),
validator=loader.validators.String()
)
)
async def client_ready(self):
self.games = {}
@loader.command(
ru_doc="- начать игру",
)
async def akinator(self, message):
"""- start the game"""
sta = akinator.Akinator()
self.games.update({message.chat_id: {message.id: sta}})
await self.inline.form(
message=message,
photo=aki_photo,
text=self.strings("text"),
reply_markup={
"text": self.strings("start"),
"callback": self.doai,
"args": (message,),
}
)
async def doai(self, call: InlineCall, message):
chat_id = int(message.chat_id)
mid = int(message.id)
qu = self.games[chat_id][mid].start_game(child_mode=self.config["child_mode"])
text = deep_translator.GoogleTranslator(
source="auto",
target=self.config["target_lang"]
).translate(qu)
emo = random.choice(emojies)
await call.edit(
f"{emo} <b>{text}</b>",
reply_markup=[
[
{
"text": self.strings("yes"),
"callback": self.cont,
"args": ("Yes", message,),
},
{
"text": self.strings("no"),
"callback": self.cont,
"args": ("No", message,),
},
{
"text": self.strings("idk"),
"callback": self.cont,
"args": ("Idk", message,),
}
],
[
{
"text": self.strings("maybe"),
"callback": self.cont,
"args": ("Probably", message,),
},
{
"text": self.strings("maybe_not"),
"callback": self.cont,
"args": ("Probably Not", message,),
}
]
]
)
async def cont(
self,
call: InlineCall,
args: str,
message
):
chat_id = message.chat_id
mid = message.id
gm = self.games[chat_id][mid]
text = gm.answer(args)
try:
if gm.progression >= 85:
gm.win()
gs = gm.first_guess
text = self.strings("this_is").format(name=gs["name"], description=gs["description"])
await call.edit(
text,
photo=gs["absolute_picture_path"],
reply_markup=[
{
"text": self.strings("not_right"),
"callback": self.cont,
"args": ("No", message,),
},
]
)
else:
text = deep_translator.GoogleTranslator(
source="auto",
target=self.config["target_lang"]
).translate(text)
emo = random.choice(emojies)
await call.edit(
text=f"{emo} <b>{text}</b>",
photo=aki_photo,
reply_markup=[
[
{
"text": self.strings("yes"),
"callback": self.cont,
"args": ("Yes", message,),
},
{
"text": self.strings("no"),
"callback": self.cont,
"args": ("No", message,),
},
{
"text": self.strings("idk"),
"callback": self.cont,
"args": ("Idk", message,),
}
],
[
{
"text": self.strings("maybe"),
"callback": self.cont,
"args": ("Probably", message,),
},
{
"text": self.strings("maybe_not"),
"callback": self.cont,
"args": ("Probably Not", message,),
}
]
]
)
except akinator.exceptions.AkinatorQuestionOutOfRangeException:
await call.edit(
text=self.strings("failed"),
photo=aki_failed
)

View File

@@ -0,0 +1,714 @@
__version__ = (2, 1, 4)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/AstroAFK.jpg
# meta developer: @AstroModules
import asyncio
import datetime
import time
from telethon import types
from telethon.tl.functions.account import UpdateProfileRequest
from telethon.tl.functions.users import GetFullUserRequest
from .. import loader, utils
from ..inline.types import InlineCall
class AstroAfkMod(loader.Module):
"""Полностью настраиваемый модуль для ухода в АФК режим! Обновление TxAFK!"""
async def client_ready(self, client, db):
self._me = await client.get_me()
strings = {
"name": "AstroAFK",
"lname": "| afk.",
"bt_off_afk": "🚫 <b>АФК</b> режим <b>отключен</b>!",
"_cfg_cst_btn": "Ссылка на чат, которая будет находиться под текстом АФК. Чтобы вовсе убрать, напишите None",
"feedback_bot__text": "Юзернейм вашего feedback бота. Если нету - не трогайте",
"button__text": "Добавить инлайн кнопку отключения АФК режима?",
"custom_text__afk_text": "Кастомный текст афк. Используй {time} для вывода последнего времени нахождения в сети и {reason} для указания причины ухода в афк",
}
def render_settings(self):
"""Settings message"""
active = self._db.get(__name__, "afk")
a_active = "Включен ✅" if active else "Выключен 🚫"
change_bio = self._db.get(__name__, "change_bio")
a_change_bio = "Да" if change_bio else "Нет"
change_name = self._db.get(__name__, "change_name")
a_change_name = "Да" if change_name else "Нет"
fb = self.config["feedback"]
text = (
f"🎆 <b>AstroAfk</b>\n"
f"<b>├{a_active}</b>\n"
f"<b>├Смена биографии:</b> <code>{a_change_bio}</code> 📖\n"
f"<b>├Смена префикса:</b> <code>{a_change_name}</code> 📝\n"
f"<b>└Бот для связи:</b> <code>@{fb}</code> 🤖"
)
return text
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"prefix",
"| afk.",
doc=lambda: "Префикс, который будет добавляться к вашему имени во время входа в АФК"
),
loader.ConfigValue(
"feedback",
None,
doc=lambda: self.strings("feedback_bot__text"),
),
loader.ConfigValue(
"about_text",
None,
doc=lambda: "Текст, который будет выставляться в био при входе в АФК. Используйте {bot} для указания фидбэк бота и {reason} для причины."
),
loader.ConfigValue(
"afk_text",
"None",
doc=lambda: self.strings("custom_text__afk_text"),
),
loader.ConfigValue(
"link_button",
None,
lambda: self.strings("_cfg_cst_btn"),
validator=loader.validators.Union(
loader.validators.Series(fixed_len=2),
loader.validators.NoneType()
),
),
loader.ConfigValue(
"ignore_chats",
[1554874075],
lambda: "Чаты, в которых AstroAfk не будет срабатывать (По умолчанию выставлен Support chat хикки, лучше не убирать его)",
validator=loader.validators.Series(
validator=loader.validators.Union(
loader.validators.TelegramID(),
loader.validators.RegExp("[0-9]"),
),
),
),
loader.ConfigValue(
"button",
True,
doc=lambda: self.strings("button__text"),
validator=loader.validators.Boolean(),
)
)
def _afk_custom_text(self) -> str:
"""Custom text afk"""
now = datetime.datetime.now().replace(microsecond=0)
gone = datetime.datetime.fromtimestamp(
self._db.get(__name__, "gone")
).replace(microsecond=0)
time = now - gone
reason = self._db.get(__name__, "reason")
return (
"<b> </b>\n"
+ self.config["afk_text"].format(
time=time,
reason=reason,
)
)
def _afk_about_text(self) -> str:
"""Custom text about"""
bot = self.config["feedback"]
reason = self._db.get(__name__, "reason")
return (
""
+ self.config["about_text"].format(
bot=bot,
reason=reason
)
)
@loader.command()
async def asst(self, message):
"""- открыть настройки модуля"""
await self.inline.form(
message=message,
text="<b>⚙️ Открыть настройки</b>",
reply_markup=[{"text": "🔴 Открыть", "callback": self.settings}],
silent=True
)
@loader.command()
async def goafk(self, message):
""" <reason/empty>- войти в АФК режим"""
reason = utils.get_args_raw(message)
if "-n" in reason:
reason = reason.replace("-n", "")
self._db.set(__name__, "force", True)
if not reason:
self._db.set(__name__, "reason", "­")
else:
self._db.set(__name__, "reason", reason)
user_id = self._tg_id
user = await self._client(GetFullUserRequest(user_id))
self._db.set(__name__, "afk", True)
self._db.set(__name__, "gone", time.time())
self._db.set(__name__, "ratelimit", [])
change_bio = self._db.get(__name__, "change_bio")
change_name = self._db.get(__name__, "change_name")
about = user.full_user.about
self._db.set(__name__, "about", about)
if change_name:
prefix = self.config["prefix"]
await message.client(UpdateProfileRequest(last_name=prefix))
if change_bio:
cfg_bio = self.config["about_text"]
if not cfg_bio:
await message.client(UpdateProfileRequest(about="Нахожусь в афк."))
else:
bio = self._afk_about_text()
await message.client(UpdateProfileRequest(about=bio))
m = await utils.answer(message, "<emoji document_id=5188391205909569136>✅</emoji> <b>АФК</b> режим был успешно <b>включен</b>!")
await asyncio.sleep(5)
await m.delete()
@loader.command()
async def ungoafk(self, message):
"""- выйти из режима АФК"""
self._db.set(__name__, "afk", False)
self._db.set(__name__, "gone", None)
self._db.set(__name__, "ratelimit", [])
change_bio = self._db.get(__name__, "change_bio")
change_name = self._db.get(__name__, "change_name")
if self._db.get(__name__, "force"):
self._db.set(__name__, "force", False)
if change_name:
await message.client(UpdateProfileRequest(last_name=" "))
if change_bio:
try:
await message.client(UpdateProfileRequest(about=f"{self.db.get(__name__, 'about')}"))
except:
await message.client(UpdateProfileRequest(about="@AstroOfftop - лучший чат для общения."))
m = await utils.answer(message, "<emoji document_id=5465665476971471368>❌</emoji> <b>АФК</b> режим был успешно <b>выключен</b>!")
await self.allmodules.log("AstroAfk now stoped.")
await asyncio.sleep(5)
await m.delete()
@loader.watcher()
async def watcher(self, message):
if not isinstance(message, types.Message):
return
if utils.get_chat_id(message) in self.config["ignore_chats"]:
return
if message.mentioned or getattr(message.to_id, "user_id", None) == self._me.id:
afk_state = self.get_afk()
if not afk_state:
return
ratelimit = self._db.get(__name__, "ratelimit", [])
if utils.get_chat_id(message) in ratelimit:
return
else:
self._db.setdefault(__name__, {}).setdefault("ratelimit", []).append(
utils.get_chat_id(message)
)
self._db.save()
user = await utils.get_user(message)
if user.is_self or user.bot or user.verified:
return
if self.get_afk() is False:
return
now = datetime.datetime.now().replace(microsecond=0)
gone = datetime.datetime.fromtimestamp(
self._db.get(__name__, "gone")
).replace(microsecond=0)
time = now - gone
reason = self._db.get(__name__, "reason")
if self._db.get(__name__, "forcenot "):
if not self.config["link_button"]:
if self.config["buttonnot "]:
if not self.config["afk_text"]:
await self.inline.form(
message=message,
text=f"<b>😴 Сейчас я в АФК режиме</b>\n\n❇️ Был <b>онлайн</b>: <code>{time}</code> назад.\n📝 Ушел по <b>причине:</b> {reason}",
reply_markup=[
{
"text": "🚫 Закрыть",
"callback": self.callback_handler_ok,
"args": (message.chat.id,)
}
],
silent=True
)
else:
await self.inline.form(
message=message,
text=self._afk_custom_text(),
reply_markup=[
{
"text": "🚫 Закрыть",
"callback": self.callback_handler_ok,
"args": (message.chat.id, )
}
],
silent=True
)
elif self.config["button"]:
if not self.config["afk_text"]:
await self.inline.form(
message=message,
text=f"<b>😴 Сейчас я в АФК режиме</b>\n❇️ Был <b>онлайн</b>: <code>{time}</code> назад.\n📝 Ушел по <b>причине:</b> {reason}",
reply_markup=[
[
{
"text": "🥱 Выйти из АФК",
"callback": self.button_cancel,
}
],
[
{
"text": "🚫 Закрыть",
"callback": self.callback_handler_ok,
"args": (message.chat.id,)
}
]
],
silent=True
)
else:
await self.inline.form(
message=message,
text=self._afk_custom_text(),
reply_markup=[
[
{
"text": "🥱 Выйти из АФК",
"callback": self.button_cancel,
}
],
[
{
"text": "🚫 Закрыть",
"callback": self.callback_handler_ok,
"args": (message.chat.id,)
}
]
],
silent=True
)
else:
if not self.config["button"]:
if not self.config["afk_text"]:
await self.inline.form(
message=message,
text=f"😴 Сейчас я в <b>АФК</b> режиме\n❇️ Был <b>онлайн</b>: <code>{time}</code> назад.\n📝 Ушел по <b>причине:</b> {reason}",
reply_markup=[
[
{
"text": self.config["link_button"][0],
"url": self.config["link_button"][1]
}
],
[
{
"text": "🚫 Закрыть",
"callback": self.callback_handler_ok,
"args": (message.chat.id, )
}
]
],
silent=True
)
else:
await self.inline.form(
message=message,
text=self._afk_custom_text(),
reply_markup=[
[
{
"text": self.config["link_button"][0],
"url": self.config["link_button"][1]
}
],
[
{
"text": "🚫 Закрыть",
"callback": self.callback_handler_ok,
"args": (message.chat.id,)
}
]
],
silent=True
)
elif self.config["button"]:
if not self.config["afk_text"]:
await self.inline.form(
message=message,
text=f"😴 Сейчас я в <b>АФК</b> режиме\n❇️ Был <b>онлайн</b>: <code>{time}</code> назад.\n📝 Ушел по <b>причине:</b> {reason}",
reply_markup=[
[
{
"text": self.config["link_button"][0],
"url": self.config["link_button"][1],
}
],
[
{
"text": "🥱 Выйти из АФК",
"callback": self.button_cancel,
}
],
[
{
"text": "🚫 Закрыть",
"callback": self.callback_handler_ok,
"args": (message.chat.id,)
}
]
],
silent=True
)
else:
await self.inline.form(
message=message,
text=self._afk_custom_text(),
reply_markup=[
[
{
"text": self.config["link_button"][0],
"url": self.config["link_button"][1],
}
],
[
{
"text": "🥱 Выйти из АФК",
"callback": self.button_cancel,
}
],
[
{
"text": "🚫 Закрыть",
"callback": self.callback_handler_ok,
"args": (message.chat.id,)
}
]
],
silent=True
)
else:
if not self.config["afk_text"]:
await utils.answer(
message,
(
"😴 Сейчас я в <b>АФК</b> режиме\n"
f"❇️ Был <b>онлайн</b>: <code>{time}"
"</code> назад.\n📝 Ушел по <b>причине:"
f"</b> {reason}"
)
)
else:
await utils.answer(message, self._afk_custom_text())
async def button_cancel(self, call: InlineCall):
"""Callback button"""
self._db.set(__name__, "afk", False)
self._db.set(__name__, "gone", None)
self._db.set(__name__, "ratelimit", [])
change_bio = self._db.get(__name__, "change_bio")
change_name = self._db.get(__name__, "change_name")
await self.allmodules.log("TxAFК now not working.")
if not change_name and not change_bio:
await call.edit(self.strings["bt_off_afk"])
return
if change_name:
await self._client(UpdateProfileRequest(last_name=" "))
if change_bio:
try:
await self._client(UpdateProfileRequest(about=self.db.get(__name__, "about")))
except:
await self._.client(UpdateProfileRequest(about="@AstroOfftop - лучший чат для общения."))
await call.edit(self.strings["bt_off_afk"])
async def settings(self, call: InlineCall):
"""Callback button"""
info = self.render_settings()
await call.edit(
text=info,
reply_markup=[
[
{
"text": "📖 Биография",
"callback": self.settings_about
},
{
"text": "📝 Префикс",
"callback": self.settings_name
}
],
[
{
"text": "🚫 Закрыть",
"action": "close"
}
]
]
)
async def settings_name(self, call: InlineCall):
"""Callback button"""
await call.edit(
text=(
"<b>📖 Установка префикса</b>\n\n"
+ "<i>❔ Хотите ли Вы, чтобы при входе в АФК режим к вашему "
+ "нику добавлялся префикс <code>| afk.</code> ?</i>\n\n"
+ " Так же Вы можете <b>изменить префикс</b>, "
+ "<b>отменить</b> или <b>сделать</b> действие, нажав на <b>кнопки ниже</b>"
),
reply_markup=[
[
{
"text": "✅ Да",
"callback": self.name_yes
},
{
"text": "🚫 Нет",
"callback": self.name_no
}
],
[
{
"text": "↩️ Назад",
"callback": self.settings
}
]
]
)
async def name_yes(self, call: InlineCall):
"""Callback button"""
self._db.set(__name__, "change_name", True)
info = self.render_settings()
await call.edit(
text=info,
reply_markup=[
[
{
"text": "📖 Биография",
"callback": self.settings_about
},
{
"text": "📝 Префикс",
"callback": self.settings_name
}
],
[
{
"text": "🚫 Закрыть",
"action": "close"
}
]
]
)
async def name_no(self, call: InlineCall):
"""Callback button"""
self._db.set(__name__, "change_name", False)
info = self.render_settings()
await call.edit(
text=info,
reply_markup=[
[
{
"text": "📖 Биография",
"callback": self.settings_about
},
{
"text": "📝 Префикс",
"callback": self.settings_name
}
],
[
{
"text": "🚫 Закрыть",
"action": "close"
}
]
]
)
async def settings_about(self, call: InlineCall):
"""Callback button"""
if not self.config["feedback"]:
text = (
"📖 <b>Смена биографии</b>"
+ "\n\n❔ <b>Хотите</b> ли Вы, чтобы при <b>входе в АФК</b> режим Ваша биография <b>менялась</b>"
+ " на \"<code>Нахожусь в афк</code>\"?\n\n"
+ " Так же Вы можете <b>изменить биографию</b> в <b>конфиге</b>. "
+ "Можно <b>отменить</b> или <b>сделать</b> действие, нажав на <b>кнопки ниже</b>"
)
else:
text = (
"📖 <b>Смена биографии</b>"
+ "\n\n❔ <b>Хотите</b> ли Вы, чтобы при <b>входе в АФК</b> режим "
+ "Ваша биография <b>менялась</b> на \"<code>Нет, на месте нахожусь в афк</code><code>."
+ f" Связь только через @{self.config['feedback']}</code>\"?\n🤖 <b>Бот для связи</b>: <code>@{self.config['feedback']}</code>\n\n"
+ " Так же Вы можете <b>изменить биографию</b> в <b>конфиге</b>. "
+ "Можно <b>отменить</b> или <b>сделать</b> действие, нажав на <b>кнопки ниже</b>"
)
await call.edit(
text=text,
reply_markup=[
[
{
"text": "✅ Да",
"callback": self.bio
},
{
"text": "🚫 Нет",
"callback": self.bio_n
}
],
[
{
"text": "↩️ Назад",
"callback": self.settings
}
]
]
)
async def bio(self, call: InlineCall):
"""Callback button"""
self._db.set(__name__, "change_bio", True)
info = self.render_settings()
await call.edit(
text=info,
reply_markup=[
[
{
"text": "📖 Биография",
"callback": self.settings_about
},
{
"text": "📝 Префикс",
"callback": self.settings_name
}
],
[
{
"text": "🚫 Закрыть",
"action": "close"
}
]
]
)
async def bio_n(self, call: InlineCall):
"""Callback button"""
self._db.set(__name__, "change_bio", False)
info = self.render_settings()
await call.edit(
text=info,
reply_markup=[
[
{
"text": "📖 Биография",
"callback": self.settings_about
},
{
"text": "📝 Префикс",
"callback": self.settings_name
}
],
[
{
"text": "🚫 Закрыть",
"action": "close"
}
]
]
)
async def callback_handler_ok(self, call, chat_id: int):
"""Callback button"""
await call.delete()
limit: list = self._db.get(__name__, "ratelimit", [])
limit.remove(chat_id)
self._db.set(__name__, "ratelimit", limit)
def get_afk(self):
return self._db.get(__name__, "afk", False)

View File

@@ -0,0 +1,162 @@
__version__ = (1, 0, 6)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/AstroWeather.jpg
import contextlib
import random
import requests
from .. import loader, utils
class AstroWeatherMod(loader.Module):
"""Модуль для получения информации о погоде в Вашем городе, в красивом формате"""
strings = {
"name": "AstroWeather",
"error": "<emoji document_id=5447644880824181073>⚠️</emoji> <b>Ошибка</b>",
"api_error": (
"<emoji document_id=5240241223632954241>🚫</emoji> <b>Вы не указали API ключ</b>!\n"
"<emoji document_id=5210956306952758910>👀</emoji> <code>Пожалуйста, укажите его в конфиге ниже</code>"
),
"search": "{} <b>Поиск информации о погоде в городе</b> <code>{}</code>.."
}
async def text(self, temperature: int, veter: int, sky, hum, city, moji):
"""Generate text"""
sky = {
"Clear": "Чистое",
"Mist": "Туман",
"Clouds": "Облачно",
"Rain": "Дождь",
"Snow": "Снег"
}[sky]
t_emoji = (
"<emoji document_id=5204204137327111088>🔥</emoji>"
if temperature > 0
else "<emoji document_id=5267186302259835638>❄️</emoji>"
)
v_emoji = (
"<emoji document_id=5447183459602669338>📉</emoji>"
if veter >= 15
else "<emoji document_id=5449683594425410231>🔼</emoji>"
)
r_emoji = random.choice([
"<emoji document_id=5208554136039073738>🌙</emoji>",
"<emoji document_id=5444932797955317203>🐾</emoji>",
"<emoji document_id=5458585073060160944>🍀</emoji>",
"<emoji document_id=5206587423269593472>🌈</emoji>",
"<emoji document_id=5413390588198265552>💤</emoji>",
"<emoji document_id=5435981940081566607>🌺</emoji>"
])
sity_emoji = random.choice([
"<emoji document_id=5416117059207572332>⏩</emoji>",
"<emoji document_id=5447410659077661506>🌐</emoji>"
])
weather = (
f"{r_emoji} <b>Погода в {city.title()}:</b>\n\n"
f"{sity_emoji} <b>Город:</b> <code>{city.title()}</code>\n"
f"{t_emoji} <b>Температура:</b> <code>{temperature}°C</code>\n"
f"<emoji document_id=5192891734635322759>💦</emoji> <b>Влажность:</b> <code>{hum}%</code>\n"
f"{v_emoji} <b>Скорость ветра:</b> <code>{veter}м/с</code>\n"
f"{moji} <b>Небо:</b> <code>{sky}</code>"
)
return weather
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"api_key",
None,
lambda: "Api key. Получить можно по туториалу https://t.me/help_code/12",
validator=loader.validators.Hidden()
)
)
async def get_weather(self, city_id):
with contextlib.suppress(Exception):
api_key = self.config["api_key"]
result = requests.get("http://api.openweathermap.org/data/2.5/weather", params={"q": city_id, "units": "metric", "APPID": api_key})
result_json = result.json()
if result_json["cod"] != 200:
return
weather = {}
weather["temp"] = round(result_json["main"]["temp"])
weather["hum"] = result_json["main"]["humidity"]
weather["wind_speed"] = result_json["wind"]["speed"]
weather["sky"] = result_json["weather"][0]["main"]
if weather["sky"] == "Clouds":
weather["sky_emoji"] = "<emoji document_id=5391322797123314747>☁️</emoji>"
if weather["sky"] == "Rain":
weather["sky_emoji"] = "<emoji document_id=5224681716760715555>🌧️</emoji>"
if weather["sky"] == "Clear":
weather["sky_emoji"] = "<emoji document_id=5262761021361104549>☀️</emoji>"
if weather["sky"] == "Mist":
weather["sky_emoji"] = "<emoji document_id=5453984836668627018>🌫️</emoji>"
if weather["sky"] == "Snow":
weather["sky_emoji"] = "<emoji document_id=5282833267551117457>🌨️</emoji>"
return weather
@loader.command()
async def aw(self, message):
"""<город> - узнать погоду в указанном городе"""
search_moji = random.choice([
"<emoji document_id=5443038326535759644>💬</emoji>",
"<emoji document_id=5452069934089641166>🔎</emoji>"
])
city = utils.get_args_raw(message)
city = city.title()
getting = await utils.answer(message, self.strings("search").format(search_moji, city))
if self.config["api_key"] is None:
await utils.answer(getting, self.strings("api_error"))
msg = await self.client.send_message(message.chat.id, "<b>Открываю конфиг...</b>")
await self.allmodules.commands["config"](
await utils.answer(msg, f"{self.get_prefix()}config AstroWeather")
)
return
try:
dict_wea = await self.get_weather(city)
temp = dict_wea["temp"]
hum = dict_wea["hum"]
speed = dict_wea["wind_speed"]
sky = dict_wea["sky"]
moji = dict_wea["sky_emoji"]
text = await self.text(temp, speed, sky, hum, city, moji)
await utils.answer(getting, text)
except Exception:
await utils.answer(getting, self.strings("error"))

View File

@@ -0,0 +1,246 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/BrawlStats.jpg
# requires: brawlstats
import brawlstats as bs
import requests
from .. import loader, utils
@loader.tds
class BrawlStatsInfo(loader.Module):
'''Brawl Stars Players/Clubs information :)'''
strings = {
"name": "BrawlStatsInfo"
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"bs_api_token",
None,
doc="Сохраните здесь свой API-Токен BrawlStarsAPI",
validator=loader.validators.Hidden()
)
)
def getip(self):
ip = requests.get('https://api.myip.com/').json()["ip"]
return ip
async def client_ready(self, client, db):
await client.send_message("me", "<b>Модуль был инициализирован.\nВаш IP-Адрес для получения API-Токена BrawlStars: <code>{}</code></b>".format(self.getip()))
try:
self.bsc = bs.Client(self.config["bs_api_token"]) if self.config["bs_api_token"] else None
except Exception:
self.bsc = None
def get_bs_client(self):
if self.bsc is None:
self.bsc = bs.Client(self.config["bs_api_token"]) if self.config["bs_api_token"] else None
return None
@loader.command()
async def get_my_ip(self, message):
"""Получить свой IP-Адрес для получения API-Токен BrawlStarsAPI"""
await utils.answer(message, "<b>Ваш IP-Адрес для получения API-Токена BrawlStars: <code>{}</code></b>".format(self.getip()))
@loader.command()
async def set_bs_api_token(self, message):
"""<api_token> - сохранить свой API-Токен в конфиге модуля."""
await self.allmodules.commands['fconfig'](
await utils.answer(message, '{}fconfig BrawlStatsInfo bs_api_token {}'.format(self.get_prefix(), utils.get_args_raw(message)))
)
self.get_bs_client()
def get_brawlers_names(self, text: str):
names = {
'SHELLY': "ШЕЛЛИ",
'COLT': "КОЛЬТ",
'BULL': "БУЛЛ",
'BROCK': 'БРОК',
'RICO': 'РИКО',
'SPIKE': 'СПАЙК',
'BARLEY': 'БАРЛИ',
'JESSIE': 'ДЖЕССИ',
'NITA': "НИТА",
'DYNAMIKE': 'ДИНАМАЙК',
'EL PRIMO': 'ЭЛЬ ПРИМО',
'MORTIS': 'МОРТИС',
'CROW': 'ВОРОН',
'POCO': 'ПОКО',
'BO': 'БО',
'PIPER': 'ПАЙПЕР',
'PAM': 'ПЭМ',
'TARA': 'ТАРА',
'DARRYL': 'ДЭРРИЛ',
'PENNY': 'ПЕННИ',
'FRANK': 'ФРЭНК',
'GENE': 'ДЖИН',
'TICK': 'ТИК',
'LEON': 'ЛЕОН',
'ROSA': 'РОЗА',
'CARL': 'КАРЛ',
'BIBI': 'БИБИ',
'8-BIT': '8-БИТ',
'SANDY': 'СЭНДИ',
'BEA': 'БЕА',
'EMZ': 'ЭМЗ',
'MR. P': 'МИСТЕР П.',
'MAX': 'МАКС',
'JACKY': 'ДЖЕКИ',
'GALE': 'ГЭЙЛ',
'NANI': 'НАНИ',
'SPROUT': 'СПРАУТ',
'SURGE': 'ВОЛЬТ',
'COLETTE': 'КОЛЕТТ',
'AMBER': 'АМБЕР',
'LOU': 'ЛУ',
'BYRON': 'БАЙРОН',
'EDGAR': 'ЭДГАР',
'RUFFS': 'ГАВС',
'STU': 'СТУ',
'BELLE': 'БЕЛЛЬ',
'SQUEAK': 'СКУИК',
'GROM': 'ГРОМ',
'BUZZ': 'БАЗЗ',
'GRIFF': 'ГРИФФ',
'ASH': 'ЭШ',
'MEG': 'МЭГ',
'LOLA': 'ЛОЛА',
'FANG': 'ФЭНГ',
'EVE': 'ЕВА',
'JANET': 'ДЖАНЕТ',
'BONNIE': 'БОННИ',
'OTIS': 'ОТИС',
'SAM': 'СЭМ',
'GUS': 'ГАС',
'BUSTER': 'БАСТЕР',
'CHESTER': 'ЧЕСТЕР',
'GRAY': 'ГРЕЙ',
'MANDY': 'МЭНДИ',
}
text_replaced = text
for i, o in names.items():
text_replaced = text_replaced.replace(i, o)
return text_replaced
def get_player_info(self, tag: str, raw: bool = False):
self.get_bs_client()
player = self.bsc.get_player(
tag if not tag.startswith("#") else tag.replace("#", "").replace(" ", "")
)
return player if raw else f"<b>Информация об игроке:\nНикнейм: {player.name}\nТег: <code>{player.tag}</code>\nКол-во кубков всего: {player.trophies}\nМакс. кол-во кубков: {player.highest_trophies}\nУровень опыта: {player.exp_level}\nПобед 3x3: {player.x3vs3_victories}\nОдиночных побед: {player.solo_victories}\nПарных побед: {player.duo_victories}\nБравлеров(Бойцов): {len(player.brawlers)}\nТег клуба: <code>{player.club.tag if player.club.tag else 'Отсутствует клуб.'}</code>\nИмя Клуба: {player.club.name if player.club.name else 'Отсутствует клуб.'}</b>"
def get_club_info(self, tag: str, raw: bool = False):
self.get_bs_client()
club = self.bsc.get_club(
tag if not tag.startswith("#") else tag.replace("#", "").replace(" ", "")
)
return club if raw else f"<b>Информация о клубе:\nИмя клуба: {club.name}\nТег: <code>{club.tag}</code>\nКол-во кубков всего: {club.trophies}\nМин. необходимое кол-во кубков для входа: {club.required_trophies}\nОписание: {self.get_club_description(club.description)}\nТип клуба: {club.type}\nУчастники:\n{self.get_club_members_info(club)}</b>"
def get_club_members_info(self, club, full: bool = False):
self.get_bs_client()
def get_member_role(role: str):
for i, o in {"vicePresident": "Вице-президент", "president": "Президент", "member": "Участник"}.items():
role = role.replace(i, o)
return role
return "\n————\n".join(
[
f"{i.name}{get_member_role(i.role)} (<code>{i.tag}</code> | {i.trophies}) " for i in club.get_members()
] if full else [
f"{i.name}{get_member_role(i.role)} (<code>{i.tag}</code>)" for i in club.get_members()
]
)
def get_club_description(self, text: str):
text_replaced = text
for i in range(15):
text_replaced = text_replaced.replace(f"c{i}", "code")
return text_replaced
@loader.command()
async def bs_get_player(self, message):
"""<#player_tag> <#player_tag2> -> получить информацию об игроке/игроках(теги можно через пробел указывать)"""
msg = await utils.answer(message, "Собираю информацию, пожалуйста подождите...")
args = utils.get_args_raw(message)
info = []
self.get_bs_client()
if len(args.split(" ")) != 1:
for player_tag in args.split(" "):
info.append(self.get_player_info(player_tag))
info = "\n———————————\n".join(info)
else:
info = self.get_player_info(args)
return await utils.answer(msg, info)
@loader.command()
async def bs_get_club(self, message):
"""<#CLUB_TAG> -> получить информацию о клубе по его #ТЕГУ"""
msg = await utils.answer(message, "Собираю информацию, пожалуйста подождите...")
args = utils.get_args_raw(message)
info = []
info = self.get_club_info(args)
return await utils.answer(msg, info)
@loader.command()
async def bs_get_club_members(self, message):
"""<#CLUB_TAG> -> получить информацию об участниках клуба по его #ТЕГУ"""
msg = await utils.answer(message, "Собираю информацию, пожалуйста подождите...")
args = utils.get_args_raw(message)
info = f"Участники:\n{self.get_club_members_info(self.get_club_info(args, True), True)}"
return await utils.answer(msg, info)
@loader.command()
async def bs_get_player_brawlers(self, message):
"""<#player_tag> -> получить информацию о Бравлерах(Бойцах) игрока по его #ТЕГУ"""
msg = await utils.answer(message, "Собираю информацию, пожалуйста подождите...")
args = utils.get_args_raw(message)
player = self.get_player_info(args, True)
brawlers = []
for brawler in player.brawlers:
brawlers.append(f"<b>Имя: {brawler.name}\nКубков на бойце: {brawler.trophies}\nМакс. кол-во кубков на бойце: {brawler.highest_trophies}\nРанг: {brawler.rank}\nСила: {brawler.power}")
info = "\n————————\n".join(brawlers)
info = self.get_brawlers_names(info)
return await utils.answer(msg, info)

View File

@@ -0,0 +1,135 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/HikkaCommandsLogger.jpg
import logging
from telethon.tl.functions.channels import InviteToChannelRequest
from hikkatl.tl.types import PeerUser, PeerChannel, PeerChat, Channel, User
from .. import loader
from .. import utils
logger = logging.getLogger(__name__)
@loader.tds
class HikkaCommandsLoggerMod(loader.Module):
'''Hikka Commands Logger'''
strings = {
"name": "HikkaCommandsLogger",
"log-groups": (
"<b>#GROUP\n\n"
"┌ Command:\n├ « <code>{}</code> »\n"
"├ From --> {}\n"
"├ Chat --> {}\n"
"└ Message Link --> <a href='https://t.me/c/{}/{}'>CLICK</a></b>"
),
"log-pm": (
"<b>#PM\n\n"
"┌ Command:\n├ « <code>{}</code> »\n"
"├ From --> {}\n"
"├ Chat with --> {}\n"
"└ Message Link --> <a href='tg://openmessage?user_id={}&message_id={}'>CLICK</a></b>"
),
"log-channels": (
"<b>#CHANNEL\n\n"
"┌ Command:\n├ « <code>{}</code> »\n"
"├ From --> {}\n"
"├ Channel --> {}\n"
"└ Message Link --> <a href='https://t.me/c/{}/{}'>CLICK</a></b>"
),
}
async def client_ready(self, client, _):
self.chat_l, _ = await utils.asset_channel(
client,
"hikka-commands-logs",
"💬 Chat for Hikka commands logger",
silent=True,
avatar="https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/HikkaCommandsLoggerAvatar.png",
)
self.chat_logs = f"-100{self.chat_l.id}"
logger.warning("[AstroModules::HikkaCommandsLogger] Commands logger started.")
@loader.watcher(only_commands=True)
async def watcher(self, message):
is_pm = isinstance(message.peer_id, PeerUser)
sender = await message.get_sender()
is_channel = message.post or isinstance(sender, Channel)
chat_id = (
message.peer_id.user_id
if is_pm
else message.peer_id.chat_id
if isinstance(message.peer_id, PeerChat)
else message.peer_id.channel_id
if isinstance(message.peer_id, PeerChannel)
else self.hikka_me.id
)
chat = await self._client.get_entity(chat_id)
chat_username = getattr(chat, "username", None)
user_link = (
f"<a href='https://t.me/{sender.username}'>{sender.first_name if not is_channel else sender.title}</a>"
if sender.username
else f"<a href=tg://user?id={sender.id}>{sender.first_name if not is_channel else sender.title}</a>"
)
chat_link = (
f"<a href='https://t.me/{chat_username}'>{chat.title}</a>"
if chat_username
else chat.title
) if not is_pm else (
f"<a href='https://t.me/{chat.username}'>{chat.first_name}</a>"
if chat.username
else f"<a href='tg://user?id={chat.id}'>{chat.first_name}</a>"
)
async def send():
await self.inline.bot.send_message(
self.chat_logs,
self.strings(
"log-pm"
if is_pm
else "log-channels"
if message.post
else "log-groups"
).format(
utils.escape_html(message.raw_text),
user_link,
chat_link,
chat.id,
message.id,
),
disable_web_page_preview=True,
parse_mode="HTML",
)
try:
await send()
except Exception:
await utils.invite_inline_bot(self.client, self.chat_l)
await send()

View File

@@ -0,0 +1,242 @@
__version__ = (1, 0, 0)
import asyncio
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/Convertio.jpg
# meta developer: @AstroModules
import base64
import os
import requests
from .. import loader, utils
async def download_media(message):
media = None
msg = None
if message.media:
media, msg = message.media, message
elif (reply := await message.get_reply_message()) and reply.media:
media, msg = reply.media, reply
if not (media and msg):
return False
return await msg.download_media()
def generate_api_key():
return requests.post("https://den4iksop.org/convertio/getApiKey").json()
class ConvertioClient:
# Original from https://github.com/PetitPotiron/python-convertio/blob/main/convertio/client.py#L14
# This is edited version
def __init__(self, token: str) -> None:
self.token = token
def upload(self, fp: str, output_format: str):
"""Converts the file found in the path provided.
Args:
fp (str): The file's path
output_format (str): The file format you want the file to be converted to
"""
r1 = requests.post(
"http://api.convertio.co/convert",
json={
"apikey": self.token,
"input": "upload",
"outputformat": output_format,
}
).json()
if r1.get("error", None):
raise ValueError(r1["error"])
id = r1['data']['id']
with open(fp, 'rb') as file:
content = file.read()
r2 = requests.put(f'http://api.convertio.co/convert/{id}/{fp.split("/")[-1]}', data=content).json()
if r2.get("error", None):
raise ValueError(r2["error"])
return id
def check_conversion(self, id: str):
"""Checks the step of a conversion
Args:
id (str) : The id of the conversion
Returns:
Conversion: The status of the conversion
"""
r = requests.get(f"https://api.convertio.co/convert/{id}/status").json()
if r.get("error", None):
raise ValueError(r["error"])
return {
"code": r['code'],
"status": r['status'],
"id": r['data']['id'],
"step": r['data']['step'],
"step_percent": r['data']['step_percent'],
"minutes": r['data']['minutes'],
}
def download(self, id: str, fp: str) -> None:
"""Writes the file content to a path."""
r = requests.get(f"https://api.convertio.co/convert/{id}/dl").json()
if r.get("error", None):
raise ValueError(r["error"])
if r['status'] == 'error':
raise ValueError(r['error'])
content = base64.b64decode(r["data"]["content"])
with open(fp, "wb") as file:
file.write(content)
return fp
class ConvertioMod(loader.Module):
"""Convert file with api from https://convertio.co"""
strings = {
"name": "Convertio",
"converting": "<emoji document_id=5440739140347907722>☺️</emoji><b> Wait, converting...</b>",
"getting_api_key": "<emoji document_id=5220033539944237102>#️⃣</emoji><b> Wait, getting random API key...</b>",
"error": "<emoji document_id=5213157963023273778>💔</emoji><b> Something went wrong...</b>\n<emoji document_id=5220115526574950412>💭</emoji> Contact @AstroModsChat",
"no_file": "<emoji document_id=5219866512961062330>⁉️</emoji> <b>Where is the file?</b>",
"no_args": "<emoji document_id=5206479194388713063>❓</emoji> <b>Where is the file format you want to convert the file to?</b>",
"renewed": "<emoji document_id=5199658498559854923>🍀</emoji> <b>New API-key generated and saved!</b>",
"downloading_file": "<emoji document_id=5217697679030637222>⏳</emoji> <b>Downloading your file...</b>",
"converted": "<emoji document_id=5220064167356025824>⭐️</emoji> <b>File successfully converted from</b> <code>{}</code> to <code>{}</code>",
"api_error": "<emoji document_id=5220214598585568818>🚨</emoji><b> API:</b> <i>{}</i>",
"uploading": "<emoji document_id=5440739140347907722>☺️</emoji> <b>File converted. Uploading to Telegram...</b>",
}
strings_ru = {
"_cls_doc": "Конвертирует файл с помощью https://convertio.co",
"converting": "<emoji document_id=5440739140347907722>☺️</emoji><b> Подождите, идёт конвертация...</b>",
"getting_api_key": "<emoji document_id=5220033539944237102>#️⃣</emoji><b> Подождите, получаю рандомный API KEY...</b>",
"error": "<emoji document_id=5213157963023273778>💔</emoji><b> Что-то пошло не так...</b>\n<emoji document_id=5220115526574950412>💭</emoji> Обратитесь в @AstroModsChat",
"no_file": "<emoji document_id=5219866512961062330>⁉️</emoji> <b>Где файл?</b>",
"no_args": "<emoji document_id=5206479194388713063>❓</emoji> <b>Где формат файла, в который вы хотите преобразовать файл?</b>",
"renewed": "<emoji document_id=5199658498559854923>🍀</emoji> <b>Новый API-ключ сохранен!</b>",
"downloading_file": "<emoji document_id=5217697679030637222>⏳</emoji> <b>Загружаю ваш файл...</b>",
"converted": "<emoji document_id=5220064167356025824>⭐️</emoji> <b>Файл успешно конвертирован с</b> <code>{}</code> в <code>{}</code>",
"uploading": "<emoji document_id=5440739140347907722>☺️</emoji><b> Файл конвертирован. Загружаю в Telegram...</b>"
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"API_KEY",
None,
lambda: "API key from https://developers.convertio.co (Getting automatically)",
validator=loader.validators.String()
)
)
async def convert_file(self, message, m) -> str:
args: str = utils.get_args_raw(message)
if not args:
raise ValueError(self.strings("no_args"))
m = await utils.answer(m, self.strings("downloading_file"))
file_name = await download_media(message)
if not file_name:
raise ValueError(self.strings("no_file"))
m = await utils.answer(m, self.strings("converting"))
client = ConvertioClient(token=self.config["API_KEY"])
conversion_id = await utils.run_sync(client.upload, file_name, args)
os.remove(file_name)
while (await utils.run_sync(client.check_conversion, conversion_id))["step"] != 'finish':
await asyncio.sleep(1)
m = await utils.answer(m, self.strings("uploading"))
output_file_path = os.path.abspath("".join([*file_name.split(".")[:-1], ".", args]))
await utils.run_sync(client.download, conversion_id, output_file_path)
return output_file_path, file_name.split(".")[-1], output_file_path.split(".")[-1], m
@loader.command(alias="renewconv")
async def renewconvertio(self, message):
"""Renew convertio api key"""
await utils.answer(message, self.strings("getting_api_key"))
response = await utils.run_sync(generate_api_key)
if response["status"] == "Failed":
await utils.answer(self.strings("error"))
return
self.config["API_KEY"] = response["api_key"]
await utils.answer(message, self.strings("renewed"))
@loader.command(
ru_doc="<выходной формат> | Пример: png",
alias="conv",
)
async def convert(self, message):
"""<output format> <!reply to file> | Example: png"""
m = message
if not self.config["API_KEY"]:
m = await utils.answer(message, self.strings("getting_api_key"))
response = await utils.run_sync(generate_api_key)
if response["status"] == "Failed":
await utils.answer(self.strings("error"))
return
self.config["API_KEY"] = response["api_key"]
try:
new_file, old_format, new_format, m = await self.convert_file(message, m)
except ValueError as e:
await utils.answer(m, self.strings("api_error").format(str(e)))
return
except Exception as e:
await utils.answer(m, self.strings("error") + "\n\n" + utils.escape_html(str(e)))
raise e
if not (msg := await message.get_reply_message()):
msg = message
await utils.answer_file(
m, new_file.split("/")[-1],
reply_to=msg,
caption=self.strings("converted").format(
old_format.upper(), new_format.upper()
),
force_document=True
)
os.remove(new_file.split("/")[-1])

View File

@@ -0,0 +1,387 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/Demotivator.jpg
# requires: pillow
import io
import os
import re
from typing import Optional
import requests
from hikkatl.tl.types import MessageMediaDocument, MessageMediaPhoto
from PIL import Image, ImageColor, ImageDraw, ImageFont, ImageOps
from .. import loader, utils
MIME_TYPES = ["webp", "png", "jpeg", "jpg", "bmp", "dds", "dib", "eps", "ico", "tiff"]
class FontValidator(loader.validators.Validator):
"""Valid link to file with font"""
def __init__(self):
super().__init__(
self._validate,
{
"en": "link to file with font",
"ru": "ссылкой на файл со шрифтом"
}
)
@staticmethod
def _validate(value) -> str:
if not isinstance(value, str):
raise loader.validators.ValidationError("Value must be a string - URL(Link) to file with font.")
try:
if not value.endswith(".ttf") or not utils.check_url(value):
raise Exception("Invalid URL")
except Exception:
raise loader.validators.ValidationError(f"Passed value ({value}) is not a valid URL to file with font.")
return value
class ColorValidator(loader.validators.Validator):
"""Valid string color (for PIL.ImageColor)"""
def __init__(self):
super().__init__(
self._validate,
{
"en": "color (red/blue/green/...)",
"ru": "цветом (red/blue/green/...)",
}
)
@staticmethod
def _validate(value) -> str:
if not isinstance(value, str):
raise loader.validators.ValidationError("Value must be a string - valid color")
try:
_ = ImageColor.getcolor(value, "RGBA")
except Exception:
raise loader.validators.ValidationError(f"Passed value ({value}) is not a valid color")
return value
@loader.tds
class DemotivatorMod(loader.Module):
'''Demotivate picture with text, arguments and config.'''
strings = {
"name": "Demotivator",
"require_photo": "<b>Reply with a photo, attach it to the team.</b>",
"require_text": "<b>Text required!</b>",
"require_args": "<b>Args required!</b>",
"error": "<b>An error occurred...</b>",
"success": "<b>Result:</b>",
"demotivation": "<b>Demotivation, please wait...</b>",
"watermark_cfg": "Default watermark.",
"font_color_cfg": "Default text font color.",
"fill_color_cfg": "Default background color",
"font_name_cfg": "Link to font file (.ttf, not .zip)",
"top_size_cfg": "Default top text size.",
"bottom_size_cfg": "Default additional (bottom) text size.",
"arrange_cfg": "Adjust photo frames or not",
}
strings_ru = {
"require_photo": "<b>Ответьте на фото, приложите его к команде.</b>",
"require_text": "<b>Необходим текст!</b>",
"require_args": "<b>Необходимы аргументы!</b>",
"error": "<b>Произошла ошибка...</b>",
"success": "<b>Результат:</b>",
"demotivation": "<b>Демотивация, подождите, пожалуйста...</b>",
"watermark_cfg": "Водяной знак по умолчанию.",
"font_color_cfg": "Цвет шрифта текста по умолчанию.",
"fill_color_cfg": "Цвет фона по умолчанию",
"font_name_cfg": "Ссылка на файл со шрифтом (.ttf, не .zip)",
"top_size_cfg": "Размер главного текста по умолчанию.",
"bottom_size_cfg": "Размер дополнительного (нижнего) текста по умолчанию.",
"arrange_cfg": "Регулировать рамки под фотографию или нет",
"_cls_doc": "Демотивировает картинку по параметрам(текст, аргументы и конфиг)."
}
def __init__(self) -> None:
self.config = loader.ModuleConfig(
loader.ConfigValue(
"watermark",
"@AstroModules",
lambda: self.strings("watermark_cfg"),
validator=loader.validators.String(),
),
loader.ConfigValue(
"font_color",
"white",
lambda: self.strings("font_color_cfg"),
validator=ColorValidator(),
),
loader.ConfigValue(
"fill_color",
"black",
lambda: self.strings("fill_color_cfg"),
validator=ColorValidator(),
),
loader.ConfigValue(
"font_name_link",
"https://0x0.st/HHyo.ttf",
lambda: self.strings("font_name_cfg"),
validator=FontValidator(),
),
loader.ConfigValue(
"top_size",
80,
lambda: self.strings("top_size_cfg"),
validator=loader.validators.Integer(minimum=10),
),
loader.ConfigValue(
"bottom_size",
60,
lambda: self.strings("bottom_size_cfg"),
validator=loader.validators.Integer(minimum=10),
),
loader.ConfigValue(
"arrange",
True,
lambda: self.strings("arrange_cfg"),
validator=loader.validators.Boolean(),
),
)
def parse_args(self, text: str):
args = text.replace("\n", " ").split(" ")
text = " " + text
parsed = {}
for arg in args:
try:
if arg in ["-bottom-text", "-btm-text", "-bottom"]:
parsed["bottom_text"] = args[args.index(arg)+1]
elif arg in ["-wt", "-watermark"]:
parsed["watermark"] = args[args.index(arg)+1]
elif arg in ["-font-color", "-ftc"]:
parsed["font_color"] = args[args.index(arg)+1]
elif arg in ["-fill-color", "-flc"]:
parsed["fill_color"] = args[args.index(arg)+1]
elif arg in ["-font-name", "-font", "-font-link"]:
parsed["font_name"] = args[args.index(arg)+1]
elif arg in ["-top-size", "-tpsz", "-topsize"]:
parsed["top_size"] = args[args.index(arg)+1]
elif arg in ["-bottom-size", "-btmsz"]:
parsed["bottom_size"] = args[args.index(arg)+1]
elif arg in ["-arrange", "-arr"]:
parsed["arrange"] = True
text = text.replace(f" {arg}", "")
continue
else:
continue
text = text.replace(f" {arg} {args[args.index(arg)+1]}", "")
except IndexError:
pass
parsed["top_text"] = text
return parsed
async def download_media(self, message):
media = None
msg = None
if message.media:
media, msg = message.media, message
elif (reply := await message.get_reply_message()) and reply.media:
media, msg = reply.media, reply
if not (media and msg) or not isinstance(media, (MessageMediaDocument, MessageMediaPhoto)):
return False
if (isinstance(media, MessageMediaDocument) and media.document) and (not (image := re.match(r"image/(.*)", media.document.mime_type)) or image.group(1) not in MIME_TYPES):
return False
return await msg.download_media()
def create_demot(self,
top_text: str = "",
bottom_text: str = "",
*,
file: str,
watermark: Optional[str] = None,
result_filename: str,
font_color: str = 'white',
fill_color: str = 'black',
font_name,
top_size: int = 80,
bottom_size: int = 60,
arrange: bool = False
):
"""
This method in https://github.com/Infqq/simpledemotivators/blob/main/simpledemotivators/Demotivator.py
Author: Infqq
GitHub Repo: https://github.com/Infqq/simpledemotivators/
"""
if arrange:
user_img = Image.open(file).convert("RGBA")
(width, height) = user_img.size
img = Image.new('RGB', (width + 250, height + 260), color=fill_color)
img_border = Image.new('RGB', (width + 10, height + 10), color='#000000')
border = ImageOps.expand(img_border, border=2, fill='#ffffff')
img.paste(border, (111, 96))
img.paste(user_img, (118, 103))
drawer = ImageDraw.Draw(img)
else:
img = Image.new('RGB', (1280, 1024), color=fill_color)
img_border = Image.new('RGB', (1060, 720), color='#000000')
border = ImageOps.expand(img_border, border=2, fill='#ffffff')
user_img = Image.open(file).convert("RGBA").resize((1050, 710))
(width, height) = user_img.size
img.paste(border, (111, 96))
img.paste(user_img, (118, 103))
drawer = ImageDraw.Draw(img)
font_1 = ImageFont.truetype(font=font_name(), size=top_size, encoding='UTF-8')
text_width = font_1.getsize(top_text)[0]
while text_width >= (width + 250) - 20:
font_1 = ImageFont.truetype(font=font_name(), size=top_size, encoding='UTF-8')
text_width = font_1.getsize(top_text)[0]
top_size -= 1
font_2 = ImageFont.truetype(font=font_name(), size=bottom_size, encoding='UTF-8')
text_width = font_2.getsize(bottom_text)[0]
while text_width >= (width + 250) - 20:
font_2 = ImageFont.truetype(font=font_name(), size=bottom_size, encoding='UTF-8')
text_width = font_2.getsize(bottom_text)[0]
bottom_size -= 1
size_1 = drawer.textsize(top_text, font=font_1)
size_2 = drawer.textsize(bottom_text, font=font_2)
if arrange:
drawer.text((((width + 250) - size_1[0]) / 2, ((height + 190) - size_1[1])), top_text, fill=font_color, font=font_1)
drawer.text((((width + 250) - size_2[0]) / 2, ((height + 235) - size_2[1])), bottom_text, fill=font_color, font=font_2)
else:
drawer.text(((1280 - size_1[0]) / 2, 840), top_text, fill=font_color, font=font_1)
drawer.text(((1280 - size_2[0]) / 2, 930), bottom_text, fill=font_color, font=font_2)
if watermark:
(width, height) = img.size
idraw = ImageDraw.Draw(img)
idraw.line((1000 - len(watermark) * 5, 817, 1008 + len(watermark) * 5, 817), fill=0, width=4)
font_2 = ImageFont.truetype(font=font_name(), size=20, encoding='UTF-8')
size_2 = idraw.textsize(watermark.lower(), font=font_2)
idraw.text((((width + 729) - size_2[0]) / 2, ((height - 192) - size_2[1])),
watermark.lower(), font=font_2)
img.save(result_filename)
os.remove(file)
return result_filename
async def demotivate_pic(self, args: dict):
result_path = "/tmp/_demoted_" + args["file"]
font_name = args.get("font_name", self.config["font_name_link"])
font_resp = await utils.run_sync(requests.get, font_name)
def _get_font():
font = io.BytesIO(font_resp.content)
font.name = font_name.split("/")[-1]
return font
result = self.create_demot(
top_text=args["top_text"],
bottom_text=args.get("bottom_text", ''),
file=args["file"],
watermark=args.get("watermark", self.config["watermark"]) if not args.get("arrange", self.config["arrange"]) else None,
result_filename=result_path,
font_color=args.get("font_color", self.config["font_color"]),
font_name=_get_font,
fill_color=args.get("fill_color", self.config["fill_color"]),
top_size=int(args.get("top_size", self.config["top_size"])),
bottom_size=int(args.get("bottom_size", self.config["bottom_size"])),
arrange=args.get("arrange", self.config["arrange"]),
)
return result_path if result else ""
@loader.command(
ru_doc="""<текст>
[-bottom/-btm-text/-bottom-text <текст> - доп. текст внизу]
[-wt/-watermark <текст> - добавить водяной знак]
[-font-color/-ftc <цвет> (red/while/blue/yellow/...) - цвет шрифта (по дефолту white)]
[-fill-color/-flc <цвет> (red/while/blue/yellow/...) - цвет заднего фона (по дефолту black)]
[-font/-font-name/-font-link <ссылка на файл со шрифтами> (не zip, а ttf) - шрифт для текста]
[-top-size/-topsize/-tpsz <размер> (по дефолту 80) - размер главного текста]
[-bottom-size/-btmsz <размер> (по дефолту 60) - размер доп.(нижнего) текста]
[-arrange - регулировать рамки под фотографию]
- демотивировать картинку по заданному тексту и аргументам
""",
alias="demot",
)
async def demotivate(self, message):
"""<text>
[-bottom/-btm-text/-bottom-text <text> - add. text below]
[-wt/-watermark <text> - add watermark]
[-font-color/-ftc <color> (red/while/blue/yellow/...) - font color (white by default)]
[-fill-color/-flc <color> (red/while/blue/yellow/...) - background color (black by default)]
[-font/-font-name/-font-link <link to file with fonts> (not zip, but ttf) - font for text]
[-top-size/-topsize/-tpsz <size> (default 80) - main text size]
[-bottom-size/-btmsz <size> (default 60) - extra size text]
[-arrange - adjust photo frames]
- demotivate a picture according to the given text and arguments
"""
if not (args := utils.get_args_raw(message)):
return await utils.answer(message, self.strings("require_args"))
m = await utils.answer(message, self.strings("demotivation"))
args = self.parse_args(args)
media = ''
if not args:
return await utils.answer(m, self.strings("require_args"))
elif not args.get("top_text", None):
return await utils.answer(m, self.strings("require_text"))
if not (media := await self.download_media(message)):
return await utils.answer(m, self.strings("require_photo"))
args["file"] = media
demoted = await self.demotivate_pic(args)
if not demoted:
return await utils.answer(m, self.strings("error"))
await utils.answer_file(m, demoted, self.strings("success"), reply_to=(await message.get_reply_message()))
os.remove(demoted)

View File

@@ -0,0 +1,224 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/DialogsManager.jpg
import random
from telethon import functions
from telethon.tl.types import Message
from .. import loader
from ..utils import answer, get_args_raw
premium_emojies = [
"<emoji document_id=5807752501042089473>⭐️</emoji>",
"<emoji document_id=5809735165320104963>⭐️</emoji>",
"<emoji document_id=5807791714093502248>⭐️</emoji>",
"<emoji document_id=5807432062122070581>⭐️</emoji>",
"<emoji document_id=5807657096933543955>⭐️</emoji>",
"<emoji document_id=5809782942536306227>⭐️</emoji>",
"<emoji document_id=5807952178366648233>⭐️</emoji>",
"<emoji document_id=5807529673843805138>⭐️</emoji>",
"<emoji document_id=5807678760748584365>⭐️</emoji>",
"<emoji document_id=5807434488778591925>⭐️</emoji>",
"<emoji document_id=5807779713954876564>⭐️</emoji>",
"<emoji document_id=5834463121699245596>⭐️</emoji>",
"<emoji document_id=5832542373669769430>⭐️</emoji>",
"<emoji document_id=5782804629452492061>⭐️</emoji>"
]
@loader.tds
class DialogsManagerMod(loader.Module):
'''
Check your all info for dialogs, chats, PMs
Delete definite dialog,
delete all dialogs by arguments,
leave the chats, ids/usernames which you specify
Dialogs Manager!
'''
strings = {
'name': 'DialogsManager',
'dialogs_info': "<b>All Dialogs info:\n\n<emoji document_id=6048540195995782913>👤</emoji> All users PM ➪ {}\n<emoji document_id=6037355667365300960>👥</emoji> All chats ➪ {}\n<emoji document_id=5764623873974734153>📢</emoji> All channels ➪ {}\n<emoji document_id=6037190220930092878>🤖</emoji> All bots PM ➪ {}\n\n<emoji document_id=6048540195995782913>👤</emoji> Users(PM):\n\n <emoji document_id=5805597488316419570>🚫</emoji> Fake ➪ {}\n <emoji document_id=5805441297535733440>🚫</emoji> Scam ➪ {}\n {} Premium ➪ {}\n <emoji document_id=5850654130497916523>✅️</emoji> Verified ➪ {}\n <emoji document_id=6050677771154231040>🗑</emoji> Deleted ➪ {}\n\n<emoji document_id=6037355667365300960>👥</emoji> Chats:\n\n <emoji document_id=6323524880121726602>✅</emoji> Megagroups ➪ {}\n\n <emoji document_id=6323380805443782200>☑️</emoji> Gigagroups ➪ {}\n\n <emoji document_id=5805597488316419570>🚫</emoji> Fake ➪ {}\n <emoji document_id=5805441297535733440>🚫</emoji> Scam ➪ {}\n <emoji document_id=5850654130497916523>✅️</emoji> Verified ➪ {}\n\n<emoji document_id=5764623873974734153>📢</emoji> Channels:\n <emoji document_id=5805597488316419570>🚫</emoji> Fake ➪ {}\n <emoji document_id=5805441297535733440>🚫</emoji> Scam ➪ {}\n <emoji document_id=5850654130497916523>✅️</emoji> Verified ➪ {}\n\n<emoji document_id=6037190220930092878>🤖</emoji> Bots(PM):\n <emoji document_id=5805597488316419570>🚫</emoji> Fake ➪ {}\n <emoji document_id=5805441297535733440>🚫</emoji> Scam ➪ {}\n<emoji document_id=5850654130497916523>✅️</emoji> Verified ➪ {}",
"waiting_dinfo": "<b>Please wait, loading information...</b>",
}
strings_ru = {
"waiting_dinfo": "<b>Пожалуйста подождите, идёт загрузка данных...</b>",
}
@loader.command(
ru_doc="➪ полная информация о ваших диалогах, чатах лс и т.д.",
alias='dinfo'
)
async def dialogsinfo(self, message: Message):
"""➪ all info for your dialogs, chats, PMs..."""
msg = await answer(message, self.strings('waiting_dinfo'))
chats, users, scam_bots, scam_users, scam_chats, scam_channels, fake_users, fake_chats, fake_bots, fake_channels, bots, channels, premium, deleted, verified_users, verified_chats, verified_bots, verified_channels, gigagroups, megagroups = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
async for dialog in self._client.iter_dialogs():
ent = dialog.entity
if dialog.is_user:
if ent.bot:
bots += 1
if ent.scam:
scam_bots += 1
elif ent.verified:
verified_bots += 1
elif ent.fake:
fake_bots += 1
elif not ent.bot:
users += 1
if ent.deleted:
deleted += 1
elif ent.scam:
scam_users += 1
elif ent.verified:
verified_users += 1
elif ent.fake:
fake_users += 1
elif ent.premium:
premium += 1
elif dialog.is_group:
chats += 1
elif dialog.is_channel:
if ent.megagroup or ent.gigagroup:
if ent.megagroup:
megagroups += 1
elif ent.gigagroup:
gigagroups += 1
if ent.fake:
fake_chats += 1
elif ent.scam:
scam_chats += 1
elif ent.verified:
verified_chats += 1
elif not ent.megagroup and not ent.gigagroup:
channels += 1
if ent.fake:
fake_channels += 1
elif ent.scam:
scam_channels += 1
elif ent.verified:
verified_channels += 1
textik = self.strings('dialogs_info').format(
users, chats, channels, bots,
fake_users, scam_users,
random.choice(premium_emojies),
premium, verified_users, deleted,
megagroups, gigagroups, fake_chats,
scam_chats, verified_chats, fake_channels,
scam_channels, verified_channels, fake_bots,
scam_bots, verified_bots
)
await answer(msg, textik)
@loader.command(
ru_doc="<id or @username> ➪ удалить чат(диалог) с юзером"
)
async def dialog_clear(self, message: Message):
"""<id or @username> ➪ delete dialog with user"""
args = get_args_raw(message)
try:
await self._client.delete_dialog(args)
except:
await answer(message, '<b>Кажется произошла ошибка...</b>')
return
await answer(message, f'<b>Чат с юзером «{args}» был удален успешно!</b>')
@loader.command(
ru_doc="➪ алиас для команды 'dialogs_clear'"
)
async def dclear(self, message: Message):
"""➪ alias for command 'dialog_clear'"""
await self.dialog_clear(message)
@loader.command(
ru_doc="""Аргументы:
-deleted ➪ очистить все ЛС с удаленными аккаунтами
-fake ➪ очистить все ЛС с аккаунтами с пометкой "FAKE"
-scam ➪ очистить все ЛС со скам аккаунтами
-bots ➪ очистить все ЛС с ботами
-allpms ➪ очистить ВСЕ АБСОЛЮТНО ЛС(ОПАСНО)
-prem ➪ очистить все ЛС с юзерами, обладающими Premium⭐
"""
)
async def all_dialogs_clear(self, message: Message):
"""
Arguments:
-deleted ➪ delete all dialogs PM with deleted accounts
-fake ➪ delete all dialogs PM with fake accounts
-scam ➪ delete all dialogs PM with scam accounts
-bots ➪ delete all dialog with bots
-allpms ➪ delete all dialogs PM
-prem ➪ delete all dialogs PM with PREMIUM⭐ users
"""
await self.clear_dialogs(message)
async def clear_dialogs(self, message):
msg = await answer(message, "<b>Пожалуйста подождите, выполняется очистка...</b>")
args = get_args_raw(message)
deleted_dialogs = 0
async for chat in self._client.iter_dialogs():
if chat.is_user:
ent = chat.entity
if args == '-deleted' and ent.deleted:
await self._client.delete_dialog(chat.id)
deleted_dialogs += 1
elif args == '-fake' and ent.fake:
await self._client.delete_dialog(chat.id)
deleted_dialogs += 1
elif args == '-scam' and ent.scam:
await self._client.delete_dialog(chat.id)
deleted_dialogs += 1
elif args == '-bots' and ent.bot:
await self._client.delete_dialog(chat.id)
deleted_dialogs += 1
elif args == '-allpms' and chat.id != (await self._client.get_me()).id:
await self._client.delete_dialog(chat.id)
deleted_dialogs += 1
elif args == '-prem' and ent.premium:
await self._client.delete_dialog(chat.id)
deleted_dialogs += 1
#else:
# await answer(message, self.strings('args-wrong'))
# return
await answer(msg, f"<b>Было успешно удалено {deleted_dialogs} чатов ЛС.</b>")
@loader.command(
ru_doc="@chat_username1, @chat_username2, ... ➪ покинуть чаты, с определенными @username"
)
async def leave_chats(self, message: Message):
"""@chat_username1, @chat_username2, ... ➪ leave chats, with usernames in arguments"""
args = get_args_raw(message)
if not args:
await answer(message, 'Не было указано аргументов.')
return
msg = await answer(message, '<b>Пожалуйста подождите, процесс выполняется...</b>')
dd = args.split(', ')
leave_chatsss = 0
for id in dd:
await self._client(functions.channels.LeaveChannelRequest(channel=id))
leave_chatsss += 1
await answer(msg, f'<b>Работа завершена.\nВы успешно покинули {leave_chatsss} чата(-ов)!</b>')

View File

@@ -0,0 +1,173 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/YouTubePreviews.jpg
from telethon.tl.types import Message
from .. import loader, utils
from ..inline.types import InlineCall
class YTPreviewMod(loader.Module):
'''Скачивает превью с ютуба'''
strings = {
"name": "YT-Preview",
"choice": '<b>Select YouTube preview extension:</b>',
"caption": "<b>You have selected an extension: {}</b>",
"error": "There doesn't seem to be an extension for this video...Choose another.",
}
strings_ru = {
"choice": '<b>Выберите расширение для превью ролика YouTube:</b>',
"caption": "<b>Вы выбрали расширение: {}</b>",
"error": "Кажется этого расширения для этого видео нету...Выберите другое.",
}
@loader.command(ru_doc="<link> --> скачивает превью")
async def ytpcmd(self, message: Message):
"""<link> --> download YouTube video preview"""
self.args = utils.get_args_raw(message)
self.chat_id = message.chat_id
await self.inline.form(
text=self.strings("choice"),
reply_markup=[
[
{
"text": "maxresdefault",
"callback": self.maxresdefault
},
{
"text": "sddefault",
"callback": self.sddefault
},
],
[
{
"text": "hqdefault",
"callback": self.hqdefault
},
{
"text": "mqdefault",
"callback": self.mqdefault
},
],
[
{
"text": "default",
"callback": self.default
},
]
],
message=message
)
async def maxresdefault(self, call: InlineCall):
try:
count1 = "http://i1.ytimg.com/vi/"
count2 = "/maxresdefault.jpg"
count = "maxresdefault"
nm = self.args.split("=")
if len(nm) == 2:
preview = nm[1]
yt = count1 + preview + count2
else:
x = self.args.split("/")
preview = x[3]
yt = count1 + preview + count2
await self._client.send_file(self.chat_id, file=yt, caption=self.strings("caption").format(count))
except Exception:
await call.answer(self.strings("error"))
async def sddefault(self, call: InlineCall):
try:
count1 = "http://i1.ytimg.com/vi/"
count2 = "/sddefault.jpg"
count = "sddefault"
nm = self.args.split("=")
if len(nm) == 2:
preview = nm[1]
yt = count1 + preview + count2
else:
x = self.args.split("/")
preview = x[3]
yt = count1 + preview + count2
await self._client.send_file(self.chat_id, file=yt, caption=self.strings("caption").format(count))
except Exception:
await call.answer(self.strings("error"))
async def hqdefault(self, call: InlineCall):
try:
count1 = "http://i1.ytimg.com/vi/"
count2 = "/hqdefault.jpg"
count = "hqdefault"
nm = self.args.split("=")
if len(nm) == 2:
preview = nm[1]
yt = count1 + preview + count2
else:
x = self.args.split("/")
preview = x[3]
yt = count1 + preview + count2
await self._client.send_file(self.chat_id, file=yt, caption=self.strings("caption").format(count))
except Exception:
await call.answer(self.strings("error"))
async def mqdefault(self, call: InlineCall):
try:
count1 = "http://i1.ytimg.com/vi/"
count2 = "/mqdefault.jpg"
count = "mqdefault"
nm = self.args.split("=")
if len(nm) == 2:
preview = nm[1]
yt = count1 + preview + count2
else:
x = self.args.split("/")
preview = x[3]
yt = count1 + preview + count2
await self._client.send_file(self.chat_id, file=yt, caption=self.strings("caption").format(count))
except Exception:
await call.answer(self.strings("error"))
async def default(self, call: InlineCall):
try:
count1 = "http://i1.ytimg.com/vi/"
count2 = "/default.jpg"
count = "default"
nm = self.args.split("=")
if len(nm) == 2:
preview = nm[1]
yt = count1 + preview + count2
else:
x = self.args.split("/")
preview = x[3]
yt = count1 + preview + count2
await self._client.send_file(self.chat_id, file=yt, caption=self.strings("caption").format(count))
except Exception:
await call.answer(self.strings("error"))

View File

@@ -0,0 +1,34 @@
komarumod
RandomPasswordGenerator
gamecheat
convertio
mindtalk
dialogs_manager
inline_bot_manager
RandomTrack
iOSAppsForAndroid
video_to_voice
вахуи_пон
RandomStatuses
TwinkManager
brawl_stats
astroafk
YandexMusic
astroweather
wordly
RandomUser
summer
пон_вахуи
pcmanager
shazam
achievements
Steam
minesweeper
dl_yt_previews
TxAFK
akinator
Compliments
commands_logger
Emotions
AntiMat
demotivator

View File

@@ -0,0 +1,114 @@
__version__ = (1, 0, 5)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# old source: https://github.com/norouzy/Gamee-Cheat
# meta developer: @astromodules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/GameeCheat.jpg
# meta designer: @XizurK
# requirements: certifi==2022.6.15, charset-normalizer==2.1.0, idna==3.3, requests==2.28.1, urllib3==1.26.10
import hashlib
import random
import re
from telethon.tl.types import Message
from .. import loader, utils
class GameeCheatMod(loader.Module):
'''Читы для игр в @gamee'''
strings = {
"name": "GameeCheats",
"result": (
"<emoji document_id=6334592388073260525>🪄</emoji> <b>Рекорд накручен</b>!\n"
"<emoji document_id=6334649330749671032>✨</emoji> Новый рекорд: <code>{}</code>"
),
"err_args": (
'<emoji document_id=6334664779747034990>🚫</emoji> <b>Введите нужные аргументы</b>!\n'
'<emoji document_id=6334638004920911460></emoji> Пример: <code>{}chg <ссылка> <рекорд></code>'
),
"banned": (
"<emoji document_id=6334363088359262569>⛔️</emoji> <b>Вы были заблокированы в боте</b>!\n"
"<emoji document_id=6334638004920911460></emoji> <code>Вы не можете ставить новые рекорды в течении 24 часов</code>"
),
"banned_perm": (
"<emoji document_id=6334363088359262569>⛔️</emoji> <b>Вы были заблокированы в боте навсегда</b>!\n"
"<emoji document_id=6334638004920911460></emoji> <code>Вы не можете ставить новые рекорды в @gamee</code>"
),
"error_link": (
"<emoji document_id=6334664779747034990>🚫</emoji> <b>Вы ввели неправильную ссылку</b>!\n"
"<emoji document_id=6334638004920911460></emoji> <code>Введите правильную ссылку или же"
' посмотрите</code> <a href="https://t.me/help_code/15">туториал</a>'
)
}
async def client_ready(self):
self.lib = await self.import_lib('https://raw.githubusercontent.com/ToXic2290/Hikka-moduless/main/GameCheatsLib.py')
async def game_link(self, url):
pattern = r"https:\/\/prizes\.gamee\.com(\/game-bot\/.*)#tg"
result = re.match(pattern, url)
if result:
return result.groups(0)[0]
else:
return False
async def get_checksum(self, score, playTime, url):
str2hash = f"{score}:{playTime}:{url}::crmjbjm3lczhlgnek9uaxz2l9svlfjw14npauhen"
result = hashlib.md5(str2hash.encode())
checksum = result.hexdigest()
return checksum
@loader.command()
async def chg(self, message: Message):
"""<ссылка> <рекорд> - запустить чит"""
args = utils.get_args_raw(message)
if not args:
await utils.answer(message, self.strings('err_args').format(self.get_prefix()))
try:
game, score = args.split(' ')
except ValueError:
await utils.answer(message, self.strings('err_args').format(self.get_prefix()))
return
game_url = await self.game_link(game)
if not game_url:
await utils.answer(message, self.strings('error_link'))
return
time = random.randint(308, 19187)
checksum = await self.get_checksum(score, time, game_url)
token = await self.lib.get_token(game_url)
Game_number = await self.lib.game_id(game_url)
result = await self.lib.send_score(score, time, checksum, token, game_url, Game_number)
if result == 'ban':
await utils.answer(message, self.strings('banned'))
return
if result == 'ban_permanent':
return await utils.answer(message, self.strings('banned_perm'))
await utils.answer(message, self.strings("result").format(score))

View File

@@ -0,0 +1,471 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/iOSAppsForAndroid.jpg
from .. import loader
@loader.tds
class iOSAppsForAndroid(loader.Module):
'''iOS Applications for Android, or more simply, Android applications with an interface like on iOS'''
strings = {
"name": "iOSappsForAndroid",
"apps-list": (
"<i><b>The list of applications in the module at the moment:\n| iCall |"
" iLauncher | iLock |\n| iSwiftKeyboard | iWhatsApp |\n| iNotes | iMessages"
" | iContacts |\n| iPhotos | iCalculator | iVoice |\n|iCompas |\n| All"
" applications are taken from the channel @progi95 | @IbreymMods |</b></i>"
),
"support_chat_btn": "🎩 Support Chat 🎓",
"more_modules_btn": "🌌 More Modules ✨",
"close_btn": "🚫 Close",
"iCalculator_text": (
"<b>ICalculator Pro is an ios—style calculator for your android, with ios"
" design, with calculator history and with other settings.\n♦️ Ibreym Mods"
" (https://t.me/IbreymMods).\nMods: the full version is open, without"
" ads.\nIbreym Mods. (<a"
" href='https://telegra.ph/Kalkulyator-v-stile-ios-16-na-lyuboj-android-07-12"
" '>screenshots</a>)</b>"
),
"iCall_text": (
"🔥<b>iCall Pro</b> — <i>a dialer in the style of iOS on Android with a"
" beautiful iPhone design and various functions, such as changing the"
" contact wallpaper, etc.<i>\n<b>🔑Mods: PRO version.\n \n \n🔑Description of"
" the modification:</b>\n<i>— Update: 2.4.4. \n— The full version has been"
" purchased. \n— All functions are open. \n— All templates are available."
" \n— Advertising is disabled. \n— Removed excess. \n is a working"
" mod.</i></b>"
),
"iLauncher_text1": (
"<b>🔥Ios 16 Launcher is an application with which you can turn your android"
" desktop into an iPhone. Changes icons, style, screen recording on ios."
" \n🔑Mods: PRO version.</b>"
),
"iLauncher_text2": (
"<b>🚀Description of the modification: \nModder: Ibreym. \n— Removed the"
" advertising completely. \n— The application is completely in Russian, so"
" it will not be so difficult to configure it. ✅To activate, you need to"
" issue all the necessary permissions, and then click on the 'make default"
" launcher' button.</b>"
),
"iLock_text": (
"<i><b>🚀iLock — ios-style screen lock, with the coolest style, translated"
" into Russian, removed ads, you can put your background, password and"
" more. Throw screenshots in the comments.\n🔑Mods: PRO version. \n🔘Mods"
" from Ibreym: \n— Removed the ad.\n— Translated into Russian to make it"
" more understandable for you to configure.\n— And also translated the"
" inscriptions on the lock screen to make it look better.Set up following"
" the instructions, everything is easy and simple. The screen works cool,"
" and it looks.</b></i>"
),
"iSwiftKey_text1": (
"<b>😍The newest iPhone keyboard for your android. And now attention: - ios"
" themes, ios 16 emoticons, there are any languages, including Russian,"
" there is a t9 (hint, correction of words), the ability to change the"
" size, and most importantly - the iPhone sound when typing.\n😍Run to"
" watch:</b>"
),
"iSwiftKey_text2": (
"<b>🌚iOS—style keyboard for any android with iOS 16 and emoticons: \n— Dark"
" and white iOS theme.\n- Supports Russian and other languages. \n— there"
" is a T9 hint, correction of words. \n— you can adjust the size of the"
" keyboard for yourself. \n— there is an iPhone typing sound.\n🎥All this"
" needs to be configured, and for this, watch the video review on the"
" button above</b>"
),
"iWhatsApp_text1": (
"<b>♻Ibreym-WhatsApp is the best whatsapp mod from the developer Ibreym."
" It's two in one! - WhatsApp+ features, and the design is apple where you"
" can spend time with a buzz!\n🔺Developer: Stefano (Mb Mods)\n<a"
" href='https://youtu.be/rlFNpG2BRB0'>🎥Video review</a></b>"
),
"iWhatsApp_text3": (
"<b>MB WhatsApp Sticker.\nThe version is for those who need stickers in"
" whatsapp.\nWorks great with sticker programs, for example:"
" https://t.me/progi95/3562\n\nTo install, you need to remove the original"
" version from the play store.\nDelete the old one, or the version that is"
" not needed at the top, you can install both versions at once and use them"
" from two numbers.</b>"
),
"iWhatsApp_text2": (
"<b><i>Custom double-tap emoticons for each chat (chat > call icon > custom"
" reaction)\n🔷 Added: Showing notifications about blocked calls due to call"
" privacy.\n🔷 Added: The ability to disable double-tapping to put a"
" like.\n🔷 Added: Admin indicator in groups.\n🔷 Added: Custom background"
" color for text status.\n🔷 Added: Custom text color for text status.\n🔷"
" Added: New way to display updates.\n🔷 New pencil drawing tool v2.\n🔷 New"
" user interface challenge.\n🔷 New rounded font.\n🔷 Added the ability to"
" hide the admin icon. \n🔷 Added the ability to reduce the lag in some"
" actions.\n🔷 Added the ability to disable bold font (useful if you want to"
" use your system font).\n🔷 Added the ability to disable notifications from"
" those who blocked you.\netc.</i></b>."
),
"iNotes_text": (
"<b>iNotes Pro — ios-style notes for your android with ios design and"
" themes, with the ability to set a password when logging in, and with"
" other various functions and features!\nMods: the full version is open,"
" without ads.\nIbreym Mods. (<a"
" href='https://telegra.ph/Zametki-v-stile-ios-16-na-lyuboj-android-07-11'>screenshots</a>)</b>"
),
"iPhotos_text": (
"<b>iPhotos is a very beautiful iOS—style gallery for your android, with a"
" beautiful iPhone design, two themes, with a basket, with albums and other"
" various settings.\nMods: the full version is open, without ads.\nIbreym"
" Mods. (<a"
" href='https://telegra.ph/Galereya-v-stile-ios-16-na-lyuboj-android-07-10"
" '>screenshots</a>)</b>"
),
"iMessages_text": (
"<b>iMessages — ios-style messages for your android, with built-in iOS"
" themes in black and light colors, with a beautiful design, and various"
" settings!\nThe full version is open for subscribers, where there are no"
" ads and pro functions are available.\nIbreym Mods.</b>"
),
"iContacts_text": (
"<b>iContacts Ios — iOS-style contacts for your android with a dark and"
" light iPhone theme, design, and other functions like an iPhone.\nMods:"
" the full version is open, without ads.\nIbreym Mods.</b>"
),
"icompas1": (
"<b>iCompass Pro is an iOS—style compass for android, with a beautiful"
" iPhone design that will help you quickly and easily determine the exact"
" direction and position on the map.\n🔑Mods: PRO version.</b>"
),
"icompas2": (
"<b>🚀Description of the modification:\n— Update: 1.1.5\n— The full version"
" is open.\n— Removed ads.\n— All functionality is available.\n— Removed"
" unnecessary.</b>"
),
"ivoice1": (
"<b>iVoice Pro is an iOS—style voice recorder with full iphone design and"
" functionality on android. A dark and light theme, a choice of quality and"
" a full version without ads are available.\n🔑Mods: PRO version.</b>"
),
"ivoice2": (
"<b>🚀Description of the modification:\n— Update: 1.6.1\n— The full version"
" is open.\n— Removed ads.\n— All functionality is available.\n— Removed"
" unnecessary.\n— Updated to the latest version.\n— And so on.</b>"
),
"itelegram": (
"<b>Ibreym-Telegram is an iPhone telegram for android, with a very"
" beautiful iPhone design, themes, fonts and with various cool"
" settings.</b>"
),
}
strings_ru = {
"_cls_doc": (
"iOS приложения на Android, или же проще говоря Android приложения с"
" интерфейсом, как на iOS"
),
"apps-list": (
"<i><b>Список приложений в модуле на данный момент: \n| iCall | iLauncher |"
" iLock |\n| iSwiftKeyboard | iWhatsApp |\n| iNotes | iMessages | iContacts"
" |\n| iPhotos | iCalculator | iVoice |\n|iCompas |\n| Все приложения взяты"
" из каналов @progi95 | @IbreymMods |</b></i>"
),
"support_chat_btn": "🎩 Чат поддержки 🎓",
"more_modules_btn": "🌌 Больше Модулей ✨",
"close_btn": "🚫 Закрыть",
"iCalculator_text": (
"<b>iCalculator Pro — калькулятор в стиле ios на ваш андроид, с ios"
" дизайном, с историей калькулятора и с другими настройками.\n♦️ Ibreym"
" Mods (https://t.me/IbreymMods).\nМоды: открыта полная версия, без"
" рекламы.\nIbreym Mods. (<a"
" href='https://telegra.ph/Kalkulyator-v-stile-ios-16-na-lyuboj-android-07-12'>скрины</a></b>"
),
"iCall_text": (
"🔥<b>iCall Pro</b> — <i>звонилка в стиле iOS на Android с красивым,"
" айфоновским дизайном и различными функциями, например смена обоев"
" контакта и т.д.<i>\n<b>🔑Моды: PRO версия.\n \n \n🔑Описание"
" модификации:</b>\n<i>— Обнова: 2.4.4. \n— Куплена полная версия. \n"
" Открыты все функции. \n— Доступны все шаблоны. \n— Отключена реклама. \n"
" Удалено лишнее. \n— Мод рабочий.</i>"
),
"iLauncher_text1": (
"<b>🔥Ios 16 Launcher — приложение с помощью которого вы можете превратить"
" свой рабочий стол андроида в айфон. Меняет иконки, стиль, запись экрана"
" на ios. \n🔑Моды: PRO версия.\n<a"
" href='https://youtu.be/D3IjVjuy9kI'>🎥Видеообзор</a></b>"
),
"iLauncher_text2": (
"<b>🚀Описание модификации: \nМоддер: Ibreym. \n— Убрали полностью рекламу."
" \n— Приложение полностью на русском языке, поэтому настроить его будет не"
" так сложно. \n ✅Для активации нужно выдать все необходимые разрешения, а"
" потом нажать на кнопку «make default launcher».</b>"
),
"iLock_text": (
"<i><b>🚀iLock — блокировка экрана в стиле ios, с крутейшим стилем., перевел"
" на русским язык, удалил рекламу, можно поставить свой фон, пароль и не"
" только. Скрины кидайте в комментариях.\n🔑Моды: PRO версия. \n🔘Моды от"
" Ibreym: \n— Удалил рекламу.\n— Перевел на русский язык, чтобы вам было"
" более понятно настроить.\nА также перевел надписи на экране блокировки,"
" чтобы выглядело лучше.\nНастраивайте следуя инструкциям, все легко и"
" просто. Экран круто работает, и выглядит.</b></i>"
),
"iSwiftKey_text1": (
"<b>😍Новейшая айфоновская клавиатура на ваш андроид. А теперь внимание: -"
" темы ios, смайлы ios 16, есть любые языки, в том числе русский, есть"
" т9(подсказка, исправление слов), возможность менять размер, и самое"
" главное - айфоновский звук при печатании.\n😍Беги смотреть:<a"
" href='https://youtu.be/n0aFenC3cz0'>🎥Видеообзор</a></b>"
),
"iSwiftKey_text2": (
"<b>🌚Клавиатура в стиле ios на любой андроид со смайлами ios 16 и: \n"
" темная и белая тема ios.\n— поддерживает русский и другие языки. \n— есть"
" Т9 подсказка, исправление слов. \n— можно подстроить под себя размер"
" клавиатуры. \n— есть айфоновский звук печатания.\n🎥Всё это нужно"
" настроить, а для этого смотрите видеообзор по кнопке выше</b>"
),
"iWhatsApp_text1": (
"<b>♻Ibreym-WhatsApp — самый лучший мод на whatsapp от разработчика"
" Ibreym. Это два в одном! - функции whatsApp +, а дизайн - apple где можно"
" с кайфом проводить время!\n🔺Developer: Stefano (Mb Mods)\n<a"
" href='https://youtu.be/rlFNpG2BRB0'>🎥Видеообзор</a></b>"
),
"iWhatsApp_text2": (
"<b><i>Пользовательские смайлы двойного нажатия для каждого чата (чат >"
" значок вызова > пользовательская реакция)\n🔷 Добавлено: показ уведомлений"
" о заблокированных вызовах из-за конфиденциальности звонков.\n🔷 Добавлено:"
" Возможность отключить двойное нажатие, чтобы поставить лайк.\n🔷"
" Добавлено: Индикатор администратора в группах.\n🔷 Добавлено:"
" Пользовательский цвет фона для текстового статуса.\n🔷 Добавлено:"
" Пользовательский цвет текста для текстового статуса.\n🔷 Добавлено: Новый"
" способ отображения обновлений.\n🔷 Новый инструмент для рисования"
" карандашом v2.\n🔷 Новый вызов пользовательского интерфейса.\n🔷 Новый"
" округленный шрифт.\n🔷 Добавлена возможность скрыть значок администратора."
" \n🔷 Добавлена возможность уменьшить отставание в некоторых действиях.\n🔷"
" Добавлена возможность отключить жирный шрифт (полезно, если вы хотите"
" использовать свой системный шрифт).\n🔷 Добавлена возможность отключения"
" уведомлений от тех , кто Вас заблокировал.\nИ т.п.</i></b>."
),
"iWhatsApp_text3": (
"<b>MBWhatsApp Sticker.\nВерсия для тех, кому нужны стикеры в"
" ватсап.\nОтлично работает с прогами для стикеров, например:"
" https://t.me/progi95/3562\n\nДля установки нужно удалить оригинальную"
" версию с плай маркета.\nУдалять старую, или версию которая вверху не"
" нужно, можно установить сразу оба версии и пользоваться с двух"
" номеров.</b>"
),
"iNotes_text": (
"<b>iNotes Pro — заметки в стиле ios на ваш андроид с дизайном и темами"
" ios, с возможностью поставить пароль при входе, и с другими различными"
" функциями и возможностями!\nМоды: открыта полная версия, без"
" рекламы.\nIbreym Mods. (<a"
" href='https://telegra.ph/Zametki-v-stile-ios-16-na-lyuboj-android-07-11'>скрины</a>)</b>"
),
"iPhotos_text": (
"<b>iPhotos — очень красивая галерея в стиле ios на ваш андроид, с красивым"
" айфоновским дизайном, двумя темами, с корзиной, с альбомами и другими"
" различными настройками.\nМоды: открыта полная версия, без"
" рекламы.\nIbreym Mods. (<a"
" href='https://telegra.ph/Galereya-v-stile-ios-16-na-lyuboj-android-07-10'>скрины</a>)</b>"
),
"iMessages_text": (
"<b>iMessages — сообщения в стиле ios на ваш андроид, со встроенными ios"
" темами черного и светлого цвета, с красивым дизайном, и различными"
" настройками!\nОткрыта полная версия для подписчиков, где нет рекламы и"
" доступны pro функции.\nIbreym Mods.</b>"
),
"iContacts_text": (
"<b>iContacts Ios — контакты в стиле ios на ваш андроид с темной и светлой"
" айфоновской темой, дизайном, и другими функциями как у айфона.\nМоды:"
" открыта полная версия, без рекламы.\nIbreym Mods.</b>"
),
"icompas1": (
"<b>🔥iCompass Pro — это компасс в стиле ios на android, с красивым"
" айфоновским дизайном, которые поможет вам быстро и легко определить"
" точное направление и положение на карте.\n🔑Моды: PRO версия.</b>"
),
"icompas2": (
"<b>🚀Описание модификации:\n— Обнова: 1.1.5\n— Открыта полная версия.\n"
" Удалена реклама.\n— Доступен весь функционал.\n— Удалено лишнее.</b>"
),
"ivoice1": (
"<b>🚀iVoice Pro — диктофон в стиле ios в полным дизайном и функционалом"
" iphone на android. Доступны тёмная и светлая тема, выбор качества и"
" полная версия без рекламы.\n🔑Моды: PRO версия.</b>"
),
"ivoice2": (
"<b>🚀Описание модификации:\n— Обнова: 1.6.1.\n— <a"
" href='https://t.me/progi95_screen/41'>Скрин</a>.\n— Открыта полная"
" версия.\n— Удалена реклама.\n— Доступен весь функционал.\n— Удалено"
" лишнее.\n— Обновлена до последней версии.\n— И прочее.</b>"
),
"itelegram": (
"<b>Ibreym-Telegram — это айфоновский телеграм на андроид, с очень"
" красивым, айфоновским дизайном, темами, шрифтами и с различными классными"
" настройками.</b>"
),
}
@loader.command(ru_doc="-->Inline Лист iOS приложений для Android")
async def iappslistcmd(self, message):
"""-->Inline List iOS Apps for Android"""
self.chat_id = message.chat_id
await self.inline.form(
self.strings("apps-list"),
reply_markup=[
[
{"text": "iCall", "callback": self.icall},
{"text": "iLauncher", "callback": self.ilauncher},
{"text": "iLock", "callback": self.ilock},
],
[
{"text": "iSwift", "callback": self.iswift},
{"text": "iWhatsApp", "callback": self.iwhatsapp},
{"text": "iNotes", "callback": self.inotes},
],
[
{"text": "iPhotos", "callback": self.iphotos},
{"text": "iContacts", "callback": self.icontacts},
{"text": "iMessages", "callback": self.imessages},
],
[
{"text": "iCalculator", "callback": self.icalculator},
{"text": "iCompas", "callback": self.icompas},
{"text": "iVoice", "callback": self.ivoice},
],
[{"text": "iTelegram", "callback": self.itelegram}],
[
{
"text": self.strings("support_chat_btn"),
"url": "https://t.me/AstroModsChat",
},
{
"text": self.strings("more_modules_btn"),
"url": "https://t.me/AstroModules",
},
],
[{"text": self.strings("close_btn"), "action": "close"}],
],
message=message,
)
async def icall(self, *_):
await self.client.send_message(
self.chat_id, self.strings("iCall_text"), file="https://t.me/progi95/3806"
)
async def ilauncher(self, *_):
await self.client.send_message(
self.chat_id,
self.strings("iLauncher_text1"),
file="https://0x0.st/o1Pe.jpg",
)
await self.client.send_message(
self.chat_id,
self.strings("iLauncher_text2"),
file="https://t.me/progi95/3801",
)
async def ilock(self, *_):
await self.client.send_message(
self.chat_id, self.strings("iLock_text"), file="https://t.me/progi95/3796"
)
async def iswift(self, *_):
await self.client.send_message(
self.chat_id,
self.strings("iSwiftKey_text1"),
file="https://0x0.st/o1ZH.jpg",
)
await self.client.send_message(
self.chat_id,
self.strings("iSwiftKey_text2"),
file="https://t.me/progi95/3754",
)
async def iwhatsapp(self, *_):
await self.client.send_message(
self.chat_id,
self.strings("iWhatsApp_text1"),
file="https://0x0.st/o1Zm.jpg",
)
await self.client.send_message(
self.chat_id,
self.strings("iWhatsApp_text2"),
file="https://t.me/progi95/3897",
)
await self.client.send_message(
self.chat_id,
self.strings("iWhatsApp_text3"),
file="https://t.me/progi95/3898",
)
async def inotes(self, *_):
await self.client.send_message(
self.chat_id,
self.strings("iNotes_text"),
file="https://t.me/IbreymMods/576",
)
async def iphotos(self, *_):
await self.client.send_message(
self.chat_id,
self.strings("iPhotos_text"),
file="https://t.me/IbreymMods/574",
)
async def icontacts(self, *_):
await self.client.send_message(
self.chat_id,
self.strings("iContacts_text"),
file="https://t.me/IbreymMods/573",
)
async def imessages(self, *_):
await self.client.send_message(
self.chat_id,
self.strings("iMessages_text"),
file="https://t.me/IbreymMods/572",
)
async def icalculator(self, *_):
await self.client.send_message(
self.chat_id,
self.strings("iCalculator_text"),
file="https://t.me/IbreymMods/577",
)
async def icompas(self, *_):
await self.client.send_message(
self.chat_id, self.strings("icompas1"), file="https://0x0.st/oeEW.jpg"
)
await self.client.send_message(
self.chat_id, self.strings("icompas2"), file="https://t.me/progi95/3885"
)
async def ivoice(self, *_):
await self.client.send_message(
self.chat_id, self.strings("ivoice1"), file="https://0x0.st/oelz.jpg"
)
await self.client.send_message(
self.chat_id, self.strings("ivoice2"), file="https://t.me/progi95/3851"
)
async def itelegram(self, *_):
await self.client.send_message(
self.chat_id, self.strings("itelegram"), file="https://t.me/IbreymMods/585"
)

View File

@@ -0,0 +1,296 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/InlineBotManager.jpg
import logging
from .. import loader
from .. import utils as u
logger = logging.getLogger(__name__)
@loader.tds
class InlineBotManagerMod(loader.Module):
'''Control over your Inline bot!'''
strings = {
"name": "InlineBotManager",
"no_args": (
"No arguments :( | Read, how to use the module, command: <code>{}>/code>"
),
"...-set": (
"<b>{} for your inline bot(@{}) successfully set to <code>{}</code></b>"
),
"error": "An error has occurred.",
"namea": "Name",
"inline-text": "Inline-Text",
"about-text": "About",
"description-text": "Description",
"help-mod": """<b><i>•<u>Instructions for the module:</u>
------------------------------------------------
•<u>Information about the module:</u>
•Module name --> <code>InlineBotManager</code>
•Module description --> <code>Control over your Inline bot!</code>
•Link to the module(to download) --> <code></code>
•Unload the module --> <code>{prefix}unloadmod InlineBotManager</code>
•Your inline botname --> <code>{}</code>
•Your inline bot username --> @{}
------------------------------------------------
• Commands:
• <code>{prefix}ibcheckname</code> --> check bot name to be: "<code>🌘 Hikka Userbot of {your nickname}</code>"
--------------------------------------------
• <code>{prefix}ibsetname </code><name> --> set a name for your Inline Bot
Command example:
<code>{prefix}ibsetname DSOP-UserBot</code>
--------------------------------------------
• <code>{prefix}ibsetqtext </code><text> --> set text instead of "InlineQuery" for your Inline Bot
Command example:
<code>{prefix}ibsetqtext UserBot-Inline-Query</code>
--------------------------------------------
• <code>{prefix}ibsetdescription </code><text> --> change the information Description the inline bot
Command example:
<code>{prefix}ibsetdescription DSOP-UserBot</code>
--------------------------------------------
• <code>{prefix}ibsetabout </code><text> --> change the text about the information about the inline bot
Command example:
<code>{prefix}ibsetabout DSOP-UserBot-about</code>
------------------------------------------------</i></b>""",
"check-yes": "<b>Bot name checked successfully!\nIt's correct.</b>",
"check-no": (
"<b>Your inline bot name(@{}) was successfully checked! Result: bot name"
" didn't match account name, bot name was changed from <code>{}</code> to"
" <code>{}</code></b>"
),
"_cfg_check_name": (
"Check and change the name of your inline bot after every restart?"
),
}
strings_ru = {
"_cls_doc": """Управление над своим Inline ботом!""",
"no_args": (
"Нет аргументов :( | Прочитайте, как пользоваться модулем, командой:"
" <code>{}</code>"
),
"...-set": (
"<b>{} для вашего инлайн-бота(@{}) успешно установлен(-о/-а) на"
" <code>{}</code></b>"
),
"namea": "Имя",
"inline-text": "Inline-Текст",
"about-text": "Текст об информации",
"description-text": "Информация",
"error": "Произошла ошибка.",
"help-mod": """<b><i>•<u>Инструкция к модулю:</u>
------------------------------------------------
•<u>Информация о модуле:</u>
•Название модуля --> <code>InlineBotManager</code>
•Описание модуля --> <code>Управление над своим Inline ботом!</code>
•Ссылка на модуль(для загрузки) --> <code></code>
•Выгрузить модуль --> <code>{prefix}unloadmod InlineBotManager</code>
------------------------------------------------
•Информация о вашем Инлайн-Боте:
------
•Имя бота --> <code>{}</code>
----------------------
•Юзернейм бота --> @{}
------------------------------------------------
•Команды:
• <code>{prefix}ibcheckname</code> --> проверить имя бота, чтобы оно было: "🌘 Hikka Userbot of (ваш ник-нейм)"
------------------------------------------------
• <code>{prefix}ibsetname </code><имя> --> установить имя для вашего Инлайн-Бота
Пример команды:
<code>{prefix}ibsetname DSOP-UserBot</code>
------------------------------------------------
• <code>{prefix}ibsetqtext </code><текст> --> установить текст вместо "InlineQuery" для вашего Инлайн-Бота
Пример команды:
<code>{prefix}ibsetqtext UserBot-Inline-Query</code>
------------------------------------------------
• <code>{prefix}ibsetdescription </code><текст> --> изменить информацию о инлайн-боте
Пример команды:
<code>{prefix}ibsetdescription DSOP-UserBot</code>
------------------------------------------------
• <code>{prefix}ibsetabout </code><текст> --> изменить текст об информации о инлайн-боте
Пример команды:
<code>{prefix}ibsetabout DSOP-UserBot-about</code>
------------------------------------------------</i></b>""",
"ib-help": """<b>----------------------
</b>""",
"check-yes": "<b>Имя бота успешно проверено!\nОно верное.</b>",
"check-no": (
"<b>Имя вашего инлайн-бота(@{}) было успешно проверено! Результат: имя бота"
" не соответствовало имени аккаунта, имя бота было сменено с"
" <code>{}</code> на <code>{}</code></b>"
),
"_cfg_check_name": (
"Проверять и изменять имя вашего инлайн-бота после каждого рестарта?"
),
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"check_name",
False,
lambda: self.strings("_cfg_check_name"),
validator=loader.validators.Boolean(),
)
)
@loader.command(ru_doc="--> Просмотреть помощь по этому модулю")
async def inlinebothelpcmd(self, message):
"""--> Check help for this module"""
await message.delete()
name = self.bot.first_name
username = self.bot.username
await self.client.send_message(
message.peer_id,
self.strings("help-mod").format(
name,
username,
prefix=self.get_prefix(),
),
)
@loader.command(ru_doc="<имя> --> изменить имя для вашего Инлайн-Бота")
async def ibsetnamecmd(self, message):
"""<name> --> change Name for your Inline-Bot"""
args = u.get_args_raw(message)
if not args:
command = f"{self.get_prefix()}inlinebothelp"
await u.answer(message, self.strings("no_args").format(command))
else:
async with self.client.conversation(self.botfather) as conv:
await conv.send_message("/setname")
await conv.send_message(f"@{self.inline.bot_username}")
await conv.send_message(args)
await conv.mark_read()
await u.answer(
message,
self.strings("...-set").format(
self.strings("namea"), self.inline.bot_username, args
),
)
@loader.command(
ru_doc="<текст> --> изменить текст в InlineQuery для вашего Инлайн-Бота"
)
async def ibsetqtextcmd(self, message):
"""<text> --> change text in InlineQuery for your Inline-Bot"""
args = u.get_args_raw(message)
if not args:
command = f"{self.get_prefix()}inlinebothelp"
await u.answer(message, self.strings("no_args").format(command))
else:
async with self.client.conversation(self.botfather) as conv:
await conv.send_message("/setinline")
await conv.send_message(f"@{self.inline.bot_username}")
await conv.send_message(args)
await conv.mark_read()
await u.answer(
message,
self.strings("...-set").format(
self.strings("inline-text"), self.inline.bot_username, args
),
)
@loader.command(ru_doc="<текст> --> изменить информацию о инлайн-боте")
async def ibsetdescriptioncmd(self, message):
"""<description> --> change inline-bot description"""
args = u.get_args_raw(message)
if not args:
command = f"{self.get_prefix()}inlinebothelp"
await u.answer(message, self.strings("no_args").format(command))
else:
async with self.client.conversation(self.botfather) as conv:
await conv.send_message("/setdescription")
await conv.mark_read()
await conv.send_message(f"@{self.inline.bot_username}")
await conv.mark_read()
await conv.send_message(args)
await u.answer(
message,
self.strings("...-set").format(
self.strings("description-text"), self.inline.bot_username, args
),
)
@loader.command(ru_doc="<текст> --> изменить текст об информации о инлайн-боте")
async def ibsetaboutcmd(self, message):
"""<about> --> change inline-bot about text"""
args = u.get_args_raw(message)
if not args:
command = f"{self.get_prefix()}inlinebothelp"
await u.answer(message, self.strings("no_args").format(command))
else:
async with self.client.conversation(self.botfather) as conv:
await conv.send_message("/setabouttext")
await conv.send_message(f"@{self.inline.bot_username}")
await conv.send_message(args)
await conv.mark_read()
await u.answer(
message,
self.strings("...-set").format(
self.strings("about-text"), self.inline.bot_username, args
),
)
@loader.command(
ru_doc="""-->проверить имя бота, чтобы оно было: "🌘 Hikka Userbot of {ваш ник}" """
)
async def ibchecknamecmd(self, message):
"""-->check bot name to be: "🌘 Hikka Userbot of {your nickname}" """
bot_name = self.bot.first_name
acc_name = self.acc.first_name
norm_nameb = f"🌘 Hikka Userbot of {acc_name}"
if bot_name == norm_nameb:
await u.answer(message, self.strings("check-yes"))
logger.debug(self.strings("check-yes"))
else:
async with self.client.conversation(self.botfather) as conv:
await conv.send_message("/setname")
await conv.send_message(f"@{self.inline.bot_username}")
await conv.send_message(norm_nameb)
await conv.mark_read()
logger.info(
self.strings("check-no").format(self.bot.username, bot_name, norm_nameb)
)
await u.answer(
message,
self.strings("check-no").format(
self.inline.bot_username, bot_name, norm_nameb
),
)
async def client_ready(self, *_):
self.botfather = "@BotFather"
self.bot = await self.inline.bot.get_me()
self.acc = await self.client.get_me()
if self.config["check_name"]:
m = await self.client.send_message("me", f"{self.get_prefix()}ibcheckname")
await self.ibchecknamecmd(m)

View File

@@ -0,0 +1,92 @@
__version__ = (1, 0, 2)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/Komaru.jpg
# meta developer: @AstroModules
from random import choice
from telethon.tl.types import (
InputMessagesFilterGif,
InputMessagesFilterPhotos,
InputMessagesFilterVideo,
Message,
)
from .. import loader, utils
class KomaruMod(loader.Module):
'''Random picture/video/gif from the @komarueveryday'''
strings = {
"name": "Komaru",
"choosing": "<emoji document_id=5328311576736833844>🔴</emoji> Choosing {}...",
"gif": "gif",
"video": "video",
"photo": "photo",
}
strings_ru = {
"choosing": "<emoji document_id=5328311576736833844>🔴</emoji> Подбираем {}...",
"gif": "ваш гиф",
"video": "ваше видео",
"photo": "вашу картинку(пикчу)",
}
SEARCH_TYPES = {
InputMessagesFilterGif: "gif",
InputMessagesFilterPhotos: "photo",
InputMessagesFilterVideo: "video",
}
@loader.command(
ru_doc="- подобрать рандом картинку(пикчу)/видео/гиф"
)
async def komaru(self, message: Message):
"""- choose a random picture/gif/video"""
search_type = choice([
InputMessagesFilterGif,
InputMessagesFilterPhotos,
InputMessagesFilterVideo
])
search_type_str = self.strings(self.SEARCH_TYPES[search_type])
msg = await utils.answer(message, self.strings("choosing").format(search_type_str))
chosed_msg = choice([
message_in_channel
async for message_in_channel in self.client.iter_messages(
"komarueveryday",
limit=200,
filter=search_type
)
])
reply = None if not (reply := await message.get_reply_message()) else reply.id
return await utils.answer_file(
msg,
chosed_msg,
chosed_msg.text or "<b>Подобрал " + search_type_str + ".</b>",
reply_to=reply
)

View File

@@ -0,0 +1,149 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/MindTalk.jpg
import requests
from .. import loader, utils
class MindTalkMod(loader.Module):
'''Your little psychologist Based on MindTalk by Hikamoru'''
strings = {
'name': 'MindTalk',
'args_error': '<emoji document_id=5273793379300289907>❗️</emoji> <b>Missing or invalid arguments!</b>',
'successful_login': '<emoji document_id=5206607081334906820>✔️</emoji> <b>Login completed successfully. Token saved in config</b>',
'not_token': '<emoji document_id=5210952531676504517>❌</emoji> <b>Missing access token. Please login using the <code>{}login</code> command</b>',
'wait': '<emoji document_id=5310192647313301616>☕️</emoji> <b>Waiting answer from a psychologist...</b>',
'login_error': (
'<emoji document_id=5210952531676504517>❌</emoji> '
'<b>Login failed. You may have entered the wrong password or you are not registered. '
'Try again, or go through the authorization again using <a href="https://t.me/hikpsybot?start=register">this link.</a></b>'
),
'answer': (
'<emoji document_id=5818995853544656277>👩‍💻</emoji> '
'<b>Your question:</b> {}\n\n'
'<emoji document_id=5431602426354344379>👩‍⚕️</emoji> '
'<b>Answer from psychologist:</b> {}'
),
'history_cleared': '<emoji document_id=5818967120213445821>🛡</emoji> <b>Your history has been successfully cleared</b>'
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
'token',
None,
lambda: 'Your access token. Displayed automatically!',
validator=loader.validators.Hidden()
)
)
self.url = 'https://ps.hikamoru.uz'
async def get_token(self, login, password):
params = {
'username': login,
'password': password
}
if (
await utils.run_sync(
requests.post,
self.url + '/api/authenticate',
params=params
)
).json()['result']:
token = (
await utils.run_sync(
requests.post,
self.url + '/api/createUserToken',
params=params
)
).json()['result']
self.config['token'] = token
return True
else:
return False
@loader.command()
async def login(self, message):
'''<login> <password> - log in and save token'''
args = utils.get_args_raw(message)
if not args or not args.split()[1]:
return await utils.answer(message, self.strings('args_error'))
login, password = args.split()
gen = await self.get_token(login, password)
return await utils.answer(
message,
self.strings(
'login_error'
if not gen
else 'successful_login'
)
)
@loader.command()
async def ask(self, message):
'''<message> - ask a psychologist a question'''
args = utils.get_args_raw(message)
if not args:
return await utils.answer(message, self.strings('args_error'))
if not self.config['token']:
return await utils.answer(
message,
self.strings('not_token').format(self.get_prefix())
)
params = {
'userMessage': args,
'TOKEN': self.config['token']
}
msg = await utils.answer(message, self.strings('wait'))
response = (requests.post(self.url + '/api/chat', params=params)).json()
text = response['result']
await utils.answer(msg, self.strings('answer').format(args, text))
@loader.command()
async def mtclear(self, message):
'''- clear MindTalk history'''
if not self.config['token']:
return await utils.answer(
message,
self.strings('not_token').format(self.get_prefix())
)
params = {'TOKEN': self.config['token']}
await utils.run_sync(
requests.post,
self.url + '/api/clear_chat_history',
params=params
)
await utils.answer(message, self.strings('history_cleared'))

View File

@@ -0,0 +1,373 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/MineSwepper.png
# meta developer: @AstroModules
import random
from .. import loader, utils
class Cell:
"""Cell on the minesweeper board"""
def __init__(self, value: int = 0, is_mine: bool = False, is_visible: bool = False):
self.is_mine = is_mine
self.value = value
self.is_visible = is_visible
self.emoji = "◽️"
self.emoji2 = ""
class MineSweeperGame:
"""Minesweeper game"""
def __init__(self, rows: int, cols: int, mines: int):
self.mode = 1 # 1 - miner, 2 - flag
self.flags = 0
self.board: list[list[Cell]] = []
self.rows = rows
self.cols = cols
self.mines = mines
def generate_board(self):
"""Generate the minesweeper board"""
self.board = [
[
Cell()
for _ in range(self.cols)
] for _ in range(self.rows)
]
mine_positions = random.sample(range(self.rows * self.cols), self.mines)
for position in mine_positions:
row = position // self.cols
col = position % self.cols
self.board[row][col].value = None
self.board[row][col].is_mine = True
self.board[row][col].emoji2 = "💣"
for i in range(row - 1, row + 2):
for j in range(col - 1, col + 2):
if 0 <= i < self.rows and 0 <= j < self.cols and not self.board[i][j].is_mine:
self.board[i][j].value += 1
for row in self.board:
for cell in row:
if cell.value:
cell.emoji2 = {
1: "1",
2: "2",
3: "3",
4: "4",
5: "5",
6: "6",
7: "7",
8: "8",
}[cell.value]
def reveal_cell(self, row_index, col):
"""Reveal a cell on the minesweeper board"""
if self.board[row_index][col].is_mine:
if len([
cell
for row in self.board
for cell in row
if cell.is_visible
]) in [0, 1]:
self.generate_board()
return self.reveal_cell(row_index, col)
return False
elif self.board[row_index][col].value == 0:
self._reveal_empty_cells(row_index, col)
else:
self.board[row_index][col].is_visible = True
return self.board
def reveal_next_to_empty_cells(self):
"""Reveal all next to empty cells"""
for index_row, row in enumerate(self.board):
for index_cell, cell in enumerate(row):
if cell.value == 0 and cell.is_visible:
for i in range(index_row - 1, index_row + 2):
for j in range(index_cell - 1, index_cell + 2):
if 0 <= i < self.rows and 0 <= j < self.cols:
if not self.board[i][j].is_mine and not self.board[i][j].is_visible:
self.reveal_cell(i, j)
def _reveal_empty_cells(self, row, col):
"""Reveal all empty cells connected to the given cell"""
if self.board[row][col].value == 0:
self.board[row][col].is_visible = True
for i in range(row - 1, row + 2):
for j in range(col - 1, col + 2):
if 0 <= i < self.rows and 0 <= j < self.cols:
if not self.board[i][j].is_mine and not self.board[i][j].is_visible and self.board[i][j].value == 0:
self.reveal_cell(i, j)
class MineSwepperModule(loader.Module):
"""Minesweeper game"""
strings = {
"name": "MineSweeper",
"mines": "Number of mines",
"rows": "Number of rows",
"cols": "Number of columns",
"game": "🎮 <b>MineSweeper game</b>\n\n💣 <b>{mines}</b> mines\n🧮 <b>{rows}</b> rows\n💈 <b>{cols}</b> columns\n🚩 <b>{flags}</b> flags",
"game-over": "❌ <b>Game over!</b>\n💣 <b>You hit a mine.</b>\n\n💣 <b>{mines}</b> mines\n🧮 <b>{rows}</b> rows\n💈 <b>{cols}</b> columns\n🚩 <b>{flags}</b> flags",
"game-end": "❌ <b>Game over!</b>\n🎉 <b>You win!</b>\n\n💣 <b>{mines}</b> mines\n🧮 <b>{rows}</b> rows\n💈 <b>{cols}</b> columns\n🚩 <b>{flags}</b> flags",
"game-ended": "❌ Game over!",
"continue-or-start-new-game": "⚠️ <b>Game already started!</b>\n❔ Continue or start new game?",
"continue": "▶️ Continue",
"start-new-game": "🆕 Start new game",
"game-title": "🎮 <b>MineSweeper game</b>",
"game-not-found": "❌ Game not found!",
"cell-flagged": "🚩 Cell flagged",
"switch-mode": "🔄 Switch to «🚩» mode",
}
strings_ru = {
"_cls_doc": "Игра \"Сапёр\"",
"mines": "Количество мин",
"rows": "Количество строк",
"cols": "Количество столбцов",
"game": "🎮 <b>Игра \"Сапёр\"</b>\n\n💣 <b>{mines}</b> мин\n🧮 <b>{rows}</b> строк\n💈 <b>{cols}</b> столбцов\n🚩 <b>{flags}</b> флагов",
"game-over": "❌ <b>Игра окончена!</b>\n<b>💣 Вы попали на мину.</b>\n\n💣 <b>{mines}</b> мин\n🧮 <b>{rows}</b> строк\n💈 <b>{cols}</b> столбцов\n🚩 <b>{flags}</b> флагов",
"game-end": "❌ <b>Игра окончена!</b> \n<b>🎉 Вы выиграли!</b>\n\n💣 <b>{mines}</b> мин\n🧮 <b>{rows}</b> строк\n💈 <b>{cols}</b> столбцов\n🚩 <b>{flags}</b> флагов",
"game-ended": "❌ Игра окончена!",
"continue-or-start-new-game": "⚠️ <b>В этом чате уже идёт игра!</b>\n❔ Продолжить или начать новую игру?",
"continue": "▶️ Продолжить",
"start-new-game": "🆕 Начать новую игру",
"game-title": "🎮 <b>Игра \"Сапёр\"</b>",
"game-not-found": "❌ Игра не найдена! Возможно она уже завершена.",
"cell-flagged": "🚩 Поле помечено",
"switch-mode": "🔄 Переключиться на режим «{}»"
}
def __init__(self):
self.games = {}
self.config = loader.ModuleConfig(
loader.ConfigValue(
"mines",
10,
lambda: self.strings("mines"),
validator=loader.validators.Integer(minimum=1, maximum=99),
),
loader.ConfigValue(
"rows",
8,
lambda: self.strings("rows"),
validator=loader.validators.Integer(minimum=1, maximum=10),
),
loader.ConfigValue(
"cols",
8,
lambda: self.strings("cols"),
validator=loader.validators.Integer(minimum=1, maximum=8),
)
)
def generate_markup(self, chat_id):
if not self.games.get(chat_id):
return
return [
[
{
"text": i.emoji2 if i.is_visible else i.emoji,
"callback": self.mine if self.games.get(chat_id).mode == 1 else self.flag,
"kwargs": {
"row": self.games.get(chat_id).board.index(row),
"col": row.index(i),
"chat_id": chat_id
}
}
for i in row
]
for row in self.games.get(chat_id).board
] + [
[
{
"text": self.strings("switch-mode").format('🚩' if self.games.get(chat_id).mode == 1 else '⛏️'),
"callback": self.switch_mode,
"kwargs": {
"chat_id": chat_id
}
}
]
]
async def switch_mode(self, call, chat_id):
self.games.get(chat_id).mode = 1 if self.games.get(chat_id).mode == 2 else 2
await call.edit(
self.strings("game").format(
mines=self.games.get(chat_id).mines,
rows=self.games.get(chat_id).rows,
cols=self.games.get(chat_id).cols,
flags=self.games.get(chat_id).flags
),
reply_markup=self.generate_markup(chat_id)
)
async def flag(self, call, row, col, chat_id):
if self.games.get(chat_id).mode != 2:
return
if self.games.get(chat_id).board[row][col].emoji != "🚩":
self.games.get(chat_id).flags += 1
self.games.get(chat_id).board[row][col].emoji = "🚩"
else:
self.games.get(chat_id).flags -= 1
self.games.get(chat_id).board[row][col].emoji = "◽️"
await call.edit(
self.strings("game").format(
mines=self.games.get(chat_id).mines,
rows=self.games.get(chat_id).rows,
cols=self.games.get(chat_id).cols,
flags=self.games.get(chat_id).flags
),
reply_markup=self.generate_markup(chat_id)
)
@loader.command(
ru_doc="- начать игру \"Сапёр\"",
alias="mines",
)
async def minesweeper(self, message):
"""- start the game "Minesweeper" """
chat_id: int = utils.get_chat_id(message)
if chat_id in self.games:
await utils.answer(message, self.strings("continue-or-start-new-game"), reply_markup=[
[
{
"text": self.strings("continue"),
"callback": self.continue_game,
"kwargs": {
"chat_id": chat_id
}
}
],
[
{
"text": self.strings("start-new-game"),
"callback": self.start_game,
"kwargs": {
"chat_id": chat_id
}
}
]
])
else:
await utils.answer(message, self.strings("game-title"), reply_markup=[
[
{
"text": self.strings("start-new-game"),
"callback": self.start_game,
"kwargs": {
"chat_id": chat_id
}
}
]
])
async def start_game(self, call, chat_id: int):
self.games[chat_id] = MineSweeperGame(
rows=self.config["rows"],
cols=self.config["cols"],
mines=self.config["mines"],
)
self.games.get(chat_id).generate_board()
await call.edit(
self.strings("game").format(
mines=self.games.get(chat_id).mines,
rows=self.games.get(chat_id).rows,
cols=self.games.get(chat_id).cols,
flags=self.games.get(chat_id).flags
),
reply_markup=self.generate_markup(chat_id)
)
async def continue_game(self, call, chat_id: int):
await call.edit(
self.strings("game").format(
mines=self.games.get(chat_id).mines,
rows=self.games.get(chat_id).rows,
cols=self.games.get(chat_id).cols,
flags=self.games.get(chat_id).flags
),
reply_markup=self.generate_markup(chat_id)
)
async def mine(self, call, row, col, chat_id):
if not self.games.get(chat_id, None):
return await call.answer(self.strings("game-not-found"), show_alert=True)
if self.games.get(chat_id).board[row][col].emoji == "🚩":
return await call.answer(self.strings("cell-flagged"), show_alert=True)
result = self.games.get(chat_id).reveal_cell(row, col)
self.games.get(chat_id).reveal_next_to_empty_cells()
if not result or len([
i
for row in self.games.get(chat_id).board
for i in row
if not i.is_visible
]) == self.games.get(chat_id).mines:
await call.edit(
self.strings("game-over" if not result else "game-end").format(
mines=self.games.get(chat_id).mines,
rows=self.games.get(chat_id).rows,
cols=self.games.get(chat_id).cols,
flags=self.games.get(chat_id).flags
),
reply_markup=[
[
{
"text": i.emoji2,
"action": "answer",
"message": self.strings("game-ended")
}
for i in row
]
for row in self.games.get(chat_id).board
] + [
[
{
"text": self.strings("start-new-game"),
"callback": self.start_game,
"kwargs": {
"chat_id": chat_id
}
}
]
])
del self.games[chat_id]
else:
await call.edit(
self.strings("game").format(
mines=self.games.get(chat_id).mines,
rows=self.games.get(chat_id).rows,
cols=self.games.get(chat_id).cols,
flags=self.games.get(chat_id).flags
),
reply_markup=self.generate_markup(chat_id)
)

View File

@@ -0,0 +1,291 @@
__version__ = (1, 0, 0)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/PCManager.jpg
from typing import Union
from telethon.tl.types import Message
from .. import loader, utils
from ..inline.types import InlineCall
class PCManagerMod(loader.Module):
'''Управление вашим компьютером через юзербота'''
strings = {"name": "PC-Manager"}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
'bot_username',
None,
doc=lambda: "Введите юзернейм вашего бота для управления ПК"
)
)
async def client_ready(self):
self.lib = await self.import_lib(
'https://raw.githubusercontent.com/ToXic2290/Hikka-moduless/main/AstroModules_Library.py',
suspend_on_error=False,
)
@loader.command()
async def addbot(self, message: Message):
'''- добавить бота
💎 Основные команды:'''
await self.allmodules.commands["config"](
await utils.answer(message, f"{self.get_prefix()}config PC-Manager")
)
@loader.command()
async def tutor(self, message: Message):
"""- туториал по подключению"""
await utils.answer(message, "<emoji document_id=5787237370709413702>⚙️</emoji> <b>Туториал по настройке модуля:</b>\n\n@PC_AM_Tutor\n\nЕсли возникли трудности с установкой, пожалуйста, обратитесь в чат AstroModules ")
@loader.command()
async def pcoff(self, message: Message):
"""- выключить компьютер"""
bot = self.config["bot_username"]
call = await self.lib.message_g('🛑 Shutdown',
bot,
mark_read=True,
delete=True
)
await utils.answer(message, f'<emoji document_id=5787544344906959608></emoji> <b>[PC_Manager]</b> <emoji document_id=5787544344906959608></emoji>\n\n{call.text}')
@loader.command()
async def pcreboot(self, message: Message):
"""- перезагрузить компьютер"""
bot = self.config["bot_username"]
call = await self.lib.message_g('🔄 Reboot',
bot,
mark_read=True,
delete=True
)
await utils.answer(message, f'<emoji document_id=5787544344906959608></emoji> <b>[PC_Manager]</b> <emoji document_id=5787544344906959608></emoji>\n\n{call.text}')
@loader.command()
async def pcinfo(self, message: Message):
"""- просмотреть характеристики системы"""
bot = self.config["bot_username"]
call = await self.lib.message_q('💻 System Info',
bot,
mark_read=True,
delete=True
)
await utils.answer(message, f'<emoji document_id=5787544344906959608></emoji> <b>[PC_Manager]</b> <emoji document_id=5787544344906959608></emoji>\n\n{call.text}')
@loader.command()
async def pcip(self, message: Message):
"""- просмотреть информацию об айпи адресе"""
bot = self.config["bot_username"]
call = await self.lib.message_q('🌐 IP Info',
bot,
mark_read=True,
delete=True
)
await utils.answer(message, f'<emoji document_id=5787544344906959608></emoji> <b>[PC_Manager]</b> <emoji document_id=5787544344906959608></emoji>\n\n{call.text}')
@loader.command()
async def pcscrin(self, message: Message):
"""- сделать скриншот экрана"""
bot = self.config['bot_username']
call = await self.lib.message_g('/screenshot',
bot,
mark_read=True,
delete=True
)
await utils.answer(message, '<emoji document_id=5787544344906959608></emoji> <b>[PC_Manager]</b> <emoji document_id=5787544344906959608></emoji>\n\nОтправка скриншота...')
await message.respond(call)
@loader.command()
async def pcweb(self, message: Message):
"""<ссылка> - открыть ссылку в браузере"""
bot = self.config['bot_username']
args = utils.get_args_raw(message)
call = await self.lib.message_q(f'/browse {args}',
bot,
mark_read=True,
delete=True
)
await utils.answer(message, f'<emoji document_id=5787544344906959608></emoji> <b>[PC_Manager]</b> <emoji document_id=5787544344906959608></emoji>\n\n{call.text}\n\nСсылка: {args}')
@loader.command()
async def pcwebscrin(self, message: Message):
"""- сделать снимок с веб-камеры
🔑 Дополнительно:"""
bot = self.config['bot_username']
call = await self.lib.message_g('/photo',
bot,
mark_read=True,
delete=True
)
await utils.answer(message, '<emoji document_id=5787544344906959608></emoji> <b>[PC_Manager]</b> <emoji document_id=5787544344906959608></emoji>\n\nОтправка снимка...')
await message.respond(call)
@loader.command()
async def pcalert(self, message: Message):
"""<сообщение> - вывести на экран сообщение"""
bot = self.config['bot_username']
args = utils.get_args_raw(message)
call = await self.lib.message_q(f'/alert {args}',
bot,
mark_read=True,
delete=True
)
await message.respond(f'<emoji document_id=5787544344906959608></emoji> <b>[PC_Manager]</b> <emoji document_id=5787544344906959608></emoji>\n\n{call.text}')
await message.delete()
@loader.command()
async def pcvol(self, message: Message):
"""- управление звуком"""
await self.inline.form(
text=" <b>[PC_Manager]</b> \n\n<b>Мишкер громкости</b>",
reply_markup=[
[
{
"text": "10%",
"callback": self.set_volume,
"args": (10,)
},
{
"text": "20%",
"callback": self.set_volume,
"args": (20,)
},
{
"text": "30%",
"callback": self.set_volume,
"args": (30,)
},
],
[
{
"text": "40%",
"callback": self.set_volume,
"args": (40,)
},
{
"text": "50%",
"callback": self.set_volume,
"args": (50,)
},
{
"text": "60%",
"callback": self.set_volume,
"args": (60,)
},
],
[
{
"text": "70%",
"callback": self.set_volume,
"args": (70,)
},
{
"text": "80%",
"callback": self.set_volume,
"args": (80,)
},
{
"text": "90%",
"callback": self.set_volume,
"args": (90,)
},
],
[
{
"text": "⬆️",
"callback": self.set_volume,
"args": ("up",)
},
{
"text": "100%",
"callback": self.set_volume,
"args": (100,)
},
{
"text": "⬇️",
"callback": self.set_volume,
"args": ("down",)
},
],
[
{
"text": "🚫 Закрыть",
"action": "close"
}
],
],
message=message,
)
@loader.command()
async def pcmedia(self, message: Message):
"""- управление музыкой"""
await self.inline.form(
text=" <b>[PC_Manager]</b> \n\n<b>Управление медиа</b>",
reply_markup=[
[
{
"text": "",
"callback": self.nazad
},
{
"text": "",
"callback": self.pausa
},
{
"text": "",
"callback": self.vpered
},
],
[{"text": "🚫 Закрыть", "action": "close"}],
],
message=message,
)
async def set_volume(self, call: InlineCall, volume: Union[int, str]):
bot = self.config['bot_username']
await self.client.send_message(bot, f'/volume {volume}')
return await call.answer("Успешно!", show_alert=False)
async def nazad(self, call: InlineCall):
bot = self.config['bot_username']
await self.client.send_message(f'{bot}', '/key__prev')
return await call.answer("Успешно!", show_alert=False)
async def pausa(self, call: InlineCall):
bot = self.config['bot_username']
await self.client.send_message(f'{bot}', '/key__play')
return await call.answer("Успешно!", show_alert=False)
async def vpered(self, call: InlineCall):
bot = self.config['bot_username']
await self.client.send_message(f'{bot}', '/key__next')
return await call.answer("Успешно!", show_alert=False)
# Tx...

View File

@@ -0,0 +1,87 @@
__version__ = (1, 0, 0)
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/AstroShazam.png
# The code snippet is adapted from VoiceMod code by D4n1l3k300
# requires: ShazamAPI
import io
from ShazamAPI import Shazam
from .. import loader, utils
@loader.tds
class ShazamMod(loader.Module):
"""Use <reply to voice> to search for a song using audio."""
strings = {
"name": 'Shazam',
"Downloading": "<emoji document_id=5443127283898405358>📥</emoji> <b>Downloading...</b>",
"Searching": "<emoji document_id=5447410659077661506>🔎</emoji> <b>Searching...</b>",
"no_reply": "<emoji document_id=5294339927318739359>🎙</emoji> <b>Please reply to an audio message.</b>",
"not_found": "<emoji document_id=5210952531676504517>🚫</emoji> <b>Song not found.</b>",
"track_info": (
"<emoji document_id=5325547803936572038>✨</emoji> <b>Song found</b>\n"
'<emoji document_id=5460795800101594035>📝</emoji> <b>Name</b> "<code>{}</code>"'
)
}
strings_ru = {
"Downloading": "<emoji document_id=5443127283898405358>📥</emoji> <b>Загрузка..</b>",
"Searching": "<emoji document_id=5447410659077661506>🔎</emoji> <b>Поиск..</b>",
"no_reply": "<emoji document_id=5294339927318739359>🎙</emoji> <b>Oтветьте на аудио сообщение</b>",
"not_found": "<emoji document_id=5210952531676504517>🚫</emoji> <b>Не удалось найти песню</b>",
"track_info": (
"<emoji document_id=5325547803936572038>✨</emoji> <b>Песня найдена</b>\n"
'<emoji document_id=5460795800101594035>📝</emoji> <b>Название:</b> "<code>{}</code>"'
)
}
async def fetch_audio(self, message):
reply = await message.get_reply_message()
if reply and reply.file and reply.file.mime_type.startswith("audio"):
await utils.answer(message, self.strings['Downloading'])
audio_data = io.BytesIO(await reply.download_media(bytes))
await utils.answer(message, self.strings['Searching'])
return audio_data, reply
await utils.answer(message, self.strings['no_reply'])
return None, None
@loader.command(ru_doc='<reply to audio> - распознать трек')
async def sh(self, message):
"""<reply to audio> - recognize track"""
audio_data, reply = await self.fetch_audio(message)
if not audio_data:
return
try:
shazam = Shazam(audio_data.read())
recog = next(shazam.recognizeSong())[1]["track"]
await self.client.send_file(
message.peer_id,
file=recog["images"]["background"],
caption=self.strings['track_info'].format(recog["share"]["subject"]),
reply_to=reply.id,
)
await message.delete()
except Exception:
await utils.answer(message, self.strings['not_found'])

View File

@@ -0,0 +1,56 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/Summer.jpg
from datetime import datetime
from .. import loader, utils
class SummerMod(loader.Module):
'''Сколько осталось дней до лета?)'''
strings = {'name': 'SummerTimer'}
@loader.command()
async def st(self, message):
"""- вывести таймер"""
now = datetime.now()
summer = datetime(now.year, 6, 1)
if now.month > 6 or (now.month == 6 and now.day > 1):
summer = datetime(now.year + 1, 6, 1)
time_to_summer = abs(summer - now)
await utils.answer(
message,
(
'<b><emoji document_id=6334560373387036241>🏝️</emoji> '
f'До <u>лета</u> осталось {time_to_summer.days} дней, '
f'{time_to_summer.seconds // 3600} часов, {time_to_summer.seconds // 60 % 60}'
f' минут, {time_to_summer.seconds % 60} секунд.\n<b><emoji '
'document_id=5393226077520798225>🥰</emoji> Жди лето вместе '
'с <u>AstroModules</u></b>'
)
)

View File

@@ -0,0 +1,96 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/VideoToVoice.jpg
# requires: moviepy
import os
from pathlib import Path
import moviepy.editor
import telethon
from .. import loader, utils
@loader.tds
class VideoToVoice(loader.Module):
'''Convert Video to voice'''
strings = {
"name": "VideoToVoice"
}
def get_audio(self, path: str) -> str:
video_file = Path(path)
video = moviepy.editor.VideoFileClip(str(video_file))
audio = video.audio
audio.write_audiofile(f"{video_file.stem}.ogg")
os.remove(path)
return f"{video_file.stem}.ogg"
def get_duration(self, attributes):
duration = 0
for i in attributes:
if isinstance(i, telethon.tl.types.DocumentAttributeVideo):
duration = i.duration
break
return duration
@loader.command()
async def convert_to_voice(self, message):
"""<reply_to_video> -> получить Войс звука видео, либо отправлять команду с прикрепленным видео(оно удалится после отправления сделанного войса), либо отправить команду ответом на видео."""
msg = await utils.answer(message, "Ожидайте, загрузка...")
reply = await message.get_reply_message()
if message.media is None and reply and reply.media is None or message.media is None and reply is None:
return await utils.answer(msg, "Кажется вы не ответили командой на видео или не прикрепили видео к сообщению с командой.")
if message.media:
msg_media = message
elif reply and reply.media:
msg_media = await message.get_reply_message()
else:
return await utils.answer(msg, "Кажется вы не ответили командой на видео или не прикрепили видео к сообщению с командой.")
path = self.get_audio((await msg_media.download_media()))
await self.client.send_file(
message.chat.id,
path,
attributes=[
telethon.tl.types.DocumentAttributeAudio(
duration=(self.get_duration(msg_media.media.document.attributes)),
voice=True,
title=None,
performer=None,
waveform=None
)
]
)
os.remove(path)
if msg.out:
await msg.delete()

View File

@@ -0,0 +1,111 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
# meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/WordlyHelper.jpg
import re
import requests
from .. import loader, utils
@loader.tds
class WordlyHelper(loader.Module):
'''Помощник для игры "Вордли на Русском"'''
strings = {
"name": "WordlyHelper",
"not_args": "<emoji document_id=5352594935281360755>🚫</emoji> | <b>Аргументы где?</b>",
"search": "<emoji document_id=5310041868191407556>🔸</emoji> | Поиск слов...",
"result": (
'<emoji document_id=5276288708054624909>🔹</emoji>'
' <b>Слова по вашему запросу</b>:\n\n<code>{}</code>\n\n'
'<emoji document_id=5841711707939933938>🔸</emoji>'
' Запрос: <code>{}</code>'
),
"not_found": "<emoji document_id=6334578700012488415>❌</emoji> Не найдено",
"not_in_db": "<emoji document_id=5352594935281360755>🚫</emoji> | <b>В базе нету слов из {} букв</b> 😠",
}
async def client_ready(self):
self.slova = {}
for i, o in requests.get("https://0x0.st/HNeQ.json").json().items():
self.slova[i] = [
word + " "
for word in o
]
def letters_in_word(self, word: str, letters: list[str]):
for letter in letters:
if letter not in word:
return False
return True
def letters_not_in_word(self, word: str, letters: list[str]):
for letter in letters:
if letter in word:
return False
return True
def get_word(self, marking, _not: list[str] = [], _yes: list[str] = []):
return [
i
for i in utils.array_sum(list(self.slova.values()))
if re.match(marking.replace("*", "(.)").replace("$", "(.*)") + " ", i)
and self.letters_in_word(i, _yes)
and self.letters_not_in_word(i, _not)
]
@loader.command()
async def wordly(self, message):
"""<маркировка слова> [-not <буквы подряд, которых точно нету в слове>] [-yes <буквы подряд, которые точно есть в слове] - Найти слова по маркировке:
* - одна любая буква
$ - любое кол-во любых букв
пример: *т**т -yes оч -not абвгд : отчет
"""
args = utils.get_args(message)
if not args:
return await utils.answer(message, self.strings("not_args"))
markirovka = args[0]
if str(len(markirovka)) not in self.slova:
return await utils.answer(message, self.strings("not_in_db").format(len(markirovka)))
_not = []
_yes = []
msg = await utils.answer(message, self.strings("search"))
for arg in args:
if arg == "-not":
_not = list(args[args.index(arg)+1])
if arg == "-yes":
_yes = list(args[args.index(arg)+1])
return await utils.answer(msg, self.strings("result").format(
"</code>\n<code>".join(
self.get_word(markirovka, _not, _yes)
) or self.strings("not_found"), " ".join(args)
))

View File

@@ -0,0 +1,61 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
import random
from telethon.tl.types import Message
from .. import loader
@loader.tds
class ВахуиПонMod(loader.Module):
'''пон и вахуи'''
strings = {"name": "ВАХУИ-ПОН", "pon": "пон", "vahui": "вахуи"}
@loader.command()
async def понcmd(self, message: Message):
"""--> пон"""
reply = await message.get_reply_message()
m = random.choice(await self.client.get_messages("@PON_STICKS", limit=100))
if reply:
await self.client.send_message(message.chat_id, file=m, reply_to=reply)
else:
await message.respond(file=m)
if message.out:
await message.delete()
@loader.command()
async def вахуиcmd(self, message: Message):
"""--> вахуи"""
reply = await message.get_reply_message()
m = random.choice(await self.client.get_messages("@VAHUI_STICKS", limit=100))
if reply:
await self.client.send_message(message.chat_id, file=m, reply_to=reply)
else:
await message.respond(file=m)
if message.out:
await message.delete()

View File

@@ -0,0 +1,104 @@
#
# @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@
# @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
# @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@
# !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@!
# @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!!
# !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!!
# !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:!
# :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:!
# :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: ::
# : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : :
#
# © Copyright 2024
#
# https://t.me/Den4ikSuperOstryyPer4ik
# and
# https://t.me/ToXicUse
#
# 🔒 Licensed under the GNU AGPLv3
# https://www.gnu.org/licenses/agpl-3.0.html
#
# meta developer: @AstroModules
import random
import typing
from .. import loader
@loader.tds
class ПонВахуиMod(loader.Module):
'''пон и вахуи'''
strings = {"name": "ПОН-ВАХУИ"}
@loader.command()
async def пон(self, message):
"""--> инлайн меню со стикерами пон"""
reply = await message.get_reply_message()
await self.inline.form(
message=message,
text="👇<b>пон</b>👇",
reply_markup=[
[
{
"text": "пон",
"callback": self.open_menu_pon,
"kwargs": {"chat_id": message.chat_id, "reply_to": reply.id if reply else None}
}
]
],
)
@loader.command()
async def вахуи(self, message):
"""--> инлайн меню со стикерами "вахуи" """
reply = await message.get_reply_message()
await self.inline.form(
message=message,
text="👇<b>вахуи</b>👇",
reply_markup=[
[
{
"text": "вахуи",
"callback": self.open_menu_vahui,
"kwargs": {"chat_id": message.chat_id, "reply_to": reply.id if reply else None}
}
]
],
)
async def send_sticker_pon(self, chat_id, reply_to: typing.Optional[int] = None):
m = await self.client.get_messages("@PON_STICKS", ids=random.randint(1, 100))
await self.client.send_message(chat_id, file=m, reply_to=reply_to)
async def send_sticker_vahui(self, chat_id, reply_to: typing.Optional[int] = None):
m = await self.client.get_messages("@VAHUI_STICKS", ids=random.randint(1, 100))
await self.client.send_message(chat_id, file=m, reply_to=reply_to)
async def open_menu_pon(self, call, chat_id, reply_to: typing.Optional[int] = None):
await call.edit(
text="<b>пон</b>",
reply_markup=[
[
{"text": "пон", "callback": self.send_sticker_pon, "kwargs": {"chat_id": chat_id, "reply_to": reply_to}}
for __ in range(7)
]
for _ in range(3)
],
)
async def open_menu_vahui(self, call):
await call.edit(
text="<b>вахуи</b>",
reply_markup=[
[
{"text": "вахуи", "callback": self.send_sticker_vahui, "kwargs": {"chat_id": chat_id, "reply_to": reply_to}}
for __ in range(7)
]
for _ in range(3)
],
)