Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 8ddf3e8

Browse files
committed
Replace ISong with ISpotifyTrack to handle different track types
1 parent cb1727e commit 8ddf3e8

20 files changed

+477
-211
lines changed

Toastify.Test/Toastify.Tests.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
</Reference>
5959
<Reference Include="PresentationCore" />
6060
<Reference Include="SpotifyAPI.Web, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
61-
<HintPath>..\packages\SpotifyAPI.Web.3.0.2\lib\net46\SpotifyAPI.Web.dll</HintPath>
61+
<HintPath>..\packages\SpotifyAPI.Web.3.1.0\lib\net46\SpotifyAPI.Web.dll</HintPath>
6262
</Reference>
6363
<Reference Include="System" />
6464
<Reference Include="System.Windows" />

Toastify.Test/packages.config

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
<package id="JetBrains.Annotations" version="11.1.0" targetFramework="net45" />
77
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net45" />
88
<package id="NUnit" version="3.10.1" targetFramework="net45" />
9-
<package id="SpotifyAPI.Web" version="3.0.2" targetFramework="net472" />
9+
<package id="SpotifyAPI.Web" version="3.1.0" targetFramework="net472" />
1010
</packages>

Toastify/Toastify.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<PackageReference Include="Microsoft.Packaging.Tools.Trimming" Version="1.1.0-preview1-26619-01" />
6464
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
6565
<PackageReference Include="PowerArgs" Version="2.8.1" />
66-
<PackageReference Include="SpotifyAPI.Web" Version="3.0.2" />
66+
<PackageReference Include="SpotifyAPI.Web" Version="3.1.0" />
6767
</ItemGroup>
6868

6969
<!-- Regular References -->

Toastify/src/Core/Broadcaster/JsonGreetingsObject.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ public class JsonGreetingsObject
99
{
1010
#region Public Properties
1111

12-
[JsonProperty("song")]
13-
public JsonSong Song { get; set; }
12+
[JsonProperty("track")]
13+
public JsonTrack Track { get; set; }
1414

1515
[JsonProperty("playing")]
1616
public bool Playing { get; set; }

Toastify/src/Core/Broadcaster/JsonSong.cs Toastify/src/Core/Broadcaster/JsonTrack.cs

+19-9
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,46 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using Newtonsoft.Json;
5+
using ToastifyAPI.Core;
56
using ToastifyAPI.Model.Interfaces;
67

78
namespace Toastify.Core.Broadcaster
89
{
910
[Serializable]
1011
[JsonObject(MemberSerialization.OptIn)]
11-
public class JsonSong
12+
public class JsonTrack
1213
{
1314
#region Public Properties
1415

16+
[JsonProperty("type")]
17+
public SpotifyTrackType Type { get; }
18+
1519
[JsonProperty("title")]
1620
public string Title { get; }
1721

22+
[JsonProperty("length")]
23+
public int Length { get; }
24+
1825
[JsonProperty("artists")]
1926
public List<string> Artists { get; }
2027

2128
[JsonProperty("album")]
2229
public string Album { get; }
2330

24-
[JsonProperty("length")]
25-
public int Length { get; }
26-
2731
#endregion
2832

29-
public JsonSong(ISong song)
33+
public JsonTrack(ISpotifyTrack track)
3034
{
31-
this.Title = song?.Title;
32-
this.Artists = song?.Artists.ToList();
33-
this.Album = song?.Album;
34-
this.Length = song?.Length ?? -1;
35+
this.Type = track?.Type ?? SpotifyTrackType.Unknown;
36+
this.Title = track?.Title;
37+
this.Length = track?.Length ?? 0;
38+
39+
if (track?.Type == SpotifyTrackType.Song)
40+
{
41+
ISong song = track as ISong;
42+
this.Artists = song?.Artists.ToList();
43+
this.Album = song?.Album;
44+
}
3545
}
3646
}
3747
}

Toastify/src/Core/Broadcaster/ToastifyBroadcaster.cs

+36-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Globalization;
23
using System.Net;
34
using System.Net.Sockets;
45
using System.Net.WebSockets;
@@ -19,6 +20,12 @@ public class ToastifyBroadcaster : IToastifyBroadcaster, IDisposable
1920
{
2021
private static readonly ILog logger = LogManager.GetLogger(typeof(ToastifyBroadcaster));
2122

23+
#region Static Fields and Properties
24+
25+
public static JsonSerializerSettings JsonSerializerSettings { get; }
26+
27+
#endregion
28+
2229
private ClientWebSocket socket;
2330
private KestrelWebSocketHost<ToastifyWebSocketHostStartup> webHost;
2431
private Thread receiveMessageThread;
@@ -40,6 +47,32 @@ public class ToastifyBroadcaster : IToastifyBroadcaster, IDisposable
4047

4148
#endregion
4249

50+
static ToastifyBroadcaster()
51+
{
52+
JsonSerializerSettings = new JsonSerializerSettings
53+
{
54+
StringEscapeHandling = StringEscapeHandling.Default,
55+
FloatParseHandling = FloatParseHandling.Decimal,
56+
FloatFormatHandling = FloatFormatHandling.String,
57+
DateParseHandling = DateParseHandling.DateTime,
58+
DateTimeZoneHandling = DateTimeZoneHandling.Local,
59+
DateFormatHandling = DateFormatHandling.IsoDateFormat,
60+
Formatting = Formatting.None,
61+
MaxDepth = null,
62+
Culture = CultureInfo.InvariantCulture,
63+
ConstructorHandling = ConstructorHandling.Default,
64+
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
65+
MetadataPropertyHandling = MetadataPropertyHandling.Default,
66+
TypeNameHandling = TypeNameHandling.None,
67+
PreserveReferencesHandling = PreserveReferencesHandling.None,
68+
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
69+
NullValueHandling = NullValueHandling.Ignore,
70+
ObjectCreationHandling = ObjectCreationHandling.Auto,
71+
MissingMemberHandling = MissingMemberHandling.Ignore,
72+
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
73+
};
74+
}
75+
4376
public ToastifyBroadcaster() : this(41348)
4477
{
4578
}
@@ -444,10 +477,10 @@ private async Task Broadcast(params string[] args)
444477
await this.SendCommand("BROADCAST", args).ConfigureAwait(false);
445478
}
446479

447-
public async Task BroadcastCurrentSong<T>(T song) where T : ISong
480+
public async Task BroadcastCurrentTrack<T>(T track) where T : ISpotifyTrack
448481
{
449-
string songJson = song != null ? JsonConvert.SerializeObject(new JsonSong(song)) : "null";
450-
await this.Broadcast("CURRENT-SONG", songJson).ConfigureAwait(false);
482+
string trackJson = track != null ? JsonConvert.SerializeObject(new JsonTrack(track), JsonSerializerSettings) : "null";
483+
await this.Broadcast("CURRENT-TRACK", trackJson).ConfigureAwait(false);
451484
}
452485

453486
public async Task BroadcastPlayState(bool playing)

Toastify/src/Core/Broadcaster/ToastifyWebSocketHostStartup.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private async Task HandleInternal(string message, WebSocket webSocket)
7575
string cmd = match.Groups[1].Value;
7676
switch (match.Groups[1].Value)
7777
{
78-
case "CURRENT-SONG":
78+
case "CURRENT-TRACK":
7979
foreach (var client in this.clients)
8080
{
8181
await RedirectTo($"{cmd} {match.Groups[2].Value}", client).ConfigureAwait(false);
@@ -191,7 +191,7 @@ protected override void OnWebSocketConnected(HttpContext context, WebSocket webS
191191
{
192192
JsonGreetingsObject greetings = new JsonGreetingsObject
193193
{
194-
Song = new JsonSong(Spotify.Instance.CurrentSong),
194+
Track = new JsonTrack(Spotify.Instance.CurrentTrack),
195195
Playing = Spotify.Instance.IsPlaying
196196
};
197197
await RedirectTo($"HELLO {JsonConvert.SerializeObject(greetings)}", webSocket).ConfigureAwait(false);

Toastify/src/Core/Spotify.cs

+23-23
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public bool IsRunning
6262
get { return this.spotifyWindow?.IsValid ?? false; }
6363
}
6464

65-
public ISong CurrentSong { get; private set; }
65+
public ISpotifyTrack CurrentTrack { get; private set; }
6666

6767
public bool IsPlaying { get; private set; }
6868

@@ -80,7 +80,7 @@ public bool IsRunning
8080

8181
public event EventHandler<SpotifyStateEventArgs> Connected;
8282

83-
public event EventHandler<SpotifyTrackChangedEventArgs> SongChanged;
83+
public event EventHandler<SpotifyTrackChangedEventArgs> TrackChanged;
8484

8585
public event EventHandler<SpotifyPlayStateChangedEventArgs> PlayStateChanged;
8686

@@ -555,23 +555,23 @@ private void BeginInitializeWebAPI()
555555
logger.Debug("Begin Spotify WebAPI initialization");
556556
}
557557

558-
private async Task<bool> UpdateSongInfoUsingWebApi()
558+
private async Task<bool> UpdateTrackInfoUsingWebApi()
559559
{
560560
if (this.Web?.API == null)
561561
return false;
562562

563563
// Pre-emptively waiting a little bit to let the remote Spotify server update its own information
564-
await Task.Delay(TimeSpan.FromMilliseconds(25)).ConfigureAwait(false);
564+
await Task.Delay(TimeSpan.FromMilliseconds(50)).ConfigureAwait(false);
565565
var currentlyPlayingObject = await this.Web.API.GetCurrentlyPlayingTrackAsync().ConfigureAwait(false);
566566
if (currentlyPlayingObject?.Track == null || !currentlyPlayingObject.Track.IsValid())
567567
return false;
568568

569-
ISong newSong = currentlyPlayingObject.Track;
570-
if (newSong != null && !Song.Equal(this.CurrentSong, newSong))
569+
ISpotifyTrack newTrack = currentlyPlayingObject.Track;
570+
if (!SpotifyTrack.Equal(this.CurrentTrack, newTrack))
571571
{
572-
ISong oldSong = this.CurrentSong;
573-
this.CurrentSong = newSong;
574-
await this.OnSongChanged(oldSong).ConfigureAwait(false);
572+
ISpotifyTrack oldTrack = this.CurrentTrack;
573+
this.CurrentTrack = newTrack;
574+
await this.OnTrackChanged(oldTrack).ConfigureAwait(false);
575575
}
576576

577577
await this.OnPlayStateChanged(currentlyPlayingObject.IsPlaying).ConfigureAwait(false);
@@ -680,12 +680,12 @@ private async void OnWebAPIInitializationSucceeded()
680680
var currentlyPlayingObject = await this.Web.API.GetCurrentlyPlayingTrackAsync().ConfigureAwait(false);
681681
if (currentlyPlayingObject?.Track != null && currentlyPlayingObject.Track.IsValid())
682682
{
683-
this.CurrentSong = currentlyPlayingObject.Track;
683+
this.CurrentTrack = currentlyPlayingObject.Track;
684684
this.IsPlaying = currentlyPlayingObject.IsPlaying;
685685
}
686686

687687
this.IsWebApiRunning = true;
688-
this.WebAPIInitializationSucceeded?.Invoke(this, new SpotifyStateEventArgs(this.CurrentSong, this.IsPlaying, this.CurrentSong?.Length ?? 0.0, 1.0));
688+
this.WebAPIInitializationSucceeded?.Invoke(this, new SpotifyStateEventArgs(this.CurrentTrack, this.IsPlaying, this.CurrentTrack?.Length ?? 0.0, 1.0));
689689
}
690690

691691
private void OnWebAPIInitializationFailed(SpotifyWebAPIInitializationFailedReason reason)
@@ -708,7 +708,7 @@ private async Task OnSpotifyConnected(SpotifyStateEventArgs e)
708708
{
709709
StringBuilder sb = new StringBuilder();
710710
sb.Append($"Spotify Connected. Status = {{{Environment.NewLine}")
711-
.Append($" CurrentSong: {(e.CurrentSong != null ? $"\"{e.CurrentSong}\"" : "null")},{Environment.NewLine}")
711+
.Append($" CurrentSong: {(e.CurrentTrack != null ? $"\"{e.CurrentTrack}\"" : "null")},{Environment.NewLine}")
712712
.Append($" Playing: {e.Playing},{Environment.NewLine}")
713713
.Append($" TrackTime: {e.TrackTime},{Environment.NewLine}")
714714
.Append($" Volume: {e.Volume}{Environment.NewLine}")
@@ -717,7 +717,7 @@ private async Task OnSpotifyConnected(SpotifyStateEventArgs e)
717717
}
718718

719719
this.IsPlaying = e.Playing;
720-
this.CurrentSong = e.CurrentSong;
720+
this.CurrentTrack = e.CurrentTrack;
721721

722722
this.Connected?.Invoke(this, e);
723723

@@ -732,14 +732,14 @@ private async Task OnSpotifyConnected(SpotifyStateEventArgs e)
732732
{
733733
await this.Broadcaster.StartAsync().ConfigureAwait(false);
734734
await this.Broadcaster.BroadcastPlayState(e.Playing).ConfigureAwait(false);
735-
await this.Broadcaster.BroadcastCurrentSong(e.CurrentSong).ConfigureAwait(false);
735+
await this.Broadcaster.BroadcastCurrentTrack(e.CurrentTrack).ConfigureAwait(false);
736736
}
737737
}
738738

739-
private async Task OnSongChanged(ISong previousSong)
739+
private async Task OnTrackChanged(ISpotifyTrack previousTrack)
740740
{
741-
this.SongChanged?.Invoke(this, new SpotifyTrackChangedEventArgs(previousSong, this.CurrentSong));
742-
await this.Broadcaster.BroadcastCurrentSong(this.CurrentSong).ConfigureAwait(false);
741+
this.TrackChanged?.Invoke(this, new SpotifyTrackChangedEventArgs(previousTrack, this.CurrentTrack));
742+
await this.Broadcaster.BroadcastCurrentTrack(this.CurrentTrack).ConfigureAwait(false);
743743
}
744744

745745
private async Task OnPlayStateChanged(bool playing)
@@ -853,7 +853,7 @@ private async void SpotifyWindowTitleWatcher_TitleChanged(object sender, WindowT
853853
logger.Debug($"Spotify's window title changed: \"{e.NewTitle}\". Fetching song info...");
854854

855855
if (!(Settings.Current.EnableSpotifyWebApi && this.IsWebApiRunning &&
856-
await this.UpdateSongInfoUsingWebApi().ConfigureAwait(false)))
856+
await this.UpdateTrackInfoUsingWebApi().ConfigureAwait(false)))
857857
{
858858
// If the WebAPIs are disabled or they weren't able to retrieve the song info, fallback to
859859
// the old method based on the title of Spotify's window.
@@ -872,12 +872,12 @@ await this.UpdateSongInfoUsingWebApi().ConfigureAwait(false)))
872872

873873
if (updateSong)
874874
{
875-
ISong newSong = Song.FromSpotifyWindowTitle(e.NewTitle);
876-
if (!Song.Equal(this.CurrentSong, newSong))
875+
ISpotifyTrack newSong = Song.FromSpotifyWindowTitle(e.NewTitle);
876+
if (!SpotifyTrack.Equal(this.CurrentTrack, newSong))
877877
{
878-
ISong oldSong = this.CurrentSong;
879-
this.CurrentSong = newSong;
880-
await this.OnSongChanged(oldSong).ConfigureAwait(false);
878+
ISpotifyTrack oldSong = this.CurrentTrack;
879+
this.CurrentTrack = newSong;
880+
await this.OnTrackChanged(oldSong).ConfigureAwait(false);
881881
}
882882
}
883883
}

Toastify/src/Events/SpotifyStateEventArgs.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ public class SpotifyStateEventArgs : EventArgs
88
{
99
#region Public Properties
1010

11-
public ISong CurrentSong { get; }
11+
public ISpotifyTrack CurrentTrack { get; }
1212
public bool Playing { get; }
1313
public double TrackTime { get; }
1414
public double Volume { get; }
1515

1616
#endregion
1717

18-
public SpotifyStateEventArgs(ISong currentSong, bool playing, double trackTime, double volume)
18+
public SpotifyStateEventArgs(ISpotifyTrack currentTrack, bool playing, double trackTime, double volume)
1919
{
20-
this.CurrentSong = currentSong;
20+
this.CurrentTrack = currentTrack;
2121
this.Playing = playing;
2222
this.TrackTime = trackTime;
2323
this.Volume = volume;
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using ToastifyAPI.Model.Interfaces;
33

44
namespace Toastify.Events
@@ -7,15 +7,15 @@ public class SpotifyTrackChangedEventArgs : EventArgs
77
{
88
#region Public Properties
99

10-
public ISong PreviousSong { get; }
11-
public ISong NewSong { get; }
10+
public ISpotifyTrack PreviousTrack { get; }
11+
public ISpotifyTrack NewTrack { get; }
1212

1313
#endregion
1414

15-
public SpotifyTrackChangedEventArgs(ISong previousSong, ISong newSong)
15+
public SpotifyTrackChangedEventArgs(ISpotifyTrack previousTrack, ISpotifyTrack newTrack)
1616
{
17-
this.PreviousSong = previousSong;
18-
this.NewSong = newSong;
17+
this.PreviousTrack = previousTrack;
18+
this.NewTrack = newTrack;
1919
}
2020
}
2121
}

0 commit comments

Comments
 (0)