add profile and update start

parent 52d76ad8
...@@ -3,6 +3,7 @@ from urllib.parse import urlencode ...@@ -3,6 +3,7 @@ from urllib.parse import urlencode
from . import models from . import models
class BaseAPI: class BaseAPI:
BASE_URL = "https://rdb.altlinux.org/api" BASE_URL = "https://rdb.altlinux.org/api"
...@@ -16,7 +17,8 @@ class BaseAPI: ...@@ -16,7 +17,8 @@ class BaseAPI:
async def get(self, path: str, params: dict = None): async def get(self, path: str, params: dict = None):
url = f"{self.BASE_URL}/{path.lstrip('/')}" url = f"{self.BASE_URL}/{path.lstrip('/')}"
if params: if params:
query = urlencode({k: ",".join(v) if isinstance(v, list) else v for k, v in params.items()}) query = urlencode({k: ",".join(v) if isinstance(
v, list) else v for k, v in params.items()})
url += f"?{query}" url += f"?{query}"
async with self.session.get(url) as resp: async with self.session.get(url) as resp:
resp.raise_for_status() resp.raise_for_status()
...@@ -25,6 +27,7 @@ class BaseAPI: ...@@ -25,6 +27,7 @@ class BaseAPI:
async def close(self): async def close(self):
await self.session.close() await self.session.close()
class APIInfo: class APIInfo:
def __init__(self, client: BaseAPI): def __init__(self, client: BaseAPI):
self.client = client self.client = client
...@@ -34,10 +37,47 @@ class APIInfo: ...@@ -34,10 +37,47 @@ class APIInfo:
return models.APIVersion(**data) return models.APIVersion(**data)
class BugInfo:
def __init__(self, client: BaseAPI):
self.client = client
async def bugzilla_by_maintainer(self, maintainer_nickname: str, by_acl: str | None = None):
data = await self.client.get(
"/bug/bugzilla_by_maintainer",
{"maintainer_nickname": maintainer_nickname,
"by_acl": by_acl if by_acl else "none"}
)
return models.BugzillaInfoModel(**data)
class SiteInfo:
def __init__(self, client: BaseAPI):
self.client = client
async def all_maintainers(self, branch: str) -> models.AllMaintainersModel:
return await self.all_maintainers_with_nicknames(branch)
async def all_maintainers_with_nicknames(self, branch: str) -> models.AllMaintainersModel:
data = await self.client.get(
"/site/all_maintainers_with_nicknames",
{"branch": branch}
)
return models.AllMaintainersModel(**data)
async def maintainer_info(self, branch: str, maintainer_nickname: str) -> models.MaintainerInfoModel:
data = await self.client.get(
"/site/maintainer_info",
{"branch": branch, "maintainer_nickname": maintainer_nickname}
)
return models.MaintainerInfoModel(**data)
class PackagesAPI: class PackagesAPI:
def __init__(self): def __init__(self):
self._client = BaseAPI() self._client = BaseAPI()
self.api = APIInfo(self._client) self.api = APIInfo(self._client)
self.bug = BugInfo(self._client)
self.site = SiteInfo(self._client)
async def init(self): async def init(self):
await self._client.init() await self._client.init()
......
from pydantic import BaseModel from pydantic import BaseModel
from typing import List, Dict, Any
class APIVersion(BaseModel): class APIVersion(BaseModel):
name: str name: str
version: str version: str
description: str description: str
class AllMaintainersElementModel(BaseModel):
packager_name: str
packager_nickname: str
count_source_pkg: int
class MaintainerInfoModel(BaseModel):
request_args: Dict[str, Any]
information: AllMaintainersElementModel
class AllMaintainersModel(BaseModel):
request_args: Dict[str, Any]
length: int
maintainers: List[AllMaintainersElementModel]
class BugzillaInfoElementModel(BaseModel):
id: str
status: str
resolution: str
severity: str
product: str
version: str | None
platform: str | None
component: str
source_package_name: str
binary_package_name: str
reporter: str
summary: str
last_changed: str
class BugzillaInfoModel(BaseModel):
request_args: Dict[str, Any]
length: int
bugs: List[BugzillaInfoElementModel]
\ No newline at end of file
...@@ -9,3 +9,10 @@ class Config(BaseSettings): ...@@ -9,3 +9,10 @@ class Config(BaseSettings):
BOT_TOKEN: str BOT_TOKEN: str
config = Config() config = Config()
DEFAUIL_BRANCHES = [
"sisyphus",
"p11",
"p10",
"p9"
]
\ No newline at end of file
from . import start as start_keyboards
from telegrinder import Button, Keyboard
from config import DEFAUIL_BRANCHES
def default_branch_kb():
kb = Keyboard(one_time_keyboard=True)
for branch in DEFAUIL_BRANCHES:
kb.add(Button(branch))
kb.row()
return kb.get_markup()
from .models import User from .models import User
class UserMethod: class UserMethod:
@classmethod @classmethod
def add( def add(
cls, cls,
user_id: int, user_id: int,
maintainer: str, maintainer: str,
default_branch: str = "sisyphus",
): ):
"""создание записи пользователя""" """создание записи пользователя"""
if cls.get(user_id=user_id) is None: if cls.get(user_id=user_id) is None:
user = User(user_id=user_id, maintainer=maintainer) user = User(user_id=user_id, maintainer=maintainer,
default_branch=default_branch)
user.save() user.save()
return True return True
return False return False
...@@ -30,5 +33,6 @@ class UserMethod: ...@@ -30,5 +33,6 @@ class UserMethod:
user.delete_instance() user.delete_instance()
return True return True
class DB: class DB:
user = UserMethod user = UserMethod
...@@ -21,8 +21,11 @@ class BaseModel(Model): ...@@ -21,8 +21,11 @@ class BaseModel(Model):
class User(BaseModel): class User(BaseModel):
"""модель пользователя""" """модель пользователя"""
user_id = IntegerField() # id пользователя user_id = IntegerField() # id пользователя
maintainer = TextField() # никнейм сопровождающего maintainer = TextField() # никнейм сопровождающего
default_branch = TextField( # Репозитоий по умолчанию
default="sisyphus"
)
class Meta: class Meta:
table_name = "users" table_name = "users"
from telegrinder import Dispatch, Message
from telegrinder.rules import Command
from api import api
from api.models import BugzillaInfoModel
from database.models import User
dp = Dispatch()
@dp.message(Command("profile"))
async def info_handler(m: Message, user: User | None) -> None:
if user is None:
return
maintainer_data = await api.site.maintainer_info(user.default_branch, user.maintainer)
maintainer = maintainer_data.information
bugs_data: BugzillaInfoModel = await api.bug.bugzilla_by_maintainer(user.maintainer)
unresolved_bugs = [bug for bug in bugs_data.bugs if bug.status not in ["RESOLVED", "CLOSED"]]
await m.answer(
"Профиль:\n\n"
f"Сопровождающий: {maintainer.packager_name} ({maintainer.packager_nickname})\n"
f"Исходные пакеты: {maintainer.count_source_pkg}\n"
"\n"
f"Всего багов: {bugs_data.length}\n"
f"Открытых багов: {len(unresolved_bugs)}\n"
)
@dp.message(Command("menu"))
async def info_handler(m: Message, user: User | None) -> None:
return
\ No newline at end of file
...@@ -4,9 +4,15 @@ from telegrinder.rules import StartCommand, HasText ...@@ -4,9 +4,15 @@ from telegrinder.rules import StartCommand, HasText
from database.func import DB from database.func import DB
from database.models import User from database.models import User
from data.keyboards import start_keyboards
from api import api
from config import DEFAUIL_BRANCHES
dp = Dispatch() dp = Dispatch()
wm = WaiterMachine(dp) wm = WaiterMachine(dp)
@dp.message(StartCommand()) @dp.message(StartCommand())
async def start_handler(m: Message, user: User | None) -> None: async def start_handler(m: Message, user: User | None) -> None:
...@@ -14,15 +20,46 @@ async def start_handler(m: Message, user: User | None) -> None: ...@@ -14,15 +20,46 @@ async def start_handler(m: Message, user: User | None) -> None:
await m.answer( await m.answer(
"Введите никнейм сопровождающего:" "Введите никнейм сопровождающего:"
) )
msg, _ = await wm.wait(MESSAGE_FROM_USER, m.from_user.id, release=HasText()) api_data = await api.site.all_maintainers("sisyphus")
maintainer = msg.text.unwrap() while True:
msg, _ = await wm.wait(MESSAGE_FROM_USER, m.from_user.id, release=HasText())
maintainer = msg.text.unwrap().lower()
if any(_m.packager_nickname == maintainer for _m in api_data.maintainers):
await m.answer(
f"Вы выбрали {maintainer}"
)
DB.user.add(
m.from_user.id,
maintainer
)
break
else:
await m.answer(
f"Сопровождающий {maintainer} не найден.\n"
"Введите никнейм сопровождающего:"
)
await m.answer( await m.answer(
f"Вы выбрали {maintainer}" "Выберите репозиторий по умолчанию.",
) reply_markup=start_keyboards.default_branch_kb())
while True:
msg, _ = await wm.wait(MESSAGE_FROM_USER, m.from_user.id, release=HasText())
branch = msg.text.unwrap().lower()
if branch in DEFAUIL_BRANCHES:
await m.answer(
f"Вы выбрали {branch}"
)
break
else:
await m.answer(
f"Репозиторий {branch} не найден.\n"
"Выберите репозиторий по умолчанию.",
reply_markup=start_keyboards.default_branch_kb()
)
DB.user.add( DB.user.add(
m.from_user.id, m.from_user.id,
maintainer maintainer,
branch
) )
return
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