diff --git a/Tv7Playlist.Data/Migrations/20190124221302_AddedEnabledAvailableNameOverride.Designer.cs b/Tv7Playlist.Data/Migrations/20190124221302_AddedEnabledAvailableNameOverride.Designer.cs
new file mode 100644
index 0000000..220e9b1
--- /dev/null
+++ b/Tv7Playlist.Data/Migrations/20190124221302_AddedEnabledAvailableNameOverride.Designer.cs
@@ -0,0 +1,50 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Tv7Playlist.Data;
+
+namespace Tv7Playlist.Data.Migrations
+{
+ [DbContext(typeof(PlaylistContext))]
+ [Migration("20190124221302_AddedEnabledAvailableNameOverride")]
+ partial class AddedEnabledAvailableNameOverride
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "2.2.0-rtm-35687");
+
+ modelBuilder.Entity("Tv7Playlist.Data.PlaylistEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("IsAvailable");
+
+ b.Property("IsEnabled");
+
+ b.Property("Name");
+
+ b.Property("NameOverride");
+
+ b.Property("TrackNumber");
+
+ b.Property("Url");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name");
+
+ b.HasIndex("TrackNumber")
+ .IsUnique();
+
+ b.ToTable("PlaylistEntries");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Tv7Playlist.Data/Migrations/20190124221302_AddedEnabledAvailableNameOverride.cs b/Tv7Playlist.Data/Migrations/20190124221302_AddedEnabledAvailableNameOverride.cs
new file mode 100644
index 0000000..f11796b
--- /dev/null
+++ b/Tv7Playlist.Data/Migrations/20190124221302_AddedEnabledAvailableNameOverride.cs
@@ -0,0 +1,70 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Tv7Playlist.Data.Migrations
+{
+ public partial class AddedEnabledAvailableNameOverride : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropUniqueConstraint(
+ name: "AK_PlaylistEntries_TrackNumber",
+ table: "PlaylistEntries");
+
+ migrationBuilder.AddColumn(
+ name: "IsAvailable",
+ table: "PlaylistEntries",
+ nullable: false,
+ defaultValue: false);
+
+ migrationBuilder.AddColumn(
+ name: "IsEnabled",
+ table: "PlaylistEntries",
+ nullable: false,
+ defaultValue: false);
+
+ migrationBuilder.AddColumn(
+ name: "NameOverride",
+ table: "PlaylistEntries",
+ nullable: 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)
+ {
+ migrationBuilder.DropIndex(
+ name: "IX_PlaylistEntries_Name",
+ table: "PlaylistEntries");
+
+ migrationBuilder.DropIndex(
+ name: "IX_PlaylistEntries_TrackNumber",
+ table: "PlaylistEntries");
+
+ migrationBuilder.DropColumn(
+ name: "IsAvailable",
+ table: "PlaylistEntries");
+
+ migrationBuilder.DropColumn(
+ name: "IsEnabled",
+ table: "PlaylistEntries");
+
+ migrationBuilder.DropColumn(
+ name: "NameOverride",
+ table: "PlaylistEntries");
+
+ migrationBuilder.AddUniqueConstraint(
+ name: "AK_PlaylistEntries_TrackNumber",
+ table: "PlaylistEntries",
+ column: "TrackNumber");
+ }
+ }
+}
diff --git a/Tv7Playlist.Data/Migrations/PlaylistContextModelSnapshot.cs b/Tv7Playlist.Data/Migrations/PlaylistContextModelSnapshot.cs
index 996c02a..d434f9a 100644
--- a/Tv7Playlist.Data/Migrations/PlaylistContextModelSnapshot.cs
+++ b/Tv7Playlist.Data/Migrations/PlaylistContextModelSnapshot.cs
@@ -21,15 +21,24 @@ namespace Tv7Playlist.Data.Migrations
b.Property("Id")
.ValueGeneratedOnAdd();
+ b.Property("IsAvailable");
+
+ b.Property("IsEnabled");
+
b.Property("Name");
+ b.Property("NameOverride");
+
b.Property("TrackNumber");
b.Property("Url");
b.HasKey("Id");
- b.HasAlternateKey("TrackNumber");
+ b.HasIndex("Name");
+
+ b.HasIndex("TrackNumber")
+ .IsUnique();
b.ToTable("PlaylistEntries");
});
diff --git a/Tv7Playlist.Data/PlaylistContext.cs b/Tv7Playlist.Data/PlaylistContext.cs
index 0921675..416fd27 100644
--- a/Tv7Playlist.Data/PlaylistContext.cs
+++ b/Tv7Playlist.Data/PlaylistContext.cs
@@ -17,7 +17,8 @@ namespace Tv7Playlist.Data
var entityTypeBuilder = modelBuilder.Entity();
entityTypeBuilder.HasKey(e => e.Id);
- entityTypeBuilder.HasAlternateKey(e => e.TrackNumber);
+ entityTypeBuilder.HasIndex(e => e.TrackNumber).IsUnique();
+ entityTypeBuilder.HasIndex(e => e.Name);
}
}
}
\ No newline at end of file
diff --git a/Tv7Playlist.Data/PlaylistEntry.cs b/Tv7Playlist.Data/PlaylistEntry.cs
index d1ba666..f6728fd 100644
--- a/Tv7Playlist.Data/PlaylistEntry.cs
+++ b/Tv7Playlist.Data/PlaylistEntry.cs
@@ -9,7 +9,13 @@ namespace Tv7Playlist.Data
public int TrackNumber { get; set; }
public string Name { get; set; }
+
+ public string NameOverride { get; set; }
public string Url { get; set; }
+
+ public bool IsAvailable { get; set; }
+
+ public bool IsEnabled { get; set; }
}
}
\ No newline at end of file
diff --git a/Tv7Playlist/Controllers/HomeController.cs b/Tv7Playlist/Controllers/HomeController.cs
index 617e533..8c6e23a 100644
--- a/Tv7Playlist/Controllers/HomeController.cs
+++ b/Tv7Playlist/Controllers/HomeController.cs
@@ -1,7 +1,6 @@
using System;
-using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
+using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
@@ -28,14 +27,14 @@ namespace Tv7Playlist.Controllers
{
var tracks = await _playlistLoader.LoadPlaylistFromUrl(_appConfig.TV7Url);
var model = new HomeModel(tracks);
-
+
return View(model);
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
- return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
+ return View(new ErrorViewModel {RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier});
}
}
}
diff --git a/Tv7Playlist/Controllers/PlayListController.cs b/Tv7Playlist/Controllers/PlayListController.cs
index dec146b..72dbfb4 100644
--- a/Tv7Playlist/Controllers/PlayListController.cs
+++ b/Tv7Playlist/Controllers/PlayListController.cs
@@ -10,7 +10,7 @@ using Tv7Playlist.Core;
namespace Tv7Playlist.Controllers
{
- [Route("api/playlist")]
+ [Route("api/playlist-old")]
[ApiController]
public class PlayListController : ControllerBase
{
diff --git a/Tv7Playlist/Controllers/PlaylistApiController.cs b/Tv7Playlist/Controllers/PlaylistApiController.cs
new file mode 100644
index 0000000..e23533a
--- /dev/null
+++ b/Tv7Playlist/Controllers/PlaylistApiController.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+using Tv7Playlist.Core;
+using Tv7Playlist.Core.Parsers;
+using Tv7Playlist.Data;
+
+namespace Tv7Playlist.Controllers
+{
+ [Route("api/playlist")]
+ [ApiController]
+ public class PlaylistApiController : Controller
+ {
+ private readonly IAppConfig _appConfig;
+ private readonly ILogger _logger;
+ private readonly PlaylistContext _playlistContext;
+ private readonly IPlaylistLoader _playlistLoader;
+
+ public PlaylistApiController(ILogger logger, PlaylistContext playlistContext,
+ IPlaylistLoader playlistLoader, IAppConfig appConfig)
+ {
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _playlistContext = playlistContext ?? throw new ArgumentNullException(nameof(playlistContext));
+ _playlistLoader = playlistLoader ?? throw new ArgumentNullException(nameof(playlistLoader));
+ _appConfig = appConfig ?? throw new ArgumentNullException(nameof(appConfig));
+ }
+
+ [HttpGet]
+ [Route("synchronize")]
+ public async Task Synchronize()
+ {
+ //TODO: Refactor to post method
+ _logger.LogDebug("Synchronizing playlist from server...");
+
+ var tracks = await _playlistLoader.LoadPlaylistFromUrl(_appConfig.TV7Url);
+ await MarkNotAvailableEntriesAsync(tracks);
+ await AddOrUpdateEntriesAsync(tracks);
+ _logger.LogDebug("Synchronizing playlist completed saving changes...");
+
+ await _playlistContext.SaveChangesAsync();
+ _logger.LogDebug("Playlist changes saved successfully...");
+
+ return Ok();
+ }
+
+ private async Task AddOrUpdateEntriesAsync(IEnumerable tracks)
+ {
+ foreach (var track in tracks)
+ {
+ var entry = await _playlistContext.PlaylistEntries.Where(e => e.TrackNumber == track.Id).FirstOrDefaultAsync();
+ if (entry == null)
+ {
+ _logger.LogInformation($"Adding playlist entry {track.Id} - {track.Name}");
+ entry = new PlaylistEntry {Id = Guid.NewGuid(), TrackNumber = track.Id, IsEnabled = true};
+ _playlistContext.PlaylistEntries.Add(entry);
+ }
+
+ entry.IsAvailable = true;
+ entry.Name = track.Name;
+ entry.Url = track.Url;
+ }
+ }
+
+ private async Task MarkNotAvailableEntriesAsync(IReadOnlyCollection tracks)
+ {
+ var unavailableEntries =
+ await _playlistContext.PlaylistEntries.Where(e => tracks.All(t => t.Id != e.TrackNumber)).ToListAsync();
+ foreach (var entry in unavailableEntries)
+ {
+ _logger.LogInformation($"Channel {entry.TrackNumber} - {entry.Name} is no longer available.");
+ entry.IsAvailable = false;
+ }
+ }
+ }
+}
\ No newline at end of file