|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +# |
| 3 | +# This file is part of CERN Analysis Preservation Framework. |
| 4 | +# Copyright (C) 2016 CERN. |
| 5 | +# |
| 6 | +# CERN Analysis Preservation Framework is free software; you can redistribute |
| 7 | +# it and/or modify it under the terms of the GNU General Public License as |
| 8 | +# published by the Free Software Foundation; either version 2 of the |
| 9 | +# License, or (at your option) any later version. |
| 10 | +# |
| 11 | +# CERN Analysis Preservation Framework is distributed in the hope that it will |
| 12 | +# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | +# General Public License for more details. |
| 15 | +# |
| 16 | +# You should have received a copy of the GNU General Public License |
| 17 | +# along with CERN Analysis Preservation Framework; if not, write to the |
| 18 | +# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| 19 | +# MA 02111-1307, USA. |
| 20 | +# |
| 21 | +# In applying this license, CERN does not |
| 22 | +# waive the privileges and immunities granted to it by virtue of its status |
| 23 | +# as an Intergovernmental Organization or submit itself to any jurisdiction. |
| 24 | +"""Extra records views.""" |
| 25 | + |
| 26 | +from __future__ import absolute_import, print_function |
| 27 | + |
| 28 | +from flask import Blueprint, g |
| 29 | +from invenio_files_rest.views import bucket_view, object_view |
| 30 | +from sqlalchemy.orm.exc import NoResultFound |
| 31 | + |
| 32 | +from .api import CAPRecord |
| 33 | + |
| 34 | + |
| 35 | +def create_cap_record_blueprint(app): |
| 36 | + """Create blueprint from a Flask application. |
| 37 | + :params app: A Flask application. |
| 38 | + :returns: Configured blueprint. |
| 39 | + """ |
| 40 | + cap_records_bp = Blueprint('cap_records_files', __name__, url_prefix='') |
| 41 | + |
| 42 | + record_item_path = app.config['RECORDS_REST_ENDPOINTS']['recid'][ |
| 43 | + 'item_route'] |
| 44 | + cap_records_bp.add_url_rule('{}/files'.format(record_item_path), |
| 45 | + view_func=bucket_view) |
| 46 | + cap_records_bp.add_url_rule('{}/files/<path:key>'.format(record_item_path), |
| 47 | + view_func=object_view) |
| 48 | + |
| 49 | + @cap_records_bp.url_value_preprocessor |
| 50 | + def resolve_pid_to_bucket_id(endpoint, values): |
| 51 | + """Flask URL preprocessor to resolve pid to Bucket ID. |
| 52 | + In the ``cap_records_bp`` we are gluing together Records-REST |
| 53 | + and Files-REST APIs. Records-REST knows about PIDs but Files-REST does |
| 54 | + not, this function will pre-process the URL so the PID is removed from |
| 55 | + the URL and resolved to bucket ID which is injected into Files-REST |
| 56 | + view calls: |
| 57 | + ``/api/<record_type>/<pid_value>/files/<key>`` -> |
| 58 | + ``/files/<bucket>/<key>``. |
| 59 | + """ |
| 60 | + # Remove the 'pid_value' in order to match the Files-REST bucket view |
| 61 | + # signature. Store the value in Flask global request object for later |
| 62 | + # usage. |
| 63 | + g.pid = values.pop('pid_value') |
| 64 | + pid, _ = g.pid.data |
| 65 | + |
| 66 | + try: |
| 67 | + record = CAPRecord.get_record(pid.object_uuid) |
| 68 | + values['bucket_id'] = str(record.files.bucket) |
| 69 | + except (AttributeError, NoResultFound): |
| 70 | + # Hack, to make invenio_files_rest.views.as_uuid throw a |
| 71 | + # ValueError instead of a TypeError if we set the value to None. |
| 72 | + values['bucket_id'] = '' |
| 73 | + |
| 74 | + @cap_records_bp.url_defaults |
| 75 | + def restore_pid_to_url(endpoint, values): |
| 76 | + """Put ``pid_value`` back to the URL after matching Files-REST views. |
| 77 | + Since we are computing the URL more than one times, we need the |
| 78 | + original values of the request to be unchanged so that it can be |
| 79 | + reproduced. |
| 80 | + """ |
| 81 | + # Value here has been saved in above method (resolve_pid_to_bucket_id) |
| 82 | + values['pid_value'] = g.pid |
| 83 | + |
| 84 | + return cap_records_bp |
0 commit comments