creating player watcher on register, adding live gif
This commit is contained in:
parent
b19337bf20
commit
a3628182c9
@ -2,4 +2,6 @@
|
|||||||
|
|
||||||
![ci](https://github.com/sarsoo/Selector/actions/workflows/ci.yml/badge.svg)
|
![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.
|
@ -16,6 +16,8 @@ namespace Selector.Cache
|
|||||||
public const string PlayCountName = "PlayCount";
|
public const string PlayCountName = "PlayCount";
|
||||||
|
|
||||||
public const string WorkerName = "Worker";
|
public const string WorkerName = "Worker";
|
||||||
|
public const string WatcherName = "Watcher";
|
||||||
|
public const string ReservedName = "Reserved";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current playback for a user
|
/// 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 AlbumPlayCount(string name, string artist) => Namespace(AlbumName, artist, name, PlayCountName);
|
||||||
public static string ArtistPlayCount(string name) => Namespace(ArtistName, 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);
|
public static string Namespace(params string[] args) => string.Join(":", args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,31 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Design;
|
using Microsoft.EntityFrameworkCore.Design;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
|
|
||||||
namespace Selector.Model
|
namespace Selector.Model
|
||||||
{
|
{
|
||||||
|
|
||||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
|
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
|
||||||
{
|
{
|
||||||
|
private readonly ILogger<ApplicationDbContext> Logger;
|
||||||
|
|
||||||
public DbSet<Watcher> Watcher { get; set; }
|
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)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
@ -35,6 +44,22 @@ namespace Selector.Model
|
|||||||
|
|
||||||
SeedData.Seed(modelBuilder);
|
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>
|
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
|
||||||
@ -49,7 +74,7 @@ namespace Selector.Model
|
|||||||
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||||
builder.UseNpgsql(configuration.GetConnectionString("Default"));
|
builder.UseNpgsql(configuration.GetConnectionString("Default"));
|
||||||
|
|
||||||
return new ApplicationDbContext(builder.Options);
|
return new ApplicationDbContext(builder.Options, NullLogger<ApplicationDbContext>.Instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,17 +23,20 @@ namespace Selector.Web.Areas.Identity.Pages.Account
|
|||||||
{
|
{
|
||||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||||
private readonly UserManager<ApplicationUser> _userManager;
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
|
private readonly ApplicationDbContext DbContext;
|
||||||
private readonly ILogger<RegisterModel> _logger;
|
private readonly ILogger<RegisterModel> _logger;
|
||||||
private readonly IEmailSender _emailSender;
|
private readonly IEmailSender _emailSender;
|
||||||
|
|
||||||
public RegisterModel(
|
public RegisterModel(
|
||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
SignInManager<ApplicationUser> signInManager,
|
SignInManager<ApplicationUser> signInManager,
|
||||||
|
ApplicationDbContext dbContext,
|
||||||
ILogger<RegisterModel> logger,
|
ILogger<RegisterModel> logger,
|
||||||
IEmailSender emailSender)
|
IEmailSender emailSender)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_signInManager = signInManager;
|
_signInManager = signInManager;
|
||||||
|
DbContext = dbContext;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_emailSender = emailSender;
|
_emailSender = emailSender;
|
||||||
}
|
}
|
||||||
@ -84,6 +87,8 @@ namespace Selector.Web.Areas.Identity.Pages.Account
|
|||||||
var result = await _userManager.CreateAsync(user, Input.Password);
|
var result = await _userManager.CreateAsync(user, Input.Password);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
|
DbContext.CreatePlayerWatcher(user.Id);
|
||||||
|
|
||||||
_logger.LogInformation("User created a new account with password.");
|
_logger.LogInformation("User created a new account with password.");
|
||||||
|
|
||||||
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||||
|
@ -24,7 +24,10 @@ let component: Vue.Component = {
|
|||||||
<span>{{ artist.name }}</span>
|
<span>{{ artist.name }}</span>
|
||||||
</template>
|
</template>
|
||||||
</h6>
|
</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>
|
||||||
|
|
||||||
<div class="card now-playing-card" v-else-if="IsEpisodePlaying">
|
<div class="card now-playing-card" v-else-if="IsEpisodePlaying">
|
||||||
@ -36,7 +39,10 @@ let component: Vue.Component = {
|
|||||||
<h6>
|
<h6>
|
||||||
{{ episode.show.publisher }}
|
{{ episode.show.publisher }}
|
||||||
</h6>
|
</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>
|
||||||
|
|
||||||
<div class="card now-playing-card" v-else>
|
<div class="card now-playing-card" v-else>
|
||||||
|
BIN
Selector.Web/wwwroot/live.gif
Normal file
BIN
Selector.Web/wwwroot/live.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
Loading…
Reference in New Issue
Block a user