feat: add karkas_lite

This commit is contained in:
Maxim Slipenko 2024-10-03 19:59:23 +03:00
parent 0881fe02d5
commit 9ac88652e0
No known key found for this signature in database
GPG Key ID: 6DEA9FA7DE98C7D6
20 changed files with 2650 additions and 18 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ __pycache__
Karkas.db
config.yaml
dist
*.py[cod]

View File

@ -23,6 +23,10 @@
{
"name": "ALT Linux",
"path": "src/altlinux"
},
{
"name": "Karkas Lite",
"path": "src/karkas_lite"
}
],
"extensions": {

View File

@ -5,18 +5,22 @@ from karkas_core.modules_system.public_api import set_my_commands
commands = dict()
def register_command(command, description, role="USER"):
def register_command(command, description, long_description=None, role="USER"):
if long_description is None:
long_description = description
if role not in commands:
commands[role] = dict()
commands[role][command] = {
"description": description,
"long_description": long_description,
}
async def set_user_commands():
async def set_commands(role="USER"):
bot_commands = []
if "USER" in commands:
user_commands = commands["USER"]
if role in commands:
user_commands = commands[role]
for command in user_commands:
bot_commands.append(
BotCommand(
@ -25,18 +29,24 @@ async def set_user_commands():
)
)
# log(bot_commands)
await set_my_commands(
bot_commands,
)
def get_user_commands():
if "USER" in commands:
return commands["USER"].copy()
def get_commands(role="USER"):
if role in commands:
return commands[role].copy()
return {}
async def set_user_commands():
await set_commands("USER")
def get_user_commands():
return get_commands("USER")
async def module_late_init():
await set_user_commands()

View File

@ -2,6 +2,7 @@ from .filters import (
ChatIDFilter,
ChatModerOrAdminFilter,
ChatNotInApproveFilter,
SimpleAdminFilter,
chat_not_in_approve,
module_init,
)

View File

@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict
from aiogram import BaseMiddleware, Bot
from aiogram.filters import BaseFilter
from aiogram.types import Message, TelegramObject
from aiogram.utils.chat_member import ADMINS
from typing_extensions import deprecated
from karkas_core.modules_system.public_api import (
@ -121,3 +122,9 @@ class ChatModerOrAdminFilter(BaseFilter):
or await roles.check_moderator_permission(user_id)
or any(user_id == admin.user.id for admin in admins)
)
class SimpleAdminFilter(BaseFilter):
async def __call__(self, message: Message, bot: Bot) -> bool:
member = await bot.get_chat_member(message.chat.id, message.from_user.id)
return isinstance(member, ADMINS)

View File

@ -42,7 +42,7 @@ FOOTER = """===============
def format_commands(commands_dict):
formatted_commands = []
for command, details in commands_dict.items():
formatted_commands.append(f"/{command} - {details['description']}")
formatted_commands.append(f"/{command} - {details['long_description']}")
return "\n".join(formatted_commands)

View File

@ -0,0 +1,29 @@
from piccolo.apps.migrations.auto.migration_manager import MigrationManager
ID = "2024-10-03T19:24:33:522177"
VERSION = "1.16.0"
DESCRIPTION = ""
async def forwards():
manager = MigrationManager(
migration_id=ID, app_name="standard.spam", description=DESCRIPTION
)
manager.drop_column(
table_class_name="SpamLog",
tablename="spam_log",
column_name="chat_id",
db_column_name="chat_id",
schema=None,
)
manager.drop_column(
table_class_name="SpamLog",
tablename="spam_log",
column_name="user_id",
db_column_name="user_id",
schema=None,
)
return manager

View File

@ -1,10 +1,8 @@
from piccolo.columns import JSON, Date, Integer, Text
from piccolo.columns import JSON, Date, Text
from piccolo.table import Table
class SpamLog(Table):
chat_id = Integer()
user_id = Integer()
message_text = Text(null=True)
attachments = JSON()
created_at = Date()

View File

@ -1,4 +1,4 @@
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Type
from aiogram import Bot, Router
from aiogram.filters import Command
@ -17,6 +17,8 @@ except Exception:
if TYPE_CHECKING:
from aiogram.types import Message
from karkas_blocks.standard.filters import SimpleAdminFilter as ISimpleAdminFilter
async def spam(message: "Message", bot: "Bot"):
if not message.reply_to_message:
@ -41,8 +43,6 @@ async def spam(message: "Message", bot: "Bot"):
}
spam_log = SpamLog(
chat_id=chat_id,
user_id=spam_message.from_user.id,
message_text=spam_message.text,
attachments=attachments,
)
@ -67,15 +67,23 @@ async def spam(message: "Message", bot: "Bot"):
def module_init():
register_app_config = get_module("standard.database", "register_app_config")
SimpleAdminFilter: "Type[ISimpleAdminFilter]" = get_module(
"standard.filters", "SimpleAdminFilter"
)
from .db import APP_CONFIG
register_app_config(APP_CONFIG)
router = Router()
router.message.register(spam, Command("spam"))
router.message.register(spam, SimpleAdminFilter(), Command("spam"))
register_router(router)
if COMMAND_HELPER_MODULE_LOADED:
register_command("spam", "Спам", role="ADMIN")
register_command(
"spam",
"Удалить спам и забанить пользователя",
long_description="Удалить спам и забанить пользователя. "
"Собирает обезличенные данные для дальнейшего создания алгоритма",
)

View File

@ -0,0 +1,38 @@
FROM python:3.12-slim AS dependencies_installer
RUN pip install poetry
WORKDIR /app
COPY ./src/karkas_core/poetry* ./src/karkas_core/pyproject.toml /app/src/karkas_core/
COPY ./src/karkas_blocks/poetry* ./src/karkas_blocks/pyproject.toml /app/src/karkas_blocks/
COPY ./src/karkas_piccolo/poetry* ./src/karkas_piccolo/pyproject.toml /app/src/karkas_piccolo/
COPY ./src/karkas_lite/poetry* ./src/karkas_lite/pyproject.toml /app/src/karkas_lite/
WORKDIR /app/src/karkas_lite
RUN poetry install --no-root --no-directory
FROM python:3.12-slim AS src
COPY ./src/karkas_core /app/src/karkas_core
COPY ./src/karkas_blocks /app/src/karkas_blocks
COPY ./src/karkas_piccolo /app/src/karkas_piccolo
COPY ./src/karkas_lite /app/src/karkas_lite
FROM python:3.12-slim AS local_dependencies_installer
RUN pip install poetry
COPY --from=dependencies_installer /app/src/karkas_lite/.venv /app/src/karkas_lite/.venv
COPY --from=src /app/src/ /app/src/
WORKDIR /app/src/karkas_lite
RUN poetry install
FROM python:3.12-slim AS base
COPY --from=local_dependencies_installer /app/src/karkas_lite/.venv /app/src/karkas_lite/.venv
COPY --from=src /app/src/ /app/src/
WORKDIR /app/src/karkas_lite
ENV PATH="/app/.venv/bin:$PATH"
CMD ["/bin/bash", "-c", ". .venv/bin/activate && python -m karkas_lite"]

View File

@ -0,0 +1,14 @@
**/Dockerfile
**/*.dockerignore
**/docker-compose.yml
**/.git
**/.gitignore
**/.venv
**/.mypy_cache
**/__pycache__/
src/karkas_lite/config.yaml
src/karkas_lite/database/*

View File

View File

@ -0,0 +1,3 @@
core:
mode: LONG_POLLING
token: xxx

View File

View File

@ -0,0 +1,10 @@
services:
app:
build:
context: ../..
dockerfile: src/karkas_lite/Dockerfile
ports:
- 9000:9000
volumes:
- ./config.yaml:/app/src/karkas_lite/config.yaml
- ./database:/app/database

View File

View File

@ -0,0 +1,24 @@
import asyncio
from karkas_blocks import block_loader
from karkas_core import Karkas
async def main():
ocab = Karkas()
await ocab.init_app(
[
block_loader("standard", "config", safe=False),
block_loader("standard", "filters", safe=False),
block_loader("standard", "database", safe=False),
block_loader("standard", "command_helper"),
block_loader("standard", "spam", safe=False),
block_loader("standard", "report"),
block_loader("standard", "welcome", safe=False),
block_loader("standard", "help"),
]
)
await ocab.start()
asyncio.run(main())

2465
src/karkas_lite/poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
[virtualenvs]
in-project = true

View File

@ -0,0 +1,18 @@
[tool.poetry]
name = "karkas-lite"
version = "0.1.0"
description = ""
authors = [
"Maxim Slipenko <maxim@slipenko.com>"
]
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.10,<3.13"
karkas-core = { extras=["webhook"], path = "../karkas_core", develop = true }
karkas-blocks = { path = "../karkas_blocks", develop = true }
karkas-piccolo = { path = "../karkas_piccolo", develop = true }
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"