mirror of
https://gitflic.ru/project/maks1ms/ocab.git
synced 2025-03-13 22:03:50 +03:00
wip
This commit is contained in:
parent
f9f6eaad0d
commit
3295d4acec
4
.gitignore
vendored
4
.gitignore
vendored
@ -7,5 +7,5 @@ venv
|
|||||||
__pycache__
|
__pycache__
|
||||||
OCAB.db
|
OCAB.db
|
||||||
src/paths.json
|
src/paths.json
|
||||||
src/core/config.yaml
|
src/ocab_core/config.yaml
|
||||||
src/core/log/**/*
|
src/ocab_core/log/**/*
|
||||||
|
3
docs/MODULES-SPEC.md
Normal file
3
docs/MODULES-SPEC.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Спецификация модулей
|
||||||
|
|
||||||
|
Каждый модуль - это Py
|
@ -4,9 +4,9 @@ from pathlib import Path
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
pwd = Path().cwd()
|
pwd = Path().cwd()
|
||||||
dir_core = pwd / "src" / "core"
|
dir_core = pwd / "src" / "ocab_core"
|
||||||
dir_modules_standard = pwd / "src" / "modules" / "standard"
|
dir_modules_standard = pwd / "src" / "ocab_modules" / "standard"
|
||||||
dir_modules_custom = pwd / "src" / "modules" / "custom"
|
dir_modules_custom = pwd / "src" / "ocab_modules" / "custom"
|
||||||
|
|
||||||
json = {
|
json = {
|
||||||
"core": str(dir_core),
|
"core": str(dir_core),
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
import src.core
|
import ocab_core
|
||||||
import src.service
|
import service
|
||||||
|
@ -1 +0,0 @@
|
|||||||
from .public_api import get_module, register_router
|
|
@ -1,13 +0,0 @@
|
|||||||
from aiogram import Router
|
|
||||||
|
|
||||||
from src.core.singleton import Singleton
|
|
||||||
|
|
||||||
|
|
||||||
def register_router(router: Router):
|
|
||||||
app = Singleton()
|
|
||||||
app.dp.include_router(router)
|
|
||||||
|
|
||||||
|
|
||||||
def get_module(module_id: str):
|
|
||||||
app = Singleton()
|
|
||||||
return app.modules_manager.get_by_id(module_id)
|
|
@ -1 +0,0 @@
|
|||||||
from . import db_api, models
|
|
@ -1,12 +0,0 @@
|
|||||||
from aiogram import F, Router
|
|
||||||
|
|
||||||
from src.core.modules_system.public_api import register_router
|
|
||||||
|
|
||||||
from .handlers import get_chat_info, get_user_info
|
|
||||||
|
|
||||||
router = Router()
|
|
||||||
|
|
||||||
router.message.register(get_user_info, F.text.startswith("/info"))
|
|
||||||
router.message.register(get_chat_info, F.text.startswith("/chatinfo"))
|
|
||||||
|
|
||||||
register_router(router)
|
|
@ -1,20 +0,0 @@
|
|||||||
class IRoles:
|
|
||||||
user: str
|
|
||||||
moderator: str
|
|
||||||
admin: str
|
|
||||||
bot: str
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def check_admin_permission(self, user_id: int) -> bool:
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def check_moderator_permission(self, user_id) -> bool:
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def get_role_name(self, role_id) -> str:
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def get_user_permission(self, user_id) -> str | None:
|
|
||||||
pass
|
|
@ -3,14 +3,13 @@ import traceback
|
|||||||
|
|
||||||
from aiogram import Bot, Dispatcher
|
from aiogram import Bot, Dispatcher
|
||||||
|
|
||||||
from src.core.logger import setup_logger
|
from ocab_core.logger import setup_logger
|
||||||
from src.core.modules_system import ModulesManager
|
from ocab_core.modules_system import ModulesManager
|
||||||
from src.core.modules_system.loaders import FSLoader
|
from ocab_core.modules_system.loaders import FSLoader
|
||||||
from src.core.modules_system.loaders.unsafe_fs_loader import UnsafeFSLoader
|
from ocab_core.modules_system.loaders.unsafe_fs_loader import UnsafeFSLoader
|
||||||
from src.core.singleton import Singleton
|
from ocab_core.singleton import Singleton
|
||||||
from src.modules.standard.config.config import get_telegram_token
|
from ocab_modules.standard.config.config import get_telegram_token
|
||||||
from src.modules.standard.database.db_api import connect_database, create_tables
|
from service import paths
|
||||||
from src.service import paths
|
|
||||||
|
|
||||||
bot_modules = [
|
bot_modules = [
|
||||||
UnsafeFSLoader(f"{paths.modules_standard}/config"),
|
UnsafeFSLoader(f"{paths.modules_standard}/config"),
|
||||||
@ -29,9 +28,6 @@ async def main():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
bot = Bot(token=get_telegram_token())
|
bot = Bot(token=get_telegram_token())
|
||||||
database, path = connect_database()
|
|
||||||
database.connect()
|
|
||||||
create_tables(database)
|
|
||||||
|
|
||||||
app.dp = Dispatcher()
|
app.dp = Dispatcher()
|
||||||
app.modules_manager = ModulesManager()
|
app.modules_manager = ModulesManager()
|
@ -3,12 +3,12 @@ from pathlib import Path
|
|||||||
|
|
||||||
from RestrictedPython import compile_restricted_exec
|
from RestrictedPython import compile_restricted_exec
|
||||||
|
|
||||||
from src.core.modules_system.loaders.fs_loader.policy import (
|
from ocab_core.modules_system.loaders.fs_loader.policy import (
|
||||||
ALLOWED_IMPORTS,
|
ALLOWED_IMPORTS,
|
||||||
BUILTINS,
|
BUILTINS,
|
||||||
RestrictedPythonPolicy,
|
RestrictedPythonPolicy,
|
||||||
)
|
)
|
||||||
from src.core.modules_system.loaders.unsafe_fs_loader import UnsafeFSLoader
|
from ocab_core.modules_system.loaders.unsafe_fs_loader import UnsafeFSLoader
|
||||||
|
|
||||||
|
|
||||||
class FSLoader(UnsafeFSLoader):
|
class FSLoader(UnsafeFSLoader):
|
||||||
@ -48,11 +48,12 @@ class FSLoader(UnsafeFSLoader):
|
|||||||
return file_path
|
return file_path
|
||||||
|
|
||||||
def _hook_import(self, name: str, *args, **kwargs):
|
def _hook_import(self, name: str, *args, **kwargs):
|
||||||
if name in ALLOWED_IMPORTS:
|
for allowed in ALLOWED_IMPORTS:
|
||||||
return ALLOWED_IMPORTS[name]
|
if name == allowed or name.startswith(f"{allowed}."):
|
||||||
|
return __import__(name, *args, **kwargs)
|
||||||
|
|
||||||
# TODO: allow only public api for modules
|
# TODO: allow only public api for modules
|
||||||
if name.startswith("src."):
|
if name.startswith("ocab_core."):
|
||||||
return __import__(name, *args, **kwargs)
|
return __import__(name, *args, **kwargs)
|
||||||
|
|
||||||
module_file_path = self._resolve_module_from_path(name)
|
module_file_path = self._resolve_module_from_path(name)
|
@ -1,9 +1,6 @@
|
|||||||
import typing
|
|
||||||
import warnings
|
|
||||||
from _ast import AnnAssign
|
from _ast import AnnAssign
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import aiogram
|
|
||||||
from RestrictedPython import (
|
from RestrictedPython import (
|
||||||
RestrictingNodeTransformer,
|
RestrictingNodeTransformer,
|
||||||
limited_builtins,
|
limited_builtins,
|
||||||
@ -11,7 +8,6 @@ from RestrictedPython import (
|
|||||||
utility_builtins,
|
utility_builtins,
|
||||||
)
|
)
|
||||||
from RestrictedPython.Eval import default_guarded_getitem
|
from RestrictedPython.Eval import default_guarded_getitem
|
||||||
from RestrictedPython.Guards import full_write_guard
|
|
||||||
|
|
||||||
|
|
||||||
class RestrictedPythonPolicy(RestrictingNodeTransformer):
|
class RestrictedPythonPolicy(RestrictingNodeTransformer):
|
||||||
@ -75,18 +71,19 @@ def _metaclass(name, bases, dict):
|
|||||||
return ob
|
return ob
|
||||||
|
|
||||||
|
|
||||||
ALLOWED_IMPORTS = {
|
ALLOWED_IMPORTS = [
|
||||||
"typing": typing,
|
"typing",
|
||||||
"aiogram": aiogram,
|
"aiogram",
|
||||||
"warnings": warnings,
|
"warnings",
|
||||||
}
|
]
|
||||||
|
|
||||||
BUILTINS = safe_builtins.copy()
|
BUILTINS = safe_builtins.copy()
|
||||||
BUILTINS.update(utility_builtins)
|
BUILTINS.update(utility_builtins)
|
||||||
BUILTINS.update(limited_builtins)
|
BUILTINS.update(limited_builtins)
|
||||||
BUILTINS["__metaclass__"] = _metaclass
|
BUILTINS["__metaclass__"] = _metaclass
|
||||||
BUILTINS["_getitem_"] = default_guarded_getitem
|
BUILTINS["_getitem_"] = default_guarded_getitem
|
||||||
BUILTINS["_write_"] = full_write_guard
|
# BUILTINS["_write_"] = full_write_guard
|
||||||
|
BUILTINS["staticmethod"] = staticmethod
|
||||||
|
|
||||||
|
|
||||||
class GuardedDictType:
|
class GuardedDictType:
|
@ -3,7 +3,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from src.core.modules_system.loaders.base import AbstractLoader, ModuleInfo
|
from ocab_core.modules_system.loaders.base import AbstractLoader, ModuleInfo
|
||||||
|
|
||||||
|
|
||||||
class UnsafeFSLoader(AbstractLoader):
|
class UnsafeFSLoader(AbstractLoader):
|
@ -1,4 +1,4 @@
|
|||||||
from src.core.modules_system.loaders.base import AbstractLoader
|
from ocab_core.modules_system.loaders.base import AbstractLoader
|
||||||
|
|
||||||
|
|
||||||
class ModulesManager:
|
class ModulesManager:
|
||||||
@ -9,13 +9,14 @@ class ModulesManager:
|
|||||||
info = loader.info()
|
info = loader.info()
|
||||||
module = loader.load()
|
module = loader.load()
|
||||||
|
|
||||||
print(module)
|
|
||||||
|
|
||||||
self.modules[info.id] = {
|
self.modules[info.id] = {
|
||||||
"info": info,
|
"info": info,
|
||||||
"module": module,
|
"module": module,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if hasattr(module, "module_init"):
|
||||||
|
module.module_init()
|
||||||
|
|
||||||
def get_by_id(self, module_id: str):
|
def get_by_id(self, module_id: str):
|
||||||
if module_id not in self.modules:
|
if module_id not in self.modules:
|
||||||
raise Exception(f"Module with id {module_id} not loaded")
|
raise Exception(f"Module with id {module_id} not loaded")
|
1
src/ocab_core/modules_system/public_api/__init__.py
Normal file
1
src/ocab_core/modules_system/public_api/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .public_api import Storage, get_module, register_router
|
54
src/ocab_core/modules_system/public_api/public_api.py
Normal file
54
src/ocab_core/modules_system/public_api/public_api.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import types
|
||||||
|
from typing import Any, Tuple, Union
|
||||||
|
|
||||||
|
from aiogram import Router
|
||||||
|
|
||||||
|
from ocab_core.singleton import Singleton
|
||||||
|
|
||||||
|
|
||||||
|
def register_router(router: Router):
|
||||||
|
app = Singleton()
|
||||||
|
app.dp.include_router(router)
|
||||||
|
|
||||||
|
|
||||||
|
def get_module(
|
||||||
|
module_id: str, paths=None
|
||||||
|
) -> Union[types.ModuleType, Union[Any, None], Tuple[Union[Any, None], ...]]:
|
||||||
|
app = Singleton()
|
||||||
|
module = app.modules_manager.get_by_id(module_id)
|
||||||
|
|
||||||
|
if paths is None:
|
||||||
|
return module
|
||||||
|
|
||||||
|
if isinstance(paths, str):
|
||||||
|
paths = [paths]
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
for path in paths:
|
||||||
|
current_obj = module
|
||||||
|
try:
|
||||||
|
parts = path.split(".")
|
||||||
|
for part in parts:
|
||||||
|
current_obj = getattr(current_obj, part)
|
||||||
|
results.append(current_obj)
|
||||||
|
except AttributeError:
|
||||||
|
results.append(None)
|
||||||
|
|
||||||
|
if len(results) == 1:
|
||||||
|
return results[0]
|
||||||
|
else:
|
||||||
|
return tuple(results)
|
||||||
|
|
||||||
|
|
||||||
|
class Storage:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set(key: str, value: Any):
|
||||||
|
storage = Singleton().storage
|
||||||
|
storage[key] = value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get(key: str):
|
||||||
|
storage = Singleton().storage
|
||||||
|
return storage.get(key)
|
@ -1,9 +1,9 @@
|
|||||||
from aiogram import Dispatcher
|
from aiogram import Dispatcher
|
||||||
|
|
||||||
from src.modules.standard.admin.routers import router as admin_router
|
from src.ocab_modules.standard.admin.routers import router as admin_router
|
||||||
|
|
||||||
# from src.modules.standard.info.routers import router as info_router
|
# from src.modules.standard.info.routers import router as info_router
|
||||||
from src.modules.standard.message_processing.message_api import (
|
from src.ocab_modules.standard.message_processing.message_api import (
|
||||||
router as process_message,
|
router as process_message,
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
from aiogram import Dispatcher
|
from aiogram import Dispatcher
|
||||||
|
|
||||||
from src.core.modules_system import ModulesManager
|
from ocab_core.modules_system import ModulesManager
|
||||||
|
|
||||||
|
|
||||||
class SingletonMeta(type):
|
class SingletonMeta(type):
|
||||||
@ -16,3 +16,4 @@ class SingletonMeta(type):
|
|||||||
class Singleton(metaclass=SingletonMeta):
|
class Singleton(metaclass=SingletonMeta):
|
||||||
dp: Dispatcher = None
|
dp: Dispatcher = None
|
||||||
modules_manager: ModulesManager = None
|
modules_manager: ModulesManager = None
|
||||||
|
storage = dict()
|
@ -4,14 +4,13 @@ import asyncio
|
|||||||
from aiogram import Bot
|
from aiogram import Bot
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message
|
||||||
|
|
||||||
from src.core.logger import log
|
from ocab_modules.external.yandexgpt.yandexgpt import *
|
||||||
from src.modules.external.yandexgpt.yandexgpt import *
|
from ocab_modules.standard.config.config import (
|
||||||
from src.modules.standard.config.config import (
|
|
||||||
get_yandexgpt_catalog_id,
|
get_yandexgpt_catalog_id,
|
||||||
get_yandexgpt_prompt,
|
get_yandexgpt_prompt,
|
||||||
get_yandexgpt_token,
|
get_yandexgpt_token,
|
||||||
)
|
)
|
||||||
from src.modules.standard.database.db_api import add_message
|
from ocab_modules.standard.database.db_api import add_message
|
||||||
|
|
||||||
|
|
||||||
async def answer_to_message(message: Message, bot: Bot):
|
async def answer_to_message(message: Message, bot: Bot):
|
@ -1,7 +1,7 @@
|
|||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
from aiogram import F, Router
|
from aiogram import F, Router
|
||||||
|
|
||||||
from src.modules.external.yandexgpt.handlers import answer_to_message
|
from src.ocab_modules.external.yandexgpt.handlers import answer_to_message
|
||||||
|
|
||||||
router = Router()
|
router = Router()
|
||||||
# Если сообщение содержит в начале текст "Гномик" или "гномик" или отвечает на сообщение бота, то вызывается функция answer_to_message
|
# Если сообщение содержит в начале текст "Гномик" или "гномик" или отвечает на сообщение бота, то вызывается функция answer_to_message
|
@ -5,7 +5,7 @@ import json
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from src.core.logger import log
|
from ocab_core.logger import log
|
||||||
|
|
||||||
from ...standard.config.config import *
|
from ...standard.config.config import *
|
||||||
from ...standard.database import *
|
from ...standard.database import *
|
@ -4,7 +4,7 @@ import time
|
|||||||
from aiogram import Bot
|
from aiogram import Bot
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message
|
||||||
|
|
||||||
from src.modules.standard.config.config import get_default_chat_tag
|
from src.ocab_modules.standard.config.config import get_default_chat_tag
|
||||||
|
|
||||||
|
|
||||||
async def delete_message(message: Message, bot: Bot):
|
async def delete_message(message: Message, bot: Bot):
|
@ -1,13 +1,13 @@
|
|||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
from aiogram import F, Router
|
from aiogram import F, Router
|
||||||
|
|
||||||
from src.modules.standard.admin.handlers import (
|
from src.ocab_modules.standard.admin.handlers import (
|
||||||
chat_not_in_approve_list,
|
chat_not_in_approve_list,
|
||||||
delete_message,
|
delete_message,
|
||||||
error_access,
|
error_access,
|
||||||
get_chat_id,
|
get_chat_id,
|
||||||
)
|
)
|
||||||
from src.modules.standard.filters.filters import (
|
from src.ocab_modules.standard.filters.filters import (
|
||||||
ChatModerOrAdminFilter,
|
ChatModerOrAdminFilter,
|
||||||
ChatNotInApproveFilter,
|
ChatNotInApproveFilter,
|
||||||
)
|
)
|
@ -1,6 +1,6 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from src.modules.standard.config.config import get_config
|
from src.ocab_modules.standard.config.config import get_config
|
||||||
|
|
||||||
yaml_load = get_config(is_test=True)
|
yaml_load = get_config(is_test=True)
|
||||||
|
|
5
src/ocab_modules/standard/database/__init__.py
Normal file
5
src/ocab_modules/standard/database/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from . import db_api, models
|
||||||
|
|
||||||
|
|
||||||
|
def module_init():
|
||||||
|
db_api.connect_database()
|
@ -6,6 +6,7 @@ from src.service import paths
|
|||||||
from .exceptions import MissingModuleName, NotExpectedModuleName
|
from .exceptions import MissingModuleName, NotExpectedModuleName
|
||||||
from .models.chat_stats import ChatStats
|
from .models.chat_stats import ChatStats
|
||||||
from .models.chats import Chats
|
from .models.chats import Chats
|
||||||
|
from .models.db import database_proxy
|
||||||
from .models.messages import Messages
|
from .models.messages import Messages
|
||||||
from .models.user_stats import UserStats
|
from .models.user_stats import UserStats
|
||||||
from .models.users import Users
|
from .models.users import Users
|
||||||
@ -21,15 +22,12 @@ def connect_database(is_test: bool = False, module: str | None = None):
|
|||||||
raise NotExpectedModuleName()
|
raise NotExpectedModuleName()
|
||||||
db_path = f"{paths.core}/database"
|
db_path = f"{paths.core}/database"
|
||||||
|
|
||||||
# WTF?????
|
database = pw.SqliteDatabase(f"{db_path}/OCAB.db")
|
||||||
_database = pw.SqliteDatabase(f"{db_path}/OCAB.db")
|
database_proxy.initialize(database)
|
||||||
Chats._meta.database = _database
|
database.connect()
|
||||||
Messages._meta.database = _database
|
create_tables(database)
|
||||||
Users._meta.database = _database
|
|
||||||
UserStats._meta.database = _database
|
|
||||||
ChatStats._meta.database = _database
|
|
||||||
|
|
||||||
return _database, f"{db_path}/OCAB.db"
|
return database, f"{db_path}/OCAB.db"
|
||||||
|
|
||||||
|
|
||||||
def create_tables(db: pw.SqliteDatabase):
|
def create_tables(db: pw.SqliteDatabase):
|
||||||
@ -140,7 +138,7 @@ def get_chat_all_stat(chat_id):
|
|||||||
# Работа с таблицей пользователей
|
# Работа с таблицей пользователей
|
||||||
|
|
||||||
|
|
||||||
def get_user(user_id):
|
def get_user(user_id) -> Users | None:
|
||||||
return Users.get_or_none(Users.id == user_id)
|
return Users.get_or_none(Users.id == user_id)
|
||||||
|
|
||||||
|
|
||||||
@ -198,7 +196,8 @@ def change_user_role(user_id, new_user_role):
|
|||||||
|
|
||||||
def get_message(message_chat_id, message_id):
|
def get_message(message_chat_id, message_id):
|
||||||
return Messages.get_or_none(
|
return Messages.get_or_none(
|
||||||
Messages.message_chat_id == message_chat_id, Messages.message_id == message_id
|
Messages.message_chat_id == message_chat_id,
|
||||||
|
Messages.message_id == message_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
|||||||
import peewee as pw
|
import peewee as pw
|
||||||
|
|
||||||
|
from .db import database_proxy
|
||||||
|
|
||||||
|
|
||||||
class ChatStats(pw.Model):
|
class ChatStats(pw.Model):
|
||||||
class Meta: ...
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
|
||||||
chat_id = pw.IntegerField(null=False)
|
chat_id = pw.IntegerField(null=False)
|
||||||
date = pw.DateField(null=False)
|
date = pw.DateField(null=False)
|
@ -1,8 +1,11 @@
|
|||||||
import peewee as pw
|
import peewee as pw
|
||||||
|
|
||||||
|
from .db import database_proxy
|
||||||
|
|
||||||
|
|
||||||
class Chats(pw.Model):
|
class Chats(pw.Model):
|
||||||
class Meta: ...
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
|
||||||
chat_name = pw.CharField(null=False)
|
chat_name = pw.CharField(null=False)
|
||||||
chat_type = pw.IntegerField(null=False, default=10)
|
chat_type = pw.IntegerField(null=False, default=10)
|
3
src/ocab_modules/standard/database/models/db.py
Normal file
3
src/ocab_modules/standard/database/models/db.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from peewee import DatabaseProxy
|
||||||
|
|
||||||
|
database_proxy = DatabaseProxy()
|
@ -1,8 +1,11 @@
|
|||||||
import peewee as pw
|
import peewee as pw
|
||||||
|
|
||||||
|
from .db import database_proxy
|
||||||
|
|
||||||
|
|
||||||
class Messages(pw.Model):
|
class Messages(pw.Model):
|
||||||
class Meta: ...
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
|
||||||
message_chat_id = pw.IntegerField(null=False)
|
message_chat_id = pw.IntegerField(null=False)
|
||||||
message_id = pw.IntegerField(null=False)
|
message_id = pw.IntegerField(null=False)
|
@ -1,8 +1,11 @@
|
|||||||
import peewee as pw
|
import peewee as pw
|
||||||
|
|
||||||
|
from .db import database_proxy
|
||||||
|
|
||||||
|
|
||||||
class UserStats(pw.Model):
|
class UserStats(pw.Model):
|
||||||
class Meta: ...
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
|
||||||
chat_id = pw.IntegerField(null=False)
|
chat_id = pw.IntegerField(null=False)
|
||||||
user_id = pw.IntegerField(null=False)
|
user_id = pw.IntegerField(null=False)
|
@ -1,8 +1,11 @@
|
|||||||
import peewee as pw
|
import peewee as pw
|
||||||
|
|
||||||
|
from .db import database_proxy
|
||||||
|
|
||||||
|
|
||||||
class Users(pw.Model):
|
class Users(pw.Model):
|
||||||
class Meta: ...
|
class Meta:
|
||||||
|
database = database_proxy
|
||||||
|
|
||||||
user_tag = pw.CharField(null=True)
|
user_tag = pw.CharField(null=True)
|
||||||
user_name = pw.CharField(null=False) # до 255 символов
|
user_name = pw.CharField(null=False) # до 255 символов
|
@ -2,9 +2,9 @@ from aiogram import Bot
|
|||||||
from aiogram.filters import BaseFilter
|
from aiogram.filters import BaseFilter
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message
|
||||||
|
|
||||||
from src.core.logger import log
|
from ocab_core.logger import log
|
||||||
from src.modules.standard.config.config import get_aproved_chat_id
|
from ocab_modules.standard.config.config import get_aproved_chat_id
|
||||||
from src.modules.standard.roles.roles import Roles
|
from ocab_modules.standard.roles.roles import Roles
|
||||||
|
|
||||||
|
|
||||||
class ChatModerOrAdminFilter(BaseFilter):
|
class ChatModerOrAdminFilter(BaseFilter):
|
14
src/ocab_modules/standard/info/__init__.py
Normal file
14
src/ocab_modules/standard/info/__init__.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from aiogram import F, Router
|
||||||
|
|
||||||
|
from ocab_core.modules_system.public_api import register_router
|
||||||
|
|
||||||
|
from .handlers import get_chat_info, get_user_info
|
||||||
|
|
||||||
|
|
||||||
|
def module_init():
|
||||||
|
router = Router()
|
||||||
|
|
||||||
|
router.message.register(get_user_info, F.text.startswith("/info"))
|
||||||
|
router.message.register(get_chat_info, F.text.startswith("/chatinfo"))
|
||||||
|
|
||||||
|
register_router(router)
|
@ -1,60 +1,65 @@
|
|||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
from typing import Type
|
from typing import Any, Type
|
||||||
|
|
||||||
from aiogram import Bot
|
from aiogram import Bot
|
||||||
|
from aiogram.types import Message
|
||||||
|
|
||||||
from src.core.logger import log
|
from ocab_core.logger import log
|
||||||
from src.core.modules_system.public_api import get_module
|
from ocab_core.modules_system.public_api import get_module
|
||||||
from src.modules.standard.database.db_api import (
|
|
||||||
Message,
|
from .interfaces import IDbApi, IRoles
|
||||||
get_chat_all_stat,
|
|
||||||
get_message_ai_model,
|
# from src.modules.standard.database import db_api
|
||||||
get_user,
|
|
||||||
get_user_all_stats,
|
|
||||||
get_user_id,
|
db_api: Type[IDbApi] = get_module(
|
||||||
get_user_name,
|
"standard.database",
|
||||||
get_user_rep,
|
"db_api",
|
||||||
get_user_role,
|
|
||||||
get_user_tag,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from .interfaces import IRoles
|
# db_api.init_db_connection()
|
||||||
|
|
||||||
Roles: Type[IRoles] = get_module("standard.roles").Roles
|
Roles: Type[IRoles] = get_module("standard.roles", "Roles")
|
||||||
|
|
||||||
|
|
||||||
async def get_info_answer_by_id(message: Message, bot: Bot, user_id: int):
|
async def get_info_answer_by_id(message: Message, bot: Bot, user_id: int):
|
||||||
if get_message_ai_model(message.chat.id, message.message_id) is not None:
|
ai_model = db_api.get_message_ai_model(message.chat.id, message.message_id)
|
||||||
|
if ai_model is not None:
|
||||||
await message.reply(
|
await message.reply(
|
||||||
"Это сообщение было сгенерировано ботом используя модель: "
|
"Это сообщение было сгенерировано ботом используя модель: " + ai_model
|
||||||
+ get_message_ai_model(message.chat.id, message.message_id)
|
|
||||||
)
|
)
|
||||||
elif user_id == bot.id:
|
return
|
||||||
|
|
||||||
|
if user_id == bot.id:
|
||||||
await message.reply("Это сообщение было отправлено ботом")
|
await message.reply("Это сообщение было отправлено ботом")
|
||||||
elif get_user(user_id) is None:
|
return
|
||||||
|
|
||||||
|
user = db_api.get_user(user_id)
|
||||||
|
|
||||||
|
if user is None:
|
||||||
await message.reply("Пользователь не найден")
|
await message.reply("Пользователь не найден")
|
||||||
# print(get_user(user_id))
|
await log(f"Пользователь не найден: {user_id}, {user}")
|
||||||
await log(f"Пользователь не найден: {user_id}, {get_user(user_id)}")
|
return
|
||||||
else:
|
|
||||||
roles = Roles()
|
roles = Roles()
|
||||||
answer = (
|
answer = (
|
||||||
f"Пользователь: {get_user_name(user_id)}\n"
|
f"Пользователь: {user.user_name}\n"
|
||||||
f"Роль: {await roles.get_role_name(role_id=get_user_role(user_id))}\n"
|
f"Роль: {await roles.get_role_name(role_id=user.user_role)}\n"
|
||||||
f"Тег: @{get_user_tag(user_id)}\n"
|
f"Тег: @{user.user_tag}\n"
|
||||||
f"Кол-во сообщений: {get_user_all_stats(user_id)}\n"
|
f"Кол-во сообщений: {user.user_stats}\n"
|
||||||
f"Репутация: {get_user_rep(user_id)}"
|
f"Репутация: {user.user_rep}"
|
||||||
)
|
)
|
||||||
await message.reply(answer)
|
await message.reply(answer)
|
||||||
|
|
||||||
|
|
||||||
async def get_user_info(message: Message, bot: Bot):
|
async def get_user_info(message: Message, bot: Bot):
|
||||||
# Проверяем содержимое сообщения, если содержит вторым элементом тег пользователя, то выводим информацию о нем
|
# Проверяем содержимое сообщения, если содержит вторым элементом тег пользователя, то выводим информацию о нем
|
||||||
# Если сообщение отвечает на другое сообщение, то выводим информацию о пользователе, на чье сообщение был ответ
|
# Если сообщение отвечает на другое сообщение, то выводим информацию о пользователе, на чье сообщение был ответ
|
||||||
# Если это бот то выводим информацию что это бот и какая модель yandexgpt используется
|
# Если это бот то выводим информацию, что это бот и какая модель yandexgpt используется
|
||||||
try:
|
try:
|
||||||
if len(message.text.split()) > 1 and message.text.split()[1].startswith("@"):
|
if len(message.text.split()) > 1 and message.text.split()[1].startswith("@"):
|
||||||
user_tag = message.text.split()[1][1:]
|
user_tag = message.text.split()[1][1:]
|
||||||
user_id = get_user_id(user_tag)
|
user_id = db_api.get_user_id(user_tag)
|
||||||
if user_id:
|
if user_id:
|
||||||
await get_info_answer_by_id(message, bot, user_id)
|
await get_info_answer_by_id(message, bot, user_id)
|
||||||
else:
|
else:
|
||||||
@ -77,7 +82,7 @@ async def get_chat_info(message: Message, bot: Bot):
|
|||||||
answer = (
|
answer = (
|
||||||
f"*Название чата:* {message.chat.title}\n"
|
f"*Название чата:* {message.chat.title}\n"
|
||||||
f"*ID чата:* `{message.chat.id}`\n \n"
|
f"*ID чата:* `{message.chat.id}`\n \n"
|
||||||
f"*Суммарное количество сообщений в чате:* {get_chat_all_stat(message.chat.id)}\n"
|
f"*Суммарное количество сообщений в чате:* {db_api.get_chat_all_stat(message.chat.id)}\n"
|
||||||
f"*Количество пользователей в чате:* {await bot.get_chat_member_count(message.chat.id)}\n"
|
f"*Количество пользователей в чате:* {await bot.get_chat_member_count(message.chat.id)}\n"
|
||||||
f"*Количество администраторов в чате:* {len(await bot.get_chat_administrators(message.chat.id))}"
|
f"*Количество администраторов в чате:* {len(await bot.get_chat_administrators(message.chat.id))}"
|
||||||
)
|
)
|
47
src/ocab_modules/standard/info/interfaces.py
Normal file
47
src/ocab_modules/standard/info/interfaces.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
class IRoles:
|
||||||
|
user: str
|
||||||
|
moderator: str
|
||||||
|
admin: str
|
||||||
|
bot: str
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def check_admin_permission(self, user_id: int) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def check_moderator_permission(self, user_id) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def get_role_name(self, role_id) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def get_user_permission(self, user_id) -> str | None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class IUsers:
|
||||||
|
user_id: int
|
||||||
|
user_name: str
|
||||||
|
user_role: int
|
||||||
|
user_tag: str
|
||||||
|
user_stats: int
|
||||||
|
user_rep: int
|
||||||
|
|
||||||
|
|
||||||
|
class IDbApi:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_message_ai_model(message_chat_id: Any, message_id: Any) -> Any | None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_user(user_id: int) -> IUsers | None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_chat_all_stat(chat_id: int) -> int:
|
||||||
|
pass
|
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
from aiogram import Bot, F, Router, types
|
from aiogram import Bot, F, Router, types
|
||||||
|
|
||||||
from src.core.logger import log
|
from ocab_core.logger import log
|
||||||
from src.modules.external.yandexgpt.handlers import answer_to_message
|
from ocab_modules.external.yandexgpt.handlers import answer_to_message
|
||||||
from src.modules.standard.config.config import (
|
from ocab_modules.standard.config.config import (
|
||||||
get_aproved_chat_id,
|
get_aproved_chat_id,
|
||||||
get_yandexgpt_in_words,
|
get_yandexgpt_in_words,
|
||||||
get_yandexgpt_start_words,
|
get_yandexgpt_start_words,
|
||||||
)
|
)
|
||||||
from src.modules.standard.database.db_api import *
|
from ocab_modules.standard.database.db_api import *
|
||||||
|
|
||||||
|
|
||||||
async def chat_check(message: types.Message):
|
async def chat_check(message: types.Message):
|
@ -1,7 +1,7 @@
|
|||||||
from src.core.modules_system.public_api import get_module
|
from ocab_core.modules_system.public_api import get_module
|
||||||
|
|
||||||
get_user_role = get_module("standard.database").db_api.get_user_role
|
get_user_role = get_module("standard.database", "db_api.get_user_role")
|
||||||
config = get_module("standard.config").config
|
config: dict = get_module("standard.config", "config")
|
||||||
|
|
||||||
|
|
||||||
class Roles:
|
class Roles:
|
@ -9,10 +9,14 @@ from aiogram.types import Message
|
|||||||
from aiogram.types import inline_keyboard_button as types
|
from aiogram.types import inline_keyboard_button as types
|
||||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||||
|
|
||||||
from src.modules.standard.config.config import get_telegram_check_bot
|
from src.ocab_modules.standard.config.config import get_telegram_check_bot
|
||||||
from src.modules.standard.database.db_api import *
|
from src.ocab_modules.standard.database.db_api import *
|
||||||
from src.modules.standard.moderation.moderation import ban_user, mute_user, unmute_user
|
from src.ocab_modules.standard.moderation.moderation import (
|
||||||
from src.modules.standard.roles.roles import Roles
|
ban_user,
|
||||||
|
mute_user,
|
||||||
|
unmute_user,
|
||||||
|
)
|
||||||
|
from src.ocab_modules.standard.roles.roles import Roles
|
||||||
|
|
||||||
|
|
||||||
async def create_math_task():
|
async def create_math_task():
|
@ -1,6 +1,6 @@
|
|||||||
from aiogram import F, Router
|
from aiogram import F, Router
|
||||||
|
|
||||||
from src.modules.standard.welcome.handlers import check_new_user
|
from src.ocab_modules.standard.welcome.handlers import check_new_user
|
||||||
|
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user