diff --git a/Selector.CLI/Options.cs b/Selector.CLI/Options.cs index 441c200..61ff915 100644 --- a/Selector.CLI/Options.cs +++ b/Selector.CLI/Options.cs @@ -1,10 +1,50 @@  +using System.Collections.Generic; + namespace Selector.CLI { class RootOptions { public const string Key = "Selector"; - public int Number { get; set; } = 2; + /// + /// Spotify client ID + /// + public string ClientId { get; set; } + /// + /// Spotify app secret + /// + public string ClientSecret { get; set; } + public WatcherOptions WatcherOptions { get; set; } = new(); + public EqualityChecker Equality { get; set; } = EqualityChecker.Uri; + } + + enum EqualityChecker + { + Uri, String + } + + class WatcherOptions + { + public const string Key = "Watcher"; + + public List Instances { get; set; } = new(); + } + + class WatcherInstanceOptions + { + public const string Key = "Instances"; + + public string Name { get; set; } + public string AccessKey { get; set; } + public string RefreshKey { get; set; } + public int PollPeriod { get; set; } = 5000; + public WatcherType Type { get; set; } = WatcherType.Player; + public string? PlaylistUri { get; set; } + } + + enum WatcherType + { + Player, Playlist } } diff --git a/Selector.CLI/Program.cs b/Selector.CLI/Program.cs index 40b4efd..9420053 100644 --- a/Selector.CLI/Program.cs +++ b/Selector.CLI/Program.cs @@ -21,14 +21,24 @@ namespace Selector.CLI .ConfigureServices((context, services) => { // CONFIG - services.Configure(options => - context.Configuration.GetSection(RootOptions.Key).Bind(options) - ); + services.Configure(options => { + context.Configuration.GetSection(RootOptions.Key).Bind(options); + context.Configuration.GetSection($"{RootOptions.Key}:{WatcherOptions.Key}").Bind(options.WatcherOptions); + }); // SERVICES - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + //services.AddTransient(); + //services.AddTransient(); + + switch(context.Configuration.GetValue("selector:equality")) + { + case EqualityChecker.Uri: + services.AddTransient(); + break; + case EqualityChecker.String: + services.AddTransient(); + break; + } // HOSTED SERVICES services.AddHostedService(); diff --git a/Selector.CLI/WatcherService.cs b/Selector.CLI/WatcherService.cs index ffd4be3..dc670ce 100644 --- a/Selector.CLI/WatcherService.cs +++ b/Selector.CLI/WatcherService.cs @@ -16,6 +16,8 @@ namespace Selector.CLI private readonly ILogger Logger; private readonly RootOptions Config; + private Dictionary Watchers { get; set; } = new(); + public WatcherService(ILogger logger, IOptions config) { Logger = logger; @@ -26,12 +28,21 @@ namespace Selector.CLI { Logger.LogInformation("Starting up"); + Config.WatcherOptions.Instances.ForEach(i => Logger.LogInformation($"Config: {i.Type}")); + return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { Logger.LogInformation("Shutting down"); + + foreach((var key, var watcher) in Watchers) + { + Logger.LogInformation($"Stopping watcher collection: {key}"); + watcher.Stop(); + } + return Task.CompletedTask; } } diff --git a/Selector.CLI/appsettings.json b/Selector.CLI/appsettings.json index a228a47..c066b15 100644 --- a/Selector.CLI/appsettings.json +++ b/Selector.CLI/appsettings.json @@ -1,8 +1,21 @@ { - //"Selector": { - // "Number2": 4, - // "Number": 4 - //}, + "Selector": { + "ClientId": "", + "ClientSecret" "", + "Equality": "uri", + "Watcher": { + "Instances": [ + { + "name": "sarsoo", + "type": "player" + }, + { + "name": "andy", + "type": "playlist" + } + ] + } + }, "Logging": { "LogLevel": { "Default": "Information" diff --git a/Selector.Tests/Equal.cs b/Selector.Tests/Equal.cs index c9e4394..38f8835 100644 --- a/Selector.Tests/Equal.cs +++ b/Selector.Tests/Equal.cs @@ -62,7 +62,7 @@ namespace Selector.Tests [MemberData(nameof(TrackData))] public void TrackEquality(FullTrack track1, FullTrack track2, bool shouldEqual) { - var eq = Equal.String(); + var eq = new StringEqual(); eq.IsEqual(track1, track2).Should().Be(shouldEqual); } @@ -105,7 +105,7 @@ namespace Selector.Tests [MemberData(nameof(AlbumData))] public void AlbumEquality(SimpleAlbum album1, SimpleAlbum album2, bool shouldEqual) { - var eq = Equal.String(); + var eq = new StringEqual(); eq.IsEqual(album1, album2).Should().Be(shouldEqual); } @@ -130,7 +130,7 @@ namespace Selector.Tests [MemberData(nameof(ArtistData))] public void ArtistEquality(SimpleArtist artist1, SimpleArtist artist2, bool shouldEqual) { - var eq = Equal.String(); + var eq = new StringEqual(); eq.IsEqual(artist1, artist2).Should().Be(shouldEqual); } @@ -155,7 +155,7 @@ namespace Selector.Tests [MemberData(nameof(EpisodeData))] public void EpisodeEquality(FullEpisode episode1, FullEpisode episode2, bool shouldEqual) { - var eq = Equal.String(); + var eq = new StringEqual(); eq.IsEqual(episode1, episode2).Should().Be(shouldEqual); } } diff --git a/Selector/Equality/Equal.cs b/Selector/Equality/Equal.cs index fe9c2bb..f886429 100644 --- a/Selector/Equality/Equal.cs +++ b/Selector/Equality/Equal.cs @@ -7,25 +7,7 @@ namespace Selector { public class Equal : IEqual { - private Dictionary comps; - - public static Equal String() { - return new Equal(){ - comps = new Dictionary(){ - {typeof(FullTrack), new FullTrackStringComparer()}, - {typeof(FullEpisode), new FullEpisodeStringComparer()}, - {typeof(FullAlbum), new FullAlbumStringComparer()}, - {typeof(FullShow), new FullShowStringComparer()}, - {typeof(FullArtist), new FullArtistStringComparer()}, - - {typeof(SimpleTrack), new SimpleTrackStringComparer()}, - {typeof(SimpleEpisode), new SimpleEpisodeStringComparer()}, - {typeof(SimpleAlbum), new SimpleAlbumStringComparer()}, - {typeof(SimpleShow), new SimpleShowStringComparer()}, - {typeof(SimpleArtist), new SimpleArtistStringComparer()}, - } - }; - } + protected Dictionary comps; public bool IsEqual(T item, T other) { diff --git a/Selector/Equality/StringEqual.cs b/Selector/Equality/StringEqual.cs new file mode 100644 index 0000000..a3bde2d --- /dev/null +++ b/Selector/Equality/StringEqual.cs @@ -0,0 +1,25 @@ +using SpotifyAPI.Web; + +namespace Selector +{ + public class StringEqual: Equal + { + public StringEqual() + { + comps = new() + { + { typeof(FullTrack), new FullTrackStringComparer() }, + { typeof(FullEpisode), new FullEpisodeStringComparer() }, + { typeof(FullAlbum), new FullAlbumStringComparer() }, + { typeof(FullShow), new FullShowStringComparer() }, + { typeof(FullArtist), new FullArtistStringComparer() }, + + { typeof(SimpleTrack), new SimpleTrackStringComparer() }, + { typeof(SimpleEpisode), new SimpleEpisodeStringComparer() }, + { typeof(SimpleAlbum), new SimpleAlbumStringComparer() }, + { typeof(SimpleShow), new SimpleShowStringComparer() }, + { typeof(SimpleArtist), new SimpleArtistStringComparer() }, + }; + } + } +} diff --git a/Selector/Spotify/ISpotifyClientFactory.cs b/Selector/Spotify/ISpotifyClientFactory.cs new file mode 100644 index 0000000..5b45dae --- /dev/null +++ b/Selector/Spotify/ISpotifyClientFactory.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using SpotifyAPI.Web; + +namespace Selector +{ + public interface ISpotifyClientFactory + { + public Task GetConfig(); + } +} diff --git a/Selector/Spotify/RefreshTokenFactory.cs b/Selector/Spotify/RefreshTokenFactory.cs new file mode 100644 index 0000000..22cc4e6 --- /dev/null +++ b/Selector/Spotify/RefreshTokenFactory.cs @@ -0,0 +1,42 @@ +using System.Threading.Tasks; + +using SpotifyAPI.Web; + + +namespace Selector +{ + /// + /// Get config from a refresh token + /// + public class RefreshTokenFactory : ISpotifyClientFactory + { + private string ClientId { get; set; } + private string ClientSecret { get; set; } + private string RefreshToken { get; set; } + + public RefreshTokenFactory(string clientId, string clientSecret, string refreshToken) { + ClientId = clientId; + ClientSecret = clientSecret; + RefreshToken = refreshToken; + } + + public async Task GetConfig() + { + var refreshed = await new OAuthClient() + .RequestToken(new AuthorizationCodeRefreshRequest(ClientId, ClientSecret, RefreshToken)); + + var config = SpotifyClientConfig + .CreateDefault() + .WithAuthenticator(new AuthorizationCodeAuthenticator(ClientId, ClientSecret, new(){ + AccessToken = refreshed.AccessToken, + TokenType = refreshed.TokenType, + ExpiresIn = refreshed.ExpiresIn, + Scope = refreshed.Scope, + RefreshToken = refreshed.RefreshToken, + CreatedAt = refreshed.CreatedAt + })); + + return config; + } + } +} diff --git a/Selector/Watcher/Interfaces/IWatcherFactory.cs b/Selector/Watcher/Interfaces/IWatcherFactory.cs new file mode 100644 index 0000000..5c5444e --- /dev/null +++ b/Selector/Watcher/Interfaces/IWatcherFactory.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Selector +{ + public interface IWatcherFactory + { + public IWatcher Create(); + } +} diff --git a/Selector/Watcher/WatcherFactory.cs b/Selector/Watcher/WatcherFactory.cs new file mode 100644 index 0000000..c88a24e --- /dev/null +++ b/Selector/Watcher/WatcherFactory.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Selector +{ + //class PlayerWatcherFactory : IWatcherFactory + //{ + // public IWatcher Create() + // { + + // } + //} +}