Author SHA1 Message Date
dize_dev 13238d5139 edit 2023-10-30 18:40:06 +06:00
dize_dev 4c99f4042a Обновление: v0.4 2023-10-30 18:38:30 +06:00
dize_dev 0368bc75eb Обновление: v0.3 2023-10-30 18:37:31 +06:00
dize_dev 4091e409b5 Обновление: v0.3 2023-10-30 18:35:36 +06:00
dize_dev 5beb9d01bc Обновление: v0.3 2023-10-30 18:28:18 +06:00
dize_dev 11c2e8c16e Обновление: v0.3 2023-10-30 18:26:34 +06:00
dize_dev 4c62f4a920 Обновление: v0.3 2023-10-30 18:25:17 +06:00
dize_dev 7cf41c6bc3 Обновление: v0.1 2023-10-30 18:18:55 +06:00
dize_dev 6019f6a287 Обновление: v0.2 2023-10-30 18:16:29 +06:00
dize_dev f96505a675 Обновление: v0.2 2023-10-30 18:05:42 +06:00
dize_dev bf61685d8e Обновление: v0.2 2023-10-30 17:53:33 +06:00
dize_dev b6082e3778 Обновление: v0.2 2023-10-30 17:50:32 +06:00
27 changed files with 124 additions and 619 deletions
-255
View File
@@ -1,255 +0,0 @@
### VisualStudioCode template
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### Python template
# 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/
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/
cover/
# 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
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .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
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__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/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
### PyCharm+all template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
+3
View File
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="ASK" />
<option name="description" value="" />
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (UserVKBot)" project-jdk-type="Python SDK" />
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/UserVKBot.iml" filepath="$PROJECT_DIR$/.idea/UserVKBot.iml" />
</modules>
</component>
</project>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
+9 -12
View File
@@ -1,17 +1,14 @@
import vkbottle from vkbottle.user import UserLabeler, Message, User
from vkbottle.user import Message
import typing TOKEN = 'vk1.a.4nNdLuOJin9tn71J-cKGu6MKCR2rNHkdRPn4lbW28CS9aL0Q-rhG3ZQi6UQnV9ClpBrNp2obRUltWREoSuwz2Km7OXGlBaP3jt9KsEeut4N3OvHWoTUuqNEtiRrgz2koSrPXLEJZ8i974KD2CgXWqmX4IsSC3kCMDK_aS1xetU3S38-Z1JFyNZu5Tl8yUGopptCjEqA9jF8CjznWv1gC2A'
bl = UserLabeler()
user = User(token=TOKEN)
TOKEN = "test"
prefix_bot = "хуй" prefix_bot = "хуй"
prefix_dd = "дд" prefix_dd = "дд"
user: typing.Optional[vkbottle.User] = None
DB_LOGIN = "postgres"
DB_PASSWORD = "MQLDUhDrF3cxj3zszsA63tZoSeSW"
DB_HOST = "51.38.114.136"
DB_NAME = "vk_lp"
async def edit_message( async def edit_message(
message: Message, message: Message,
@@ -26,5 +23,5 @@ async def edit_message(
kwargs.setdefault('dont_parse_links', False) kwargs.setdefault('dont_parse_links', False)
return await user.api.messages.edit( return await user.api.messages.edit(
**kwargs **kwargs
) )
+13 -12
View File
@@ -1,22 +1,23 @@
import json
from vkbottle.dispatch.rules import ABCRule from vkbottle.dispatch.rules import ABCRule
from vkbottle.user import Message from vkbottle.user import Message
import json
def load_trusted_ids():
try:
with open("./user_ids.json", "r") as json_file:
data = json.load(json_file)
return data
except FileNotFoundError:
# Если файл не существует, вернуть пустой список
return []
class Permission(ABCRule[Message]): class Permission(ABCRule[Message]):
def __init__(self): def __init__(self):
self.trusted_ids = load_trusted_ids() self.trusted_ids = self.load_trusted_ids()
def load_trusted_ids(self):
try:
with open("./user_ids.json", "r") as json_file:
data = json.load(json_file)
return data
except FileNotFoundError:
# Если файл не существует, вернуть пустой список
return []
async def check(self, event: Message) -> bool: async def check(self, event: Message) -> bool:
return event.from_id in self.trusted_ids return event.from_id in self.trusted_ids
-1
View File
@@ -1 +0,0 @@
from . import config, models, requests
-7
View File
@@ -1,7 +0,0 @@
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
import config
DB_CONNECT_URL = f"postgresql+asyncpg://{config.DB_LOGIN}:{config.DB_PASSWORD}@{config.DB_HOST}/{config.DB_NAME}"
engine = create_async_engine(DB_CONNECT_URL)
async_session = async_sessionmaker(engine)
-30
View File
@@ -1,30 +0,0 @@
from sqlalchemy import (BigInteger, Column, Identity, Text, JSON, TIMESTAMP)
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass
class UsersTokens(Base):
__tablename__ = "users_tokens"
id = Column("id", BigInteger, Identity(start=1, increment=1, minvalue=1, cycle=False, cache=1), nullable=False,
primary_key=True)
vkid = Column("vkid", BigInteger, nullable=False, unique=True)
token = Column("token", Text, nullable=False)
class UsersProfile(Base):
__tablename__ = "users_profile"
# TODO: think about foreign_id
id = Column("id", BigInteger, Identity(start=1, increment=1, minvalue=1, cycle=False, cache=1), nullable=False,
primary_key=True)
vkid = Column("vkid", BigInteger, nullable=False, unique=True)
achievements = Column("achievements", JSON)
trusted_ids = Column("trusted_ids", JSON)
prefix = Column("prefix", Text)
prefix_d = Column("prefix_d", Text)
prefix_delete = Column("prefix_delete", Text)
last_login = Column("last_login", TIMESTAMP)
-54
View File
@@ -1,54 +0,0 @@
from typing import Optional
from loguru import logger
from sqlalchemy import select
import db
async def execute_statement(statement) -> None:
"""
Возвращает результат выполнения statement
:param statement:
:return:
"""
try:
async with db.config.async_session() as session:
await session.execute(statement)
await session.commit()
except Exception as e:
logger.exception(e)
# return None
async def get_user_token(user_id: int) -> Optional[db.models.UsersTokens]:
"""
Возвращает токен пользователя
:param user_id: VKID
"""
try:
async with db.config.async_session() as session:
result = await session.execute(select(db.models.UsersTokens).where(db.models.UsersTokens.vkid == user_id))
return result.scalars().one_or_none()
except Exception as e:
logger.exception(e)
return None
async def get_user_profile(user_id: int) -> Optional[db.models.UsersProfile]:
"""
Получает профиль пользователя
:param user_id: VKID
"""
try:
async with db.config.async_session() as session:
result = await session.execute(select(db.models.UsersProfile).where(db.models.UsersProfile.vkid == user_id))
return result.scalars().one_or_none()
except Exception as e:
logger.exception(e)
return None
+5 -26
View File
@@ -1,33 +1,12 @@
import asyncio
import sys import sys
from config import user
from routes import labelers
from loguru import logger from loguru import logger
from vkbottle.user import User
import config
import db
logger.add(sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO") logger.add(sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO")
for custom_labeler in labelers:
async def main(): user.labeler.load(custom_labeler)
from routes import labelers
# 368658177 - Ildyrym | 304398797 - Alex
user_info = await db.requests.get_user_token(304398797)
if not user_info:
logger.error("user don't have a token in db!")
return
config.user = User(token=user_info.token)
for custom_labeler in labelers:
config.user.labeler.load(custom_labeler)
loop.create_task(config.user.run_polling())
if __name__ == "__main__": if __name__ == "__main__":
loop = asyncio.get_event_loop() user.run_forever()
loop.create_task(main())
loop.run_forever()
-6
View File
@@ -1,6 +0,0 @@
gitpython==3.1.40
loguru==0.7.2
pytz==2023.3.post1
vkbottle==4.3.12
SQLAlchemy~=2.0.22
asyncpg
+2 -2
View File
@@ -1,3 +1,3 @@
from . import game_handler, delete_msg, info_bot, rewards, ping, profile, add_friend, not_command from . import game_handler, deletedmsg, info_bot, rewards
labelers = [game_handler.bl, delete_msg.bl, info_bot.bl, rewards.bl, ping.bl, profile.bl, add_friend.bl, not_command.bl] labelers = [game_handler.bl, deletedmsg.bl, info_bot.bl, rewards.bl]
-56
View File
@@ -1,56 +0,0 @@
from vkbottle import VKAPIError
from vkbottle.user import Message, UserLabeler
from config import edit_message, prefix_bot, user
from custom_rules.permission import Permission
bl = UserLabeler()
@bl.message(Permission(), text=[prefix_bot + " +др"])
async def add_to_friends_cmd(ctx: Message):
if not ctx.reply_message:
await ctx.answer("❗ Ошибка при выполнении, необходимо пересланное сообщение")
return
friend_id = ctx.reply_message.from_id
try:
await user.api.friends.add(user_id=friend_id)
await edit_message(ctx, "✅ Все отлично, запрос отправлен")
except Exception as e:
if VKAPIError[174]:
await edit_message(ctx, "❗ Невозможно добавить в друзья самого себя")
elif VKAPIError[175]:
await edit_message(ctx,
"❗ Невозможно добавить в друзья пользователя, который занес Вас в свой черный список")
elif VKAPIError[176]:
await edit_message(ctx,
"❗ Невозможно добавить в друзья пользователя, который занесен в Ваш черный список")
else:
await edit_message(ctx, f"❗ Невозможно добавить в друзья пользователя: {e.message}")
@bl.message(Permission(), text=[prefix_bot + " -др"])
async def remove_from_friends_cmd(ctx: Message):
if not ctx.reply_message:
await edit_message(ctx, "❗ Ошибка при выполнении, необходимо пересланное сообщение")
return
friend_id = ctx.reply_message.from_id
response = await user.api.friends.delete(user_id=friend_id)
if not response.success:
await edit_message(ctx, "❗ Произошла ошибка при удалении друга")
return
if response.friend_deleted:
await edit_message(ctx, "✅ Друг удален")
elif response.out_request_deleted:
await edit_message(ctx, "✅ Отменена исходящая заявка")
elif response.in_request_deleted:
await edit_message(ctx, "✅ Отклонена входящая заявка")
elif response.suggestion_deleted:
await edit_message(ctx, "✅ Отклонена рекомендация друга")
else:
await edit_message(ctx, "❗ Произошла ошибка")
+20 -24
View File
@@ -1,11 +1,8 @@
import datetime import datetime
from vkbottle.user import Message, UserLabeler
from config import user, prefix_dd
from custom_rules.permission import Permission from custom_rules.permission import Permission
from vkbottle.user import Message
from config import bl, user, prefix_dd, prefix_bot
bl = UserLabeler()
DD_SCRIPT = ( DD_SCRIPT = (
'var i = 0;var msg_ids = [];var count = %d;' 'var i = 0;var msg_ids = [];var count = %d;'
'var items = API.messages.getHistory({"peer_id":%d,"count":"200", "offset":"0"}).items;' 'var items = API.messages.getHistory({"peer_id":%d,"count":"200", "offset":"0"}).items;'
@@ -19,32 +16,31 @@ DD_SCRIPT = (
@bl.message( @bl.message(
Permission(), Permission(),
text=[prefix_dd + " <count:int>"], text=[prefix_dd + " <count:int>"],
) )
async def dd_cmd(ctx: Message, count: int = 2): async def dd_handler(message: Message, count: int = 2):
await user.api.execute( await user.api.execute(
DD_SCRIPT % ( DD_SCRIPT % (
count, count,
ctx.peer_id, message.peer_id,
ctx.from_id, message.from_id,
int(datetime.datetime.now().timestamp()) int(datetime.datetime.now().timestamp())
) )
) )
@bl.message( @bl.message(
Permission(), Permission(),
text=[prefix_dd + " все", prefix_dd + " всё"], text=[prefix_bot + " все"]
) )
async def dd_all_cmd(ctx: Message): async def dd_all_handler(message: Message):
count = 1000 count = 1000
await user.api.execute( await user.api.execute(
DD_SCRIPT % ( DD_SCRIPT % (
count, count,
ctx.peer_id, message.peer_id,
ctx.from_id, message.from_id,
int(datetime.datetime.now().timestamp()) int(datetime.datetime.now().timestamp())
) )
) )
+6 -10
View File
@@ -1,18 +1,14 @@
import asyncio import asyncio
from vkbottle.user import Message
from vkbottle.user import Message, UserLabeler from config import bl, prefix_bot, edit_message
from config import prefix_bot, edit_message
from custom_rules.permission import Permission from custom_rules.permission import Permission
bl = UserLabeler()
@bl.message( @bl.message(
Permission(), Permission(),
text=[prefix_bot + " игра"], text=[prefix_bot + " игра"],
) )
async def game_cmd(ctx: Message): async def game(message: Message):
loader = ( loader = (
'⬜⬜⬜⬜⬜⬜⬜⬜⬛⬛⬜⬜⬜⬜⬜⬜⬜', '⬜⬜⬜⬜⬜⬜⬜⬜⬛⬛⬜⬜⬜⬜⬜⬜⬜',
""" """
@@ -85,5 +81,5 @@ async def game_cmd(ctx: Message):
) )
for new_text in loader: for new_text in loader:
await edit_message(ctx, new_text) await edit_message(message, new_text)
await asyncio.sleep(1) await asyncio.sleep(1)
+7 -15
View File
@@ -1,19 +1,11 @@
import git
import pytz
from vkbottle.user import Message, UserLabeler
from config import edit_message, prefix_bot
from custom_rules.permission import Permission from custom_rules.permission import Permission
from vkbottle.user import Message
bl = UserLabeler() from config import bl, edit_message, prefix_bot
from utils import rewards_list
@bl.message(Permission(), text=[prefix_bot + " бот"]) @bl.message(Permission(), text=[prefix_bot + " бот"])
async def about_cmd(ctx: Message): async def about(message: Message):
repo = git.Repo(search_parent_directories=True) await edit_message(message,
version = repo.head.object.hexsha[:7] "Информация о боте 🤖:\n\n Название бота 🤖: dize_lp\n Версия бота ⚙️: v0.1\n Создатель бота 👨‍🦱: @dize_dev(Илдырым Денница)\n Достижения🏆: " +
version_date = repo.head.object.committed_datetime.astimezone(pytz.timezone("Europe/Moscow")) rewards_list[1])
# TODO: use Pillow to create img in real-time
await edit_message(ctx, attachment="photo-202995525_457239051")
-11
View File
@@ -1,11 +0,0 @@
from vkbottle.user import Message, UserLabeler
from config import edit_message, prefix_bot
from custom_rules.permission import Permission
bl = UserLabeler()
@bl.message(Permission(), text=prefix_bot + " <command>")
async def wrapper(message: Message, command):
await edit_message(message, "Такой команды не существует")
-15
View File
@@ -1,15 +0,0 @@
from vkbottle.user import Message, UserLabeler
import utils
from config import edit_message, prefix_bot
from custom_rules.permission import Permission
bl = UserLabeler()
@bl.message(Permission(), text=[prefix_bot + " пинг"])
async def ping_cmd(ctx: Message):
await edit_message(
ctx,
await utils.ping(ctx, "ПОНГ")
)
-28
View File
@@ -1,28 +0,0 @@
import git
from vkbottle.user import Message, UserLabeler
import db.requests
from config import edit_message, prefix_bot, prefix_dd
from custom_rules.permission import Permission
bl = UserLabeler()
@bl.message(Permission(), text=[prefix_bot + " профиль"])
async def get_profile_cmd(ctx: Message):
repo = git.Repo(search_parent_directories=True)
version = repo.head.object.hexsha[:7]
info = await db.requests.get_user_profile(user_id=ctx.from_id)
await edit_message(ctx,
f"[ Impulse LP ]\n"
f"Текущая версия: {version}\n"
f"Основной префикс: {info.prefix}\n"
f"Префикс дд: {info.prefix_delete}\n"
f"{info.prefix_d}\n"
f"\nДостижения\n"
f"{info.achievements}\n"
f"Последний вход на сайт: {info.last_login}\n"
f"Довы:\n"
f"{info.trusted_ids}"
)
+8 -31
View File
@@ -1,36 +1,13 @@
from vkbottle.user import Message, UserLabeler
import db
import utils
from config import edit_message, prefix_bot
from custom_rules.permission import Permission from custom_rules.permission import Permission
from vkbottle.user import Message
from config import bl, edit_message, prefix_bot
from utils import rewards_list
bl = UserLabeler()
listToStr = ' '.join(map(str, rewards_list))
@bl.message(Permission(), text=[prefix_bot + " достижения"]) @bl.message(Permission(), text=[prefix_bot + " достижения"])
async def rewards_cmd(ctx: Message): async def rewards(message: Message):
text = "Список всех достижений:\n\n" await edit_message(message,
have_ = "" "Вот список всех достижений🏆: \n " + listToStr)
dont_have = ""
info = await db.requests.get_user_profile(user_id=ctx.from_id)
# TODO: CHECK BEFORE DEPLOY!!
# TODO: create table in db
# TODO: fill items in models.py
for item in info.achievements:
if item in utils.rewards.keys():
have_ += f"{utils.rewards[item]}\n"
else:
dont_have += f"{utils.rewards[item]}\n"
if have_ != "":
text += "Открытые:\n"
text += have_
if dont_have != "":
text += "Неоткрытые:\n"
text += dont_have
await edit_message(ctx, text)
+8 -24
View File
@@ -1,24 +1,8 @@
import time rewards_list = [
"Первооткрыватель 🎓\n",
from vkbottle.user import Message "Создатель ⭐\n",
"Администратор 👨🏻‍💼\n",
rewards = { "Модератоор 🛡️\n",
"discoverer": "Первооткрыватель", "Иследователь 🔎\n",
"creator": "Создатель", "Спонсор 💸\n",
"admin": "Администратор", ]
"moderator": "Moderator",
"researcher": "Исследователь",
"sponsor": "Спонсор"
}
next_line_symbol = "\n"
async def ping(message: Message, answer: str) -> str:
delta = round(time.time() - message.date, 2)
if delta < 0:
delta = "666"
return f"{answer} Модуль Impulse LP\n" \
f"Ответ через {delta} с"
+2
View File
@@ -0,0 +1,2 @@
# created by virtualenv automatically
*