utils: add pluralize helper, fix word declension in news messages

parent 5841ec8f
......@@ -8,7 +8,7 @@ from datetime import datetime, timedelta
from altrepo import altrepo
from services.news import format_packages, format_bugs
from services.utils import _bold, int_validator
from services.utils import _bold, int_validator, pluralize
from data.keyboards import news_keyboards
dp = Dispatch()
......@@ -146,7 +146,7 @@ async def news_range_handler(
await m.answer("Максимальный диапазон — 180 дней.")
return
await m.answer(f"Загрузка новостей за {delta + 1} дн...")
await m.answer(f"Загрузка новостей за {pluralize(delta + 1, 'день', 'дня', 'дней')}...")
packages_data = await altrepo.parser.news.packages_by_range(d_from, d_to)
......@@ -181,7 +181,7 @@ async def pulse_handler(m: Message, days: int | None = None) -> None:
d_to = datetime.now().date()
d_from = d_to - timedelta(days=days - 1)
await m.answer(f"Сбор статистики за {days} дн...")
await m.answer(f"Сбор статистики за {pluralize(days, 'день', 'дня', 'дней')}...")
packages_data, bugs_data = await asyncio.gather(
altrepo.parser.news.packages_by_range(d_from, d_to),
......@@ -224,7 +224,7 @@ async def top_handler(m: Message, days: int | None = None) -> None:
d_to = datetime.now().date()
d_from = d_to - timedelta(days=days - 1)
await m.answer(f"Сбор статистики за {days} дн...")
await m.answer(f"Сбор статистики за {pluralize(days, 'день', 'дня', 'дней')}...")
packages_data = await altrepo.parser.news.packages_by_range(d_from, d_to)
if not packages_data:
......
......@@ -6,7 +6,7 @@ from collections import defaultdict
from altrepo.parser.models import PackagesModel, RemovedPackageElementModel
from config import PACKAGES_URL
from services.utils import translate_package, translate_maintainer, chunk_list
from services.utils import translate_package, translate_maintainer, chunk_list, pluralize
async def format_packages(packages: PackagesModel, news_type: str, translate: bool = False, date_range: str | None = None):
......@@ -42,7 +42,7 @@ async def format_packages(packages: PackagesModel, news_type: str, translate: bo
async def _format_removed(packages_model: PackagesModel, repo: str) -> str:
removed = packages_model.removed
lines = [f"Удалены: {len(removed)}"]
lines = [f"Удалено {pluralize(len(removed), 'пакет', 'пакета', 'пакетов')}:"]
for pkg in removed:
pkg_link = link(f"{repo}srpms/{pkg.name}", text=pkg.name)
lines.append(HTMLFormatter(bold(pkg_link)))
......@@ -67,7 +67,7 @@ async def _format_package_group(packages_model: PackagesModel, repo: str, transl
result_pages = []
for chunk in chunk_list(sorted_groups, 8):
lines = [f"{title} {total} пакетов, в том числе:"]
lines = [f"{title} {pluralize(total, 'пакет', 'пакета', 'пакетов')}, в том числе:"]
for (nick, name), maintainer_pkgs in chunk:
selected_pkgs = random.sample(maintainer_pkgs, min(15, len(maintainer_pkgs)))
......
......@@ -91,3 +91,14 @@ def int_validator(s: str) -> int | None:
if not s.isdigit():
return None
return int(s)
def pluralize(n: int, one: str, few: str, many: str) -> str:
n_abs = abs(n) % 100
if 11 <= n_abs <= 19:
return f"{n} {many}"
last = n_abs % 10
if last == 1:
return f"{n} {one}"
if 2 <= last <= 4:
return f"{n} {few}"
return f"{n} {many}"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment