Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Handle TextualBody and PaintingAnnotation with Body array #59

Merged
merged 9 commits into from
Feb 10, 2025
7 changes: 2 additions & 5 deletions .github/workflows/build_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ jobs:
- name: Determine GitVersion
uses: gittools/actions/gitversion/execute@v0.9.7

- name: Setup NuGet
uses: NuGet/setup-nuget@v1.0.5

- name: Restore dependencies
run: nuget restore $SOLUTION
run: dotnet restore $SOLUTION

- name: Setup .NET
uses: actions/setup-dotnet@v3
Expand All @@ -60,4 +57,4 @@ jobs:

- name: Publish Package and Symbols
if: startsWith(github.ref, 'refs/tags/v')
run: nuget push **\*.nupkg -Source 'https://api.nuget.org/v3/index.json' -ApiKey ${{secrets.NUGET_API_KEY}}
run: dotnet nuget push **\*.nupkg --source 'https://api.nuget.org/v3/index.json' --api-key ${{secrets.NUGET_API_KEY}}
38 changes: 35 additions & 3 deletions src/IIIF/IIIF.Tests/Serialisation/ManifestSerialisationTests.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using FluentAssertions;
using IIIF.ImageApi.V2;
using IIIF.ImageApi.V3;
using IIIF.Presentation.V3;
using IIIF.Presentation.V3.Annotation;
using IIIF.Presentation.V3.Content;
using IIIF.Presentation.V3.Strings;
using IIIF.Serialisation;
using Xunit;
using ExternalResource = IIIF.Presentation.V3.Content.ExternalResource;

namespace IIIF.Tests.Serialisation;
Expand Down Expand Up @@ -50,6 +49,39 @@ public ManifestSerialisationTests()
Id = "https://test.example.com/canvas/1",
Width = 1000,
Height = 1001,
Annotations = new List<AnnotationPage>()
{
new()
{
Id = "https://test.example.com/canvas/1/page",
Items = new List<IAnnotation>
{
new GeneralAnnotation("canvassing")
{
JackLewis-digirati marked this conversation as resolved.
Show resolved Hide resolved
Body = new List<ResourceBase>
{
new TextualBody("Hello World!")
{
Id = "https://test.example.com/canvas/1/page/textualBody",
Format = "text/plain",
Purpose = "some purpose",
Creator = "https://test.example.com/user",
Created = DateTime.UtcNow,
Modified = DateTime.UtcNow,
Generator = "https://test.example.com/user",
Generated = DateTime.UtcNow,
Role = "https://test.example.com/user/role",
Audience = "everyone",
Accessibility = "public",
Canonical = "true",
Via = "somewhere",
Rights = "some rights"
}
}
}
}
}
},
Items = new List<AnnotationPage>
{
new()
Expand Down
18 changes: 18 additions & 0 deletions src/IIIF/IIIF/Presentation/V3/Annotation/GeneralAnnotation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections.Generic;
using IIIF.Serialisation;

namespace IIIF.Presentation.V3.Annotation;

/// <summary>
/// Used for any annotation that declares a body
/// </summary>
public sealed class GeneralAnnotation : Annotation
JackLewis-digirati marked this conversation as resolved.
Show resolved Hide resolved
{
public GeneralAnnotation(string? motivation)
{
Motivation = motivation;
}

[ObjectIfSingle]
[JsonProperty(Order = 500)] public List<ResourceBase>? Body { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;

namespace IIIF.Presentation.V3.Annotation;

[Obsolete("GeneralAnnotation should be used instead")]
public class SupplementingDocumentAnnotation : Annotation
{
public override string Motivation => Constants.Motivation.Supplementing;
Expand Down
39 changes: 39 additions & 0 deletions src/IIIF/IIIF/Presentation/V3/Annotation/TextualBody.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System;
using System.Collections.Generic;

namespace IIIF.Presentation.V3.Annotation;

public class TextualBody : ResourceBase
Expand All @@ -15,6 +18,42 @@ public TextualBody(string value, string format)

public override string Type => nameof(TextualBody);

[JsonProperty(Order = 300)]
public string? Value { get; set; }

[JsonProperty(Order = 301)]
public string? Format { get; set; }

[JsonProperty(Order = 302)]
public string? Purpose { get; set; }

[JsonProperty(Order = 303)]
public string? Creator { get; set; }

[JsonProperty(Order = 304)]
public DateTime? Created { get; set; }

[JsonProperty(Order = 305)]
public DateTime? Modified { get; set; }

[JsonProperty(Order = 306)]
public string? Generator { get; set; }

[JsonProperty(Order = 307)]
public DateTime? Generated { get; set; }

[JsonProperty(Order = 308)]
public string? Role { get; set; }

[JsonProperty(Order = 309)]
public string? Audience { get; set; }

[JsonProperty(Order = 310)]
public string? Accessibility { get; set; }

[JsonProperty(Order = 311)]
public string? Canonical { get; set; }

[JsonProperty(Order = 312)]
public string? Via { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
using System;

namespace IIIF.Presentation.V3.Annotation;

[Obsolete("GeneralAnnotation should be used instead")]
public class TypeClassifyingAnnotation : Annotation
{
public override string Motivation => Constants.Motivation.Classifying;

public ResourceBase? Body { get; set; }
}

/// <summary>
/// Marker class for deserialising json object with an unknown motivation
/// </summary>
internal sealed class UnknownMotivation : Annotation
{
public UnknownMotivation(string motivation)
{
Motivation = motivation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ public class AnnotationV3Converter : ReadOnlyConverter<IAnnotation>
{
var jsonObject = JObject.Load(reader);

IAnnotation annotation = jsonObject["motivation"].Value<string>() switch
var motivation = jsonObject["motivation"]?.Value<string>();
IAnnotation annotation = motivation switch
{
Presentation.V3.Constants.Motivation.Painting => new PaintingAnnotation(),
Presentation.V3.Constants.Motivation.Supplementing => new SupplementingDocumentAnnotation(),
JackLewis-digirati marked this conversation as resolved.
Show resolved Hide resolved
Presentation.V3.Constants.Motivation.Classifying => new TypeClassifyingAnnotation(),
_ => new Annotation()
_ => jsonObject["body"] is not { HasValues: true } ? new Annotation() : new GeneralAnnotation(motivation)
};

serializer.Populate(jsonObject.CreateReader(), annotation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ public class ResourceBaseV3Converter : ReadOnlyConverter<ResourceBase>

if (jsonObject.ContainsKey("motivation"))
{
var motivation = jsonObject["motivation"].Value<string>();
var motivation = jsonObject["motivation"]?.Value<string>();
resourceBase = motivation switch
{
Presentation.V3.Constants.Motivation.Supplementing => new SupplementingDocumentAnnotation(),
Presentation.V3.Constants.Motivation.Painting => new PaintingAnnotation(),
Presentation.V3.Constants.Motivation.Classifying => new TypeClassifyingAnnotation(),
_ => new UnknownMotivation(motivation)
_ => new GeneralAnnotation(motivation)
};
}

Expand Down
Loading