mirror of
https://github.com/Sarsoo/Spotify.NET.git
synced 2024-12-23 22:56:25 +00:00
Added support for Spotify's Web API
- New Namespaces -> SpotifyAPI.SpotifyLocalAPI -> SpotifyAPI.SpotifyWebAPI -> SpotifyAPI.SpotifyWebAPI.Models - Wiki created, examples coming soon - Added example for the new Web API - README updated
This commit is contained in:
parent
ba03b3cd90
commit
0b78f12df3
160
README.md
160
README.md
@ -10,162 +10,4 @@ Following 3 files will be needed for all features:
|
||||
+ nircmd.dll (Used to Mute & UnMute Spotify)
|
||||
|
||||
Screenshot of the Example:
|
||||
![alt text](http://i.imgur.com/R9Xsma0.png "Example Screen")
|
||||
|
||||
Update:
|
||||
===
|
||||
This API will also support the "new" Spotify Web API soon, following things will be possible:
|
||||
|
||||
(Ticked = implemented and ready to push,Not ticked = Work in Progress)
|
||||
|
||||
- [ ] Get an Album
|
||||
- [ ] Get Several Albums
|
||||
- [ ] Get an Album'S Tracks
|
||||
- [ ] Get an Artist
|
||||
- [ ] Get Several Artists
|
||||
- [ ] Get an Artist's Albums
|
||||
- [ ] Get an Artist's Top Tracks
|
||||
- [ ] Get an Artist'S Related Artists
|
||||
- [ ] Get a Track
|
||||
- [ ] Get several Tracks
|
||||
- [ ] Search for an Item
|
||||
- [x] Get a User's Profile
|
||||
- [x] Get Current User’s Profile
|
||||
- [x] Get a List of a User's Profile
|
||||
- [x] Get a Playlist
|
||||
- [x] Get a Playlist's Tracks
|
||||
- [ ] Create a Playlist
|
||||
- [ ] Add Tracks to a Playlist
|
||||
|
||||
With this Update, there will be 2 new/modified namespaces:
|
||||
> SpotifyAPI.SpotifyLocalAPI (Old local API)
|
||||
|
||||
> SpotifyAPI.SpotifyWebAPI (New web API)
|
||||
|
||||
___
|
||||
|
||||
Usage:
|
||||
==============
|
||||
|
||||
|
||||
### SpotifyAPI
|
||||
#####Boolean Connect()
|
||||
> Connects the SpotifyAPI to the Spotify Client (Needs to be called before making calls, Spotify has to run)
|
||||
> Returns true if it was successful
|
||||
|
||||
#####void Update()
|
||||
> Updates Information about Tracks etc.
|
||||
|
||||
#####void RunSpotify()
|
||||
> Runs Spotify (Client has to run for API Calls)
|
||||
|
||||
#####void RunSpotifyWebHelper()
|
||||
> Runs SpotifyWebHelper (Client has to run for API Calls)
|
||||
|
||||
#####static Boolean IsSpotifyRunning()
|
||||
> Returns true, if Spotify is running
|
||||
|
||||
#####static Boolean IsSpotifyWebHelperRunning()
|
||||
> Returns true, if SpotifyWebHelper is running
|
||||
|
||||
#####static Boolean IsValidSpotifyURL(String SpotifyURL)
|
||||
> Returns true, if the provided Spotify URL is working (Not working yet)
|
||||
|
||||
#####[SpotifyMusicHandler](https://github.com/JohnnyCrazy/SpotifyAPI-NET#spotifymusichandler) GetMusicHandler()
|
||||
> Returns the MusicHandler
|
||||
|
||||
#####[SpotifyEventHandler](https://github.com/JohnnyCrazy/SpotifyAPI-NET#spotifyeventhandler) GetEventHandler()
|
||||
> Returns the EventHandler
|
||||
|
||||
|
||||
### SpotifyMusicHandler
|
||||
#####void Play()
|
||||
> Play "button"
|
||||
|
||||
#####void Pause()
|
||||
> Pause "button"
|
||||
|
||||
#####void Skip()
|
||||
> Skip Track
|
||||
|
||||
#####void Previous()
|
||||
> Previous Track
|
||||
|
||||
#####void PlayURL(String SpotifyURI)
|
||||
> Plays the provided URI
|
||||
|
||||
#####double GetVolume()
|
||||
> Returns the current volume (0.00 - 1.00)
|
||||
|
||||
#####Boolean IsAdRunning()
|
||||
> Returns true, if an AD is running
|
||||
|
||||
#####double GetTrackPostion()
|
||||
> Returns the current position of the Track
|
||||
|
||||
#####void Mute()
|
||||
> Mutes Spotify (Requires nircmd.dll)
|
||||
|
||||
#####void UnMute()
|
||||
> Unmutes Spotify (Requires nircmd.dll
|
||||
|
||||
#####Boolean IsPlaying()
|
||||
> Returns true, if Spotify is playing atm
|
||||
|
||||
#####[Track](https://github.com/JohnnyCrazy/SpotifyAPI-NET#track) GetCurrentTrack()
|
||||
> Returns the current Track
|
||||
|
||||
#####StatusResponse GetStatusResponse()
|
||||
> Returns the StatusResponse, which contains all Information gathered by the Call (Should not be used at all)
|
||||
|
||||
|
||||
### SpotifyEventHandler
|
||||
#####Event OnTrackChange
|
||||
> Triggered, when the Track gets changed
|
||||
|
||||
#####Event OnPlayStateChange
|
||||
> Triggered, when Spotify's Play/Pause-State changes
|
||||
|
||||
#####Event OnVolumeChange
|
||||
> Triggered, when the volume gets changed
|
||||
|
||||
#####Event TrackTimeChangeEventHandler
|
||||
> Triggered, when the current trackposition changes
|
||||
|
||||
#####void ListenForEvents(Boolean listen)
|
||||
> Should it listen for events?
|
||||
|
||||
#####void SetSynchronizingObject(ISynchronizeInvoke obj)
|
||||
> Sets the synced object, so no Invoke is required (Events doesnt get called from the Main-Thread)
|
||||
|
||||
|
||||
### Track
|
||||
#####String GetTrackName()
|
||||
> Returns Track-name
|
||||
|
||||
#####String GetArtistName()
|
||||
> Returns Artist-name
|
||||
|
||||
#####String GetAlbumName()
|
||||
> Returns Album-name
|
||||
|
||||
#####int GetLength()
|
||||
> Returns the Track lenght
|
||||
|
||||
#####String GetAlbumURI()
|
||||
> Returns the URI for the album
|
||||
|
||||
#####String GetTrackURI()
|
||||
> Returns the URI for the Track
|
||||
|
||||
#####String GetArtistURI()
|
||||
> Returns the URI for the Artist
|
||||
|
||||
#####String GetAlbumArtURL(AlbumArtSize size)
|
||||
> Returns the URL of the Albumart based on the choosen size
|
||||
|
||||
#####Bitmap GetAlbumArt(AlbumArtSize size)
|
||||
> Returns a Bitmap of the Albumart based on the choosen size
|
||||
|
||||
#####Bitmap GetAlbumArtAsync(AlbumArtSize size)
|
||||
> Returns a Bitmap of the Albumart based on the choosen size asynchronously
|
||||
![alt text](http://i.imgur.com/R9Xsma0.png "Example Screen")
|
@ -1,10 +1,12 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
VisualStudioVersion = 12.0.30324.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpotifyAPI", "SpotifyAPI\SpotifyAPI.csproj", "{EBBE35E2-7B91-4D7D-B8FC-3A0472F5119D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpotifyWebAPIExample", "SpotifyWebAPIExample\SpotifyWebAPIExample.csproj", "{004B45C3-BB98-4E62-AD11-D80BA64FEB8E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpotifyAPI_Example", "SpotifyAPI_Example\SpotifyAPI_Example.csproj", "{C12D46F9-BB35-46D6-B821-522B8F9C3CBE}"
|
||||
EndProject
|
||||
Global
|
||||
@ -17,6 +19,10 @@ Global
|
||||
{EBBE35E2-7B91-4D7D-B8FC-3A0472F5119D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EBBE35E2-7B91-4D7D-B8FC-3A0472F5119D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EBBE35E2-7B91-4D7D-B8FC-3A0472F5119D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{004B45C3-BB98-4E62-AD11-D80BA64FEB8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{004B45C3-BB98-4E62-AD11-D80BA64FEB8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{004B45C3-BB98-4E62-AD11-D80BA64FEB8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{004B45C3-BB98-4E62-AD11-D80BA64FEB8E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C12D46F9-BB35-46D6-B821-522B8F9C3CBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C12D46F9-BB35-46D6-B821-522B8F9C3CBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C12D46F9-BB35-46D6-B821-522B8F9C3CBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
|
||||
// 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")]
|
||||
[assembly: AssemblyTitle("SpotifyLocalAPIClass")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SpotifyAPI")]
|
||||
[assembly: AssemblyProduct("SpotifyLocalAPIClass")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// JSON Response, used internaly
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum for the AlbumArt
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Event gets triggered, when the Track is changed
|
@ -5,7 +5,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
class ExtendedWebClient : WebClient
|
||||
{
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
class RemoteHandler
|
||||
{
|
||||
@ -119,7 +119,7 @@ namespace SpotifyAPIv1
|
||||
try
|
||||
{
|
||||
//Need to find a better solution
|
||||
if (SpotifyAPI.IsSpotifyRunning())
|
||||
if (SpotifyLocalAPIClass.IsSpotifyRunning())
|
||||
response = "[ " + wc.DownloadString(a) + " ]";
|
||||
}
|
||||
catch (Exception z)
|
@ -4,14 +4,14 @@ using Newtonsoft.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
public class SpotifyAPI
|
||||
public class SpotifyLocalAPIClass
|
||||
{
|
||||
SpotifyMusicHandler mh;
|
||||
RemoteHandler rh;
|
||||
SpotifyEventHandler eh;
|
||||
public SpotifyAPI()
|
||||
public SpotifyLocalAPIClass()
|
||||
{
|
||||
rh = RemoteHandler.GetInstance();
|
||||
mh = new SpotifyMusicHandler();
|
||||
@ -21,6 +21,7 @@ namespace SpotifyAPIv1
|
||||
/// <summary>
|
||||
/// Connects with Spotify. Needs to be called before all other SpotifyAPI functions
|
||||
/// </summary>
|
||||
/// <returns>Returns true, if it was successful, false if not</returns>
|
||||
public Boolean Connect()
|
||||
{
|
||||
return rh.Init();
|
||||
@ -95,7 +96,7 @@ namespace SpotifyAPIv1
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
if (!SpotifyAPI.IsSpotifyWebHelperRunning() || !SpotifyAPI.IsSpotifyRunning())
|
||||
if (!SpotifyLocalAPIClass.IsSpotifyWebHelperRunning() || !SpotifyLocalAPIClass.IsSpotifyRunning())
|
||||
return;
|
||||
mh.Update(rh.Update());
|
||||
}
|
@ -2,15 +2,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SpotifyAPIv1;
|
||||
using SpotifyAPI.SpotifyLocalAPI;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
public class SpotifyEventHandler
|
||||
{
|
||||
private Boolean listen = false;
|
||||
private System.Timers.Timer timer;
|
||||
private SpotifyAPI api;
|
||||
private SpotifyLocalAPIClass api;
|
||||
private SpotifyMusicHandler mh;
|
||||
|
||||
private StatusResponse response;
|
||||
@ -24,7 +24,7 @@ namespace SpotifyAPIv1
|
||||
public event VolumeChangeEventHandler OnVolumeChange;
|
||||
public event TrackTimeChangeEventHandler OnTrackTimeChange;
|
||||
|
||||
public SpotifyEventHandler(SpotifyAPI api, SpotifyMusicHandler mh)
|
||||
public SpotifyEventHandler(SpotifyLocalAPIClass api, SpotifyMusicHandler mh)
|
||||
{
|
||||
timer = new System.Timers.Timer();
|
||||
timer.Interval = 50;
|
@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
public class SpotifyMusicHandler
|
||||
{
|
||||
@ -56,7 +56,7 @@ namespace SpotifyAPIv1
|
||||
/// <summary>
|
||||
/// Plays a Spotify URI
|
||||
/// </summary>
|
||||
/// <param name="uri">The Spotify URI. Can be checked with <seealso cref="SpotifyAPI.IsValidSpotifyURI"/></param>
|
||||
/// <param name="uri">The Spotify URI. Can be checked with <seealso cref="SpotifyLocalAPIClass.IsValidSpotifyURI"/></param>
|
||||
public void PlayURL(String uri)
|
||||
{
|
||||
rh.SendPlayRequest(uri);
|
@ -3,7 +3,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
public class StatusResponse
|
||||
{
|
@ -6,7 +6,7 @@ using System.Drawing;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
|
||||
namespace SpotifyAPIv1
|
||||
namespace SpotifyAPI.SpotifyLocalAPI
|
||||
{
|
||||
public class Track
|
||||
{
|
@ -7,7 +7,7 @@
|
||||
<ProjectGuid>{EBBE35E2-7B91-4D7D-B8FC-3A0472F5119D}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SpotifyAPIv1</RootNamespace>
|
||||
<RootNamespace>SpotifyAPI.SpotifyLocalAPI</RootNamespace>
|
||||
<AssemblyName>SpotifyAPI</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
@ -38,6 +38,7 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
@ -46,23 +47,49 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CFID.cs" />
|
||||
<Compile Include="Enum.cs" />
|
||||
<Compile Include="ExtendedWebClient.cs">
|
||||
<Compile Include="SpoitfyLocalAPI\CFID.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\Enum.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\ExtendedWebClient.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SpotifyEventHandler.cs" />
|
||||
<Compile Include="Events.cs" />
|
||||
<Compile Include="SpotifyMusicHandler.cs" />
|
||||
<Compile Include="RemoteHandler.cs" />
|
||||
<Compile Include="SpotifyAPI.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\SpotifyEventHandler.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\Events.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\SpotifyMusicHandler.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\RemoteHandler.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\SpotifyAPI.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="StatusResponse.cs" />
|
||||
<Compile Include="Track.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\StatusResponse.cs" />
|
||||
<Compile Include="SpoitfyLocalAPI\Track.cs" />
|
||||
<Compile Include="SpotifyWebAPI\AlbumType.cs" />
|
||||
<Compile Include="SpotifyWebAPI\AutorizationCodeAuth.cs" />
|
||||
<Compile Include="SpotifyWebAPI\ClientCredentialsAuth.cs" />
|
||||
<Compile Include="SpotifyWebAPI\ImplicitGrantAuth.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\BasicModel.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\FullAlbum.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\FullArtist.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\FullTrack.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\SearchItem.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\PrivateProfile.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\GeneralModels.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\FullPlaylist.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\PublicProfile.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\SimpleAlbum.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\SimpleArtist.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\SimpleTrack.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\Token.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\SimplePlaylist.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Models\Paging.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Scope.cs" />
|
||||
<Compile Include="SpotifyWebAPI\SearchType.cs" />
|
||||
<Compile Include="SpotifyWebAPI\SimpleHttpServer.cs" />
|
||||
<Compile Include="SpotifyWebAPI\SpotifyWebAPIClass.cs" />
|
||||
<Compile Include="SpotifyWebAPI\StringAttribute.cs" />
|
||||
<Compile Include="SpotifyWebAPI\Util.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
23
SpotifyAPI/SpotifyWebAPI/AlbumType.cs
Normal file
23
SpotifyAPI/SpotifyWebAPI/AlbumType.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
[Flags]
|
||||
public enum AlbumType
|
||||
{
|
||||
[StringAttribute("album")]
|
||||
ALBUM = 1,
|
||||
[StringAttribute("single")]
|
||||
SINGLE = 2,
|
||||
[StringAttribute("compilation")]
|
||||
COMPILATION = 4,
|
||||
[StringAttribute("appears_on")]
|
||||
APPEARS_ON = 8,
|
||||
[StringAttribute("album,single,compilation,appears_on")]
|
||||
ALL = 16
|
||||
}
|
||||
}
|
124
SpotifyAPI/SpotifyWebAPI/AutorizationCodeAuth.cs
Normal file
124
SpotifyAPI/SpotifyWebAPI/AutorizationCodeAuth.cs
Normal file
@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Specialized;
|
||||
using Newtonsoft.Json;
|
||||
using SpotifyAPI.SpotifyWebAPI.Models;
|
||||
using System.IO;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
public class AutorizationCodeAuth
|
||||
{
|
||||
public String ClientId { get; set; }
|
||||
public String RedirectUri { get; set; }
|
||||
public String State { get; set; }
|
||||
public Scope Scope { get; set; }
|
||||
public Boolean ShowDialog { get; set; }
|
||||
|
||||
Thread httpThread;
|
||||
SimpleHttpServer httpServer;
|
||||
|
||||
public delegate void OnResponseReceived(AutorizationCodeAuthResponse response);
|
||||
public event OnResponseReceived OnResponseReceivedEvent;
|
||||
|
||||
public void DoAuth()
|
||||
{
|
||||
String uri = GetUri();
|
||||
Process.Start(uri);
|
||||
}
|
||||
/// <summary>
|
||||
/// Also don't use this, you would need to provide your clientSecretKey
|
||||
/// </summary>
|
||||
/// <param name="refreshToken"></param>
|
||||
/// <param name="clientId"></param>
|
||||
/// <param name="clientSecret"></param>
|
||||
public Token RefreshToken(String refreshToken,String clientSecret)
|
||||
{
|
||||
using(WebClient wc = new WebClient())
|
||||
{
|
||||
wc.Proxy = null;
|
||||
wc.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientId + ":" + clientSecret)));
|
||||
NameValueCollection col = new NameValueCollection();
|
||||
col.Add("grant_type", "refresh_token");
|
||||
col.Add("refresh_token", refreshToken);
|
||||
|
||||
String response = "";
|
||||
try
|
||||
{
|
||||
byte[] data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col);
|
||||
response = Encoding.UTF8.GetString(data);
|
||||
}catch(WebException e)
|
||||
{
|
||||
response = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
|
||||
}
|
||||
return JsonConvert.DeserializeObject<Token>(response);
|
||||
}
|
||||
}
|
||||
private String GetUri()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("https://accounts.spotify.com/authorize/?");
|
||||
builder.Append("client_id=" + ClientId);
|
||||
builder.Append("&response_type=code");
|
||||
builder.Append("&redirect_uri=" + RedirectUri);
|
||||
builder.Append("&state=" + State);
|
||||
builder.Append("&scope=" + Scope.GetScopeValue(" "));
|
||||
builder.Append("&show_dialog=" + ShowDialog.ToString());
|
||||
return builder.ToString();
|
||||
}
|
||||
public void StartHttpServer()
|
||||
{
|
||||
httpServer = new SimpleHttpServer(80, SetResponse,AuthType.AUTHORIZATION);
|
||||
httpThread = new Thread(httpServer.listen); ;
|
||||
httpThread.Start();
|
||||
}
|
||||
public void SetResponse(String code,String state,String error)
|
||||
{
|
||||
if (OnResponseReceivedEvent != null)
|
||||
OnResponseReceivedEvent(new AutorizationCodeAuthResponse() { Code = code, State = state, Error = error });
|
||||
}
|
||||
public void StopHttpServer()
|
||||
{
|
||||
httpServer = null;
|
||||
}
|
||||
/// <summary>
|
||||
/// Don't use this!!! Use a PHP-Script or sth...
|
||||
/// </summary>
|
||||
public Token ExchangeAuthCode(String code,String clientSecret)
|
||||
{
|
||||
using(WebClient wc = new WebClient())
|
||||
{
|
||||
wc.Proxy = null;
|
||||
|
||||
NameValueCollection col = new NameValueCollection();
|
||||
col.Add("grant_type","authorization_code");
|
||||
col.Add("code",code);
|
||||
col.Add("redirect_uri", RedirectUri);
|
||||
col.Add("client_id", ClientId);
|
||||
col.Add("client_secret", clientSecret);
|
||||
|
||||
String response = "";
|
||||
try
|
||||
{
|
||||
byte[] data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col);
|
||||
response = Encoding.UTF8.GetString(data);
|
||||
}catch(WebException e)
|
||||
{
|
||||
response = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
|
||||
}
|
||||
return JsonConvert.DeserializeObject<Token>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
public struct AutorizationCodeAuthResponse
|
||||
{
|
||||
public String Code { get; set; }
|
||||
public String State { get; set; }
|
||||
public String Error { get; set; }
|
||||
}
|
||||
}
|
43
SpotifyAPI/SpotifyWebAPI/ClientCredentialsAuth.cs
Normal file
43
SpotifyAPI/SpotifyWebAPI/ClientCredentialsAuth.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using System.Collections.Specialized;
|
||||
using Newtonsoft.Json;
|
||||
using SpotifyAPI.SpotifyWebAPI.Models;
|
||||
using System.IO;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
public class ClientCredentialsAuth
|
||||
{
|
||||
public Scope Scope { get; set; }
|
||||
public String ClientId { get; set; }
|
||||
public String ClientSecret { get; set; }
|
||||
|
||||
public Token DoAuth()
|
||||
{
|
||||
using(WebClient wc = new WebClient())
|
||||
{
|
||||
wc.Proxy = null;
|
||||
wc.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientId + ":" + ClientSecret)));
|
||||
|
||||
NameValueCollection col = new NameValueCollection();
|
||||
col.Add("grant_type","client_credentials");
|
||||
col.Add("scope", Scope.GetScopeValue(" "));
|
||||
|
||||
byte[] data = null;
|
||||
try
|
||||
{
|
||||
data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col);
|
||||
}catch(WebException e)
|
||||
{
|
||||
String test = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
|
||||
}
|
||||
return JsonConvert.DeserializeObject<Token>(Encoding.UTF8.GetString(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
71
SpotifyAPI/SpotifyWebAPI/ImplicitGrantAuth.cs
Normal file
71
SpotifyAPI/SpotifyWebAPI/ImplicitGrantAuth.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using SpotifyAPI.SpotifyWebAPI.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
public class ImplicitGrantAuth
|
||||
{
|
||||
public String ClientId { get; set; }
|
||||
public String RedirectUri { get; set; }
|
||||
public String State { get; set; }
|
||||
public Scope Scope { get; set; }
|
||||
public Boolean ShowDialog { get; set; }
|
||||
|
||||
Thread httpThread;
|
||||
SimpleHttpServer httpServer;
|
||||
|
||||
public delegate void OnResponseReceived(Token token,String state,String error);
|
||||
public event OnResponseReceived OnResponseReceivedEvent;
|
||||
|
||||
public void DoAuth()
|
||||
{
|
||||
String uri = GetUri();
|
||||
Process.Start(uri);
|
||||
}
|
||||
private String GetUri()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("https://accounts.spotify.com/authorize/?");
|
||||
builder.Append("client_id=" + ClientId);
|
||||
builder.Append("&response_type=token");
|
||||
builder.Append("&redirect_uri=" + RedirectUri);
|
||||
builder.Append("&state=" + State);
|
||||
builder.Append("&scope=" + Scope.GetScopeValue(" "));
|
||||
builder.Append("&show_dialog=" + ShowDialog.ToString());
|
||||
return builder.ToString();
|
||||
}
|
||||
public void StartHttpServer()
|
||||
{
|
||||
httpServer = new SimpleHttpServer(80, SetResponse, AuthType.IMPLICIT);
|
||||
httpThread = new Thread(httpServer.listen); ;
|
||||
httpThread.Start();
|
||||
}
|
||||
public void SetResponse(String accessToken, String tokenType, int expiresIn,String state, String error)
|
||||
{
|
||||
if (OnResponseReceivedEvent != null)
|
||||
OnResponseReceivedEvent(new Token()
|
||||
{
|
||||
AccessToken = accessToken,
|
||||
TokenType = tokenType,
|
||||
ExpiresIn = expiresIn
|
||||
},state,error);
|
||||
}
|
||||
public void StopHttpServer()
|
||||
{
|
||||
try
|
||||
{
|
||||
httpThread.Abort();
|
||||
}catch(ThreadAbortException e)
|
||||
{
|
||||
|
||||
}
|
||||
httpServer = null;
|
||||
}
|
||||
}
|
||||
}
|
20
SpotifyAPI/SpotifyWebAPI/Models/BasicModel.cs
Normal file
20
SpotifyAPI/SpotifyWebAPI/Models/BasicModel.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public abstract class BasicModel
|
||||
{
|
||||
[JsonProperty("error")]
|
||||
public Error Error { get; set; }
|
||||
|
||||
public Boolean HasError()
|
||||
{
|
||||
return Error != null;
|
||||
}
|
||||
}
|
||||
}
|
45
SpotifyAPI/SpotifyWebAPI/Models/FullAlbum.cs
Normal file
45
SpotifyAPI/SpotifyWebAPI/Models/FullAlbum.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class FullAlbum : BasicModel
|
||||
{
|
||||
[JsonProperty("album_type")]
|
||||
public String AlbumType { get; set; }
|
||||
[JsonProperty("artists")]
|
||||
public List<SimpleArtist> Artists { get; set; }
|
||||
[JsonProperty("available_markets")]
|
||||
public List<String> AvailableMarkets { get; set; }
|
||||
[JsonProperty("external_ids")]
|
||||
public Dictionary<String, String> ExternalIds { get; set; }
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<String, String> ExternalUrls { get; set; }
|
||||
[JsonProperty("genres")]
|
||||
public List<String> Genres { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("images")]
|
||||
public List<Image> Images { get; set; }
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("popularity")]
|
||||
public int Popularity { get; set; }
|
||||
[JsonProperty("release_date")]
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
[JsonProperty("release_date_precision")]
|
||||
public String ReleaseDatePrecision { get; set; }
|
||||
[JsonProperty("tracks")]
|
||||
public Paging<SimpleTrack> Tracks { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
31
SpotifyAPI/SpotifyWebAPI/Models/FullArtist.cs
Normal file
31
SpotifyAPI/SpotifyWebAPI/Models/FullArtist.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class FullArtist : BasicModel
|
||||
{
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<String, String> ExternalUrls { get; set; }
|
||||
[JsonProperty("genres")]
|
||||
public List<String> Genres { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("images")]
|
||||
public List<Image> Images { get; set; }
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("popularity")]
|
||||
public int Popularity { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
39
SpotifyAPI/SpotifyWebAPI/Models/FullPlaylist.cs
Normal file
39
SpotifyAPI/SpotifyWebAPI/Models/FullPlaylist.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class FullPlaylist : BasicModel
|
||||
{
|
||||
[JsonProperty("collaborative")]
|
||||
public Boolean Collaborative { get; set; }
|
||||
[JsonProperty("description")]
|
||||
public String Description { get; set; }
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<string, string> ExternalUrls { get; set; }
|
||||
[JsonProperty("followers")]
|
||||
public Followers Followers { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("images")]
|
||||
public List<Image> Images { get; set; }
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("owner")]
|
||||
public PublicProfile Owner { get; set; }
|
||||
[JsonProperty("public")]
|
||||
public Boolean Public { get; set; }
|
||||
[JsonProperty("tracks")]
|
||||
public Paging<PlaylistTrack> Tracks { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
48
SpotifyAPI/SpotifyWebAPI/Models/FullTrack.cs
Normal file
48
SpotifyAPI/SpotifyWebAPI/Models/FullTrack.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class FullTrack : BasicModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple-Album object of the track @<see cref="Paging"/>
|
||||
/// </summary>
|
||||
[JsonProperty("album")]
|
||||
public SimpleAlbum Album { get; set; }
|
||||
[JsonProperty("artist")]
|
||||
public SimpleArtist Artist { get; set; }
|
||||
[JsonProperty("available_markets")]
|
||||
public List<String> AvailableMarkets { get; set; }
|
||||
[JsonProperty("disc_number")]
|
||||
public int DiscNumber { get; set; }
|
||||
[JsonProperty("duration_ms")]
|
||||
public int DurationMs { get; set; }
|
||||
[JsonProperty("explicit")]
|
||||
public Boolean Explicit { get; set; }
|
||||
[JsonProperty("external_ids")]
|
||||
public Dictionary<String, String> ExternalIds { get; set; }
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<String, String> ExternUrls { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("popularity")]
|
||||
public int Popularity { get; set; }
|
||||
[JsonProperty("preview_url")]
|
||||
public String PreviewUrl { get; set; }
|
||||
[JsonProperty("track_number")]
|
||||
public int TrackNumber { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
71
SpotifyAPI/SpotifyWebAPI/Models/GeneralModels.cs
Normal file
71
SpotifyAPI/SpotifyWebAPI/Models/GeneralModels.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class Image
|
||||
{
|
||||
[JsonProperty("url")]
|
||||
public String Url { get; set; }
|
||||
[JsonProperty("width")]
|
||||
public int Width { get; set; }
|
||||
[JsonProperty("height")]
|
||||
public int Height { get; set; }
|
||||
}
|
||||
public class Error
|
||||
{
|
||||
[JsonProperty("status")]
|
||||
public int Status { get; set; }
|
||||
[JsonProperty("message")]
|
||||
public String Message { get; set; }
|
||||
}
|
||||
public class PlaylistTrackCollection
|
||||
{
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("total")]
|
||||
public int Total { get; set; }
|
||||
}
|
||||
public class Followers
|
||||
{
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("total")]
|
||||
public int Total { get; set; }
|
||||
}
|
||||
public class PlaylistTrack
|
||||
{
|
||||
[JsonProperty("added_at")]
|
||||
public DateTime AddedAt { get; set; }
|
||||
[JsonProperty("added_by")]
|
||||
public PublicProfile AddedBy { get; set; }
|
||||
[JsonProperty("track")]
|
||||
public FullTrack Track { get; set; }
|
||||
}
|
||||
internal class CreatePlaylistArgs
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("public")]
|
||||
public Boolean Public { get; set; }
|
||||
}
|
||||
public class SeveralTracks
|
||||
{
|
||||
[JsonProperty("tracks")]
|
||||
public List<FullTrack> Tracks { get; set; }
|
||||
}
|
||||
public class SeveralArtists
|
||||
{
|
||||
[JsonProperty("artists")]
|
||||
public List<FullArtist> Artists { get; set; }
|
||||
}
|
||||
public class SeveralAlbums
|
||||
{
|
||||
[JsonProperty("albums")]
|
||||
public List<FullAlbum> Albums { get; set; }
|
||||
}
|
||||
}
|
27
SpotifyAPI/SpotifyWebAPI/Models/Paging.cs
Normal file
27
SpotifyAPI/SpotifyWebAPI/Models/Paging.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class Paging<T> : BasicModel
|
||||
{
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("items")]
|
||||
public List<T> Items { get; set; }
|
||||
[JsonProperty("limit")]
|
||||
public int Limit { get; set; }
|
||||
[JsonProperty("next")]
|
||||
public String Next { get; set; }
|
||||
[JsonProperty("offset")]
|
||||
public int Offset { get; set; }
|
||||
[JsonProperty("previous")]
|
||||
public String Previous { get; set; }
|
||||
[JsonProperty("total")]
|
||||
public int Total { get; set; }
|
||||
}
|
||||
}
|
31
SpotifyAPI/SpotifyWebAPI/Models/PrivateProfile.cs
Normal file
31
SpotifyAPI/SpotifyWebAPI/Models/PrivateProfile.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class PrivateProfile : BasicModel
|
||||
{
|
||||
[JsonProperty("country")]
|
||||
public String Country { get; set; }
|
||||
[JsonProperty("display_name")]
|
||||
public String DisplayName { get; set; }
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<string, string> ExternalUrls { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("images")]
|
||||
public List<Image> Images { get; set; }
|
||||
[JsonProperty("product")]
|
||||
public String Product { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
23
SpotifyAPI/SpotifyWebAPI/Models/PublicProfile.cs
Normal file
23
SpotifyAPI/SpotifyWebAPI/Models/PublicProfile.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class PublicProfile : BasicModel
|
||||
{
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<string, string> ExternalUrls { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
19
SpotifyAPI/SpotifyWebAPI/Models/SearchItem.cs
Normal file
19
SpotifyAPI/SpotifyWebAPI/Models/SearchItem.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class SearchItem : BasicModel
|
||||
{
|
||||
[JsonProperty("artists")]
|
||||
public Paging<SimpleArtist> Artists { get; set; }
|
||||
[JsonProperty("albums")]
|
||||
public Paging<SimpleAlbum> Albums { get; set; }
|
||||
[JsonProperty("tracks")]
|
||||
public Paging<FullTrack> Tracks { get; set; }
|
||||
}
|
||||
}
|
31
SpotifyAPI/SpotifyWebAPI/Models/SimpleAlbum.cs
Normal file
31
SpotifyAPI/SpotifyWebAPI/Models/SimpleAlbum.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class SimpleAlbum : BasicModel
|
||||
{
|
||||
[JsonProperty("album_type")]
|
||||
public String AlbumType { get; set; }
|
||||
[JsonProperty("available_markets")]
|
||||
public List<String> AvailableMarkets { get; set; }
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<String, String> ExternalUrls { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("images")]
|
||||
public List<Image> Images { get; set; }
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
25
SpotifyAPI/SpotifyWebAPI/Models/SimpleArtist.cs
Normal file
25
SpotifyAPI/SpotifyWebAPI/Models/SimpleArtist.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class SimpleArtist : BasicModel
|
||||
{
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<String, String> ExternalUrls { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
33
SpotifyAPI/SpotifyWebAPI/Models/SimplePlaylist.cs
Normal file
33
SpotifyAPI/SpotifyWebAPI/Models/SimplePlaylist.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class SimplePlaylist : BasicModel
|
||||
{
|
||||
[JsonProperty("collaborative")]
|
||||
public Boolean Collaborative { get; set; }
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<string, string> ExternalUrls { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("owner")]
|
||||
public PublicProfile Owner { get; set; }
|
||||
[JsonProperty("public")]
|
||||
public Boolean Public { get; set; }
|
||||
[JsonProperty("tracks")]
|
||||
public PlaylistTrackCollection Tracks { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
37
SpotifyAPI/SpotifyWebAPI/Models/SimpleTrack.cs
Normal file
37
SpotifyAPI/SpotifyWebAPI/Models/SimpleTrack.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class SimpleTrack : BasicModel
|
||||
{
|
||||
[JsonProperty("artist")]
|
||||
public SimpleArtist Artist { get; set; }
|
||||
[JsonProperty("disc_number")]
|
||||
public int DiscNumber { get; set; }
|
||||
[JsonProperty("duration_ms")]
|
||||
public int DurationMs { get; set; }
|
||||
[JsonProperty("explicit")]
|
||||
public Boolean Explicit { get; set; }
|
||||
[JsonProperty("external_urls")]
|
||||
public Dictionary<String, String> ExternUrls { get; set; }
|
||||
[JsonProperty("href")]
|
||||
public String Href { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public String Id { get; set; }
|
||||
[JsonProperty("name")]
|
||||
public String Name { get; set; }
|
||||
[JsonProperty("preview_url")]
|
||||
public String PreviewUrl { get; set; }
|
||||
[JsonProperty("track_number")]
|
||||
public int TrackNumber { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public String Type { get; set; }
|
||||
[JsonProperty("uri")]
|
||||
public String Uri { get; set; }
|
||||
}
|
||||
}
|
39
SpotifyAPI/SpotifyWebAPI/Models/Token.cs
Normal file
39
SpotifyAPI/SpotifyWebAPI/Models/Token.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI.Models
|
||||
{
|
||||
public class Token
|
||||
{
|
||||
[JsonProperty("access_token")]
|
||||
public String AccessToken { get; set; }
|
||||
|
||||
[JsonProperty("token_type")]
|
||||
public String TokenType { get; set; }
|
||||
|
||||
[JsonProperty("expires_in")]
|
||||
public int ExpiresIn { get; set; }
|
||||
|
||||
[JsonProperty("refresh_token")]
|
||||
public String RefreshToken { get; set; }
|
||||
|
||||
[JsonProperty("error")]
|
||||
public String Error { get; set; }
|
||||
[JsonProperty("error_description")]
|
||||
public String ErrorDescription { get; set; }
|
||||
|
||||
public DateTime CreateDate { get; set; }
|
||||
public Token()
|
||||
{
|
||||
CreateDate = DateTime.Now;
|
||||
}
|
||||
public Boolean IsExpired()
|
||||
{
|
||||
return CreateDate.Add(TimeSpan.FromSeconds(ExpiresIn)) >= DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
27
SpotifyAPI/SpotifyWebAPI/Scope.cs
Normal file
27
SpotifyAPI/SpotifyWebAPI/Scope.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
[Flags]
|
||||
public enum Scope
|
||||
{
|
||||
[StringAttribute("")]
|
||||
NONE = 1,
|
||||
[StringAttribute("playlist-modify")]
|
||||
PLAYLIST_MODIFY = 2,
|
||||
[StringAttribute("playlist-modify-private")]
|
||||
PLAYLIST_MODIFY_PRIVATE = 4,
|
||||
[StringAttribute("playlist-read-private")]
|
||||
PLAYLIST_READ_PRIVATE = 8,
|
||||
[StringAttribute("streaming")]
|
||||
STREAMING = 16,
|
||||
[StringAttribute("user-read-private")]
|
||||
USER_READ_PRIVATE = 32,
|
||||
[StringAttribute("user-read-email")]
|
||||
USER_READ_EMAIL = 64
|
||||
}
|
||||
}
|
21
SpotifyAPI/SpotifyWebAPI/SearchType.cs
Normal file
21
SpotifyAPI/SpotifyWebAPI/SearchType.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
[Flags]
|
||||
public enum SearchType
|
||||
{
|
||||
[StringAttribute("artist")]
|
||||
ARTIST = 1,
|
||||
[StringAttribute("album")]
|
||||
ALBUM = 2,
|
||||
[StringAttribute("track")]
|
||||
TRACK = 4,
|
||||
[StringAttribute("track,album,artist")]
|
||||
ALL = 8
|
||||
}
|
||||
}
|
274
SpotifyAPI/SpotifyWebAPI/SimpleHttpServer.cs
Normal file
274
SpotifyAPI/SpotifyWebAPI/SimpleHttpServer.cs
Normal file
@ -0,0 +1,274 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Collections.Specialized;
|
||||
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.
|
||||
|
||||
// simple HTTP explanation
|
||||
// http://www.jmarshall.com/easy/http/
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
|
||||
public class HttpProcessor {
|
||||
public TcpClient socket;
|
||||
public HttpServer srv;
|
||||
|
||||
private Stream inputStream;
|
||||
public StreamWriter outputStream;
|
||||
|
||||
public String http_method;
|
||||
public String http_url;
|
||||
public String http_protocol_versionstring;
|
||||
public Hashtable httpHeaders = new Hashtable();
|
||||
|
||||
|
||||
private static int MAX_POST_SIZE = 10 * 1024 * 1024; // 10MB
|
||||
|
||||
public HttpProcessor(TcpClient s, HttpServer srv) {
|
||||
this.socket = s;
|
||||
this.srv = srv;
|
||||
}
|
||||
|
||||
|
||||
private string streamReadLine(Stream inputStream) {
|
||||
int next_char;
|
||||
string data = "";
|
||||
while (true) {
|
||||
next_char = inputStream.ReadByte();
|
||||
if (next_char == '\n') { break; }
|
||||
if (next_char == '\r') { continue; }
|
||||
if (next_char == -1) { Thread.Sleep(1); continue; };
|
||||
data += Convert.ToChar(next_char);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
public void process() {
|
||||
// we can't use a StreamReader for input, because it buffers up extra data on us inside it's
|
||||
// "processed" view of the world, and we want the data raw after the headers
|
||||
inputStream = new BufferedStream(socket.GetStream());
|
||||
|
||||
// we probably shouldn't be using a streamwriter for all output from handlers either
|
||||
outputStream = new StreamWriter(new BufferedStream(socket.GetStream()));
|
||||
try {
|
||||
parseRequest();
|
||||
readHeaders();
|
||||
if (http_method.Equals("GET")) {
|
||||
handleGETRequest();
|
||||
} else if (http_method.Equals("POST")) {
|
||||
handlePOSTRequest();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine("Exception: " + e.ToString());
|
||||
writeFailure();
|
||||
}
|
||||
outputStream.Flush();
|
||||
// bs.Flush(); // flush any remaining output
|
||||
inputStream = null; outputStream = null; // bs = null;
|
||||
socket.Close();
|
||||
}
|
||||
|
||||
public void parseRequest() {
|
||||
String request = streamReadLine(inputStream);
|
||||
string[] tokens = request.Split(' ');
|
||||
if (tokens.Length < 2) {
|
||||
throw new Exception("invalid http request line");
|
||||
}
|
||||
http_method = tokens[0].ToUpper();
|
||||
http_url = tokens[1];
|
||||
}
|
||||
|
||||
public void readHeaders() {
|
||||
String line;
|
||||
while ((line = streamReadLine(inputStream)) != null) {
|
||||
if (line.Equals("")) {
|
||||
return;
|
||||
}
|
||||
|
||||
int separator = line.IndexOf(':');
|
||||
if (separator == -1) {
|
||||
throw new Exception("invalid http header line: " + line);
|
||||
}
|
||||
String name = line.Substring(0, separator);
|
||||
int pos = separator + 1;
|
||||
while ((pos < line.Length) && (line[pos] == ' ')) {
|
||||
pos++; // strip any spaces
|
||||
}
|
||||
|
||||
string value = line.Substring(pos, line.Length - pos);
|
||||
httpHeaders[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void handleGETRequest() {
|
||||
srv.handleGETRequest(this);
|
||||
}
|
||||
|
||||
private const int BUF_SIZE = 4096;
|
||||
public void handlePOSTRequest() {
|
||||
// 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!
|
||||
|
||||
int content_len = 0;
|
||||
MemoryStream ms = new MemoryStream();
|
||||
if (this.httpHeaders.ContainsKey("Content-Length")) {
|
||||
content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]);
|
||||
if (content_len > MAX_POST_SIZE) {
|
||||
throw new Exception(
|
||||
String.Format("POST Content-Length({0}) too big for this simple server",
|
||||
content_len));
|
||||
}
|
||||
byte[] buf = new byte[BUF_SIZE];
|
||||
int to_read = content_len;
|
||||
while (to_read > 0) {
|
||||
|
||||
int numread = this.inputStream.Read(buf, 0, Math.Min(BUF_SIZE, to_read));
|
||||
if (numread == 0) {
|
||||
if (to_read == 0) {
|
||||
break;
|
||||
} else {
|
||||
throw new Exception("client disconnected during post");
|
||||
}
|
||||
}
|
||||
to_read -= numread;
|
||||
ms.Write(buf, 0, numread);
|
||||
}
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
srv.handlePOSTRequest(this, new StreamReader(ms));
|
||||
|
||||
}
|
||||
|
||||
public void writeSuccess(string content_type="text/html") {
|
||||
outputStream.WriteLine("HTTP/1.0 200 OK");
|
||||
outputStream.WriteLine("Content-Type: " + content_type);
|
||||
outputStream.WriteLine("Connection: close");
|
||||
outputStream.WriteLine("");
|
||||
}
|
||||
|
||||
public void writeFailure() {
|
||||
outputStream.WriteLine("HTTP/1.0 404 File not found");
|
||||
outputStream.WriteLine("Connection: close");
|
||||
outputStream.WriteLine("");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class HttpServer {
|
||||
|
||||
protected int port;
|
||||
TcpListener listener;
|
||||
bool is_active = true;
|
||||
|
||||
public HttpServer(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void listen()
|
||||
{
|
||||
listener = new TcpListener(port);
|
||||
listener.Start();
|
||||
while (is_active) {
|
||||
TcpClient s = listener.AcceptTcpClient();
|
||||
HttpProcessor processor = new HttpProcessor(s, this);
|
||||
Thread thread = new Thread(new ThreadStart(processor.process));
|
||||
thread.Start();
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void handleGETRequest(HttpProcessor p);
|
||||
public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData);
|
||||
}
|
||||
|
||||
public class SimpleHttpServer : HttpServer {
|
||||
|
||||
Action<String, String, String> funcOne;
|
||||
Action<String, String, int, String, String> funcTwo;
|
||||
AuthType type;
|
||||
public SimpleHttpServer(int port, Action<String, String, String> func,AuthType type) : base(port)
|
||||
{
|
||||
this.funcOne = func;
|
||||
this.type = type;
|
||||
}
|
||||
public SimpleHttpServer(int port, Action<String, String, int, String, String> func, AuthType type) : base(port)
|
||||
{
|
||||
this.funcTwo = func;
|
||||
this.type = type;
|
||||
}
|
||||
public override void handleGETRequest (HttpProcessor p)
|
||||
{
|
||||
p.writeSuccess();
|
||||
if (p.http_url == "/favicon.ico")
|
||||
return;
|
||||
|
||||
|
||||
|
||||
|
||||
Thread t = null;
|
||||
if(type == AuthType.AUTHORIZATION)
|
||||
{
|
||||
String url = p.http_url;
|
||||
url = url.Substring(2, url.Length - 2);
|
||||
NameValueCollection col = HttpUtility.ParseQueryString(url);
|
||||
if (col.Keys.Get(0) != "code")
|
||||
{
|
||||
p.outputStream.WriteLine("<html><body><h1>Spotify Auth canceled!</h1></body></html>");
|
||||
t = new Thread(new ParameterizedThreadStart((o) => { funcOne(null, col.Get(1), col.Get(0)); }));
|
||||
}
|
||||
else
|
||||
{
|
||||
p.outputStream.WriteLine("<html><body><h1>Spotify Auth successful!</h1></body></html>");
|
||||
t = new Thread(new ParameterizedThreadStart((o) => { funcOne(col.Get(0), col.Get(1), null); }));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(p.http_url == "/")
|
||||
{
|
||||
p.outputStream.WriteLine("<html><body>" +
|
||||
"<script>" +
|
||||
"" +
|
||||
"var hashes = window.location.hash;" +
|
||||
"hashes = hashes.replace('#','&');" +
|
||||
"window.location = hashes" +
|
||||
"</script>" +
|
||||
"<h1>Spotify Auth successful!<br>Please copy the URL and paste it into the application</h1></body></html>");
|
||||
return;
|
||||
}
|
||||
String url = p.http_url;
|
||||
url = url.Substring(2, url.Length - 2);
|
||||
NameValueCollection col = HttpUtility.ParseQueryString(url);
|
||||
if (col.Keys.Get(0) != "access_token")
|
||||
{
|
||||
p.outputStream.WriteLine("<html><body><h1>Spotify Auth canceled!</h1></body></html>");
|
||||
t = new Thread(new ParameterizedThreadStart((o) => { funcTwo(null, null,0,col.Get(1),col.Get(0)); }));
|
||||
}
|
||||
else
|
||||
{
|
||||
p.outputStream.WriteLine("<html><body><h1>Spotify Auth successful!</h1></body></html>");
|
||||
t = new Thread(new ParameterizedThreadStart((o) => { funcTwo(col.Get(0), col.Get(1), Convert.ToInt32(col.Get(2)),col.Get(3),null); }));
|
||||
}
|
||||
}
|
||||
t.Start();
|
||||
|
||||
}
|
||||
|
||||
public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData)
|
||||
{
|
||||
p.writeSuccess();
|
||||
}
|
||||
}
|
||||
public enum AuthType
|
||||
{
|
||||
IMPLICIT,AUTHORIZATION
|
||||
}
|
||||
}
|
175
SpotifyAPI/SpotifyWebAPI/SpotifyWebAPIClass.cs
Normal file
175
SpotifyAPI/SpotifyWebAPI/SpotifyWebAPIClass.cs
Normal file
@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
using SpotifyAPI.SpotifyWebAPI;
|
||||
using SpotifyAPI.SpotifyWebAPI.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
public class SpotifyWebAPIClass
|
||||
{
|
||||
public String TokenType { get; set; }
|
||||
public String AccessToken { get; set; }
|
||||
/// <summary>
|
||||
/// Set to false, if you want anonymous calls without auth
|
||||
/// </summary>
|
||||
public Boolean UseAuth { get; set; }
|
||||
|
||||
WebClient webclient;
|
||||
JsonSerializerSettings settings;
|
||||
public SpotifyWebAPIClass()
|
||||
{
|
||||
UseAuth = true;
|
||||
webclient = new WebClient();
|
||||
webclient.Proxy = null;
|
||||
settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
|
||||
}
|
||||
public PrivateProfile GetPrivateProfile()
|
||||
{
|
||||
return DownloadString<PrivateProfile>("https://api.spotify.com/v1/me");
|
||||
}
|
||||
public PublicProfile GetPublicProfile(String userId = "")
|
||||
{
|
||||
if(userId.Length == 0)
|
||||
return DownloadString<PublicProfile>("https://api.spotify.com/v1/me");
|
||||
else
|
||||
return DownloadString<PublicProfile>("https://api.spotify.com/v1/users/" + userId);
|
||||
}
|
||||
public Paging<SimplePlaylist> GetUserPlaylists(String userId)
|
||||
{
|
||||
return DownloadString<Paging<SimplePlaylist>>("https://api.spotify.com/v1/users/" + userId + "/playlists");
|
||||
}
|
||||
public FullPlaylist GetPlaylist(String userId,String playlistId)
|
||||
{
|
||||
return DownloadString<FullPlaylist>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId);
|
||||
}
|
||||
public Paging<PlaylistTrack> GetPlaylistTracks(String userId,String playlistId)
|
||||
{
|
||||
return DownloadString<Paging<PlaylistTrack>>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks");
|
||||
}
|
||||
public FullPlaylist CreatePlaylist(String userId,String playlistName,Boolean isPublic = true)
|
||||
{
|
||||
CreatePlaylistArgs args = new CreatePlaylistArgs()
|
||||
{
|
||||
Name = playlistName,
|
||||
Public = isPublic
|
||||
};
|
||||
return UploadData<FullPlaylist>("https://api.spotify.com/v1/users/" + userId + "/playlists",JsonConvert.SerializeObject(args));
|
||||
}
|
||||
public Error AddTracks(String userId,String playlistId,List<String> uris,int position = int.MaxValue)
|
||||
{
|
||||
if(position == int.MaxValue)
|
||||
return UploadData<Error>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", JsonConvert.SerializeObject(uris));
|
||||
else
|
||||
{
|
||||
String tracks = string.Join(",", uris);
|
||||
return UploadData<Error>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks?position=" + position
|
||||
+ "&ids=" + tracks
|
||||
, JsonConvert.SerializeObject(uris));
|
||||
}
|
||||
}
|
||||
public SearchItem SearchItems(String q,SearchType type,int limit = 20,int offset = 0)
|
||||
{
|
||||
limit = Math.Min(50, limit);
|
||||
StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/search");
|
||||
builder.Append("?q=" + q);
|
||||
builder.Append("&type=" + type.GetSearchValue(","));
|
||||
builder.Append("&limit=" + limit);
|
||||
builder.Append("&offset=" + offset);
|
||||
|
||||
return DownloadString<SearchItem>(builder.ToString());
|
||||
}
|
||||
public SeveralTracks GetSeveralTracks(List<String> ids)
|
||||
{
|
||||
return DownloadString<SeveralTracks>("https://api.spotify.com/v1/tracks?ids=" + string.Join(",",ids));
|
||||
}
|
||||
public SeveralAlbums GetSeveralAlbums(List<String> ids)
|
||||
{
|
||||
return DownloadString<SeveralAlbums>("https://api.spotify.com/v1/albums?ids=" + string.Join(",", ids));
|
||||
}
|
||||
public SeveralArtists GetSeveralArtists(List<String> ids)
|
||||
{
|
||||
return DownloadString<SeveralArtists>("https://api.spotify.com/v1/artists?ids=" + string.Join(",", ids));
|
||||
}
|
||||
public FullTrack GetTrack(String id)
|
||||
{
|
||||
return DownloadString<FullTrack>("https://api.spotify.com/v1/tracks/" + id);
|
||||
}
|
||||
public SeveralArtists GetRelatedArtists(String id)
|
||||
{
|
||||
return DownloadString<SeveralArtists>("https://api.spotify.com/v1/artists/" + id + "/related-artists");
|
||||
}
|
||||
public SeveralTracks GetArtistsTopTracks(String id, String country)
|
||||
{
|
||||
return DownloadString<SeveralTracks>("https://api.spotify.com/v1/artists/" + id + "/top-tracks?country=" + country);
|
||||
}
|
||||
public Paging<SimpleAlbum> GetArtistsAlbums(String id,AlbumType type = AlbumType.ALL,String country = "",int limit = 20,int offset = 0)
|
||||
{
|
||||
limit = Math.Min(50, limit);
|
||||
StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/artists/" + id + "/albums");
|
||||
builder.Append("?type=" + type.GetAlbumValue(","));
|
||||
builder.Append("&limit=" + limit);
|
||||
builder.Append("&offset=" + offset);
|
||||
return DownloadString<Paging<SimpleAlbum>>(builder.ToString());
|
||||
}
|
||||
public FullArtist GetArtist(String id)
|
||||
{
|
||||
return DownloadString<FullArtist>("https://api.spotify.com/v1/artists/" + id);
|
||||
}
|
||||
public Paging<SimpleTrack> GetAlbumTracks(String id,int limit = 20,int offset = 0)
|
||||
{
|
||||
limit = Math.Min(50, limit);
|
||||
StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/albums/" + id + "/tracks");
|
||||
builder.Append("?limit=" + limit);
|
||||
builder.Append("&offset=" + offset);
|
||||
return DownloadString<Paging<SimpleTrack>>(builder.ToString());
|
||||
}
|
||||
public FullAlbum GetAlbum(String id )
|
||||
{
|
||||
return DownloadString<FullAlbum>("https://api.spotify.com/v1/albums/" + id);
|
||||
}
|
||||
public T UploadData<T>(String url,String uploadData)
|
||||
{
|
||||
if (!UseAuth)
|
||||
throw new Exception("UseAuth required for 'UploadData'");
|
||||
webclient.Headers.Add("Authorization", TokenType + " " + AccessToken);
|
||||
webclient.Headers.Add("Content-Type","application/json");
|
||||
String response = "";
|
||||
try
|
||||
{
|
||||
byte[] data = webclient.UploadData(url,Encoding.UTF8.GetBytes(uploadData));
|
||||
response = Encoding.UTF8.GetString(data);
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
response = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
|
||||
}
|
||||
return JsonConvert.DeserializeObject<T>(response, settings);
|
||||
}
|
||||
public T DownloadString<T>(String url)
|
||||
{
|
||||
if(UseAuth)
|
||||
webclient.Headers.Add("Authorization", TokenType + " " + AccessToken);
|
||||
String response = "";
|
||||
try
|
||||
{
|
||||
byte [] data = webclient.DownloadData(url);
|
||||
response = Encoding.UTF8.GetString(data);
|
||||
}catch(WebException e)
|
||||
{
|
||||
response = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
|
||||
}
|
||||
return JsonConvert.DeserializeObject<T>(response, settings);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
webclient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
18
SpotifyAPI/SpotifyWebAPI/StringAttribute.cs
Normal file
18
SpotifyAPI/SpotifyWebAPI/StringAttribute.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
public class StringAttribute : Attribute
|
||||
{
|
||||
public String Text {get;set;}
|
||||
public StringAttribute(String text)
|
||||
{
|
||||
this.Text = text;
|
||||
}
|
||||
}
|
||||
}
|
56
SpotifyAPI/SpotifyWebAPI/Util.cs
Normal file
56
SpotifyAPI/SpotifyWebAPI/Util.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using SpotifyAPI.SpotifyWebAPI.Models;
|
||||
|
||||
namespace SpotifyAPI.SpotifyWebAPI
|
||||
{
|
||||
public static class Util
|
||||
{
|
||||
public static string GetScopeValue(this Scope en,String separator)
|
||||
{
|
||||
IEnumerable<StringAttribute> attributes =
|
||||
Enum.GetValues(typeof(Scope))
|
||||
.Cast<Scope>()
|
||||
.Where(v => en.HasFlag(v))
|
||||
.Select(v => typeof(Scope).GetField(v.ToString()))
|
||||
.Select(f => f.GetCustomAttributes(typeof(StringAttribute), false)[0])
|
||||
.Cast<StringAttribute>();
|
||||
|
||||
List<String> list = new List<String>();
|
||||
attributes.ToList().ForEach((element) => list.Add(element.Text));
|
||||
return string.Join(" ", list);
|
||||
}
|
||||
public static string GetSearchValue(this SearchType en, String separator)
|
||||
{
|
||||
IEnumerable<StringAttribute> attributes =
|
||||
Enum.GetValues(typeof(SearchType))
|
||||
.Cast<SearchType>()
|
||||
.Where(v => en.HasFlag(v))
|
||||
.Select(v => typeof(SearchType).GetField(v.ToString()))
|
||||
.Select(f => f.GetCustomAttributes(typeof(StringAttribute), false)[0])
|
||||
.Cast<StringAttribute>();
|
||||
|
||||
List<String> list = new List<String>();
|
||||
attributes.ToList().ForEach((element) => list.Add(element.Text));
|
||||
return string.Join(" ", list);
|
||||
}
|
||||
public static string GetAlbumValue(this AlbumType en, String separator)
|
||||
{
|
||||
IEnumerable<StringAttribute> attributes =
|
||||
Enum.GetValues(typeof(AlbumType))
|
||||
.Cast<AlbumType>()
|
||||
.Where(v => en.HasFlag(v))
|
||||
.Select(v => typeof(AlbumType).GetField(v.ToString()))
|
||||
.Select(f => f.GetCustomAttributes(typeof(StringAttribute), false)[0])
|
||||
.Cast<StringAttribute>();
|
||||
|
||||
List<String> list = new List<String>();
|
||||
attributes.ToList().ForEach((element) => list.Add(element.Text));
|
||||
return string.Join(" ", list);
|
||||
}
|
||||
}
|
||||
}
|
2
SpotifyAPI_Example/Form1.Designer.cs
generated
2
SpotifyAPI_Example/Form1.Designer.cs
generated
@ -336,7 +336,7 @@
|
||||
this.MaximumSize = new System.Drawing.Size(1018, 702);
|
||||
this.MinimumSize = new System.Drawing.Size(1018, 702);
|
||||
this.Name = "Form1";
|
||||
this.Text = "SpotifyAPI Example";
|
||||
this.Text = "SpotifyLocalAPIClass Example";
|
||||
this.Load += new System.EventHandler(this.Form1_Load);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
|
@ -8,29 +8,29 @@ using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using SpotifyAPIv1;
|
||||
using SpotifyAPI.SpotifyLocalAPI;
|
||||
using System.Threading;
|
||||
using SpotifyEventHandler = SpotifyAPIv1.SpotifyEventHandler;
|
||||
using SpotifyEventHandler = SpotifyAPI.SpotifyLocalAPI.SpotifyEventHandler;
|
||||
|
||||
|
||||
namespace SpotifyAPI_Example
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
SpotifyAPI spotify;
|
||||
SpotifyLocalAPIClass spotify;
|
||||
SpotifyMusicHandler mh;
|
||||
SpotifyEventHandler eh;
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
spotify = new SpotifyAPI();
|
||||
if (!SpotifyAPI.IsSpotifyRunning())
|
||||
spotify = new SpotifyLocalAPIClass();
|
||||
if (!SpotifyLocalAPIClass.IsSpotifyRunning())
|
||||
{
|
||||
spotify.RunSpotify();
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
|
||||
if (!SpotifyAPI.IsSpotifyWebHelperRunning())
|
||||
|
||||
if (!SpotifyLocalAPIClass.IsSpotifyWebHelperRunning())
|
||||
{
|
||||
spotify.RunSpotifyWebHelper();
|
||||
Thread.Sleep(4000);
|
||||
@ -41,7 +41,7 @@ namespace SpotifyAPI_Example
|
||||
Boolean retry = true;
|
||||
while(retry)
|
||||
{
|
||||
if (MessageBox.Show("SpotifyAPI could'nt load!", "Error", MessageBoxButtons.RetryCancel) == System.Windows.Forms.DialogResult.Retry)
|
||||
if (MessageBox.Show("SpotifyLocalAPIClass could'nt load!", "Error", MessageBoxButtons.RetryCancel) == System.Windows.Forms.DialogResult.Retry)
|
||||
{
|
||||
if(spotify.Connect())
|
||||
retry = false;
|
||||
|
6
SpotifyWebAPIExample/App.config
Normal file
6
SpotifyWebAPIExample/App.config
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
</configuration>
|
145
SpotifyWebAPIExample/Program.cs
Normal file
145
SpotifyWebAPIExample/Program.cs
Normal file
@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using SpotifyAPI.SpotifyWebAPI;
|
||||
using SpotifyAPI.SpotifyWebAPI.Models;
|
||||
|
||||
namespace SpotifyWebAPIExample
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static ImplicitGrantAuth auth;
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("### SpotifyWebAPI .NET Test App");
|
||||
Console.WriteLine("Starting auth process...");
|
||||
//Create the auth object
|
||||
auth = new ImplicitGrantAuth()
|
||||
{
|
||||
//Your client Id
|
||||
ClientId = "26d287105e31491889f3cd293d85bfea",
|
||||
//Set this to localhost if you want to use the built-in HTTP Server
|
||||
RedirectUri = "http://localhost",
|
||||
//How many permissions we need?
|
||||
Scope = Scope.USER_READ_PRIVATE | Scope.USER_READ_EMAIL | Scope.PLAYLIST_READ_PRIVATE
|
||||
};
|
||||
//Start the internal http server
|
||||
auth.StartHttpServer();
|
||||
//When we got our response
|
||||
auth.OnResponseReceivedEvent += auth_OnResponseReceivedEvent;
|
||||
//Start
|
||||
auth.DoAuth();
|
||||
}
|
||||
|
||||
static void auth_OnResponseReceivedEvent(Token token, string state, string error)
|
||||
{
|
||||
//stop the http server
|
||||
auth.StopHttpServer();
|
||||
|
||||
if(error != null)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Error: " + error);
|
||||
return;
|
||||
}
|
||||
DisplayMenu(new SpotifyWebAPIClass()
|
||||
{
|
||||
AccessToken = token.AccessToken,
|
||||
TokenType = token.TokenType,
|
||||
UseAuth = true
|
||||
});
|
||||
}
|
||||
|
||||
public static void DisplayMenu(SpotifyWebAPIClass spotify)
|
||||
{
|
||||
Console.WriteLine("Choose one of the following Tests:");
|
||||
Console.WriteLine("1 - Display Profile information");
|
||||
Console.WriteLine("2 - Display all of your playlists");
|
||||
Console.WriteLine("3 - List all of your playlist-tracks");
|
||||
Console.Write("Number: ");
|
||||
String number = Console.ReadLine();
|
||||
switch (number)
|
||||
{
|
||||
default:
|
||||
DisplayMenu(spotify);
|
||||
break;
|
||||
case "1":
|
||||
DisplayProfile(spotify);
|
||||
break;
|
||||
case "2":
|
||||
DisplayPlaylists(spotify);
|
||||
break;
|
||||
case "3":
|
||||
DisplayPlaylistTracks(spotify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public static void DisplayProfile(SpotifyWebAPIClass spotify)
|
||||
{
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
PrivateProfile profile = spotify.GetPrivateProfile();
|
||||
Console.WriteLine("Your Display name: " + profile.DisplayName);
|
||||
Console.WriteLine("Your Country: " + profile.Country);
|
||||
Console.WriteLine("Your ID: " + profile.Id);
|
||||
Console.WriteLine("Account product: " + profile.Product);
|
||||
Console.WriteLine("Your images:");
|
||||
foreach (Image image in profile.Images)
|
||||
Console.WriteLine("- " + image.Url);
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
DisplayMenu(spotify);
|
||||
}
|
||||
private static void DisplayPlaylists(SpotifyWebAPIClass spotify)
|
||||
{
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
Paging<SimplePlaylist> playlists = spotify.GetUserPlaylists(spotify.GetPublicProfile().Id);
|
||||
|
||||
Console.WriteLine("Printing playlists...");
|
||||
Console.WriteLine("");
|
||||
foreach (SimplePlaylist playlist in playlists.Items)
|
||||
Console.WriteLine(playlist.Name + " (" + playlist.Id + ")");
|
||||
while(playlists.Next != null)
|
||||
{
|
||||
playlists = spotify.DownloadString<Paging<SimplePlaylist>>(playlists.Next);
|
||||
foreach (SimplePlaylist playlist in playlists.Items)
|
||||
Console.WriteLine(playlist.Name + " (" + playlist.Id + ")");
|
||||
}
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
DisplayMenu(spotify);
|
||||
}
|
||||
private static void DisplayPlaylistTracks(SpotifyWebAPIClass spotify)
|
||||
{
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
Console.Write("Playlist ID (must be one of yours): ");
|
||||
String id = Console.ReadLine();
|
||||
|
||||
Paging<PlaylistTrack> col = spotify.GetPlaylistTracks(spotify.GetPrivateProfile().Id, id);
|
||||
if(col.HasError())
|
||||
{
|
||||
Console.WriteLine("ERROR: " + col.Error.Message);
|
||||
DisplayMenu(spotify);
|
||||
return;
|
||||
}
|
||||
foreach(PlaylistTrack track in col.Items)
|
||||
Console.WriteLine(track.Track.Name + " (" + track.Track.Id + ")");
|
||||
while (col.Next != null)
|
||||
{
|
||||
col = spotify.DownloadString<Paging<PlaylistTrack>>(col.Next);
|
||||
foreach (PlaylistTrack track in col.Items)
|
||||
Console.WriteLine(track.Track.Name + " (" + track.Track.Id + ")");
|
||||
}
|
||||
DisplayMenu(spotify);
|
||||
}
|
||||
}
|
||||
}
|
36
SpotifyWebAPIExample/Properties/AssemblyInfo.cs
Normal file
36
SpotifyWebAPIExample/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 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("SpotifyWebAPIExample")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SpotifyWebAPIExample")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[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
|
||||
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("a09c6b3c-dd43-4423-9daa-4b69f031e695")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// 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")]
|
66
SpotifyWebAPIExample/SpotifyWebAPIExample.csproj
Normal file
66
SpotifyWebAPIExample/SpotifyWebAPIExample.csproj
Normal file
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{004B45C3-BB98-4E62-AD11-D80BA64FEB8E}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SpotifyWebAPIExample</RootNamespace>
|
||||
<AssemblyName>SpotifyWebAPIExample</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SpotifyAPI\SpotifyAPI.csproj">
|
||||
<Project>{ebbe35e2-7b91-4d7d-b8fc-3a0472f5119d}</Project>
|
||||
<Name>SpotifyAPI</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user