mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
* Update API, added some new features * Fixed unknown chat_action value * Separate events from dispatcher messages * Disabled cache for I18n LazyProxy * Rework events isolation * Added chat member status changed filter, update Bot API 5.7, other small changes * Improve exceptions in chat member status filter * Fixed tests, covered flags and events isolation modules * Try to fix flake8 unused type ignore * Fixed linter error * Cover chat member updated filter * Cover chat action sender * Added docs for chat action util * Try to fix tests for python <= 3.9 * Fixed headers * Added docs for flags functionality * Added docs for chat_member_updated filter * Added change notes * Update dependencies and fix mypy checks * Bump version
75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
from asyncio import Lock
|
|
from collections import defaultdict
|
|
from contextlib import asynccontextmanager
|
|
from dataclasses import dataclass, field
|
|
from typing import Any, AsyncGenerator, DefaultDict, Dict, Hashable, Optional
|
|
|
|
from aiogram import Bot
|
|
from aiogram.dispatcher.fsm.state import State
|
|
from aiogram.dispatcher.fsm.storage.base import (
|
|
BaseEventIsolation,
|
|
BaseStorage,
|
|
StateType,
|
|
StorageKey,
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class MemoryStorageRecord:
|
|
data: Dict[str, Any] = field(default_factory=dict)
|
|
state: Optional[str] = None
|
|
|
|
|
|
class MemoryStorage(BaseStorage):
|
|
"""
|
|
Default FSM storage, stores all data in :class:`dict` and loss everything on shutdown
|
|
|
|
.. warning::
|
|
|
|
Is not recommended using in production in due to you will lose all data
|
|
when your bot restarts
|
|
"""
|
|
|
|
def __init__(self) -> None:
|
|
self.storage: DefaultDict[StorageKey, MemoryStorageRecord] = defaultdict(
|
|
MemoryStorageRecord
|
|
)
|
|
|
|
async def close(self) -> None:
|
|
pass
|
|
|
|
async def set_state(self, bot: Bot, key: StorageKey, state: StateType = None) -> None:
|
|
self.storage[key].state = state.state if isinstance(state, State) else state
|
|
|
|
async def get_state(self, bot: Bot, key: StorageKey) -> Optional[str]:
|
|
return self.storage[key].state
|
|
|
|
async def set_data(self, bot: Bot, key: StorageKey, data: Dict[str, Any]) -> None:
|
|
self.storage[key].data = data.copy()
|
|
|
|
async def get_data(self, bot: Bot, key: StorageKey) -> Dict[str, Any]:
|
|
return self.storage[key].data.copy()
|
|
|
|
|
|
class DisabledEventIsolation(BaseEventIsolation):
|
|
@asynccontextmanager
|
|
async def lock(self, bot: Bot, key: StorageKey) -> AsyncGenerator[None, None]:
|
|
yield
|
|
|
|
async def close(self) -> None:
|
|
pass
|
|
|
|
|
|
class SimpleEventIsolation(BaseEventIsolation):
|
|
def __init__(self) -> None:
|
|
# TODO: Unused locks cleaner is needed
|
|
self._locks: DefaultDict[Hashable, Lock] = defaultdict(Lock)
|
|
|
|
@asynccontextmanager
|
|
async def lock(self, bot: Bot, key: StorageKey) -> AsyncGenerator[None, None]:
|
|
lock = self._locks[key]
|
|
async with lock:
|
|
yield
|
|
|
|
async def close(self) -> None:
|
|
self._locks.clear()
|