Эх сурвалжийг харах

feat(routers): add PostRouter, use asyncio.create_task for moderation calls instead of await

Librellium 2 өдөр өмнө
parent
commit
5438864bc9

+ 2 - 1
anonflow/bot/routers/__init__.py

@@ -1,5 +1,6 @@
+from .callbacks import PostRouter
 from .media import MediaRouter
 from .media import MediaRouter
 from .start import StartRouter
 from .start import StartRouter
 from .text import TextRouter
 from .text import TextRouter
 
 
-__all__ = ["MediaRouter", "StartRouter", "TextRouter"]
+__all__ = ["PostRouter", "MediaRouter", "StartRouter", "TextRouter"]

+ 3 - 0
anonflow/bot/routers/callbacks/__init__.py

@@ -0,0 +1,3 @@
+from .post import PostRouter
+
+__all__ = ["PostRouter"]

+ 40 - 0
anonflow/bot/routers/callbacks/post.py

@@ -0,0 +1,40 @@
+from aiogram import Router
+from aiogram.types import CallbackQuery
+
+from anonflow.bot.keyboards.callbacks import PostCallbackData
+from anonflow.bot.transport.types import RequestContext
+from anonflow.interfaces import PostResponsesPort, ModeratorResponsesPort
+from anonflow.services import ModeratorService
+from anonflow.services.moderator.permissions import ModeratorPermission
+
+
+class PostRouter(Router):
+    def __init__(
+        self,
+        post_responses_port: PostResponsesPort,
+        moderator_responses_port: ModeratorResponsesPort,
+        moderator_service: ModeratorService
+    ):
+        super().__init__()
+
+        self._post_responses_port = post_responses_port
+        self._moderator_responses_port = moderator_responses_port
+        self._moderator_service = moderator_service
+
+    async def _on_post_callback_query(self, query: CallbackQuery, callback_data: PostCallbackData, user_language: str):
+        message = query.message
+
+        if message:
+            if await self._moderator_service.can(query.from_user.id, ModeratorPermission.MANAGE_POSTS):
+                await self._post_responses_port.post_moderators_decision(
+                    RequestContext(message.chat.id, user_language),
+                    True if callback_data.action == "approve" else False,
+                    message.message_id
+                )
+            else:
+                await self._moderator_responses_port.moderator_permission_error(
+                    RequestContext(message.chat.id, user_language), query.id
+                )
+
+    def setup(self):
+        self.callback_query.register(self._on_post_callback_query, PostCallbackData.filter())

+ 11 - 7
anonflow/bot/routers/media.py

@@ -3,17 +3,21 @@ import base64
 from asyncio import CancelledError
 from asyncio import CancelledError
 from contextlib import suppress
 from contextlib import suppress
 from io import BytesIO
 from io import BytesIO
-from typing import Dict, FrozenSet, List
+from typing import Dict, List, Set
 
 
 from aiogram import F, Router
 from aiogram import F, Router
 from aiogram.enums import ChatType
 from aiogram.enums import ChatType
 from aiogram.types import Message
 from aiogram.types import Message
 
 
+from anonflow.bot.transport.content import (
+    ContentGroup,
+    ContentMediaItem,
+    MediaType
+)
+from anonflow.bot.transport.types import RequestContext
 from anonflow.config.models import ForwardingType
 from anonflow.config.models import ForwardingType
 from anonflow.interfaces import PostResponsesPort
 from anonflow.interfaces import PostResponsesPort
 from anonflow.moderation import ModerationService
 from anonflow.moderation import ModerationService
-from anonflow.bot.transport.content import ContentGroup, ContentMediaItem, MediaType
-from anonflow.bot.transport.types import RequestContext
 
 
 
 
 class MediaRouter(Router):
 class MediaRouter(Router):
@@ -21,7 +25,7 @@ class MediaRouter(Router):
         self,
         self,
         responses_port: PostResponsesPort,
         responses_port: PostResponsesPort,
         moderation_service: ModerationService,
         moderation_service: ModerationService,
-        forwarding_types: FrozenSet[ForwardingType],
+        forwarding_types: Set[ForwardingType],
     ):
     ):
         super().__init__()
         super().__init__()
 
 
@@ -57,7 +61,7 @@ class MediaRouter(Router):
         elif message.video and "video" in self._forwarding_types:
         elif message.video and "video" in self._forwarding_types:
             return {"type": MediaType.VIDEO, "file_id": message.video.file_id}
             return {"type": MediaType.VIDEO, "file_id": message.video.file_id}
 
 
-    async def _process_messages(self, messages: List[Message], user_language: str):
+    async def _process(self, messages: List[Message], user_language: str):
         if not messages:
         if not messages:
             return
             return
 
 
@@ -94,7 +98,7 @@ class MediaRouter(Router):
                     messages = self.media_groups.pop(media_group_id, [])  # type: ignore
                     messages = self.media_groups.pop(media_group_id, [])  # type: ignore
                     self.media_groups_tasks.pop(media_group_id, None)  # type: ignore
                     self.media_groups_tasks.pop(media_group_id, None)  # type: ignore
 
 
-                await self._process_messages(messages, user_language)
+                asyncio.create_task(self._process(messages, user_language))
 
 
         if media_group_id:
         if media_group_id:
             async with self._media_groups_lock:
             async with self._media_groups_lock:
@@ -109,7 +113,7 @@ class MediaRouter(Router):
                 )
                 )
             return
             return
 
 
-        await self._process_messages([message], user_language)
+        asyncio.create_task(self._process([message], user_language))
 
 
     def setup(self):
     def setup(self):
         self.message.register(self._on_media, F.photo | F.video)
         self.message.register(self._on_media, F.photo | F.video)

+ 2 - 2
anonflow/bot/routers/start.py

@@ -2,9 +2,9 @@ from aiogram import Router
 from aiogram.filters import CommandStart
 from aiogram.filters import CommandStart
 from aiogram.types import Message
 from aiogram.types import Message
 
 
-from anonflow.services import UserService
-from anonflow.interfaces import UserResponsesPort
 from anonflow.bot.transport.types import RequestContext
 from anonflow.bot.transport.types import RequestContext
+from anonflow.interfaces import UserResponsesPort
+from anonflow.services import UserService
 
 
 
 
 class StartRouter(Router):
 class StartRouter(Router):

+ 15 - 11
anonflow/bot/routers/text.py

@@ -1,14 +1,15 @@
-from typing import FrozenSet
+import asyncio
+from typing import Set
 
 
 from aiogram import F, Router
 from aiogram import F, Router
 from aiogram.enums import ChatType
 from aiogram.enums import ChatType
 from aiogram.types import Message
 from aiogram.types import Message
 
 
+from anonflow.bot.transport.content import ContentTextItem
+from anonflow.bot.transport.types import RequestContext
 from anonflow.config.models import ForwardingType
 from anonflow.config.models import ForwardingType
 from anonflow.interfaces import PostResponsesPort
 from anonflow.interfaces import PostResponsesPort
 from anonflow.moderation import ModerationService
 from anonflow.moderation import ModerationService
-from anonflow.bot.transport.content import ContentTextItem
-from anonflow.bot.transport.types import RequestContext
 
 
 
 
 class TextRouter(Router):
 class TextRouter(Router):
@@ -16,7 +17,7 @@ class TextRouter(Router):
         self,
         self,
         responses_port: PostResponsesPort,
         responses_port: PostResponsesPort,
         moderation_service: ModerationService,
         moderation_service: ModerationService,
-        forwarding_types: FrozenSet[ForwardingType],
+        forwarding_types: Set[ForwardingType],
     ):
     ):
         super().__init__()
         super().__init__()
 
 
@@ -24,15 +25,18 @@ class TextRouter(Router):
         self._moderation_service = moderation_service
         self._moderation_service = moderation_service
         self._forwarding_types = forwarding_types
         self._forwarding_types = forwarding_types
 
 
-    async def _on_text(self, message: Message, user_language: str):
-        if message.chat.type == ChatType.PRIVATE and "text" in self._forwarding_types:
-            context = RequestContext(message.chat.id, user_language)
+    async def _process(self, message: Message, user_language: str):
+        context = RequestContext(message.chat.id, user_language)
+
+        is_approved = await self._moderation_service.process(context, message.text)
 
 
-            is_approved = await self._moderation_service.process(context, message.text)
+        await self._responses_port.post_prepared(
+            context, ContentTextItem(message.text or ""), is_approved
+        )
 
 
-            await self._responses_port.post_prepared(
-                context, ContentTextItem(message.text or ""), is_approved
-            )
+    async def _on_text(self, message: Message, user_language: str):
+        if message.chat.type == ChatType.PRIVATE and "text" in self._forwarding_types:
+            asyncio.create_task(self._process(message, user_language))
 
 
     def setup(self):
     def setup(self):
         self.message.register(self._on_text, F.text)
         self.message.register(self._on_text, F.text)