list_repositories: добавлены пагинация и серверный фильтр полей

This commit is contained in:
2026-08-12 13:18:03 +03:00
parent 6720fb8e0a
commit 14fa6697c9
+65 -5
View File
@@ -1,7 +1,7 @@
""" """
title: Gitea Manager title: Gitea Manager
author: Claude author: Claude
version: 1.2.0 version: 1.3.0
description: Инструмент для управления Gitea из Open WebUI — создание и удаление репозиториев, организаций, файлов, веток, загрузка и безопасная распаковка ZIP-архивов. description: Инструмент для управления Gitea из Open WebUI — создание и удаление репозиториев, организаций, файлов, веток, загрузка и безопасная распаковка ZIP-архивов.
requirements: requests requirements: requests
""" """
@@ -70,9 +70,69 @@ class Tools:
"""Создать репозиторий внутри организации.""" """Создать репозиторий внутри организации."""
return self._request("POST", f"/orgs/{quote(org, safe='')}/repos", json={"name": name, "description": description, "private": private, "auto_init": auto_init}) return self._request("POST", f"/orgs/{quote(org, safe='')}/repos", json={"name": name, "description": description, "private": private, "auto_init": auto_init})
def list_repositories(self) -> str: def list_repositories(
"""Получить список репозиториев текущего пользователя.""" self,
return self._request("GET", "/user/repos") limit: int = 50,
page: int = 1,
sort: str = "updated",
fields: Optional[str] = "name,private,language,html_url,description,updated_at,default_branch",
) -> str:
"""
Получить список репозиториев текущего пользователя в компактном виде.
По умолчанию возвращает не весь JSON Gitea, а только краткий набор полей —
иначе ответ раздувается из-за permissions/url/настроек и обрезается в чате.
Если репозиториев больше, чем limit, в конце добавляется подсказка про page+1.
Args:
limit: максимум репозиториев на странице (1..100).
page: номер страницы (начиная с 1).
sort: сортировка — updated | created | alpha | size | id.
fields: список полей через запятую, которые нужно оставить.
Пустая строка — вернуть весь JSON как есть.
"""
safe_limit = max(1, min(int(limit or 50), 100))
safe_page = max(1, int(page or 1))
allowed_sort = {"updated", "created", "alpha", "size", "id"}
safe_sort = sort if sort in allowed_sort else "updated"
raw = self._request(
"GET",
"/user/repos",
params={"limit": safe_limit, "page": safe_page, "sort": safe_sort},
)
# Если Gitea вернула ошибку — _request отдаёт строку "Ошибка ...".
# Парсить как JSON нечего — возвращаем как есть.
if not raw or not raw.lstrip().startswith("["):
return raw
try:
repos = json.loads(raw)
except (ValueError, TypeError):
return raw
if not isinstance(repos, list):
return raw
# Пустой fields — режим «как раньше», отдаём весь JSON.
if not fields:
return raw
keep = {f.strip() for f in fields.split(",") if f.strip()}
compact = [
{k: r.get(k) for k in keep if isinstance(r, dict) and k in r}
for r in repos
if isinstance(r, dict)
]
hint = ""
if len(repos) >= safe_limit:
hint = (
f"\n\n[Есть ещё репозитории — вызови "
f"list_repositories(limit={safe_limit}, page={safe_page + 1})]"
)
return json.dumps(compact, ensure_ascii=False, indent=2) + hint
def get_repository_info(self, owner: str, repo: str) -> str: def get_repository_info(self, owner: str, repo: str) -> str:
"""Получить информацию о репозитории.""" """Получить информацию о репозитории."""
@@ -273,4 +333,4 @@ class Tools:
else: else:
if target.exists(): if target.exists():
target.unlink() target.unlink()
shutil.move(str(item), str(target)) shutil.move(str(item), str(target))