altrepo.parser: add news.sisyphus and news.p11 parsers

parent c79bf4a2
......@@ -6,6 +6,7 @@ import calendar
import re
from . import models
from .news import packages_parser
class BaseParser:
......@@ -121,9 +122,19 @@ class NewsInfo:
return models.BugsModel(**data)
async def sisyphus(self):
...
async def sisyphus(self) -> models.PackagesModel | None:
url = (await self.news_urls()).sisyphus
if not url:
return None
html = await self.client.get(url, "koi8-r")
return await packages_parser(html)
async def p11(self) -> models.PackagesModel | None:
url = (await self.news_urls()).p11
if not url:
return None
html = await self.client.get(url, "koi8-r")
return await packages_parser(html)
async def _get_bug_section_name(self, line: str) -> str:
line = line.lower()
......
......@@ -23,3 +23,21 @@ class BugsModel(BaseModel):
resolved: List[BugsElementModel] | None = None
reopened: List[BugsElementModel] | None = None
random: List[BugsElementModel] | None = None
class RemovedPackageElementModel(BaseModel):
name: str
version: str
class PackageElementModel(BaseModel):
name: str
description: str
maintainer_name: str
maintainer_nick: str
class PackagesModel(BaseModel):
added: List[PackageElementModel] | None = None
removed: List[RemovedPackageElementModel] | None = None
updated: List[PackageElementModel] | None = None
from .packages import packages_parser
from bs4 import BeautifulSoup
import re
from .. import models
async def packages_parser(html: str):
soup = BeautifulSoup(html, "html.parser")
pre_tag = soup.find("pre")
if not pre_tag:
return {}
text = pre_tag.get_text()
lines = text.strip().splitlines()
sections = {"added": [], "removed": [], "updated": []}
current_section = None
current_package = {}
for line in lines:
# Смена секции
if re.search(r"^\s*\d+\s+ADDED package[s]?", line):
if current_package and current_section:
sections[current_section].append(current_package)
current_section = "added"
current_package = {}
continue
elif re.search(r"^\s*\d+\s+REMOVED package[s]?", line):
if current_package and current_section:
sections[current_section].append(current_package)
current_section = "removed"
current_package = {}
continue
elif re.search(r"^\s*\d+\s+UPDATED packages[s]?", line):
if current_package and current_section:
sections[current_section].append(current_package)
current_section = "updated"
current_package = {}
continue
if current_section == "removed":
if line.strip():
parts = line.strip().split("\t")
if len(parts) == 2:
name, version = parts
sections["removed"].append({
"name": name.strip(),
"version": version.strip()
})
continue
match = re.match(r"^(\S+)\s+-\s+(.*)", line)
if match:
if current_package:
sections[current_section].append(current_package)
current_package = {}
current_package["name"] = match.group(1)
current_package["description"] = await _clean_description(match.group(2))
continue
match = re.match(
r"^\*\s+\w+\s+\w+\s+\d+\s+\d+\s+(.+?) <([a-z0-9._-]+) на altlinux>", line
)
if match and current_section != "removed":
if current_package:
current_package["maintainer_name"] = match.group(1).strip()
current_package["maintainer_nick"] = match.group(2).strip()
if current_package and current_section:
sections[current_section].append(current_package)
return models.PackagesModel(**sections)
async def _clean_description(desc: str):
desc = desc.strip()
desc = re.sub(r'\s+', ' ', desc)
desc = re.sub(r'\[\d+[KMG]?\]', '', desc).strip()
return desc
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