from flask_restful import Resource, request from flask_restful import current_app from helpers.Error import ImportApiError import requests import json class WriteTypeReportToDrupal(Resource): def __init__(self): self.base_url = current_app.config["drupal-api-url"] self.headers = { 'Content-Type': 'application/vnd.api+json', 'Accept': 'application/vnd.api+json', 'X-API-Key': current_app.config['drupal-api-key'] } def post(self): """ Write a report for an recordset or institution Drupal --- tags: - reporting parameters: - in: body name: body required: true schema: item: type: object properties: node_type: type: string example: 'recordset' description: Either 'recordset' or 'institution'. id: type: string example: 'sag' description: The memobase id of the record set or institution. status: type: boolean example: True description: The status report: type: string example: "Failed to process record set." description: Text message of the report. responses: 200: description: It was successful 404: description: No content with such a id found 500: description: There was a problem """ try: node_type = request.json['node_type'] identifier = request.json['id'] status = request.json['status'] report = request.json['report'] except KeyError as er: return { 'message': f'Missing a element in input body: {er}' }, 400 try: node_id = self.get_node_id(identifier, node_type) return self.write_results(node_type, node_id, status, report) except ImportApiError as e: current_app.logger.error( f"Could not write report to {node_type}/{identifier}: {e.message}") return { 'error': f"Could not write report to {node_type}/{identifier}: " f"{e.message}"}, 500 def get_node_id(self, memobase_id: str, node_type: str): current_app.logger.debug( f'Retrieve node id from durpal json api with memobase id {memobase_id}.') url = f'{self.base_url}/jsonapi/node/{node_type}?filter[' \ f'field_memobase_id]={memobase_id}' response = requests.get(url, headers=self.headers) if response.ok: try: return response.json()['data'][0]['attributes']['drupal_internal__nid'] except KeyError as er: current_app.logger.error(f"Could not find the key {er} in data: {response.text}.") raise ImportApiError(f"Could not find the key {er} in data (url={url}): " f"{response.text}.") except IndexError: current_app.logger.error(f"Data field does not contain a list (url={url}): " f"{response.text}.") raise ImportApiError(f"Data field does not contain a list (url={url}): " f"{response.text}.") else: raise ImportApiError(f"Could not find element for report: {response.text}.") def write_results(self, node_type, identifier, status, report): current_app.logger.debug( "writing: " + node_type + "/" + str(identifier) + "/" + str(status) + "/" + report) drupal_type = '' url = f'{self.base_url}/jsonapi/node/' if node_type == 'institution': drupal_type = 'node--institution' url += 'institution/' elif node_type == 'recordset': drupal_type = 'node--record_set' url += 'record_set/' url = f'{url}{identifier}' data = { "data": { "type": drupal_type, "attributes": { "field_migrated": status, "field_error": report } } } result = {'message': ''} try: response = requests.patch( url, headers=self.headers, data=json.dumps(data) ) except requests.exceptions.RequestException: message = f'Request Error: {url}' current_app.logger.error(message) raise ImportApiError(message) if response.ok: current_app.logger.debug('Updated: ' + url) result['message'] += 'Updated: ' + url + '\n' elif response.status_code == 403: message = f"Authorization Failed: {url}" current_app.logger.error(message) raise ImportApiError(message) elif response.status_code == 404: message = 'Not Found: ' + url current_app.logger.error(message) raise ImportApiError(message) else: message = "Unknown response status code for drupal api for url " + url current_app.logger.error(message) raise ImportApiError(message) return result