Ajoute ISBN, tris et nouveautés d'auteur
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot
parent
359f4f59c6
commit
6b8f08ef26
@@ -2,6 +2,7 @@ using MaBibli.Api.Data;
|
||||
using MaBibli.Api.Services.Isbn;
|
||||
using MaBibli.Shared.Dtos;
|
||||
using MaBibli.Shared.Entites;
|
||||
using MaBibli.Shared.Isbn;
|
||||
using MaBibli.Shared.Textes;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
@@ -15,6 +16,9 @@ public interface IServiceBibliographie
|
||||
/// </summary>
|
||||
Task<BibliographieDto?> ObtenirAsync(int auteurId, string? utilisateur, CancellationToken ct = default);
|
||||
|
||||
Task<BibliographieDto?> ObtenirNouveautesAsync(
|
||||
int auteurId, string? utilisateur, CancellationToken ct = default);
|
||||
|
||||
Task<bool> MasquerAsync(int auteurId, string titre, string? utilisateur, CancellationToken ct = default);
|
||||
|
||||
Task<bool> DemasquerAsync(int auteurId, string titre, string? utilisateur, CancellationToken ct = default);
|
||||
@@ -101,6 +105,70 @@ public sealed class ServiceBibliographie(
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<BibliographieDto?> ObtenirNouveautesAsync(
|
||||
int auteurId, string? utilisateur, CancellationToken ct = default)
|
||||
{
|
||||
var auteur = await auteurs.ObtenirAsync(auteurId, ct);
|
||||
if (auteur is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var recherche = bnf is IBnfClientNouveautes etendu
|
||||
? await etendu.RechercherParAuteurNouveautesAsync(auteur.Nom, ct)
|
||||
: await bnf.RechercherParAuteurAsync(auteur.Nom, ct);
|
||||
var resultat = recherche.Resultat;
|
||||
|
||||
var possedes = await db.LivreAuteurs
|
||||
.AsNoTracking()
|
||||
.Where(la => la.AuteurId == auteurId)
|
||||
.Select(la => new { la.LivreId, la.Livre!.Titre, la.Livre.Isbn })
|
||||
.ToListAsync(ct);
|
||||
|
||||
var parTitre = new Dictionary<string, int>();
|
||||
var parIsbn = new Dictionary<string, int>();
|
||||
foreach (var livre in possedes)
|
||||
{
|
||||
var cle = CleOeuvre.Cle(livre.Titre);
|
||||
if (cle.Length > 0)
|
||||
{
|
||||
parTitre.TryAdd(cle, livre.LivreId);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(livre.Isbn))
|
||||
{
|
||||
parIsbn.TryAdd(livre.Isbn, livre.LivreId);
|
||||
}
|
||||
}
|
||||
|
||||
var souhaits = await SouhaitsAsync(utilisateur, ct);
|
||||
var masquees = await MasqueesAsync(auteurId, utilisateur, ct);
|
||||
var oeuvres = Regrouper(resultat)
|
||||
.Select(o => Confronter(o, parTitre, parIsbn, souhaits, masquees))
|
||||
.ToList();
|
||||
var seuil = AnneeSeuilNouveautes(
|
||||
possedes.Select(l => (l.Titre, l.Isbn)), resultat.Notices);
|
||||
|
||||
// Une notice d'édition originale ne date pas la dernière édition de l'œuvre. Le
|
||||
// regroupement conserve donc AnneeDerniereEdition, qui est la seule date pertinente
|
||||
// pour répondre à « paru depuis ».
|
||||
var nouveautes = FiltrerNouveautes(oeuvres, seuil);
|
||||
|
||||
return new BibliographieDto
|
||||
{
|
||||
Auteur = auteur,
|
||||
Oeuvres = nouveautes,
|
||||
NoticesAnnoncees = resultat.NombreAnnonce,
|
||||
NoticesLues = resultat.NombreLu,
|
||||
NoticesEcartees = resultat.EcarteesAutreAuteur + resultat.EcarteesTypeNonLivre,
|
||||
Avertissement = recherche.Avertissement,
|
||||
Etat = resultat.Etat,
|
||||
EstNouveautes = true,
|
||||
AnneeSeuilNouveautes = seuil,
|
||||
SeuilNouveautesInconnu = seuil is null && possedes.Count > 0,
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<bool> MasquerAsync(
|
||||
int auteurId, string titre, string? utilisateur, CancellationToken ct = default)
|
||||
{
|
||||
@@ -222,6 +290,12 @@ public sealed class ServiceBibliographie(
|
||||
{
|
||||
Titre = reference.Titre,
|
||||
Annee = reference.Annee,
|
||||
AnneeDerniereEdition = ordonnees
|
||||
.Select(n => AnneeTriable(n.Annee))
|
||||
.Where(a => a is not null)
|
||||
.Select(a => a!.Value)
|
||||
.DefaultIfEmpty()
|
||||
.Max() is var annee && annee > 0 ? annee : null,
|
||||
Editeur = reference.Editeur,
|
||||
Isbn = ordonnees.Select(n => n.Isbn).FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)),
|
||||
NombreEditions = groupe.Count(),
|
||||
@@ -258,6 +332,61 @@ public sealed class ServiceBibliographie(
|
||||
};
|
||||
}
|
||||
|
||||
public static int? AnneeSeuilNouveautes(
|
||||
IEnumerable<(string Titre, string? Isbn)> possedes,
|
||||
IReadOnlyList<NoticeAuteur> notices)
|
||||
{
|
||||
var annees = new List<int>();
|
||||
foreach (var livre in possedes)
|
||||
{
|
||||
var correspondantes = !string.IsNullOrWhiteSpace(livre.Isbn)
|
||||
? notices.Where(n => MemesIsbn(n.Isbn, livre.Isbn))
|
||||
: notices.Where(n => n.CleTitre == CleOeuvre.Cle(livre.Titre));
|
||||
|
||||
annees.AddRange(correspondantes
|
||||
.Select(n => AnneeTriable(n.Annee))
|
||||
.Where(a => a is not null)
|
||||
.Select(a => a!.Value));
|
||||
}
|
||||
|
||||
return annees.Count == 0 ? null : annees.Max();
|
||||
}
|
||||
|
||||
private static bool MemesIsbn(string? gauche, string? droite)
|
||||
{
|
||||
var a = IsbnUtils.Normaliser(gauche);
|
||||
var b = IsbnUtils.Normaliser(droite);
|
||||
if (string.IsNullOrWhiteSpace(a) || string.IsNullOrWhiteSpace(b))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.Equals(a, b, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return IsbnUtils.TryConvertirEnIsbn10(a, out var a10)
|
||||
&& string.Equals(a10, b, StringComparison.OrdinalIgnoreCase)
|
||||
|| IsbnUtils.TryConvertirEnIsbn10(b, out var b10)
|
||||
&& string.Equals(b10, a, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static IReadOnlyList<OeuvreBibliographie> FiltrerNouveautes(
|
||||
IEnumerable<OeuvreBibliographie> oeuvres, int? seuil)
|
||||
{
|
||||
if (seuil is null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return oeuvres
|
||||
.Where(o => o.AnneeDerniereEdition > seuil && o.ADecouvrir)
|
||||
.OrderByDescending(o => o.AnneeDerniereEdition)
|
||||
.ThenBy(o => o.Titre, StringComparer.CurrentCultureIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Année exploitable pour le tri, extraite d'une date BnF.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user