mirror of
https://gitflic.ru/project/alt-gnome/karkas.git
synced 2025-01-11 17:28:13 +03:00
Merged with chore/small-fixes-KarkasLite
This commit is contained in:
commit
da2a5c21c1
2
.flake8
2
.flake8
@ -4,3 +4,5 @@ per-file-ignores =
|
|||||||
max-line-length = 88
|
max-line-length = 88
|
||||||
count = true
|
count = true
|
||||||
extend-ignore = E203,E701
|
extend-ignore = E203,E701
|
||||||
|
|
||||||
|
extend-select = TC010,TC200
|
||||||
|
@ -29,6 +29,8 @@ repos:
|
|||||||
rev: 7.1.0 # sync:flake8:poetry.lock
|
rev: 7.1.0 # sync:flake8:poetry.lock
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
|
additional_dependencies:
|
||||||
|
- flake8-type-checking
|
||||||
- repo: https://github.com/PyCQA/bandit
|
- repo: https://github.com/PyCQA/bandit
|
||||||
rev: 1.7.9 # sync:bandit:poetry.lock
|
rev: 1.7.9 # sync:bandit:poetry.lock
|
||||||
hooks:
|
hooks:
|
||||||
|
@ -12,10 +12,6 @@
|
|||||||
"name": "Karkas Core",
|
"name": "Karkas Core",
|
||||||
"path": "src/karkas_core"
|
"path": "src/karkas_core"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Gnomik",
|
|
||||||
"path": "src/gnomik"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "ALT Linux",
|
"name": "ALT Linux",
|
||||||
"path": "src/altlinux"
|
"path": "src/altlinux"
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
## Описание
|
## Описание
|
||||||
|
|
||||||
Подготовленная версия Karkas Lite для интеграции в чат [Альт Линукс](https://t.me/alt_linux)
|
Подготовленная версия Karkas для интеграции в чат [Альт Линукс](https://t.me/alt_linux)
|
||||||
|
|
||||||
## Функционал
|
## Функционал
|
||||||
Список OCAB-модулей используемых в боте:
|
Список OCAB-модулей используемых в боте:
|
||||||
|
|
||||||
* report - Вызов администрации чата одной командой
|
* report - Вызов администрации чата одной командой
|
||||||
* welcome - Автоматическая вариативная проверка пользователей на признаки бота или другой автоматической рекламной системы
|
* welcome - Автоматическая вариативная проверка пользователей на признаки бота или другой автоматической рекламной системы
|
||||||
* help - Получение информации об Karkas Lite
|
* help - Получение справки о боте
|
||||||
|
|
||||||
## Запуск
|
## Запуск
|
||||||
|
|
||||||
@ -17,29 +17,31 @@
|
|||||||
|
|
||||||
1. Соберите Docker-образ:
|
1. Соберите Docker-образ:
|
||||||
```bash
|
```bash
|
||||||
docker build -t gnomik .
|
docker build -t altlinux -f Dockerfile ../..
|
||||||
```
|
```
|
||||||
2. Запустите контейнер:
|
2. Запустите контейнер:
|
||||||
```bash
|
```bash
|
||||||
docker run -p 9000:9000 -v ./config.yaml:/app/config.yaml -v ./database:/app/database gnomik
|
docker run -v ./config.yaml:/app/config.yaml altlinux
|
||||||
```
|
```
|
||||||
|
|
||||||
Замените `./config.yaml` и `./database` на пути к вашим локальным файлам конфигурации и паки для базы данных.
|
Замените `./config.yaml` на путь к вашему локальному файлу конфигурации.
|
||||||
|
|
||||||
### Вручную
|
### Вручную
|
||||||
|
|
||||||
1. Активируйте виртуальное окружение Gnomика:
|
1. Активируйте виртуальное окружение:
|
||||||
```bash
|
```bash
|
||||||
poetry shell
|
poetry shell
|
||||||
```
|
```
|
||||||
2. Запустите бота:
|
2. Запустите бота:
|
||||||
```bash
|
```bash
|
||||||
python -m gnomik
|
python -m altlinux
|
||||||
```
|
```
|
||||||
|
|
||||||
## Конфигурация
|
## Конфигурация
|
||||||
|
|
||||||
Конфигурация бота находится в файле `config.yaml`.
|
Конфигурация хранится в файле `config.yaml`.
|
||||||
|
|
||||||
|
Пример конфигурации бота находится в файле `config-example.yaml`.
|
||||||
|
|
||||||
## Модули
|
## Модули
|
||||||
|
|
||||||
|
@ -2,6 +2,45 @@ core:
|
|||||||
mode: LONG_POLLING
|
mode: LONG_POLLING
|
||||||
token: xxx
|
token: xxx
|
||||||
|
|
||||||
filters:
|
#
|
||||||
approved_chat_id:
|
# filters:
|
||||||
- -111111
|
# approved_chat_id:
|
||||||
|
# - -100000000000
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# welcome:
|
||||||
|
# show_success_message: True
|
||||||
|
# max_attempts: 5
|
||||||
|
# timeout: 60
|
||||||
|
# tasks:
|
||||||
|
# math_buttons:
|
||||||
|
# enabled: False
|
||||||
|
# math_poll:
|
||||||
|
# enabled: True
|
||||||
|
# question_buttons:
|
||||||
|
# enabled: False
|
||||||
|
# question_poll:
|
||||||
|
# enabled: False
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# report:
|
||||||
|
# errors:
|
||||||
|
# no_reply_message: "Пожалуйста, используйте команду в ответ на сообщение"
|
||||||
|
# mention:
|
||||||
|
# text: "⚠️ Внимание, жалоба на спам! $mention"
|
||||||
|
# limit: 5
|
||||||
|
# list:
|
||||||
|
# - "@test1"
|
||||||
|
# - "@test2"
|
||||||
|
# - "@test3"
|
||||||
|
# - "@test4"
|
||||||
|
# - "@test5"
|
||||||
|
# - "@test6"
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# help:
|
||||||
|
# message: "$commands"
|
||||||
|
#
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
build:
|
build:
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from .config_manager import ConfigManager
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import dash_bootstrap_components as dbc
|
import dash_bootstrap_components as dbc
|
||||||
import flask
|
import flask
|
||||||
@ -17,8 +15,10 @@ from karkas_core.modules_system.public_api import get_module
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from karkas_blocks.standard.roles import Roles as IRoles
|
from karkas_blocks.standard.roles import Roles as IRoles
|
||||||
|
|
||||||
|
from .config_manager import ConfigManager
|
||||||
|
|
||||||
def create_control(key: str, config: ConfigManager):
|
|
||||||
|
def create_control(key: str, config: "ConfigManager"):
|
||||||
value = config.get(key)
|
value = config.get(key)
|
||||||
meta = config.get_meta(key)
|
meta = config.get_meta(key)
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ def create_control(key: str, config: ConfigManager):
|
|||||||
return dbc.Row(row, className="mb-3 mx-1")
|
return dbc.Row(row, className="mb-3 mx-1")
|
||||||
|
|
||||||
|
|
||||||
def build_settings_tree(config: ConfigManager):
|
def build_settings_tree(config: "ConfigManager"):
|
||||||
tree = {}
|
tree = {}
|
||||||
|
|
||||||
for key, value in config._metadata.items():
|
for key, value in config._metadata.items():
|
||||||
@ -134,7 +134,7 @@ def create_settings_components(tree, level=0):
|
|||||||
return components
|
return components
|
||||||
|
|
||||||
|
|
||||||
def get_miniapp_blueprint(config: ConfigManager, prefix: str):
|
def get_miniapp_blueprint(config: "ConfigManager", prefix: str):
|
||||||
Roles: "type[IRoles]" = get_module("standard.roles", "Roles")
|
Roles: "type[IRoles]" = get_module("standard.roles", "Roles")
|
||||||
|
|
||||||
roles = Roles()
|
roles = Roles()
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from aiogram import Bot
|
|
||||||
from aiogram.filters import BaseFilter
|
from aiogram.filters import BaseFilter
|
||||||
from aiogram.types import Message
|
|
||||||
from typing_extensions import deprecated
|
from typing_extensions import deprecated
|
||||||
|
|
||||||
from karkas_core.modules_system.public_api import get_module
|
from karkas_core.modules_system.public_api import get_module
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from aiogram import Bot
|
||||||
|
from aiogram.types import Message
|
||||||
|
|
||||||
from karkas_blocks.standard.config import IConfig
|
from karkas_blocks.standard.config import IConfig
|
||||||
from karkas_blocks.standard.roles import Roles as IRoles
|
from karkas_blocks.standard.roles import Roles as IRoles
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ def get_approved_chat_id() -> list:
|
|||||||
|
|
||||||
|
|
||||||
@deprecated("Use ChatIDFilter or own implementation")
|
@deprecated("Use ChatIDFilter or own implementation")
|
||||||
def chat_not_in_approve(message: Message) -> bool:
|
def chat_not_in_approve(message: "Message") -> bool:
|
||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
if chat_id in get_approved_chat_id():
|
if chat_id in get_approved_chat_id():
|
||||||
# log(f"Chat in approve list: {chat_id}")
|
# log(f"Chat in approve list: {chat_id}")
|
||||||
@ -50,7 +51,7 @@ class ChatIDFilter(BaseFilter):
|
|||||||
self.approved_chats = approved_chats
|
self.approved_chats = approved_chats
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
async def __call__(self, message: Message, bot: Bot) -> bool:
|
async def __call__(self, message: "Message", bot: "Bot") -> bool:
|
||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
|
|
||||||
approved_chats = self.approved_chats or get_approved_chat_id()
|
approved_chats = self.approved_chats or get_approved_chat_id()
|
||||||
@ -70,7 +71,7 @@ class ChatNotInApproveFilter(ChatIDFilter):
|
|||||||
|
|
||||||
|
|
||||||
class ChatModerOrAdminFilter(BaseFilter):
|
class ChatModerOrAdminFilter(BaseFilter):
|
||||||
async def __call__(self, message: Message, bot: Bot) -> bool:
|
async def __call__(self, message: "Message", bot: "Bot") -> bool:
|
||||||
if not ROLES_MODULE_LOADED:
|
if not ROLES_MODULE_LOADED:
|
||||||
raise Exception("Roles module not loaded")
|
raise Exception("Roles module not loaded")
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
from aiogram import Router
|
from aiogram import Router
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
from aiogram.types import Message
|
|
||||||
|
|
||||||
from karkas_core.modules_system.public_api import (
|
from karkas_core.modules_system.public_api import (
|
||||||
get_metainfo,
|
get_metainfo,
|
||||||
@ -12,6 +11,8 @@ from karkas_core.modules_system.public_api import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from aiogram.types import Message
|
||||||
|
|
||||||
from karkas_blocks.standard.config import IConfig
|
from karkas_blocks.standard.config import IConfig
|
||||||
|
|
||||||
config: "IConfig" = get_module("standard.config", "config")
|
config: "IConfig" = get_module("standard.config", "config")
|
||||||
@ -46,7 +47,7 @@ def format_commands(commands_dict):
|
|||||||
return "\n".join(formatted_commands)
|
return "\n".join(formatted_commands)
|
||||||
|
|
||||||
|
|
||||||
async def help(message: Message):
|
async def help(message: "Message"):
|
||||||
commands = ""
|
commands = ""
|
||||||
version = ""
|
version = ""
|
||||||
|
|
||||||
|
@ -4,11 +4,13 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
from aiogram import Router
|
from aiogram import Router
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
from aiogram.types import ChatMemberAdministrator, ChatMemberOwner, Message
|
from aiogram.types import ChatMemberOwner
|
||||||
|
|
||||||
from karkas_core.modules_system.public_api import get_module, log, register_router
|
from karkas_core.modules_system.public_api import get_module, log, register_router
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from aiogram.types import ChatMemberAdministrator, Message
|
||||||
|
|
||||||
from karkas_blocks.standard.config import IConfig
|
from karkas_blocks.standard.config import IConfig
|
||||||
from karkas_blocks.standard.filters import ChatIDFilter as IChatIDFilter
|
from karkas_blocks.standard.filters import ChatIDFilter as IChatIDFilter
|
||||||
|
|
||||||
@ -29,7 +31,7 @@ except Exception:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def can_moderate(admin: ChatMemberOwner | ChatMemberAdministrator) -> bool:
|
def can_moderate(admin: "ChatMemberOwner | ChatMemberAdministrator") -> bool:
|
||||||
if isinstance(admin, ChatMemberOwner):
|
if isinstance(admin, ChatMemberOwner):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ def can_moderate(admin: ChatMemberOwner | ChatMemberAdministrator) -> bool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def report(message: Message):
|
async def report(message: "Message"):
|
||||||
try:
|
try:
|
||||||
if message.reply_to_message is None:
|
if message.reply_to_message is None:
|
||||||
await message.reply(config.get("report::errors::no_reply_message"))
|
await message.reply(config.get("report::errors::no_reply_message"))
|
||||||
|
@ -7,7 +7,6 @@ from aiogram import Bot, Router, types
|
|||||||
from aiogram.enums import ChatMemberStatus, ParseMode
|
from aiogram.enums import ChatMemberStatus, ParseMode
|
||||||
from aiogram.exceptions import TelegramBadRequest
|
from aiogram.exceptions import TelegramBadRequest
|
||||||
from aiogram.filters import JOIN_TRANSITION, LEAVE_TRANSITION, ChatMemberUpdatedFilter
|
from aiogram.filters import JOIN_TRANSITION, LEAVE_TRANSITION, ChatMemberUpdatedFilter
|
||||||
from aiogram.types import ChatMemberUpdated, PollAnswer
|
|
||||||
|
|
||||||
from karkas_core.modules_system.public_api import get_module, log, register_router
|
from karkas_core.modules_system.public_api import get_module, log, register_router
|
||||||
|
|
||||||
@ -22,6 +21,8 @@ from .verifications_methods.simple import (
|
|||||||
from .verifications_methods.utils import user_mention
|
from .verifications_methods.utils import user_mention
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from aiogram.types import ChatMemberUpdated, PollAnswer
|
||||||
|
|
||||||
from karkas_blocks.standard.config import IConfig
|
from karkas_blocks.standard.config import IConfig
|
||||||
from karkas_blocks.standard.filters import ChatIDFilter as IChatIDFilter
|
from karkas_blocks.standard.filters import ChatIDFilter as IChatIDFilter
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ verification_tasks = MultiKeyDict()
|
|||||||
last_success = {}
|
last_success = {}
|
||||||
|
|
||||||
|
|
||||||
async def new_member_handler(event: ChatMemberUpdated, bot: Bot):
|
async def new_member_handler(event: "ChatMemberUpdated", bot: Bot):
|
||||||
# НЕ СРАБОТАЕТ, ЕСЛИ ЧЕЛОВЕК УЖЕ ОГРАНИЧЕН В ПРАВАХ (RESTRICTED)
|
# НЕ СРАБОТАЕТ, ЕСЛИ ЧЕЛОВЕК УЖЕ ОГРАНИЧЕН В ПРАВАХ (RESTRICTED)
|
||||||
if event.new_chat_member.status == ChatMemberStatus.MEMBER:
|
if event.new_chat_member.status == ChatMemberStatus.MEMBER:
|
||||||
task = task_manager.build_random_task(event, bot)
|
task = task_manager.build_random_task(event, bot)
|
||||||
@ -87,7 +88,7 @@ async def new_member_handler(event: ChatMemberUpdated, bot: Bot):
|
|||||||
verification_tasks.add(task, keys)
|
verification_tasks.add(task, keys)
|
||||||
|
|
||||||
|
|
||||||
async def left_member_handler(event: ChatMemberUpdated, bot: Bot):
|
async def left_member_handler(event: "ChatMemberUpdated", bot: Bot):
|
||||||
user_id = event.from_user.id
|
user_id = event.from_user.id
|
||||||
chat_id = event.chat.id
|
chat_id = event.chat.id
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ async def success_end(task: BaseTask):
|
|||||||
last_success[task.from_chat_id] = message.message_id
|
last_success[task.from_chat_id] = message.message_id
|
||||||
|
|
||||||
|
|
||||||
async def handle_poll_verification(answer: PollAnswer, bot: Bot):
|
async def handle_poll_verification(answer: "PollAnswer", bot: Bot):
|
||||||
key = key_from_poll(answer.poll_id)
|
key = key_from_poll(answer.poll_id)
|
||||||
if not verification_tasks.exists(key):
|
if not verification_tasks.exists(key):
|
||||||
return
|
return
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from aiogram import Bot
|
|
||||||
from aiogram.exceptions import TelegramBadRequest
|
from aiogram.exceptions import TelegramBadRequest
|
||||||
from aiogram.filters.callback_data import CallbackData
|
from aiogram.filters.callback_data import CallbackData
|
||||||
from aiogram.types import ChatMemberUpdated
|
|
||||||
|
|
||||||
from karkas_core.modules_system.public_api import log
|
from karkas_core.modules_system.public_api import log
|
||||||
|
|
||||||
from .utils import mute_user, unmute_user
|
from .utils import mute_user, unmute_user
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from aiogram import Bot
|
||||||
|
from aiogram.types import ChatMemberUpdated
|
||||||
|
|
||||||
|
|
||||||
class BaseTask:
|
class BaseTask:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
event: ChatMemberUpdated,
|
event: "ChatMemberUpdated",
|
||||||
bot: Bot,
|
bot: "Bot",
|
||||||
timeout_func=None,
|
timeout_func=None,
|
||||||
attempt_number=1,
|
attempt_number=1,
|
||||||
max_attempts=1,
|
max_attempts=1,
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
from string import Template
|
from string import Template
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from aiogram import Bot
|
|
||||||
from aiogram.enums import ParseMode, PollType
|
from aiogram.enums import ParseMode, PollType
|
||||||
from aiogram.types import ChatMemberUpdated, InlineKeyboardButton, InlineKeyboardMarkup
|
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||||
|
|
||||||
from ..utils import get_plural_form, key_from_poll, key_from_user_chat
|
from ..utils import get_plural_form, key_from_poll, key_from_user_chat
|
||||||
from .base import BaseTask, VerificationCallback, mute_while_task
|
from .base import BaseTask, VerificationCallback, mute_while_task
|
||||||
from .utils import user_mention
|
from .utils import user_mention
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from aiogram import Bot
|
||||||
|
from aiogram.types import ChatMemberUpdated
|
||||||
|
|
||||||
|
|
||||||
class SimpleBaseTask(BaseTask):
|
class SimpleBaseTask(BaseTask):
|
||||||
pass
|
pass
|
||||||
@ -119,8 +123,8 @@ class SimpleInlineButtonsTask(SimpleVariantsBaseTask):
|
|||||||
class SimplePollTask(SimpleVariantsBaseTask):
|
class SimplePollTask(SimpleVariantsBaseTask):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
event: ChatMemberUpdated,
|
event: "ChatMemberUpdated",
|
||||||
bot: Bot,
|
bot: "Bot",
|
||||||
timeout_func=None,
|
timeout_func=None,
|
||||||
attempt_number=1,
|
attempt_number=1,
|
||||||
max_attempts=1,
|
max_attempts=1,
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import time
|
import time
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from aiogram import Bot
|
|
||||||
from aiogram.enums import ParseMode
|
from aiogram.enums import ParseMode
|
||||||
from aiogram.types import ChatPermissions, User
|
from aiogram.types import ChatPermissions, User
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from aiogram import Bot
|
||||||
|
|
||||||
|
|
||||||
def user_mention(user: User, mode=ParseMode.HTML):
|
def user_mention(user: User, mode=ParseMode.HTML):
|
||||||
if mode == ParseMode.HTML:
|
if mode == ParseMode.HTML:
|
||||||
@ -14,7 +17,7 @@ def user_mention(user: User, mode=ParseMode.HTML):
|
|||||||
raise ValueError(f"Unknown parse mode {mode}")
|
raise ValueError(f"Unknown parse mode {mode}")
|
||||||
|
|
||||||
|
|
||||||
async def mute_user(chat_id, user_id, until, bot: Bot):
|
async def mute_user(chat_id, user_id, until, bot: "Bot"):
|
||||||
end_time = until + int(time.time())
|
end_time = until + int(time.time())
|
||||||
await bot.restrict_chat_member(
|
await bot.restrict_chat_member(
|
||||||
chat_id,
|
chat_id,
|
||||||
@ -40,7 +43,7 @@ async def mute_user(chat_id, user_id, until, bot: Bot):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def unmute_user(chat_id, user_id, bot: Bot):
|
async def unmute_user(chat_id, user_id, bot: "Bot"):
|
||||||
await bot.restrict_chat_member(
|
await bot.restrict_chat_member(
|
||||||
chat_id,
|
chat_id,
|
||||||
user_id,
|
user_id,
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from aiogram import Bot, Dispatcher
|
|
||||||
from aiogram.types import Update
|
from aiogram.types import Update
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from aiogram import Bot, Dispatcher
|
||||||
|
from fastapi import FastAPI, Request
|
||||||
|
|
||||||
|
|
||||||
def get_module_directory(module_name):
|
def get_module_directory(module_name):
|
||||||
spec = importlib.util.find_spec(module_name)
|
spec = importlib.util.find_spec(module_name)
|
||||||
@ -16,15 +20,10 @@ def get_module_directory(module_name):
|
|||||||
return os.path.dirname(module_path)
|
return os.path.dirname(module_path)
|
||||||
|
|
||||||
|
|
||||||
|
async def register_bot_webhook(app: "FastAPI", bot: "Bot", dp: "Dispatcher"):
|
||||||
|
async def handle_webhook(request: "Request"):
|
||||||
try:
|
try:
|
||||||
from fastapi import FastAPI, Request
|
update = Update.model_validate(await request.json(), context={"bot": bot})
|
||||||
|
|
||||||
async def register_bot_webhook(app: FastAPI, bot: Bot, dp: Dispatcher):
|
|
||||||
async def handle_webhook(request: Request):
|
|
||||||
try:
|
|
||||||
update = Update.model_validate(
|
|
||||||
await request.json(), context={"bot": bot}
|
|
||||||
)
|
|
||||||
await dp.feed_update(bot, update)
|
await dp.feed_update(bot, update)
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@ -33,6 +32,3 @@ try:
|
|||||||
return {"ok": True}
|
return {"ok": True}
|
||||||
|
|
||||||
app.post("/webhook")(handle_webhook)
|
app.post("/webhook")(handle_webhook)
|
||||||
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
@ -84,7 +84,7 @@ class Karkas:
|
|||||||
await register_bot_webhook(app, singleton.bot, singleton.dp)
|
await register_bot_webhook(app, singleton.bot, singleton.dp)
|
||||||
await singleton.bot.set_webhook(config.get("core::webhook::public_url"))
|
await singleton.bot.set_webhook(config.get("core::webhook::public_url"))
|
||||||
hyperConfig = HyperConfig()
|
hyperConfig = HyperConfig()
|
||||||
hyperConfig.bind = [f"0.0.0.0:{config.get("core::webhook::port")}"]
|
hyperConfig.bind = [f"0.0.0.0:{config.get('core::webhook::port')}"]
|
||||||
hyperConfig.logger_class = CustomLogger
|
hyperConfig.logger_class = CustomLogger
|
||||||
await serve(app, hyperConfig)
|
await serve(app, hyperConfig)
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import types
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Dict, List, Optional, Union
|
from typing import TYPE_CHECKING, Dict, List, Optional, Union
|
||||||
|
|
||||||
from dataclasses_json import dataclass_json
|
from dataclasses_json import dataclass_json
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
import types
|
||||||
|
|
||||||
|
|
||||||
@dataclass_json
|
@dataclass_json
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -39,5 +41,5 @@ class AbstractLoader:
|
|||||||
def info(self) -> ModuleInfo:
|
def info(self) -> ModuleInfo:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def load(self) -> types.ModuleType:
|
def load(self) -> "types.ModuleType":
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import types
|
import types
|
||||||
from typing import Any, Tuple, Union
|
from typing import TYPE_CHECKING, Any, Tuple, Union
|
||||||
|
|
||||||
from aiogram import BaseMiddleware, Router
|
|
||||||
from aiogram.fsm.context import FSMContext
|
from aiogram.fsm.context import FSMContext
|
||||||
from aiogram.fsm.storage.base import StorageKey
|
from aiogram.fsm.storage.base import StorageKey
|
||||||
|
|
||||||
@ -10,18 +9,21 @@ from aiogram.fsm.storage.base import StorageKey
|
|||||||
from karkas_core.modules_system.loaders.base import DependencyInfo
|
from karkas_core.modules_system.loaders.base import DependencyInfo
|
||||||
from karkas_core.singleton import Singleton
|
from karkas_core.singleton import Singleton
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from aiogram import BaseMiddleware, Router
|
||||||
|
|
||||||
|
|
||||||
async def set_chat_menu_button(menu_button):
|
async def set_chat_menu_button(menu_button):
|
||||||
app = Singleton()
|
app = Singleton()
|
||||||
await app.bot.set_chat_menu_button(menu_button=menu_button)
|
await app.bot.set_chat_menu_button(menu_button=menu_button)
|
||||||
|
|
||||||
|
|
||||||
def register_router(router: Router):
|
def register_router(router: "Router"):
|
||||||
app = Singleton()
|
app = Singleton()
|
||||||
app.storage["_routers"].append(router)
|
app.storage["_routers"].append(router)
|
||||||
|
|
||||||
|
|
||||||
def register_outer_message_middleware(middleware: BaseMiddleware):
|
def register_outer_message_middleware(middleware: "BaseMiddleware"):
|
||||||
app = Singleton()
|
app = Singleton()
|
||||||
app.storage["_outer_message_middlewares"].append(middleware)
|
app.storage["_outer_message_middlewares"].append(middleware)
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import types
|
import types
|
||||||
from _ast import AnnAssign
|
from typing import TYPE_CHECKING, Any
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from aiogram import Bot
|
from aiogram import Bot
|
||||||
from RestrictedPython import (
|
from RestrictedPython import (
|
||||||
@ -20,6 +19,9 @@ from RestrictedPython.Guards import ( # guarded_setattr,; full_write_guard,
|
|||||||
from karkas_core.logger import log
|
from karkas_core.logger import log
|
||||||
from karkas_core.modules_system.safe.zope_guards import extra_safe_builtins
|
from karkas_core.modules_system.safe.zope_guards import extra_safe_builtins
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from _ast import AnnAssign
|
||||||
|
|
||||||
|
|
||||||
class RestrictedPythonPolicy(RestrictingNodeTransformer):
|
class RestrictedPythonPolicy(RestrictingNodeTransformer):
|
||||||
def visit_AsyncFunctionDef(self, node):
|
def visit_AsyncFunctionDef(self, node):
|
||||||
@ -50,7 +52,7 @@ class RestrictedPythonPolicy(RestrictingNodeTransformer):
|
|||||||
return self.node_contents_visit(node)
|
return self.node_contents_visit(node)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def visit_AnnAssign(self, node: AnnAssign) -> Any:
|
def visit_AnnAssign(self, node: "AnnAssign") -> Any:
|
||||||
# missing in RestrictingNodeTransformer
|
# missing in RestrictingNodeTransformer
|
||||||
# this doesn't need the logic that is in visit_Assign
|
# this doesn't need the logic that is in visit_Assign
|
||||||
# because it doesn't have a "targets" attribute,
|
# because it doesn't have a "targets" attribute,
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
from aiogram import Bot, Dispatcher
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from aiogram.fsm.storage.memory import MemoryStorage
|
from aiogram.fsm.storage.memory import MemoryStorage
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from aiogram import Bot, Dispatcher
|
||||||
|
|
||||||
from karkas_core.modules_system import ModulesManager
|
from karkas_core.modules_system import ModulesManager
|
||||||
|
|
||||||
|
|
||||||
@ -15,9 +19,9 @@ class SingletonMeta(type):
|
|||||||
|
|
||||||
|
|
||||||
class Singleton(metaclass=SingletonMeta):
|
class Singleton(metaclass=SingletonMeta):
|
||||||
bot: Bot
|
bot: "Bot"
|
||||||
dp: Dispatcher = None
|
dp: "Dispatcher" = None
|
||||||
modules_manager: ModulesManager = None
|
modules_manager: "ModulesManager" = None
|
||||||
storage = {
|
storage = {
|
||||||
"_fsm_storage": MemoryStorage(),
|
"_fsm_storage": MemoryStorage(),
|
||||||
"_routers": [],
|
"_routers": [],
|
||||||
|
Loading…
Reference in New Issue
Block a user