mirror of https://github.com/ErsatzTV/ErsatzTV.git
17 changed files with 155 additions and 62 deletions
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
using System.Collections.Generic; |
||||
|
||||
namespace ErsatzTV.Application.MediaItems |
||||
{ |
||||
public record AggregateMediaItemResults(int Count, List<AggregateMediaItemViewModel> DataPage); |
||||
} |
||||
@ -1,13 +1,7 @@
@@ -1,13 +1,7 @@
|
||||
namespace ErsatzTV.Application.MediaItems |
||||
{ |
||||
public record AggregateMediaItemViewModel( |
||||
string Source, |
||||
string Title, |
||||
string Subtitle, |
||||
int Count, |
||||
string Duration) : IMediaCard |
||||
{ |
||||
public string SortTitle => |
||||
Title.ToLowerInvariant().StartsWith("the ") ? Title.Substring(4) : Title; |
||||
} |
||||
string SortTitle) : IMediaCard; |
||||
} |
||||
|
||||
@ -1,9 +1,8 @@
@@ -1,9 +1,8 @@
|
||||
using System.Collections.Generic; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Domain; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaItems.Queries |
||||
{ |
||||
public record GetAggregateMediaItems |
||||
(MediaType MediaType, string SearchString) : IRequest<List<AggregateMediaItemViewModel>>; |
||||
(MediaType MediaType, int PageNumber, int PageSize) : IRequest<AggregateMediaItemResults>; |
||||
} |
||||
|
||||
@ -1,49 +1,37 @@
@@ -1,49 +1,37 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.AggregateModels; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaItems.Queries |
||||
{ |
||||
public class |
||||
GetAggregateMediaItemsHandler : IRequestHandler<GetAggregateMediaItems, List<AggregateMediaItemViewModel>> |
||||
GetAggregateMediaItemsHandler : IRequestHandler<GetAggregateMediaItems, AggregateMediaItemResults> |
||||
{ |
||||
private readonly IMediaItemRepository _mediaItemRepository; |
||||
|
||||
public GetAggregateMediaItemsHandler(IMediaItemRepository mediaItemRepository) => |
||||
_mediaItemRepository = mediaItemRepository; |
||||
|
||||
public async Task<List<AggregateMediaItemViewModel>> Handle( |
||||
public async Task<AggregateMediaItemResults> Handle( |
||||
GetAggregateMediaItems request, |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
IEnumerable<MediaItem> allItems = await _mediaItemRepository.GetAll(request.MediaType); |
||||
int count = await _mediaItemRepository.GetCountByType(request.MediaType); |
||||
|
||||
if (!string.IsNullOrEmpty(request.SearchString)) |
||||
{ |
||||
allItems = allItems.Filter( |
||||
i => i.Metadata?.Title.Contains(request.SearchString, StringComparison.OrdinalIgnoreCase) == |
||||
true); |
||||
} |
||||
IEnumerable<MediaItemSummary> allItems = await _mediaItemRepository.GetPageByType( |
||||
request.MediaType, |
||||
request.PageNumber, |
||||
request.PageSize); |
||||
|
||||
return allItems.GroupBy(c => new { c.Source.Name, c.Metadata.Title }).Map( |
||||
group => new AggregateMediaItemViewModel( |
||||
group.Key.Name, |
||||
group.Key.Title, |
||||
request.MediaType == MediaType.TvShow |
||||
? $"{group.Count()} Episodes" |
||||
: group.Min(i => i.Metadata?.Aired?.Year).ToString(), |
||||
group.Count(), |
||||
group.Count() == 1 ? DisplayDuration(group.Head()) : string.Empty)) |
||||
var results = allItems |
||||
.Map(s => new AggregateMediaItemViewModel(s.Title, s.Subtitle, s.SortTitle)) |
||||
.ToList(); |
||||
} |
||||
|
||||
private static string DisplayDuration(MediaItem mediaItem) => string.Format( |
||||
mediaItem.Metadata?.Duration.TotalHours >= 1 ? @"{0:h\:mm\:ss}" : @"{0:mm\:ss}", |
||||
mediaItem.Metadata?.Duration); |
||||
return new AggregateMediaItemResults(count, results); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Core.AggregateModels |
||||
{ |
||||
public record MediaItemSummary(string Title, string SortTitle, string Subtitle); |
||||
} |
||||
@ -1,12 +0,0 @@
@@ -1,12 +0,0 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Data.Configurations |
||||
{ |
||||
public class LogEntryConfiguration : IEntityTypeConfiguration<LogEntry> |
||||
{ |
||||
public void Configure(EntityTypeBuilder<LogEntry> builder) => |
||||
builder.ToTable("Logs"); |
||||
} |
||||
} |
||||
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
using ErsatzTV.Core.AggregateModels; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Data.Configurations |
||||
{ |
||||
public class MediaItemSummaryConfiguration : IEntityTypeConfiguration<MediaItemSummary> |
||||
{ |
||||
public void Configure(EntityTypeBuilder<MediaItemSummary> builder) => |
||||
builder.HasNoKey(); |
||||
} |
||||
} |
||||
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations |
||||
{ |
||||
public partial class MetadataSortTitle : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.AddColumn<string>( |
||||
name: "Metadata_SortTitle", |
||||
table: "MediaItems", |
||||
type: "TEXT", |
||||
nullable: true); |
||||
|
||||
migrationBuilder.Sql( |
||||
@"UPDATE MediaItems
|
||||
SET Metadata_SortTitle = Metadata_Title");
|
||||
|
||||
migrationBuilder.Sql( |
||||
@"UPDATE MediaItems
|
||||
SET Metadata_SortTitle = substr(Metadata_Title, 5) |
||||
WHERE Metadata_Title LIKE 'the %'");
|
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.DropColumn( |
||||
name: "Metadata_SortTitle", |
||||
table: "MediaItems"); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue