Files
Libation/Source/DataLayer/EfClasses/Contributor.cs
T
Cursor Agentandrmcrackan a0045156c1 docs: drop Neil Gaiman from the examples
Replaced with Stephen Fry, who the search and naming-template docs already use
as a narrator and who writes and narrates his own books, so the author-narrator
examples still say what they meant to.

The one code mention is a comment describing how Audible builds a contributor
URL. It used his real author page and id; the point being made is that the name
in the path is decorative, so a placeholder id makes it better, not worse.

Two things fell out of editing the narrator format line. Its template printed
'\) ' - a backslash inside quotes that already make the paren literal - so it
produced "Arthur (Conan\) Doyle", not the output printed beside it. And the
line is raw HTML rather than backticks, so markdown ate the backslash before
the opening paren, leaving the website showing a different template from the
markdown. Both spellings produce the documented output; the line now uses the
one that survives rendering, so source and page agree.

The screenshot for the author-narrator search showed a Gaiman query, so it is
replaced by the query inline. The now-unreferenced image is removed with it.

Co-authored-by: rmcrackan <rmcrackan@gmail.com>
2026-08-24 20:31:29 +00:00

55 lines
2.2 KiB
C#

using Dinah.Core;
using System.Collections.Generic;
using System.Linq;
namespace DataLayer;
public class Contributor
{
// Empty is a special case. use private ctor w/o validation
public static Contributor GetEmpty() => new() { ContributorId = -1, Name = "" };
// contributors search links are just name with url-encoding. space can be + or %20
// author search link: /search?searchAuthor=Robert+Bevan
// narrator search link: /search?searchNarrator=Robert+Bevan
// can also search multiples. concat with comma before url encode
// id.s
// ----
// the name in the path is decorative; the id is what resolves it. Both of these reach the same page:
// https://www.audible.com/author/Robert-Bevan/B0EXAMPLE1 == https://www.audible.com/author/B0EXAMPLE1
// goes to summary page
// at bottom "See all titles by Robert Bevan" goes to https://www.audible.com/search?searchAuthor=Robert+Bevan
// some authors have no id. simply goes to https://www.audible.com/search?searchAuthor=Rufus+Fears
// all narrators have no id: https://www.audible.com/search?searchNarrator=Robert+Bevan
internal int ContributorId { get; private set; }
public string Name { get; private set; }
private readonly HashSet<BookContributor> _booksLink;
public IEnumerable<BookContributor> BooksLink => _booksLink?.ToList() ?? [];
public string? AudibleContributorId { get; private set; }
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
private Contributor() { }
#pragma warning restore CS8618
public Contributor(string name, string? audibleContributorId = null)
{
Name = ArgumentValidator.EnsureNotNullOrWhiteSpace(name, nameof(name));
_booksLink = new HashSet<BookContributor>();
SetAudibleContributorId(audibleContributorId);
}
public override string ToString() => Name;
public void SetAudibleContributorId(string? audibleContributorId)
{
// don't overwrite with null or whitespace but not an error
if (!string.IsNullOrWhiteSpace(audibleContributorId))
AudibleContributorId = audibleContributorId;
}
public bool IsEmpty => ContributorId == -1;
}