add package module

parent e12aa616
import aiohttp
from urllib.parse import urlencode
from typing import List
from typing import List, Literal
from . import models
from . import errors
......@@ -19,9 +19,11 @@ class BaseAPI:
case 200 | 201:
return await resp.json()
case 400:
raise errors.RequestValidationError("Request parameters validation error (400)")
raise errors.RequestValidationError(
"Request parameters validation error (400)")
case 404:
raise errors.DataNotFoundError("Requested data not found in database (404)")
raise errors.DataNotFoundError(
"Requested data not found in database (404)")
case 429:
raise errors.TooManyRequests("Too Many Requests (429)")
case _:
......@@ -60,9 +62,41 @@ class PackageInfo:
def __init__(self, client: BaseAPI):
self.client = client
async def package_info(
self,
name: str | None = None,
version: str | None = None,
release: str | None = None,
arch: str | None = None,
source: bool | None = None,
branch: str | None = None,
disttag: str | None = None,
sha1: str | None = None,
packager: str | None = None,
packager_email: str | None = None,
full: bool | None = None,
) -> models.PackageInfoModel:
params = {
k: v for k, v in {
"name": name,
"version": version,
"release": release,
"arch": arch,
"source": source,
"branch": branch,
"disttag": disttag,
"sha1": sha1,
"packager": packager,
"packager_email": packager_email,
"full": full,
}.items() if v is not None
}
data = await self.client.get("/package/package_info", params)
return models.PackageInfoModel(**data)
async def packages_by_file_names(self, files: List[str], branch: str, arch: str | None = None) -> models.PackageByFileNameModel:
data = {"files": files,"branch": branch}
data = {"files": files, "branch": branch}
if arch:
data["arch"] = arch
......@@ -89,7 +123,7 @@ class PackagesetInfo:
class AclInfo:
def __init__(self, client: BaseAPI):
self.client = client
async def groups(self, branch: str, name: str | None = None):
data = {"branch": branch}
if name:
......@@ -101,6 +135,7 @@ class AclInfo:
)
return models.AclGroupsModel(**data)
class BugInfo:
def __init__(self, client: BaseAPI):
self.client = client
......@@ -153,6 +188,13 @@ class SiteInfo:
)
return models.AllMaintainersModel(**data)
async def find_source_package(self, branch: str, name: str) -> models.FindSourcePackageInBranch:
data = await self.client.get(
"/site/find_source_package",
{"branch": branch, "name": name}
)
return models.FindSourcePackageInBranch(**data)
async def maintainer_info(self, branch: str, maintainer_nickname: str) -> models.MaintainerInfoModel:
data = await self.client.get(
"/site/maintainer_info",
......@@ -160,6 +202,26 @@ class SiteInfo:
)
return models.MaintainerInfoModel(**data)
async def package_info(
self,
branch: str,
pkghash: int,
changelog_last: int = 3,
package_type: Literal["source", "binary"] = "source"
) -> models.SitePackageInfoModel:
data = await self.client.get(
f"/site/package_info/{pkghash}",
{"branch": branch, "changelog_last": changelog_last, "package_type": package_type}
)
return models.SitePackageInfoModel(**data)
async def pkghash_by_name(self, branch: str, name: str) -> models.SitePackagesetPackageHashModel:
data = await self.client.get(
"/site/pkghash_by_name",
{"branch": branch, "name": name}
)
return models.SitePackagesetPackageHashModel(**data)
async def watch_by_maintainer(self, maintainer_nickname: str) -> models.SiteWatchByMaintainerModel | None:
try:
data = await self.client.get(
......@@ -173,7 +235,7 @@ class SiteInfo:
class ALTRepoAPI:
def __init__(self, session: aiohttp.ClientSession):
self.BASE_API_VERSION = "1.19.32"
self.BASE_API_VERSION = "1.19.34"
self._client = BaseAPI(session)
self.api = APIInfo(self._client)
self.package = PackageInfo(self._client)
......@@ -182,6 +244,6 @@ class ALTRepoAPI:
self.bug = BugInfo(self._client)
self.file = FileInfo(self._client)
self.site = SiteInfo(self._client)
async def version(self) -> models.APIVersion:
return await self.api.version()
......@@ -101,6 +101,82 @@ class FilePackagesByFileModel(BaseModel):
packages: List[FilePackagesByFileElementModel]
class PackageInfoChangelogElementModel(BaseModel):
date: str | None
name: str | None
evr: str | None
message: str | None
class PackageInfoDependenciesModel(BaseModel):
require: List[str] | None
provide: List[str] | None
conflict: List[str] | None
obsolete: List[str] | None
class PackageInfoPackageModel(BaseModel):
name: str
version: str
release: str
sha1: str
packager: str
packager_email: str
arch: str
epoch: int
disttag: str
sourcepackage: int
filename: str
sourcerpm: str
serial: int | None
buildtime: int | None
buildhost: str | None
size: int | None
archivesize: int | None
filesize: int | None
rpmversion: str | None
cookie: str | None
license: str | None
group: str | None
url: str | None
summary: str | None
description: str | None
distribution: str | None
vendor: str | None
os: str | None
gif: str | None
xpm: str | None
icon: str | None
prein: str | None
postin: str | None
preun: str | None
postun: str | None
preinprog: List[str] | None
postinprog: List[str] | None
preunprog: List[str] | None
postunprog: List[str] | None
buildarchs: List[str] | None
verifyscript: str | None
verifyscriptprog: List[str] | None
prefixes: List[str] | None
instprefixes: List[str] | None
optflags: str | None
disturl: str | None
payloadformat: str | None
payloadcompressor: str | None
payloadflags: str | None
platform: str | None
changelog: List[PackageInfoChangelogElementModel] | PackageInfoChangelogElementModel
files: List[str] | None
depends: List[PackageInfoDependenciesModel] | PackageInfoDependenciesModel
class PackageInfoModel(BaseModel):
request_args: Dict[str, Any]
length: int
packages: List[PackageInfoPackageModel]
class PackageByFileNameElementModel(BaseModel):
name: str
version: str
......@@ -111,12 +187,14 @@ class PackageByFileNameElementModel(BaseModel):
arch: str
files: List[str]
class PackageByFileNameModel(BaseModel):
request_args: Dict[str, Any]
length: int
packages: List[PackageByFileNameElementModel]
not_found: List[str]
class FilesElementModel(BaseModel):
file_name: str
file_hashname: str
......@@ -141,3 +219,95 @@ class AclGroupsModel(BaseModel):
request_args: Dict[str, Any]
length: int
groups: List[AclGroupsElementModel]
class SitePackageInfoArchsModel(BaseModel):
name: str
archs: list[str]
pkghash: list[str]
class SitePackageTasksElementModel(BaseModel):
type: str
id: int
date: str
class SitePackageInfoChangelogElementModel(BaseModel):
date: str
name: str
nick: str
evr: str
message: str
class SitePackageNewVersionModel(BaseModel):
task_id: int
date: str
pkghash: str
version: str
release: str
class SitePackageBeehiveElementModel(BaseModel):
arch: str
status: str
updated: str
build_time: float
ftbfs_since: str
url: str
class SitePackageDependenciesElementModel(BaseModel):
name: str
version: str
type: str
flag: int
flag_decoded: List[str]
class SitePackageLicenseTokensElementModel(BaseModel):
token: str
license: str
class SitePackageInfoModel(BaseModel):
pkghash: str
request_args: Dict[str, Any]
name: str
version: str
release: str
arch: str
buildtime: int
task: int
task_date: str
gear: str
license: str
category: str
url: str
vcs: str
summary: str
description: str
packager: str
packager_nickname: str
acl: List[str]
maintainers: List[str]
package_archs: List[SitePackageInfoArchsModel]
tasks: List[SitePackageTasksElementModel]
changelog: List[SitePackageInfoChangelogElementModel]
new_version: List[SitePackageNewVersionModel]
beehive: List[SitePackageBeehiveElementModel]
dependencies: List[SitePackageDependenciesElementModel]
license_tokens: List[SitePackageLicenseTokensElementModel]
class SitePackagesetPackageHashModel(BaseModel):
request_args: Dict[str, Any]
pkghash: str
version: str
release: str
class FindSourcePackageInBranch(BaseModel):
request_args: Dict[str, Any]
source_package: str
from telegrinder import Dispatch, Message
from telegrinder.rules import Command, Argument, Text, IsUser
from telegrinder.tools.formatting import HTMLFormatter
from datetime import datetime
from altrepo import altrepo
from altrepo.api.errors import DataNotFoundError
from database.models import User
from database.func import DB
from data.keyboards import watch_keyboards
from services.utils import _bold
dp = Dispatch()
@dp.message(
Command("package",
Argument("name", optional=True),
Argument("branch", optional=True),
Argument("arch", optional=True),
)
)
async def package_info_handler(
m: Message,
name: str | None = None,
branch: str | None = None,
arch: str | None = None
) -> None:
if name is None:
await m.answer("Не указано имя пакета")
return
branch = branch or "sisyphus"
try:
package_data = await altrepo.api.package.package_info(
name=name,
branch=branch,
source=False if arch else True,
arch=arch or None,
full=True
)
package = package_data.packages[0]
except:
await m.answer("Не удалось найти пакет.")
return
buildtime = datetime.fromtimestamp(package.buildtime).strftime("%Y-%m-%d %H:%M:%S")
packager = DB.maintainer.get(package.packager_email.split("@")[0])
if arch:
sourse_package = (await altrepo.api.site.find_source_package(
branch, package.name
)).source_package
if not arch:
pkghash = (await altrepo.api.site.pkghash_by_name(branch, package.name)).pkghash
binary_packages = await altrepo.api.site.package_info(branch, pkghash)
binary_packages_message = _bold("\n\nБинарные пакеты:\n")
for binary_package in binary_packages.package_archs:
binary_packages_message += f" {binary_package.name}"
binary_packages_message += f" ({", ".join(binary_package.archs)})\n"
_package = DB.package.get(package.name)
if _package and _package.summary_ru:
summary = _package.summary_ru
else:
summary = package.summary
message = (
f"{_bold("Пакет " + package.name)}\n\n"
f"Версия: {package.version}-{package.release}\n"
f"{f"Архитектура: {package.arch}\n" if arch else ""}"
f"Собран: {buildtime}\n"
f"{f"Исходный пакет: {sourse_package}\n" if arch else ""}"
f"Сопровождающий: {packager.name_ru} ({packager.nickname})\n\n"
f"Категория: {package.group}\n"
f"Домашняя страница: {package.url}\n"
f"Лицензия: {package.license}\n\n"
f"{_bold("О пакете:")}\n"
f"{summary}"
f"{f"{binary_packages_message}" if not arch else ""}"
)
await m.answer(message)
\ No newline at end of file
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