Assume every json entry may be null

Depending on the tool used to save the metadata to the file, not every
value is properly saved. Before storing a null value in the database,
skip this value.
This commit is contained in:
Patrick Farwick 2021-11-04 22:42:24 +00:00
parent 52c0f4b9e9
commit c058bc9538
4 changed files with 109 additions and 38 deletions

View File

@ -1,16 +1,17 @@
using System.Text.Json.Serialization;
#nullable enable
namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
{
public class ComicBookInfoFormat
{
[JsonPropertyName("appID")]
public string AppId { get; set; }
public string? AppId { get; set; }
[JsonPropertyName("lastModified")]
public string LastModified { get; set; }
public string? LastModified { get; set; }
[JsonPropertyName("ComicBookInfo/1.0")]
public ComicBookInfoMetadata Metadata { get; set; }
public ComicBookInfoMetadata? Metadata { get; set; }
}
}

View File

@ -1,16 +1,17 @@
using System.Text.Json.Serialization;
#nullable enable
namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
{
public class ComicBookInfoCredit
{
[JsonPropertyName("person")]
public string Person { get; set; }
public string? Person { get; set; }
[JsonPropertyName("role")]
public string Role { get; set; }
public string? Role { get; set; }
[JsonPropertyName("primary")]
public string Primary { get; set; }
public string? Primary { get; set; }
}
}

View File

@ -1,23 +1,24 @@
using System.Text.Json.Serialization;
#nullable enable
namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
{
public class ComicBookInfoMetadata
{
[JsonPropertyName("series")]
public string Series { get; set; }
public string? Series { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; }
public string? Title { get; set; }
[JsonPropertyName("publisher")]
public string Publisher { get; set; }
public string? Publisher { get; set; }
[JsonPropertyName("publicationMonth")]
public int PublicationMonth { get; set; }
public int? PublicationMonth { get; set; }
[JsonPropertyName("publicationYear")]
public int PublicationYear { get; set; }
public int? PublicationYear { get; set; }
[JsonPropertyName("issue")]
public int? Issue { get; set; }
@ -32,24 +33,24 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
public int? NumberOfVolumes { get; set; }
[JsonPropertyName("rating")]
public int? Ratung { get; set; }
public int? Rating { get; set; }
[JsonPropertyName("genre")]
public string Genre { get; set; }
public string? Genre { get; set; }
[JsonPropertyName("language")]
public string Language { get; set; }
public string? Language { get; set; }
[JsonPropertyName("country")]
public string Country { get; set; }
public string? Country { get; set; }
[JsonPropertyName("credits")]
public ComicBookInfoCredit[] Credits { get; set; }
public ComicBookInfoCredit[]? Credits { get; set; }
[JsonPropertyName("tags")]
public string[] Tags { get; set; }
public string[]? Tags { get; set; }
[JsonPropertyName("comments")]
public string Comments { get; set; }
public string? Comments { get; set; }
}
}

View File

@ -7,6 +7,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Archives.Zip;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.IO;
@ -41,7 +42,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
{
using Stream stream = File.OpenRead(path);
// not yet async: https://github.com/adamhathcock/sharpcompress/pull/565
using var archive = SharpCompress.Archives.Zip.ZipArchive.Open(stream);
using var archive = ZipArchive.Open(stream);
if (archive.IsComplete)
{
@ -92,43 +93,97 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
private MetadataResult<Book> SaveMetadata(ComicBookInfoFormat comic)
{
var book = new Book
if (comic.Metadata is null)
{
Name = comic.Metadata.Title,
SeriesName = comic.Metadata.Series,
ProductionYear = comic.Metadata.PublicationYear,
IndexNumber = comic.Metadata.Issue,
Tags = comic.Metadata.Tags
};
return new MetadataResult<Book> { HasMetadata = false };
}
book.SetStudios(new[] { comic.Metadata.Series });
book.PremiereDate = ReadTwoPartDateInto(comic.Metadata.PublicationYear, comic.Metadata.PublicationMonth);
book.AddGenre(comic.Metadata.Genre);
var book = ReadComicBookMetadata(comic.Metadata);
if (book is null)
{
return new MetadataResult<Book> { HasMetadata = false };
}
var metadataResult = new MetadataResult<Book> { Item = book, HasMetadata = true };
metadataResult.ResultLanguage = ReadCultureInfoAsThreeLetterIsoInto(comic.Metadata.Language);
foreach (var person in comic.Metadata.Credits)
if (comic.Metadata.Language is not null)
{
var personInfo = new PersonInfo { Name = person.Person, Type = person.Role };
metadataResult.AddPerson(personInfo);
metadataResult.ResultLanguage = ReadCultureInfoAsThreeLetterIsoInto(comic.Metadata.Language);
}
if (comic.Metadata.Credits is not null && comic.Metadata.Credits.Length > 0)
{
foreach (var person in comic.Metadata.Credits)
{
if (person.Person is null || person.Role is null)
{
continue;
}
var personInfo = new PersonInfo { Name = person.Person, Type = person.Role };
metadataResult.AddPerson(personInfo);
}
}
return metadataResult;
}
private string? ReadCultureInfoAsThreeLetterIsoInto(string language)
private Book? ReadComicBookMetadata(ComicBookInfoMetadata comic)
{
try
var book = new Book();
var hasFoundMetadata = false;
hasFoundMetadata |= ReadStringInto(comic.Title, (title) => book.Name = title);
hasFoundMetadata |= ReadStringInto(comic.Series, (series) => book.SeriesName = series);
hasFoundMetadata |= ReadStringInto(comic.Genre, (genre) => book.AddGenre(genre));
hasFoundMetadata |= ReadStringInto(comic.Comments, (overview) => book.Overview = overview);
hasFoundMetadata |= ReadStringInto(comic.Publisher, (publisher) => book.SetStudios(new[] { publisher }));
if (comic.PublicationYear is not null)
{
return new CultureInfo(language).ThreeLetterISOLanguageName;
book.ProductionYear = comic.PublicationYear;
hasFoundMetadata |= true;
}
catch (Exception)
if (comic.Issue is not null)
{
book.IndexNumber = comic.Issue;
hasFoundMetadata |= true;
}
if (comic.Tags is not null && comic.Tags.Length > 0)
{
book.Tags = comic.Tags;
hasFoundMetadata |= true;
}
if (comic.PublicationYear is not null && comic.PublicationMonth is not null)
{
book.PremiereDate = ReadTwoPartDateInto(comic.PublicationYear.Value, comic.PublicationMonth.Value);
hasFoundMetadata |= true;
}
if (hasFoundMetadata)
{
return book;
}
else
{
//Ignored
return null;
}
}
private bool ReadStringInto(string? data, Action<string> commitResult)
{
if (!string.IsNullOrWhiteSpace(data))
{
commitResult(data);
return true;
}
return false;
}
private DateTime? ReadTwoPartDateInto(int year, int month)
{
//Try-Catch because DateTime actually wants a real date, how boring
@ -145,6 +200,19 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
}
}
private string? ReadCultureInfoAsThreeLetterIsoInto(string language)
{
try
{
return new CultureInfo(language).ThreeLetterISOLanguageName;
}
catch (Exception)
{
//Ignored
return null;
}
}
private FileSystemMetadata? GetComicBookFile(string path)
{
var fileInfo = _fileSystem.GetFileSystemInfo(path);