add search_file

parent 13f8b8b8
import aiohttp
from urllib.parse import urlencode
from typing import List
from . import models
......@@ -24,6 +26,13 @@ class BaseAPI:
resp.raise_for_status()
return await resp.json()
async def post(self, path: str, data: dict = None, json: dict = None):
url = f"{self.BASE_URL}/{path.lstrip('/')}"
async with self.session.post(url, data=data, json=json) as resp:
resp.raise_for_status()
return await resp.json()
async def close(self):
await self.session.close()
......@@ -37,14 +46,27 @@ class APIInfo:
return models.APIVersion(**data)
class PackagesetInfo:
class PackageInfo:
def __init__(self, client: BaseAPI):
self.client = client
async def packages_by_file_names(self, files: List[str], branch: str, arch: str | None = None) -> models.PackageByFileNameModel:
data = {"files": files,"branch": branch}
if arch:
data["arch"] = arch
data = await self.client.post("/package/packages_by_file_names", json=data)
return models.PackageByFileNameModel(**data)
class PackagesetInfo:
def __init__(self, client: BaseAPI):
self.client = client
async def active_packagesets(self) -> models.PackageSetActivePackageSetsModel:
data = await self.client.get("/packageset/active_packagesets")
return models.PackageSetActivePackageSetsModel(**data)
async def repository_statistics(self, branch: str | None = None) -> models.RepositoryStatisticsModel:
if branch:
data = await self.client.get("/packageset/repository_statistics", {"branch": branch})
......@@ -66,6 +88,26 @@ class BugInfo:
return models.BugzillaInfoModel(**data)
class FileInfo:
def __init__(self, client: BaseAPI):
self.client = client
async def packages_by_file(self, branch: str, file_name: str) -> models.FilePackagesByFileModel:
data = await self.client.get(
"/file/packages_by_file",
{"branch": branch, "file_name": file_name}
)
return models.FilePackagesByFileModel(**data)
async def search(self, branch: str, file_name: str, limit: int | None = None) -> models.FilesModel:
data = await self.client.get(
"/file/search",
{"branch": branch, "file_name": file_name,
"limit": limit if limit else 1000}
)
return models.FilesModel(**data)
class SiteInfo:
def __init__(self, client: BaseAPI):
self.client = client
......@@ -99,8 +141,10 @@ class PackagesAPI:
def __init__(self):
self._client = BaseAPI()
self.api = APIInfo(self._client)
self.package = PackageInfo(self._client)
self.packageset = PackagesetInfo(self._client)
self.bug = BugInfo(self._client)
self.file = FileInfo(self._client)
self.site = SiteInfo(self._client)
async def init(self):
......
......@@ -85,3 +85,47 @@ class BugzillaInfoModel(BaseModel):
request_args: Dict[str, Any]
length: int
bugs: List[BugzillaInfoElementModel]
class FilePackagesByFileElementModel(BaseModel):
hash: str
name: str
version: str
release: str
arch: str
class FilePackagesByFileModel(BaseModel):
request_args: Dict[str, Any]
length: int
packages: List[FilePackagesByFileElementModel]
class PackageByFileNameElementModel(BaseModel):
name: str
version: str
release: str
disttag: str
sha1: str
branch: str
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
file_class: str
symlink: str
file_mode: str
class FilesModel(BaseModel):
request_args: Dict[str, Any]
length: int
files: List[FilesElementModel]
\ No newline at end of file
from telegrinder import MESSAGE_FROM_USER, Dispatch, Message, WaiterMachine, CallbackQuery
from telegrinder.rules import Command, PayloadEqRule, Text, IsUser, Markup, Argument
from telegrinder.tools.formatting import HTMLFormatter, link, bold
from aiohttp import ClientResponseError
from database.models import User
from collections import defaultdict
from api import api
from api.models import FilesModel, PackageByFileNameModel
dp = Dispatch()
wm = WaiterMachine(dp)
@dp.message(Command("search_file", Argument("file_name"), Argument("branch", optional=True)))
async def search_file_handler(m: Message, user: User | None, file_name: str, branch: str | None = None) -> None:
if not len(file_name):
return
if not branch:
branch = user.default_branch \
if user.default_branch \
else (await api.packageset.active_packagesets()).packagesets[0]
try:
search_file_data = await api.file.packages_by_file(branch, file_name)
except ClientResponseError:
await m.answer("Ничего не найдено.")
return
search_file_message = "Пакеты:\n\n"
for package in search_file_data.packages:
search_file_message += f"{package.arch} | {package.name} | {package.version}-{package.release}\n"
await m.answer(
search_file_message
)
"""
@dp.message(Command("test_search_file", Argument("file_name"), Argument("branch", optional=True), Argument("pattern", optional=True)))
async def search_file_handler(m: Message, user: User | None, file_name: str, branch: str | None = None, pattern: str | None = None) -> None:
if not len(file_name):
return
if not branch:
branch = user.default_branch \
if user.default_branch \
else (await api.packageset.active_packagesets()).packagesets[0]
try:
search_file_data: FilesModel = await api.file.search(branch, file_name)
except ClientResponseError:
await m.answer("Ничего не найдено.")
return
list_files = [file.file_name for file in search_file_data.files]
search_packages_data: PackageByFileNameModel = await api.package.packages_by_file_names(
list_files, branch, "x86_64"
)
grouped = defaultdict(set)
for pkg in search_packages_data.packages:
key = f"{pkg.name}"
for f in pkg.files:
grouped[key].add(f)
grouped = {k: sorted(v) for k, v in grouped.items()}
search_file_message = "Пакеты:\n\n"
for pkg, files in grouped.items():
if "devel" in pkg and pattern != "devel":
continue
if (pattern and pattern in pkg) or not pattern:
search_file_message += HTMLFormatter(bold(
link(f"https://packages.altlinux.org/ru/{branch}/srpms/{pkg}", text=pkg))) + ":\n"
for i, file in enumerate(files):
search_file_message += f" {file}\n"
if i == 9:
search_file_message += "...\n"
break
search_file_message += "\n"
res = await m.answer(search_file_message)
print(res)
"""
......@@ -27,7 +27,7 @@ async def profile_handler(m: Message, user: User | None, branch: str | None = No
if user:
branch = user.default_branch
else:
branch = (await api.packageset.active_packagesets())[0]
branch = active_branches[0]
statistics_data = (await api.packageset.repository_statistics(branch)).branches[0]
......
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