mews.packages: improve text formatting

parent 81595ad4
...@@ -34,14 +34,14 @@ class NewsInfo: ...@@ -34,14 +34,14 @@ class NewsInfo:
if not url: if not url:
return None return None
html = await self.client.get(url, "koi8-r") html = await self.client.get(url, "koi8-r")
return await packages_parser(html) return await packages_parser(html, url)
async def p11(self) -> models.PackagesModel | None: async def p11(self) -> models.PackagesModel | None:
url = (await self.news_urls()).p11 url = (await self.news_urls()).p11
if not url: if not url:
return None return None
html = await self.client.get(url, "koi8-r") html = await self.client.get(url, "koi8-r")
return await packages_parser(html) return await packages_parser(html, url)
class ALTRepoParser: class ALTRepoParser:
......
...@@ -39,6 +39,7 @@ class PackageElementModel(BaseModel): ...@@ -39,6 +39,7 @@ class PackageElementModel(BaseModel):
class PackagesModel(BaseModel): class PackagesModel(BaseModel):
url: str
added: List[PackageElementModel] | None = None added: List[PackageElementModel] | None = None
removed: List[RemovedPackageElementModel] | None = None removed: List[RemovedPackageElementModel] | None = None
updated: List[PackageElementModel] | None = None updated: List[PackageElementModel] | None = None
...@@ -4,7 +4,7 @@ import re ...@@ -4,7 +4,7 @@ import re
from .. import models from .. import models
async def packages_parser(html: str): async def packages_parser(html: str, url: str):
soup = BeautifulSoup(html, "html.parser") soup = BeautifulSoup(html, "html.parser")
pre_tag = soup.find("pre") pre_tag = soup.find("pre")
if not pre_tag: if not pre_tag:
...@@ -68,6 +68,8 @@ async def packages_parser(html: str): ...@@ -68,6 +68,8 @@ async def packages_parser(html: str):
current_package["maintainer_nick"] = match.group(2).strip() current_package["maintainer_nick"] = match.group(2).strip()
if current_package and current_section: if current_package and current_section:
sections[current_section].append(current_package) sections[current_section].append(current_package)
sections["url"] = url
return models.PackagesModel(**sections) return models.PackagesModel(**sections)
......
...@@ -23,13 +23,15 @@ async def news_handler(m: Message, news_type: str | None, translate: str | None) ...@@ -23,13 +23,15 @@ async def news_handler(m: Message, news_type: str | None, translate: str | None)
packages_data = await altrepo.parser.news.sisyphus() packages_data = await altrepo.parser.news.sisyphus()
elif news_type == "p11": elif news_type == "p11":
packages_data = await altrepo.parser.news.p11() packages_data = await altrepo.parser.news.p11()
else:
return
if not packages_data: if not packages_data:
await m.answer("Новостей пока нет.") await m.answer("Новостей пока нет.")
return return
added, removed, updated = await format_packages(packages_data, bool(translate)) added, removed, updated, info_message = await format_packages(packages_data, bool(translate))
await m.answer(f"{added}{removed}") await m.answer(f"{added}{removed}{info_message}")
for msg in updated: for msg in updated:
res = await m.answer(msg) res = await m.answer(msg)
from telegrinder.tools.formatting import HTMLFormatter, link, bold from telegrinder.tools.formatting import HTMLFormatter, link, bold
import random
from collections import defaultdict
from altrepo.parser.models import PackagesModel, PackageElementModel, RemovedPackageElementModel from altrepo.parser.models import PackagesModel, PackageElementModel, RemovedPackageElementModel
from config import PACKAGES_URL from config import PACKAGES_URL
...@@ -8,6 +11,7 @@ from services.utils import translate_async, chunk_list ...@@ -8,6 +11,7 @@ from services.utils import translate_async, chunk_list
repo = PACKAGES_URL.format(repo="sisyphus") repo = PACKAGES_URL.format(repo="sisyphus")
async def format_packages(packages: PackagesModel, translate: bool | None = None): async def format_packages(packages: PackagesModel, translate: bool | None = None):
added_message = "" added_message = ""
...@@ -25,13 +29,18 @@ async def format_packages(packages: PackagesModel, translate: bool | None = None ...@@ -25,13 +29,18 @@ async def format_packages(packages: PackagesModel, translate: bool | None = None
removed_message += await _format_removed_package(package) removed_message += await _format_removed_package(package)
if packages.updated: if packages.updated:
for packages in chunk_list(packages.updated, 20): updated_messages = await _format_updated_packages(packages, translate)
updated_message = "Обновлены:\n"
for package in packages: info_message = (
updated_message += await _format_package(package, translate) "Источник: " +
updated_messages.append(updated_message) HTMLFormatter(link(packages.url, text="sisyphus-cybertalk")) +
"\n\n"
"Сформировано при помощи " +
HTMLFormatter(bold(link("https://t.me/altlinux_packages_bot", text="ALT Packages Bot")))
)
return added_message, removed_message, updated_messages, info_message
return added_message, removed_message, updated_messages
async def _format_package(package: PackageElementModel, translate: bool): async def _format_package(package: PackageElementModel, translate: bool):
message = HTMLFormatter( message = HTMLFormatter(
...@@ -40,10 +49,46 @@ async def _format_package(package: PackageElementModel, translate: bool): ...@@ -40,10 +49,46 @@ async def _format_package(package: PackageElementModel, translate: bool):
message += f"{(await translate_async(package.maintainer_name)) if translate else package.maintainer_name} ({package.maintainer_nick})\n\n" message += f"{(await translate_async(package.maintainer_name)) if translate else package.maintainer_name} ({package.maintainer_nick})\n\n"
return message return message
async def _format_removed_package(package: RemovedPackageElementModel): async def _format_removed_package(package: RemovedPackageElementModel):
message = HTMLFormatter( message = HTMLFormatter(
bold(link(f"{repo}srpms/{package.name}", text=package.name))) + "\n\n" bold(link(f"{repo}srpms/{package.name}", text=package.name))) + "\n\n"
return message return message
\ No newline at end of file
async def _format_updated_packages(packages_model: PackagesModel, translate: bool):
updated = packages_model.updated or []
total_updated = len(updated)
grouped = defaultdict(list)
for pkg in updated:
grouped[(pkg.maintainer_nick, pkg.maintainer_name)].append(pkg)
sorted_groups = sorted(grouped.items(), key=lambda x: x[0][0])
result_pages = []
for chunk in chunk_list(sorted_groups, 8):
lines = [f"Обновлено {total_updated} пакетов, в том числе:"]
for (nick, name), pkgs in chunk:
selected_pkgs = random.sample(pkgs, min(8, len(pkgs)))
maintainer_display = (
await translate_async(name) if translate else name
) + f" ({nick})"
for pkg in selected_pkgs:
description = (
await translate_async(pkg.description)
if translate else pkg.description
)
pkg_link = link(f"{repo}srpms/{pkg.name}", text=pkg.name)
pkg_name = HTMLFormatter(bold(pkg_link))
lines.append(f"{pkg_name} — {description}")
lines.append(f"* {maintainer_display}\n")
result_pages.append("\n".join(lines).strip())
return result_pages
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