Browse Source

Merge branch 'main' into scanning-and-metadata

pull/23/head
Jason Dove 6 years ago
parent
commit
ab968d0c6c
  1. 4
      .github/workflows/release.yml
  2. 5
      Directory.Build.props
  3. 3
      Dockerfile
  4. 12
      ErsatzTV.Application/Logs/LogEntryViewModel.cs
  5. 16
      ErsatzTV.Application/Logs/Mapper.cs
  6. 7
      ErsatzTV.Application/Logs/Queries/GetRecentLogEntries.cs
  7. 21
      ErsatzTV.Application/Logs/Queries/GetRecentLogEntriesHandler.cs
  8. 12
      ErsatzTV.Core/Domain/LogEntry.cs
  9. 2
      ErsatzTV.Core/FileSystemLayout.cs
  10. 11
      ErsatzTV.Core/Interfaces/Repositories/ILogRepository.cs
  11. 12
      ErsatzTV.Infrastructure/Data/Configurations/LogEntryConfiguration.cs
  12. 21
      ErsatzTV.Infrastructure/Data/LogContext.cs
  13. 19
      ErsatzTV.Infrastructure/Data/Repositories/LogRepository.cs
  14. 1
      ErsatzTV/ErsatzTV.csproj
  15. 29
      ErsatzTV/Pages/Logs.razor
  16. 2
      ErsatzTV/Program.cs
  17. 13
      ErsatzTV/Shared/MainLayout.razor
  18. 4
      ErsatzTV/Startup.cs
  19. 2
      docker-compose.yml

4
.github/workflows/release.yml

@ -42,8 +42,8 @@ jobs: @@ -42,8 +42,8 @@ jobs:
release_name_cli="ErsatzTV.CommandLine-$tag-${{ matrix.target }}"
# Build everything
dotnet publish ErsatzTV/ErsatzTV.csproj --framework net5.0 --runtime "${{ matrix.target }}" -c Release -o "$release_name"
dotnet publish ErsatzTV.CommandLine/ErsatzTV.CommandLine.csproj --framework net5.0 --runtime "${{ matrix.target }}" -c Release -o "$release_name_cli"
dotnet publish ErsatzTV/ErsatzTV.csproj --framework net5.0 --runtime "${{ matrix.target }}" -c Release -o "$release_name" /property:InformationalVersion="${tag:1}-${{ matrix.target }}"
dotnet publish ErsatzTV.CommandLine/ErsatzTV.CommandLine.csproj --framework net5.0 --runtime "${{ matrix.target }}" -c Release -o "$release_name_cli" /property:InformationalVersion="${tag:1}-${{ matrix.target }}"
# Pack files
if [ "${{ matrix.target }}" == "win-x64" ]; then

5
Directory.Build.props

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
<Project>
<PropertyGroup>
<InformationalVersion>develop</InformationalVersion>
</PropertyGroup>
</Project>

3
Dockerfile

@ -26,7 +26,8 @@ COPY ErsatzTV.Core/. ./ErsatzTV.Core/ @@ -26,7 +26,8 @@ COPY ErsatzTV.Core/. ./ErsatzTV.Core/
COPY ErsatzTV.Core.Tests/. ./ErsatzTV.Core.Tests/
COPY ErsatzTV.Infrastructure/. ./ErsatzTV.Infrastructure/
WORKDIR /source/ErsatzTV
RUN dotnet publish -c release -o /app -r linux-x64 --self-contained false --no-restore
ARG INFO_VERSION="unknown"
RUN dotnet publish -c release -o /app -r linux-x64 --self-contained false --no-restore /p:InformationalVersion=${INFO_VERSION}
# final stage/image
FROM runtime-base

12
ErsatzTV.Application/Logs/LogEntryViewModel.cs

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
using System;
namespace ErsatzTV.Application.Logs
{
public record LogEntryViewModel(
int Id,
DateTime Timestamp,
string Level,
string Exception,
string RenderedMessage,
string Properties);
}

16
ErsatzTV.Application/Logs/Mapper.cs

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
using ErsatzTV.Core.Domain;
namespace ErsatzTV.Application.Logs
{
internal static class Mapper
{
internal static LogEntryViewModel ProjectToViewModel(LogEntry logEntry) =>
new(
logEntry.Id,
logEntry.Timestamp,
logEntry.Level,
logEntry.Exception,
logEntry.RenderedMessage,
logEntry.Properties);
}
}

7
ErsatzTV.Application/Logs/Queries/GetRecentLogEntries.cs

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
using System.Collections.Generic;
using MediatR;
namespace ErsatzTV.Application.Logs.Queries
{
public record GetRecentLogEntries : IRequest<List<LogEntryViewModel>>;
}

21
ErsatzTV.Application/Logs/Queries/GetRecentLogEntriesHandler.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ErsatzTV.Core.Interfaces.Repositories;
using LanguageExt;
using MediatR;
using static ErsatzTV.Application.Logs.Mapper;
namespace ErsatzTV.Application.Logs.Queries
{
public class GetRecentLogEntriesHandler : IRequestHandler<GetRecentLogEntries, List<LogEntryViewModel>>
{
private readonly ILogRepository _logRepository;
public GetRecentLogEntriesHandler(ILogRepository logRepository) => _logRepository = logRepository;
public Task<List<LogEntryViewModel>> Handle(GetRecentLogEntries request, CancellationToken cancellationToken) =>
_logRepository.GetRecentLogEntries().Map(list => list.Map(ProjectToViewModel).ToList());
}
}

12
ErsatzTV.Core/Domain/LogEntry.cs

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
using System;
namespace ErsatzTV.Core.Domain
{
public record LogEntry(
int Id,
DateTime Timestamp,
string Level,
string Exception,
string RenderedMessage,
string Properties);
}

2
ErsatzTV.Core/FileSystemLayout.cs

@ -13,6 +13,8 @@ namespace ErsatzTV.Core @@ -13,6 +13,8 @@ namespace ErsatzTV.Core
public static readonly string DatabasePath = Path.Combine(AppDataFolder, "ersatztv.sqlite3");
public static readonly string LogDatabasePath = Path.Combine(AppDataFolder, "logs.sqlite3");
public static readonly string ImageCacheFolder = Path.Combine(AppDataFolder, "cache", "images");
public static readonly string PlexSecretsPath = Path.Combine(AppDataFolder, "plex-secrets.json");

11
ErsatzTV.Core/Interfaces/Repositories/ILogRepository.cs

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using ErsatzTV.Core.Domain;
namespace ErsatzTV.Core.Interfaces.Repositories
{
public interface ILogRepository
{
public Task<List<LogEntry>> GetRecentLogEntries();
}
}

12
ErsatzTV.Infrastructure/Data/Configurations/LogEntryConfiguration.cs

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
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");
}
}

21
ErsatzTV.Infrastructure/Data/LogContext.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
using ErsatzTV.Core.Domain;
using Microsoft.EntityFrameworkCore;
namespace ErsatzTV.Infrastructure.Data
{
public class LogContext : DbContext
{
public LogContext(DbContextOptions<LogContext> options)
: base(options)
{
}
public DbSet<LogEntry> LogEntries { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfigurationsFromAssembly(typeof(LogContext).Assembly);
}
}
}

19
ErsatzTV.Infrastructure/Data/Repositories/LogRepository.cs

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories;
using Microsoft.EntityFrameworkCore;
namespace ErsatzTV.Infrastructure.Data.Repositories
{
public class LogRepository : ILogRepository
{
private readonly LogContext _logContext;
public LogRepository(LogContext logContext) => _logContext = logContext;
public Task<List<LogEntry>> GetRecentLogEntries() =>
_logContext.LogEntries.OrderByDescending(e => e.Id).Take(100).ToListAsync();
}
}

1
ErsatzTV/ErsatzTV.csproj

@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.SQLite" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.0.2" />
</ItemGroup>

29
ErsatzTV/Pages/Logs.razor

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
@page "/system/logs"
@using ErsatzTV.Application.Logs
@using ErsatzTV.Application.Logs.Queries
@inject IMediator Mediator
<MudTable FixedHeader="true" Dense="true" Items="_logEntries">
<HeaderContent>
<MudTh>Timestamp</MudTh>
<MudTh>Level</MudTh>
<MudTh>Message</MudTh>
<MudTh>Properties</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Timestamp">@context.Timestamp</MudTd>
<MudTd DataLabel="Level">@context.Level</MudTd>
<MudTd DataLabel="Message">@context.RenderedMessage</MudTd>
<MudTd DataLabel="Message">@context.Properties</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager/>
</PagerContent>
</MudTable>
@code {
private List<LogEntryViewModel> _logEntries;
protected override async Task OnInitializedAsync() => _logEntries = await Mediator.Send(new GetRecentLogEntries());
}

2
ErsatzTV/Program.cs

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
using ErsatzTV.Core;
using ErsatzTV.Extensions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
@ -25,6 +26,7 @@ namespace ErsatzTV @@ -25,6 +26,7 @@ namespace ErsatzTV
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.Enrich.FromLogContext()
.WriteTo.SQLite(FileSystemLayout.LogDatabasePath, retentionPeriod: TimeSpan.FromDays(1))
.CreateLogger();
try

13
ErsatzTV/Shared/MainLayout.razor

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
@inherits LayoutComponentBase
@using System.Reflection
@inherits LayoutComponentBase
<MudThemeProvider Theme="_ersatzTvTheme"/>
<MudDialogProvider DisableBackdropClick="true"/>
@ -32,6 +33,12 @@ @@ -32,6 +33,12 @@
</MudNavGroup>
<MudNavLink Href="/schedules">Schedules</MudNavLink>
<MudNavLink Href="/playouts">Playouts</MudNavLink>
<MudNavLink Href="/system/logs">Logs</MudNavLink>
<MudDivider Class="my-6" DividerType="DividerType.Middle" />
<MudContainer Style="text-align: right" Class="mr-6">
<MudText Typo="Typo.body2">ErsatzTV Version</MudText>
<MudText Typo="Typo.body2" Color="Color.Info">@InfoVersion</MudText>
</MudContainer>
</MudNavMenu>
</MudDrawer>
<MudMainContent>
@ -42,7 +49,9 @@ @@ -42,7 +49,9 @@
</MudLayout>
@code {
bool _drawerOpen = true;
private static readonly string InfoVersion = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "unknown";
private bool _drawerOpen = true;
private void DrawerToggle() => _drawerOpen = !_drawerOpen;

4
ErsatzTV/Startup.cs

@ -108,6 +108,9 @@ namespace ErsatzTV @@ -108,6 +108,9 @@ namespace ErsatzTV
o.MigrationsAssembly("ErsatzTV.Infrastructure");
}));
services.AddDbContext<LogContext>(
options => options.UseSqlite($"Data Source={FileSystemLayout.LogDatabasePath}"));
services.AddMediatR(typeof(GetAllChannels).Assembly);
services.AddRefitClient<IPlexTvApi>()
@ -156,6 +159,7 @@ namespace ErsatzTV @@ -156,6 +159,7 @@ namespace ErsatzTV
services.AddScoped<IConfigElementRepository, ConfigElementRepository>();
services.AddScoped<IProgramScheduleRepository, ProgramScheduleRepository>();
services.AddScoped<IPlayoutRepository, PlayoutRepository>();
services.AddScoped<ILogRepository, LogRepository>();
services.AddScoped<IFFmpegLocator, FFmpegLocator>();
services.AddScoped<ISmartCollectionBuilder, SmartCollectionBuilder>();
services.AddScoped<ILocalMetadataProvider, LocalMetadataProvider>();

2
docker-compose.yml

@ -4,6 +4,8 @@ services: @@ -4,6 +4,8 @@ services:
ersatztv:
build:
context: .
args:
INFO_VERSION: "docker-compose-develop"
ports:
- "8409:8409"
volumes:

Loading…
Cancel
Save