Skip to content
Snippets Groups Projects
Select Git revision
  • b9ca6d1085dcf70776c3eaf2f8278679239da590
  • main default protected
  • export
  • 28-conversion-tests
  • extraction
  • exploration
  • exploration-old
  • 2-encoding-fix
  • main-old
9 results

transform.py

Blame
  • SimpleAnnotationServerV2Adapter.js 6.04 KiB
    /** */
    export default class SimpleAnnotationServerV2Adapter {
      /** */
      constructor(canvasId, endpointUrl) {
        this.canvasId = canvasId;
        this.endpointUrl = endpointUrl;
      }
    
      /** */
      get annotationPageId() {
        return `${this.endpointUrl}/search?uri=${this.canvasId}`;
      }
    
      /** */
      async create(annotation) {
        return fetch(`${this.endpointUrl}/create`, {
          body: JSON.stringify(SimpleAnnotationServerV2Adapter.createV2Anno(annotation)),
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
          },
          method: 'POST',
        })
          .then((response) => this.all())
          .catch(() => this.all());
      }
    
      /** */
      async update(annotation) {
        return fetch(`${this.endpointUrl}/update`, {
          body: JSON.stringify(SimpleAnnotationServerV2Adapter.createV2Anno(annotation)),
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
          },
          method: 'POST',
        })
          .then((response) => this.all())
          .catch(() => this.all());
      }
    
      /** */
      async delete(annoId) {
        return fetch(`${this.endpointUrl}/destroy?uri=${encodeURIComponent(annoId)}`, {
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
          },
          method: 'DELETE',
        })
          .then((response) => this.all())
          .catch(() => this.all());
      }
    
      /** */
      async get(annoId) {
        // SAS does not have GET for a single annotation
        const annotationPage = await this.all();
        if (annotationPage) {
          return annotationPage.items.find((item) => item.id === annoId);
        }
        return null;
      }
    
      /** Returns an AnnotationPage with all annotations */
      async all() {
        const resp = await fetch(this.annotationPageId);
        const annos = await resp.json();
        return this.createAnnotationPage(annos);
      }
    
      /** Creates a V2 annotation from a V3 annotation */
      static createV2Anno(v3anno) {
        const v2anno = {
          '@context': 'http://iiif.io/api/presentation/2/context.json',
          '@type': 'oa:Annotation',
          motivation: 'oa:commenting',
          on: {
            '@type': 'oa:SpecificResource',
            full: v3anno.target.source.id,
          },
        };
        // copy id if it is SAS-generated
        if (v3anno.id && v3anno.id.startsWith('http')) {
          v2anno['@id'] = v3anno.id;
        }
        if (Array.isArray(v3anno.body)) {
          v2anno.resource = v3anno.body.map((b) => this.createV2AnnoBody(b));
        } else {
          v2anno.resource = this.createV2AnnoBody(v3anno.body);
        }
        if (v3anno.target.selector) {
          if (Array.isArray(v3anno.target.selector)) {
            const selectors = v3anno.target.selector.map((s) => this.createV2AnnoSelector(s));
            // create choice, assuming two elements and 0 is default
            v2anno.on.selector = {
              '@type': 'oa:Choice',
              default: selectors[0],
              item: selectors[1],
            };
          } else {
            v2anno.on.selector = this.createV2AnnoSelector(v3anno.target.selector);
          }
          if (v3anno.target.source.partOf) {
            v2anno.on.within = {
              '@id': v3anno.target.source.partOf.id,
              '@type': 'sc:Manifest',
            };
          }
        }
        return v2anno;
      }
    
      /** */
      static createV2AnnoBody(v3body) {
        const v2body = {
          chars: v3body.value,
        };
        if (v3body.purpose === 'tagging') {
          v2body['@type'] = 'oa:Tag';
        } else {
          v2body['@type'] = 'dctypes:Text';
        }
        if (v3body.format) {
          v2body.format = v3body.format;
        }
        if (v3body.language) {
          v2body.language = v3body.language;
        }
        return v2body;
      }
    
      /** */
      static createV2AnnoSelector(v3selector) {
        switch (v3selector.type) {
          case 'SvgSelector':
            return {
              '@type': 'oa:SvgSelector',
              value: v3selector.value,
            };
          case 'FragmentSelector':
            return {
              '@type': 'oa:FragmentSelector',
              value: v3selector.value,
            };
          default:
            return null;
        }
      }
    
      /** Creates an AnnotationPage from a list of V2 annotations */
      createAnnotationPage(v2annos) {
        if (Array.isArray(v2annos)) {
          const v3annos = v2annos.map((a) => SimpleAnnotationServerV2Adapter.createV3Anno(a));
          return {
            id: this.annotationPageId,
            items: v3annos,
            type: 'AnnotationPage',
          };
        }
        return v2annos;
      }
    
      /** Creates a V3 annotation from a V2 annotation */
      static createV3Anno(v2anno) {
        const v3anno = {
          id: v2anno['@id'],
          motivation: 'commenting',
          type: 'Annotation',
        };
        if (Array.isArray(v2anno.resource)) {
          v3anno.body = v2anno.resource.map((b) => this.createV3AnnoBody(b));
        } else {
          v3anno.body = this.createV3AnnoBody(v2anno.resource);
        }
        let v2target = v2anno.on;
        if (Array.isArray(v2target)) {
          [v2target] = v2target;
        }
        v3anno.target = {
          selector: this.createV3AnnoSelector(v2target.selector),
          source: v2target.full,
        };
        if (v2target.within) {
          v3anno.target.source = {
            id: v2target.full,
            partOf: {
              id: v2target.within['@id'],
              type: 'Manifest',
            },
            type: 'Canvas',
          };
        }
        return v3anno;
      }
    
      /** */
      static createV3AnnoBody(v2body) {
        const v3body = {
          type: 'TextualBody',
          value: v2body.chars,
        };
        if (v2body.format) {
          v3body.format = v2body.format;
        }
        if (v2body.language) {
          v3body.language = v2body.language;
        }
        if (v2body['@type'] === 'oa:Tag') {
          v3body.purpose = 'tagging';
        }
        return v3body;
      }
    
      /** */
      static createV3AnnoSelector(v2selector) {
        switch (v2selector['@type']) {
          case 'oa:SvgSelector':
            return {
              type: 'SvgSelector',
              value: v2selector.value,
            };
          case 'oa:FragmentSelector':
            return {
              type: 'FragmentSelector',
              value: v2selector.value,
            };
          case 'oa:Choice':
            /* create alternate selectors */
            return [
              this.createV3AnnoSelector(v2selector.default),
              this.createV3AnnoSelector(v2selector.item),
            ];
          default:
            return null;
        }
      }
    }