diff --git a/aurweb/models/package_dependency.py b/aurweb/models/package_dependency.py index c4c5f6c1..44d9c839 100644 --- a/aurweb/models/package_dependency.py +++ b/aurweb/models/package_dependency.py @@ -1,3 +1,6 @@ +from typing import List + +from sqlalchemy import and_, literal from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import backref, relationship @@ -6,6 +9,7 @@ from aurweb.models.declarative import Base from aurweb.models.dependency_type import DependencyType as _DependencyType from aurweb.models.official_provider import OfficialProvider as _OfficialProvider from aurweb.models.package import Package as _Package +from aurweb.models.package_relation import PackageRelation class PackageDependency(Base): @@ -51,3 +55,24 @@ class PackageDependency(Base): official = db.query(_OfficialProvider).filter( _OfficialProvider.Name == self.DepName).exists() return db.query(pkg).scalar() or db.query(official).scalar() + + def provides(self) -> List[PackageRelation]: + from aurweb.models.relation_type import PROVIDES_ID + + rels = db.query(PackageRelation).join(_Package).filter( + and_(PackageRelation.RelTypeID == PROVIDES_ID, + PackageRelation.RelName == self.DepName) + ).with_entities( + _Package.Name, + literal(False).label("is_official") + ).order_by(_Package.Name.asc()) + + official_rels = db.query(_OfficialProvider).filter( + and_(_OfficialProvider.Provides == self.DepName, + _OfficialProvider.Name != self.DepName) + ).with_entities( + _OfficialProvider.Name, + literal(True).label("is_official") + ).order_by(_OfficialProvider.Name.asc()) + + return rels.union(official_rels).all() diff --git a/aurweb/packages/util.py b/aurweb/packages/util.py index 9a7b48d9..53af4446 100644 --- a/aurweb/packages/util.py +++ b/aurweb/packages/util.py @@ -5,18 +5,20 @@ from typing import Dict, List, Union import orjson from fastapi import HTTPException, Request -from sqlalchemy import and_, orm +from sqlalchemy import orm from aurweb import db, l10n, models, util from aurweb.models import Package, PackageBase, User from aurweb.models.official_provider import OFFICIAL_BASE, OfficialProvider from aurweb.models.package_comaintainer import PackageComaintainer from aurweb.models.package_dependency import PackageDependency -from aurweb.models.relation_type import PROVIDES_ID +from aurweb.models.package_relation import PackageRelation from aurweb.redis import redis_connection from aurweb.scripts import notify from aurweb.templates import register_filter +Providers = List[Union[PackageRelation, OfficialProvider]] + def dep_extra_with_arch(dep: models.PackageDependency, annotation: str) -> str: output = [annotation] @@ -77,27 +79,13 @@ def package_link(package: Union[Package, OfficialProvider]) -> str: return f"/packages/{package.Name}" -@register_filter("provides_list") -def provides_list(package: models.Package, depname: str) -> list: - providers = db.query(models.Package).join( - models.PackageRelation).join(models.RelationType).filter( - and_( - models.PackageRelation.RelName == depname, - models.RelationType.ID == PROVIDES_ID - ) - ) - - string = ", ".join([ +@register_filter("provides_markup") +def provides_markup(provides: Providers) -> str: + return ", ".join([ f'{pkg.Name}' - for pkg in providers + for pkg in provides ]) - if string: - # If we actually constructed a string, wrap it. - string = f"({string})" - - return string - def get_pkg_or_base( name: str, diff --git a/templates/partials/packages/package_metadata.html b/templates/partials/packages/package_metadata.html index 7f132c61..5f831711 100644 --- a/templates/partials/packages/package_metadata.html +++ b/templates/partials/packages/package_metadata.html @@ -1,23 +1,33 @@