added watcherfactory, theoretically working watcher service
This commit is contained in:
parent
1694f8e3a9
commit
b5956ef4a0
@ -41,6 +41,7 @@ namespace Selector.CLI
|
||||
public WatcherType Type { get; set; } = WatcherType.Player;
|
||||
#nullable enable
|
||||
public string? PlaylistUri { get; set; }
|
||||
public string? WatcherCollection { get; set; }
|
||||
#nullable disable
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,9 @@ namespace Selector.CLI
|
||||
});
|
||||
|
||||
// SERVICES
|
||||
//services.AddTransient<IWatcherFactory, PlayerWatcher>();
|
||||
//services.AddTransient<IWatcherCollection, WatcherCollection>();
|
||||
services.AddSingleton<IWatcherFactory, WatcherFactory>();
|
||||
services.AddSingleton<IWatcherCollectionFactory, WatcherCollectionFactory>();
|
||||
// For generating spotify clients
|
||||
services.AddSingleton<IRefreshTokenFactoryProvider, RefreshTokenFactoryProvider>();
|
||||
|
||||
switch(context.Configuration.GetValue<EqualityChecker>("selector:equality"))
|
||||
|
10
Selector.CLI/Properties/launchSettings.json
Normal file
10
Selector.CLI/Properties/launchSettings.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Selector.CLI": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"DOTNET_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.Development.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@ -13,28 +14,103 @@ namespace Selector.CLI
|
||||
{
|
||||
class WatcherService : IHostedService
|
||||
{
|
||||
private const string ConfigInstanceKey = "localconfig";
|
||||
|
||||
private readonly ILogger<WatcherService> Logger;
|
||||
private readonly RootOptions Config;
|
||||
private readonly IRefreshTokenFactoryProvider TokenFactoryProvider;
|
||||
private readonly IWatcherFactory WatcherFactory;
|
||||
private readonly IWatcherCollectionFactory WatcherCollectionFactory;
|
||||
private readonly IRefreshTokenFactoryProvider SpotifyFactory;
|
||||
|
||||
private Dictionary<string, IWatcherCollection> Watchers { get; set; } = new();
|
||||
|
||||
public WatcherService(IRefreshTokenFactoryProvider tokenFactoryProvider, ILogger<WatcherService> logger, IOptions<RootOptions> config)
|
||||
{
|
||||
public WatcherService(
|
||||
IWatcherFactory watcherFactory,
|
||||
IWatcherCollectionFactory watcherCollectionFactory,
|
||||
IRefreshTokenFactoryProvider spotifyFactory,
|
||||
ILogger<WatcherService> logger,
|
||||
IOptions<RootOptions> config
|
||||
) {
|
||||
Logger = logger;
|
||||
Config = config.Value;
|
||||
TokenFactoryProvider = tokenFactoryProvider;
|
||||
WatcherFactory = watcherFactory;
|
||||
WatcherCollectionFactory = watcherCollectionFactory;
|
||||
SpotifyFactory = spotifyFactory;
|
||||
|
||||
TokenFactoryProvider.Initialise(Config.ClientId, Config.ClientSecret);
|
||||
SpotifyFactory.Initialise(Config.ClientId, Config.ClientSecret);
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Logger.LogInformation("Starting up");
|
||||
|
||||
Config.WatcherOptions.Instances.ForEach(i => Logger.LogInformation($"Config: {i.Type}"));
|
||||
Logger.LogInformation("Loading config instances...");
|
||||
var watcherIndices = await InitialiseConfigInstances();
|
||||
|
||||
return Task.CompletedTask;
|
||||
Logger.LogInformation($"Starting {watcherIndices.Count()} affected watcher collection(s)...");
|
||||
StartWatcherCollections(watcherIndices);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<string>> InitialiseConfigInstances()
|
||||
{
|
||||
var indices = new HashSet<string>();
|
||||
|
||||
foreach (var watcherOption in Config.WatcherOptions.Instances)
|
||||
{
|
||||
var logMsg = new StringBuilder();
|
||||
if (!string.IsNullOrWhiteSpace(watcherOption.Name))
|
||||
{
|
||||
logMsg.Append($"Creating {watcherOption.Name} watcher [{watcherOption.Type}]");
|
||||
}
|
||||
else
|
||||
{
|
||||
logMsg.Append($"Creating new {watcherOption.Type} watcher");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(watcherOption.PlaylistUri)) logMsg.Append($" [{ watcherOption.PlaylistUri}]");
|
||||
Logger.LogInformation(logMsg.ToString());
|
||||
|
||||
var watcherCollectionIdx = watcherOption.WatcherCollection ?? ConfigInstanceKey;
|
||||
indices.Add(watcherCollectionIdx);
|
||||
|
||||
if (!Watchers.ContainsKey(watcherCollectionIdx))
|
||||
Watchers[watcherCollectionIdx] = WatcherCollectionFactory.Get();
|
||||
|
||||
var watcherCollection = Watchers[watcherCollectionIdx];
|
||||
|
||||
Logger.LogDebug("Getting Spotify factory");
|
||||
var spotifyFactory = await SpotifyFactory.GetFactory(watcherOption.RefreshKey);
|
||||
|
||||
IWatcher watcher = null;
|
||||
switch(watcherOption.Type)
|
||||
{
|
||||
case WatcherType.Player:
|
||||
watcher = await WatcherFactory.Get<PlayerWatcher>(spotifyFactory, watcherOption.PollPeriod);
|
||||
break;
|
||||
case WatcherType.Playlist:
|
||||
throw new NotImplementedException("Playlist watchers not implemented");
|
||||
break;
|
||||
}
|
||||
|
||||
watcherCollection.Add(watcher);
|
||||
}
|
||||
|
||||
return indices;
|
||||
}
|
||||
|
||||
private void StartWatcherCollections(IEnumerable<string> indices)
|
||||
{
|
||||
foreach (var index in indices)
|
||||
{
|
||||
try
|
||||
{
|
||||
Watchers[index].Start();
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
Logger.LogError($"Unable to retrieve watcher collection [{index}] when starting");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
|
@ -6,12 +6,9 @@
|
||||
"Watcher": {
|
||||
"Instances": [
|
||||
{
|
||||
"name": "sarsoo",
|
||||
"type": "player"
|
||||
},
|
||||
{
|
||||
"name": "andy",
|
||||
"type": "playlist"
|
||||
"name": "player watcher",
|
||||
"type": "player",
|
||||
"pollperiod": 1000
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace Selector
|
||||
ClientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public bool Initialised => string.IsNullOrWhiteSpace(ClientId) || string.IsNullOrWhiteSpace(ClientSecret);
|
||||
public bool Initialised => !string.IsNullOrWhiteSpace(ClientId) && !string.IsNullOrWhiteSpace(ClientSecret);
|
||||
|
||||
public Task<RefreshTokenFactory> GetFactory(string refreshToken)
|
||||
{
|
||||
|
@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
public interface IWatcherFactory
|
||||
{
|
||||
public IWatcher Create();
|
||||
public Task<IWatcher> Get<T>(ISpotifyConfigFactory spotifyFactory, int pollPeriod)
|
||||
where T : class, IWatcher;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
namespace Selector
|
||||
{
|
||||
public interface IWatcherCollectionFactory
|
||||
{
|
||||
public IWatcherCollection Get();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
public class WatcherCollectionFactory: IWatcherCollectionFactory
|
||||
{
|
||||
private readonly ILoggerFactory LoggerFactory;
|
||||
|
||||
public WatcherCollectionFactory(ILoggerFactory loggerFactory)
|
||||
{
|
||||
LoggerFactory = loggerFactory;
|
||||
}
|
||||
|
||||
public IWatcherCollection Get()
|
||||
{
|
||||
return new WatcherCollection(LoggerFactory.CreateLogger<WatcherCollection>());
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,10 @@ namespace Selector
|
||||
IsRunning = true;
|
||||
TokenSource = new();
|
||||
Task = Watcher.Watch(TokenSource.Token);
|
||||
Task.ContinueWith(t =>
|
||||
{
|
||||
if (t.Exception != null) throw t.Exception;
|
||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
|
@ -1,14 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using SpotifyAPI.Web;
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
//class PlayerWatcherFactory : IWatcherFactory
|
||||
//{
|
||||
// public IWatcher Create()
|
||||
// {
|
||||
public class WatcherFactory : IWatcherFactory {
|
||||
|
||||
private readonly ILoggerFactory LoggerFactory;
|
||||
private readonly IEqual Equal;
|
||||
|
||||
public WatcherFactory(ILoggerFactory loggerFactory, IEqual equal)
|
||||
{
|
||||
LoggerFactory = loggerFactory;
|
||||
Equal = equal;
|
||||
}
|
||||
|
||||
public async Task<IWatcher> Get<T>(ISpotifyConfigFactory spotifyFactory, int pollPeriod = 3000)
|
||||
where T : class, IWatcher
|
||||
{
|
||||
if(typeof(T).IsAssignableFrom(typeof(PlayerWatcher)))
|
||||
{
|
||||
var config = await spotifyFactory.GetConfig();
|
||||
var client = new SpotifyClient(config);
|
||||
|
||||
return new PlayerWatcher(
|
||||
client.Player,
|
||||
Equal,
|
||||
LoggerFactory?.CreateLogger<PlayerWatcher>(),
|
||||
pollPeriod: pollPeriod
|
||||
);
|
||||
}
|
||||
//else if (typeof(T).IsAssignableFrom(typeof(PlaylistWatcher)))
|
||||
//{
|
||||
|
||||
// }
|
||||
//}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Type unsupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user