Source code for fairdm.core.project.validators

"""Validators for the project app."""

from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

#: The keys a DataCite funding reference may carry. No others are accepted.
FUNDING_REFERENCE_KEYS = frozenset(
    {
        "funderName",
        "funderIdentifier",
        "funderIdentifierType",
        "awardNumber",
        "awardTitle",
        "awardURI",
    }
)

#: DataCite's controlled set of funder identifier schemes.
FUNDER_IDENTIFIER_TYPES = ("ISNI", "GRID", "Crossref Funder ID", "ROR", "Other")


[docs] def validate_funding(value): """Validate that a value is a list of DataCite funding references. A project may carry several funding records, so the stored value must be a list. Each member must be an object carrying only keys from ``FUNDING_REFERENCE_KEYS``, with ``funderName`` required and every other key optional. A ``funderIdentifierType``, when present, must be one of DataCite's identifier schemes. Args: value: The funding value to validate. Raises: ValidationError: The value is not a list of funding reference objects. The error code is ``funding_not_list``, ``funding_unknown_key``, ``funding_missing_funder_name``, ``funding_invalid_type`` or ``funding_invalid_identifier_type``. """ if not isinstance(value, list): raise ValidationError( _("Funding must be a list of funding reference objects."), code="funding_not_list", ) for record in value: if not isinstance(record, dict): raise ValidationError( _("Funding must be a list of funding reference objects."), code="funding_not_list", ) unknown_keys = set(record) - FUNDING_REFERENCE_KEYS if unknown_keys: raise ValidationError( _( "'%(keys)s' is not a recognised funding reference field. " "Accepted fields are: %(accepted)s." ), code="funding_unknown_key", params={ "keys": ", ".join(sorted(unknown_keys)), "accepted": ", ".join(sorted(FUNDING_REFERENCE_KEYS)), }, ) funder_name = record.get("funderName") if not isinstance(funder_name, str) or not funder_name: raise ValidationError( _("Every funding reference must name a funder."), code="funding_missing_funder_name", ) for key in FUNDING_REFERENCE_KEYS - {"funderName"}: value_ = record.get(key) if value_ is not None and not isinstance(value_, str): raise ValidationError( _("'%(key)s' must be given as a string."), code="funding_invalid_type", params={"key": key}, ) identifier_type = record.get("funderIdentifierType") if identifier_type and identifier_type not in FUNDER_IDENTIFIER_TYPES: raise ValidationError( _( "'%(value)s' is not a funder identifier scheme DataCite " "defines. Accepted schemes are: %(schemes)s." ), code="funding_invalid_identifier_type", params={ "value": identifier_type, "schemes": ", ".join(FUNDER_IDENTIFIER_TYPES), }, )