creating player watcher on register, adding live gif

This commit is contained in:
andy 2021-11-10 09:15:39 +00:00
parent b19337bf20
commit a3628182c9
6 changed files with 48 additions and 6 deletions

View File

@ -2,4 +2,6 @@
![ci](https://github.com/sarsoo/Selector/actions/workflows/ci.yml/badge.svg)
Investigating a Spotify listening agent
Selector is a suite for monitoring and reacting to live changes on a Spotify account. The player watcher keeps an eye on what you're listening to and fires off events when things change. The idea is that various pieces of information will be collated and presented in a now-playing-style dashboard.
Last.fm play counts will be collected, as will the Spotify audio features.

View File

@ -16,6 +16,8 @@ namespace Selector.Cache
public const string PlayCountName = "PlayCount";
public const string WorkerName = "Worker";
public const string WatcherName = "Watcher";
public const string ReservedName = "Reserved";
/// <summary>
/// Current playback for a user
@ -29,6 +31,8 @@ namespace Selector.Cache
public static string AlbumPlayCount(string name, string artist) => Namespace(AlbumName, artist, name, PlayCountName);
public static string ArtistPlayCount(string name) => Namespace(ArtistName, name, PlayCountName);
public static string WatcherReserved(int id) => Namespace(WatcherName, id.ToString(), ReservedName);
public static string Namespace(params string[] args) => string.Join(":", args);
}
}

View File

@ -1,22 +1,31 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Selector.Model
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly ILogger<ApplicationDbContext> Logger;
public DbSet<Watcher> Watcher { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
public ApplicationDbContext(
DbContextOptions<ApplicationDbContext> options,
ILogger<ApplicationDbContext> logger
) : base(options)
{
Logger = logger;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
@ -35,6 +44,22 @@ namespace Selector.Model
SeedData.Seed(modelBuilder);
}
public void CreatePlayerWatcher(string userId)
{
if(Watcher.Any(w => w.UserId == userId && w.Type == WatcherType.Player))
{
Logger.LogWarning($"Trying to create more than one player watcher for user [{userId}]");
return;
}
Watcher.Add(new Watcher {
UserId = userId,
Type = WatcherType.Player
});
SaveChanges();
}
}
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
@ -49,7 +74,7 @@ namespace Selector.Model
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
builder.UseNpgsql(configuration.GetConnectionString("Default"));
return new ApplicationDbContext(builder.Options);
return new ApplicationDbContext(builder.Options, NullLogger<ApplicationDbContext>.Instance);
}
}
}

View File

@ -23,17 +23,20 @@ namespace Selector.Web.Areas.Identity.Pages.Account
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ApplicationDbContext DbContext;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;
public RegisterModel(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ApplicationDbContext dbContext,
ILogger<RegisterModel> logger,
IEmailSender emailSender)
{
_userManager = userManager;
_signInManager = signInManager;
DbContext = dbContext;
_logger = logger;
_emailSender = emailSender;
}
@ -84,6 +87,8 @@ namespace Selector.Web.Areas.Identity.Pages.Account
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
DbContext.CreatePlayerWatcher(user.Id);
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);

View File

@ -24,7 +24,10 @@ let component: Vue.Component = {
<span>{{ artist.name }}</span>
</template>
</h6>
<spotify-logo :link="track.externalUrls.spotify" />
<div style="width: 100%">
<spotify-logo :link="track.externalUrls.spotify" style="float: left" />
<img src="/live.gif" style="height: 20px; float: right">
</div>
</div>
<div class="card now-playing-card" v-else-if="IsEpisodePlaying">
@ -36,7 +39,10 @@ let component: Vue.Component = {
<h6>
{{ episode.show.publisher }}
</h6>
<spotify-logo :link="episode.externalUrls.spotify" />
<div style="width: 100%">
<spotify-logo :link="episode.externalUrls.spotify" style="float: left" />
<img src="/live.gif" style="height: 20px; float: right">
</div>
</div>
<div class="card now-playing-card" v-else>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB