update_institution.py 9.33 KB
Newer Older
Jonas Waeber's avatar
Jonas Waeber committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Import API Service
# Copyright (C) 2020-2021 Memobase Project
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17
import uuid

Matthias's avatar
Matthias committed
18
19
20
21
from flask_restful import Resource, current_app
from kafka import KafkaProducer
import requests
import json
Matthias's avatar
Matthias committed
22
import traceback
23
24
from requests.auth import HTTPBasicAuth

Matthias's avatar
Matthias committed
25

26
class UpdateInstitution(Resource):
Matthias's avatar
Matthias committed
27

28
29
30
31
32
    def __init__(self):
        self.producer = KafkaProducer(bootstrap_servers=current_app.config['kafka-broker-url'],
                                      value_serializer=lambda m: json.dumps(m, ensure_ascii=False)
                                      .encode('utf-8'))

33
    def get(self, institution_drupal_uuid):
Matthias's avatar
Matthias committed
34
        """
35
        Update the institution with the given drupal UUID in the backend.
Matthias's avatar
Matthias committed
36
37
        ---
        tags:
38
          - Update Institution
Matthias's avatar
Matthias committed
39
40
        parameters:
          - in: path
41
            name: institution_drupal_uuid
Matthias's avatar
Matthias committed
42
43
            required: true
            description: The UUID of the updated institution
Matthias's avatar
Matthias committed
44
            example: 0c4c777c-94f8-45ba-945a-bfe6967d40da
Matthias's avatar
Matthias committed
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
            type: string
        responses:
          200:
            description: Success, the information has been written into
                the kafka topic
            schema:
              properties:
                status:
                  type: string
                  example: SUCCESS/FAILURE
                  enum: ['SUCCESS', 'FAILURE']
                topic_value:
                  type: string/json
                  example: the value written into the topic

        """
61
        result = ''
62
        headers = {'X-API-Key': current_app.config['drupal-api-key']}
63
64
65
        user = current_app.config['drupal-user']
        password = current_app.config['drupal-password']
        auth = HTTPBasicAuth(user, password)
66
        base_url = current_app.config['drupal-api-url']
67
68
69
70
71
72
73
74
75
        institution_path = f'/jsonapi/node/institution/{institution_drupal_uuid}'
        extended_address_path = '/jsonapi/paragraph/extended_address/'
        record_set_path = '/jsonapi/node/record_set'
        de_url = f"{base_url}/de{institution_path}"
        fr_url = f"{base_url}/fr{institution_path}"
        it_url = f"{base_url}/it{institution_path}"
        response_de, status_de = UpdateInstitution.request_institution_data(de_url, headers, auth)
        response_fr, status_fr = UpdateInstitution.request_institution_data(fr_url, headers, auth)
        response_it, status_it = UpdateInstitution.request_institution_data(it_url, headers, auth)
76
        if status_de + status_fr + status_it != 600:
77
            return {
Jonas Waeber's avatar
Jonas Waeber committed
78
79
80
81
                       'de': response_de,
                       'fr': response_fr,
                       'it': response_it
                   }, 500
82
83
84
85
        institution_data_de = response_de
        institution_data_fr = response_fr
        institution_data_it = response_it

86
        try:
Matthias's avatar
Matthias committed
87
            addresses = []
88
89
90
91
92
            address_paragraphs = institution_data_de['relationships']['field_extended_address']
            for element in address_paragraphs['data']:
                paragraph_url = f'{base_url}{extended_address_path}{element["id"]}'
                drupal_response_address = requests.get(paragraph_url, headers=headers, auth=auth)
                response_data = drupal_response_address.json()['data']
Jonas Waeber's avatar
Jonas Waeber committed
93
94
95
                next_address = response_data['attributes']['field_address']
                if next_address is not None:
                    next_address['coordinates'] = \
96
                        response_data['attributes']['field_geographical_coordinates']['value']
Jonas Waeber's avatar
Jonas Waeber committed
97
                    addresses.append(next_address)
Matthias's avatar
Matthias committed
98

99
100
            institution_types = []
            paragraph_url = \
101
102
                institution_data_de['relationships']['field_institution_types']['links']['related'][
                    'href']  # noqa: E501
103
104
105
106
            institution_types_data = \
                requests.get(paragraph_url, headers=headers, auth=auth).json()['data']
            for element in institution_types_data:
                institution_types.append(element['attributes']['field_wikidata']['uri'])
Matthias's avatar
Matthias committed
107

108
109
110
111
112
113
114
            record_set_ids = []
            filter_param = f'?filter[field_institution.id][value]={institution_drupal_uuid}'
            url = f'{base_url}{record_set_path}{filter_param}'
            record_set_data = requests.get(url, headers=headers, auth=auth).json()['data']
            for record_set in record_set_data:
                record_set_ids.append(
                    record_set['attributes']['field_memobase_id']
115
                )
Matthias's avatar
Matthias committed
116
        except LookupError as ex:
117
            msg = f'Could not find key ({institution_drupal_uuid}): {ex}.'
118
            current_app.logger.error(msg)
Matthias's avatar
Matthias committed
119
120
            return {
                       'status': 'FAILURE',
Jonas Waeber's avatar
Jonas Waeber committed
121
                       'message': str(ex),
122
                       'topic_value': result
Matthias's avatar
Matthias committed
123
                   }, 500
Matthias's avatar
Matthias committed
124
        except Exception as ex:
125
            msg = f'Unknown Exception ({institution_drupal_uuid}): {ex}\n{traceback.format_exc()}'
126
            current_app.logger.error(msg)
Matthias's avatar
Matthias committed
127
            return {
128
                       'status': 'FAILURE',
Jonas Waeber's avatar
Jonas Waeber committed
129
                       'message': str(ex),
130
                       'topic_value': result
131
                   }, 500
132
        result = {
133
134
135
136
137
            'type': institution_data_de['type'],
            'status': institution_data_de['attributes']['status'],
            'title_de': institution_data_de['attributes']['title'],
            'title_fr': institution_data_fr['attributes']['title'],
            'title_it': institution_data_it['attributes']['title'],
138
            'field_address': addresses,
139
140
141
142
143
144
            'field_isil': institution_data_de['attributes']['field_isil'],
            'field_memobase_id': institution_data_de['attributes']['field_memobase_id'],
            'field_old_memobase_id': institution_data_de['attributes']['field_old_memobase_id'],
            'field_email': institution_data_de['attributes']['field_email'],
            'field_website': institution_data_de['attributes']['field_website'],
            'field_wikidata_id': institution_data_de['attributes']['field_wikidata_id']['uri'],
145
            'field_link_archive_catalog':
146
147
148
149
                institution_data_de['attributes']['field_link_archive_catalog'],
            'field_text_de': institution_data_de['attributes']['field_text'],
            'field_text_fr': institution_data_fr['attributes']['field_text'],
            'field_text_it': institution_data_it['attributes']['field_text'],
150
            'field_institution_types': institution_types,
151
            'field_teaser_color': institution_data_de['attributes']['field_teaser_color'],
152
            'recordset_ids': record_set_ids,
153
            'computed_teaser_image_url':
154
155
                institution_data_de['attributes']['computed_teaser_image_url'],
            'computed_teaser_color': institution_data_de['attributes']['computed_teaser_color'],
156
        }
Matthias's avatar
Matthias committed
157
        try:
Jonas Waeber's avatar
Jonas Waeber committed
158
159
160
161
162
163
164
            producer_topic = current_app.config['topic-drupal-export']
            headers = [
                ('recordSetId', bytes('none', encoding='utf-8')),
                ('sessionId', bytes(str(uuid.uuid4()), encoding='utf-8')),
                ('institutionId', bytes(result.get('field_memobase_id'), encoding='utf-8')),
                ('isPublished', bytes(str(result['status']), encoding='utf-8'))
            ]
165
166
            key = bytes(result.get('field_memobase_id'), encoding='utf-8')
            self.producer.send(producer_topic, result, key, headers=headers)
Matthias's avatar
Matthias committed
167
        except Exception as ex:
168
169
170
            msg = f'Unknown Exception ({institution_drupal_uuid}): {ex}. '\
                  f'Check logs for more details.'
            current_app.logger.error(f'{msg}\n{traceback.format_exc()}')
Matthias's avatar
Matthias committed
171
            return {
172
                       'status': 'FAILURE',
173
174
                       'topic_key': result.get('field_memobase_id'),
                       'topic_value': result
175
                   }, 500
Matthias's avatar
Matthias committed
176

177
        current_app.logger.debug('success for ' + institution_drupal_uuid)
178
179
        return {
                   'status': 'SUCCESS',
180
181
                   'topic_key': result.get('field_memobase_id'),
                   'topic_value': result
182
               }, 200
183

184
185
    @staticmethod
    def request_institution_data(url, headers, auth):
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
        response = requests.get(url, headers=headers, auth=auth)
        if response.ok:
            try:
                json_data = response.json()
                if 'data' in json_data:
                    return json_data['data'], 200
                else:
                    return {'message': "No key 'data' found in json response: " + json_data}, 500
            except json.decoder.JSONDecodeError:
                return {
                           'message': 'Could not parse response message as JSON: ' + response.text
                       }, 404

        else:
            return {
                       'url': url,
                       'message': response.text
                   }, response.status_code