altrepo: make module configurable with ALTRepoConfig dataclass

parent a4016de2
......@@ -2,30 +2,28 @@ import aiohttp
from .api import ALTRepoAPI
from .appstream import ALTRepoAppStream
from .config import ALTRepoConfig
from .parser import ALTRepoParser
class ALTRepo:
def __init__(self):
def __init__(self, config: ALTRepoConfig | None = None):
self.config = config or ALTRepoConfig()
self._session: aiohttp.ClientSession | None = None
self.api: ALTRepoAPI | None = None
self.appstream: ALTRepoAppStream | None = None
self.parser: ALTRepoParser | None = None
async def init(
self,
appstream_dir: str = "appstream"
):
async def init(self, session: aiohttp.ClientSession | None = None):
if self._session is None:
self._session = aiohttp.ClientSession()
self.api = ALTRepoAPI(self._session)
self.appstream = ALTRepoAppStream(self._session, appstream_dir)
self.parser = ALTRepoParser(self._session)
self._session = session or aiohttp.ClientSession()
self.api = ALTRepoAPI(self._session, self.config)
self.appstream = ALTRepoAppStream(self._session, self.config)
self.parser = ALTRepoParser(self._session, self.config)
async def close(self):
await self._session.close()
altrepo = ALTRepo()
__all__ = ("altrepo")
__all__ = ("ALTRepo", "ALTRepoConfig")
......@@ -8,10 +8,10 @@ from . import errors
class BaseAPI:
BASE_URL = "https://rdb.altlinux.org/api"
def __init__(self, session: aiohttp.ClientSession):
def __init__(self, session: aiohttp.ClientSession, base_url: str):
self.session = session
self.BASE_URL = base_url
async def _handle_response(self, resp: aiohttp.ClientResponse):
......@@ -1813,9 +1813,9 @@ class VulnInfo:
class ALTRepoAPI:
def __init__(self, session: aiohttp.ClientSession):
def __init__(self, session: aiohttp.ClientSession, config: "ALTRepoConfig"):
self.BASE_API_VERSION = "1.25.6"
self._client = BaseAPI(session)
self._client = BaseAPI(session, config.api_base_url)
self.api = APIInfo(self._client)
self.task = TaskInfo(self._client)
self.package = PackageInfo(self._client)
......
......@@ -5,13 +5,10 @@ from lxml import etree
class AppStreamClient:
BASE_URL = (
"https://git.altlinux.org/gears/a/appstream-data-desktop.git?"
"a=blob_plain;f=xmls/altlinux.xml;hb=refs/heads/{}"
)
def __init__(self, session: aiohttp.ClientSession):
def __init__(self, session: aiohttp.ClientSession, appstream_url: str):
self.session = session
self._appstream_url = appstream_url
async def _handle_response(self, resp: aiohttp.ClientResponse):
......@@ -22,7 +19,7 @@ class AppStreamClient:
return None
async def get(self, branch: str) -> str | None:
url = self.BASE_URL.format(branch)
url = self._appstream_url.format(branch=branch)
async with self.session.get(url) as resp:
return await self._handle_response(resp)
......@@ -99,14 +96,14 @@ class PackageInfo:
class ALTRepoAppStream:
BRANCHES = ["sisyphus", "p11"]
def __init__(self, session: aiohttp.ClientSession, appstream_dir: str):
self._client = AppStreamClient(session)
self.data = DataInfo(self._client, appstream_dir)
def __init__(self, session: aiohttp.ClientSession, config: "ALTRepoConfig"):
self.branches = config.appstream_branches
self._client = AppStreamClient(session, config.appstream_url)
self.data = DataInfo(self._client, config.appstream_dir)
self.package = PackageInfo(self._client, self.data)
self.data._on_update = self.package.rebuild_cache
for branch in self.BRANCHES:
for branch in self.branches:
if self.data.has_file(branch):
self.package.rebuild_cache(branch)
from dataclasses import dataclass, field
@dataclass
class ALTRepoConfig:
api_base_url: str = "https://rdb.altlinux.org/api"
cybertalk_url: str = "https://lists.altlinux.org/pipermail/sisyphus-cybertalk/{}/"
ftbfs_url: str = "https://git.altlinux.org/beehive/stats/Sisyphus-x86_64/ftbfs-joined"
watch_url: str = "https://watch.altlinux.org/pub/watch/{by_acl}/{nickname}.txt"
appstream_url: str = (
"https://git.altlinux.org/gears/a/appstream-data-desktop.git?"
"a=blob_plain;f=xmls/altlinux.xml;hb=refs/heads/{branch}"
)
appstream_branches: list[str] = field(default_factory=lambda: ["sisyphus", "p11"])
appstream_dir: str = "appstream"
......@@ -25,11 +25,12 @@ class BaseParser:
class NewsInfo:
def __init__(self, client: BaseParser):
def __init__(self, client: BaseParser, cybertalk_url: str):
self.client = client
self._cybertalk_url = cybertalk_url
async def news_urls(self) -> models.NewsURL:
return await urls_parser(self.client)
return await urls_parser(self.client, self._cybertalk_url)
async def _get_packages(self, branch: str) -> models.PackagesModel | None:
url = getattr(await self.news_urls(), branch, None)
......@@ -57,7 +58,7 @@ class NewsInfo:
async def bugs_by_range(
self, date_from: date, date_to: date
) -> dict[str, int] | None:
urls = await urls_for_range(self.client, date_from, date_to, "bugs")
urls = await urls_for_range(self.client, date_from, date_to, self._cybertalk_url, "bugs")
if not urls:
return None
......@@ -83,7 +84,7 @@ class NewsInfo:
async def packages_by_range(
self, date_from: date, date_to: date
) -> models.PackagesModel | None:
urls = await urls_for_range(self.client, date_from, date_to)
urls = await urls_for_range(self.client, date_from, date_to, self._cybertalk_url)
if not urls:
return None
......@@ -145,12 +146,13 @@ def _aggregate_packages(
class PackagesInfo:
def __init__(self, client: BaseParser):
def __init__(self, client: BaseParser, ftbfs_url: str, watch_url: str):
self.client = client
self._ftbfs_url = ftbfs_url
self._watch_url = watch_url
async def ftbfs(self) -> List[models.FTBFSModel]:
url = "https://git.altlinux.org/beehive/stats/Sisyphus-x86_64/ftbfs-joined"
text = await self.client.get(url)
text = await self.client.get(self._ftbfs_url)
return ftbfs_parser(text)
async def watch_by_maintainer(
......@@ -158,7 +160,7 @@ class PackagesInfo:
maintainer_nickname: str,
by_acl: Literal["by-acl", "by-expanded-acl", "by-expanded-leader", "by-leader"],
) -> List[models.WatchByMaintainerModel]:
url = f"https://watch.altlinux.org/pub/watch/{by_acl}/{maintainer_nickname}.txt"
url = self._watch_url.format(by_acl=by_acl, nickname=maintainer_nickname)
try:
text = await self.client.get(url)
return watch_parser(text)
......@@ -167,7 +169,7 @@ class PackagesInfo:
class ALTRepoParser:
def __init__(self, session: aiohttp.ClientSession):
def __init__(self, session: aiohttp.ClientSession, config: "ALTRepoConfig"):
self._client = BaseParser(session)
self.news = NewsInfo(self._client)
self.packages = PackagesInfo(self._client)
self.news = NewsInfo(self._client, config.cybertalk_url)
self.packages = PackagesInfo(self._client, config.ftbfs_url, config.watch_url)
......@@ -5,15 +5,12 @@ from datetime import datetime, date
from .. import models
from config import CYBERTALK_URL
async def urls_parser(client):
async def urls_parser(client, cybertalk_url: str):
now = datetime.now()
year_month = f"{now.year}-{now.strftime("%B")}"
today = now.strftime("%Y%m%d")
base_url = CYBERTALK_URL.format(year_month)
base_url = cybertalk_url.format(year_month)
html = await client.get(f"{base_url}date.html", "koi8-r")
soup = BeautifulSoup(html, "html.parser")
......@@ -42,7 +39,8 @@ async def urls_parser(client):
async def urls_for_range(
client, date_from: date, date_to: date, news_type: str = "packages"
client, date_from: date, date_to: date,
cybertalk_url: str, news_type: str = "packages",
) -> list[tuple[date, str]]:
results = []
pattern = re.compile(rf"Sisyphus-(\d{{8}}) {re.escape(news_type)}")
......@@ -50,7 +48,7 @@ async def urls_for_range(
current = date_from.replace(day=1)
while current <= date_to:
year_month = f"{current.year}-{current.strftime('%B')}"
base_url = CYBERTALK_URL.format(year_month)
base_url = cybertalk_url.format(year_month)
try:
html = await client.get(f"{base_url}date.html", "koi8-r")
except:
......
......@@ -5,6 +5,8 @@ from telegrinder.tools.formatting import HTMLFormatter
from pydantic_settings import BaseSettings, SettingsConfigDict
from altrepo import ALTRepo
from typing import List
......@@ -19,6 +21,7 @@ class Config(BaseSettings):
config = Config()
altrepo = ALTRepo()
DEFAUIL_BRANCHES = [
"sisyphus",
......@@ -37,7 +40,6 @@ APPSTREAM_SKIP_LIST = [
TASK_URL = "https://packages.altlinux.org/ru/tasks/"
BUGS_URL = "https://bugzilla.altlinux.org/"
PACKAGES_URL = "https://packages.altlinux.org/ru/{repo}/"
CYBERTALK_URL = "https://lists.altlinux.org/pipermail/sisyphus-cybertalk/{}/"
INSTALL_APP_URL = "https://appstream.k8s.eterfund.ru/app/{app_id}/"
# ====== BOT
......
......@@ -2,7 +2,7 @@ from telegrinder import Dispatch, Message, CallbackQuery
from telegrinder.rules import Command, Argument, Text, IsPrivate, CallbackDataMarkup
from telegrinder.tools.formatting import HTMLFormatter
from altrepo import altrepo
from config import altrepo
from config import BUGS_URL
from database.models import User
......
from telegrinder import Dispatch, Message, CallbackQuery
from telegrinder.rules import Command, Argument, CallbackDataMarkup
from altrepo import altrepo
from config import altrepo
from altrepo.api.errors import DataNotFoundError, RequestValidationError
from database.models import User
......
from telegrinder import Dispatch, Message
from telegrinder.rules import Command, Argument
from altrepo import altrepo
from config import altrepo
from database.models import User
from database.func import DB
......
......@@ -2,7 +2,7 @@ from telegrinder import Dispatch, Message
from telegrinder.rules import Command
from telegrinder.tools.formatting import HTMLFormatter, link
from altrepo import altrepo
from config import altrepo
from database.func import DB
from services.utils import _bold
from config import bot_repositories, bot_developers
......
......@@ -5,7 +5,7 @@ from telegrinder.rules import Command, Argument, CallbackDataMarkup, Text, IsPri
from datetime import datetime, timedelta
from altrepo import altrepo
from config import altrepo
from services.news import format_packages, format_bugs
from services.utils import _bold, int_validator, pluralize
......
......@@ -3,7 +3,7 @@ from telegrinder.rules import Command, Argument
from telegrinder.tools.formatting import HTMLFormatter, link
from altrepo import altrepo
from config import altrepo
from altrepo.api.errors import DataNotFoundError, RequestValidationError
from data.keyboards import package_keyboards
......
......@@ -10,7 +10,7 @@ from database.func import DB
from data.keyboards import profile_keyboards
from modules import scheduler
from altrepo import altrepo
from config import altrepo
from services.menu import send_menu
from services.utils import _bold
......
......@@ -8,7 +8,7 @@ from services.utils import _bold
from database.models import User
from collections import defaultdict
from altrepo import altrepo
from config import altrepo
dp = Dispatch()
wm = WaiterMachine(dp)
......
......@@ -3,7 +3,7 @@ from telegrinder.rules import Command, Text, IsPrivate, Argument
from datetime import datetime
from altrepo import altrepo
from config import altrepo
from database.models import User
from services.utils import _bold
......
......@@ -3,7 +3,7 @@ from telegrinder.rules import Command, Argument, CallbackDataMarkup
from telegrinder.tools.formatting import HTMLFormatter, code_inline
from altrepo import altrepo
from config import altrepo
from altrepo.api.errors import DataNotFoundError
from database.models import User
......
......@@ -2,7 +2,7 @@ from telegrinder import Dispatch, Message, CallbackQuery
from telegrinder.rules import Command, Argument, Text, IsPrivate, CallbackDataMarkup
from telegrinder.tools.formatting import HTMLFormatter
from altrepo import altrepo
from config import altrepo
from database.models import User
from data.keyboards import watch_keyboards
......
......@@ -3,10 +3,10 @@ from telegrinder.modules import logger
from telegrinder.types import BotCommand
from telegrinder.node import Error
from config import tg_api
from config import tg_api, altrepo
from modules import scheduler
from altrepo import altrepo
from altrepo.api.errors import TooManyRequests
from database.models import db, Maintainer, User, Package, ScheduledTask
from middlewares import UserMiddleware
......
......@@ -2,21 +2,19 @@ import asyncio
from telegrinder.modules import logger
from altrepo import altrepo
BRANCHES = ["sisyphus", "p11"]
from config import altrepo
async def update_appstream_data():
branches = altrepo.appstream.branches
results = await asyncio.gather(*(
altrepo.api.package.package_info(
"appstream-data-desktop", branch=branch, source=True
)
for branch in BRANCHES
for branch in branches
))
for branch, result in zip(BRANCHES, results):
for branch, result in zip(branches, results):
package = result.packages[0]
current_version = altrepo.appstream.data.get_current_version(branch)
package_version = f"{package.version}-{package.release}"
......
......@@ -2,7 +2,7 @@ from telegrinder.tools.formatting import HTMLFormatter
from config import tg_api
from altrepo import altrepo
from config import altrepo
from database.models import User
from data.keyboards import bugs_keyboards
......
from telegrinder.modules import logger
from config import config, tg_api
from altrepo import altrepo
from config import altrepo
async def test_api_version():
......
from telegrinder.modules import logger
from altrepo import altrepo
from config import altrepo
from database.func import DB
async def update_maintainers():
......
......@@ -2,7 +2,7 @@ from telegrinder.tools.formatting import HTMLFormatter
from config import tg_api
from altrepo import altrepo
from config import altrepo
from database.models import User
from data.keyboards import watch_keyboards
......
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