From 15e2a650b9c0d0cec81e951d3a1508554e43960e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=A4felfinger?= Date: Wed, 30 Jan 2019 22:49:01 +0100 Subject: [PATCH] Updated DB Schema and added new initial create --- Tv7Playlist.Core/IPlaylistBuilder.cs | 2 +- Tv7Playlist.Core/PlaylistBuilder.cs | 67 ++++++++++++++----- Tv7Playlist.Core/PlaylistSynchronizer.cs | 17 +++-- ... 20190130214707_InitialCreate.Designer.cs} | 30 +++++---- ...ate.cs => 20190130214707_InitialCreate.cs} | 25 ++++--- .../PlaylistContextModelSnapshot.cs | 28 +++++--- Tv7Playlist.Data/PlaylistContext.cs | 2 +- Tv7Playlist.Data/PlaylistEntry.cs | 16 +++-- Tv7Playlist/Controllers/HomeController.cs | 2 +- .../Controllers/PlaylistApiController.cs | 21 +++++- .../Controllers/PlaylistEntryController.cs | 6 +- Tv7Playlist/Views/Home/Index.cshtml | 22 +++--- Tv7Playlist/Views/PlaylistEntry/Edit.cshtml | 29 +++++--- Tv7Playlist/Views/Shared/_Layout.cshtml | 5 +- 14 files changed, 188 insertions(+), 84 deletions(-) rename Tv7Playlist.Data/Migrations/{20190125212615_InitialCreate.Designer.cs => 20190130214707_InitialCreate.Designer.cs} (72%) rename Tv7Playlist.Data/Migrations/{20190125212615_InitialCreate.cs => 20190130214707_InitialCreate.cs} (70%) diff --git a/Tv7Playlist.Core/IPlaylistBuilder.cs b/Tv7Playlist.Core/IPlaylistBuilder.cs index 0bfa2e4..b74fe1e 100644 --- a/Tv7Playlist.Core/IPlaylistBuilder.cs +++ b/Tv7Playlist.Core/IPlaylistBuilder.cs @@ -5,6 +5,6 @@ namespace Tv7Playlist.Core { public interface IPlaylistBuilder { - Task GeneratePlaylistAsync(); + Task GeneratePlaylistAsync(bool useProxy); } } \ No newline at end of file diff --git a/Tv7Playlist.Core/PlaylistBuilder.cs b/Tv7Playlist.Core/PlaylistBuilder.cs index 7bf9bfe..67e4118 100644 --- a/Tv7Playlist.Core/PlaylistBuilder.cs +++ b/Tv7Playlist.Core/PlaylistBuilder.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -20,42 +21,78 @@ namespace Tv7Playlist.Core _playlistContext = playlistContext ?? throw new ArgumentNullException(nameof(playlistContext)); } - public async Task GeneratePlaylistAsync() + public async Task GeneratePlaylistAsync(bool useProxy) { _logger.LogInformation(LoggingEvents.Playlist, "Building m3u file content"); var playlistEntries = await _playlistContext.PlaylistEntries.Where(e => e.IsAvailable).Where(e => e.IsEnabled) .OrderBy(e => e.Position).AsNoTracking().ToListAsync(); - - return await CreatePlaylistStreamAsync(playlistEntries); + return await CreatePlaylistStreamAsync(playlistEntries, useProxy); } - private static async Task CreatePlaylistStreamAsync(IEnumerable playlistEntries) + private static async Task CreatePlaylistStreamAsync(IEnumerable playlistEntries, bool useProxy) { var outStream = new MemoryStream(); var outWriter = new StreamWriter(outStream); await outWriter.WriteLineAsync(M3UConstants.ExtFileStartTag); - foreach (var entry in playlistEntries) await WriteEntryAsync(outWriter, entry); + foreach (var entry in playlistEntries) await WriteM3UEntryAsync(outWriter, entry, useProxy); - outStream.Seek(0, SeekOrigin.Begin); + await outWriter.FlushAsync(); + outStream.Seek(0, SeekOrigin.Begin); + return outStream; } - private static async Task WriteEntryAsync(TextWriter outWriter, PlaylistEntry entry) + private static async Task WriteM3UEntryAsync(TextWriter outWriter, PlaylistEntry entry, bool useProxy) { + await WriteExtInfoLineAsync(outWriter, entry); + await WriteUrlAsync(outWriter, entry, useProxy); + } + + private static async Task WriteUrlAsync(TextWriter outWriter, PlaylistEntry entry, bool useProxy) + { + if (useProxy) + await outWriter.WriteLineAsync(entry.UrlProxy); + else + await outWriter.WriteLineAsync(entry.UrlOriginal); + } + + private static async Task WriteExtInfoLineAsync(TextWriter outWriter, PlaylistEntry entry) + { + // telly default tags from 1.1 dev code: + // - NameKey # Parsed from the end of the exif by default + // - ChannelNumberKey = "tvg-chno" + // - LogoKey = "tvg-logo" + // - EPGMatchKey = "tvg-id" + //#EXTINF:-1 tvg-chno="34" tvg-id="SRF1HD" tvg-logo="http://",test + var exInfoBuilder = new StringBuilder(); + exInfoBuilder.Append(M3UConstants.ExtInfStartTag); + const int duration = -1; - var number = entry.TrackNumberOverride != 0 ? entry.TrackNumberOverride : entry.TrackNumber; - var name = !string.IsNullOrWhiteSpace(entry.NameOverride) ? entry.NameOverride : entry.Name; - - //var extInfo = $"{M3UConstants.ExtInfStartTag}{duration},{number},{name}"; - //TODO: check tagformat and how to serialize them - var extInfo = $"{M3UConstants.ExtInfStartTag}{duration},{name}"; - await outWriter.WriteLineAsync(extInfo); - await outWriter.WriteLineAsync(entry.Url); + exInfoBuilder.Append(duration); + + AddTag(exInfoBuilder, "tvg-chno", entry.ChannelNumberExport.ToString()); + AddTag(exInfoBuilder, "tvg-id", entry.EpgMatchName); + + if (!string.IsNullOrWhiteSpace(entry.LogoUrl)) AddTag(exInfoBuilder, "tvg-logo", entry.LogoUrl); + + exInfoBuilder.Append(","); + exInfoBuilder.Append(entry.Name); + + await outWriter.WriteLineAsync(exInfoBuilder.ToString()); + } + + private static void AddTag(StringBuilder builder, string name, string value) + { + builder.Append(" "); + builder.Append(name); + builder.Append("=\""); + builder.Append(value); + builder.Append("\""); } } } \ No newline at end of file diff --git a/Tv7Playlist.Core/PlaylistSynchronizer.cs b/Tv7Playlist.Core/PlaylistSynchronizer.cs index 2c2815f..8ab4d71 100644 --- a/Tv7Playlist.Core/PlaylistSynchronizer.cs +++ b/Tv7Playlist.Core/PlaylistSynchronizer.cs @@ -36,7 +36,7 @@ namespace Tv7Playlist.Core _logger.LogDebug(LoggingEvents.Synchronize, "Synchronizing playlist from server..."); var tv7Url = GetTv7SourceUrl(); - var existingEntries = await _playlistContext.PlaylistEntries.ToDictionaryAsync(e => e.TrackNumber); + var existingEntries = await _playlistContext.PlaylistEntries.ToDictionaryAsync(e => e.ChannelNumberImport); var tracks = await _playlistLoader.LoadPlaylistFromUrl(tv7Url); MarkNotAvailableEntries(existingEntries, tracks); @@ -57,7 +57,13 @@ namespace Tv7Playlist.Core _logger.LogInformation(LoggingEvents.Synchronize, $"Adding playlist entry {track.Id} - {track.Name}"); entry = new PlaylistEntry { - Id = Guid.NewGuid(), Position = track.Id, TrackNumber = track.Id, IsEnabled = true + Id = Guid.NewGuid(), + Position = track.Id, + ChannelNumberImport = track.Id, + ChannelNumberExport = track.Id, + EpgMatchName = track.Name?.Replace(" ",string.Empty), + IsEnabled = false, + Created = DateTime.Now }; _playlistContext.PlaylistEntries.Add(entry); } @@ -69,11 +75,12 @@ namespace Tv7Playlist.Core entry.IsAvailable = true; entry.Name = track.Name; entry.UrlOriginal = track.Url; - entry.Url = BuildUrl(entry); + entry.UrlProxy = BuildProxiedUrl(entry); + entry.Modified = DateTime.Now; } } - private string BuildUrl(PlaylistEntry entry) + private string BuildProxiedUrl(PlaylistEntry entry) { return MultiCastRegex.Replace(entry.UrlOriginal, $"{_proxyUrl}/$2/"); } @@ -118,7 +125,7 @@ namespace Tv7Playlist.Core var unavailableEntries = existingEntries.Where(e => tracks.All(t => t.Id != e.Key)).Select(e => e.Value); foreach (var entry in unavailableEntries) { - _logger.LogInformation(LoggingEvents.Synchronize, $"Channel {entry.TrackNumber} - {entry.Name} is no longer available."); + _logger.LogInformation(LoggingEvents.Synchronize, $"Channel {entry.ChannelNumberImport} - {entry.Name} is no longer available."); entry.IsAvailable = false; } } diff --git a/Tv7Playlist.Data/Migrations/20190125212615_InitialCreate.Designer.cs b/Tv7Playlist.Data/Migrations/20190130214707_InitialCreate.Designer.cs similarity index 72% rename from Tv7Playlist.Data/Migrations/20190125212615_InitialCreate.Designer.cs rename to Tv7Playlist.Data/Migrations/20190130214707_InitialCreate.Designer.cs index 503f491..111c8c9 100644 --- a/Tv7Playlist.Data/Migrations/20190125212615_InitialCreate.Designer.cs +++ b/Tv7Playlist.Data/Migrations/20190130214707_InitialCreate.Designer.cs @@ -9,7 +9,7 @@ using Tv7Playlist.Data; namespace Tv7Playlist.Data.Migrations { [DbContext(typeof(PlaylistContext))] - [Migration("20190125212615_InitialCreate")] + [Migration("20190130214707_InitialCreate")] partial class InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -23,31 +23,37 @@ namespace Tv7Playlist.Data.Migrations b.Property("Id") .ValueGeneratedOnAdd(); + b.Property("ChannelNumberExport"); + + b.Property("ChannelNumberImport"); + + b.Property("Created"); + + b.Property("EpgMatchName"); + b.Property("IsAvailable"); b.Property("IsEnabled"); - b.Property("Name"); + b.Property("LogoUrl"); - b.Property("NameOverride"); + b.Property("Modified"); + + b.Property("Name"); b.Property("Position"); - b.Property("TrackNumber"); - - b.Property("TrackNumberOverride"); - - b.Property("Url"); - b.Property("UrlOriginal"); + b.Property("UrlProxy"); + b.HasKey("Id"); - b.HasIndex("Name"); - - b.HasIndex("TrackNumber") + b.HasIndex("ChannelNumberImport") .IsUnique(); + b.HasIndex("Name"); + b.ToTable("PlaylistEntries"); }); #pragma warning restore 612, 618 diff --git a/Tv7Playlist.Data/Migrations/20190125212615_InitialCreate.cs b/Tv7Playlist.Data/Migrations/20190130214707_InitialCreate.cs similarity index 70% rename from Tv7Playlist.Data/Migrations/20190125212615_InitialCreate.cs rename to Tv7Playlist.Data/Migrations/20190130214707_InitialCreate.cs index f93ba7f..0e9c160 100644 --- a/Tv7Playlist.Data/Migrations/20190125212615_InitialCreate.cs +++ b/Tv7Playlist.Data/Migrations/20190130214707_InitialCreate.cs @@ -13,30 +13,33 @@ namespace Tv7Playlist.Data.Migrations { Id = table.Column(nullable: false), Position = table.Column(nullable: false), - TrackNumber = table.Column(nullable: false), - TrackNumberOverride = table.Column(nullable: false), + ChannelNumberImport = table.Column(nullable: false), + ChannelNumberExport = table.Column(nullable: false), Name = table.Column(nullable: true), - NameOverride = table.Column(nullable: true), - Url = table.Column(nullable: true), + EpgMatchName = table.Column(nullable: true), + UrlProxy = table.Column(nullable: true), UrlOriginal = table.Column(nullable: true), + LogoUrl = table.Column(nullable: true), IsAvailable = table.Column(nullable: false), - IsEnabled = table.Column(nullable: false) + IsEnabled = table.Column(nullable: false), + Created = table.Column(nullable: false), + Modified = table.Column(nullable: false) }, constraints: table => { table.PrimaryKey("PK_PlaylistEntries", x => x.Id); }); + migrationBuilder.CreateIndex( + name: "IX_PlaylistEntries_ChannelNumberImport", + table: "PlaylistEntries", + column: "ChannelNumberImport", + unique: true); + migrationBuilder.CreateIndex( name: "IX_PlaylistEntries_Name", table: "PlaylistEntries", column: "Name"); - - migrationBuilder.CreateIndex( - name: "IX_PlaylistEntries_TrackNumber", - table: "PlaylistEntries", - column: "TrackNumber", - unique: true); } protected override void Down(MigrationBuilder migrationBuilder) diff --git a/Tv7Playlist.Data/Migrations/PlaylistContextModelSnapshot.cs b/Tv7Playlist.Data/Migrations/PlaylistContextModelSnapshot.cs index edcc5af..c708c93 100644 --- a/Tv7Playlist.Data/Migrations/PlaylistContextModelSnapshot.cs +++ b/Tv7Playlist.Data/Migrations/PlaylistContextModelSnapshot.cs @@ -21,31 +21,37 @@ namespace Tv7Playlist.Data.Migrations b.Property("Id") .ValueGeneratedOnAdd(); + b.Property("ChannelNumberExport"); + + b.Property("ChannelNumberImport"); + + b.Property("Created"); + + b.Property("EpgMatchName"); + b.Property("IsAvailable"); b.Property("IsEnabled"); - b.Property("Name"); + b.Property("LogoUrl"); - b.Property("NameOverride"); + b.Property("Modified"); + + b.Property("Name"); b.Property("Position"); - b.Property("TrackNumber"); - - b.Property("TrackNumberOverride"); - - b.Property("Url"); - b.Property("UrlOriginal"); + b.Property("UrlProxy"); + b.HasKey("Id"); - b.HasIndex("Name"); - - b.HasIndex("TrackNumber") + b.HasIndex("ChannelNumberImport") .IsUnique(); + b.HasIndex("Name"); + b.ToTable("PlaylistEntries"); }); #pragma warning restore 612, 618 diff --git a/Tv7Playlist.Data/PlaylistContext.cs b/Tv7Playlist.Data/PlaylistContext.cs index 416fd27..22013e9 100644 --- a/Tv7Playlist.Data/PlaylistContext.cs +++ b/Tv7Playlist.Data/PlaylistContext.cs @@ -17,7 +17,7 @@ namespace Tv7Playlist.Data var entityTypeBuilder = modelBuilder.Entity(); entityTypeBuilder.HasKey(e => e.Id); - entityTypeBuilder.HasIndex(e => e.TrackNumber).IsUnique(); + entityTypeBuilder.HasIndex(e => e.ChannelNumberImport).IsUnique(); entityTypeBuilder.HasIndex(e => e.Name); } } diff --git a/Tv7Playlist.Data/PlaylistEntry.cs b/Tv7Playlist.Data/PlaylistEntry.cs index cf3ce20..05fd533 100644 --- a/Tv7Playlist.Data/PlaylistEntry.cs +++ b/Tv7Playlist.Data/PlaylistEntry.cs @@ -8,20 +8,26 @@ namespace Tv7Playlist.Data public int Position { get; set; } - public int TrackNumber { get; set; } + public int ChannelNumberImport { get; set; } - public int TrackNumberOverride { get; set; } + public int ChannelNumberExport { get; set; } public string Name { get; set; } - public string NameOverride { get; set; } + public string EpgMatchName { get; set; } + + public string UrlProxy { get; set; } - public string Url { get; set; } - public string UrlOriginal { get; set; } + public string LogoUrl { get; set; } + public bool IsAvailable { get; set; } public bool IsEnabled { get; set; } + + public DateTime Created { get; set; } + + public DateTime Modified { get; set; } } } \ No newline at end of file diff --git a/Tv7Playlist/Controllers/HomeController.cs b/Tv7Playlist/Controllers/HomeController.cs index c05013c..0b3de43 100644 --- a/Tv7Playlist/Controllers/HomeController.cs +++ b/Tv7Playlist/Controllers/HomeController.cs @@ -26,7 +26,7 @@ namespace Tv7Playlist.Controllers [HttpGet] public async Task Index() { - var playlistEntries = await _playlistContext.PlaylistEntries.AsNoTracking().OrderBy(e => e.TrackNumber).ToListAsync(); + var playlistEntries = await _playlistContext.PlaylistEntries.AsNoTracking().OrderBy(e => e.Position).ToListAsync(); var model = new HomeModel(playlistEntries); return View(model); diff --git a/Tv7Playlist/Controllers/PlaylistApiController.cs b/Tv7Playlist/Controllers/PlaylistApiController.cs index b979b08..c8ad960 100644 --- a/Tv7Playlist/Controllers/PlaylistApiController.cs +++ b/Tv7Playlist/Controllers/PlaylistApiController.cs @@ -25,11 +25,30 @@ namespace Tv7Playlist.Controllers _appConfig = appConfig ?? throw new ArgumentNullException(nameof(appConfig)); } + [HttpGet] + [Route("without-proxy")] + public async Task GetPlaylistWithoutProxy() + { + return await GetPlaylistInternal(false); + } + [HttpGet] [Route("")] public async Task GetPlaylist() { - var playlistStream = await _playlistBuilder.GeneratePlaylistAsync(); + return await GetPlaylistInternal(true); + } + + [HttpGet] + [Route("with-proxy")] + public async Task GetPlaylistWithProxy() + { + return await GetPlaylistInternal(true); + } + + private async Task GetPlaylistInternal(bool useProxy) + { + var playlistStream = await _playlistBuilder.GeneratePlaylistAsync(useProxy); var downloadFileName = GetDownloadFileName(); _logger.LogInformation(LoggingEvents.Playlist, "Sending updated playlist {filename}", diff --git a/Tv7Playlist/Controllers/PlaylistEntryController.cs b/Tv7Playlist/Controllers/PlaylistEntryController.cs index 9d0b481..429b088 100644 --- a/Tv7Playlist/Controllers/PlaylistEntryController.cs +++ b/Tv7Playlist/Controllers/PlaylistEntryController.cs @@ -43,9 +43,11 @@ namespace Tv7Playlist.Controllers if (entry == null) return NotFound(); entry.Position = updatedEntry.Position; - entry.TrackNumberOverride = updatedEntry.TrackNumberOverride; - entry.NameOverride = updatedEntry.NameOverride; + entry.ChannelNumberExport = updatedEntry.ChannelNumberExport; + entry.EpgMatchName = updatedEntry.EpgMatchName; entry.IsEnabled = updatedEntry.IsEnabled; + entry.LogoUrl = updatedEntry.LogoUrl; + entry.Modified = DateTime.Now; await _playlistContext.SaveChangesAsync(); diff --git a/Tv7Playlist/Views/Home/Index.cshtml b/Tv7Playlist/Views/Home/Index.cshtml index d28ea62..2a0e058 100644 --- a/Tv7Playlist/Views/Home/Index.cshtml +++ b/Tv7Playlist/Views/Home/Index.cshtml @@ -8,15 +8,17 @@ - - + + - + - - + + + + @{ @@ -24,15 +26,17 @@ { - - + + - + - + + + } } diff --git a/Tv7Playlist/Views/PlaylistEntry/Edit.cshtml b/Tv7Playlist/Views/PlaylistEntry/Edit.cshtml index a624659..65a0bfd 100644 --- a/Tv7Playlist/Views/PlaylistEntry/Edit.cshtml +++ b/Tv7Playlist/Views/PlaylistEntry/Edit.cshtml @@ -1,17 +1,16 @@ @model Tv7Playlist.Data.PlaylistEntry; @{ - ViewData["Title"] = $"Edit channel {Model.TrackNumber} - {Model.Name}"; + ViewData["Title"] = $"Edit channel {Model.ChannelNumberExport} - {Model.Name}"; }
-

Edit channel @Model.TrackNumber - @Model.Name

+

Edit channel @Model.ChannelNumberExport - @Model.Name


- @@ -54,25 +53,37 @@
- +
- +
- +
- +
- +
- + +
+
+ +
+
+ +
+
+ +
+
+
diff --git a/Tv7Playlist/Views/Shared/_Layout.cshtml b/Tv7Playlist/Views/Shared/_Layout.cshtml index eef96a0..1dbddde 100644 --- a/Tv7Playlist/Views/Shared/_Layout.cshtml +++ b/Tv7Playlist/Views/Shared/_Layout.cshtml @@ -32,7 +32,10 @@ Synchronize playlist +
NumberNumber overrideNumber ImportNumber Export Position NameName overrideEPG Name Enabled AvailableURLoriginal URLURL ProxyURL OriginalCreatedModified
Edit@track.TrackNumber@(track.TrackNumberOverride==0?string.Empty:track.TrackNumberOverride.ToString())@track.ChannelNumberImport@track.ChannelNumberExport @track.Position @track.Name@track.NameOverride@track.EpgMatchName @track.IsEnabled @track.IsAvailable@track.Url@track.UrlProxy @track.UrlOriginal@track.Created.ToString("g")@track.Modified.ToString("g")