feat(FastAPI): add /pkgbase/{name}/request (get)

This change brings in the package base request form
for new submissions.

Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
Kevin Morris 2021-09-12 21:51:20 -07:00
parent 1cf9420997
commit ad8369395e
No known key found for this signature in database
GPG key ID: F7E46DED420788F3
4 changed files with 157 additions and 0 deletions

View file

@ -568,3 +568,17 @@ async def requests(request: Request,
).limit(PP).offset(O).all() ).limit(PP).offset(O).all()
return render_template(request, "requests.html", context) return render_template(request, "requests.html", context)
@router.get("/pkgbase/{name}/request")
@auth_required(True)
async def package_request(request: Request, name: str):
context = make_context(request, "Submit Request")
pkgbase = db.query(PackageBase).filter(PackageBase.Name == name).first()
if not pkgbase:
raise HTTPException(status_code=int(HTTPStatus.NOT_FOUND))
context["pkgbase"] = pkgbase
return render_template(request, "pkgbase/request.html", context)

View file

@ -0,0 +1,87 @@
{% extends "partials/layout.html" %}
{% block pageContent %}
<div class="box">
<h2>{{ "Submit Request" | tr }}: {{ pkgbase.Name }}</h2>
<p>
{{ "Use this form to file a request against package base "
"%s%s%s which includes the following packages:"
| tr | format("<strong>", pkgbase.Name, "</strong>") | safe }}
</p>
<ul>
{% for package in pkgbase.packages %}
<li>{{ package.Name }}</li>
{% endfor %}
</ul>
{# Request form #}
<form id="request-form" action="/pkgbase/{{ pkgbase.Name }}/request">
<fieldset>
<p>
<label for="id_type">{{ "Request type" | tr }}:</label>
<select id="id_type" name="type">
<option value="deletion">{{ "Deletion" | tr }}</option>
<option value="merge">{{ "Merge" | tr }}</option>
<option value="orphan">{{ "Orphan" | tr }}</option>
</select>
</p>
{# Javascript included for HTML-changing triggers depending
on the selected type (above). #}
<script type="text/javascript"
src="/static/js/typeahead-pkgbase-request.js"></script>
<p id="merge_section" style="display: none">
<label for="id_merge_into">{{ "Merge into" | tr }}:</label>
<input id="id_merge_into" type="text" name="merge_into"
autocomplete="off" />
</p>
<p>
<label for="id_comments">{{ "Comments" | tr }}:</label>
<textarea id="id_comments" name="comments"
rows="5" cols="50"></textarea>
</p>
<p id="deletion_hint">
{{
"By submitting a deletion request, you ask a Trusted "
"User to delete the package base. This type of "
"request should be used for duplicates, software "
"abandoned by upstream, as well as illegal and "
"irreparably broken packages." | tr
}}
</p>
<p id="merge_hint" style="display: none">
{{
"By submitting a merge request, you ask a Trusted "
"User to delete the package base and transfer its "
"votes and comments to another package base. "
"Merging a package does not affect the corresponding "
"Git repositories. Make sure you update the Git "
"history of the target package yourself." | tr
}}
</p>
<p id="orphan_hint" style="display: none">
{{
"By submitting an orphan request, you ask a Trusted "
"User to disown the package base. Please only do this "
"if the package needs maintainer action, the "
"maintainer is MIA and you already tried to contact "
"the maintainer previously." | tr
}}
</p>
<p>
<button class="button" type="submit">
{{ "Submit Request" | tr }}
</button>
</p>
</fieldset>
</form>
</div>
{% endblock %}

View file

@ -1400,3 +1400,23 @@ def test_requests_selfmade(client: TestClient, user: User,
for row in rows: for row in rows:
last_row = row.xpath('./td')[-1].xpath('./a')[0] last_row = row.xpath('./td')[-1].xpath('./a')[0]
assert last_row.text.strip() == "Close" assert last_row.text.strip() == "Close"
def test_pkgbase_request_not_found(client: TestClient, user: User):
pkgbase_name = "fake"
endpoint = f"/pkgbase/{pkgbase_name}/request"
cookies = {"AURSID": user.login(Request(), "testPassword")}
with client as request:
resp = request.get(endpoint, cookies=cookies)
assert resp.status_code == int(HTTPStatus.NOT_FOUND)
def test_pkgbase_request(client: TestClient, user: User, package: Package):
pkgbase = package.PackageBase
endpoint = f"/pkgbase/{pkgbase.Name}/request"
cookies = {"AURSID": user.login(Request(), "testPassword")}
with client as request:
resp = request.get(endpoint, cookies=cookies)
assert resp.status_code == int(HTTPStatus.OK)

View file

@ -0,0 +1,36 @@
function showHideMergeSection() {
const elem = document.getElementById('id_type');
const merge_section = document.getElementById('merge_section');
if (elem.value == 'merge') {
merge_section.style.display = '';
} else {
merge_section.style.display = 'none';
}
}
function showHideRequestHints() {
document.getElementById('deletion_hint').style.display = 'none';
document.getElementById('merge_hint').style.display = 'none';
document.getElementById('orphan_hint').style.display = 'none';
const elem = document.getElementById('id_type');
document.getElementById(elem.value + '_hint').style.display = '';
}
document.addEventListener('DOMContentLoaded', function() {
showHideMergeSection();
showHideRequestHints();
const input = document.getElementById('id_merge_into');
const form = document.getElementById('request-form');
const type = "suggest-pkgbase";
typeahead.init(type, input, form, false);
});
// Bind the change event here, otherwise we have to inline javascript,
// which angers CSP (Content Security Policy).
document.getElementById("id_type").addEventListener("change", function() {
showHideMergeSection();
showHideRequestHints();
});