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;
|
public WatcherType Type { get; set; } = WatcherType.Player;
|
||||||
#nullable enable
|
#nullable enable
|
||||||
public string? PlaylistUri { get; set; }
|
public string? PlaylistUri { get; set; }
|
||||||
|
public string? WatcherCollection { get; set; }
|
||||||
#nullable disable
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,9 @@ namespace Selector.CLI
|
|||||||
});
|
});
|
||||||
|
|
||||||
// SERVICES
|
// SERVICES
|
||||||
//services.AddTransient<IWatcherFactory, PlayerWatcher>();
|
services.AddSingleton<IWatcherFactory, WatcherFactory>();
|
||||||
//services.AddTransient<IWatcherCollection, WatcherCollection>();
|
services.AddSingleton<IWatcherCollectionFactory, WatcherCollectionFactory>();
|
||||||
|
// For generating spotify clients
|
||||||
services.AddSingleton<IRefreshTokenFactoryProvider, RefreshTokenFactoryProvider>();
|
services.AddSingleton<IRefreshTokenFactoryProvider, RefreshTokenFactoryProvider>();
|
||||||
|
|
||||||
switch(context.Configuration.GetValue<EqualityChecker>("selector:equality"))
|
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>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Update="appsettings.Development.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Update="appsettings.json">
|
<None Update="appsettings.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
@ -5,6 +5,7 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@ -13,28 +14,103 @@ namespace Selector.CLI
|
|||||||
{
|
{
|
||||||
class WatcherService : IHostedService
|
class WatcherService : IHostedService
|
||||||
{
|
{
|
||||||
|
private const string ConfigInstanceKey = "localconfig";
|
||||||
|
|
||||||
private readonly ILogger<WatcherService> Logger;
|
private readonly ILogger<WatcherService> Logger;
|
||||||
private readonly RootOptions Config;
|
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();
|
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;
|
Logger = logger;
|
||||||
Config = config.Value;
|
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");
|
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)
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
@ -6,12 +6,9 @@
|
|||||||
"Watcher": {
|
"Watcher": {
|
||||||
"Instances": [
|
"Instances": [
|
||||||
{
|
{
|
||||||
"name": "sarsoo",
|
"name": "player watcher",
|
||||||
"type": "player"
|
"type": "player",
|
||||||
},
|
"pollperiod": 1000
|
||||||
{
|
|
||||||
"name": "andy",
|
|
||||||
"type": "playlist"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace Selector
|
|||||||
ClientSecret = clientSecret;
|
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)
|
public Task<RefreshTokenFactory> GetFactory(string refreshToken)
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Selector
|
namespace Selector
|
||||||
{
|
{
|
||||||
public interface IWatcherFactory
|
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;
|
IsRunning = true;
|
||||||
TokenSource = new();
|
TokenSource = new();
|
||||||
Task = Watcher.Watch(TokenSource.Token);
|
Task = Watcher.Watch(TokenSource.Token);
|
||||||
|
Task.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
if (t.Exception != null) throw t.Exception;
|
||||||
|
}, TaskContinuationOptions.OnlyOnFaulted);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
|
@ -1,14 +1,47 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
using SpotifyAPI.Web;
|
||||||
|
|
||||||
namespace Selector
|
namespace Selector
|
||||||
{
|
{
|
||||||
//class PlayerWatcherFactory : IWatcherFactory
|
public class WatcherFactory : IWatcherFactory {
|
||||||
//{
|
|
||||||
// public IWatcher Create()
|
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