Unification of pagination, admins control and more
This commit is contained in:
@@ -3,14 +3,11 @@ from aiogram.types import CallbackQuery
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from config import PAGE_SIZE
|
||||
from misc.kb import render_category
|
||||
from config import VERIFIED_ACCOUNTS
|
||||
from misc.kb.client import (
|
||||
get_back_to_catalogue,
|
||||
render_products,
|
||||
render_catalogue,
|
||||
)
|
||||
from repositories.categories import CategoriesRepository
|
||||
from repositories.products import ProductRepository
|
||||
from services.catalogue import CatalogueService
|
||||
|
||||
router = Router()
|
||||
|
||||
@@ -20,80 +17,23 @@ async def subcatalogue(
|
||||
cb: CallbackQuery,
|
||||
state: FSMContext,
|
||||
session: AsyncSession,
|
||||
categories_repo: CategoriesRepository,
|
||||
products_repo: ProductRepository,
|
||||
catalogue_service: CatalogueService,
|
||||
):
|
||||
await state.clear()
|
||||
|
||||
cat_id = cb.data.split(":")[1]
|
||||
is_admin = cb.from_user.id in VERIFIED_ACCOUNTS
|
||||
|
||||
if cat_id == "root":
|
||||
children = await categories_repo.get_categories_by_parent_id(session)
|
||||
kb = render_category(
|
||||
children, show_menu=True, category_cb_factory=lambda c: f"cat:{c.id}"
|
||||
)
|
||||
await cb.message.edit_text(
|
||||
view = await catalogue_service.build_category_view(session, cat_id)
|
||||
kb = render_catalogue(view, is_admin=is_admin)
|
||||
|
||||
if cb.message.photo:
|
||||
await cb.message.delete()
|
||||
await cb.answer(
|
||||
"category selection",
|
||||
reply_markup=kb,
|
||||
)
|
||||
return
|
||||
|
||||
cat_id = int(cat_id)
|
||||
|
||||
children = await categories_repo.get_categories_by_parent_id(session, cat_id)
|
||||
category = await categories_repo.get_category_by_id(session, cat_id)
|
||||
parent_id = category.parent_id or "root"
|
||||
|
||||
if not children:
|
||||
products = await products_repo.get_product_by_category(
|
||||
session, cat_id, limit=PAGE_SIZE + 1, offset=0
|
||||
)
|
||||
products_len = len(products)
|
||||
|
||||
if not products:
|
||||
await cb.message.edit_text(
|
||||
"🍃 Здесь ничего нет...",
|
||||
reply_markup=get_back_to_catalogue(parent_id),
|
||||
)
|
||||
return
|
||||
|
||||
if cb.message.photo:
|
||||
await cb.message.delete()
|
||||
await cb.message.answer(
|
||||
"hya",
|
||||
reply_markup=render_products(
|
||||
products[:PAGE_SIZE],
|
||||
product_cb_factory=lambda p: f"product:{p.id}",
|
||||
back_cb=f"cat:{parent_id}",
|
||||
next_cb=(
|
||||
f"products:{cat_id}:{0 + 1}"
|
||||
if products_len > PAGE_SIZE
|
||||
else None
|
||||
),
|
||||
columns=2,
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
await cb.message.edit_text(
|
||||
"hya",
|
||||
reply_markup=render_products(
|
||||
products[:PAGE_SIZE],
|
||||
product_cb_factory=lambda p: f"product:{p.id}",
|
||||
back_cb=f"cat:{parent_id}",
|
||||
prev_cb=f"products:{cat_id}:{0 - 1}" if products_len < 0 else None,
|
||||
next_cb=(
|
||||
f"products:{cat_id}:{0 + 1}" if products_len > PAGE_SIZE else None
|
||||
),
|
||||
columns=2,
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
kb = render_category(
|
||||
children, parent_id, category_cb_factory=lambda c: f"cat:{c.id}"
|
||||
)
|
||||
|
||||
await cb.message.edit_text(
|
||||
"category selection",
|
||||
reply_markup=kb,
|
||||
|
||||
@@ -5,15 +5,15 @@ from aiogram.types import CallbackQuery, FSInputFile
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from config import PAGE_SIZE, VERIFIED_ACCOUNTS
|
||||
from config import VERIFIED_ACCOUNTS
|
||||
from misc.kb import admins
|
||||
from misc.kb.client import (
|
||||
render_catalogue,
|
||||
render_product_interactions,
|
||||
render_products,
|
||||
)
|
||||
from misc.texts import get_product_description
|
||||
from repositories.categories import CategoriesRepository
|
||||
from repositories.products import ProductRepository
|
||||
from services.catalogue import CatalogueService
|
||||
from services.orders import OrderService
|
||||
|
||||
router = Router()
|
||||
@@ -29,35 +29,22 @@ async def products_pagination(
|
||||
state: FSMContext,
|
||||
pagination_match: Match[str],
|
||||
session: AsyncSession,
|
||||
products_repo: ProductRepository,
|
||||
categories_repo: CategoriesRepository,
|
||||
catalogue_service: CatalogueService,
|
||||
):
|
||||
await state.clear()
|
||||
|
||||
pagination_data = pagination_match.groupdict()
|
||||
category_id = int(pagination_data.get("category_id"))
|
||||
category = await categories_repo.get_category_by_id(session, category_id)
|
||||
page_id = int(pagination_data.get("page_id", 0))
|
||||
|
||||
products = await products_repo.get_product_by_category(
|
||||
session, category_id, limit=PAGE_SIZE + 1, offset=page_id * PAGE_SIZE
|
||||
view = await catalogue_service.build_category_view(
|
||||
session, category_id, page=page_id
|
||||
)
|
||||
products_len = len(products)
|
||||
is_admin = cb.from_user.id in VERIFIED_ACCOUNTS
|
||||
|
||||
await cb.message.edit_reply_markup(
|
||||
reply_markup=render_products(
|
||||
products[:PAGE_SIZE],
|
||||
product_cb_factory=lambda p: f"product:{p.id}",
|
||||
back_cb=f"cat:{category.parent_id}",
|
||||
prev_cb=(f"products:{category_id}:{page_id - 1}" if page_id > 0 else None),
|
||||
next_cb=(
|
||||
f"products:{category_id}:{page_id + 1}"
|
||||
if products_len > PAGE_SIZE
|
||||
else None
|
||||
),
|
||||
columns=2,
|
||||
),
|
||||
)
|
||||
kb = render_catalogue(view, is_admin=is_admin)
|
||||
|
||||
await cb.message.edit_reply_markup(reply_markup=kb)
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("product:"))
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
from typing import Optional
|
||||
import hashlib
|
||||
|
||||
from aiogram import Router, F
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from config import PAGE_SIZE
|
||||
from misc.kb.client import render_products
|
||||
from misc.kb.common import return_menu
|
||||
from misc.redis import RedisClient
|
||||
from misc.states import SearchStorage
|
||||
from repositories.products import ProductRepository
|
||||
|
||||
@@ -28,31 +31,62 @@ async def searching(
|
||||
state: FSMContext,
|
||||
session: AsyncSession,
|
||||
products_repo: ProductRepository,
|
||||
redis_client: RedisClient,
|
||||
):
|
||||
data = await state.get_data()
|
||||
await state.clear()
|
||||
|
||||
orig_msg: Optional[Message] = data.get("msg")
|
||||
await msg.delete()
|
||||
orig_msg: Optional[Message] = data.get("msg") or await msg.answer("⏳")
|
||||
await orig_msg.edit_text("⏳ Поиск...")
|
||||
results = await products_repo.search(
|
||||
session,
|
||||
msg.text,
|
||||
)
|
||||
|
||||
if not orig_msg:
|
||||
await msg.answer(
|
||||
"here",
|
||||
reply_markup=render_products(
|
||||
results,
|
||||
product_cb_factory=lambda p: f"product:{p.id}",
|
||||
back_cb="menu:main",
|
||||
next_cb="",
|
||||
),
|
||||
)
|
||||
return
|
||||
next_cb = None
|
||||
if len(results) > PAGE_SIZE:
|
||||
query_hash = hashlib.sha256(msg.text.encode()).hexdigest()[:16]
|
||||
await redis_client.set_search_query(query_hash, msg.text)
|
||||
next_cb = f"search:{query_hash}:1"
|
||||
|
||||
await orig_msg.edit_text(
|
||||
"here",
|
||||
reply_markup=render_products(
|
||||
results, product_cb_factory=lambda p: f"product:{p.id}", back_cb="menu:main"
|
||||
results[:PAGE_SIZE],
|
||||
product_cb_factory=lambda p: f"product:{p.id}",
|
||||
back_cb="menu:main",
|
||||
next_cb=next_cb,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("search:"))
|
||||
async def search_pagination(
|
||||
cb: CallbackQuery,
|
||||
state: FSMContext,
|
||||
session: AsyncSession,
|
||||
products_repo: ProductRepository,
|
||||
redis_client: RedisClient,
|
||||
):
|
||||
await state.clear()
|
||||
|
||||
data = cb.data.split(":")
|
||||
q_hash = data[1]
|
||||
page = int(data[2])
|
||||
|
||||
query = await redis_client.get_search_query(q_hash)
|
||||
if not query:
|
||||
await cb.message.edit_text("🍃 Попробуйте ещё раз...")
|
||||
|
||||
results = await products_repo.search(session, query, offset=PAGE_SIZE * page)
|
||||
|
||||
await cb.message.edit_reply_markup(
|
||||
reply_markup=render_products(
|
||||
results[:PAGE_SIZE],
|
||||
product_cb_factory=lambda p: f"product:{p.id}",
|
||||
back_cb="menu:main",
|
||||
next_cb=f"search:{q_hash}:{page + 1}" if len(results) > PAGE_SIZE else None,
|
||||
prev_cb=f"search:{q_hash}:{page - 1}" if page > 0 else None,
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user