added null CurrentlyPlaying from api, better testing
This commit is contained in:
parent
55bba58fca
commit
823c1368e7
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: dotnet package
|
name: ci
|
||||||
|
|
||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
# Selector
|
# Selector
|
||||||
|
|
||||||
|
![ci](https://github.com/sarsoo/Selector/actions/workflows/ci.yml/badge.svg)
|
||||||
|
|
||||||
Investigating a Spotify listening agent
|
Investigating a Spotify listening agent
|
@ -140,6 +140,31 @@ namespace Selector.Tests
|
|||||||
var eq = new UriEquality();
|
var eq = new UriEquality();
|
||||||
eq.Artist(artist1, artist2).Should().Be(shouldEqual);
|
eq.Artist(artist1, artist2).Should().Be(shouldEqual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> EpisodeData =>
|
||||||
|
new List<object[]>
|
||||||
|
{
|
||||||
|
// SAME
|
||||||
|
new object[] {
|
||||||
|
Helper.FullEpisode("1"),
|
||||||
|
Helper.FullEpisode("1"),
|
||||||
|
true
|
||||||
|
},
|
||||||
|
// DIFFERENT
|
||||||
|
new object[] {
|
||||||
|
Helper.FullEpisode("1"),
|
||||||
|
Helper.FullEpisode("2"),
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(EpisodeData))]
|
||||||
|
public void EpisodeEquality(FullEpisode episode1, FullEpisode episode2, bool shouldEqual)
|
||||||
|
{
|
||||||
|
var eq = new UriEquality();
|
||||||
|
eq.Episode(episode1, episode2).Should().Be(shouldEqual);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StringEqualityTests
|
public class StringEqualityTests
|
||||||
@ -273,5 +298,42 @@ namespace Selector.Tests
|
|||||||
var eq = new StringEquality();
|
var eq = new StringEquality();
|
||||||
eq.Artist(artist1, artist2).Should().Be(shouldEqual);
|
eq.Artist(artist1, artist2).Should().Be(shouldEqual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> EpisodeData =>
|
||||||
|
new List<object[]>
|
||||||
|
{
|
||||||
|
// SAME
|
||||||
|
new object[] {
|
||||||
|
Helper.FullEpisode("1", "1", "1"),
|
||||||
|
Helper.FullEpisode("1", "1", "1"),
|
||||||
|
true
|
||||||
|
},
|
||||||
|
// DIFFERENT PUBLISHER
|
||||||
|
new object[] {
|
||||||
|
Helper.FullEpisode("1", "1", "1"),
|
||||||
|
Helper.FullEpisode("1", "1", "2"),
|
||||||
|
false
|
||||||
|
},
|
||||||
|
// DIFFERENT SHOW
|
||||||
|
new object[] {
|
||||||
|
Helper.FullEpisode("1", "1", "1"),
|
||||||
|
Helper.FullEpisode("1", "2", "1"),
|
||||||
|
false
|
||||||
|
},
|
||||||
|
// DIFFERENT EPISODE
|
||||||
|
new object[] {
|
||||||
|
Helper.FullEpisode("1", "1", "1"),
|
||||||
|
Helper.FullEpisode("2", "1", "1"),
|
||||||
|
false
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(EpisodeData))]
|
||||||
|
public void EpisodeEquality(FullEpisode episode1, FullEpisode episode2, bool shouldEqual)
|
||||||
|
{
|
||||||
|
var eq = new StringEquality();
|
||||||
|
eq.Episode(episode1, episode2).Should().Be(shouldEqual);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,16 @@ namespace Selector.Tests
|
|||||||
return FullTrack(name, album, new List<string>() { artist });
|
return FullTrack(name, album, new List<string>() { artist });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FullEpisode FullEpisode(string name, string show = null, string publisher = null)
|
||||||
|
{
|
||||||
|
return new FullEpisode()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Uri = name,
|
||||||
|
Show = SimpleShow(show ?? name, publisher: publisher)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static SimpleAlbum SimpleAlbum(string name, List<string> artists)
|
public static SimpleAlbum SimpleAlbum(string name, List<string> artists)
|
||||||
{
|
{
|
||||||
return new SimpleAlbum()
|
return new SimpleAlbum()
|
||||||
@ -50,6 +60,16 @@ namespace Selector.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SimpleShow SimpleShow(string name, string publisher = null)
|
||||||
|
{
|
||||||
|
return new SimpleShow()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Publisher = publisher ?? name,
|
||||||
|
Uri = name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static CurrentlyPlaying CurrentlyPlaying(FullTrack track, bool isPlaying = true, string context = null)
|
public static CurrentlyPlaying CurrentlyPlaying(FullTrack track, bool isPlaying = true, string context = null)
|
||||||
{
|
{
|
||||||
return new CurrentlyPlaying()
|
return new CurrentlyPlaying()
|
||||||
@ -60,6 +80,16 @@ namespace Selector.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CurrentlyPlaying CurrentlyPlaying(FullEpisode episode, bool isPlaying = true, string context = null)
|
||||||
|
{
|
||||||
|
return new CurrentlyPlaying()
|
||||||
|
{
|
||||||
|
Context = Context(context ?? episode.Uri),
|
||||||
|
IsPlaying = isPlaying,
|
||||||
|
Item = episode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static Context Context(string uri)
|
public static Context Context(string uri)
|
||||||
{
|
{
|
||||||
return new Context()
|
return new Context()
|
||||||
|
@ -5,7 +5,7 @@ using Moq;
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using SpotifyAPI.Web;
|
using SpotifyAPI.Web;
|
||||||
|
|
||||||
using Selector;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Selector.Tests
|
namespace Selector.Tests
|
||||||
{
|
{
|
||||||
@ -29,12 +29,11 @@ namespace Selector.Tests
|
|||||||
var playingQueue = new Queue<CurrentlyPlaying>(playing);
|
var playingQueue = new Queue<CurrentlyPlaying>(playing);
|
||||||
|
|
||||||
var spotMock = new Mock<IPlayerClient>();
|
var spotMock = new Mock<IPlayerClient>();
|
||||||
var scheduleMock = new Mock<IScheduler>();
|
|
||||||
var eq = new UriEquality();
|
var eq = new UriEquality();
|
||||||
|
|
||||||
spotMock.Setup(s => s.GetCurrentlyPlaying(It.IsAny<PlayerCurrentlyPlayingRequest>()).Result).Returns(playingQueue.Dequeue);
|
spotMock.Setup(s => s.GetCurrentlyPlaying(It.IsAny<PlayerCurrentlyPlayingRequest>()).Result).Returns(playingQueue.Dequeue);
|
||||||
|
|
||||||
var watcher = new PlayerWatcher(spotMock.Object, scheduleMock.Object, eq);
|
var watcher = new PlayerWatcher(spotMock.Object, eq);
|
||||||
|
|
||||||
for(var i = 0; i < playing.Count; i++)
|
for(var i = 0; i < playing.Count; i++)
|
||||||
{
|
{
|
||||||
@ -56,7 +55,7 @@ namespace Selector.Tests
|
|||||||
// to raise
|
// to raise
|
||||||
new List<string>(){ },
|
new List<string>(){ },
|
||||||
// to not raise
|
// to not raise
|
||||||
new List<string>(){ "TrackChange", "AlbumChange", "ArtistChange", "ContextChange", "PlayingChange" }
|
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "PlayingChange" }
|
||||||
},
|
},
|
||||||
// TRACK CHANGE
|
// TRACK CHANGE
|
||||||
new object[] { new List<CurrentlyPlaying>(){
|
new object[] { new List<CurrentlyPlaying>(){
|
||||||
@ -64,7 +63,7 @@ namespace Selector.Tests
|
|||||||
Helper.CurrentlyPlaying(Helper.FullTrack("track2", "album1", "artist1"))
|
Helper.CurrentlyPlaying(Helper.FullTrack("track2", "album1", "artist1"))
|
||||||
},
|
},
|
||||||
// to raise
|
// to raise
|
||||||
new List<string>(){ "TrackChange" },
|
new List<string>(){ "ItemChange" },
|
||||||
// to not raise
|
// to not raise
|
||||||
new List<string>(){ "AlbumChange", "ArtistChange" }
|
new List<string>(){ "AlbumChange", "ArtistChange" }
|
||||||
},
|
},
|
||||||
@ -74,7 +73,7 @@ namespace Selector.Tests
|
|||||||
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album2", "artist1"))
|
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album2", "artist1"))
|
||||||
},
|
},
|
||||||
// to raise
|
// to raise
|
||||||
new List<string>(){ "TrackChange", "AlbumChange" },
|
new List<string>(){ "ItemChange", "AlbumChange" },
|
||||||
// to not raise
|
// to not raise
|
||||||
new List<string>(){ "ArtistChange" }
|
new List<string>(){ "ArtistChange" }
|
||||||
},
|
},
|
||||||
@ -84,7 +83,7 @@ namespace Selector.Tests
|
|||||||
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist2"))
|
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist2"))
|
||||||
},
|
},
|
||||||
// to raise
|
// to raise
|
||||||
new List<string>(){ "TrackChange", "AlbumChange", "ArtistChange" },
|
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange" },
|
||||||
// to not raise
|
// to not raise
|
||||||
new List<string>(){ }
|
new List<string>(){ }
|
||||||
},
|
},
|
||||||
@ -96,7 +95,7 @@ namespace Selector.Tests
|
|||||||
// to raise
|
// to raise
|
||||||
new List<string>(){ "ContextChange" },
|
new List<string>(){ "ContextChange" },
|
||||||
// to not raise
|
// to not raise
|
||||||
new List<string>(){ "TrackChange", "AlbumChange", "ArtistChange" }
|
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange" }
|
||||||
},
|
},
|
||||||
// PLAYING CHANGE
|
// PLAYING CHANGE
|
||||||
new object[] { new List<CurrentlyPlaying>(){
|
new object[] { new List<CurrentlyPlaying>(){
|
||||||
@ -106,7 +105,37 @@ namespace Selector.Tests
|
|||||||
// to raise
|
// to raise
|
||||||
new List<string>(){ "PlayingChange" },
|
new List<string>(){ "PlayingChange" },
|
||||||
// to not raise
|
// to not raise
|
||||||
new List<string>(){ "TrackChange", "AlbumChange", "ArtistChange", "ContextChange" }
|
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange" }
|
||||||
|
},
|
||||||
|
// PLAYING CHANGE
|
||||||
|
new object[] { new List<CurrentlyPlaying>(){
|
||||||
|
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1"),
|
||||||
|
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
|
||||||
|
},
|
||||||
|
// to raise
|
||||||
|
new List<string>(){ "PlayingChange" },
|
||||||
|
// to not raise
|
||||||
|
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange" }
|
||||||
|
},
|
||||||
|
// CONTENT CHANGE
|
||||||
|
new object[] { new List<CurrentlyPlaying>(){
|
||||||
|
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
|
||||||
|
Helper.CurrentlyPlaying(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2")
|
||||||
|
},
|
||||||
|
// to raise
|
||||||
|
new List<string>(){ "ContentChange", "ContextChange", "ItemChange" },
|
||||||
|
// to not raise
|
||||||
|
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange" }
|
||||||
|
},
|
||||||
|
// CONTENT CHANGE
|
||||||
|
new object[] { new List<CurrentlyPlaying>(){
|
||||||
|
Helper.CurrentlyPlaying(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2"),
|
||||||
|
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
|
||||||
|
},
|
||||||
|
// to raise
|
||||||
|
new List<string>(){ "ContentChange", "ContextChange", "ItemChange" },
|
||||||
|
// to not raise
|
||||||
|
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange" }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -117,12 +146,11 @@ namespace Selector.Tests
|
|||||||
var playingQueue = new Queue<CurrentlyPlaying>(playing);
|
var playingQueue = new Queue<CurrentlyPlaying>(playing);
|
||||||
|
|
||||||
var spotMock = new Mock<IPlayerClient>();
|
var spotMock = new Mock<IPlayerClient>();
|
||||||
var scheduleMock = new Mock<IScheduler>();
|
|
||||||
var eq = new UriEquality();
|
var eq = new UriEquality();
|
||||||
|
|
||||||
spotMock.Setup(s => s.GetCurrentlyPlaying(It.IsAny<PlayerCurrentlyPlayingRequest>()).Result).Returns(playingQueue.Dequeue);
|
spotMock.Setup(s => s.GetCurrentlyPlaying(It.IsAny<PlayerCurrentlyPlayingRequest>()).Result).Returns(playingQueue.Dequeue);
|
||||||
|
|
||||||
var watcher = new PlayerWatcher(spotMock.Object, scheduleMock.Object, eq);
|
var watcher = new PlayerWatcher(spotMock.Object, eq);
|
||||||
using var monitoredWatcher = watcher.Monitor();
|
using var monitoredWatcher = watcher.Monitor();
|
||||||
|
|
||||||
for(var i = 0; i < playing.Count; i++)
|
for(var i = 0; i < playing.Count; i++)
|
||||||
@ -137,5 +165,16 @@ namespace Selector.Tests
|
|||||||
monitoredWatcher.Should().NotRaise(notRraise);
|
monitoredWatcher.Should().NotRaise(notRraise);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [Fact]
|
||||||
|
// public async void Auth()
|
||||||
|
// {
|
||||||
|
// var spot = new SpotifyClient("");
|
||||||
|
// var eq = new UriEquality();
|
||||||
|
// var watch = new PlayerWatcher(spot.Player, eq);
|
||||||
|
|
||||||
|
// var token = new CancellationTokenSource();
|
||||||
|
// await watch.Watch(token.Token);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,13 @@ namespace Selector {
|
|||||||
public bool Track(FullTrack track1, FullTrack track2, bool includingAlbum);
|
public bool Track(FullTrack track1, FullTrack track2, bool includingAlbum);
|
||||||
public bool Episode(FullEpisode ep1, FullEpisode ep2);
|
public bool Episode(FullEpisode ep1, FullEpisode ep2);
|
||||||
public bool Album(FullAlbum album1, FullAlbum album2);
|
public bool Album(FullAlbum album1, FullAlbum album2);
|
||||||
|
public bool Show(FullShow show1, FullShow show2);
|
||||||
public bool Artist(FullArtist artist1, FullArtist artist2);
|
public bool Artist(FullArtist artist1, FullArtist artist2);
|
||||||
|
|
||||||
public bool Track(SimpleTrack track1, SimpleTrack track2);
|
public bool Track(SimpleTrack track1, SimpleTrack track2);
|
||||||
public bool Episode(SimpleEpisode ep1, SimpleEpisode ep2);
|
public bool Episode(SimpleEpisode ep1, SimpleEpisode ep2);
|
||||||
public bool Album(SimpleAlbum album1, SimpleAlbum album2);
|
public bool Album(SimpleAlbum album1, SimpleAlbum album2);
|
||||||
|
public bool Show(SimpleShow show1, SimpleShow show2);
|
||||||
public bool Artist(SimpleArtist artist1, SimpleArtist artist2);
|
public bool Artist(SimpleArtist artist1, SimpleArtist artist2);
|
||||||
|
|
||||||
public bool Context(Context context1, Context context2);
|
public bool Context(Context context1, Context context2);
|
||||||
|
@ -18,7 +18,8 @@ namespace Selector {
|
|||||||
|
|
||||||
new public bool Episode(FullEpisode ep1, FullEpisode ep2)
|
new public bool Episode(FullEpisode ep1, FullEpisode ep2)
|
||||||
{
|
{
|
||||||
return ep1.Uri == ep2.Uri;
|
return ep1.Uri == ep2.Uri
|
||||||
|
&& Show(ep1.Show, ep2.Show);
|
||||||
}
|
}
|
||||||
|
|
||||||
new public bool Album(FullAlbum album1, FullAlbum album2)
|
new public bool Album(FullAlbum album1, FullAlbum album2)
|
||||||
@ -27,6 +28,12 @@ namespace Selector {
|
|||||||
&& Enumerable.SequenceEqual(album1.Artists.Select(a => a.Name), album2.Artists.Select(a => a.Name));
|
&& Enumerable.SequenceEqual(album1.Artists.Select(a => a.Name), album2.Artists.Select(a => a.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new public bool Show(FullShow show1, FullShow show2)
|
||||||
|
{
|
||||||
|
return show1.Name == show2.Name
|
||||||
|
&& show1.Publisher == show2.Publisher;
|
||||||
|
}
|
||||||
|
|
||||||
new public bool Artist(FullArtist artist1, FullArtist artist2)
|
new public bool Artist(FullArtist artist1, FullArtist artist2)
|
||||||
{
|
{
|
||||||
return artist1.Name == artist2.Name;
|
return artist1.Name == artist2.Name;
|
||||||
@ -49,6 +56,12 @@ namespace Selector {
|
|||||||
&& Enumerable.SequenceEqual(album1.Artists.Select(a => a.Name), album2.Artists.Select(a => a.Name));
|
&& Enumerable.SequenceEqual(album1.Artists.Select(a => a.Name), album2.Artists.Select(a => a.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new public bool Show(SimpleShow show1, SimpleShow show2)
|
||||||
|
{
|
||||||
|
return show1.Name == show2.Name
|
||||||
|
&& show1.Publisher == show2.Publisher;
|
||||||
|
}
|
||||||
|
|
||||||
new public bool Artist(SimpleArtist artist1, SimpleArtist artist2)
|
new public bool Artist(SimpleArtist artist1, SimpleArtist artist2)
|
||||||
{
|
{
|
||||||
return artist1.Name == artist2.Name;
|
return artist1.Name == artist2.Name;
|
||||||
|
@ -24,6 +24,11 @@ namespace Selector {
|
|||||||
return album1.Uri == album2.Uri
|
return album1.Uri == album2.Uri
|
||||||
&& Enumerable.SequenceEqual(album1.Artists.Select(a => a.Uri), album2.Artists.Select(a => a.Uri));
|
&& Enumerable.SequenceEqual(album1.Artists.Select(a => a.Uri), album2.Artists.Select(a => a.Uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Show(FullShow show1, FullShow show2)
|
||||||
|
{
|
||||||
|
return show1.Uri == show2.Uri;
|
||||||
|
}
|
||||||
public bool Artist(FullArtist artist1, FullArtist artist2)
|
public bool Artist(FullArtist artist1, FullArtist artist2)
|
||||||
{
|
{
|
||||||
return artist1.Uri == artist2.Uri;
|
return artist1.Uri == artist2.Uri;
|
||||||
@ -45,6 +50,12 @@ namespace Selector {
|
|||||||
return album1.Uri == album2.Uri
|
return album1.Uri == album2.Uri
|
||||||
&& Enumerable.SequenceEqual(album1.Artists.Select(a => a.Uri), album2.Artists.Select(a => a.Uri));
|
&& Enumerable.SequenceEqual(album1.Artists.Select(a => a.Uri), album2.Artists.Select(a => a.Uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Show(SimpleShow show1, SimpleShow show2)
|
||||||
|
{
|
||||||
|
return show1.Uri == show2.Uri;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Artist(SimpleArtist artist1, SimpleArtist artist2)
|
public bool Artist(SimpleArtist artist1, SimpleArtist artist2)
|
||||||
{
|
{
|
||||||
return artist1.Uri == artist2.Uri;
|
return artist1.Uri == artist2.Uri;
|
||||||
@ -54,6 +65,7 @@ namespace Selector {
|
|||||||
{
|
{
|
||||||
return context1.Uri == context2.Uri;
|
return context1.Uri == context2.Uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Device(Device device1, Device device2)
|
public bool Device(Device device1, Device device2)
|
||||||
{
|
{
|
||||||
return device1.Id == device2.Id;
|
return device1.Id == device2.Id;
|
||||||
|
@ -6,10 +6,11 @@ namespace Selector
|
|||||||
{
|
{
|
||||||
public interface IPlayerWatcher: IWatcher
|
public interface IPlayerWatcher: IWatcher
|
||||||
{
|
{
|
||||||
public event EventHandler<ListeningChangeEventArgs> TrackChange;
|
public event EventHandler<ListeningChangeEventArgs> ItemChange;
|
||||||
public event EventHandler<ListeningChangeEventArgs> AlbumChange;
|
public event EventHandler<ListeningChangeEventArgs> AlbumChange;
|
||||||
public event EventHandler<ListeningChangeEventArgs> ArtistChange;
|
public event EventHandler<ListeningChangeEventArgs> ArtistChange;
|
||||||
public event EventHandler<ListeningChangeEventArgs> ContextChange;
|
public event EventHandler<ListeningChangeEventArgs> ContextChange;
|
||||||
|
public event EventHandler<ListeningChangeEventArgs> ContentChange;
|
||||||
|
|
||||||
// public event EventHandler<ListeningChangeEventArgs> VolumeChange;
|
// public event EventHandler<ListeningChangeEventArgs> VolumeChange;
|
||||||
// public event EventHandler<ListeningChangeEventArgs> DeviceChange;
|
// public event EventHandler<ListeningChangeEventArgs> DeviceChange;
|
||||||
|
@ -9,13 +9,13 @@ namespace Selector
|
|||||||
public class PlayerWatcher: IPlayerWatcher
|
public class PlayerWatcher: IPlayerWatcher
|
||||||
{
|
{
|
||||||
private readonly IPlayerClient spotifyClient;
|
private readonly IPlayerClient spotifyClient;
|
||||||
private IScheduler sleepScheduler;
|
|
||||||
private IEqualityChecker equalityChecker;
|
private IEqualityChecker equalityChecker;
|
||||||
|
|
||||||
public event EventHandler<ListeningChangeEventArgs> TrackChange;
|
public event EventHandler<ListeningChangeEventArgs> ItemChange;
|
||||||
public event EventHandler<ListeningChangeEventArgs> AlbumChange;
|
public event EventHandler<ListeningChangeEventArgs> AlbumChange;
|
||||||
public event EventHandler<ListeningChangeEventArgs> ArtistChange;
|
public event EventHandler<ListeningChangeEventArgs> ArtistChange;
|
||||||
public event EventHandler<ListeningChangeEventArgs> ContextChange;
|
public event EventHandler<ListeningChangeEventArgs> ContextChange;
|
||||||
|
public event EventHandler<ListeningChangeEventArgs> ContentChange;
|
||||||
|
|
||||||
// public event EventHandler<ListeningChangeEventArgs> VolumeChange;
|
// public event EventHandler<ListeningChangeEventArgs> VolumeChange;
|
||||||
// public event EventHandler<ListeningChangeEventArgs> DeviceChange;
|
// public event EventHandler<ListeningChangeEventArgs> DeviceChange;
|
||||||
@ -24,80 +24,157 @@ namespace Selector
|
|||||||
private CurrentlyPlaying live { get; set; }
|
private CurrentlyPlaying live { get; set; }
|
||||||
private List<List<CurrentlyPlaying>> lastPlays { get; set; }
|
private List<List<CurrentlyPlaying>> lastPlays { get; set; }
|
||||||
|
|
||||||
public PlayerWatcher(IPlayerClient spotifyClient, IScheduler sleepScheduler, IEqualityChecker equalityChecker) {
|
private int _pollPeriod;
|
||||||
|
public int PollPeriod {
|
||||||
|
get => _pollPeriod;
|
||||||
|
set => _pollPeriod = Math.Max(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerWatcher(IPlayerClient spotifyClient,
|
||||||
|
IEqualityChecker equalityChecker,
|
||||||
|
int pollPeriod = 3000) {
|
||||||
|
|
||||||
this.spotifyClient = spotifyClient;
|
this.spotifyClient = spotifyClient;
|
||||||
this.sleepScheduler = sleepScheduler;
|
|
||||||
this.equalityChecker = equalityChecker;
|
this.equalityChecker = equalityChecker;
|
||||||
|
this.PollPeriod = pollPeriod;
|
||||||
|
|
||||||
lastPlays = new List<List<CurrentlyPlaying>>();
|
lastPlays = new List<List<CurrentlyPlaying>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task WatchOne()
|
public async Task WatchOne()
|
||||||
{
|
{
|
||||||
|
try{
|
||||||
var polledCurrent = await spotifyClient.GetCurrentlyPlaying(new PlayerCurrentlyPlayingRequest());
|
var polledCurrent = await spotifyClient.GetCurrentlyPlaying(new PlayerCurrentlyPlayingRequest());
|
||||||
|
|
||||||
StoreCurrentPlaying(polledCurrent);
|
if (polledCurrent != null) StoreCurrentPlaying(polledCurrent);
|
||||||
|
|
||||||
CurrentlyPlaying existing;
|
CurrentlyPlaying previous;
|
||||||
if(live is null) {
|
if(live is null) {
|
||||||
live = polledCurrent;
|
live = polledCurrent;
|
||||||
existing = polledCurrent;
|
previous = polledCurrent;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
existing = live;
|
previous = live;
|
||||||
live = polledCurrent;
|
live = polledCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
// NOT PLAYING
|
||||||
var existingItem = (FullTrack) existing.Item;
|
if(previous is null && live is null)
|
||||||
|
{
|
||||||
|
// Console.WriteLine("not playing");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// STARTED PLAYBACK
|
||||||
|
if(previous is null && (live.Item is FullTrack || live.Item is FullEpisode))
|
||||||
|
{
|
||||||
|
// Console.WriteLine("started playing");
|
||||||
|
|
||||||
|
}
|
||||||
|
// STOPPED PLAYBACK
|
||||||
|
else if((previous.Item is FullTrack || previous.Item is FullEpisode) && live is null)
|
||||||
|
{
|
||||||
|
// Console.WriteLine("stopped playing");
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// MUSIC
|
||||||
|
if(previous.Item is FullTrack && live.Item is FullTrack)
|
||||||
|
{
|
||||||
|
var previousItem = (FullTrack) previous.Item;
|
||||||
var currentItem = (FullTrack) live.Item;
|
var currentItem = (FullTrack) live.Item;
|
||||||
|
|
||||||
if(!equalityChecker.Track(existingItem, currentItem, true)) {
|
if(!equalityChecker.Track(previousItem, currentItem, true)) {
|
||||||
OnTrackChange(new ListeningChangeEventArgs(){
|
OnItemChange(new ListeningChangeEventArgs(){
|
||||||
Previous = existing,
|
Previous = previous,
|
||||||
Current = live
|
Current = live
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!equalityChecker.Album(existingItem.Album, currentItem.Album)) {
|
if(!equalityChecker.Album(previousItem.Album, currentItem.Album)) {
|
||||||
OnAlbumChange(new ListeningChangeEventArgs(){
|
OnAlbumChange(new ListeningChangeEventArgs(){
|
||||||
Previous = existing,
|
Previous = previous,
|
||||||
Current = live
|
Current = live
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!equalityChecker.Artist(existingItem.Artists[0], currentItem.Artists[0])) {
|
if(!equalityChecker.Artist(previousItem.Artists[0], currentItem.Artists[0])) {
|
||||||
OnArtistChange(new ListeningChangeEventArgs(){
|
OnArtistChange(new ListeningChangeEventArgs(){
|
||||||
Previous = existing,
|
Previous = previous,
|
||||||
Current = live
|
Current = live
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// CHANGED CONTENT
|
||||||
|
else if(previous.Item is FullTrack && live.Item is FullEpisode
|
||||||
|
|| previous.Item is FullEpisode && live.Item is FullTrack)
|
||||||
|
{
|
||||||
|
OnContentChange(new ListeningChangeEventArgs(){
|
||||||
|
Previous = previous,
|
||||||
|
Current = live
|
||||||
|
});
|
||||||
|
OnItemChange(new ListeningChangeEventArgs(){
|
||||||
|
Previous = previous,
|
||||||
|
Current = live
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// PODCASTS
|
||||||
|
else if(previous.Item is FullEpisode && live.Item is FullEpisode)
|
||||||
|
{
|
||||||
|
var previousItem = (FullEpisode) previous.Item;
|
||||||
|
var currentItem = (FullEpisode) live.Item;
|
||||||
|
|
||||||
if(!equalityChecker.Context(existing.Context, live.Context)) {
|
if(!equalityChecker.Episode(previousItem, currentItem)) {
|
||||||
|
OnItemChange(new ListeningChangeEventArgs(){
|
||||||
|
Previous = previous,
|
||||||
|
Current = live
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new NotSupportedException("Unknown item combination");
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONTEXT
|
||||||
|
if(!equalityChecker.Context(previous.Context, live.Context)) {
|
||||||
OnContextChange(new ListeningChangeEventArgs(){
|
OnContextChange(new ListeningChangeEventArgs(){
|
||||||
Previous = existing,
|
Previous = previous,
|
||||||
Current = live
|
Current = live
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(existing.IsPlaying != live.IsPlaying) {
|
// IS PLAYING
|
||||||
|
if(previous.IsPlaying != live.IsPlaying) {
|
||||||
OnPlayingChange(new ListeningChangeEventArgs(){
|
OnPlayingChange(new ListeningChangeEventArgs(){
|
||||||
Previous = existing,
|
Previous = previous,
|
||||||
Current = live
|
Current = live
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(InvalidCastException)
|
}
|
||||||
|
}
|
||||||
|
catch(APIUnauthorizedException e)
|
||||||
{
|
{
|
||||||
var existingItem = (FullEpisode) existing.Item;
|
throw e;
|
||||||
|
}
|
||||||
throw new NotImplementedException("Podcasts not implemented");
|
catch(APITooManyRequestsException e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch(APIException e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Watch(CancellationToken cancelToken)
|
public async Task Watch(CancellationToken cancelToken)
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
while (!cancelToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
await WatchOne();
|
||||||
|
await Task.Delay(PollPeriod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CurrentlyPlaying NowPlaying()
|
public CurrentlyPlaying NowPlaying()
|
||||||
@ -156,9 +233,9 @@ namespace Selector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnTrackChange(ListeningChangeEventArgs args)
|
protected virtual void OnItemChange(ListeningChangeEventArgs args)
|
||||||
{
|
{
|
||||||
TrackChange?.Invoke(this, args);
|
ItemChange?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnAlbumChange(ListeningChangeEventArgs args)
|
protected virtual void OnAlbumChange(ListeningChangeEventArgs args)
|
||||||
@ -176,6 +253,10 @@ namespace Selector
|
|||||||
ContextChange?.Invoke(this, args);
|
ContextChange?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void OnContentChange(ListeningChangeEventArgs args)
|
||||||
|
{
|
||||||
|
ContentChange?.Invoke(this, args);
|
||||||
|
}
|
||||||
|
|
||||||
// protected virtual void OnVolumeChange(ListeningChangeEventArgs args)
|
// protected virtual void OnVolumeChange(ListeningChangeEventArgs args)
|
||||||
// {
|
// {
|
||||||
|
Loading…
Reference in New Issue
Block a user