mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
feat(FastAPI): add /packages (post) action: 'notify'
Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
fb85cb60a0
commit
b277d94e0b
3 changed files with 96 additions and 5 deletions
|
@ -846,11 +846,7 @@ async def pkgbase_unflag(request: Request, name: str):
|
||||||
status_code=HTTPStatus.SEE_OTHER)
|
status_code=HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/pkgbase/{name}/notify")
|
def pkgbase_notify_instance(request: Request, pkgbase: models.PackageBase):
|
||||||
@auth_required(True, redirect="/pkgbase/{name}")
|
|
||||||
async def pkgbase_notify(request: Request, name: str):
|
|
||||||
pkgbase = get_pkg_or_base(name, models.PackageBase)
|
|
||||||
|
|
||||||
notif = db.query(pkgbase.notifications.filter(
|
notif = db.query(pkgbase.notifications.filter(
|
||||||
models.PackageNotification.UserID == request.user.ID
|
models.PackageNotification.UserID == request.user.ID
|
||||||
).exists()).scalar()
|
).exists()).scalar()
|
||||||
|
@ -861,6 +857,12 @@ async def pkgbase_notify(request: Request, name: str):
|
||||||
PackageBase=pkgbase,
|
PackageBase=pkgbase,
|
||||||
User=request.user)
|
User=request.user)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/pkgbase/{name}/notify")
|
||||||
|
@auth_required(True, redirect="/pkgbase/{name}")
|
||||||
|
async def pkgbase_notify(request: Request, name: str):
|
||||||
|
pkgbase = get_pkg_or_base(name, models.PackageBase)
|
||||||
|
pkgbase_notify_instance(request, pkgbase)
|
||||||
return RedirectResponse(f"/pkgbase/{name}",
|
return RedirectResponse(f"/pkgbase/{name}",
|
||||||
status_code=HTTPStatus.SEE_OTHER)
|
status_code=HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
|
@ -1070,11 +1072,51 @@ async def packages_unflag(request: Request, package_ids: List[int] = [],
|
||||||
pkgbase_unflag_instance(request, pkgbase)
|
pkgbase_unflag_instance(request, pkgbase)
|
||||||
return (True, ["The selected packages have been unflagged."])
|
return (True, ["The selected packages have been unflagged."])
|
||||||
|
|
||||||
|
|
||||||
|
async def packages_notify(request: Request, package_ids: List[int] = [],
|
||||||
|
**kwargs):
|
||||||
|
# In cases where we encounter errors with the request, we'll
|
||||||
|
# use this error tuple as a return value.
|
||||||
|
# TODO: This error does not yet have a translation.
|
||||||
|
error_tuple = (False,
|
||||||
|
["You did not select any packages to be notified about."])
|
||||||
|
if not package_ids:
|
||||||
|
return error_tuple
|
||||||
|
|
||||||
|
bases = set()
|
||||||
|
package_ids = set(package_ids)
|
||||||
|
packages = db.query(models.Package).filter(
|
||||||
|
models.Package.ID.in_(package_ids)).all()
|
||||||
|
|
||||||
|
for pkg in packages:
|
||||||
|
if pkg.PackageBase not in bases:
|
||||||
|
bases.update({pkg.PackageBase})
|
||||||
|
|
||||||
|
# Perform some checks on what the user selected for notify.
|
||||||
|
for pkgbase in bases:
|
||||||
|
notif = db.query(pkgbase.notifications.filter(
|
||||||
|
models.PackageNotification.UserID == request.user.ID
|
||||||
|
).exists()).scalar()
|
||||||
|
has_cred = request.user.has_credential("CRED_PKGBASE_NOTIFY")
|
||||||
|
|
||||||
|
# If the request user either does not have credentials
|
||||||
|
# or the notification already exists:
|
||||||
|
if not (has_cred and not notif):
|
||||||
|
return error_tuple
|
||||||
|
|
||||||
|
# If we get here, user input is good.
|
||||||
|
for pkgbase in bases:
|
||||||
|
pkgbase_notify_instance(request, pkgbase)
|
||||||
|
|
||||||
|
# TODO: This message does not yet have a translation.
|
||||||
|
return (True, ["The selected packages' notifications have been enabled."])
|
||||||
|
|
||||||
# A mapping of action string -> callback functions used within the
|
# A mapping of action string -> callback functions used within the
|
||||||
# `packages_post` route below. We expect any action callback to
|
# `packages_post` route below. We expect any action callback to
|
||||||
# return a tuple in the format: (succeeded: bool, message: List[str]).
|
# return a tuple in the format: (succeeded: bool, message: List[str]).
|
||||||
PACKAGE_ACTIONS = {
|
PACKAGE_ACTIONS = {
|
||||||
"unflag": packages_unflag,
|
"unflag": packages_unflag,
|
||||||
|
"notify": packages_notify,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -958,6 +958,14 @@ msgstr ""
|
||||||
msgid "Package details could not be found."
|
msgid "Package details could not be found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: aurweb/routers/packages.py
|
||||||
|
msgid "You did not select any packages to be notified about."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: aurweb/routers/packages.py
|
||||||
|
msgid "The selected packages' notifications have been enabled."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lib/pkgbasefuncs.inc.php
|
#: lib/pkgbasefuncs.inc.php
|
||||||
msgid "You must be logged in before you can flag packages."
|
msgid "You must be logged in before you can flag packages."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -2113,3 +2113,44 @@ def test_packages_post_unflag(client: TestClient, user: User,
|
||||||
errors = get_errors(resp.text)
|
errors = get_errors(resp.text)
|
||||||
expected = "You did not select any packages to unflag."
|
expected = "You did not select any packages to unflag."
|
||||||
assert errors[0].text.strip() == expected
|
assert errors[0].text.strip() == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_packages_post_notify(client: TestClient, user: User, package: Package):
|
||||||
|
notif = package.PackageBase.notifications.filter(
|
||||||
|
PackageNotification.UserID == user.ID
|
||||||
|
).first()
|
||||||
|
assert notif is None
|
||||||
|
|
||||||
|
# Try to enable notifications but supply no packages, causing
|
||||||
|
# an error to be rendered.
|
||||||
|
cookies = {"AURSID": user.login(Request(), "testPassword")}
|
||||||
|
with client as request:
|
||||||
|
resp = request.post("/packages", data={"action": "notify"},
|
||||||
|
cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
errors = get_errors(resp.text)
|
||||||
|
expected = "You did not select any packages to be notified about."
|
||||||
|
assert errors[0].text.strip() == expected
|
||||||
|
|
||||||
|
# Now let's actually enable notifications on `package`.
|
||||||
|
with client as request:
|
||||||
|
resp = request.post("/packages", data={
|
||||||
|
"action": "notify",
|
||||||
|
"IDs": [package.ID]
|
||||||
|
}, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
expected = "The selected packages' notifications have been enabled."
|
||||||
|
successes = get_successes(resp.text)
|
||||||
|
assert successes[0].text.strip() == expected
|
||||||
|
|
||||||
|
# Try to enable notifications when they're already enabled,
|
||||||
|
# causing an error to be rendered.
|
||||||
|
with client as request:
|
||||||
|
resp = request.post("/packages", data={
|
||||||
|
"action": "notify",
|
||||||
|
"IDs": [package.ID]
|
||||||
|
}, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
errors = get_errors(resp.text)
|
||||||
|
expected = "You did not select any packages to be notified about."
|
||||||
|
assert errors[0].text.strip() == expected
|
||||||
|
|
Loading…
Add table
Reference in a new issue