diff --git a/.DS_Store b/.DS_Store index 5d1ff1d..2c8816e 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/sources/DtoAbstractLayer/DtoAbstractLayer.csproj b/sources/DtoAbstractLayer/DtoAbstractLayer.csproj new file mode 100644 index 0000000..496da7a --- /dev/null +++ b/sources/DtoAbstractLayer/DtoAbstractLayer.csproj @@ -0,0 +1,12 @@ + + + + net7.0 + enable + enable + + + + + + diff --git a/sources/DtoAbstractLayer/IDtoManager.cs b/sources/DtoAbstractLayer/IDtoManager.cs new file mode 100644 index 0000000..4edf2da --- /dev/null +++ b/sources/DtoAbstractLayer/IDtoManager.cs @@ -0,0 +1,97 @@ +using LibraryDTO; + +namespace DtoAbstractLayer; + +/// +/// abstract layer for requests on Books Library +/// +public interface IDtoManager +{ + /// + /// get a book by specifying its id + /// + /// id of the Book to get + /// a Book with this id (or null if id is unknown) + Task GetBookById(string id); + + /// + /// get a book by specifying its isbn + /// + /// isbn of the Book to get + /// a Book with this isbn (or null if isbn is unknown) + Task GetBookByISBN(string isbn); + + /// + /// get books containing a substring in their titles + /// + /// the substring to look for in book titles + /// index of the page of resulting books + /// number of resulting books per page + /// sort criterium (not mandatory): + /// + /// + /// max count books + Task>> GetBooksByTitle(string title, int index, int count, string sort = ""); + + /// + /// get books of a particular author by giving the author id + /// + /// the id of the author + /// index of the page of resulting books + /// number of resulting books per page + /// sort criterium (not mandatory): + ///
    + ///
  • ```title```: sort books by titles in alphabetical order,
  • + ///
  • ```title_reverse```: sort books by titles in reverse alphabetical order,
  • + ///
  • ```new```: sort books by publishing dates, beginning with the most recents,
  • + ///
  • ```old```: sort books by publishing dates, beginning with the oldest
  • + ///
+ /// + /// max count books + Task>> GetBooksByAuthorId(string authorId, int index, int count, string sort = ""); + + /// + /// get books of authors whose name (or alternate names) contains a particular substring + /// + /// name to look for in author names or alternate names + /// index of the page of resulting books + /// number of resulting books per page + /// sort criterium (not mandatory): + ///
    + ///
  • ```title```: sort books by titles in alphabetical order,
  • + ///
  • ```title_reverse```: sort books by titles in reverse alphabetical order,
  • + ///
  • ```new```: sort books by publishing dates, beginning with the most recents,
  • + ///
  • ```old```: sort books by publishing dates, beginning with the oldest
  • + ///
+ /// + /// max count books + Task>> GetBooksByAuthor(string author, int index, int count, string sort = ""); + + /// + /// get an author by specifying its id + /// + /// id of the Author to get + /// an author with this id (or null if id is unknown) + Task GetAuthorById(string id); + + /// + /// get authors containing a substring in their names (or alternate names) + /// + /// the substring to look for in author names (or alternate names) + /// index of the page of resulting authors + /// number of resulting authors per page + /// sort criterium (not mandatory): + ///
    + ///
  • ```name```: sort authors by names in alphabetical order,
  • + ///
  • ```name_reverse```: sort authors by names in reverse alphabetical order,
  • + ///
+ /// + /// max count authors + Task>> GetAuthorsByName(string substring, int index, int count, string sort = ""); +} + diff --git a/sources/ExtensionsAndMappers/Class1.cs b/sources/ExtensionsAndMappers/Class1.cs new file mode 100644 index 0000000..ed6e84a --- /dev/null +++ b/sources/ExtensionsAndMappers/Class1.cs @@ -0,0 +1,7 @@ +namespace ExtensionsAndMappers; + +public class Class1 +{ + +} + diff --git a/sources/ExtensionsAndMappers/ExtensionsAndMappers.csproj b/sources/ExtensionsAndMappers/ExtensionsAndMappers.csproj new file mode 100644 index 0000000..4658cbf --- /dev/null +++ b/sources/ExtensionsAndMappers/ExtensionsAndMappers.csproj @@ -0,0 +1,9 @@ + + + + net7.0 + enable + enable + + + diff --git a/sources/JsonReader/AuthorJsonReader.cs b/sources/JsonReader/AuthorJsonReader.cs new file mode 100644 index 0000000..0ae07db --- /dev/null +++ b/sources/JsonReader/AuthorJsonReader.cs @@ -0,0 +1,80 @@ +using System; +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); + } + } +} + diff --git a/sources/JsonReader/BookJsonReader.cs b/sources/JsonReader/BookJsonReader.cs new file mode 100644 index 0000000..ab2a87e --- /dev/null +++ b/sources/JsonReader/BookJsonReader.cs @@ -0,0 +1,97 @@ +using System.Globalization; +using LibraryDTO; +using Newtonsoft.Json.Linq; + +namespace JsonReader; + +public static class BookJsonReader +{ + static Dictionary languages = new Dictionary() + { + [@"/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> pubDateFormat =new List>() + //{ + // 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(), + Authors = o["authors"]?.Select(a => new AuthorDTO { Id = (string)a["key"] }).ToList() + }; + if(book.Authors == null) + { + book.Authors = new List(); + } + return book; + } + + public static Tuple> 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> 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); + } +} + diff --git a/sources/JsonReader/JsonReader.csproj b/sources/JsonReader/JsonReader.csproj new file mode 100644 index 0000000..8e77096 --- /dev/null +++ b/sources/JsonReader/JsonReader.csproj @@ -0,0 +1,15 @@ + + + + net7.0 + enable + enable + + + + + + + + + diff --git a/sources/JsonReader/WorkJsonReader.cs b/sources/JsonReader/WorkJsonReader.cs new file mode 100644 index 0000000..387dbbd --- /dev/null +++ b/sources/JsonReader/WorkJsonReader.cs @@ -0,0 +1,55 @@ +using System; +using LibraryDTO; +using Newtonsoft.Json.Linq; +using System.Globalization; + +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(), + Description = description, + Subjects = o.TryGetValue("subjects", out JToken? subjects) ? subjects.Select(s => (string)s).ToList() : new List(), + Ratings = ratingsDto + }; + return work; + } + } +} + diff --git a/sources/LibraryDTO/AuthorDTO.cs b/sources/LibraryDTO/AuthorDTO.cs new file mode 100644 index 0000000..22376e7 --- /dev/null +++ b/sources/LibraryDTO/AuthorDTO.cs @@ -0,0 +1,18 @@ +using System; +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 AlternateNames { get; set; } = new List(); + public List Links { get; set; } + public DateTime? BirthDate { get; set; } + public DateTime? DeathDate { get; set; } + } +} + diff --git a/sources/LibraryDTO/BookDTO.cs b/sources/LibraryDTO/BookDTO.cs new file mode 100644 index 0000000..a260ae0 --- /dev/null +++ b/sources/LibraryDTO/BookDTO.cs @@ -0,0 +1,23 @@ +using System; +namespace LibraryDTO +{ + public class BookDTO + { + public string Id { get; set; } + public string Title { get; set; } + public List Publishers { get; set; } = new List(); + public DateTime PublishDate { get; set; } + public string ISBN13 { get; set; } + public List Series { get; set; } = new List(); + public int NbPages { get; set; } + public string Format { get; set; } + public Languages Language { get; set; } + public List 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 Works { get; set; } = new List(); + public List Authors { get; set; } = new List(); + } +} + diff --git a/sources/LibraryDTO/ContributorDTO.cs b/sources/LibraryDTO/ContributorDTO.cs new file mode 100644 index 0000000..beab5d1 --- /dev/null +++ b/sources/LibraryDTO/ContributorDTO.cs @@ -0,0 +1,10 @@ +using System; +namespace LibraryDTO +{ + public class ContributorDTO + { + public string Name { get; set; } + public string Role { get; set; } + } +} + diff --git a/sources/LibraryDTO/Languages.cs b/sources/LibraryDTO/Languages.cs new file mode 100644 index 0000000..fcf51b5 --- /dev/null +++ b/sources/LibraryDTO/Languages.cs @@ -0,0 +1,11 @@ +using System; +namespace LibraryDTO +{ + public enum Languages + { + Unknown, + French, + English + } +} + diff --git a/sources/LibraryDTO/LibraryDTO.csproj b/sources/LibraryDTO/LibraryDTO.csproj new file mode 100644 index 0000000..ef76c53 --- /dev/null +++ b/sources/LibraryDTO/LibraryDTO.csproj @@ -0,0 +1,18 @@ + + + + net7.0 + enable + enable + + + + 4 + bin\Debug\net7.0\LibraryDTO.xml + + + true + 4 + bin\Release\net7.0\LibraryDTO.xml + + diff --git a/sources/LibraryDTO/LinkDTO.cs b/sources/LibraryDTO/LinkDTO.cs new file mode 100644 index 0000000..336909c --- /dev/null +++ b/sources/LibraryDTO/LinkDTO.cs @@ -0,0 +1,10 @@ +using System; +namespace LibraryDTO +{ + public class LinkDTO + { + public string Title { get; set; } + public string Url { get; set; } + } +} + diff --git a/sources/LibraryDTO/RatingsDTO.cs b/sources/LibraryDTO/RatingsDTO.cs new file mode 100644 index 0000000..f15e5eb --- /dev/null +++ b/sources/LibraryDTO/RatingsDTO.cs @@ -0,0 +1,10 @@ +using System; +namespace LibraryDTO +{ + public class RatingsDTO + { + public float Average { get; set; } + public int Count { get; set; } + } +} + diff --git a/sources/LibraryDTO/WorkDTO.cs b/sources/LibraryDTO/WorkDTO.cs new file mode 100644 index 0000000..2c41813 --- /dev/null +++ b/sources/LibraryDTO/WorkDTO.cs @@ -0,0 +1,14 @@ +using System; +namespace LibraryDTO +{ + public class WorkDTO + { + public string Id { get; set; } + public string Description { get; set; } + public string Title { get; set; } + public List Subjects { get; set; } = new List(); + public List Authors { get; set; } = new List(); + public RatingsDTO Ratings { get; set; } + } +} + diff --git a/sources/Model/Author.cs b/sources/Model/Author.cs new file mode 100644 index 0000000..9992f2f --- /dev/null +++ b/sources/Model/Author.cs @@ -0,0 +1,32 @@ +using System; +namespace Model +{ + public class Author : IEquatable + { + 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 AlternateNames { get; set; } = new List(); + public List Links { get; set; } + public DateTime? BirthDate { get; set; } + public DateTime? DeathDate { get; set; } + + public bool Equals(Author? other) + => Id == other.Id; + + public override bool Equals(object? obj) + { + if(ReferenceEquals(obj, null)) return false; + if(ReferenceEquals(this, obj)) return true; + if(GetType() != obj.GetType()) return false; + return Equals(obj as Author); + } + + public override int GetHashCode() + => Id.GetHashCode(); + } +} + diff --git a/sources/Model/Book.cs b/sources/Model/Book.cs new file mode 100644 index 0000000..092b1b8 --- /dev/null +++ b/sources/Model/Book.cs @@ -0,0 +1,41 @@ +using static Model.Book; + +namespace Model; + +public class Book : IEquatable +{ + public string Id { get; set; } + public string Title { get; set; } + public List Publishers { get; set; } = new List(); + public DateTime PublishDate { get; set; } + public string ISBN13 { get; set; } + public List Series { get; set; } = new List(); + public int NbPages { get; set; } + public string Format { get; set; } + public Languages Language { get; set; } + public List 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 Works { get; set; } = new List(); + public List Authors { get; set; } = new List(); + public Status Status { get; set; } + public List UserTags { get; set; } = new List(); + public float? UserRating { get; set; } + public string UserNote { get; set; } + + public bool Equals(Book? other) + => Id == other.Id; + + public override bool Equals(object? obj) + { + if(ReferenceEquals(obj, null)) return false; + if(ReferenceEquals(this, obj)) return true; + if(GetType() != obj.GetType()) return false; + return Equals(obj as Book); + } + + public override int GetHashCode() + => Id.GetHashCode(); +} + diff --git a/sources/Model/Borrowing.cs b/sources/Model/Borrowing.cs new file mode 100644 index 0000000..7110c3b --- /dev/null +++ b/sources/Model/Borrowing.cs @@ -0,0 +1,29 @@ +using System; +using static System.Runtime.InteropServices.JavaScript.JSType; + +namespace Model +{ + public class Borrowing : IEquatable //emprunt + { + public string Id { get; set; } + public Book Book { get; set; } + public Contact Owner { get; set; } + public DateTime BorrowedAt { get; set; } + public DateTime? ReturnedAt { get; set; } + + public bool Equals(Borrowing? other) + => Id == other.Id; + + public override bool Equals(object? obj) + { + if(ReferenceEquals(obj, null)) return false; + if(ReferenceEquals(this, obj)) return true; + if(GetType() != obj.GetType()) return false; + return Equals(obj as Borrowing); + } + + public override int GetHashCode() + => Id.GetHashCode(); + } +} + diff --git a/sources/Model/Contact.cs b/sources/Model/Contact.cs new file mode 100644 index 0000000..9066aa6 --- /dev/null +++ b/sources/Model/Contact.cs @@ -0,0 +1,25 @@ +using System; +namespace Model +{ + public class Contact : IEquatable + { + public string Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public bool Equals(Contact? other) + => Id == other.Id; + + public override bool Equals(object? obj) + { + if(ReferenceEquals(obj, null)) return false; + if(ReferenceEquals(this, obj)) return true; + if(GetType() != obj.GetType()) return false; + return Equals(obj as Contact); + } + + public override int GetHashCode() + => Id.GetHashCode(); + } +} + diff --git a/sources/Model/Contributor.cs b/sources/Model/Contributor.cs new file mode 100644 index 0000000..d1b5c12 --- /dev/null +++ b/sources/Model/Contributor.cs @@ -0,0 +1,10 @@ +using System; +namespace Model +{ + public class Contributor + { + public string Name { get; set; } + public string Role { get; set; } + } +} + diff --git a/sources/Model/ILibraryManager.cs b/sources/Model/ILibraryManager.cs new file mode 100644 index 0000000..8edc427 --- /dev/null +++ b/sources/Model/ILibraryManager.cs @@ -0,0 +1,15 @@ +using System; +namespace Model +{ + public interface ILibraryManager + { + Task GetBookById(string id); + Task GetBookByISBN(string isbn); + Task>> GetBooksByTitle(string title, int index, int count, string sort = ""); + Task>> GetBooksByAuthorId(string authorId, int index, int count, string sort = ""); + Task>> GetBooksByAuthor(string author, int index, int count, string sort = ""); + Task GetAuthorById(string id); + Task>> GetAuthorsByName(string substring, int index, int count, string sort = ""); + } +} + diff --git a/sources/Model/IUserLibraryManager.cs b/sources/Model/IUserLibraryManager.cs new file mode 100644 index 0000000..3e05af1 --- /dev/null +++ b/sources/Model/IUserLibraryManager.cs @@ -0,0 +1,40 @@ +using System; +namespace Model +{ + public interface IUserLibraryManager : ILibraryManager + { + Task>> GetBooksFromCollection(int index, int count, string sort = ""); + + Task AddBook(Book book); + Task AddBook(string id); + Task AddBookByIsbn(string isbn); + Task RemoveBook(Book book); + Task RemoveBook(string id); + Task RemoveBookByIsbn(string isbn); + + Task AddToFavorites(Book book); + Task AddToFavorites(string bookId); + Task RemoveFromFavorites(Book book); + Task RemoveFromFavorites(string bookId); + + Task UpdateBook(Book updatedBook); + + Task AddContact(Contact contact); + Task RemoveContact(Contact contact); + + Task LendBook(Book book, Contact contact, DateTime? loanDate); + Task GetBackBook(Book book, DateTime? returnedDate); + Task BorrowBook(Book book, Contact owner, DateTime? borrowedDate); + Task GiveBackBook(Book book, DateTime? returnedDate); + + Task>> GetCurrentLoans(int index, int count); + Task>> GetPastLoans(int index, int count); + + Task>> GetCurrentBorrowings(int index, int count); + Task>> GetPastBorrowings(int index, int count); + + Task>> GetContacts(int index, int count); + + } +} + diff --git a/sources/Model/Languages.cs b/sources/Model/Languages.cs new file mode 100644 index 0000000..d5c2014 --- /dev/null +++ b/sources/Model/Languages.cs @@ -0,0 +1,11 @@ +using System; +namespace Model +{ + public enum Languages + { + Unknown, + French, + English + } +} + diff --git a/sources/Model/Link.cs b/sources/Model/Link.cs new file mode 100644 index 0000000..04afed9 --- /dev/null +++ b/sources/Model/Link.cs @@ -0,0 +1,10 @@ +using System; +namespace Model +{ + public class Link + { + public string Title { get; set; } + public string Url { get; set; } + } +} + diff --git a/sources/Model/Loan.cs b/sources/Model/Loan.cs new file mode 100644 index 0000000..f6c2168 --- /dev/null +++ b/sources/Model/Loan.cs @@ -0,0 +1,27 @@ +using System; +namespace Model +{ + public class Loan : IEquatable //prêt + { + public string Id { get; set; } + public Book Book { get; set; } + public Contact Loaner { get; set; } + public DateTime LoanedAt { get; set; } + public DateTime? ReturnedAt { get; set; } + + public bool Equals(Loan? other) + => Id == other.Id; + + public override bool Equals(object? obj) + { + if(ReferenceEquals(obj, null)) return false; + if(ReferenceEquals(this, obj)) return true; + if(GetType() != obj.GetType()) return false; + return Equals(obj as Loan); + } + + public override int GetHashCode() + => Id.GetHashCode(); + } +} + diff --git a/sources/Model/Manager.cs b/sources/Model/Manager.cs new file mode 100644 index 0000000..32bedf6 --- /dev/null +++ b/sources/Model/Manager.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.ObjectModel; +using System.Reflection; + +namespace Model +{ + public class Manager + { + private ILibraryManager LibraryManager { get; set; } + private IUserLibraryManager UserLibraryManager { get; set; } + + public ReadOnlyCollection Books { get; private set; } + private List books = new(); + + public Manager(ILibraryManager libMgr, IUserLibraryManager userLibMgr) + { + LibraryManager = libMgr; + UserLibraryManager = userLibMgr; + Books = new ReadOnlyCollection(books); + } + + public async Task GetBookById(string id) + => await LibraryManager.GetBookById(id); + + public async Task GetBookByISBN(string isbn) + => await LibraryManager.GetBookByISBN(isbn); + + public async Task<(long count, IEnumerable books)> GetBooksByTitle(string title, int index, int count, string sort = "") + { + var result = await LibraryManager.GetBooksByTitle(title, index, count, sort); + return (result.Item1, result.Item2); + } + + public async Task<(long count, IEnumerable books)> GetBooksByAuthorId(string authorId, int index, int count, string sort = "") + { + var result = await LibraryManager.GetBooksByAuthorId(authorId, index, count, sort); + return (result.Item1, result.Item2); + } + + public async Task<(long count, IEnumerable books)> GetBooksByAuthor(string author, int index, int count, string sort = "") + { + var result = await LibraryManager.GetBooksByAuthor(author, index, count, sort); + return (result.Item1, result.Item2); + } + + public async Task GetAuthorById(string id) + => await LibraryManager.GetAuthorById(id); + + public async Task<(long count, IEnumerable authors)> GetAuthorsByName(string substring, int index, int count, string sort = "") + { + var result = await LibraryManager.GetAuthorsByName(substring, index, count, sort); + return (result.Item1, result.Item2); + } + + public Task AddBookToCollection(string id) + { + return UserLibraryManager.AddBook(id); + } + + public async Task GetBookByIdFromCollection(string id) + => await UserLibraryManager.GetBookById(id); + + + public Task UpdateBook(Book book) + { + return UserLibraryManager.UpdateBook(book); + } + + public Task<(long count, IEnumerable books)> GetBooksFromCollection(int index, int count, string sort = "") + { + var result = UserLibraryManager.GetBooksFromCollection(index, count, sort).Result; + return Task.FromResult((result.Item1, result.Item2)); + } + + public Task<(long count, IEnumerable contacts)> GetContacts(int index, int count) + { + var result = UserLibraryManager.GetContacts(index, count).Result; + return Task.FromResult((result.Item1, result.Item2)); + } + + public Task<(long count, IEnumerable loans)> GetCurrentLoans(int index, int count) + { + var result = UserLibraryManager.GetCurrentLoans(index, count).Result; + return Task.FromResult((result.Item1, result.Item2)); + } + + public Task<(long count, IEnumerable loans)> GetPastLoans(int index, int count) + { + var result = UserLibraryManager.GetPastLoans(index, count).Result; + return Task.FromResult((result.Item1, result.Item2)); + } + + public Task<(long count, IEnumerable borrowings)> GetCurrentBorrowings(int index, int count) + { + var result = UserLibraryManager.GetCurrentBorrowings(index, count).Result; + return Task.FromResult((result.Item1, result.Item2)); + } + + public Task<(long count, IEnumerable borrowings)> GetPastBorrowings(int index, int count) + { + var result = UserLibraryManager.GetPastBorrowings(index, count).Result; + return Task.FromResult((result.Item1, result.Item2)); + } + } +} + diff --git a/sources/Model/Model.csproj b/sources/Model/Model.csproj new file mode 100644 index 0000000..4658cbf --- /dev/null +++ b/sources/Model/Model.csproj @@ -0,0 +1,9 @@ + + + + net7.0 + enable + enable + + + diff --git a/sources/Model/Ratings.cs b/sources/Model/Ratings.cs new file mode 100644 index 0000000..9579f4c --- /dev/null +++ b/sources/Model/Ratings.cs @@ -0,0 +1,10 @@ +using System; +namespace Model +{ + public class Ratings + { + public float Average { get; set; } + public int Count { get; set; } + } +} + diff --git a/sources/Model/Status.cs b/sources/Model/Status.cs new file mode 100644 index 0000000..3ec0a44 --- /dev/null +++ b/sources/Model/Status.cs @@ -0,0 +1,13 @@ +using System; +namespace Model +{ + public enum Status + { + Unknown, + Finished, + Reading, + NotRead, + ToBeRead + } +} + diff --git a/sources/Model/Work.cs b/sources/Model/Work.cs new file mode 100644 index 0000000..e9705bd --- /dev/null +++ b/sources/Model/Work.cs @@ -0,0 +1,28 @@ +using System; +namespace Model +{ + public class Work : IEquatable + { + public string Id { get; set; } + public string Description { get; set; } + public string Title { get; set; } + public List Subjects { get; set; } = new List(); + public List Authors { get; set; } = new List(); + public Ratings Ratings { get; set; } + + public bool Equals(Work? other) + => Id == other.Id; + + public override bool Equals(object? obj) + { + if(ReferenceEquals(obj, null)) return false; + if(ReferenceEquals(this, obj)) return true; + if(GetType() != obj.GetType()) return false; + return Equals(obj as Work); + } + + public override int GetHashCode() + => Id.GetHashCode(); + } +} + diff --git a/sources/PocketBook/Applicative_VM/NavigatorVM.cs b/sources/PocketBook/Applicative_VM/NavigatorVM.cs index 2489665..f67eec9 100644 --- a/sources/PocketBook/Applicative_VM/NavigatorVM.cs +++ b/sources/PocketBook/Applicative_VM/NavigatorVM.cs @@ -1,6 +1,7 @@ using System; using System.Windows.Input; using System.Threading.Tasks; +using System.Reflection; namespace PocketBook.Applicative_VM { @@ -9,42 +10,18 @@ namespace PocketBook.Applicative_VM public ICommand Navigateto { get; private set; } public NavigatorVM() { - Navigateto = new Command(async (parameter) => + Navigateto = new Command(async (name) => { - if (!string.IsNullOrEmpty(parameter)) + + Type pageType = Assembly.GetExecutingAssembly().GetTypes() + .Where(t => typeof(Page).IsAssignableFrom(t) && t.Name == name as String) + .FirstOrDefault(); + + if (pageType != null) { - switch (parameter) - { - case "TousPage": - await App.Current.MainPage.Navigation.PushAsync(new TousPage()); - break; - case "SharePage": - await App.Current.MainPage.Navigation.PushAsync(new SharePage()); - break; - case "Auteur": - await App.Current.MainPage.Navigation.PushAsync(new Auteur()); - break; - case "BookDetail": - await App.Current.MainPage.Navigation.PushAsync(new BookDetail()); - break; - case "DatePublic": - await App.Current.MainPage.Navigation.PushAsync(new DatePublic()); - break; - case "LaterPage": - await App.Current.MainPage.Navigation.PushAsync(new LaterPage()); - break; - case "MarkPage": - await App.Current.MainPage.Navigation.PushAsync(new MarkPage()); - break; - case "StatutPage": - await App.Current.MainPage.Navigation.PushAsync(new StatutPage()); - break; - case "LikePage": - await App.Current.MainPage.Navigation.PushAsync(new LikePage()); - break; - } + Page page = (Page)Activator.CreateInstance(pageType,this); + await App.Current.MainPage.Navigation.PushAsync(page); } - else await App.Current.MainPage.Navigation.PopToRootAsync(); }); } } diff --git a/sources/PocketBook/Applicative_VM/ScanMenuVM.cs b/sources/PocketBook/Applicative_VM/ScanMenuVM.cs new file mode 100644 index 0000000..1385472 --- /dev/null +++ b/sources/PocketBook/Applicative_VM/ScanMenuVM.cs @@ -0,0 +1,43 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Windows.Input; + +namespace PocketBook.Applicative_VM +{ + public class ScanMenuVM : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + public ICommand ShowScanMenu { get; private set; } + + private bool scanMenuIsVisible; + + public bool ScanMenuIsVisible + { + get { return scanMenuIsVisible; } + set + { + if (scanMenuIsVisible != value) + { + scanMenuIsVisible = value; + OnPropertyChanged(nameof(ScanMenuIsVisible)); + } + } + } + + public ScanMenuVM() + { + ShowScanMenu = new Command(() => + { + ScanMenuIsVisible = !ScanMenuIsVisible; + }); + } + + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/sources/PocketBook/MauiProgram.cs b/sources/PocketBook/MauiProgram.cs index 43fdb1d..d8ede8c 100644 --- a/sources/PocketBook/MauiProgram.cs +++ b/sources/PocketBook/MauiProgram.cs @@ -40,7 +40,17 @@ public static class MauiProgram }); builder.Services .AddSingleton() + .AddSingleton() .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() ; #if DEBUG builder.Logging.AddDebug(); diff --git a/sources/PocketBook/Pages/Auteur.xaml b/sources/PocketBook/Pages/Auteur.xaml index 602985b..9ec3630 100644 --- a/sources/PocketBook/Pages/Auteur.xaml +++ b/sources/PocketBook/Pages/Auteur.xaml @@ -10,9 +10,6 @@ - - - diff --git a/sources/PocketBook/Pages/Auteur.xaml.cs b/sources/PocketBook/Pages/Auteur.xaml.cs index f1f5f82..7dda99e 100644 --- a/sources/PocketBook/Pages/Auteur.xaml.cs +++ b/sources/PocketBook/Pages/Auteur.xaml.cs @@ -1,14 +1,15 @@ +using PocketBook.Applicative_VM; + namespace PocketBook; public partial class Auteur : ContentPage { - public Auteur() + public NavigatorVM NavigateCommandBooks { get; private set; } + + public Auteur(NavigatorVM navigator) { + NavigateCommandBooks = navigator; InitializeComponent(); } - private async void RetourMainMenu(object sender, EventArgs e) - { - await Navigation.PopToRootAsync(); - } } \ No newline at end of file diff --git a/sources/PocketBook/Pages/BookDetail.xaml.cs b/sources/PocketBook/Pages/BookDetail.xaml.cs index 18d411a..27145bc 100644 --- a/sources/PocketBook/Pages/BookDetail.xaml.cs +++ b/sources/PocketBook/Pages/BookDetail.xaml.cs @@ -1,22 +1,23 @@ +using PocketBook.Applicative_VM; + namespace PocketBook; public partial class BookDetail : ContentPage { - public BookDetail() - { - InitializeComponent(); - titreBook.Text = "La horde du contrevent"; - bookAuteur.Text = "Alain Damasio"; - bookEdition.Text = "Fayard (2019)"; - bookNbPages.Text = "700"; - bookISBN.Text = "9854645645456"; - bookLangue.Text = "français"; - bookStatus.Text = "Non lu"; - bookAdd.Text = "15 août 2013"; - } - private async void RetourMainMenu(object sender, EventArgs e) + public NavigatorVM NavigateCommandBooks { get; private set; } + + public BookDetail(NavigatorVM navigator) { - await Navigation.PopAsync(); + NavigateCommandBooks = navigator; + InitializeComponent(); + titreBook.Text = "La horde du contrevent"; + bookAuteur.Text = "Alain Damasio"; + bookEdition.Text = "Fayard (2019)"; + bookNbPages.Text = "700"; + bookISBN.Text = "9854645645456"; + bookLangue.Text = "français"; + bookStatus.Text = "Non lu"; + bookAdd.Text = "15 août 2013"; } } \ No newline at end of file diff --git a/sources/PocketBook/Pages/Composants/ContentView/ContentViewBook.xaml b/sources/PocketBook/Pages/Composants/ContentView/ContentViewBook.xaml index 24f8a6a..1966585 100644 --- a/sources/PocketBook/Pages/Composants/ContentView/ContentViewBook.xaml +++ b/sources/PocketBook/Pages/Composants/ContentView/ContentViewBook.xaml @@ -2,15 +2,18 @@ + xmlns:local="clr-namespace:PocketBook" + x:Name="root"> + + + - + -