WriteTypeReportToDrupal.py 5.65 KB
Newer Older
1
2
3
4
5
6
7
8
from flask_restful import Resource, request
from flask_restful import current_app
from helpers.Error import ImportApiError
import requests
import json


class WriteTypeReportToDrupal(Resource):
9
10
11
12
13
14
15
16
17

    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']
        }

18
19
20
21
22
    def post(self):
        """
        Write a report for an recordset or institution Drupal
        ---
        tags:
Matthias's avatar
Matthias committed
23
          - reporting
24
        parameters:
Matthias's avatar
Matthias committed
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
            - 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.
48
        responses:
Matthias's avatar
Matthias committed
49
50
51
52
53
54
            200:
                description: It was successful
            404:
                description: No content with such a id found
            500:
                description: There was a problem
55
        """
Matthias's avatar
Matthias committed
56

57
        try:
Jonas Waeber's avatar
Jonas Waeber committed
58
59
60
61
            node_type = request.json['node_type']
            identifier = request.json['id']
            status = request.json['status']
            report = request.json['report']
62
63
64
65
66
        except KeyError as er:
            return {
                       'message': f'Missing a element in input body: {er}'
                   }, 400
        try:
67
68
            node_id = self.get_node_id(identifier, node_type)
            return self.write_results(node_type, node_id, status, report)
69
        except ImportApiError as e:
70
71
72
73
74
75
            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

76
77
78
79
80
    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}'
81

82
83
84
85
86
87
88
        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}): "
Jonas Waeber's avatar
Jonas Waeber committed
89
                                     f"{response.text}.")
90
91
92
93
94
95
96
            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}.")
97

98
99
100
    def write_results(self, node_type, identifier, status, report):
        current_app.logger.debug(
            "writing: " + node_type + "/" + str(identifier) + "/" + str(status) + "/" + report)
101

102
103
104
105
106
107
108
109
110
        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}'
111

112
113
114
115
116
117
118
        data = {
            "data": {
                "type": drupal_type,
                "attributes": {
                    "field_migrated": status,
                    "field_error": report
                }
119
120
121
            }
        }

122
        result = {'message': ''}
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
        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