Untitled
4ae4d
plain_text
02/10/2026 7:41 AM
10.8 KB
9
Indexable
--- a/src/bot/core/handlers/events_filters.py
+++ b/src/bot/core/handlers/events_filters.py
@@ -1,12 +1,13 @@
from dialog_bot_sdk.entities.messaging import UpdateInteractiveMediaEvent
from core.bot_kit.fsm import FSMContext, State, StatesGroup
from core.config import bot
from core.handlers.events_ui import send_city_events_page, send_my_events_page, send_points_page
-from core.markups.events_filters import events_filters_menu_keyboard
+from core.markups.events_filters import events_filters_city_keyboard, events_filters_menu_keyboard
from core.markups.tags import TagChoice
+from core.services.city import CityService
from core.services.event import EventService
from core.services.tag import TagService
from core.utils import delete_prev_message_by_peer
from core.utils.events_filter import (
format_events_filter_summary,
get_events_filter,
reset_events_filter,
set_events_filter,
)
from core.utils.tags_toggle_ui import TagsToggleCfg, is_done, parse_toggle_key, send_tags_toggle_ui
@@
class EventsFiltersTagsState(StatesGroup):
tags = State()
+
+
+class EventsFiltersCityState(StatesGroup):
+ city = State()
@@
_CTX_KEY = "events_filters_edit_ctx"
_OFFSET_KEY = "events_filters_edit_offset"
_TAG_IDS_KEY = "events_filters_edit_tags_selected"
+
+_CITIES_OFFSET_KEY = "events_filters_city_offset"
+_CITY_SELECTED_ID_KEY = "events_filters_city_selected_id"
+_CITY_SELECTED_NAME_KEY = "events_filters_city_selected_name"
+
+_CITIES_PAGE_LIMIT = 10
@@
def events_filters_not_implemented_handler(event: UpdateInteractiveMediaEvent, context: FSMContext):
@@
bot.messaging.send_message(
peer=event.peer,
text=f"⚠️ Пока не реализовано в этом коммите.\n\n{summary}\n\nВыбери, что изменить:",
interactive_media_groups=events_filters_menu_keyboard(ctx_name=ctx_name, offset=offset),
)
+
+
+def _safe_int(value: object, default: int = 0) -> int:
+ try:
+ if value is None:
+ return default
+ n = int(value)
+ return n if n >= 0 else default
+ except Exception:
+ return default
+
+
+def _send_city_picker(
+ *,
+ peer,
+ ctx_name: str,
+ back_offset: int,
+ cities_offset: int,
+ selected_city_id: str | None,
+ city_service: CityService,
+):
+ cities = city_service.get_all(offset=cities_offset, limit=_CITIES_PAGE_LIMIT)
+ has_prev = cities_offset > 0
+ has_next = len(cities) >= _CITIES_PAGE_LIMIT
+
+ bot.messaging.send_message(
+ peer=peer,
+ text="🏙️ *Фильтры: город*\n\nВыбери один город и нажми «Готово»:",
+ interactive_media_groups=events_filters_city_keyboard(
+ ctx_name=ctx_name,
+ back_offset=back_offset,
+ cities=cities,
+ cities_offset=cities_offset,
+ limit=_CITIES_PAGE_LIMIT,
+ selected_city_id=selected_city_id,
+ has_prev=has_prev,
+ has_next=has_next,
+ ),
+ )
+
+
[email protected]
+def events_filters_city_open_handler(
+ event: UpdateInteractiveMediaEvent,
+ context: FSMContext,
+ event_service: EventService,
+ city_service: CityService,
+):
+ delete_prev_message_by_peer(bot, event.peer)
+ context.set_state(None)
+
+ ctx_name, back_offset = _split_ctx_offset(event.data.value)
+ flt = get_events_filter(context, ctx_name=ctx_name)
+
+ # сохраняем "куда вернуться" + текущий выбор
+ context.update_data(
+ {
+ _CTX_KEY: ctx_name,
+ _OFFSET_KEY: int(back_offset),
+ _CITIES_OFFSET_KEY: 0,
+ _CITY_SELECTED_ID_KEY: flt.city_id,
+ _CITY_SELECTED_NAME_KEY: flt.city_name,
+ }
+ )
+ context.set_state(EventsFiltersCityState.city)
+
+ _send_city_picker(
+ peer=event.peer,
+ ctx_name=ctx_name,
+ back_offset=back_offset,
+ cities_offset=0,
+ selected_city_id=flt.city_id,
+ city_service=city_service,
+ )
+
+
[email protected]
+def events_filters_city_select_handler(
+ event: UpdateInteractiveMediaEvent,
+ context: FSMContext,
+ event_service: EventService,
+ city_service: CityService,
+):
+ state = context.get_state()
+ if not (state == EventsFiltersCityState.city or str(state) == str(EventsFiltersCityState.city)):
+ return
+
+ delete_prev_message_by_peer(bot, event.peer)
+
+ raw = str(event.data.value or "").strip()
+ data = context.get_data() or {}
+
+ ctx_name = str(data.get(_CTX_KEY) or "events")
+ back_offset = _safe_int(data.get(_OFFSET_KEY), 0)
+ cities_offset = _safe_int(data.get(_CITIES_OFFSET_KEY), 0)
+ selected_city_id = data.get(_CITY_SELECTED_ID_KEY)
+
+ # BACK / DONE несут ctx|offset
+ if raw.startswith("back:"):
+ _ctx, _off = _split_ctx_offset(raw[len("back:") :])
+ summary = format_events_filter_summary(get_events_filter(context, ctx_name=_ctx))
+ context.set_state(None)
+ context.update_data(
+ {
+ _CTX_KEY: None,
+ _OFFSET_KEY: None,
+ _CITIES_OFFSET_KEY: None,
+ _CITY_SELECTED_ID_KEY: None,
+ _CITY_SELECTED_NAME_KEY: None,
+ }
+ )
+ bot.messaging.send_message(
+ peer=event.peer,
+ text=f"🧰 *Фильтры*\n\n{summary}\n\nВыбери, что изменить:",
+ interactive_media_groups=events_filters_menu_keyboard(ctx_name=_ctx, offset=_off),
+ )
+ return
+
+ if raw.startswith("done:"):
+ _ctx, _off = _split_ctx_offset(raw[len("done:") :])
+ sel_id = str(data.get(_CITY_SELECTED_ID_KEY) or "").strip() or None
+ sel_name = str(data.get(_CITY_SELECTED_NAME_KEY) or "").strip() or None
+
+ flt = get_events_filter(context, ctx_name=_ctx)
+ flt.city_id = sel_id
+ flt.city_name = sel_name
+ set_events_filter(context, ctx_name=_ctx, flt=flt)
+
+ summary = format_events_filter_summary(get_events_filter(context, ctx_name=_ctx))
+ context.set_state(None)
+ context.update_data(
+ {
+ _CTX_KEY: None,
+ _OFFSET_KEY: None,
+ _CITIES_OFFSET_KEY: None,
+ _CITY_SELECTED_ID_KEY: None,
+ _CITY_SELECTED_NAME_KEY: None,
+ }
+ )
+ bot.messaging.send_message(
+ peer=event.peer,
+ text=f"🧰 *Фильтры*\n\n{summary}\n\nВыбери, что изменить:",
+ interactive_media_groups=events_filters_menu_keyboard(ctx_name=_ctx, offset=_off),
+ )
+ return
+
+ # CLEAR
+ if raw == "clear":
+ context.update_data({_CITY_SELECTED_ID_KEY: None, _CITY_SELECTED_NAME_KEY: None})
+ _send_city_picker(
+ peer=event.peer,
+ ctx_name=ctx_name,
+ back_offset=back_offset,
+ cities_offset=cities_offset,
+ selected_city_id=None,
+ city_service=city_service,
+ )
+ return
+
+ # PAGE
+ if raw.startswith("page:"):
+ new_off = _safe_int(raw[len("page:") :], 0)
+ context.update_data({_CITIES_OFFSET_KEY: new_off})
+ _send_city_picker(
+ peer=event.peer,
+ ctx_name=ctx_name,
+ back_offset=back_offset,
+ cities_offset=new_off,
+ selected_city_id=str(data.get(_CITY_SELECTED_ID_KEY) or "").strip() or None,
+ city_service=city_service,
+ )
+ return
+
+ # SELECT
+ if raw.startswith("select:"):
+ cid = raw[len("select:") :].strip()
+ if not cid:
+ return
+ city = city_service.get_by_id(cid)
+ context.update_data(
+ {
+ _CITY_SELECTED_ID_KEY: cid,
+ _CITY_SELECTED_NAME_KEY: (city.name if city else None),
+ }
+ )
+ _send_city_picker(
+ peer=event.peer,
+ ctx_name=ctx_name,
+ back_offset=back_offset,
+ cities_offset=cities_offset,
+ selected_city_id=cid,
+ city_service=city_service,
+ )
+ return
Editor is loading...
Leave a Comment