Skip to content

Commit

Permalink
Merge 172f68e into 49f22cd
Browse files Browse the repository at this point in the history
  • Loading branch information
ppanero committed Jul 22, 2020
2 parents 49f22cd + 172f68e commit 2c891d2
Show file tree
Hide file tree
Showing 16 changed files with 76 additions and 35 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Expand Up @@ -8,6 +8,11 @@
Changes
=======

Version 1.2.1 (released 2020-07-22)

- Support returning NEW and RESERVED PIDs by setting the `registered_only` flag.
- Support setting default status for PIDs with object type and uuid.

Version 1.2.0 (released 2020-03-09)

- Change exception interpolation for better aggregation
Expand Down
1 change: 0 additions & 1 deletion invenio_pidstore/admin.py
Expand Up @@ -9,7 +9,6 @@
"""Admin model views for PersistentIdentifier."""

import uuid

from flask import current_app, url_for
from flask_admin.contrib.sqla import ModelView
from flask_admin.contrib.sqla.filters import FilterEqual
Expand Down
1 change: 0 additions & 1 deletion invenio_pidstore/fetchers.py
Expand Up @@ -28,7 +28,6 @@ def my_fetcher(record_uuid, data):
from __future__ import absolute_import, print_function

from collections import namedtuple

from flask import current_app

from .providers.recordid import RecordIdProvider
Expand Down
8 changes: 4 additions & 4 deletions invenio_pidstore/models.py
Expand Up @@ -10,11 +10,11 @@

from __future__ import absolute_import, print_function

import logging
import uuid
from enum import Enum

import logging
import six
import uuid
from flask_babelex import gettext
from invenio_db import db
from speaklater import make_lazy_gettext
Expand Down Expand Up @@ -490,14 +490,14 @@ def is_deleted(self):
return self.status == PIDStatus.DELETED

def is_new(self):
"""Return true if the PIDhas not yet been registered or reserved.
"""Return true if the PID is new.
:returns: A boolean value.
"""
return self.status == PIDStatus.NEW

def is_reserved(self):
"""Return true if the PID has not yet been reserved.
"""Return true if the PID has been reserved.
:returns: A boolean value.
"""
Expand Down
11 changes: 8 additions & 3 deletions invenio_pidstore/providers/recordid_v2.py
Expand Up @@ -12,7 +12,6 @@
from __future__ import absolute_import

import copy

from base32_lib import base32
from flask import current_app

Expand All @@ -39,9 +38,15 @@ class RecordIdProviderV2(BaseProvider):
provide any additional features besides creation of record ids.
"""

default_status = PIDStatus.RESERVED
default_status_with_obj = PIDStatus.REGISTERED
"""Record IDs are by default registered immediately.
Default: :attr:`invenio_pidstore.models.PIDStatus.REGISTERED`
"""

default_status = PIDStatus.RESERVED
"""Record IDs with an object are by default reserved.
Default: :attr:`invenio_pidstore.models.PIDStatus.RESERVED`
"""

Expand Down Expand Up @@ -92,7 +97,7 @@ def create(cls, object_type=None, object_uuid=None, options=None,
kwargs.setdefault('status', cls.default_status)

if object_type and object_uuid:
kwargs['status'] = PIDStatus.REGISTERED
kwargs['status'] = cls.default_status_with_obj

return super(RecordIdProviderV2, cls).create(
object_type=object_type, object_uuid=object_uuid, **kwargs)
9 changes: 7 additions & 2 deletions invenio_pidstore/resolver.py
Expand Up @@ -24,7 +24,8 @@ class Resolver(object):
identifier.
"""

def __init__(self, pid_type=None, object_type=None, getter=None):
def __init__(self, pid_type=None, object_type=None, getter=None,
registered_only=True):
"""Initialize resolver.
:param pid_type: Persistent identifier type.
Expand All @@ -35,6 +36,7 @@ def __init__(self, pid_type=None, object_type=None, getter=None):
self.pid_type = pid_type
self.object_type = object_type
self.object_getter = getter
self.registered_only = registered_only

def resolve(self, pid_value):
"""Resolve a persistent identifier to an internal object.
Expand All @@ -45,7 +47,10 @@ def resolve(self, pid_value):
pid = PersistentIdentifier.get(self.pid_type, pid_value)

if pid.is_new() or pid.is_reserved():
raise PIDUnregistered(pid)
if self.registered_only:
raise PIDUnregistered(pid)
else:
obj_id = pid.get_assigned_object(object_type=self.object_type)

if pid.is_deleted():
obj_id = pid.get_assigned_object(object_type=self.object_type)
Expand Down
2 changes: 1 addition & 1 deletion invenio_pidstore/version.py
Expand Up @@ -14,4 +14,4 @@

from __future__ import absolute_import, print_function

__version__ = '1.2.0'
__version__ = '1.2.1'
2 changes: 1 addition & 1 deletion run-tests.sh
Expand Up @@ -9,7 +9,7 @@
# under the terms of the MIT License; see LICENSE file for more details.

pydocstyle invenio_pidstore tests docs && \
isort -rc -c -df && \
isort invenio_pidstore tests --check-only --diff && \
check-manifest --ignore ".travis-*" && \
sphinx-build -qnNW docs docs/_build/html && \
python setup.py test
13 changes: 3 additions & 10 deletions setup.py
Expand Up @@ -17,20 +17,13 @@
history = open('CHANGES.rst').read()

tests_require = [
'attrs>=17.4.0', # once pytest is upgraded this can be removed
'SQLAlchemy-Continuum>=1.2.1',
'check-manifest>=0.25',
'coverage>=4.0',
'isort>=4.3.0',
'invenio-admin>=1.2.0',
'Flask-Menu>=0.5.1',
'invenio-admin>=1.2.0',
'invenio-access>=1.0.0',
'invenio-accounts>=1.0.0',
'mock>=3.0.0',
'pydocstyle>=1.0.0',
'pytest-cov>=1.8.0',
'pytest-pep8>=1.0.6',
'pytest>=3.8.0,<5.0.0',
'pytest-invenio<=1.3.2',
'SQLAlchemy-Continuum>=1.2.1',
]

extras_require = {
Expand Down
3 changes: 1 addition & 2 deletions tests/conftest.py
Expand Up @@ -11,10 +11,9 @@
from __future__ import absolute_import, print_function

import os
import pytest
import shutil
import tempfile

import pytest
from flask import Flask
from invenio_db import InvenioDB
from sqlalchemy_utils.functions import create_database, database_exists
Expand Down
1 change: 0 additions & 1 deletion tests/test_admin.py
Expand Up @@ -10,7 +10,6 @@
from __future__ import absolute_import, print_function

import uuid

from flask_admin import Admin, menu
from invenio_db import db

Expand Down
1 change: 0 additions & 1 deletion tests/test_cli.py
Expand Up @@ -12,7 +12,6 @@
from __future__ import absolute_import, print_function

import uuid

from click.testing import CliRunner
from flask.cli import ScriptInfo

Expand Down
3 changes: 1 addition & 2 deletions tests/test_invenio_pidstore.py
Expand Up @@ -11,9 +11,8 @@

from __future__ import absolute_import, print_function

import uuid

import pytest
import uuid
from mock import patch
from sqlalchemy.exc import SQLAlchemyError

Expand Down
3 changes: 1 addition & 2 deletions tests/test_minters.py
Expand Up @@ -10,9 +10,8 @@

from __future__ import absolute_import, print_function

import uuid

import pytest
import uuid

from invenio_pidstore import current_pidstore
from invenio_pidstore.minters import recid_minter, recid_minter_v2
Expand Down
3 changes: 1 addition & 2 deletions tests/test_providers.py
Expand Up @@ -11,9 +11,8 @@

from __future__ import absolute_import, print_function

import uuid

import pytest
import uuid
from datacite.errors import DataCiteError, DataCiteGoneError, \
DataCiteNoContentError, DataCiteNotFoundError, HttpError
from mock import MagicMock, patch
Expand Down
45 changes: 43 additions & 2 deletions tests/test_resolver.py
Expand Up @@ -10,9 +10,8 @@

from __future__ import absolute_import, print_function

import uuid

import pytest
import uuid

from invenio_pidstore.errors import PIDDeletedError, PIDDoesNotExistError, \
PIDMissingObjectError, PIDRedirectedError, PIDUnregistered
Expand Down Expand Up @@ -126,3 +125,45 @@ def test_resolver_deleted_object(app, db):
pid_type='recid', object_type='rec', getter=records.get)

assert pytest.raises(PIDDeletedError, resolver.resolve, '1')


def test_resolver_not_registered_only(app, db):
"""Test the resolver returns a new and reserved PID when specified."""

status = [
PIDStatus.NEW,
PIDStatus.RESERVED,
PIDStatus.REGISTERED
]

with app.app_context():
rec_a = uuid.uuid4()
# Create pids for each status with and without object
for idx, s in enumerate(status, 1):
PersistentIdentifier.create('recid', idx*2 - 1, status=s)
PersistentIdentifier.create('recid', idx*2, status=s,
object_type='rec', object_uuid=rec_a)

db.session.commit()

# Start tests
resolver = Resolver(
pid_type='recid',
object_type='rec',
getter=lambda x: x,
registered_only=False)

# Resolve status new
pytest.raises(PIDMissingObjectError, resolver.resolve, '1')
pid, obj = resolver.resolve('2')
assert pid and obj == rec_a

# Resolve status reserved
pytest.raises(PIDMissingObjectError, resolver.resolve, '3')
pid, obj = resolver.resolve('4')
assert pid and obj == rec_a

# Resolve status registered
pytest.raises(PIDMissingObjectError, resolver.resolve, '5')
pid, obj = resolver.resolve('6')
assert pid and obj == rec_a

0 comments on commit 2c891d2

Please sign in to comment.