audio feature pushing to web frontend working
This commit is contained in:
parent
a3628182c9
commit
b75920867b
@ -6,7 +6,6 @@
|
||||
"Watcher": {
|
||||
"Instances": [
|
||||
{
|
||||
"name": "Player Watcher",
|
||||
"type": "player",
|
||||
"lastfmusername": "sarsoo",
|
||||
"pollperiod": 2000,
|
||||
|
@ -20,14 +20,25 @@ namespace Selector.Cache
|
||||
Cache = cache;
|
||||
}
|
||||
|
||||
public async Task<TrackAudioFeatures> Get(string userId, string trackId)
|
||||
public async Task<TrackAudioFeatures> Get(string refreshToken, string trackId)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(trackId)) throw new ArgumentNullException("No track Id provided");
|
||||
|
||||
var track = await Cache.StringGetAsync(Key.AudioFeature(trackId));
|
||||
if (track == RedisValue.Null)
|
||||
{
|
||||
// TODO: finish implementing network pull
|
||||
// return await SpotifyClient.GetAudioFeatures(trackId);
|
||||
throw new NotImplementedException("Can't pull over network yet");
|
||||
if(!string.IsNullOrWhiteSpace(refreshToken))
|
||||
{
|
||||
var factory = await SpotifyFactory.GetFactory(refreshToken);
|
||||
var spotifyClient = new SpotifyClient(await factory.GetConfig());
|
||||
|
||||
// TODO: Error checking
|
||||
return await spotifyClient.Tracks.GetAudioFeatures(trackId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4,7 +4,6 @@ using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
using SpotifyAPI.Web;
|
||||
using StackExchange.Redis;
|
||||
@ -36,7 +35,7 @@ namespace Selector.Cache
|
||||
|
||||
public async Task AsyncCacheCallback(AnalysedTrack e)
|
||||
{
|
||||
var payload = JsonSerializer.Serialize(e);
|
||||
var payload = JsonSerializer.Serialize(e.Features);
|
||||
|
||||
Logger.LogTrace($"Caching current for [{e.Track.DisplayString()}]");
|
||||
|
||||
|
@ -1,29 +1,36 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using System.Data.SqlTypes;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using SpotifyAPI.Web;
|
||||
using StackExchange.Redis;
|
||||
|
||||
using Selector.Cache;
|
||||
using System.Text.Json;
|
||||
using Selector.Model;
|
||||
|
||||
namespace Selector.Web.Hubs
|
||||
{
|
||||
public interface INowPlayingHubClient
|
||||
{
|
||||
public Task OnNewPlaying(CurrentlyPlayingDTO context);
|
||||
// public Task OnNewAudioFeature(TrackAudioFeatures features);
|
||||
public Task OnNewAudioFeature(TrackAudioFeatures features);
|
||||
}
|
||||
|
||||
public class NowPlayingHub: Hub<INowPlayingHubClient>
|
||||
{
|
||||
private readonly IDatabaseAsync Cache;
|
||||
// private readonly AudioFeaturePuller AudioFeaturePuller;
|
||||
private readonly AudioFeaturePuller AudioFeaturePuller;
|
||||
private readonly ApplicationDbContext Db;
|
||||
|
||||
public NowPlayingHub(IDatabaseAsync cache)
|
||||
public NowPlayingHub(IDatabaseAsync cache, AudioFeaturePuller puller, ApplicationDbContext db)
|
||||
{
|
||||
Cache = cache;
|
||||
AudioFeaturePuller = puller;
|
||||
Db = db;
|
||||
}
|
||||
|
||||
public async Task OnConnected()
|
||||
@ -34,13 +41,33 @@ namespace Selector.Web.Hubs
|
||||
public async Task SendNewPlaying()
|
||||
{
|
||||
var nowPlaying = await Cache.StringGetAsync(Key.CurrentlyPlaying(Context.UserIdentifier));
|
||||
if (nowPlaying != RedisValue.Null)
|
||||
{
|
||||
var deserialised = JsonSerializer.Deserialize<CurrentlyPlayingDTO>(nowPlaying);
|
||||
await Clients.Caller.OnNewPlaying(deserialised);
|
||||
}
|
||||
}
|
||||
|
||||
// public async Task SendAudioFeatures(string trackId)
|
||||
// {
|
||||
// await Clients.Caller.OnNewAudioFeature(await AudioFeaturePuller.Get(trackId));
|
||||
// }
|
||||
public async Task SendAudioFeatures(string trackId)
|
||||
{
|
||||
var user = Db.Users
|
||||
.AsNoTracking()
|
||||
.Where(u => u.Id == Context.UserIdentifier)
|
||||
.SingleOrDefault()
|
||||
?? throw new SqlNullValueException("No user returned");
|
||||
var watcher = Db.Watcher
|
||||
.AsNoTracking()
|
||||
.Where(w => w.UserId == Context.UserIdentifier
|
||||
&& w.Type == WatcherType.Player)
|
||||
.SingleOrDefault()
|
||||
?? throw new SqlNullValueException($"No player watcher found for [{user.UserName}]");
|
||||
|
||||
var feature = await AudioFeaturePuller.Get(user.SpotifyRefreshToken, trackId);
|
||||
|
||||
if (feature is not null)
|
||||
{
|
||||
await Clients.Caller.OnNewAudioFeature(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
47
Selector.Web/Services/SpotifyInitialiser.cs
Normal file
47
Selector.Web/Services/SpotifyInitialiser.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Selector.Web.Service {
|
||||
public class SpotifyInitialiser : IHostedService
|
||||
{
|
||||
private readonly ILogger<SpotifyInitialiser> Logger;
|
||||
private readonly IRefreshTokenFactoryProvider FactoryProvider;
|
||||
private readonly RootOptions Config;
|
||||
|
||||
public SpotifyInitialiser(
|
||||
ILogger<SpotifyInitialiser> logger,
|
||||
IRefreshTokenFactoryProvider factoryProvider,
|
||||
IOptions<RootOptions> config
|
||||
)
|
||||
{
|
||||
Logger = logger;
|
||||
FactoryProvider = factoryProvider;
|
||||
Config = config.Value;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Logger.LogInformation("Initialising Spotify Factory");
|
||||
|
||||
if(string.IsNullOrEmpty(Config.ClientId) || string.IsNullOrEmpty(Config.ClientSecret))
|
||||
{
|
||||
Logger.LogError("Unable to initialise Spotify factory, null client id or secret");
|
||||
}
|
||||
else
|
||||
{
|
||||
FactoryProvider.Initialise(Config.ClientId, Config.ClientSecret);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ namespace Selector.Web
|
||||
|
||||
services.AddRazorPages().AddRazorRuntimeCompilation();
|
||||
services.AddControllers();
|
||||
services.AddSignalR();
|
||||
services.AddSignalR(o => o.EnableDetailedErrors = true);
|
||||
|
||||
services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseNpgsql(Configuration.GetConnectionString("Default"))
|
||||
@ -117,7 +117,9 @@ namespace Selector.Web
|
||||
services.AddTransient<ISubscriber>(services => services.GetService<ConnectionMultiplexer>().GetSubscriber());
|
||||
}
|
||||
|
||||
services.AddHostedService<SpotifyInitialiser>();
|
||||
services.AddSingleton<IRefreshTokenFactoryProvider, CachingRefreshTokenFactoryProvider>();
|
||||
services.AddSingleton<AudioFeaturePuller>();
|
||||
|
||||
services.AddSingleton<CacheHubProxy>();
|
||||
services.AddHostedService<CacheHubProxyService>();
|
||||
|
@ -40,17 +40,17 @@ const app = Vue.createApp({
|
||||
this.currentlyPlaying = context;
|
||||
this.cards = [];
|
||||
|
||||
// if(context.track !== null && context.track !== undefined)
|
||||
// {
|
||||
// connection.invoke("SendAudioFeatures", context.track.id);
|
||||
// }
|
||||
if(context.track !== null && context.track !== undefined)
|
||||
{
|
||||
connection.invoke("SendAudioFeatures", context.track.id);
|
||||
}
|
||||
});
|
||||
|
||||
// connection.on("OnNewAudioFeature", (feature: TrackAudioFeatures) =>
|
||||
// {
|
||||
// console.log(feature);
|
||||
// this.trackFeatures = feature;
|
||||
// });
|
||||
connection.on("OnNewAudioFeature", (feature: TrackAudioFeatures) =>
|
||||
{
|
||||
console.log(feature);
|
||||
this.trackFeatures = feature;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user