using LibraryDTO; using Newtonsoft.Json.Linq; using System.Globalization; namespace JsonReader { public static class AuthorJsonReader { public static AuthorDTO ReadAuthor(string json) { JObject o = JObject.Parse(json); string bioTokenAsString = null; if (o.TryGetValue("bio", out JToken? bioToken)) { if (bioToken.Type == JTokenType.String) { bioTokenAsString = (string)bioToken; } else { var bioTokenValue = o["bio"]?["value"]; bioTokenAsString = (string)bioTokenValue; } } AuthorDTO author = new AuthorDTO { Id = (string)o["key"], Name = (string)o["name"], Bio = bioTokenAsString, BirthDate = o.TryGetValue("birth_date", out JToken? bd) ? ReadDate((string)o["birth_date"]) : null, DeathDate = o.TryGetValue("death_date", out JToken? dd) ? ReadDate((string)o["death_date"]) : null, Links = o.TryGetValue("links", out JToken? links) ? links.Select(l => new LinkDTO { Title = (string)l["title"], Url = (string)l["url"] }).ToList() : new List(), AlternateNames = o.TryGetValue("alternate_names", out JToken? altNames) ? altNames.Select(alt => (string)alt).ToList() : new List() }; return author; } public static DateTime? ReadDate(string dateInJson) { if (dateInJson == null) return null; List> pubDateFormat = new List>() { Tuple.Create("d MMMM yyyy", CultureInfo.GetCultureInfo("fr-FR")), Tuple.Create("d MMMM yyyy", CultureInfo.InvariantCulture), Tuple.Create("MMM dd, yyyy", CultureInfo.InvariantCulture) }; DateTime? publishDate = null; foreach (var format in pubDateFormat) { if (DateTime.TryParseExact(dateInJson, format.Item1, format.Item2, DateTimeStyles.None, out DateTime readDate)) { publishDate = readDate; break; } } if (!publishDate.HasValue && int.TryParse(dateInJson, out int year)) { publishDate = new DateTime(year, 12, 31); } return publishDate; } public static Tuple> GetAuthorsByName(string json) { JObject o = JObject.Parse(json); long numFound = (long)o["numFound"]; var authors = o["docs"].Select(doc => new AuthorDTO { Id = $"/authors/{(string)doc["key"]}", Name = (string)doc["name"], }); return Tuple.Create(numFound, authors); } } }