diff --git a/aurweb/routers/packages.py b/aurweb/routers/packages.py index af1ebe46..40322785 100644 --- a/aurweb/routers/packages.py +++ b/aurweb/routers/packages.py @@ -1,6 +1,6 @@ from datetime import datetime from http import HTTPStatus -from typing import Any, Dict +from typing import Any, Dict, List from fastapi import APIRouter, Form, HTTPException, Query, Request, Response from fastapi.responses import JSONResponse, RedirectResponse @@ -11,7 +11,7 @@ import aurweb.models.package_comment import aurweb.models.package_keyword import aurweb.packages.util -from aurweb import db, defaults, l10n +from aurweb import db, defaults, l10n, util from aurweb.auth import auth_required from aurweb.models.license import License from aurweb.models.package import Package @@ -26,7 +26,7 @@ from aurweb.models.package_request import ACCEPTED_ID, PENDING_ID, REJECTED_ID, from aurweb.models.package_source import PackageSource from aurweb.models.package_vote import PackageVote from aurweb.models.relation_type import CONFLICTS_ID -from aurweb.models.request_type import RequestType +from aurweb.models.request_type import DELETION_ID, RequestType from aurweb.models.user import User from aurweb.packages.search import PackageSearch from aurweb.packages.util import get_pkg_or_base, get_pkgbase_comment, query_notified, query_voted @@ -116,6 +116,76 @@ async def packages(request: Request) -> Response: return await packages_get(request, context) +def create_request_if_missing(requests: List[PackageRequest], + reqtype: RequestType, + user: User, + package: Package): + now = int(datetime.utcnow().timestamp()) + pkgreq = db.query(PackageRequest).filter( + PackageRequest.PackageBaseName == package.PackageBase.Name + ).first() + if not pkgreq: + # No PackageRequest existed. Create one. + comments = "Automatically generated by aurweb." + closure_comment = "Deleted by aurweb." + pkgreq = db.create(PackageRequest, + RequestType=reqtype, + PackageBase=package.PackageBase, + PackageBaseName=package.PackageBase.Name, + User=user, + Status=ACCEPTED_ID, + Comments=comments, + ClosureComment=closure_comment, + ClosedTS=now, + Closer=user) + requests.append(pkgreq) + + +def delete_package(deleter: User, + package: Package): + notifications = [] + requests = [] + bases_to_delete = [] + + conn = db.ConnectionExecutor(db.get_engine().raw_connection()) + # In all cases, though, just delete the Package in question. + if package.PackageBase.packages.count() == 1: + reqtype = db.query(RequestType).filter( + RequestType.ID == DELETION_ID + ).first() + + with db.begin(): + create_request_if_missing( + requests, reqtype, deleter, package) + + bases_to_delete.append(package.PackageBase) + + # Prepare DeleteNotification. + notifications.append( + notify.DeleteNotification(conn, deleter.ID, package.PackageBase.ID) + ) + + # For each PackageRequest created, mock up an open and close notification. + basename = package.PackageBase.Name + for pkgreq in requests: + notifications.append( + notify.RequestOpenNotification( + conn, deleter.ID, pkgreq.ID, reqtype.Name, + pkgreq.PackageBase.ID, merge_into=basename or None) + ) + notifications.append( + notify.RequestCloseNotification( + conn, deleter.ID, pkgreq.ID, pkgreq.status_display()) + ) + + # Perform all the deletions. + db.delete_all([package]) + db.delete_all(bases_to_delete) + + # Send out all the notifications. + util.apply_all(notifications, lambda n: n.send()) + + async def make_single_context(request: Request, pkgbase: PackageBase) -> Dict[str, Any]: """ Make a basic context for package or pkgbase.