class PresentationManifestTester(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(PresentationManifestTester, self).__init__(*args, **kwargs)
        self.book_pages = [
            ("agrtfhs:2279", 1),
            ("agrtfhs:2278", 2),
            ("agrtfhs:2291", 3),
            ("agrtfhs:2290", 4),
            ("agrtfhs:2289", 5),
            ("agrtfhs:2288", 6),
            ("agrtfhs:2287", 7),
            ("agrtfhs:2286", 8),
            ("agrtfhs:2285", 9),
            ("agrtfhs:2284", 10),
            ("agrtfhs:2283", 11),
            ("agrtfhs:2282", 12),
            ("agrtfhs:2281", 13),
            ("agrtfhs:2280", 14),
            ("agrtfhs:2277", 15),
            ("agrtfhs:2276", 16),
        ]
        self.metadata = MODSScraper(
            "agrtfhs:2275").build_iiif_descriptive_metadata_v2()
        self.collection = "collections:agrtfhs"
        self.validator = IIIFValidator(debug=True, collect_warnings=False)

    def test_presentation_manifest(self):
        manifest = Manifest(self.metadata, self.book_pages, self.collection)
        self.validator.validate(manifest.manifest_json)
        self.assertTrue(self.validator.is_valid)
def get_archivelab_org_validator():
    class PatchedManifestValidator(ManifestValidator):
        # Replace the image API with the presentation API at manifest level.
        def context_field(self, value):
            if value == 'http://iiif.io/api/image/2/context.json':
                self.log_warning("@context", "Applied library specific corrections. "
                                                 "Replaced image context with presentation context.")
                return self.PRESENTATION_API_URI
            return value

    class PatchedSequenceValidator(SequenceValidator):
        @SequenceValidator.errors_to_warnings
        def context_field(self, value):
            return super().context_field(value)

    class PatchedAnnotationValidator(AnnotationValidator):
        REQUIRED_FIELDS = AnnotationValidator.REQUIRED_FIELDS - {"on", "@type"}

        def setup(self):
            self.ImageSchema['type'] = self.type_field

    iv = IIIFValidator()
    iv.ManifestValidator = PatchedManifestValidator
    iv.AnnotationValidator = PatchedAnnotationValidator
    iv.SequenceValidator = PatchedSequenceValidator
    return iv
def test_iiif_manifest_schema(running_app, es_clear, client_with_login,
                              headers, minimal_record):
    client = client_with_login
    file_id = "test_image.png"
    recid = publish_record_with_images(client, file_id, minimal_record,
                                       headers)
    response = client.get(f"/iiif/record:{recid}/manifest")
    manifest = response.json
    validator = IIIFValidator(fail_fast=False)
    validator.validate(manifest)
    assert not validator.errors
def get_vatlib_it_validator():
    class PatchedAnnotationValidator(AnnotationValidator):
        def setup(self):
            self.REQUIRED_FIELDS = AnnotationValidator.REQUIRED_FIELDS - {"on"}
            self.RECOMMENDED_FIELDS = AnnotationValidator.RECOMMENDED_FIELDS & {"on"}

    class PatchedCanvasValidator(CanvasValidator):
        def viewing_hint_field(self, value):
            val, errs = self.mute_errors(super().viewing_hint_field, value)
            if errs:
                if val == "paged":
                    self.log_warning("viewingHint", "Applied library specific corrections. Allowd value 'paged'.")

    iv = IIIFValidator()
    iv.AnnotationValidator = PatchedAnnotationValidator
    iv.CanvasValidator = PatchedCanvasValidator
    return iv
def get_harvard_edu_validator():
    def str_to_int(self, field, value):
        """Coerce strings to ints."""
        if isinstance(value, int):
            return value
        try:
            val = int(value)
            self.log_warning(field, "Coerced to int.")
            return val
        except ValueError:
            self.log_error(field, "Could not coerce to int.")
            return value

    BaseValidator.width_field = lambda self, value: str_to_int(self, "width", value)
    BaseValidator.height_field = lambda self, value: str_to_int(self, "height", value)

    class PatchedImageContentValidator(ImageContentValidator):
        def service_field(self, value):
            """Add a context to the service if none exists."""
            val, errs = self.mute_errors(super().service_field, value)
            if not val.get('@context'):
                val['@context'] = 'http://library.stanford.edu/iiif/image-api/1.1/context.json'
                self.log_warning("@context", "Applied library specific corrections. Added @context to images.")
            return val

    class PatchedManifestValidator(ManifestValidator):
        @ManifestValidator.errors_to_warnings
        def context_field(self, value):
            """Allow the unknown top level context (since it doesn't seem to break things)"""
            return super().context_field(value)

        @ManifestValidator.errors_to_warnings
        def license_field(self, value):
            """Allow non uri in license field."""

            return super().license_field(value)

    iv = IIIFValidator()
    iv.ManifestValidator = PatchedManifestValidator
    iv.ImageContentValidator = PatchedImageContentValidator
    return iv
def get_gallica_bnf_fr_validator():

    class PatchedManifestValidator(ManifestValidator):
        # Squash the lang-val pairs down to one value, separated by semicolon.

        def metadata_field(self, value):

            """Correct any metadata entries missing a language key in lang-val pairs."""
            values, errs = self.mute_errors(super().metadata_field, value)
            if not errs:
                return values
            for value in values:
                v = value.get('value')
                if isinstance(v, list) and not all(vsub.get("@language") for vsub in v):
                    value['value'] = "; ".join((vsub.get("@value", "") for vsub in v))
                    self.log_warning("metadata", "Applied library specific corrections: "
                                                     "metadata field bad formatting ignored.")
            return values

    iv = IIIFValidator()
    iv.ManifestValidator = PatchedManifestValidator
    return iv