Example #1
0
def reindex(record_type):
    """Reindex all records for the given type.

    Reindex all records managed by `invenio-records-resouces` for the given
    type.

    :param record_type: Record type.
    """
    click.secho(f'Indexing records of type "{record_type}"')
    sonar.service(record_type).bulk_reindex()
    click.secho('Record indexed successfully!', fg='green')
Example #2
0
    def add_permissions(self, item, **kwargs):
        """Add permissions to record.

        :param item: Dict representing the record.
        :returns: Modified dict.
        """
        service = sonar.service('projects')
        identity = g.get('identity', AnonymousIdentity())

        item['metadata']['permissions'] = {
            'read':
            service.permission_policy('read', **{
                'record': item
            }).allows(identity),
            'update':
            service.permission_policy('update', **{
                'record': item
            }).allows(identity),
            'delete':
            service.permission_policy('delete', **{
                'record': item
            }).allows(identity)
        }

        return item
Example #3
0
def completion():
    """Suggestions completion."""
    query = request.args.get('q')
    field = request.args.get('field')
    resource = request.args.get('resource')

    if not query:
        return jsonify({'error': 'No query parameter given'}), 400

    if not field:
        return jsonify({'error': 'No field parameter given'}), 400

    if not resource:
        return jsonify({'error': 'No resource parameter given'}), 400

    # Suggestions from multiple fields possible
    fields = field.split(',')

    search = None
    try:
        service = sonar.service(resource)
        search = service.config.search_cls(index=resource)
    except Exception:
        for doc_type, config in current_app.config.get(
                'RECORDS_REST_ENDPOINTS').items():
            if config.get('search_index') == resource:
                search = config['search_class']()

    if not search:
        return jsonify({'error': 'Search class not found'}), 404

    results = []

    try:
        search = search.source(excludes="*")

        for field in fields:
            search = search.suggest(field,
                                    query,
                                    completion={
                                        'field': field,
                                        'skip_duplicates': True
                                    })
        for i, suggestion in search.execute().suggest.to_dict().items():
            results = results + [
                option['text'] for option in suggestion[0]['options']
            ]
    except Exception:
        return jsonify({'error': 'Bad request'}), 400

    # Remove duplicates
    results = list(dict.fromkeys(results))

    # Sort items
    results.sort()

    return jsonify(results)
Example #4
0
def project_resolver(pid):
    """Resolve referenced project.

    This resolver is kept for compatibility reason with old resource
    management.
    """
    record = sonar.service('projects').record_cls.pid.resolve(pid)

    data = {'pid': record['id'], 'name': record['metadata']['name']}

    if record['metadata'].get('investigators'):
        data['investigators'] = record['metadata']['investigators']

    return data
Example #5
0
def project(app, db, es, admin, organisation, project_json):
    """Deposit fixture."""
    json = copy.deepcopy(project_json)
    json['metadata']['user'] = {
        '$ref': 'https://sonar.ch/api/users/{pid}'.format(pid=admin['pid'])
    }
    json['metadata']['organisation'] = {
        '$ref':
        'https://sonar.ch/api/organisations/{pid}'.format(
            pid=organisation['pid'])
    }

    project = sonar.service('projects').create(None, json)
    app.extensions['invenio-search'].flush_and_refresh(index='projects')
    return project
Example #6
0
    def _make_project(role='submitter', organisation=None):
        user = make_user(role, organisation)

        project_json['metadata']['user'] = {
            '$ref': 'https://sonar.ch/api/users/{pid}'.format(pid=user['pid'])
        }

        project_json['metadata']['organisation'] = {
            '$ref':
            'https://sonar.ch/api/organisations/{pid}'.format(pid=organisation)
        }

        project_json.pop('id', None)

        project = sonar.service('projects').create(None, project_json)
        app.extensions['invenio-search'].flush_and_refresh(index='projects')
        return project
Example #7
0
def detail(pid, record, template=None, **kwargs):
    r"""Project detail view.

    Sends record_viewed signal and renders template.

    :param pid: PID object.
    :param record: Record object.
    :param template: Template to render.
    :param \*\*kwargs: Additional view arguments based on URL rule.
    :returns: The rendered template.
    """
    service = sonar.service('projects')
    item = service.result_item(service, g.identity, record)

    # Send signal when record is viewed
    record_viewed.send(
        current_app._get_current_object(),
        pid=pid,
        record=record,
    )

    return render_template(template, pid=pid, record=item.data['metadata'])
Example #8
0
    def create_document(self):
        """Create document from deposit."""
        # TODO : Do this whole process with a marshmallow schema serializer.
        metadata = {}

        # Organisation
        if current_user_record and current_user_record.get('organisation'):
            metadata['organisation'] = [current_user_record['organisation']]

        # Document type
        metadata['documentType'] = self['metadata']['documentType']

        # Language
        language = self['metadata'].get('language', 'eng')

        # Title
        metadata['title'] = [{
            'type':
            'bf:Title',
            'mainTitle': [{
                'language': language,
                'value': self['metadata']['title']
            }]
        }]

        # Subtitle
        if self['metadata'].get('subtitle'):
            metadata['title'][0]['subtitle'] = [{
                'language':
                language,
                'value':
                self['metadata']['subtitle']
            }]

        # Other title
        if self['metadata'].get('otherLanguageTitle', {}).get('title'):
            metadata['title'][0]['mainTitle'].append({
                'language':
                self['metadata']['otherLanguageTitle'].get(
                    'language', language),
                'value':
                self['metadata']['otherLanguageTitle']['title']
            })

        # Languages
        metadata['language'] = [{'value': language, 'type': 'bf:Language'}]

        # Document date
        metadata['provisionActivity'] = [{
            'type':
            'bf:Publication',
            'startDate':
            self['metadata']['documentDate']
        }]
        metadata['provisionActivity'][0]['statement'] = []

        # Publication place
        if self['metadata'].get('publicationPlace'):
            metadata['provisionActivity'][0]['statement'].append({
                'label': [{
                    'value': self['metadata']['publicationPlace']
                }],
                'type':
                'bf:Place'
            })

        # Publisher
        if self['metadata'].get('publisher'):
            metadata['provisionActivity'][0]['statement'].append({
                'label': [{
                    'value': self['metadata']['publisher']
                }],
                'type':
                'bf:Agent'
            })

        # Add a statement for date
        metadata['provisionActivity'][0]['statement'].append({
            'label': [{
                'value':
                self['metadata']['statementDate']
                if self['metadata'].get('statementDate') else
                self['metadata']['documentDate']
            }],
            'type':
            'Date'
        })

        # Published in
        if self['metadata'].get('publication'):
            year = self['metadata']['publication']['year'] if self['metadata'][
                'publication'].get(
                    'year') else self['metadata']['documentDate']
            part_of = {
                'numberingYear': year,
                'document': {
                    'title': self['metadata']['publication']['publishedIn']
                }
            }

            if self['metadata']['publication'].get('pages'):
                part_of['numberingPages'] = self['metadata']['publication'][
                    'pages']

            if self['metadata']['publication'].get('volume'):
                part_of['numberingVolume'] = self['metadata']['publication'][
                    'volume']

            if self['metadata']['publication'].get('number'):
                part_of['numberingIssue'] = self['metadata']['publication'][
                    'number']

            if self['metadata']['publication'].get('editors'):
                part_of['document']['contribution'] = self['metadata'][
                    'publication']['editors']

            if self['metadata']['publication'].get('publisher'):
                part_of['document']['publication'] = {
                    'statement': self['metadata']['publication']['publisher']
                }

            if self['metadata']['publication'].get('identifiedBy'):
                part_of['document']['identifiedBy'] = self['metadata'][
                    'publication']['identifiedBy']

            metadata['partOf'] = [part_of]

        # Other electronic versions
        if self['metadata'].get('otherElectronicVersions'):
            metadata['otherEdition'] = [{
                'document': {
                    'electronicLocator': link['url']
                },
                'publicNote': link['publicNote']
            } for link in self['metadata']['otherElectronicVersions']]

        # Collections
        if self['metadata'].get('collections'):
            collections = []
            for collection in self['metadata'].get('collections'):
                # Create a new project
                if not collection.get('$ref'):
                    data = collection.copy()
                    # Store organisation
                    data['organisation'] = current_user_record['organisation']
                    collection_record = CollectionRecord.create(data)
                    collection_record.reindex()
                    collection = {
                        '$ref':
                        SonarRecord.get_ref_link('collections',
                                                 collection_record['pid'])
                    }

                collections.append(collection)

            if collections:
                metadata['collections'] = collections

        # Classification
        if self['metadata'].get('classification'):
            metadata['classification'] = [{
                'type':
                'bf:ClassificationUdc',
                'classificationPortion':
                self['metadata']['classification']
            }]

        # Abstracts
        if self['metadata'].get('abstracts'):
            metadata['abstracts'] = [{
                'language':
                abstract.get('language', language),
                'value':
                abstract['abstract']
            } for abstract in self['metadata']['abstracts']]

        # Dissertation
        if self['metadata'].get('dissertation'):
            metadata['dissertation'] = self['metadata']['dissertation']

        # Subjects
        if self['metadata'].get('subjects'):
            metadata['subjects'] = [{
                'label': {
                    'language': subject.get('language', language),
                    'value': subject['subjects']
                }
            } for subject in self['metadata']['subjects']]

        # Identifiers
        identifiers = []
        if self['metadata'].get('identifiedBy'):
            for identifier in self['metadata']['identifiedBy']:
                data = {
                    'type': identifier['type'],
                    'value': identifier['value'],
                }

                if identifier.get('source'):
                    data['source'] = identifier['source']

                # Special for PMID
                if identifier['type'] == 'pmid':
                    data['source'] = 'PMID'
                    data['type'] = 'bf:Local'

                identifiers.append(data)

        if identifiers:
            metadata['identifiedBy'] = identifiers

        # Content note
        if self['metadata'].get('contentNote'):
            metadata['contentNote'] = self['metadata']['contentNote']

        # Extent
        if self['metadata'].get('extent'):
            metadata['extent'] = self['metadata']['extent']

        # Additional materials
        if self['metadata'].get('additionalMaterials'):
            metadata['additionalMaterials'] = self['metadata'][
                'additionalMaterials']

        # Formats
        if self['metadata'].get('formats'):
            metadata['formats'] = self['metadata']['formats']

        # Other material characteristics
        if self['metadata'].get('otherMaterialCharacteristics'):
            metadata['otherMaterialCharacteristics'] = self['metadata'][
                'otherMaterialCharacteristics']

        # Edition statement
        if self['metadata'].get('editionStatement'):
            metadata['editionStatement'] = self['metadata']['editionStatement']

        # Notes
        if self['metadata'].get('notes'):
            metadata['notes'] = self['metadata']['notes']

        # Series
        if self['metadata'].get('series'):
            metadata['series'] = self['metadata']['series']

        # Custom fields
        for field_number in range(1, 4):
            field = f'customField{field_number}'
            document_field = self['metadata'].get(field)
            if document_field:
                metadata[field] = document_field

        # Contributors
        contributors = []
        for contributor in self.get('contributors', []):
            data = {
                'agent': {
                    'type': 'bf:Person',
                    'preferred_name': contributor['name']
                },
                'role': [contributor['role']]
            }

            if contributor.get('date_of_birth'):
                 data['agent']['date_of_birth'] = contributor['date_of_birth']

            if contributor.get('date_of_death'):
                 data['agent']['date_of_death'] = contributor['date_of_death']

            if contributor.get('affiliation'):
                data['affiliation'] = contributor['affiliation']

            # ORCID for contributor
            if contributor.get('orcid'):
                data['agent']['identifiedBy'] = {
                    'type': 'bf:Local',
                    'source': 'ORCID',
                    'value': contributor['orcid']
                }

            contributors.append(data)

        if contributors:
            metadata['contribution'] = contributors

        # Projects
        if self.get('projects'):
            projects = []

            for project in self['projects']:
                # Create a new project
                if not project.get('$ref'):
                    data = project.copy()

                    # Store user
                    data['user'] = self['user']

                    # Store organisation
                    data['organisation'] = current_user_record['organisation']

                    project_record = sonar.service('projects').create(
                        g.identity, {'metadata': data})
                    project = {
                        '$ref':
                        SonarRecord.get_ref_link('projects',
                                                 project_record['id'])
                    }

                projects.append(project)

            if projects:
                metadata['projects'] = projects

        # License
        metadata['usageAndAccessPolicy'] = {
            'license': self['diffusion']['license']
        }

        # Open access status
        if self['diffusion'].get('oa_status'):
            metadata['oa_status'] = self['diffusion']['oa_status']

        # Subdivisions
        if self['diffusion'].get('subdivisions'):
            metadata['subdivisions'] = self['diffusion']['subdivisions']


        # Masked
        if self['diffusion'].get('masked') is not None:
            metadata['masked'] = self['diffusion']['masked']
        document = DocumentRecord.create(metadata,
                                         dbcommit=True,
                                         with_bucket=True)

        current_order = 2
        for file in self.files:
            with file.file.storage().open() as pdf_file:
                content = pdf_file.read()

                if file.get('category', 'main') == 'main':
                    order = 1
                else:
                    order = current_order
                    current_order += 1

                kwargs = {
                    'label': file.get('label', file['key']),
                    'order': order
                }

                if file.get('embargo', False) and file.get('embargoDate'):
                    kwargs['access'] = 'coar:c_f1cf'  # Embargoed access
                    kwargs['embargo_date'] = file['embargoDate']
                    kwargs['restricted_outside_organisation'] = file.get(
                        'exceptInOrganisation', False)

                document.add_file(content, file['key'], **kwargs)

        document.commit()
        document.reindex()

        self['document'] = {
            '$ref': DocumentRecord.get_ref_link('documents', document['pid'])
        }

        return document