ADD : Model generated

commands-19-09
Lou BRODA 1 year ago
parent 781604b8bb
commit 66f813b98d

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LibraryDTO\LibraryDTO.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,102 @@
using LibraryDTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DtoAbstractLayer
{
/// <summary>
/// abstract layer for requests on Books Library
/// </summary>
public interface IDtoManager
{
/// <summary>
/// get a book by specifying its id
/// </summary>
/// <param name="id">id of the Book to get</param>
/// <returns>a Book with this id (or null if id is unknown)</returns>
Task<BookDTO> GetBookById(string id);
/// <summary>
/// get a book by specifying its isbn
/// </summary>
/// <param name="isbn">isbn of the Book to get</param>
/// <returns>a Book with this isbn (or null if isbn is unknown)</returns>
Task<BookDTO> GetBookByISBN(string isbn);
/// <summary>
/// get books containing a substring in their titles
/// </summary>
/// <param name="title">the substring to look for in book titles</param>
/// <param name="index">index of the page of resulting books</param>
/// <param name="count">number of resulting books per page</param>
/// <param name="sort">sort criterium (not mandatory):
/// <ul>
/// <li>```title```: sort books by titles in alphabetical order,</li>
/// <li>```title_reverse```: sort books by titles in reverse alphabetical order,</li>
/// <li>```new```: sort books by publishing dates, beginning with the most recents,</li>
/// <li>```old```: sort books by publishing dates, beginning with the oldest</li>
/// </ul>
/// </param>
/// <returns>max <i>count</i> books</returns>
Task<Tuple<long, IEnumerable<BookDTO>>> GetBooksByTitle(string title, int index, int count, string sort = "");
/// <summary>
/// get books of a particular author by giving the author id
/// </summary>
/// <param name="authorId">the id of the author</param>
/// <param name="index">index of the page of resulting books</param>
/// <param name="count">number of resulting books per page</param>
/// <param name="sort">sort criterium (not mandatory):
/// <ul>
/// <li>```title```: sort books by titles in alphabetical order,</li>
/// <li>```title_reverse```: sort books by titles in reverse alphabetical order,</li>
/// <li>```new```: sort books by publishing dates, beginning with the most recents,</li>
/// <li>```old```: sort books by publishing dates, beginning with the oldest</li>
/// </ul>
/// </param>
/// <returns>max <i>count</i> books</returns>
Task<Tuple<long, IEnumerable<BookDTO>>> GetBooksByAuthorId(string authorId, int index, int count, string sort = "");
/// <summary>
/// get books of authors whose name (or alternate names) contains a particular substring
/// </summary>
/// <param name="author">name to look for in author names or alternate names</param>
/// <param name="index">index of the page of resulting books</param>
/// <param name="count">number of resulting books per page</param>
/// <param name="sort">sort criterium (not mandatory):
/// <ul>
/// <li>```title```: sort books by titles in alphabetical order,</li>
/// <li>```title_reverse```: sort books by titles in reverse alphabetical order,</li>
/// <li>```new```: sort books by publishing dates, beginning with the most recents,</li>
/// <li>```old```: sort books by publishing dates, beginning with the oldest</li>
/// </ul>
/// </param>
/// <returns>max <i>count</i> books</returns>
Task<Tuple<long, IEnumerable<BookDTO>>> GetBooksByAuthor(string author, int index, int count, string sort = "");
/// <summary>
/// get an author by specifying its id
/// </summary>
/// <param name="id">id of the Author to get</param>
/// <returns>an author with this id (or null if id is unknown)</returns>
Task<AuthorDTO> GetAuthorById(string id);
/// <summary>
/// get authors containing a substring in their names (or alternate names)
/// </summary>
/// <param name="substring">the substring to look for in author names (or alternate names)</param>
/// <param name="index">index of the page of resulting authors</param>
/// <param name="count">number of resulting authors per page</param>
/// <param name="sort">sort criterium (not mandatory):
/// <ul>
/// <li>```name```: sort authors by names in alphabetical order,</li>
/// <li>```name_reverse```: sort authors by names in reverse alphabetical order,</li>
/// </ul>
/// </param>
/// <returns>max <i>count</i> authors</returns>
Task<Tuple<long, IEnumerable<AuthorDTO>>> GetAuthorsByName(string substring, int index, int count, string sort = "");
}
}

@ -0,0 +1,78 @@
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<LinkDTO>(),
AlternateNames = o.TryGetValue("alternate_names", out JToken? altNames) ? altNames.Select(alt => (string)alt).ToList() : new List<string?>()
};
return author;
}
public static DateTime? ReadDate(string dateInJson)
{
if (dateInJson == null) return null;
List<Tuple<string, CultureInfo>> pubDateFormat = new List<Tuple<string, CultureInfo>>()
{
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<long, IEnumerable<AuthorDTO>> 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);
}
}
}

@ -0,0 +1,101 @@
using LibraryDTO;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JsonReader
{
public static class BookJsonReader
{
static Dictionary<string, Languages> languages = new Dictionary<string, Languages>()
{
[@"/languages/fre"] = Languages.French,
[@"/languages/eng"] = Languages.English,
["fre"] = Languages.French,
["eng"] = Languages.English,
[""] = Languages.Unknown
};
public static BookDTO ReadBook(string json)
{
JObject o = JObject.Parse(json);
var l = o["languages"]?.FirstOrDefault("");
Languages lang = l != null ? languages[(string)l["key"]] : Languages.Unknown;
//List<Tuple<string, CultureInfo>> pubDateFormat =new List<Tuple<string, CultureInfo>>()
//{
// Tuple.Create("d MMMM yyyy", CultureInfo.GetCultureInfo("fr-FR")),
// Tuple.Create("MMM dd, yyyy", CultureInfo.InvariantCulture)
//};
//DateTime? publishDate = null;
//foreach(var format in pubDateFormat)
//{
// if(DateTime.TryParseExact((string)o["publish_date"], format.Item1, format.Item2, DateTimeStyles.None, out DateTime readDate))
// {
// publishDate = readDate;
// break;
// }
//}
//if(!publishDate.HasValue)
//{
// publishDate = new DateTime((int)o["publish_date"], 12, 31);
//}
DateTime? publishDate = AuthorJsonReader.ReadDate((string)o["publish_date"]);
BookDTO book = new BookDTO
{
Id = (string)o["key"],
Title = (string)o["title"],
Publishers = o["publishers"].Select(p => (string)p).ToList(),
PublishDate = publishDate.GetValueOrDefault(DateTime.Now),
ISBN13 = (string)o["isbn_13"][0],
NbPages = o["number_of_pages"] != null ? (int)o["number_of_pages"] : -1,
Language = lang,
Format = o.TryGetValue("physical_format", out JToken? f) ? (string)f : null,
Works = o["works"].Select(w => new WorkDTO { Id = (string)w["key"] }).ToList(),
Contributors = o.TryGetValue("contributors", out JToken? contr) ? contr.Select(c => new ContributorDTO { Name = (string)c["name"], Role = (string)c["role"] }).ToList() : new List<ContributorDTO>(),
Authors = o["authors"]?.Select(a => new AuthorDTO { Id = (string)a["key"] }).ToList()
};
if (book.Authors == null)
{
book.Authors = new List<AuthorDTO>();
}
return book;
}
public static Tuple<long, IEnumerable<BookDTO>> GetBooksByAuthor(string json)
{
JObject o = JObject.Parse(json);
long numFound = (long)o["numFound"];
var books = o["docs"].Select(doc => new BookDTO
{
Id = (string)(doc["seed"].First()),
Title = (string)doc["title"],
ISBN13 = (string)(doc["isbn"].First()),
Authors = doc["seed"].Where(s => ((string)s).StartsWith("/authors/"))
.Select(s => new AuthorDTO { Id = (string)s }).ToList(),
Language = languages.GetValueOrDefault((string)(doc["language"].First()))
});
return Tuple.Create(numFound, books);
}
public static Tuple<long, IEnumerable<BookDTO>> GetBooksByTitle(string json)
{
JObject o = JObject.Parse(json);
long numFound = (long)o["numFound"];
var books = o["docs"].Select(doc => new BookDTO
{
Id = (string)(doc["seed"].First()),
Title = (string)doc["title"],
ISBN13 = (string)(doc["isbn"].First()),
Authors = doc["seed"].Where(s => ((string)s).StartsWith("/authors/"))
.Select(s => new AuthorDTO { Id = (string)s }).ToList(),
Language = languages.GetValueOrDefault((string)(doc["language"].First()))
});
return Tuple.Create(numFound, books);
}
}
}

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LibraryDTO\LibraryDTO.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,57 @@
using LibraryDTO;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JsonReader
{
public static class WorkJsonReader
{
public static WorkDTO ReadWork(string json, string ratingsJson)
{
JObject o = JObject.Parse(json);
JObject r = JObject.Parse(ratingsJson);
var ratingsDto = new RatingsDTO();
if (r["summary"]["average"].Type != JTokenType.Float)
{
ratingsDto.Average = -1;
ratingsDto.Count = 0;
}
else
{
ratingsDto.Average = (float)r["summary"]["average"];
ratingsDto.Count = (int)r["summary"]["count"];
}
string description = null;
if (o.TryGetValue("description", out JToken? descr))
{
if (descr.Type == JTokenType.String)
{
description = (string)descr;
}
else
{
if (descr["value"].Type == JTokenType.String)
{
description = (string)descr["value"];
}
}
}
WorkDTO work = new WorkDTO
{
Id = (string)o["key"],
Title = (string)o["title"],
Authors = o.TryGetValue("authors", out JToken? authors) ? authors.Select(a => new AuthorDTO { Id = (string)a["author"]["key"] }).ToList() : new List<AuthorDTO>(),
Description = description,
Subjects = o.TryGetValue("subjects", out JToken? subjects) ? subjects.Select(s => (string)s).ToList() : new List<string>(),
Ratings = ratingsDto
};
return work;
}
}
}

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryDTO
{
public class AuthorDTO
{
public string Id { get; set; }
public string Name { get; set; }
public string ImageSmall => $"https://covers.openlibrary.org/a/olid/{Id.Substring(Id.LastIndexOf("/"))}-S.jpg";
public string ImageMedium => $"https://covers.openlibrary.org/a/olid/{Id.Substring(Id.LastIndexOf("/"))}-M.jpg";
public string ImageLarge => $"https://covers.openlibrary.org/a/olid/{Id.Substring(Id.LastIndexOf("/"))}-L.jpg";
public string Bio { get; set; }
public List<string> AlternateNames { get; set; } = new List<string>();
public List<LinkDTO> Links { get; set; }
public DateTime? BirthDate { get; set; }
public DateTime? DeathDate { get; set; }
}
}

@ -0,0 +1,21 @@
namespace LibraryDTO
{
public class BookDTO
{
public string Id { get; set; }
public string Title { get; set; }
public List<string> Publishers { get; set; } = new List<string>();
public DateTime PublishDate { get; set; }
public string ISBN13 { get; set; }
public List<string> Series { get; set; } = new List<string>();
public int NbPages { get; set; }
public string Format { get; set; }
public Languages Language { get; set; }
public List<ContributorDTO> Contributors { get; set; }
public string ImageSmall => $"https://covers.openlibrary.org/b/isbn/{ISBN13}-S.jpg";
public string ImageMedium => $"https://covers.openlibrary.org/b/isbn/{ISBN13}-M.jpg";
public string ImageLarge => $"https://covers.openlibrary.org/b/isbn/{ISBN13}-L.jpg";
public List<WorkDTO> Works { get; set; } = new List<WorkDTO>();
public List<AuthorDTO> Authors { get; set; } = new List<AuthorDTO>();
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryDTO
{
public class ContributorDTO
{
public string Name { get; set; }
public string Role { get; set; }
}
}

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryDTO
{
public enum Languages
{
Unknown,
French,
English
}
}

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryDTO
{
public class LinkDTO
{
public string Title { get; set; }
public string Url { get; set; }
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryDTO
{
public class RatingsDTO
{
public float Average { get; set; }
public int Count { get; set; }
}
}

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryDTO
{
public class WorkDTO
{
public string Id { get; set; }
public string Description { get; set; }
public string Title { get; set; }
public List<string> Subjects { get; set; } = new List<string>();
public List<AuthorDTO> Authors { get; set; } = new List<AuthorDTO>();
public RatingsDTO Ratings { get; set; }
}
}

@ -10,7 +10,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LivreLand", "LivreLand\Livr
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{7DB41B43-9DAA-48C8-8D41-EF2F06FDD33E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{7DB41B43-9DAA-48C8-8D41-EF2F06FDD33E}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ViewModels", "ViewModels\ViewModels.csproj", "{72B707A3-3797-4F15-80BC-9D5ECA7B67EE}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ViewModels", "ViewModels\ViewModels.csproj", "{72B707A3-3797-4F15-80BC-9D5ECA7B67EE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stub", "Stub\Stub.csproj", "{65A55AED-D8C3-4416-85FE-5E0688C70B88}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StubbedDTO", "StubbedDTO\StubbedDTO.csproj", "{73CAF8BC-E443-48F3-AB04-77F1AF6A24A3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryDTO", "LibraryDTO\LibraryDTO.csproj", "{C42003CE-3CE8-4CAA-BF08-82FB9EA5E825}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DtoAbstractLayer", "DtoAbstractLayer\DtoAbstractLayer.csproj", "{0AAA2F93-2C4F-4245-A37D-DC8C7261ADEC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonReader", "JsonReader\JsonReader.csproj", "{62D56765-482A-4B7A-B77A-517B0AABF443}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "Utils\Utils.csproj", "{D74E6DD7-ED6A-400C-89EE-FA3BB50D924F}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -32,6 +44,30 @@ Global
{72B707A3-3797-4F15-80BC-9D5ECA7B67EE}.Debug|Any CPU.Build.0 = Debug|Any CPU {72B707A3-3797-4F15-80BC-9D5ECA7B67EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72B707A3-3797-4F15-80BC-9D5ECA7B67EE}.Release|Any CPU.ActiveCfg = Release|Any CPU {72B707A3-3797-4F15-80BC-9D5ECA7B67EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72B707A3-3797-4F15-80BC-9D5ECA7B67EE}.Release|Any CPU.Build.0 = Release|Any CPU {72B707A3-3797-4F15-80BC-9D5ECA7B67EE}.Release|Any CPU.Build.0 = Release|Any CPU
{65A55AED-D8C3-4416-85FE-5E0688C70B88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65A55AED-D8C3-4416-85FE-5E0688C70B88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65A55AED-D8C3-4416-85FE-5E0688C70B88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65A55AED-D8C3-4416-85FE-5E0688C70B88}.Release|Any CPU.Build.0 = Release|Any CPU
{73CAF8BC-E443-48F3-AB04-77F1AF6A24A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{73CAF8BC-E443-48F3-AB04-77F1AF6A24A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73CAF8BC-E443-48F3-AB04-77F1AF6A24A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{73CAF8BC-E443-48F3-AB04-77F1AF6A24A3}.Release|Any CPU.Build.0 = Release|Any CPU
{C42003CE-3CE8-4CAA-BF08-82FB9EA5E825}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C42003CE-3CE8-4CAA-BF08-82FB9EA5E825}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C42003CE-3CE8-4CAA-BF08-82FB9EA5E825}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C42003CE-3CE8-4CAA-BF08-82FB9EA5E825}.Release|Any CPU.Build.0 = Release|Any CPU
{0AAA2F93-2C4F-4245-A37D-DC8C7261ADEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AAA2F93-2C4F-4245-A37D-DC8C7261ADEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AAA2F93-2C4F-4245-A37D-DC8C7261ADEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AAA2F93-2C4F-4245-A37D-DC8C7261ADEC}.Release|Any CPU.Build.0 = Release|Any CPU
{62D56765-482A-4B7A-B77A-517B0AABF443}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62D56765-482A-4B7A-B77A-517B0AABF443}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62D56765-482A-4B7A-B77A-517B0AABF443}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62D56765-482A-4B7A-B77A-517B0AABF443}.Release|Any CPU.Build.0 = Release|Any CPU
{D74E6DD7-ED6A-400C-89EE-FA3BB50D924F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D74E6DD7-ED6A-400C-89EE-FA3BB50D924F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D74E6DD7-ED6A-400C-89EE-FA3BB50D924F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D74E6DD7-ED6A-400C-89EE-FA3BB50D924F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

@ -55,6 +55,8 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" /> <ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Stub\Stub.csproj" />
<ProjectReference Include="..\ViewModels\ViewModels.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

@ -2,6 +2,9 @@
using LivreLand.View; using LivreLand.View;
using LivreLand.ViewModel; using LivreLand.ViewModel;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Model;
using Stub;
using ViewModels;
namespace LivreLand; namespace LivreLand;
@ -20,10 +23,14 @@ public static class MauiProgram
}); });
builder.Services builder.Services
.AddSingleton<BibliothequeView>()
.AddSingleton<NavigatorVM>() .AddSingleton<NavigatorVM>()
.AddSingleton<BibliothequeView>();
//Ajouter des Singletons <ILibraryManager, LibraryStub>, Manager et ManagerVm .AddSingleton<ILibraryManager, LibraryStub>()
.AddSingleton<Manager>()
.AddSingleton<ManagerVM>();
#if DEBUG #if DEBUG
builder.Logging.AddDebug(); builder.Logging.AddDebug();

@ -9,17 +9,20 @@ namespace LivreLand.ViewModel
{ {
class BookVM class BookVM
{ {
#region Fields
private Book model;
#endregion
#region Properties
public Book Model public Book Model
{ {
get => model; get => model;
set => model = value; set => model = value;
} }
private Book model;
public BookVM()
{
Model = model;
}
public string Title public string Title
{ {
@ -29,5 +32,16 @@ namespace LivreLand.ViewModel
model.Title = value; model.Title = value;
} }
} }
#endregion
#region Constructor
public BookVM()
{
Model = model;
}
#endregion
} }
} }

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Utils;
namespace Stub
{
static class EnumsMapper
{
public static EnumsMapper<Model.Languages, LibraryDTO.Languages> BiddingsMapper { get; }
= new EnumsMapper<Model.Languages, LibraryDTO.Languages>(
Tuple.Create(Model.Languages.Unknown, LibraryDTO.Languages.Unknown),
Tuple.Create(Model.Languages.French, LibraryDTO.Languages.French),
Tuple.Create(Model.Languages.English, LibraryDTO.Languages.English)
);
public static TModel ToModel<TModel, TDTO>(this TDTO dto) where TModel : Enum
where TDTO : Enum
{
foreach (var prop in typeof(EnumsMapper).GetProperties())
{
if (prop.PropertyType.Equals(typeof(EnumsMapper<TModel, TDTO>)))
{
return (prop.GetValue(null) as EnumsMapper<TModel, TDTO>).GetModel(dto);
}
}
return default(TModel);
}
public static Model.Languages ToModel(this LibraryDTO.Languages dto)
=> ToModel<Model.Languages, LibraryDTO.Languages>(dto);
public static TDTO ToDTO<TModel, TDTO>(this TModel model) where TModel : Enum
where TDTO : Enum
{
foreach (var prop in typeof(EnumsMapper).GetProperties())
{
if (prop.PropertyType.Equals(typeof(EnumsMapper<TModel, TDTO>)))
{
return (prop.GetValue(null) as EnumsMapper<TModel, TDTO>).GetEntity(model);
}
}
return default(TDTO);
}
public static LibraryDTO.Languages ToDTO(this Model.Languages model)
=> ToDTO<Model.Languages, LibraryDTO.Languages>(model);
}
}

@ -0,0 +1,95 @@
using LibraryDTO;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Stub
{
public static class Extensions
{
public static Ratings ToPoco(this RatingsDTO dto)
=> new Ratings() { Average = dto.Average, Count = dto.Count };
public static IEnumerable<Ratings> ToPocos(this IEnumerable<RatingsDTO> dtos)
=> dtos.Select(dto => dto.ToPoco());
public static Contributor ToPoco(this ContributorDTO dto)
=> new Contributor { Name = dto.Name, Role = dto.Role };
public static IEnumerable<Contributor> ToPocos(this IEnumerable<ContributorDTO> dtos)
=> dtos.Select(dto => dto.ToPoco());
public static Link ToPoco(this LinkDTO dto)
=> new Link { Title = dto.Title, Url = dto.Url };
public static IEnumerable<Link> ToPocos(this IEnumerable<LinkDTO> dtos)
=> dtos.Select(dto => dto.ToPoco());
public static Author ToPoco(this AuthorDTO dto)
{
var result = Mapper.AuthorsMapper.GetT(dto);
if (result == null)
{
result = new Author
{
AlternateNames = dto.AlternateNames,
Bio = dto.Bio,
BirthDate = dto.BirthDate,
DeathDate = dto.DeathDate,
Id = dto.Id,
Links = dto.Links.ToPocos().ToList(),
Name = dto.Name
};
}
return result;
}
public static IEnumerable<Author> ToPocos(this IEnumerable<AuthorDTO> dtos)
=> dtos.Select(dto => dto.ToPoco());
public static Work ToPoco(this WorkDTO dto)
{
var result = Mapper.WorksMapper.GetT(dto);
if (result == null)
{
result = new Work
{
Authors = dto.Authors.ToPocos().ToList(),
Description = dto.Description,
Id = dto.Id,
Ratings = dto.Ratings.ToPoco(),
Subjects = dto.Subjects,
Title = dto.Title
};
}
return result;
}
public static IEnumerable<Work> ToPocos(this IEnumerable<WorkDTO> dtos)
=> dtos.Select(dto => dto.ToPoco());
public static Book ToPoco(this BookDTO dto)
{
var result = Mapper.BooksMapper.GetT(dto);
if (result == null)
{
result = new Book
{
Authors = dto.Authors.ToPocos().ToList(),
Contributors = dto.Contributors.ToPocos().ToList(),
Format = dto.Format,
Id = dto.Id,
ISBN13 = dto.ISBN13,
Language = dto.Language.ToModel(),
NbPages = dto.NbPages,
PublishDate = dto.PublishDate,
Publishers = dto.Publishers,
Series = dto.Series,
Title = dto.Title,
Works = dto.Works.ToPocos().ToList()
};
}
return result;
}
public static IEnumerable<Book> ToPocos(this IEnumerable<BookDTO> dtos)
=> dtos.Select(dto => dto.ToPoco());
}
}

@ -0,0 +1,25 @@
using LibraryDTO;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Utils;
namespace Stub
{
static class Mapper
{
internal static Mapper<Author, AuthorDTO> AuthorsMapper { get; } = new Mapper<Author, AuthorDTO>();
internal static Mapper<Work, WorkDTO> WorksMapper { get; } = new Mapper<Work, WorkDTO>();
internal static Mapper<Book, BookDTO> BooksMapper { get; } = new Mapper<Book, BookDTO>();
internal static void Reset()
{
AuthorsMapper.Reset();
WorksMapper.Reset();
BooksMapper.Reset();
}
}
}

@ -0,0 +1,48 @@
using Model;
namespace Stub
{
public class LibraryStub : ILibraryManager
{
private StubbedDTO.Stub StubDTO { get; set; } = new StubbedDTO.Stub();
public async Task<Author> GetAuthorById(string id)
{
return (await StubDTO.GetAuthorById(id)).ToPoco();
}
public async Task<Tuple<long, IEnumerable<Author>>> GetAuthorsByName(string substring, int index, int count, string sort = "")
{
var result = await StubDTO.GetAuthorsByName(substring, index, count, sort);
return Tuple.Create(result.Item1, result.Item2.ToPocos());
}
public async Task<Book> GetBookById(string id)
{
return (await StubDTO.GetBookById(id)).ToPoco();
}
public async Task<Book> GetBookByISBN(string isbn)
{
return (await StubDTO.GetBookByISBN(isbn)).ToPoco();
}
public async Task<Tuple<long, IEnumerable<Book>>> GetBooksByAuthor(string author, int index, int count, string sort = "")
{
var result = await StubDTO.GetBooksByAuthor(author, index, count, sort);
return Tuple.Create(result.Item1, result.Item2.ToPocos());
}
public async Task<Tuple<long, IEnumerable<Book>>> GetBooksByAuthorId(string authorId, int index, int count, string sort = "")
{
var result = await StubDTO.GetBooksByAuthor(authorId, index, count, sort);
return Tuple.Create(result.Item1, result.Item2.ToPocos());
}
public async Task<Tuple<long, IEnumerable<Book>>> GetBooksByTitle(string title, int index, int count, string sort = "")
{
var result = await StubDTO.GetBooksByTitle(title, index, count, sort);
return Tuple.Create(result.Item1, result.Item2.ToPocos());
}
}
}

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\StubbedDTO\StubbedDTO.csproj" />
<ProjectReference Include="..\Utils\Utils.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,201 @@
using DtoAbstractLayer;
using JsonReader;
using LibraryDTO;
namespace StubbedDTO
{
public class Stub : IDtoManager
{
public static List<AuthorDTO> Authors { get; set; } = new List<AuthorDTO>();
public static List<BookDTO> Books { get; set; } = new List<BookDTO>();
public static List<WorkDTO> Works { get; set; } = new List<WorkDTO>();
public static string BasePath { get; set; } = "";
static Stub()
{
foreach (var fileAuthor in new DirectoryInfo($"{BasePath}authors/").GetFiles())
{
using (StreamReader reader = File.OpenText(fileAuthor.FullName))
{
Authors.Add(AuthorJsonReader.ReadAuthor(reader.ReadToEnd()));
}
}
foreach (var fileWork in new DirectoryInfo($"{BasePath}works/").GetFiles())
{
var ratingsFile = $"{BasePath}ratings/{fileWork.Name.Insert((int)(fileWork.Name.Length - fileWork.Extension.Length), ".ratings")}";
using (StreamReader reader = File.OpenText(fileWork.FullName))
using (StreamReader readerRatings = File.OpenText(ratingsFile))
{
var work = WorkJsonReader.ReadWork(reader.ReadToEnd(), readerRatings.ReadToEnd());
if (work.Authors != null)
foreach (var author in work.Authors.ToList())
{
var newAuthor = Authors.SingleOrDefault(a => a.Id == author.Id);
work.Authors.Remove(author);
work.Authors.Add(newAuthor);
}
Works.Add(work);
}
}
foreach (var fileBook in new DirectoryInfo($"{BasePath}books/").GetFiles())
{
using (StreamReader reader = File.OpenText(fileBook.FullName))
{
var book = BookJsonReader.ReadBook(reader.ReadToEnd());
foreach (var author in book.Authors.ToList())
{
var newAuthor = Authors.SingleOrDefault(a => a.Id == author.Id);
book.Authors.Remove(author);
book.Authors.Add(newAuthor);
}
foreach (var work in book.Works.ToList())
{
var newWork = Works.SingleOrDefault(w => w.Id == work.Id);
book.Works.Remove(work);
book.Works.Add(newWork);
}
Books.Add(book);
}
}
}
public Task<AuthorDTO> GetAuthorById(string id)
{
var author = Stub.Authors.SingleOrDefault(a => a.Id.Contains(id));
return Task.FromResult(author);
}
private Task<Tuple<long, IEnumerable<AuthorDTO>>> OrderAuthors(IEnumerable<AuthorDTO> authors, int index, int count, string sort = "")
{
switch (sort)
{
case "name":
authors = authors.OrderBy(a => a.Name);
break;
case "name_reverse":
authors = authors.OrderByDescending(a => a.Name);
break;
}
return Task.FromResult(Tuple.Create((long)authors.Count(), authors.Skip(index * count).Take(count)));
}
public async Task<Tuple<long, IEnumerable<AuthorDTO>>> GetAuthors(int index, int count, string sort = "")
{
IEnumerable<AuthorDTO> authors = Stub.Authors;
return await OrderAuthors(authors, index, count, sort);
}
public async Task<Tuple<long, IEnumerable<AuthorDTO>>> GetAuthorsByName(string name, int index, int count, string sort = "")
{
var authors = Stub.Authors.Where(a => a.Name.Contains(name, StringComparison.OrdinalIgnoreCase)
|| a.AlternateNames.Exists(alt => alt.Contains(name, StringComparison.OrdinalIgnoreCase)));
return await OrderAuthors(authors, index, count, sort);
}
public Task<BookDTO> GetBookById(string id)
{
var book = Stub.Books.SingleOrDefault(b => b.Id.Contains(id));
return Task.FromResult(book);
}
private Task<Tuple<long, IEnumerable<BookDTO>>> OrderBooks(IEnumerable<BookDTO> books, int index, int count, string sort = "")
{
switch (sort)
{
case "title":
books = books.OrderBy(b => b.Title);
break;
case "title_reverse":
books = books.OrderByDescending(b => b.Title);
break;
case "new":
books = books.OrderByDescending(b => b.PublishDate);
break;
case "old":
books = books.OrderBy(b => b.PublishDate);
break;
}
return Task.FromResult(Tuple.Create((long)books.Count(), books.Skip(index * count).Take(count)));
}
public async Task<Tuple<long, IEnumerable<BookDTO>>> GetBooks(int index, int count, string sort = "")
{
var books = Stub.Books;
return await OrderBooks(books, index, count, sort);
}
public Task<BookDTO> GetBookByISBN(string isbn)
{
var book = Stub.Books.SingleOrDefault(b => b.ISBN13.Equals(isbn, StringComparison.OrdinalIgnoreCase));
return Task.FromResult(book);
}
public async Task<Tuple<long, IEnumerable<BookDTO>>> GetBooksByTitle(string title, int index, int count, string sort = "")
{
var books = Stub.Books.Where(b => b.Title.Contains(title, StringComparison.OrdinalIgnoreCase)
|| b.Series.Exists(s => s.Contains(title, StringComparison.OrdinalIgnoreCase)));
return await OrderBooks(books, index, count, sort);
}
public async Task<Tuple<long, IEnumerable<BookDTO>>> GetBooksByAuthorId(string authorId, int index, int count, string sort = "")
{
var books = Stub.Books.Where(b => b.Authors.Exists(a => a.Id.Contains(authorId))
|| b.Works.Exists(w => w.Authors.Exists(a => a.Id.Contains(authorId))));
return await OrderBooks(books, index, count, sort);
}
public async Task<Tuple<long, IEnumerable<BookDTO>>> GetBooksByAuthor(string name, int index, int count, string sort = "")
{
var books = Stub.Books.Where(b => ContainsAuthorName(b, name));
return await OrderBooks(books, index, count, sort);
}
private bool ContainsAuthorName(BookDTO book, string name)
{
IEnumerable<AuthorDTO> authors = new List<AuthorDTO>();
if (book.Authors != null && book.Authors.Count > 0)
{
authors = authors.Union(book.Authors);
}
if (book.Works != null)
{
var worksAuthors = book.Works.SelectMany(w => w.Authors).ToList();
if (worksAuthors.Count > 0)
authors = authors.Union(worksAuthors);
}
foreach (var author in authors)
{
if (author.Name.Contains(name, StringComparison.OrdinalIgnoreCase)
|| author.AlternateNames.Exists(alt => alt.Contains(name, StringComparison.OrdinalIgnoreCase)))
{
return true;
}
}
return false;
}
public Task<Tuple<long, IEnumerable<WorkDTO>>> GetWorks(int index, int count)
{
long nbWorks = Stub.Works.Count;
var works = Stub.Works.Skip(index * count).Take(count);
return Task.FromResult(Tuple.Create(nbWorks, works));
}
public Task<long> GetNbAuthors()
=> Task.FromResult((long)Stub.Authors.Count);
public Task<long> GetNbBooks()
=> Task.FromResult((long)Stub.Books.Count);
public Task<long> GetNbWorks()
=> Task.FromResult((long)Stub.Works.Count);
}
}

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DtoAbstractLayer\DtoAbstractLayer.csproj" />
<ProjectReference Include="..\JsonReader\JsonReader.csproj" />
<ProjectReference Include="..\LibraryDTO\LibraryDTO.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Utils
{
public class EnumsMapper<T, U> where T : Enum
where U : Enum
{
readonly HashSet<Tuple<T, U>> mapper = new HashSet<Tuple<T, U>>();
public T GetModel(U entity)
{
var result = mapper.Where(tuple => tuple.Item2.Equals(entity));
if (result.Count() != 1)
{
return default(T);
}
return result.First().Item1;
}
public U GetEntity(T model)
{
var result = mapper.Where(tuple => tuple.Item1.Equals(model));
if (result.Count() != 1)
{
return default(U);
}
return result.First().Item2;
}
public void Add(T model, U entity)
{
mapper.Add(Tuple.Create(model, entity));
}
public void AddRange(params Tuple<T, U>[] tuples)
{
foreach (var t in tuples)
{
Add(t.Item1, t.Item2);
}
}
public EnumsMapper(params Tuple<T, U>[] tuples)
{
AddRange(tuples);
}
}
}

@ -0,0 +1,41 @@
namespace Utils
{
public class Mapper<T, U> where T : class
where U : class
{
readonly HashSet<Tuple<T, U>> mapper = new HashSet<Tuple<T, U>>();
public void Reset()
{
mapper.Clear();
}
public T GetT(U entity)
{
var result = mapper.Where(tuple => ReferenceEquals(tuple.Item2, entity));
if (result.Count() != 1)
{
return null;
}
return result.First().Item1;
}
public U GetU(T model)
{
var result = mapper.Where(tuple => ReferenceEquals(tuple.Item2, model));
if (result.Count() != 1)
{
return null;
}
return result.First().Item2;
}
public bool AddMapping(T t, U u)
{
var mapping = new Tuple<T, U>(t, u);
if (mapper.Contains(mapping)) return false;
mapper.Add(mapping);
return true;
}
}
}

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -6,6 +6,12 @@ namespace ViewModels
public class ManagerVM public class ManagerVM
{ {
#region Fields
private Manager model;
#endregion
#region Properties #region Properties
public Manager Model public Manager Model
@ -13,7 +19,6 @@ namespace ViewModels
get => model; get => model;
private set => model = value; private set => model = value;
} }
private Manager model;
public ICommand GetBooksByTitleCommand; public ICommand GetBooksByTitleCommand;

Loading…
Cancel
Save