Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

deposit: Create document #136

Merged
merged 1 commit into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@
],
"invenio_records.jsonresolver": [
"institution = sonar.modules.institutions.jsonresolvers",
"user = sonar.modules.users.jsonresolvers"
"user = sonar.modules.users.jsonresolvers",
"document = sonar.modules.documents.jsonresolvers"
],
'invenio_celery.tasks' : [
'documents = sonar.modules.documents.tasks'
Expand Down
70 changes: 70 additions & 0 deletions sonar/modules/deposits/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
from datetime import datetime
from functools import partial

from sonar.modules.documents.api import DocumentRecord

from ..api import SonarRecord, SonarSearch
from ..fetchers import id_fetcher
from ..minters import id_minter
Expand Down Expand Up @@ -121,3 +123,71 @@ def log_action(self, user, action, comment=None):
self['logs'].append(log)

return log

def create_document(self):
"""Create document from deposit."""
metadata = {
'title': [{
'type':
'bf:Title',
'mainTitle': [{
'language': self['metadata']['languages'][0],
'value': self['metadata']['title']
}]
}],
'type':
self['metadata']['document_type'],
'language': [{
'type': 'bf:Language',
'value': language
} for language in self['metadata']['languages']],
}

for contributor in self['contributors']:
author = {'type': 'person', 'name': contributor['name']}
if contributor.get('affiliation'):
author['qualifier'] = contributor['affiliation']

metadata.get('authors', []).append(author)

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

for key, abstract in enumerate(self['metadata']['abstracts']):
metadata.get('abstracts', []).append({
'language':
self['metadata']['languages'][key]
if self['metadata']['languages'][key] else 'eng',
'value':
abstract
})

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

document.add_file(
content, file['key'], **{
'label': file.get('label', file['key']),
'order': order
})

document.commit()
document.reindex()

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

return document
14 changes: 14 additions & 0 deletions sonar/modules/deposits/jsonschemas/deposits/deposit-v1.0.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,20 @@
"enum": ["Rights reserved"]
}
}
},
"document": {
"title": "Document",
"description": "Document created on basis of this deposit.",
"type": "object",
"properties": {
"$ref": {
"type": "string",
"pattern": "^https://sonar.ch/api/documents/.*?$"
}
},
"required": [
"$ref"
]
}
}
}
18 changes: 7 additions & 11 deletions sonar/modules/deposits/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,8 @@ def post(pid=None):

key = request.args['key']

# Store full-text in a file
# text_key = change_filename_extension(key, 'txt')
# deposit.files[text_key] = BytesIO(
# extract_text_from_content(request.get_data()).encode())
# deposit.files[text_key]['category'] = request.args['type']
# deposit.files[text_key]['file_type'] = 'full-text'
# deposit.commit()

file_content = BytesIO(request.get_data())

# Store document
deposit.files[key] = file_content
deposit.files[key] = BytesIO(request.get_data())
deposit.files[key]['label'] = re.search(r'(.*)\..*$', key).group(1)
deposit.files[key]['embargo'] = False
deposit.files[key]['embargoDate'] = None
Expand Down Expand Up @@ -150,6 +140,9 @@ def publish(pid=None):
# Deposit can be validated directly
if user.is_granted(UserRecord.ROLE_MODERATOR):
deposit['status'] = DepositRecord.STATUS_VALIDATED

# Create document based on deposit
deposit.create_document()
else:
deposit['status'] = DepositRecord.STATUS_TO_VALIDATE

Expand Down Expand Up @@ -206,6 +199,9 @@ def review(pid=None):
if payload['action'] == DepositRecord.REVIEW_ACTION_APPROVE:
subject = 'Deposit approval'
status = DepositRecord.STATUS_VALIDATED

# Create document based on deposit
deposit.create_document()
elif payload['action'] == DepositRecord.REVIEW_ACTION_REJECT:
subject = 'Deposit rejection'
status = DepositRecord.STATUS_REJECTED
Expand Down
38 changes: 38 additions & 0 deletions sonar/modules/documents/jsonresolvers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
#
# Swiss Open Access Repository
# Copyright (C) 2019 RERO
#
# 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, version 3 of the License.
#
# 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 <http://www.gnu.org/licenses/>.

"""Document resolver."""

from __future__ import absolute_import, print_function

import jsonresolver
from invenio_pidstore.resolver import Resolver
from invenio_records.api import Record


# the host corresponds to the config value for the key JSONSCHEMAS_HOST
@jsonresolver.route('/api/documents/<pid>', host='sonar.ch')
def document_resolver(pid):
"""Resolve referenced document."""
resolver = Resolver(pid_type='doc', object_type="rec",
getter=Record.get_record)
_, record = resolver.resolve(pid)

if record.get('$schema'):
del record['$schema']

return record
60 changes: 0 additions & 60 deletions tests/api/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,70 +20,10 @@
from __future__ import absolute_import, print_function

import pytest
from flask_principal import ActionNeed
from invenio_access.models import ActionUsers, Role
from invenio_accounts.ext import hash_password
from invenio_app.factory import create_api

from sonar.modules.deposits.api import DepositRecord
from sonar.modules.users.api import UserRecord


@pytest.fixture(scope='module')
def create_app():
"""Create test app."""
return create_api


@pytest.fixture()
def user_fixture(app, db):
"""Create user in database."""
data = {
'email': 'user@rero.ch',
'full_name': 'John Doe',
'roles': ['user']
}

user = UserRecord.create(data, dbcommit=True)
user.reindex()
db.session.commit()

return user


@pytest.fixture()
def moderator_fixture(app, db):
"""Create moderator in database."""
data = {
'email': 'moderator@rero.ch',
'full_name': 'John Doe',
'roles': ['moderator']
}

user = UserRecord.create(data, dbcommit=True)
user.reindex()
db.session.commit()

return user


@pytest.fixture()
def deposit_fixture(app, db, user_fixture):
"""Create a deposit."""
data = {
'status': 'in progress',
'step': 'diffusion',
'metadata': {
'title': 'Title of deposit',
'languages': ['fre']
},
'user': {
'$ref':
'https://sonar.ch/api/users/{pid}'.format(pid=user_fixture['pid'])
}
}

deposit = DepositRecord.create(data, dbcommit=True, with_bucket=False)
deposit.reindex()
db.session.commit()
return deposit
27 changes: 19 additions & 8 deletions tests/api/deposits/test_deposits_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,18 @@

import json

from sonar.modules.deposits.rest import FilesResource

def test_publish(client, db, user_fixture, moderator_fixture, deposit_fixture):

def test_get(app, deposit_fixture):
"""Test get a deposit by its ID."""
response = FilesResource.get(deposit_fixture['pid'])
assert response.status_code == 200
assert len(response.json) == 2


def test_publish(client, db, db_user_fixture, db_moderator_fixture,
deposit_fixture):
"""Test publishing a deposit."""
url = 'https://localhost:5000/deposits/{pid}/publish'.format(
pid=deposit_fixture['pid'])
Expand All @@ -39,15 +49,16 @@ def test_publish(client, db, user_fixture, moderator_fixture, deposit_fixture):
# Test the publication by a moderator
deposit_fixture['status'] = 'in progress'
deposit_fixture.commit()
user_fixture['roles'] = ['moderator']
user_fixture.commit()
db_user_fixture['roles'] = ['moderator']
db_user_fixture.commit()
db.session.commit()

response = client.post(url, data={})
assert response.status_code == 200


def test_review(client, db, user_fixture, moderator_fixture, deposit_fixture):
def test_review(client, db, db_user_fixture, db_moderator_fixture,
deposit_fixture):
"""Test reviewing a deposit."""
url = 'https://localhost:5000/deposits/{pid}/review'.format(
pid=deposit_fixture['pid'])
Expand Down Expand Up @@ -83,7 +94,7 @@ def test_review(client, db, user_fixture, moderator_fixture, deposit_fixture):
data=json.dumps({
'action': 'approve',
'comment': None,
'user': user_fixture['pid']
'user': db_user_fixture['pid']
}),
headers=headers)
assert response.status_code == 403
Expand All @@ -93,7 +104,7 @@ def test_review(client, db, user_fixture, moderator_fixture, deposit_fixture):
data=json.dumps({
'action': 'approve',
'comment': None,
'user': moderator_fixture['pid']
'user': db_moderator_fixture['pid']
}),
headers=headers)
assert response.status_code == 200
Expand All @@ -106,7 +117,7 @@ def test_review(client, db, user_fixture, moderator_fixture, deposit_fixture):
data=json.dumps({
'action': 'reject',
'comment': 'Sorry deposit is not valid',
'user': moderator_fixture['pid']
'user': db_moderator_fixture['pid']
}),
headers=headers)
assert response.status_code == 200
Expand All @@ -119,7 +130,7 @@ def test_review(client, db, user_fixture, moderator_fixture, deposit_fixture):
data=json.dumps({
'action': 'ask-for-changes',
'comment': None,
'user': moderator_fixture['pid']
'user': db_moderator_fixture['pid']
}),
headers=headers)
assert response.status_code == 200
Loading