Commited backup
129
Den4ikSuperOstryyPer4ik/Astro-modules/.gitignore
vendored
Normal 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/
|
||||
132
Den4ikSuperOstryyPer4ik/Astro-modules/AntiMat.py
Normal 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>")
|
||||
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/Achievements.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/Akinator.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/AntiMat.jpg
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/AstroAFK.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/AstroShazam.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/AstroSteamNow.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/AstroWeather.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/BrawlStats.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/Compliments.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/Demotivator.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/DialogsManager.jpg
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/Emotions.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/GameeCheat.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 9.6 MiB |
|
After Width: | Height: | Size: 74 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/Komaru.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/MindTalk.jpg
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/MineSweeper.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/PCManager.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 76 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/RandomStatuses.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/RandomTrack.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/RandomUser.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/Summer.jpg
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/TwinkManager.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/VideoToVoice.jpg
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/WordlyHelper.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
Den4ikSuperOstryyPer4ik/Astro-modules/Banners/YaMusic.jpg
Normal file
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 75 KiB |
351
Den4ikSuperOstryyPer4ik/Astro-modules/Compliments.py
Normal 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,
|
||||
)
|
||||
182
Den4ikSuperOstryyPer4ik/Astro-modules/Emotions.py
Normal 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}')
|
||||
201
Den4ikSuperOstryyPer4ik/Astro-modules/LICENSE
Normal 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.
|
||||
8
Den4ikSuperOstryyPer4ik/Astro-modules/README.md
Normal 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*
|
||||
198
Den4ikSuperOstryyPer4ik/Astro-modules/RandomPasswordGenerator.py
Normal 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"
|
||||
}
|
||||
],
|
||||
],
|
||||
)
|
||||
311
Den4ikSuperOstryyPer4ik/Astro-modules/RandomStatuses.py
Normal 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"
|
||||
}
|
||||
],
|
||||
],
|
||||
)
|
||||
146
Den4ikSuperOstryyPer4ik/Astro-modules/RandomTrack.py
Normal 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()
|
||||
501
Den4ikSuperOstryyPer4ik/Astro-modules/RandomUser.py
Normal 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)
|
||||
400
Den4ikSuperOstryyPer4ik/Astro-modules/Steam.py
Normal 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))
|
||||
441
Den4ikSuperOstryyPer4ik/Astro-modules/TwinkManager.py
Normal 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)
|
||||
|
||||
345
Den4ikSuperOstryyPer4ik/Astro-modules/TxAFK.py
Normal 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)
|
||||
53
Den4ikSuperOstryyPer4ik/Astro-modules/YandexMusic.py
Normal 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>")
|
||||
290
Den4ikSuperOstryyPer4ik/Astro-modules/YmLive.py
Normal 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}")
|
||||
245
Den4ikSuperOstryyPer4ik/Astro-modules/achievements.py
Normal 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)
|
||||
237
Den4ikSuperOstryyPer4ik/Astro-modules/akinator.py
Normal 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
|
||||
)
|
||||
714
Den4ikSuperOstryyPer4ik/Astro-modules/astroafk.py
Normal 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)
|
||||
162
Den4ikSuperOstryyPer4ik/Astro-modules/astroweather.py
Normal 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"))
|
||||
246
Den4ikSuperOstryyPer4ik/Astro-modules/brawl_stats.py
Normal 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)
|
||||
135
Den4ikSuperOstryyPer4ik/Astro-modules/commands_logger.py
Normal 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()
|
||||
242
Den4ikSuperOstryyPer4ik/Astro-modules/convertio.py
Normal 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])
|
||||
387
Den4ikSuperOstryyPer4ik/Astro-modules/demotivator.py
Normal 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)
|
||||
224
Den4ikSuperOstryyPer4ik/Astro-modules/dialogs_manager.py
Normal 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>')
|
||||
173
Den4ikSuperOstryyPer4ik/Astro-modules/dl_yt_previews.py
Normal 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"))
|
||||
34
Den4ikSuperOstryyPer4ik/Astro-modules/full.txt
Normal 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
|
||||
114
Den4ikSuperOstryyPer4ik/Astro-modules/gamecheat.py
Normal 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))
|
||||
471
Den4ikSuperOstryyPer4ik/Astro-modules/iOSAppsForAndroid.py
Normal 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"
|
||||
)
|
||||
296
Den4ikSuperOstryyPer4ik/Astro-modules/inline_bot_manager.py
Normal 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)
|
||||
92
Den4ikSuperOstryyPer4ik/Astro-modules/komarumod.py
Normal 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
|
||||
)
|
||||
149
Den4ikSuperOstryyPer4ik/Astro-modules/mindtalk.py
Normal 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'))
|
||||
373
Den4ikSuperOstryyPer4ik/Astro-modules/minesweeper.py
Normal 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)
|
||||
)
|
||||
291
Den4ikSuperOstryyPer4ik/Astro-modules/pcmanager.py
Normal 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...
|
||||
87
Den4ikSuperOstryyPer4ik/Astro-modules/shazam.py
Normal 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'])
|
||||
56
Den4ikSuperOstryyPer4ik/Astro-modules/summer.py
Normal 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>'
|
||||
)
|
||||
)
|
||||
96
Den4ikSuperOstryyPer4ik/Astro-modules/video_to_voice.py
Normal 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()
|
||||
111
Den4ikSuperOstryyPer4ik/Astro-modules/wordly.py
Normal 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)
|
||||
))
|
||||
|
||||
61
Den4ikSuperOstryyPer4ik/Astro-modules/вахуи_пон.py
Normal 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()
|
||||
104
Den4ikSuperOstryyPer4ik/Astro-modules/пон_вахуи.py
Normal 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)
|
||||
],
|
||||
)
|
||||