Database redesign (#31)
* starting database redesign * set season and episode numbers * use datetimes in db (utc); update movie metadata * get movie cards from new table * copy show/episode metadata * remove old movie metadata type * rename new movie metadata type * code cleanup * start to remove old television classes * remove old television tables from database * fix playout building * fix collection views * fix show/season views * clean up movie metadata table * fix scanner tests * add libraries ui * code cleanup * fix movie scanning/metadata * add library scan button to ui * delete library path from ui * temp disable movie scanning * remove orphan media items and prevent duplicate paths * attach artwork to metadata * fix split show/season display * fix television artwork * store year distinct from release date * fix collections ui * code cleanup * add library paths from ui * fix adding to collections from ui * fix schedule items loading * schedule editing works again * remove some todos * more cleanup * fix unit tests * fix episode sorting * fix deleting show library paths * remove unused class * fix playout list in ui * fix log viewer * start to use version/file instead of statistics * clean up old columns * fix playout display (time zone) * fix playback * fix channel guide time zone * cascade more deletes * fix compiler warnings * fix adding new seasons * use artwork for channel logo * clean cache folder on startup (move channel logos, delete everything else) * log database migration * update homepage docs for libraries * fix adding new channel with logo * fix episode numbers in epg
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace ErsatzTV.Application.MediaCards
|
||||
{
|
||||
public record SimpleMediaCollectionCardResultsViewModel(
|
||||
public record CollectionCardResultsViewModel(
|
||||
string Name,
|
||||
List<MovieCardViewModel> MovieCards,
|
||||
List<TelevisionShowCardViewModel> ShowCards,
|
||||
@@ -1,60 +1,70 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ErsatzTV.Core.Domain;
|
||||
using static LanguageExt.Prelude;
|
||||
|
||||
namespace ErsatzTV.Application.MediaCards
|
||||
{
|
||||
internal static class Mapper
|
||||
{
|
||||
internal static TelevisionShowCardViewModel ProjectToViewModel(TelevisionShow televisionShow) =>
|
||||
internal static TelevisionShowCardViewModel ProjectToViewModel(ShowMetadata showMetadata) =>
|
||||
new(
|
||||
televisionShow.Id,
|
||||
televisionShow.Metadata?.Title,
|
||||
televisionShow.Metadata?.Year.ToString(),
|
||||
televisionShow.Metadata?.SortTitle,
|
||||
televisionShow.Poster);
|
||||
showMetadata.ShowId,
|
||||
showMetadata.Title,
|
||||
showMetadata.Year?.ToString(),
|
||||
showMetadata.SortTitle,
|
||||
GetPoster(showMetadata));
|
||||
|
||||
internal static TelevisionSeasonCardViewModel ProjectToViewModel(TelevisionSeason televisionSeason) =>
|
||||
internal static TelevisionSeasonCardViewModel ProjectToViewModel(Season season) =>
|
||||
new(
|
||||
televisionSeason.TelevisionShow.Metadata?.Title,
|
||||
televisionSeason.Id,
|
||||
televisionSeason.Number,
|
||||
GetSeasonName(televisionSeason.Number),
|
||||
season.Show.ShowMetadata.HeadOrNone().Map(m => m.Title).IfNone(string.Empty),
|
||||
season.Id,
|
||||
season.SeasonNumber,
|
||||
GetSeasonName(season.SeasonNumber),
|
||||
string.Empty,
|
||||
GetSeasonName(televisionSeason.Number),
|
||||
televisionSeason.Poster,
|
||||
televisionSeason.Number == 0 ? "S" : televisionSeason.Number.ToString());
|
||||
GetSeasonName(season.SeasonNumber),
|
||||
season.SeasonMetadata.HeadOrNone().Map(GetPoster).IfNone(string.Empty),
|
||||
season.SeasonNumber == 0 ? "S" : season.SeasonNumber.ToString());
|
||||
|
||||
internal static TelevisionEpisodeCardViewModel ProjectToViewModel(
|
||||
TelevisionEpisodeMediaItem televisionEpisode) =>
|
||||
EpisodeMetadata episodeMetadata) =>
|
||||
new(
|
||||
televisionEpisode.Id,
|
||||
televisionEpisode.Metadata?.Aired ?? DateTime.MinValue,
|
||||
televisionEpisode.Season.TelevisionShow.Metadata.Title,
|
||||
televisionEpisode.Metadata?.Title,
|
||||
$"Episode {televisionEpisode.Metadata?.Episode}",
|
||||
televisionEpisode.Metadata?.Episode.ToString(),
|
||||
televisionEpisode.Poster,
|
||||
televisionEpisode.Metadata?.Episode.ToString());
|
||||
episodeMetadata.EpisodeId,
|
||||
episodeMetadata.ReleaseDate ?? DateTime.MinValue,
|
||||
episodeMetadata.Episode.Season.Show.ShowMetadata.HeadOrNone().Map(m => m.Title).IfNone(string.Empty),
|
||||
episodeMetadata.Title,
|
||||
$"Episode {episodeMetadata.Episode.EpisodeNumber}",
|
||||
episodeMetadata.Episode.EpisodeNumber.ToString(),
|
||||
GetThumbnail(episodeMetadata),
|
||||
episodeMetadata.Episode.EpisodeNumber.ToString());
|
||||
|
||||
internal static MovieCardViewModel ProjectToViewModel(MovieMediaItem movie) =>
|
||||
internal static MovieCardViewModel ProjectToViewModel(MovieMetadata movieMetadata) =>
|
||||
new(
|
||||
movie.Id,
|
||||
movie.Metadata?.Title,
|
||||
movie.Metadata?.Year?.ToString(),
|
||||
movie.Metadata?.SortTitle,
|
||||
movie.Poster);
|
||||
movieMetadata.MovieId,
|
||||
movieMetadata.Title,
|
||||
movieMetadata.Year?.ToString(),
|
||||
movieMetadata.SortTitle,
|
||||
GetPoster(movieMetadata));
|
||||
|
||||
internal static SimpleMediaCollectionCardResultsViewModel
|
||||
ProjectToViewModel(SimpleMediaCollection collection) =>
|
||||
internal static CollectionCardResultsViewModel
|
||||
ProjectToViewModel(Collection collection) =>
|
||||
new(
|
||||
collection.Name,
|
||||
collection.Movies.Map(ProjectToViewModel).ToList(),
|
||||
collection.TelevisionShows.Map(ProjectToViewModel).ToList(),
|
||||
collection.TelevisionSeasons.Map(ProjectToViewModel).ToList(),
|
||||
collection.TelevisionEpisodes.Map(ProjectToViewModel).ToList());
|
||||
collection.MediaItems.OfType<Movie>().Map(m => ProjectToViewModel(m.MovieMetadata.Head())).ToList(),
|
||||
collection.MediaItems.OfType<Show>().Map(s => ProjectToViewModel(s.ShowMetadata.Head())).ToList(),
|
||||
collection.MediaItems.OfType<Season>().Map(ProjectToViewModel).ToList(),
|
||||
collection.MediaItems.OfType<Episode>().Map(e => ProjectToViewModel(e.EpisodeMetadata.Head()))
|
||||
.ToList());
|
||||
|
||||
private static string GetSeasonName(int number) =>
|
||||
number == 0 ? "Specials" : $"Season {number}";
|
||||
|
||||
private static string GetPoster(Metadata metadata) =>
|
||||
Optional(metadata.Artwork.FirstOrDefault(a => a.ArtworkKind == ArtworkKind.Poster))
|
||||
.Match(a => a.Path, string.Empty);
|
||||
|
||||
private static string GetThumbnail(Metadata metadata) =>
|
||||
Optional(metadata.Artwork.FirstOrDefault(a => a.ArtworkKind == ArtworkKind.Thumbnail))
|
||||
.Match(a => a.Path, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using ErsatzTV.Core;
|
||||
using LanguageExt;
|
||||
using MediatR;
|
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries
|
||||
{
|
||||
public record GetCollectionCards(int Id) : IRequest<Either<BaseError, CollectionCardResultsViewModel>>;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ErsatzTV.Core;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
using LanguageExt;
|
||||
using MediatR;
|
||||
using static ErsatzTV.Application.MediaCards.Mapper;
|
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries
|
||||
{
|
||||
public class GetCollectionCardsHandler : IRequestHandler<GetCollectionCards,
|
||||
Either<BaseError, CollectionCardResultsViewModel>>
|
||||
{
|
||||
private readonly IMediaCollectionRepository _collectionRepository;
|
||||
|
||||
public GetCollectionCardsHandler(IMediaCollectionRepository collectionRepository) =>
|
||||
_collectionRepository = collectionRepository;
|
||||
|
||||
public async Task<Either<BaseError, CollectionCardResultsViewModel>> Handle(
|
||||
GetCollectionCards request,
|
||||
CancellationToken cancellationToken) =>
|
||||
(await _collectionRepository.GetCollectionWithItemsUntracked(request.Id))
|
||||
.ToEither(BaseError.New("Unable to load collection"))
|
||||
.Map(ProjectToViewModel);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using ErsatzTV.Core;
|
||||
using LanguageExt;
|
||||
using MediatR;
|
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries
|
||||
{
|
||||
public record GetSimpleMediaCollectionCards
|
||||
(int Id) : IRequest<Either<BaseError, SimpleMediaCollectionCardResultsViewModel>>;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ErsatzTV.Core;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
using LanguageExt;
|
||||
using MediatR;
|
||||
using static ErsatzTV.Application.MediaCards.Mapper;
|
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries
|
||||
{
|
||||
public class GetSimpleMediaCollectionCardsHandler : IRequestHandler<GetSimpleMediaCollectionCards,
|
||||
Either<BaseError, SimpleMediaCollectionCardResultsViewModel>>
|
||||
{
|
||||
private readonly IMediaCollectionRepository _mediaCollectionRepository;
|
||||
|
||||
public GetSimpleMediaCollectionCardsHandler(IMediaCollectionRepository mediaCollectionRepository) =>
|
||||
_mediaCollectionRepository = mediaCollectionRepository;
|
||||
|
||||
public async Task<Either<BaseError, SimpleMediaCollectionCardResultsViewModel>> Handle(
|
||||
GetSimpleMediaCollectionCards request,
|
||||
CancellationToken cancellationToken) =>
|
||||
(await _mediaCollectionRepository.GetSimpleMediaCollectionWithItemsUntracked(request.Id))
|
||||
.ToEither(BaseError.New("Unable to load collection"))
|
||||
.Map(ProjectToViewModel);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user