namespace Halo.Core.Library; /// Eine Datei auf der Platte, so wie der Scan sie vorgefunden hat. /// /// /// /// Die Datei zeigt auf den Titel, nicht umgekehrt. Das sieht /// herumgedreht aus und ist Absicht: ein Film liegt oft zweimal vor, als 4K /// und als 1080p. Trüge der Film den Verweis auf seine eine Datei, wäre die /// zweite Fassung ein Umbau am Datenmodell — so ist sie eine Zeile mehr. /// /// /// Genau dasselbe gilt für Folgen. /// /// public sealed class MediaFile { public Guid Id { get; init; } = Guid.CreateVersion7(); public required Guid LibraryId { get; init; } /// Der Pfad, wie der Server ihn sieht — im Container, nicht auf dem Wirt. public required string Path { get; set; } public long SizeBytes { get; set; } public DateTimeOffset ModifiedAt { get; set; } /// Wann der letzte Scan diese Datei noch vorgefunden hat. /// /// /// Daran hängt das Aufräumen: Was ein Lauf nicht gesehen hat, liegt nicht /// mehr da. Ohne diese Angabe müsste der Scan sich merken, was er gesehen /// hat, und das wächst mit dem Bestand. /// public DateTimeOffset SeenAt { get; set; } public Guid? MovieId { get; set; } public Guid? EpisodeId { get; set; } } public sealed class Movie { public Guid Id { get; init; } = Guid.CreateVersion7(); public required Guid LibraryId { get; init; } /// Der Titel, wie er aus dem Dateinamen gelesen wurde. /// /// /// Daran ordnet der Scan zu, nicht an . Der /// angezeigte Titel kommt nach dem ersten Lauf von der Metadatenquelle und /// ändert sich dabei — aus „The Matrix" wird „Matrix". Würde der nächste /// Scan darauf suchen, fände er nichts, legte den Film ein zweites Mal an, /// und die Mediathek wüchse bei jedem Lauf. Dieses Feld ändert sich nie. /// public required string ParsedTitle { get; init; } public required string Title { get; set; } /// Ohne führenden Artikel — siehe . public required string SortTitleValue { get; set; } public int? Year { get; set; } public string? Overview { get; set; } /// Die Kennung bei TMDB, sobald zugeordnet. public int? TmdbId { get; set; } /// Schlüssel des zwischengespeicherten Plakats — siehe Bildablage. /// /// /// Der Schlüssel, nicht die Adresse bei TMDB. Würde die App dort unmittelbar /// laden, bräuchte sie Internet für ein Plakat, das zehn Zentimeter weiter /// auf der Platte liegt — und TMDB erführe, wer wann was ansieht. /// public string? PosterImage { get; set; } public string? BackdropImage { get; set; } public DateTimeOffset AddedAt { get; init; } = DateTimeOffset.UtcNow; } public sealed class Series { public Guid Id { get; init; } = Guid.CreateVersion7(); public required Guid LibraryId { get; init; } /// Der Titel, wie er aus dem Dateinamen gelesen wurde. /// /// /// Daran ordnet der Scan zu, nicht an . Der /// angezeigte Titel kommt nach dem ersten Lauf von der Metadatenquelle und /// ändert sich dabei — aus „The Matrix" wird „Matrix". Würde der nächste /// Scan darauf suchen, fände er nichts, legte den Film ein zweites Mal an, /// und die Mediathek wüchse bei jedem Lauf. Dieses Feld ändert sich nie. /// public required string ParsedTitle { get; init; } public required string Title { get; set; } public required string SortTitleValue { get; set; } public int? Year { get; set; } public string? Overview { get; set; } public int? TmdbId { get; set; } /// Schlüssel des zwischengespeicherten Plakats — siehe Bildablage. /// /// /// Der Schlüssel, nicht die Adresse bei TMDB. Würde die App dort unmittelbar /// laden, bräuchte sie Internet für ein Plakat, das zehn Zentimeter weiter /// auf der Platte liegt — und TMDB erführe, wer wann was ansieht. /// public string? PosterImage { get; set; } public string? BackdropImage { get; set; } public DateTimeOffset AddedAt { get; init; } = DateTimeOffset.UtcNow; } public sealed class Episode { public Guid Id { get; init; } = Guid.CreateVersion7(); public required Guid SeriesId { get; init; } public required int SeasonNumber { get; init; } public required int EpisodeNumber { get; init; } public string? Title { get; set; } public string? Overview { get; set; } /// Das Standbild der Folge. public string? StillImage { get; set; } public DateTimeOffset AddedAt { get; init; } = DateTimeOffset.UtcNow; }