From 861f4e59694dd13784ffbc0545718a4159364fec Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Fri, 16 Oct 2015 13:54:39 +0200 Subject: [PATCH 1/9] Added support for different locations of SpotifyWebHelper.exe --- SpotifyAPI/Local/SpotifyLocalAPI.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/SpotifyAPI/Local/SpotifyLocalAPI.cs b/SpotifyAPI/Local/SpotifyLocalAPI.cs index 8c4d16c6..40c8bffa 100644 --- a/SpotifyAPI/Local/SpotifyLocalAPI.cs +++ b/SpotifyAPI/Local/SpotifyLocalAPI.cs @@ -254,7 +254,7 @@ namespace SpotifyAPI.Local /// public static void RunSpotify() { - if (!IsSpotifyRunning()) + if (!IsSpotifyRunning() && File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"spotify\spotify.exe"))) Process.Start(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"spotify\spotify.exe")); } @@ -263,8 +263,14 @@ namespace SpotifyAPI.Local /// public static void RunSpotifyWebHelper() { - if (!IsSpotifyWebHelperRunning()) + if (!IsSpotifyWebHelperRunning() && File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"spotify\data\spotifywebhelper.exe"))) + { Process.Start(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"spotify\data\spotifywebhelper.exe")); + } + else if (!IsSpotifyWebHelperRunning() && File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"spotify\spotifywebhelper.exe"))) + { + Process.Start(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"spotify\spotifywebhelper.exe")); + } } } } From 10c8944e05ab23fcd740da4de3539c46c2c26cd2 Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Sat, 17 Oct 2015 00:31:01 +0200 Subject: [PATCH 2/9] Replaced all occurances of checking whether a string is empty via str == "" with String.IsNullOrEmpty(str) sealed StringAttribute because it is only contains text as attribute sealed SpotifyWebAPI class as it implements IDisposable Changed Exception catching where the Exception is not used to ignore the Exception object Removed Console.WriteLine("Exception: " + e.Message) int HttpProcessor.Process as it is a library function which might not be used in a console application --- SpotifyAPI/Local/Models/Track.cs | 4 +-- SpotifyAPI/Local/RemoteHandler.cs | 14 +++++----- SpotifyAPI/Local/SpotifyLocalAPI.cs | 2 +- SpotifyAPI/SpotifyAPI.csproj | 1 + SpotifyAPI/Web/SimpleHttpServer.cs | 21 ++++++-------- SpotifyAPI/Web/SpotifyWebAPI.cs | 43 +++++++++++++++-------------- SpotifyAPI/Web/Util.cs | 2 +- 7 files changed, 43 insertions(+), 44 deletions(-) diff --git a/SpotifyAPI/Local/Models/Track.cs b/SpotifyAPI/Local/Models/Track.cs index de2c4ecb..6b68cd1e 100644 --- a/SpotifyAPI/Local/Models/Track.cs +++ b/SpotifyAPI/Local/Models/Track.cs @@ -125,7 +125,7 @@ namespace SpotifyAPI.Local.Models { wc.Proxy = null; String url = GetAlbumArtUrl(size); - if (url == "") + if (String.IsNullOrEmpty(url)) return null; var data = wc.DownloadData(url); using (MemoryStream ms = new MemoryStream(data)) @@ -146,7 +146,7 @@ namespace SpotifyAPI.Local.Models { wc.Proxy = null; String url = GetAlbumArtUrl(size); - if (url == "") + if (String.IsNullOrEmpty(url)) return null; return wc.DownloadData(url); } diff --git a/SpotifyAPI/Local/RemoteHandler.cs b/SpotifyAPI/Local/RemoteHandler.cs index b01cbd4a..42a8645c 100644 --- a/SpotifyAPI/Local/RemoteHandler.cs +++ b/SpotifyAPI/Local/RemoteHandler.cs @@ -19,7 +19,7 @@ namespace SpotifyAPI.Local { OauthKey = GetOAuthKey(); CfidKey = GetCfid(); - return CfidKey != ""; + return !String.IsNullOrEmpty(CfidKey); } internal async void SendPauseRequest() @@ -46,7 +46,7 @@ namespace SpotifyAPI.Local internal StatusResponse GetNewStatus() { String response = Query("remote/status.json", true, true, -1); - if (response == "") + if (String.IsNullOrEmpty(response)) { return null; } @@ -77,7 +77,7 @@ namespace SpotifyAPI.Local if (cfidList == null) return ""; if (cfidList.Count != 1) - throw new Exception("CFID couldn't be loaded"); + throw new Exception("CFID could not be loaded"); return cfidList[0].Error == null ? cfidList[0].Token : ""; } @@ -114,9 +114,9 @@ namespace SpotifyAPI.Local response = "[ " + wc.DownloadString(address) + " ]"; } } - catch (Exception) + catch { - return ""; + return String.Empty; } return response; @@ -155,9 +155,9 @@ namespace SpotifyAPI.Local response = "[ " + await wc.DownloadStringTaskAsync(new Uri(address)) + " ]"; } } - catch (Exception) + catch { - return ""; + return String.Empty; } return response; diff --git a/SpotifyAPI/Local/SpotifyLocalAPI.cs b/SpotifyAPI/Local/SpotifyLocalAPI.cs index 40c8bffa..f2e5557f 100644 --- a/SpotifyAPI/Local/SpotifyLocalAPI.cs +++ b/SpotifyAPI/Local/SpotifyLocalAPI.cs @@ -12,7 +12,7 @@ namespace SpotifyAPI.Local { [DllImport("user32.dll")] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo); - [DllImport("nircmd.dll")] + [DllImport("nircmd.dll", CharSet = CharSet.Auto)] private static extern bool DoNirCmd(String nirCmdStr); private bool _listenForEvents; diff --git a/SpotifyAPI/SpotifyAPI.csproj b/SpotifyAPI/SpotifyAPI.csproj index 76cd3221..4ef06276 100644 --- a/SpotifyAPI/SpotifyAPI.csproj +++ b/SpotifyAPI/SpotifyAPI.csproj @@ -24,6 +24,7 @@ 4 bin\Debug\SpotifyAPI.XML 1591 + ..\..\..\My Data\Dokumente\Visual Studio 2015\Projects\BackupAudioRecorder\AudioRecordTest\MAXRULES.ruleset pdbonly diff --git a/SpotifyAPI/Web/SimpleHttpServer.cs b/SpotifyAPI/Web/SimpleHttpServer.cs index eac076c3..b67981c4 100644 --- a/SpotifyAPI/Web/SimpleHttpServer.cs +++ b/SpotifyAPI/Web/SimpleHttpServer.cs @@ -79,15 +79,13 @@ namespace SpotifyAPI.Web HandlePostRequest(); } } - catch (Exception e) + catch { - Console.WriteLine("Exception: " + e); WriteFailure(); } OutputStream.Flush(); - // bs.Flush(); // flush any remaining output _inputStream = null; - OutputStream = null; // bs = null; + OutputStream = null; _socket.Close(); } @@ -97,7 +95,7 @@ namespace SpotifyAPI.Web string[] tokens = request.Split(' '); if (tokens.Length < 2) { - throw new Exception("invalid http request line"); + throw new Exception("Invalid HTTP request line"); } HttpMethod = tokens[0].ToUpper(); HttpUrl = tokens[1]; @@ -108,7 +106,7 @@ namespace SpotifyAPI.Web String line; while ((line = StreamReadLine(_inputStream)) != null) { - if (line.Equals("")) + if (String.IsNullOrEmpty(line)) { return; } @@ -116,7 +114,7 @@ namespace SpotifyAPI.Web int separator = line.IndexOf(':'); if (separator == -1) { - throw new Exception("invalid http header line: " + line); + throw new Exception("Invalid HTTP header line: " + line); } String name = line.Substring(0, separator); int pos = separator + 1; @@ -149,9 +147,7 @@ namespace SpotifyAPI.Web var contentLen = Convert.ToInt32(HttpHeaders["Content-Length"]); if (contentLen > MaxPostSize) { - throw new Exception( - String.Format("POST Content-Length({0}) too big for this simple server", - contentLen)); + throw new Exception(String.Format("POST Content-Length({0}) too big for this simple server", contentLen)); } byte[] buf = new byte[BufSize]; int toRead = contentLen; @@ -164,7 +160,7 @@ namespace SpotifyAPI.Web { break; } - throw new Exception("client disconnected during post"); + throw new Exception("Client disconnected during post"); } toRead -= numread; ms.Write(buf, 0, numread); @@ -207,6 +203,8 @@ namespace SpotifyAPI.Web { IsActive = false; _listener.Stop(); + Dispose(); + GC.SuppressFinalize(this); } public void Listen() @@ -276,7 +274,6 @@ namespace SpotifyAPI.Web p.OutputStream.WriteLine("

Spotify Auth canceled!

"); t = new Thread(o => { - //_funcOne(null, col.Get(1), col.Get(0)); if(OnAuth != null) OnAuth(new AuthEventArgs() { diff --git a/SpotifyAPI/Web/SpotifyWebAPI.cs b/SpotifyAPI/Web/SpotifyWebAPI.cs index 462503b5..2db4f654 100644 --- a/SpotifyAPI/Web/SpotifyWebAPI.cs +++ b/SpotifyAPI/Web/SpotifyWebAPI.cs @@ -9,7 +9,7 @@ using SpotifyAPI.Web.Models; namespace SpotifyAPI.Web { - public class SpotifyWebAPI : IDisposable + public sealed class SpotifyWebAPI : IDisposable { public const String APIBase = "https://api.spotify.com/v1"; @@ -35,6 +35,7 @@ namespace SpotifyAPI.Web public void Dispose() { WebClient.Dispose(); + GC.SuppressFinalize(this); } #region Search @@ -56,7 +57,7 @@ namespace SpotifyAPI.Web builder.Append("&type=" + type.GetStringAttribute(",")); builder.Append("&limit=" + limit); builder.Append("&offset=" + offset); - if (market != "") + if (!String.IsNullOrEmpty(market)) builder.Append("&market=" + market); return DownloadData(builder.ToString()); } @@ -80,7 +81,7 @@ namespace SpotifyAPI.Web StringBuilder builder = new StringBuilder(APIBase + "/albums/" + id + "/tracks"); builder.Append("?limit=" + limit); builder.Append("&offset=" + offset); - if (market != "") + if (!String.IsNullOrEmpty(market)) builder.Append("&market=" + market); return DownloadData>(builder.ToString()); } @@ -93,7 +94,7 @@ namespace SpotifyAPI.Web /// public FullAlbum GetAlbum(String id, String market = "") { - if (market == "") + if (String.IsNullOrEmpty(market)) return DownloadData(APIBase + "/albums/" + id); return DownloadData(APIBase + "/albums/" + id + "?market=" + market); } @@ -106,7 +107,7 @@ namespace SpotifyAPI.Web /// public SeveralAlbums GetSeveralAlbums(List ids, String market = "") { - if (market == "") + if (String.IsNullOrEmpty(market)) return DownloadData(APIBase + "/albums?ids=" + string.Join(",", ids.Take(20))); return DownloadData(APIBase + "/albums?market=" + market + "&ids=" + string.Join(",", ids.Take(20))); } @@ -170,7 +171,7 @@ namespace SpotifyAPI.Web builder.Append("?type=" + type.GetStringAttribute(",")); builder.Append("&limit=" + limit); builder.Append("&offset=" + offset); - if (market != "") + if (!String.IsNullOrEmpty(market)) builder.Append("&market=" + market); return DownloadData>(builder.ToString()); } @@ -209,9 +210,9 @@ namespace SpotifyAPI.Web StringBuilder builder = new StringBuilder(APIBase + "/browse/featured-playlists"); builder.Append("?limit=" + limit); builder.Append("&offset=" + offset); - if (locale != "") + if (!String.IsNullOrEmpty(locale)) builder.Append("&locale=" + locale); - if (country != "") + if (!String.IsNullOrEmpty(country)) builder.Append("&country=" + country); if (timestamp != default(DateTime)) builder.Append("×tamp=" + timestamp.ToString("yyyy-MM-ddTHH:mm:ss")); @@ -234,7 +235,7 @@ namespace SpotifyAPI.Web StringBuilder builder = new StringBuilder(APIBase + "/browse/new-releases"); builder.Append("?limit=" + limit); builder.Append("&offset=" + offset); - if (country != "") + if (!String.IsNullOrEmpty(country)) builder.Append("&country=" + country); return DownloadData(builder.ToString()); } @@ -262,9 +263,9 @@ namespace SpotifyAPI.Web StringBuilder builder = new StringBuilder(APIBase + "/browse/categories"); builder.Append("?limit=" + limit); builder.Append("&offset=" + offset); - if (country != "") + if (!String.IsNullOrEmpty(country)) builder.Append("&country=" + country); - if (locale != "") + if (!String.IsNullOrEmpty(locale)) builder.Append("&locale=" + locale); return DownloadData(builder.ToString()); } @@ -286,9 +287,9 @@ namespace SpotifyAPI.Web public Category GetCategory(String categoryId, String country = "", String locale = "") { StringBuilder builder = new StringBuilder(APIBase + "/browse/categories/" + categoryId); - if (country != "") + if (!String.IsNullOrEmpty(country)) builder.Append("?country=" + country); - if (locale != "") + if (!String.IsNullOrEmpty(locale)) builder.Append((country == "" ? "?locale=" : "&locale=") + locale); return DownloadData(builder.ToString()); } @@ -308,7 +309,7 @@ namespace SpotifyAPI.Web StringBuilder builder = new StringBuilder(APIBase + "/browse/categories/" + categoryId + "/playlists"); builder.Append("?limit=" + limit); builder.Append("&offset=" + offset); - if (country != "") + if (!String.IsNullOrEmpty(country)) builder.Append("&country=" + country); return DownloadData(builder.ToString()); } @@ -332,7 +333,7 @@ namespace SpotifyAPI.Web const FollowType followType = FollowType.Artist; //currently only artist is supported. StringBuilder builder = new StringBuilder(APIBase + "/me/following?type=" + followType.GetStringAttribute("")); builder.Append("&limit=" + limit); - if (after != "") + if (!String.IsNullOrEmpty(after)) builder.Append("&after=" + after); return DownloadData(builder.ToString()); } @@ -531,7 +532,7 @@ namespace SpotifyAPI.Web StringBuilder builder = new StringBuilder(APIBase + "/me/tracks"); builder.Append("?limit=" + limit); builder.Append("&offset=" + offset); - if (market != "") + if (!String.IsNullOrEmpty(market)) builder.Append("&market=" + market); return DownloadData>(builder.ToString()); } @@ -605,7 +606,7 @@ namespace SpotifyAPI.Web throw new InvalidOperationException("Auth is required for GetPlaylist"); StringBuilder builder = new StringBuilder(APIBase + "/users/" + userId + "/playlists/" + playlistId); builder.Append("?fields=" + fields); - if (market != "") + if (!String.IsNullOrEmpty(market)) builder.Append("&market=" + market); return DownloadData(builder.ToString()); } @@ -633,7 +634,7 @@ namespace SpotifyAPI.Web builder.Append("?fields=" + fields); builder.Append("&limit=" + limit); builder.Append("&offset=" + offset); - if (market != "") + if (!String.IsNullOrEmpty(market)) builder.Append("&market=" + market); return DownloadData>(builder.ToString()); } @@ -785,7 +786,7 @@ namespace SpotifyAPI.Web {"range_length", rangeLength}, {"insert_before", insertBefore} }; - if (snapshotId != "") + if (!String.IsNullOrEmpty(snapshotId)) body.Add("snapshot_id", snapshotId); return UploadData(APIBase + "/users/" + userId + "/playlists/" + playlistId + "/tracks", body.ToString(Formatting.None), "PUT"); } @@ -828,7 +829,7 @@ namespace SpotifyAPI.Web /// public SeveralTracks GetSeveralTracks(List ids, String market = "") { - if (market == "") + if (String.IsNullOrEmpty(market)) return DownloadData(APIBase + "/tracks?ids=" + string.Join(",", ids.Take(50))); return DownloadData(APIBase + "/tracks?market=" + market + "&ids=" + string.Join(",", ids.Take(50))); } @@ -841,7 +842,7 @@ namespace SpotifyAPI.Web /// public FullTrack GetTrack(String id, String market = "") { - if (market == "") + if (String.IsNullOrEmpty(market)) return DownloadData(APIBase + "/tracks/" + id); return DownloadData(APIBase + "/tracks/" + id + "?market=" + market); } diff --git a/SpotifyAPI/Web/Util.cs b/SpotifyAPI/Web/Util.cs index bcd0d54f..7c3f4548 100644 --- a/SpotifyAPI/Web/Util.cs +++ b/SpotifyAPI/Web/Util.cs @@ -24,7 +24,7 @@ namespace SpotifyAPI.Web } } - public class StringAttribute : Attribute + public sealed class StringAttribute : Attribute { public String Text { get; set; } public StringAttribute(String text) From e4f30cb7363ea181b6fba8efdfe4229e816a20fa Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Sat, 17 Oct 2015 00:39:11 +0200 Subject: [PATCH 3/9] Changed Ruleset back to original --- SpotifyAPI/SpotifyAPI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SpotifyAPI/SpotifyAPI.csproj b/SpotifyAPI/SpotifyAPI.csproj index 4ef06276..de89e8af 100644 --- a/SpotifyAPI/SpotifyAPI.csproj +++ b/SpotifyAPI/SpotifyAPI.csproj @@ -24,7 +24,7 @@ 4 bin\Debug\SpotifyAPI.XML 1591 - ..\..\..\My Data\Dokumente\Visual Studio 2015\Projects\BackupAudioRecorder\AudioRecordTest\MAXRULES.ruleset + MinimumRecommendedRules.ruleset
pdbonly From 49441bba953fe0366dcb6db71ddc784cbeb42c4d Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Sat, 17 Oct 2015 00:44:35 +0200 Subject: [PATCH 4/9] Formatted and beautified code via codemaid Organised using statements alphabetically --- SpotifyAPI/Local/LocalEvents.cs | 9 ++- SpotifyAPI/Local/Models/CFID.cs | 6 +- SpotifyAPI/Local/Models/OpenGraphState.cs | 5 +- SpotifyAPI/Local/Models/SpotifyResource.cs | 8 ++- SpotifyAPI/Local/Models/StatusResponse.cs | 15 ++++- SpotifyAPI/Local/Models/Track.cs | 14 +++-- .../Local/Models/TrackResourceLocation.cs | 4 +- SpotifyAPI/Local/RemoteHandler.cs | 10 ++-- SpotifyAPI/Local/SpotifyLocalAPI.cs | 26 ++++++--- SpotifyAPI/Properties/AssemblyInfo.cs | 13 ++--- SpotifyAPI/Web/Auth/AutorizationCodeAuth.cs | 10 ++-- SpotifyAPI/Web/Auth/ClientCredentialsAuth.cs | 8 +-- SpotifyAPI/Web/Auth/ImplicitGrantAuth.cs | 9 +-- SpotifyAPI/Web/Enums/AlbumType.cs | 19 ++++-- SpotifyAPI/Web/Enums/FollowType.cs | 7 ++- SpotifyAPI/Web/Enums/Scope.cs | 47 +++++++++++---- SpotifyAPI/Web/Enums/SearchType.cs | 15 +++-- SpotifyAPI/Web/IClient.cs | 4 +- SpotifyAPI/Web/Models/BasicModel.cs | 4 +- SpotifyAPI/Web/Models/Category.cs | 4 +- SpotifyAPI/Web/Models/CursorPaging.cs | 4 +- SpotifyAPI/Web/Models/FeaturedPlaylists.cs | 4 +- SpotifyAPI/Web/Models/FullAlbum.cs | 4 +- SpotifyAPI/Web/Models/FullArtist.cs | 4 +- SpotifyAPI/Web/Models/FullPlaylist.cs | 4 +- SpotifyAPI/Web/Models/FullTrack.cs | 4 +- SpotifyAPI/Web/Models/GeneralModels.cs | 4 +- SpotifyAPI/Web/Models/Paging.cs | 4 +- SpotifyAPI/Web/Models/PrivateProfile.cs | 4 +- SpotifyAPI/Web/Models/PublicProfile.cs | 4 +- SpotifyAPI/Web/Models/SimpleAlbum.cs | 4 +- SpotifyAPI/Web/Models/SimpleArtist.cs | 4 +- SpotifyAPI/Web/Models/SimplePlaylist.cs | 4 +- SpotifyAPI/Web/Models/SimpleTrack.cs | 4 +- SpotifyAPI/Web/Models/Snapshot.cs | 4 +- SpotifyAPI/Web/Models/Token.cs | 4 +- SpotifyAPI/Web/SimpleHttpServer.cs | 21 +++---- SpotifyAPI/Web/SpotifyWebAPI.cs | 58 +++++++++---------- SpotifyAPI/Web/SpotifyWebClient.cs | 8 +-- SpotifyAPI/Web/Util.cs | 3 +- 40 files changed, 235 insertions(+), 156 deletions(-) diff --git a/SpotifyAPI/Local/LocalEvents.cs b/SpotifyAPI/Local/LocalEvents.cs index 8ec39ff4..b0e16d62 100644 --- a/SpotifyAPI/Local/LocalEvents.cs +++ b/SpotifyAPI/Local/LocalEvents.cs @@ -1,5 +1,5 @@ -using System; -using SpotifyAPI.Local.Models; +using SpotifyAPI.Local.Models; +using System; namespace SpotifyAPI.Local { @@ -11,6 +11,7 @@ namespace SpotifyAPI.Local public Track OldTrack { get; set; } public Track NewTrack { get; set; } } + /// /// Event gets triggered, when the Playin-state is changed (e.g Play --> Pause) /// @@ -18,6 +19,7 @@ namespace SpotifyAPI.Local { public Boolean Playing { get; set; } } + /// /// Event gets triggered, when the volume changes /// @@ -26,6 +28,7 @@ namespace SpotifyAPI.Local public double OldVolume { get; set; } public double NewVolume { get; set; } } + /// /// Event gets triggered, when the tracktime changes /// @@ -33,4 +36,4 @@ namespace SpotifyAPI.Local { public double TrackTime { get; set; } } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Local/Models/CFID.cs b/SpotifyAPI/Local/Models/CFID.cs index aaf33380..242f57d4 100644 --- a/SpotifyAPI/Local/Models/CFID.cs +++ b/SpotifyAPI/Local/Models/CFID.cs @@ -5,7 +5,7 @@ namespace SpotifyAPI.Local.Models /// /// JSON Response, used internaly /// - class Cfid + internal class Cfid { public Error Error { get; set; } public String Token { get; set; } @@ -17,9 +17,9 @@ namespace SpotifyAPI.Local.Models /// /// JSON Response, used internaly /// - class Error + internal class Error { public String Type { get; set; } public String Message { get; set; } } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Local/Models/OpenGraphState.cs b/SpotifyAPI/Local/Models/OpenGraphState.cs index 384aaa5e..8f9df2b5 100644 --- a/SpotifyAPI/Local/Models/OpenGraphState.cs +++ b/SpotifyAPI/Local/Models/OpenGraphState.cs @@ -1,5 +1,5 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace SpotifyAPI.Local.Models { @@ -7,6 +7,7 @@ namespace SpotifyAPI.Local.Models { [JsonProperty("private_session")] public Boolean PrivateSession { get; set; } + [JsonProperty("posting_disabled")] public Boolean PostingDisabled { get; set; } } diff --git a/SpotifyAPI/Local/Models/SpotifyResource.cs b/SpotifyAPI/Local/Models/SpotifyResource.cs index 97ef09e1..39d501a4 100644 --- a/SpotifyAPI/Local/Models/SpotifyResource.cs +++ b/SpotifyAPI/Local/Models/SpotifyResource.cs @@ -1,5 +1,5 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace SpotifyAPI.Local.Models { @@ -7,9 +7,11 @@ namespace SpotifyAPI.Local.Models { [JsonProperty("name")] public String Name { get; set; } + [JsonProperty("uri")] public String Uri { get; set; } + [JsonProperty("location")] public TrackResourceLocation Location { get; set; } } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Local/Models/StatusResponse.cs b/SpotifyAPI/Local/Models/StatusResponse.cs index 16a4467d..1e5ea455 100644 --- a/SpotifyAPI/Local/Models/StatusResponse.cs +++ b/SpotifyAPI/Local/Models/StatusResponse.cs @@ -6,31 +6,44 @@ namespace SpotifyAPI.Local.Models { [JsonProperty("version")] public int Version { get; set; } + [JsonProperty("client_version")] public string ClientVersion { get; set; } + [JsonProperty("playing")] public bool Playing { get; set; } + [JsonProperty("schuffle")] public bool Shuffle { get; set; } + [JsonProperty("repeat")] public bool Repeat { get; set; } + [JsonProperty("play_enabled")] public bool PlayEnabled { get; set; } + [JsonProperty("prev_enabled")] public bool PrevEnabled { get; set; } + [JsonProperty("next_enabled")] public bool NextEnabled { get; set; } + [JsonProperty("track")] public Track Track { get; set; } + [JsonProperty("playing_position")] public double PlayingPosition { get; set; } + [JsonProperty("server_time")] public int ServerTime { get; set; } + [JsonProperty("volume")] public double Volume { get; set; } + [JsonProperty("online")] public bool Online { get; set; } + [JsonProperty("running")] public bool Running { get; set; } } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Local/Models/Track.cs b/SpotifyAPI/Local/Models/Track.cs index 6b68cd1e..8c18ac0e 100644 --- a/SpotifyAPI/Local/Models/Track.cs +++ b/SpotifyAPI/Local/Models/Track.cs @@ -1,10 +1,10 @@ -using System; +using Newtonsoft.Json; +using SpotifyAPI.Local.Enums; +using System; using System.Drawing; using System.IO; using System.Net; using System.Threading.Tasks; -using Newtonsoft.Json; -using SpotifyAPI.Local.Enums; namespace SpotifyAPI.Local.Models { @@ -12,12 +12,16 @@ namespace SpotifyAPI.Local.Models { [JsonProperty("track_resource")] public SpotifyResource TrackResource { get; set; } + [JsonProperty("artist_resource")] public SpotifyResource ArtistResource { get; set; } + [JsonProperty("album_resource")] public SpotifyResource AlbumResource { get; set; } + [JsonProperty("length")] public int Length { get; set; } + [JsonProperty("track_type")] public string TrackType { get; set; } @@ -50,9 +54,11 @@ namespace SpotifyAPI.Local.Models case AlbumArtSize.Size160: albumsize = 160; break; + case AlbumArtSize.Size320: albumsize = 320; break; + case AlbumArtSize.Size640: albumsize = 640; break; @@ -152,4 +158,4 @@ namespace SpotifyAPI.Local.Models } } } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Local/Models/TrackResourceLocation.cs b/SpotifyAPI/Local/Models/TrackResourceLocation.cs index c0ed6a15..9008f0a9 100644 --- a/SpotifyAPI/Local/Models/TrackResourceLocation.cs +++ b/SpotifyAPI/Local/Models/TrackResourceLocation.cs @@ -1,5 +1,5 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace SpotifyAPI.Local.Models { diff --git a/SpotifyAPI/Local/RemoteHandler.cs b/SpotifyAPI/Local/RemoteHandler.cs index 42a8645c..c54608d8 100644 --- a/SpotifyAPI/Local/RemoteHandler.cs +++ b/SpotifyAPI/Local/RemoteHandler.cs @@ -1,10 +1,10 @@ -using System; +using Newtonsoft.Json; +using SpotifyAPI.Local.Models; +using System; using System.Collections.Generic; using System.Net; using System.Text; using System.Threading.Tasks; -using Newtonsoft.Json; -using SpotifyAPI.Local.Models; namespace SpotifyAPI.Local { @@ -145,7 +145,7 @@ namespace SpotifyAPI.Local parameters += "&returnon=login%2Clogout%2Cplay%2Cpause%2Cerror%2Cap"; } - string address = "http://" + Host + ":4380/" + request + parameters ; + string address = "http://" + Host + ":4380/" + request + parameters; string response = ""; try { @@ -168,4 +168,4 @@ namespace SpotifyAPI.Local return Convert.ToInt32((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds); } } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Local/SpotifyLocalAPI.cs b/SpotifyAPI/Local/SpotifyLocalAPI.cs index f2e5557f..5c599189 100644 --- a/SpotifyAPI/Local/SpotifyLocalAPI.cs +++ b/SpotifyAPI/Local/SpotifyLocalAPI.cs @@ -1,10 +1,10 @@ -using System; +using SpotifyAPI.Local.Models; +using System; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Timers; -using SpotifyAPI.Local.Models; namespace SpotifyAPI.Local { @@ -12,10 +12,12 @@ namespace SpotifyAPI.Local { [DllImport("user32.dll")] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo); + [DllImport("nircmd.dll", CharSet = CharSet.Auto)] private static extern bool DoNirCmd(String nirCmdStr); private bool _listenForEvents; + public bool ListenForEvents { get @@ -30,6 +32,7 @@ namespace SpotifyAPI.Local } private ISynchronizeInvoke _synchronizingObject; + public ISynchronizeInvoke SynchronizingObject { get @@ -43,22 +46,29 @@ namespace SpotifyAPI.Local } } - const byte VkMediaNextTrack = 0xb0; - const byte VkMediaPrevTrack = 0xb1; - const int KeyeventfExtendedkey = 0x1; - const int KeyeventfKeyup = 0x2; + private const byte VkMediaNextTrack = 0xb0; + private const byte VkMediaPrevTrack = 0xb1; + private const int KeyeventfExtendedkey = 0x1; + private const int KeyeventfKeyup = 0x2; - readonly RemoteHandler _rh; + private readonly RemoteHandler _rh; private readonly Timer _eventTimer; private StatusResponse _eventStatusResponse; public delegate void TrackChangeEventHandler(TrackChangeEventArgs e); + public delegate void PlayStateEventHandler(PlayStateEventArgs e); + public delegate void VolumeChangeEventHandler(VolumeChangeEventArgs e); + public delegate void TrackTimeChangeEventHandler(TrackTimeChangeEventArgs e); + public event TrackChangeEventHandler OnTrackChange; + public event PlayStateEventHandler OnPlayStateChange; + public event VolumeChangeEventHandler OnVolumeChange; + public event TrackTimeChangeEventHandler OnTrackTimeChange; public SpotifyLocalAPI() @@ -273,4 +283,4 @@ namespace SpotifyAPI.Local } } } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Properties/AssemblyInfo.cs b/SpotifyAPI/Properties/AssemblyInfo.cs index a56439af..5c4ae80d 100644 --- a/SpotifyAPI/Properties/AssemblyInfo.cs +++ b/SpotifyAPI/Properties/AssemblyInfo.cs @@ -1,8 +1,7 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// Allgemeine Informationen über eine Assembly werden über die folgenden +// Allgemeine Informationen über eine Assembly werden über die folgenden // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, // die mit einer Assembly verknüpft sind. [assembly: AssemblyTitle("SpotifyLocalAPIClass")] @@ -14,8 +13,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar -// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. [assembly: ComVisible(false)] @@ -25,12 +24,12 @@ using System.Runtime.InteropServices; // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: // // Hauptversion -// Nebenversion +// Nebenversion // Buildnummer // Revision // -// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // übernehmen, indem Sie "*" eingeben: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/SpotifyAPI/Web/Auth/AutorizationCodeAuth.cs b/SpotifyAPI/Web/Auth/AutorizationCodeAuth.cs index 5b0939b3..0be2c3ba 100644 --- a/SpotifyAPI/Web/Auth/AutorizationCodeAuth.cs +++ b/SpotifyAPI/Web/Auth/AutorizationCodeAuth.cs @@ -1,13 +1,13 @@ -using System; +using Newtonsoft.Json; +using SpotifyAPI.Web.Enums; +using SpotifyAPI.Web.Models; +using System; using System.Collections.Specialized; using System.Diagnostics; using System.IO; using System.Net; using System.Text; using System.Threading; -using Newtonsoft.Json; -using SpotifyAPI.Web.Enums; -using SpotifyAPI.Web.Models; namespace SpotifyAPI.Web.Auth { @@ -51,7 +51,7 @@ namespace SpotifyAPI.Web.Auth "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientId + ":" + clientSecret))); NameValueCollection col = new NameValueCollection { - {"grant_type", "refresh_token"}, + {"grant_type", "refresh_token"}, {"refresh_token", refreshToken} }; diff --git a/SpotifyAPI/Web/Auth/ClientCredentialsAuth.cs b/SpotifyAPI/Web/Auth/ClientCredentialsAuth.cs index 66ed60bf..27a3a6b9 100644 --- a/SpotifyAPI/Web/Auth/ClientCredentialsAuth.cs +++ b/SpotifyAPI/Web/Auth/ClientCredentialsAuth.cs @@ -1,11 +1,11 @@ -using System; +using Newtonsoft.Json; +using SpotifyAPI.Web.Enums; +using SpotifyAPI.Web.Models; +using System; using System.Collections.Specialized; using System.IO; using System.Net; using System.Text; -using Newtonsoft.Json; -using SpotifyAPI.Web.Enums; -using SpotifyAPI.Web.Models; namespace SpotifyAPI.Web.Auth { diff --git a/SpotifyAPI/Web/Auth/ImplicitGrantAuth.cs b/SpotifyAPI/Web/Auth/ImplicitGrantAuth.cs index e485d662..922a9d68 100644 --- a/SpotifyAPI/Web/Auth/ImplicitGrantAuth.cs +++ b/SpotifyAPI/Web/Auth/ImplicitGrantAuth.cs @@ -1,9 +1,9 @@ -using System; +using SpotifyAPI.Web.Enums; +using SpotifyAPI.Web.Models; +using System; using System.Diagnostics; using System.Text; using System.Threading; -using SpotifyAPI.Web.Enums; -using SpotifyAPI.Web.Models; namespace SpotifyAPI.Web.Auth { @@ -18,6 +18,7 @@ namespace SpotifyAPI.Web.Auth public String State { get; set; } public Scope Scope { get; set; } public Boolean ShowDialog { get; set; } + public event OnResponseReceived OnResponseReceivedEvent; /// @@ -74,4 +75,4 @@ namespace SpotifyAPI.Web.Auth _httpServer = null; } } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Web/Enums/AlbumType.cs b/SpotifyAPI/Web/Enums/AlbumType.cs index 4b308052..c05df333 100644 --- a/SpotifyAPI/Web/Enums/AlbumType.cs +++ b/SpotifyAPI/Web/Enums/AlbumType.cs @@ -5,10 +5,19 @@ namespace SpotifyAPI.Web.Enums [Flags] public enum AlbumType { - [String("album")] Album = 1, - [String("single")] Single = 2, - [String("compilation")] Compilation = 4, - [String("appears_on")] AppearsOn = 8, - [String("album,single,compilation,appears_on")] All = 16 + [String("album")] + Album = 1, + + [String("single")] + Single = 2, + + [String("compilation")] + Compilation = 4, + + [String("appears_on")] + AppearsOn = 8, + + [String("album,single,compilation,appears_on")] + All = 16 } } \ No newline at end of file diff --git a/SpotifyAPI/Web/Enums/FollowType.cs b/SpotifyAPI/Web/Enums/FollowType.cs index d0fa2e10..6cd802bc 100644 --- a/SpotifyAPI/Web/Enums/FollowType.cs +++ b/SpotifyAPI/Web/Enums/FollowType.cs @@ -5,7 +5,10 @@ namespace SpotifyAPI.Web.Enums [Flags] public enum FollowType { - [String("artist")] Artist = 1, - [String("user")] User = 2 + [String("artist")] + Artist = 1, + + [String("user")] + User = 2 } } \ No newline at end of file diff --git a/SpotifyAPI/Web/Enums/Scope.cs b/SpotifyAPI/Web/Enums/Scope.cs index 1410f496..0240450a 100644 --- a/SpotifyAPI/Web/Enums/Scope.cs +++ b/SpotifyAPI/Web/Enums/Scope.cs @@ -5,17 +5,40 @@ namespace SpotifyAPI.Web.Enums [Flags] public enum Scope { - [String("")] None = 1, - [String("playlist-modify-public")] PlaylistModifyPublic = 2, - [String("playlist-modify-private")] PlaylistModifyPrivate = 4, - [String("playlist-read-private")] PlaylistReadPrivate = 8, - [String("streaming")] Streaming = 16, - [String("user-read-private")] UserReadPrivate = 32, - [String("user-read-email")] UserReadEmail = 64, - [String("user-library-read")] UserLibrarayRead = 128, - [String("user-library-modify")] UserLibraryModify = 256, - [String("user-follow-modify")] UserFollowModify = 512, - [String("user-follow-read")] UserFollowRead = 1024, - [String("user-read-birthdate")] UserReadBirthdate = 2048 + [String("")] + None = 1, + + [String("playlist-modify-public")] + PlaylistModifyPublic = 2, + + [String("playlist-modify-private")] + PlaylistModifyPrivate = 4, + + [String("playlist-read-private")] + PlaylistReadPrivate = 8, + + [String("streaming")] + Streaming = 16, + + [String("user-read-private")] + UserReadPrivate = 32, + + [String("user-read-email")] + UserReadEmail = 64, + + [String("user-library-read")] + UserLibrarayRead = 128, + + [String("user-library-modify")] + UserLibraryModify = 256, + + [String("user-follow-modify")] + UserFollowModify = 512, + + [String("user-follow-read")] + UserFollowRead = 1024, + + [String("user-read-birthdate")] + UserReadBirthdate = 2048 } } \ No newline at end of file diff --git a/SpotifyAPI/Web/Enums/SearchType.cs b/SpotifyAPI/Web/Enums/SearchType.cs index c2fae029..d40c0e19 100644 --- a/SpotifyAPI/Web/Enums/SearchType.cs +++ b/SpotifyAPI/Web/Enums/SearchType.cs @@ -5,9 +5,16 @@ namespace SpotifyAPI.Web.Enums [Flags] public enum SearchType { - [String("artist")] Artist = 1, - [String("album")] Album = 2, - [String("track")] Track = 4, - [String("track,album,artist")] All = 8 + [String("artist")] + Artist = 1, + + [String("album")] + Album = 2, + + [String("track")] + Track = 4, + + [String("track,album,artist")] + All = 8 } } \ No newline at end of file diff --git a/SpotifyAPI/Web/IClient.cs b/SpotifyAPI/Web/IClient.cs index 4ba8b94e..1ab1ae36 100644 --- a/SpotifyAPI/Web/IClient.cs +++ b/SpotifyAPI/Web/IClient.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web { diff --git a/SpotifyAPI/Web/Models/BasicModel.cs b/SpotifyAPI/Web/Models/BasicModel.cs index 8fd97d29..bb968613 100644 --- a/SpotifyAPI/Web/Models/BasicModel.cs +++ b/SpotifyAPI/Web/Models/BasicModel.cs @@ -1,5 +1,5 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/Category.cs b/SpotifyAPI/Web/Models/Category.cs index 0c94efc2..a3322fcd 100644 --- a/SpotifyAPI/Web/Models/Category.cs +++ b/SpotifyAPI/Web/Models/Category.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/CursorPaging.cs b/SpotifyAPI/Web/Models/CursorPaging.cs index 5d7452d9..dc4060d5 100644 --- a/SpotifyAPI/Web/Models/CursorPaging.cs +++ b/SpotifyAPI/Web/Models/CursorPaging.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/FeaturedPlaylists.cs b/SpotifyAPI/Web/Models/FeaturedPlaylists.cs index 88b7939b..016a4ad0 100644 --- a/SpotifyAPI/Web/Models/FeaturedPlaylists.cs +++ b/SpotifyAPI/Web/Models/FeaturedPlaylists.cs @@ -1,5 +1,5 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/FullAlbum.cs b/SpotifyAPI/Web/Models/FullAlbum.cs index 1df3e4a7..bd566bd2 100644 --- a/SpotifyAPI/Web/Models/FullAlbum.cs +++ b/SpotifyAPI/Web/Models/FullAlbum.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/FullArtist.cs b/SpotifyAPI/Web/Models/FullArtist.cs index b1982cbf..72eb586b 100644 --- a/SpotifyAPI/Web/Models/FullArtist.cs +++ b/SpotifyAPI/Web/Models/FullArtist.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/FullPlaylist.cs b/SpotifyAPI/Web/Models/FullPlaylist.cs index 14e0ac95..f6bf1de8 100644 --- a/SpotifyAPI/Web/Models/FullPlaylist.cs +++ b/SpotifyAPI/Web/Models/FullPlaylist.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/FullTrack.cs b/SpotifyAPI/Web/Models/FullTrack.cs index be76d17b..bbb713b2 100644 --- a/SpotifyAPI/Web/Models/FullTrack.cs +++ b/SpotifyAPI/Web/Models/FullTrack.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/GeneralModels.cs b/SpotifyAPI/Web/Models/GeneralModels.cs index 89dbe60d..bccfae85 100644 --- a/SpotifyAPI/Web/Models/GeneralModels.cs +++ b/SpotifyAPI/Web/Models/GeneralModels.cs @@ -1,7 +1,7 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/Paging.cs b/SpotifyAPI/Web/Models/Paging.cs index db25fb8d..d40a426e 100644 --- a/SpotifyAPI/Web/Models/Paging.cs +++ b/SpotifyAPI/Web/Models/Paging.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/PrivateProfile.cs b/SpotifyAPI/Web/Models/PrivateProfile.cs index 87349d60..09357c20 100644 --- a/SpotifyAPI/Web/Models/PrivateProfile.cs +++ b/SpotifyAPI/Web/Models/PrivateProfile.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/PublicProfile.cs b/SpotifyAPI/Web/Models/PublicProfile.cs index 098a99ef..93e0459d 100644 --- a/SpotifyAPI/Web/Models/PublicProfile.cs +++ b/SpotifyAPI/Web/Models/PublicProfile.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/SimpleAlbum.cs b/SpotifyAPI/Web/Models/SimpleAlbum.cs index 8f0f292f..e9dfbbf3 100644 --- a/SpotifyAPI/Web/Models/SimpleAlbum.cs +++ b/SpotifyAPI/Web/Models/SimpleAlbum.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/SimpleArtist.cs b/SpotifyAPI/Web/Models/SimpleArtist.cs index f20a0e0c..a368c66a 100644 --- a/SpotifyAPI/Web/Models/SimpleArtist.cs +++ b/SpotifyAPI/Web/Models/SimpleArtist.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/SimplePlaylist.cs b/SpotifyAPI/Web/Models/SimplePlaylist.cs index f6e9f497..1bb2f7cc 100644 --- a/SpotifyAPI/Web/Models/SimplePlaylist.cs +++ b/SpotifyAPI/Web/Models/SimplePlaylist.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/SimpleTrack.cs b/SpotifyAPI/Web/Models/SimpleTrack.cs index 2c78c6a0..7726db4d 100644 --- a/SpotifyAPI/Web/Models/SimpleTrack.cs +++ b/SpotifyAPI/Web/Models/SimpleTrack.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/Snapshot.cs b/SpotifyAPI/Web/Models/Snapshot.cs index 798a4e82..4c54887d 100644 --- a/SpotifyAPI/Web/Models/Snapshot.cs +++ b/SpotifyAPI/Web/Models/Snapshot.cs @@ -1,5 +1,5 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/Models/Token.cs b/SpotifyAPI/Web/Models/Token.cs index e6bf4ee1..8179147f 100644 --- a/SpotifyAPI/Web/Models/Token.cs +++ b/SpotifyAPI/Web/Models/Token.cs @@ -1,5 +1,5 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace SpotifyAPI.Web.Models { diff --git a/SpotifyAPI/Web/SimpleHttpServer.cs b/SpotifyAPI/Web/SimpleHttpServer.cs index b67981c4..8c7d41fc 100644 --- a/SpotifyAPI/Web/SimpleHttpServer.cs +++ b/SpotifyAPI/Web/SimpleHttpServer.cs @@ -8,7 +8,7 @@ using System.Threading; using System.Web; // offered to the public domain for any use with no restriction -// and also with no warranty of any kind, please enjoy. - David Jeske. +// and also with no warranty of any kind, please enjoy. - David Jeske. // simple HTTP explanation // http://www.jmarshall.com/easy/http/ @@ -17,7 +17,7 @@ namespace SpotifyAPI.Web { public class HttpProcessor { - private const int MaxPostSize = 10*1024*1024; // 10MB + private const int MaxPostSize = 10 * 1024 * 1024; // 10MB private const int BufSize = 4096; private readonly TcpClient _socket; private readonly HttpServer _srv; @@ -85,7 +85,7 @@ namespace SpotifyAPI.Web } OutputStream.Flush(); _inputStream = null; - OutputStream = null; + OutputStream = null; _socket.Close(); } @@ -137,9 +137,9 @@ namespace SpotifyAPI.Web { // this post data processing just reads everything into a memory stream. // this is fine for smallish things, but for large stuff we should really - // hand an input stream to the request processor. However, the input stream - // we hand him needs to let him see the "end of the stream" at this content - // length, because otherwise he won't know when he's seen it all! + // hand an input stream to the request processor. However, the input stream + // we hand him needs to let him see the "end of the stream" at this content + // length, because otherwise he won't know when he's seen it all! MemoryStream ms = new MemoryStream(); if (HttpHeaders.ContainsKey("Content-Length")) @@ -147,7 +147,7 @@ namespace SpotifyAPI.Web var contentLen = Convert.ToInt32(HttpHeaders["Content-Length"]); if (contentLen > MaxPostSize) { - throw new Exception(String.Format("POST Content-Length({0}) too big for this simple server", contentLen)); + throw new Exception(String.Format("POST Content-Length({0}) too big for this simple server", contentLen)); } byte[] buf = new byte[BufSize]; int toRead = contentLen; @@ -230,6 +230,7 @@ namespace SpotifyAPI.Web } public abstract void HandleGetRequest(HttpProcessor p); + public abstract void HandlePostRequest(HttpProcessor p, StreamReader inputData); } @@ -237,6 +238,7 @@ namespace SpotifyAPI.Web { //Code can be an AccessToken or an Exchange Code public String Code { get; set; } + public String TokenType { get; set; } public String State { get; set; } public String Error { get; set; } @@ -262,7 +264,6 @@ namespace SpotifyAPI.Web if (p.HttpUrl == "/favicon.ico") return; - Thread t; if (_type == AuthType.Authorization) { @@ -274,7 +275,7 @@ namespace SpotifyAPI.Web p.OutputStream.WriteLine("

Spotify Auth canceled!

"); t = new Thread(o => { - if(OnAuth != null) + if (OnAuth != null) OnAuth(new AuthEventArgs() { State = col.Get(1), @@ -287,7 +288,7 @@ namespace SpotifyAPI.Web p.OutputStream.WriteLine("

Spotify Auth successful!

"); t = new Thread(o => { - if(OnAuth != null) + if (OnAuth != null) OnAuth(new AuthEventArgs() { Code = col.Get(0), diff --git a/SpotifyAPI/Web/SpotifyWebAPI.cs b/SpotifyAPI/Web/SpotifyWebAPI.cs index 2db4f654..84a9e9bc 100644 --- a/SpotifyAPI/Web/SpotifyWebAPI.cs +++ b/SpotifyAPI/Web/SpotifyWebAPI.cs @@ -1,11 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SpotifyAPI.Web.Enums; using SpotifyAPI.Web.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; namespace SpotifyAPI.Web { @@ -62,7 +62,7 @@ namespace SpotifyAPI.Web return DownloadData(builder.ToString()); } - #endregion + #endregion Search #region Albums @@ -112,7 +112,7 @@ namespace SpotifyAPI.Web return DownloadData(APIBase + "/albums?market=" + market + "&ids=" + string.Join(",", ids.Take(20))); } - #endregion + #endregion Albums #region Artists @@ -186,7 +186,7 @@ namespace SpotifyAPI.Web return DownloadData(APIBase + "/artists?ids=" + string.Join(",", ids.Take(50))); } - #endregion + #endregion Artists #region Browse @@ -314,7 +314,7 @@ namespace SpotifyAPI.Web return DownloadData(builder.ToString()); } - #endregion + #endregion Browse #region Follow @@ -327,7 +327,7 @@ namespace SpotifyAPI.Web /// AUTH NEEDED public FollowedArtists GetFollowedArtists(int limit = 20, String after = "") { - if(!UseAuth) + if (!UseAuth) throw new InvalidOperationException("Auth is required for GetFollowedArtists"); limit = Math.Max(limit, 50); const FollowType followType = FollowType.Artist; //currently only artist is supported. @@ -363,7 +363,7 @@ namespace SpotifyAPI.Web /// AUTH NEEDED public ErrorResponse Follow(FollowType followType, String id) { - return Follow(followType, new List {id}); + return Follow(followType, new List { id }); } /// @@ -391,7 +391,7 @@ namespace SpotifyAPI.Web /// AUTH NEEDED public ErrorResponse Unfollow(FollowType followType, String id) { - return Unfollow(followType, new List {id}); + return Unfollow(followType, new List { id }); } /// @@ -407,8 +407,8 @@ namespace SpotifyAPI.Web throw new InvalidOperationException("Auth is required for IsFollowing"); JToken res = DownloadData(APIBase + "/me/following/contains?type=" + followType.GetStringAttribute("") + "&ids=" + string.Join(",", ids)); if (res is JArray) - return new ListResponse {List = res.ToObject>(), Error = null}; - return new ListResponse {List = null, Error = res["error"].ToObject()}; + return new ListResponse { List = res.ToObject>(), Error = null }; + return new ListResponse { List = null, Error = res["error"].ToObject() }; } /// @@ -420,7 +420,7 @@ namespace SpotifyAPI.Web /// AUTH NEEDED public ListResponse IsFollowing(FollowType followType, String id) { - return IsFollowing(followType, new List {id}); + return IsFollowing(followType, new List { id }); } /// @@ -472,8 +472,8 @@ namespace SpotifyAPI.Web throw new InvalidOperationException("Auth is required for IsFollowingPlaylist"); JToken res = DownloadData(APIBase + "/users/" + ownerId + "/playlists/" + playlistId + "/followers/contains?ids=" + string.Join(",", ids)); if (res is JArray) - return new ListResponse {List = res.ToObject>(), Error = null}; - return new ListResponse {List = null, Error = res["error"].ToObject()}; + return new ListResponse { List = res.ToObject>(), Error = null }; + return new ListResponse { List = null, Error = res["error"].ToObject() }; } /// @@ -486,10 +486,10 @@ namespace SpotifyAPI.Web /// AUTH NEEDED public ListResponse IsFollowingPlaylist(String ownerId, String playlistId, String id) { - return IsFollowingPlaylist(ownerId, playlistId, new List {id}); + return IsFollowingPlaylist(ownerId, playlistId, new List { id }); } - #endregion + #endregion Follow #region Library @@ -513,7 +513,7 @@ namespace SpotifyAPI.Web /// AUTH NEEDED public ErrorResponse SaveTrack(String id) { - return SaveTracks(new List {id}); + return SaveTracks(new List { id }); } /// @@ -561,11 +561,11 @@ namespace SpotifyAPI.Web throw new InvalidOperationException("Auth is required for CheckSavedTracks"); JToken res = DownloadData(APIBase + "/me/tracks/contains?ids=" + string.Join(",", ids)); if (res is JArray) - return new ListResponse {List = res.ToObject>(), Error = null}; - return new ListResponse {List = null, Error = res["error"].ToObject()}; + return new ListResponse { List = res.ToObject>(), Error = null }; + return new ListResponse { List = null, Error = res["error"].ToObject() }; } - #endregion + #endregion Library #region Playlists @@ -730,7 +730,7 @@ namespace SpotifyAPI.Web /// AUTH NEEDED public ErrorResponse RemovePlaylistTrack(String userId, String playlistId, DeleteTrackUri uri) { - return RemovePlaylistTracks(userId, playlistId, new List {uri}); + return RemovePlaylistTracks(userId, playlistId, new List { uri }); } /// @@ -764,7 +764,7 @@ namespace SpotifyAPI.Web /// AUTH NEEDED public ErrorResponse AddPlaylistTrack(String userId, String playlistId, String uri, int? position = null) { - return AddPlaylistTracks(userId, playlistId, new List {uri}, position); + return AddPlaylistTracks(userId, playlistId, new List { uri }, position); } /// @@ -791,7 +791,7 @@ namespace SpotifyAPI.Web return UploadData(APIBase + "/users/" + userId + "/playlists/" + playlistId + "/tracks", body.ToString(Formatting.None), "PUT"); } - #endregion + #endregion Playlists #region Profiles @@ -817,7 +817,7 @@ namespace SpotifyAPI.Web return DownloadData(APIBase + "/users/" + userId); } - #endregion + #endregion Profiles #region Tracks @@ -847,7 +847,7 @@ namespace SpotifyAPI.Web return DownloadData(APIBase + "/tracks/" + id + "?market=" + market); } - #endregion + #endregion Tracks #region Util @@ -869,6 +869,6 @@ namespace SpotifyAPI.Web return WebClient.DownloadJson(url); } - #endregion + #endregion Util } } \ No newline at end of file diff --git a/SpotifyAPI/Web/SpotifyWebClient.cs b/SpotifyAPI/Web/SpotifyWebClient.cs index d0a6c4b3..ea9769d7 100644 --- a/SpotifyAPI/Web/SpotifyWebClient.cs +++ b/SpotifyAPI/Web/SpotifyWebClient.cs @@ -1,10 +1,10 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; -using Newtonsoft.Json; namespace SpotifyAPI.Web { @@ -46,7 +46,7 @@ namespace SpotifyAPI.Web return response; } - public byte[] DownloadRaw(string url) + public byte[] DownloadRaw(string url) { return _webClient.DownloadData(url); } @@ -93,7 +93,7 @@ namespace SpotifyAPI.Web public void RemoveHeader(string header) { - if(_webClient.Headers[header] != null) + if (_webClient.Headers[header] != null) _webClient.Headers.Remove(header); } diff --git a/SpotifyAPI/Web/Util.cs b/SpotifyAPI/Web/Util.cs index 7c3f4548..ed01516a 100644 --- a/SpotifyAPI/Web/Util.cs +++ b/SpotifyAPI/Web/Util.cs @@ -27,9 +27,10 @@ namespace SpotifyAPI.Web public sealed class StringAttribute : Attribute { public String Text { get; set; } + public StringAttribute(String text) { Text = text; } } -} +} \ No newline at end of file From 53ff4324258e25d035a8ea349e9c94c9abb048f8 Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Sat, 17 Oct 2015 11:55:27 +0200 Subject: [PATCH 5/9] Removed nircmd.exe Changed Mute and UnMute function to work with both x86 and x64 processes on Windows 7 or newer Added functions to manipulate the Volume Control of Spotify --- SpotifyAPI/Local/SpotifyLocalAPI.cs | 67 ++++++- SpotifyAPI/Local/VolumeMixerControl.cs | 250 +++++++++++++++++++++++++ SpotifyAPI/SpotifyAPI.csproj | 1 + 3 files changed, 309 insertions(+), 9 deletions(-) create mode 100644 SpotifyAPI/Local/VolumeMixerControl.cs diff --git a/SpotifyAPI/Local/SpotifyLocalAPI.cs b/SpotifyAPI/Local/SpotifyLocalAPI.cs index 5c599189..383b582f 100644 --- a/SpotifyAPI/Local/SpotifyLocalAPI.cs +++ b/SpotifyAPI/Local/SpotifyLocalAPI.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.Contracts; using System.IO; using System.Runtime.InteropServices; using System.Timers; @@ -13,9 +14,6 @@ namespace SpotifyAPI.Local [DllImport("user32.dll")] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo); - [DllImport("nircmd.dll", CharSet = CharSet.Auto)] - private static extern bool DoNirCmd(String nirCmdStr); - private bool _listenForEvents; public bool ListenForEvents @@ -159,21 +157,72 @@ namespace SpotifyAPI.Local } /// - /// Mutes Spotify (Requires nircmd.dll) + /// Mutes Spotify (Requires Windows 7 or newer) /// public void Mute() { - if (File.Exists("nircmd.dll")) - DoNirCmd("muteappvolume spotify.exe 1"); + //Windows < Windows Vista Check + Contract.Requires(Environment.OSVersion.Version.Major >= 6); + //Windows Vista Check + if (Environment.OSVersion.Version.Major == 6) + Contract.Requires(Environment.OSVersion.Version.Minor != 0); + VolumeMixerControl.MuteSpotify(true); } /// - /// Unmutes Spotify (Requires nircmd.dll) + /// Unmutes Spotify (Requires Windows 7 or newer) /// public void UnMute() { - if (File.Exists("nircmd.dll")) - DoNirCmd("muteappvolume spotify.exe 0"); + //Windows < Windows Vista Check + Contract.Requires(Environment.OSVersion.Version.Major >= 6); + //Windows Vista Check + if (Environment.OSVersion.Version.Major == 6) + Contract.Requires(Environment.OSVersion.Version.Minor != 0); + VolumeMixerControl.MuteSpotify(false); + } + + /// + /// Checks whether Spotify is muted in the Volume Mixer control + /// + /// Null if an error occured, otherwise the muted state + public bool? IsSpotifyMuted() + { + //Windows < Windows Vista Check + Contract.Requires(Environment.OSVersion.Version.Major >= 6); + //Windows Vista Check + if (Environment.OSVersion.Version.Major == 6) + Contract.Requires(Environment.OSVersion.Version.Minor != 0); + return VolumeMixerControl.IsSpotifyMuted(); + } + + /// + /// Sets the Volume Mixer volume (requires Windows 7 or newer) + /// + /// A Value between 0 and 100 + public void SetSpotifyVolume(float volume = 100) + { + Contract.Requires(0 <= volume && volume <= 100); + //Windows < Windows Vista Check + Contract.Requires(Environment.OSVersion.Version.Major >= 6); + //Windows Vista Check + if (Environment.OSVersion.Version.Major == 6) + Contract.Requires(Environment.OSVersion.Version.Minor != 0); + VolumeMixerControl.SetSpotifyVolume(volume); + } + + /// + /// Return the Volume Mixer volume of Spotify (requires Windows 7 or newer) + /// + /// Null if an error occured, otherwise a float between 0 and 100 + public float? GetSpotifyVolume() + { + //Windows < Windows Vista Check + Contract.Requires(Environment.OSVersion.Version.Major >= 6); + //Windows Vista Check + if (Environment.OSVersion.Version.Major == 6) + Contract.Requires(Environment.OSVersion.Version.Minor != 0); + return VolumeMixerControl.GetSpotifyVolume(); } /// diff --git a/SpotifyAPI/Local/VolumeMixerControl.cs b/SpotifyAPI/Local/VolumeMixerControl.cs new file mode 100644 index 00000000..29247818 --- /dev/null +++ b/SpotifyAPI/Local/VolumeMixerControl.cs @@ -0,0 +1,250 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace SpotifyAPI.Local +{ + internal class VolumeMixerControl + { + private const String SPOTIFY_PROCESS_NAME = "spotify"; + + internal static float? GetSpotifyVolume() + { + Process[] p = Process.GetProcessesByName(SPOTIFY_PROCESS_NAME); + if (p.Length == 0) + return null; + + int pid = p[0].Id; + + ISimpleAudioVolume volume = GetVolumeObject(pid); + if (volume == null) + return null; + + float level; + volume.GetMasterVolume(out level); + Marshal.ReleaseComObject(volume); + return level * 100; + } + + internal static bool? IsSpotifyMuted() + { + Process[] p = Process.GetProcessesByName(SPOTIFY_PROCESS_NAME); + if (p.Length == 0) + return null; + + int pid = p[0].Id; + + ISimpleAudioVolume volume = GetVolumeObject(pid); + if (volume == null) + return null; + + bool mute; + volume.GetMute(out mute); + Marshal.ReleaseComObject(volume); + return mute; + } + + internal static void SetSpotifyVolume(float level) + { + Process[] p = Process.GetProcessesByName(SPOTIFY_PROCESS_NAME); + if (p.Length == 0) + return; + + int pid = p[0].Id; + + ISimpleAudioVolume volume = GetVolumeObject(pid); + if (volume == null) + return; + + Guid guid = Guid.Empty; + volume.SetMasterVolume(level / 100, ref guid); + Marshal.ReleaseComObject(volume); + } + + internal static void MuteSpotify(bool mute) + { + Process[] p = Process.GetProcessesByName(SPOTIFY_PROCESS_NAME); + if (p.Length == 0) + return; + + int pid = p[0].Id; + + ISimpleAudioVolume volume = GetVolumeObject(pid); + if (volume == null) + return; + + Guid guid = Guid.Empty; + volume.SetMute(mute, ref guid); + Marshal.ReleaseComObject(volume); + } + + private static ISimpleAudioVolume GetVolumeObject(int pid) + { + // get the speakers (1st render + multimedia) device + IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator()); + IMMDevice speakers; + deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers); + + // activate the session manager. we need the enumerator + Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID; + object o; + speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out o); + IAudioSessionManager2 mgr = (IAudioSessionManager2)o; + + // enumerate sessions for on this device + IAudioSessionEnumerator sessionEnumerator; + mgr.GetSessionEnumerator(out sessionEnumerator); + int count; + sessionEnumerator.GetCount(out count); + + // search for an audio session with the required name + // NOTE: we could also use the process id instead of the app name (with IAudioSessionControl2) + ISimpleAudioVolume volumeControl = null; + for (int i = 0; i < count; i++) + { + IAudioSessionControl2 ctl; + sessionEnumerator.GetSession(i, out ctl); + int cpid; + ctl.GetProcessId(out cpid); + + if (cpid == pid) + { + volumeControl = ctl as ISimpleAudioVolume; + break; + } + Marshal.ReleaseComObject(ctl); + } + Marshal.ReleaseComObject(sessionEnumerator); + Marshal.ReleaseComObject(mgr); + Marshal.ReleaseComObject(speakers); + Marshal.ReleaseComObject(deviceEnumerator); + return volumeControl; + } + + + [ComImport] + [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] + private class MMDeviceEnumerator + { + } + + private enum EDataFlow + { + eRender, + eCapture, + eAll, + EDataFlow_enum_count + } + + private enum ERole + { + eConsole, + eMultimedia, + eCommunications, + ERole_enum_count + } + + [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + private interface IMMDeviceEnumerator + { + int NotImpl1(); + + [PreserveSig] + int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice); + } + + [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + private interface IMMDevice + { + [PreserveSig] + int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface); + + } + + [Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + private interface IAudioSessionManager2 + { + int NotImpl1(); + int NotImpl2(); + + [PreserveSig] + int GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum); + } + + [Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + private interface IAudioSessionEnumerator + { + [PreserveSig] + int GetCount(out int SessionCount); + + [PreserveSig] + int GetSession(int SessionCount, out IAudioSessionControl2 Session); + } + + [Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + private interface ISimpleAudioVolume + { + [PreserveSig] + int SetMasterVolume(float fLevel, ref Guid EventContext); + + [PreserveSig] + int GetMasterVolume(out float pfLevel); + + [PreserveSig] + int SetMute(bool bMute, ref Guid EventContext); + + [PreserveSig] + int GetMute(out bool pbMute); + } + + [Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + private interface IAudioSessionControl2 + { + [PreserveSig] + int NotImpl0(); + + [PreserveSig] + int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal); + + [PreserveSig] + int SetDisplayName([MarshalAs(UnmanagedType.LPWStr)]string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext); + + [PreserveSig] + int GetIconPath([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal); + + [PreserveSig] + int SetIconPath([MarshalAs(UnmanagedType.LPWStr)] string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext); + + [PreserveSig] + int GetGroupingParam(out Guid pRetVal); + + [PreserveSig] + int SetGroupingParam([MarshalAs(UnmanagedType.LPStruct)] Guid Override, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext); + + [PreserveSig] + int NotImpl1(); + + [PreserveSig] + int NotImpl2(); + + [PreserveSig] + int GetSessionIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal); + + [PreserveSig] + int GetSessionInstanceIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal); + + [PreserveSig] + int GetProcessId(out int pRetVal); + + [PreserveSig] + int IsSystemSoundsSession(); + + [PreserveSig] + int SetDuckingPreference(bool optOut); + } + } +} diff --git a/SpotifyAPI/SpotifyAPI.csproj b/SpotifyAPI/SpotifyAPI.csproj index de89e8af..faaaafb5 100644 --- a/SpotifyAPI/SpotifyAPI.csproj +++ b/SpotifyAPI/SpotifyAPI.csproj @@ -56,6 +56,7 @@ Component + From d5635f060ea125763478107c9b723c44ca7250fd Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Sat, 17 Oct 2015 11:57:26 +0200 Subject: [PATCH 6/9] Improved readability with codemaid in VolumMixerControl.cs --- SpotifyAPI/Local/VolumeMixerControl.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/SpotifyAPI/Local/VolumeMixerControl.cs b/SpotifyAPI/Local/VolumeMixerControl.cs index 29247818..f0613298 100644 --- a/SpotifyAPI/Local/VolumeMixerControl.cs +++ b/SpotifyAPI/Local/VolumeMixerControl.cs @@ -1,10 +1,6 @@ using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; namespace SpotifyAPI.Local { @@ -125,7 +121,6 @@ namespace SpotifyAPI.Local return volumeControl; } - [ComImport] [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] private class MMDeviceEnumerator @@ -162,13 +157,13 @@ namespace SpotifyAPI.Local { [PreserveSig] int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface); - } [Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IAudioSessionManager2 { int NotImpl1(); + int NotImpl2(); [PreserveSig] @@ -247,4 +242,4 @@ namespace SpotifyAPI.Local int SetDuckingPreference(bool optOut); } } -} +} \ No newline at end of file From 4f83ac068f19a8a5025fc6c69d7553edddd84f40 Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Sat, 17 Oct 2015 11:58:38 +0200 Subject: [PATCH 7/9] Updated documentation for new functions --- SpotifyAPI/Local/SpotifyLocalAPI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SpotifyAPI/Local/SpotifyLocalAPI.cs b/SpotifyAPI/Local/SpotifyLocalAPI.cs index 383b582f..a09c8b0d 100644 --- a/SpotifyAPI/Local/SpotifyLocalAPI.cs +++ b/SpotifyAPI/Local/SpotifyLocalAPI.cs @@ -183,7 +183,7 @@ namespace SpotifyAPI.Local } /// - /// Checks whether Spotify is muted in the Volume Mixer control + /// Checks whether Spotify is muted in the Volume Mixer control (required Windows 7 or newer) /// /// Null if an error occured, otherwise the muted state public bool? IsSpotifyMuted() From e5e57c3020e74d2e098642a96ff498a27a0ca38a Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Wed, 21 Oct 2015 13:18:57 +0200 Subject: [PATCH 8/9] Removed infinite loop in dispose call Imporved spelling in new commits --- SpotifyAPI/Local/SpotifyLocalAPI.cs | 2 +- SpotifyAPI/Web/SimpleHttpServer.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/SpotifyAPI/Local/SpotifyLocalAPI.cs b/SpotifyAPI/Local/SpotifyLocalAPI.cs index a09c8b0d..ac2f32ef 100644 --- a/SpotifyAPI/Local/SpotifyLocalAPI.cs +++ b/SpotifyAPI/Local/SpotifyLocalAPI.cs @@ -199,7 +199,7 @@ namespace SpotifyAPI.Local /// /// Sets the Volume Mixer volume (requires Windows 7 or newer) /// - /// A Value between 0 and 100 + /// A value between 0 and 100 public void SetSpotifyVolume(float volume = 100) { Contract.Requires(0 <= volume && volume <= 100); diff --git a/SpotifyAPI/Web/SimpleHttpServer.cs b/SpotifyAPI/Web/SimpleHttpServer.cs index 8c7d41fc..7dcc7a20 100644 --- a/SpotifyAPI/Web/SimpleHttpServer.cs +++ b/SpotifyAPI/Web/SimpleHttpServer.cs @@ -203,7 +203,6 @@ namespace SpotifyAPI.Web { IsActive = false; _listener.Stop(); - Dispose(); GC.SuppressFinalize(this); } From 3544c34176c02c7173df2d736413b884a072ba07 Mon Sep 17 00:00:00 2001 From: mrnikbobjeff Date: Fri, 23 Oct 2015 21:25:13 +0200 Subject: [PATCH 9/9] Changed Contracts to if-throw-else as requested Changed use of nullable return types to throw exceptions instead of returning null --- SpotifyAPI.Example/App.config | 6 +-- SpotifyAPI.Example/ExampleForm.cs | 2 +- SpotifyAPI.Example/LocalControl.cs | 22 +++++------ SpotifyAPI.Example/Program.cs | 9 ++--- SpotifyAPI.Example/Properties/AssemblyInfo.cs | 13 +++---- SpotifyAPI.Example/WebControl.cs | 19 +++++----- SpotifyAPI.Tests/Properties/AssemblyInfo.cs | 13 +++---- SpotifyAPI.Tests/TestClass.cs | 10 ++--- SpotifyAPI/Local/SpotifyLocalAPI.cs | 37 ++++++++++++------- SpotifyAPI/Local/VolumeMixerControl.cs | 33 ++++++++++++----- 10 files changed, 91 insertions(+), 73 deletions(-) diff --git a/SpotifyAPI.Example/App.config b/SpotifyAPI.Example/App.config index 8e156463..1f6eeef1 100644 --- a/SpotifyAPI.Example/App.config +++ b/SpotifyAPI.Example/App.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/SpotifyAPI.Example/ExampleForm.cs b/SpotifyAPI.Example/ExampleForm.cs index b53b2040..d311c0ef 100644 --- a/SpotifyAPI.Example/ExampleForm.cs +++ b/SpotifyAPI.Example/ExampleForm.cs @@ -9,4 +9,4 @@ namespace SpotifyAPI.Example InitializeComponent(); } } -} +} \ No newline at end of file diff --git a/SpotifyAPI.Example/LocalControl.cs b/SpotifyAPI.Example/LocalControl.cs index bb66fd8e..f43c34e4 100644 --- a/SpotifyAPI.Example/LocalControl.cs +++ b/SpotifyAPI.Example/LocalControl.cs @@ -1,10 +1,10 @@ -using System; +using SpotifyAPI.Local; +using SpotifyAPI.Local.Enums; +using SpotifyAPI.Local.Models; +using System; using System.Diagnostics; using System.Globalization; using System.Windows.Forms; -using SpotifyAPI.Local; -using SpotifyAPI.Local.Enums; -using SpotifyAPI.Local.Models; namespace SpotifyAPI.Example { @@ -102,23 +102,23 @@ namespace SpotifyAPI.Example isPlayingLabel.Text = playing.ToString(); } - void _spotify_OnVolumeChange(VolumeChangeEventArgs e) + private void _spotify_OnVolumeChange(VolumeChangeEventArgs e) { - volumeLabel.Text = (e.NewVolume*100).ToString(CultureInfo.InvariantCulture); + volumeLabel.Text = (e.NewVolume * 100).ToString(CultureInfo.InvariantCulture); } - void _spotify_OnTrackTimeChange(TrackTimeChangeEventArgs e) + private void _spotify_OnTrackTimeChange(TrackTimeChangeEventArgs e) { timeLabel.Text = FormatTime(e.TrackTime) + "/" + FormatTime(_currentTrack.Length); - timeProgressBar.Value = (int) e.TrackTime; + timeProgressBar.Value = (int)e.TrackTime; } - void _spotify_OnTrackChange(TrackChangeEventArgs e) + private void _spotify_OnTrackChange(TrackChangeEventArgs e) { UpdateTrack(e.NewTrack); } - void _spotify_OnPlayStateChange(PlayStateEventArgs e) + private void _spotify_OnPlayStateChange(PlayStateEventArgs e) { UpdatePlayingStatus(e.Playing); } @@ -162,4 +162,4 @@ namespace SpotifyAPI.Example return mins + ":" + secs; } } -} +} \ No newline at end of file diff --git a/SpotifyAPI.Example/Program.cs b/SpotifyAPI.Example/Program.cs index f07fa459..bdfac8ea 100644 --- a/SpotifyAPI.Example/Program.cs +++ b/SpotifyAPI.Example/Program.cs @@ -1,22 +1,19 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using System.Windows.Forms; namespace SpotifyAPI.Example { - static class Program + internal static class Program { /// /// Der Haupteinstiegspunkt für die Anwendung. /// [STAThread] - static void Main() + private static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new ExampleForm()); } } -} +} \ No newline at end of file diff --git a/SpotifyAPI.Example/Properties/AssemblyInfo.cs b/SpotifyAPI.Example/Properties/AssemblyInfo.cs index 4215e0a6..2dad8ee7 100644 --- a/SpotifyAPI.Example/Properties/AssemblyInfo.cs +++ b/SpotifyAPI.Example/Properties/AssemblyInfo.cs @@ -1,8 +1,7 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// Allgemeine Informationen über eine Assembly werden über die folgenden +// Allgemeine Informationen über eine Assembly werden über die folgenden // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, // die mit einer Assembly verknüpft sind. [assembly: AssemblyTitle("SpotifyAPI.Example")] @@ -14,8 +13,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar -// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. [assembly: ComVisible(false)] @@ -25,12 +24,12 @@ using System.Runtime.InteropServices; // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: // // Hauptversion -// Nebenversion +// Nebenversion // Buildnummer // Revision // -// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // übernehmen, indem Sie "*" eingeben: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/SpotifyAPI.Example/WebControl.cs b/SpotifyAPI.Example/WebControl.cs index 9e8247a9..0a06679f 100644 --- a/SpotifyAPI.Example/WebControl.cs +++ b/SpotifyAPI.Example/WebControl.cs @@ -1,14 +1,13 @@ -using System; +using SpotifyAPI.Web; +using SpotifyAPI.Web.Auth; +using SpotifyAPI.Web.Enums; +using SpotifyAPI.Web.Models; +using System; using System.Collections.Generic; -using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Windows.Forms; -using SpotifyAPI.Web; -using SpotifyAPI.Web.Auth; -using SpotifyAPI.Web.Enums; -using SpotifyAPI.Web.Models; using Image = System.Drawing.Image; namespace SpotifyAPI.Example @@ -21,7 +20,7 @@ namespace SpotifyAPI.Example private PrivateProfile _profile; private List _savedTracks; private List _playlists; - + public WebControl() { InitializeComponent(); @@ -37,7 +36,7 @@ namespace SpotifyAPI.Example _auth.OnResponseReceivedEvent += _auth_OnResponseReceivedEvent; } - void _auth_OnResponseReceivedEvent(Token token, string state) + private void _auth_OnResponseReceivedEvent(Token token, string state) { _auth.StopHttpServer(); @@ -77,7 +76,7 @@ namespace SpotifyAPI.Example _savedTracks.ForEach(track => savedTracksListView.Items.Add(new ListViewItem() { Text = track.Name, - SubItems = {string.Join(",", track.Artists.Select(source => source.Name)), track.Album.Name} + SubItems = { string.Join(",", track.Artists.Select(source => source.Name)), track.Album.Name } })); _playlists = GetPlaylists(); @@ -134,4 +133,4 @@ namespace SpotifyAPI.Example _auth.DoAuth(); } } -} +} \ No newline at end of file diff --git a/SpotifyAPI.Tests/Properties/AssemblyInfo.cs b/SpotifyAPI.Tests/Properties/AssemblyInfo.cs index 07294755..a395e345 100644 --- a/SpotifyAPI.Tests/Properties/AssemblyInfo.cs +++ b/SpotifyAPI.Tests/Properties/AssemblyInfo.cs @@ -1,8 +1,7 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// Allgemeine Informationen über eine Assembly werden über die folgenden +// Allgemeine Informationen über eine Assembly werden über die folgenden // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, // die mit einer Assembly verknüpft sind. [assembly: AssemblyTitle("SpotifyAPI.Tests")] @@ -14,8 +13,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar -// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. [assembly: ComVisible(false)] @@ -25,12 +24,12 @@ using System.Runtime.InteropServices; // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: // // Hauptversion -// Nebenversion +// Nebenversion // Buildnummer // Revision // -// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // übernehmen, indem Sie "*" eingeben: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/SpotifyAPI.Tests/TestClass.cs b/SpotifyAPI.Tests/TestClass.cs index 2c63271f..3fc90f3d 100644 --- a/SpotifyAPI.Tests/TestClass.cs +++ b/SpotifyAPI.Tests/TestClass.cs @@ -1,11 +1,11 @@ -using System; -using System.IO; -using System.Linq; -using Moq; +using Moq; using Newtonsoft.Json; using NUnit.Framework; using SpotifyAPI.Web; using SpotifyAPI.Web.Models; +using System; +using System.IO; +using System.Linq; namespace SpotifyAPI.Tests { @@ -67,4 +67,4 @@ namespace SpotifyAPI.Tests //Will add more tests once I decided if this is worth the effort (propably not?) } -} +} \ No newline at end of file diff --git a/SpotifyAPI/Local/SpotifyLocalAPI.cs b/SpotifyAPI/Local/SpotifyLocalAPI.cs index ac2f32ef..7d5ae8a6 100644 --- a/SpotifyAPI/Local/SpotifyLocalAPI.cs +++ b/SpotifyAPI/Local/SpotifyLocalAPI.cs @@ -162,10 +162,12 @@ namespace SpotifyAPI.Local public void Mute() { //Windows < Windows Vista Check - Contract.Requires(Environment.OSVersion.Version.Major >= 6); + if (Environment.OSVersion.Version.Major < 6) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); //Windows Vista Check if (Environment.OSVersion.Version.Major == 6) - Contract.Requires(Environment.OSVersion.Version.Minor != 0); + if(Environment.OSVersion.Version.Minor == 0) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); VolumeMixerControl.MuteSpotify(true); } @@ -175,10 +177,12 @@ namespace SpotifyAPI.Local public void UnMute() { //Windows < Windows Vista Check - Contract.Requires(Environment.OSVersion.Version.Major >= 6); + if (Environment.OSVersion.Version.Major < 6) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); //Windows Vista Check if (Environment.OSVersion.Version.Major == 6) - Contract.Requires(Environment.OSVersion.Version.Minor != 0); + if (Environment.OSVersion.Version.Minor == 0) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); VolumeMixerControl.MuteSpotify(false); } @@ -186,13 +190,15 @@ namespace SpotifyAPI.Local /// Checks whether Spotify is muted in the Volume Mixer control (required Windows 7 or newer) /// /// Null if an error occured, otherwise the muted state - public bool? IsSpotifyMuted() + public bool IsSpotifyMuted() { //Windows < Windows Vista Check - Contract.Requires(Environment.OSVersion.Version.Major >= 6); + if (Environment.OSVersion.Version.Major < 6) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); //Windows Vista Check if (Environment.OSVersion.Version.Major == 6) - Contract.Requires(Environment.OSVersion.Version.Minor != 0); + if (Environment.OSVersion.Version.Minor == 0) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); return VolumeMixerControl.IsSpotifyMuted(); } @@ -202,12 +208,15 @@ namespace SpotifyAPI.Local /// A value between 0 and 100 public void SetSpotifyVolume(float volume = 100) { - Contract.Requires(0 <= volume && volume <= 100); //Windows < Windows Vista Check - Contract.Requires(Environment.OSVersion.Version.Major >= 6); + if (Environment.OSVersion.Version.Major < 6) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); //Windows Vista Check if (Environment.OSVersion.Version.Major == 6) - Contract.Requires(Environment.OSVersion.Version.Minor != 0); + if (Environment.OSVersion.Version.Minor == 0) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); + if (volume < 0 || volume > 100) + throw new ArgumentOutOfRangeException("Volume parameter has to be a value between 0 and 100"); VolumeMixerControl.SetSpotifyVolume(volume); } @@ -215,13 +224,15 @@ namespace SpotifyAPI.Local /// Return the Volume Mixer volume of Spotify (requires Windows 7 or newer) /// /// Null if an error occured, otherwise a float between 0 and 100 - public float? GetSpotifyVolume() + public float GetSpotifyVolume() { //Windows < Windows Vista Check - Contract.Requires(Environment.OSVersion.Version.Major >= 6); + if (Environment.OSVersion.Version.Major < 6) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); //Windows Vista Check if (Environment.OSVersion.Version.Major == 6) - Contract.Requires(Environment.OSVersion.Version.Minor != 0); + if (Environment.OSVersion.Version.Minor == 0) + throw new NotSupportedException("This feature is only available on Windows 7 or newer"); return VolumeMixerControl.GetSpotifyVolume(); } diff --git a/SpotifyAPI/Local/VolumeMixerControl.cs b/SpotifyAPI/Local/VolumeMixerControl.cs index f0613298..4a6c9f12 100644 --- a/SpotifyAPI/Local/VolumeMixerControl.cs +++ b/SpotifyAPI/Local/VolumeMixerControl.cs @@ -8,17 +8,20 @@ namespace SpotifyAPI.Local { private const String SPOTIFY_PROCESS_NAME = "spotify"; - internal static float? GetSpotifyVolume() + internal static float GetSpotifyVolume() { Process[] p = Process.GetProcessesByName(SPOTIFY_PROCESS_NAME); if (p.Length == 0) - return null; + throw new Exception("Spotify process is not running or was not found!"); int pid = p[0].Id; ISimpleAudioVolume volume = GetVolumeObject(pid); if (volume == null) - return null; + { + Marshal.ReleaseComObject(volume); + throw new COMException("Volume object creation failed"); + } float level; volume.GetMasterVolume(out level); @@ -26,17 +29,20 @@ namespace SpotifyAPI.Local return level * 100; } - internal static bool? IsSpotifyMuted() + internal static bool IsSpotifyMuted() { Process[] p = Process.GetProcessesByName(SPOTIFY_PROCESS_NAME); if (p.Length == 0) - return null; + throw new Exception("Spotify process is not running or was not found!"); int pid = p[0].Id; ISimpleAudioVolume volume = GetVolumeObject(pid); if (volume == null) - return null; + { + Marshal.ReleaseComObject(volume); + throw new COMException("Volume object creation failed"); + } bool mute; volume.GetMute(out mute); @@ -48,13 +54,16 @@ namespace SpotifyAPI.Local { Process[] p = Process.GetProcessesByName(SPOTIFY_PROCESS_NAME); if (p.Length == 0) - return; + throw new Exception("Spotify process is not running or was not found!"); int pid = p[0].Id; ISimpleAudioVolume volume = GetVolumeObject(pid); if (volume == null) - return; + { + Marshal.ReleaseComObject(volume); + throw new COMException("Volume object creation failed"); + } Guid guid = Guid.Empty; volume.SetMasterVolume(level / 100, ref guid); @@ -65,13 +74,16 @@ namespace SpotifyAPI.Local { Process[] p = Process.GetProcessesByName(SPOTIFY_PROCESS_NAME); if (p.Length == 0) - return; + throw new Exception("Spotify process is not running or was not found!"); int pid = p[0].Id; ISimpleAudioVolume volume = GetVolumeObject(pid); if (volume == null) - return; + { + Marshal.ReleaseComObject(volume); + throw new COMException("Volume object creation failed"); + } Guid guid = Guid.Empty; volume.SetMute(mute, ref guid); @@ -125,6 +137,7 @@ namespace SpotifyAPI.Local [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] private class MMDeviceEnumerator { + } private enum EDataFlow