From afd78ed3c09290d714fa5288a6533dd63b089151 Mon Sep 17 00:00:00 2001 From: Mike Cantelon Date: Thu, 7 Sep 2023 17:25:34 -0700 Subject: [PATCH] Add METS download link to AIP page. (#46) Adds a METS download link to the AIP detail page. --- AIPscan/Reporter/templates/aip.html | 2 ++ AIPscan/Reporter/tests/test_views.py | 33 ++++++++++++++++++++++++++++ AIPscan/Reporter/views.py | 30 ++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 AIPscan/Reporter/tests/test_views.py diff --git a/AIPscan/Reporter/templates/aip.html b/AIPscan/Reporter/templates/aip.html index 0141169a..826f8e75 100644 --- a/AIPscan/Reporter/templates/aip.html +++ b/AIPscan/Reporter/templates/aip.html @@ -22,6 +22,8 @@ Originals: {{ original_file_count }}
Preservation copies: {{ preservation_file_count }} +
+ Download METS

Original files

diff --git a/AIPscan/Reporter/tests/test_views.py b/AIPscan/Reporter/tests/test_views.py new file mode 100644 index 00000000..1da4c4d1 --- /dev/null +++ b/AIPscan/Reporter/tests/test_views.py @@ -0,0 +1,33 @@ +import pytest +from flask import current_app +from werkzeug.datastructures import Headers + + +def test_download_mets(app_with_populated_files, mocker): + # Mock storage server API request response + request = mocker.patch("requests.get") + + class MockRespoonse(object): + pass + + return_response = MockRespoonse() + return_response.content = "METS content" + return_response.status_code = 200 + + request.return_value = return_response + + # Test view logic + with current_app.test_client() as test_client: + response = test_client.get("/reporter/download_mets/1") + assert response.headers == Headers( + [ + ( + "Content-Disposition", + 'attachment; filename="METS-111111111111-1111-1111-11111111.xml"', + ), + ("Content-Length", "12"), + ("Content-Type", "text/html; charset=utf-8"), + ] + ) + + assert response.status_code == 200 diff --git a/AIPscan/Reporter/views.py b/AIPscan/Reporter/views.py index fd7eaf5f..66b4273d 100644 --- a/AIPscan/Reporter/views.py +++ b/AIPscan/Reporter/views.py @@ -7,8 +7,10 @@ from datetime import datetime -from flask import jsonify, make_response, render_template, request, session +import requests +from flask import Response, jsonify, make_response, render_template, request, session +from AIPscan.Aggregator.task_helpers import get_mets_url from AIPscan.models import ( AIP, Event, @@ -272,3 +274,29 @@ def update_dates(): req = request.get_json() session["end_date"] = request.json.get("end_date") return make_response(jsonify(req), 200) + + +@reporter.route("/download_mets/", methods=["GET"]) +def download_mets(aip_id): + aip = AIP.query.get(aip_id) + storage_service = StorageService.query.get(aip.storage_service_id) + + api_url = { + "baseUrl": storage_service.url, + "userName": storage_service.user_name, + "apiKey": storage_service.api_key, + } + + mets_response = requests.get( + get_mets_url( + api_url, + aip.uuid, + f"{aip.transfer_name}-{aip.uuid}/data/METS.{aip.uuid}.xml", + ) + ) + + headers = { + "Content-Disposition": f'attachment; filename="METS-{aip.uuid}.xml"', + "Content-length": len(mets_response.content), + } + return Response(mets_response.content, mets_response.status_code, headers)