Merge branch 'master' into live

This commit is contained in:
Kevin Morris 2022-03-31 17:54:21 -07:00
commit 6082cd8809
No known key found for this signature in database
GPG key ID: F7E46DED420788F3
9 changed files with 127 additions and 18 deletions

View file

@ -6,7 +6,7 @@ from typing import Any
# Publicly visible version of aurweb. This is used to display
# aurweb versioning in the footer and must be maintained.
# Todo: Make this dynamic/automated.
AURWEB_VERSION = "v6.0.26"
AURWEB_VERSION = "v6.0.27"
_parser = None

View file

@ -214,7 +214,7 @@ def query_notified(query: List[models.Package],
return output
def pkg_required(pkgname: str, provides: List[str], limit: int) \
def pkg_required(pkgname: str, provides: List[str]) \
-> List[PackageDependency]:
"""
Get dependencies that match a string in `[pkgname] + provides`.
@ -227,8 +227,8 @@ def pkg_required(pkgname: str, provides: List[str], limit: int) \
targets = set([pkgname] + provides)
query = db.query(PackageDependency).join(Package).filter(
PackageDependency.DepName.in_(targets)
).order_by(Package.Name.asc()).limit(limit)
return query.all()
).order_by(Package.Name.asc())
return query
@register_filter("source_uri")

View file

@ -11,16 +11,25 @@ from aurweb.models.package_request import PENDING_ID, PackageRequest
from aurweb.models.package_vote import PackageVote
from aurweb.scripts import notify
from aurweb.templates import make_context as _make_context
from aurweb.templates import make_variable_context as _make_variable_context
def make_context(request: Request, pkgbase: PackageBase) -> Dict[str, Any]:
async def make_variable_context(request: Request, pkgbase: PackageBase) \
-> Dict[str, Any]:
ctx = await _make_variable_context(request, pkgbase.Name)
return make_context(request, pkgbase, ctx)
def make_context(request: Request, pkgbase: PackageBase,
context: Dict[str, Any] = None) -> Dict[str, Any]:
""" Make a basic context for package or pkgbase.
:param request: FastAPI request
:param pkgbase: PackageBase instance
:return: A pkgbase context without specific differences
"""
context = _make_context(request, pkgbase.Name)
if not context:
context = _make_context(request, pkgbase.Name)
context["git_clone_uri_anon"] = config.get("options", "git_clone_uri_anon")
context["git_clone_uri_priv"] = config.get("options", "git_clone_uri_priv")

View file

@ -2,7 +2,7 @@ from collections import defaultdict
from http import HTTPStatus
from typing import Any, Dict, List
from fastapi import APIRouter, Form, Request, Response
from fastapi import APIRouter, Form, Query, Request, Response
import aurweb.filters # noqa: F401
@ -33,7 +33,7 @@ async def packages_get(request: Request, context: Dict[str, Any],
context["O"] = offset
# Limit PP to options.max_search_results
max_search_results = aurweb.config.getint("options", "max_search_results")
max_search_results = config.getint("options", "max_search_results")
context["PP"] = per_page = min(per_page, max_search_results)
# Query search by.
@ -123,7 +123,22 @@ async def packages(request: Request) -> Response:
@router.get("/packages/{name}")
async def package(request: Request, name: str) -> Response:
async def package(request: Request, name: str,
all_deps: bool = Query(default=False),
all_reqs: bool = Query(default=False)) -> Response:
"""
Get a package by name.
By default, we limit the number of depends and requires results
to 20. To bypass this and load all of them, which should be triggered
via a "Show more" link near the limited listing.
:param name: Package.Name
:param all_deps: Boolean indicating whether we should load all depends
:param all_reqs: Boolean indicating whether we should load all requires
:return: FastAPI Response
"""
# Get the Package.
pkg = get_pkg_or_base(name, models.Package)
pkgbase = pkg.PackageBase
@ -139,23 +154,41 @@ async def package(request: Request, name: str) -> Response:
rels_data["r"].append(rel)
# Add our base information.
context = pkgbaseutil.make_context(request, pkgbase)
context = await pkgbaseutil.make_variable_context(request, pkgbase)
context.update(
{
"all_deps": all_deps,
"all_reqs": all_reqs
}
)
context["package"] = pkg
# Package sources.
context["sources"] = pkg.package_sources.order_by(
models.PackageSource.Source.asc()).all()
# Listing metadata.
context["max_listing"] = max_listing = 20
# Package dependencies.
max_depends = config.getint("options", "max_depends")
context["dependencies"] = pkg.package_dependencies.order_by(
deps = pkg.package_dependencies.order_by(
models.PackageDependency.DepTypeID.asc(),
models.PackageDependency.DepName.asc()
).limit(max_depends).all()
)
context["depends_count"] = deps.count()
if not all_deps:
deps = deps.limit(max_listing)
context["dependencies"] = deps.all()
# Package requirements (other packages depend on this one).
context["required_by"] = pkgutil.pkg_required(
pkg.Name, [p.RelName for p in rels_data.get("p", [])], max_depends)
reqs = pkgutil.pkg_required(
pkg.Name, [p.RelName for p in rels_data.get("p", [])])
context["reqs_count"] = reqs.count()
if not all_reqs:
reqs = reqs.limit(max_listing)
context["required_by"] = reqs.all()
context["licenses"] = pkg.package_licenses

View file

@ -100,6 +100,8 @@ async def make_variable_context(request: Request, title: str, next: str = None):
for k, v in to_copy.items():
context[k] = v
context["q"] = dict(request.query_params)
return context

View file

@ -2338,3 +2338,11 @@ msgstr ""
#: templates/partials/tu/proposal/details.html
msgid "assigned"
msgstr ""
#: templaets/partials/packages/package_metadata.html
msgid "Show %d more"
msgstr ""
#: templates/partials/packages/package_metadata.html
msgid "dependencies"
msgstr ""

View file

@ -8,7 +8,7 @@
#
[tool.poetry]
name = "aurweb"
version = "v6.0.26"
version = "v6.0.27"
license = "GPL-2.0-only"
description = "Source code for the Arch User Repository's website"
homepage = "https://aur.archlinux.org"

View file

@ -1,5 +1,5 @@
<div id="pkgdeps" class="listing">
<h3>{{ "Dependencies" | tr }} ({{ dependencies | length }})</h3>
<h3>{{ "Dependencies" | tr }} ({{ depends_count }})</h3>
<ul id="pkgdepslist">
{% for dep in dependencies %}
{# Collect provides for `dep`. #}
@ -34,11 +34,18 @@
{% endif %}
</li>
{% endfor %}
{% if not all_deps and depends_count > max_listing %}
<li>
<a href="/packages/{{ package.Name }}?{{ q | extend_query(['all_deps', '1']) | urlencode }}#pkgdeps">
{{ "Show %d more" | tr | format(depends_count - (dependencies | length)) }} {{ "dependencies" | tr }}...
</a>
</li>
{% endif %}
</ul>
</div>
<div id="pkgreqs" class="listing">
<h3>{{ "Required by" | tr }} ({{ required_by | length }})</h3>
<h3>{{ "Required by" | tr }} ({{ reqs_count }})</h3>
<ul id="pkgreqslist">
{% for dep in required_by %}
<li>
@ -55,6 +62,11 @@
<em>{{ dep | dep_extra }}</em>
</li>
{% endfor %}
{% if not all_reqs and (required_by | length) > max_listing %}
<a href="/packages/{{ name }}?{{ q | extend_query(['all_reqs', '1']) | urlencode }}#pkgreqs">
{{ "Show %d more" | tr | format(reqs_count - (required_by | length)) }}...
</a>
{% endif %}
</ul>
</div>

View file

@ -276,6 +276,51 @@ def test_package(client: TestClient, package: Package):
assert conflicts[0].text.strip() == ", ".join(expected)
def paged_depends_required(client: TestClient, package: Package):
maint = package.PackageBase.Maintainer
new_pkgs = []
with db.begin():
# Create 25 new packages that'll be used to depend on our package.
for i in range(26):
base = db.create(PackageBase, Name=f"new_pkg{i}", Maintainer=maint)
new_pkgs.append(db.create(Package, Name=base.Name))
# Create 25 deps.
for i in range(25):
create_package_dep(package, f"dep_{i}")
with db.begin():
# Create depends on this package so we get some required by listings.
for new_pkg in new_pkgs:
create_package_dep(new_pkg, package.Name)
with client as request:
resp = request.get(package_endpoint(package))
assert resp.status_code == int(HTTPStatus.OK)
# Test depends show link.
assert "Show 5 more" in resp.text
# Test required by show more link, we added 26 packages.
assert "Show 6 more" in resp.text
# Follow both links at the same time.
with client as request:
resp = request.get(
package_endpoint(package),
params={
"all_deps": True,
"all_reqs": True,
}
)
assert resp.status_code == int(HTTPStatus.OK)
# We're should see everything and have no link.
assert "Show 5 more" not in resp.text
assert "Show 6 more" not in resp.text
def test_package_comments(client: TestClient, user: User, package: Package):
now = (time.utcnow())
with db.begin():