Spotify.NET/SpotifyAPI/Local/RemoteHandler.cs

170 lines
5.4 KiB
C#
Raw Normal View History

using Newtonsoft.Json;
using SpotifyAPI.Local.Models;
using System;
2014-01-07 15:26:03 +00:00
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading.Tasks;
2014-01-07 15:26:03 +00:00
namespace SpotifyAPI.Local
2014-01-07 15:26:03 +00:00
{
internal class RemoteHandler
2014-01-07 15:26:03 +00:00
{
public String OauthKey { get; private set; }
public String CfidKey { get; private set; }
public const String Host = "SpotifyAPI.spotilocal.com";
2014-02-14 12:04:45 +00:00
internal Boolean Init()
2014-01-07 15:26:03 +00:00
{
OauthKey = GetOAuthKey();
CfidKey = GetCfid();
return !String.IsNullOrEmpty(CfidKey);
2014-01-07 15:26:03 +00:00
}
internal async void SendPauseRequest()
2014-01-10 07:09:14 +00:00
{
await QueryAsync("remote/pause.json?pause=true", true, true, -1);
2014-01-10 07:09:14 +00:00
}
internal async void SendPlayRequest()
2014-01-10 07:09:14 +00:00
{
await QueryAsync("remote/pause.json?pause=false", true, true, -1);
2014-01-10 07:09:14 +00:00
}
internal async void SendPlayRequest(String url, String context = "")
2014-02-01 12:52:33 +00:00
{
2015-03-12 18:44:54 +00:00
// TODO: instead of having an empty context, one way to fix the bug with the playback time beyond the length of a song would be to provide a 1-song context, and it would be fixed.
2015-10-28 16:05:09 +00:00
await QueryAsync($"remote/play.json?uri={url}&context={context}", true, true, -1);
2014-02-01 12:52:33 +00:00
}
internal async void SendQueueRequest(String url)
{
await QueryAsync("remote/play.json?uri=" + url + "?action=queue", true, true, -1);
}
internal StatusResponse GetNewStatus()
2014-01-08 22:22:54 +00:00
{
String response = Query("remote/status.json", true, true, -1);
if (String.IsNullOrEmpty(response))
2014-01-08 22:22:54 +00:00
{
2014-02-13 13:23:52 +00:00
return null;
2014-01-08 22:22:54 +00:00
}
response = response.Replace("\\n", "");
2014-02-01 12:52:33 +00:00
byte[] bytes = Encoding.Default.GetBytes(response);
response = Encoding.UTF8.GetString(bytes);
List<StatusResponse> raw = JsonConvert.DeserializeObject<List<StatusResponse>>(response);
2014-01-08 22:22:54 +00:00
return raw[0];
}
2014-02-13 13:23:52 +00:00
internal String GetOAuthKey()
2014-01-07 15:26:03 +00:00
{
String raw;
using (WebClient wc = new WebClient())
2014-01-07 15:26:03 +00:00
{
2014-01-10 07:09:14 +00:00
raw = wc.DownloadString("http://open.spotify.com/token");
2014-01-07 15:26:03 +00:00
}
Dictionary<String, object> dic = JsonConvert.DeserializeObject<Dictionary<String, object>>(raw);
return dic == null ? "" : (String)dic["t"];
2014-01-07 15:26:03 +00:00
}
internal string GetCfid()
2014-01-07 15:26:03 +00:00
{
string response = Query("simplecsrf/token.json", false, false, -1);
response = response.Replace(@"\", "");
List<Cfid> cfidList = (List<Cfid>)JsonConvert.DeserializeObject(response, typeof(List<Cfid>));
if (cfidList == null)
return "";
if (cfidList.Count != 1)
throw new Exception("CFID could not be loaded");
return cfidList[0].Error == null ? cfidList[0].Token : "";
2014-01-07 15:26:03 +00:00
}
internal string Query(string request, bool oauth, bool cfid, int wait)
2014-01-07 15:26:03 +00:00
{
2014-02-01 12:52:33 +00:00
string parameters = "?&ref=&cors=&_=" + GetTimestamp();
2014-01-07 15:26:03 +00:00
if (request.Contains("?"))
{
parameters = parameters.Substring(1);
}
if (oauth)
{
parameters += "&oauth=" + OauthKey;
2014-01-07 15:26:03 +00:00
}
if (cfid)
{
parameters += "&csrf=" + CfidKey;
2014-01-07 15:26:03 +00:00
}
if (wait != -1)
{
parameters += "&returnafter=" + wait;
parameters += "&returnon=login%2Clogout%2Cplay%2Cpause%2Cerror%2Cap";
}
string address = "http://" + Host + ":4380/" + request + parameters;
2014-02-13 13:23:52 +00:00
string response = "";
2014-01-07 15:26:03 +00:00
try
{
using (var wc = new ExtendedWebClient())
{
if (SpotifyLocalAPI.IsSpotifyRunning())
response = "[ " + wc.DownloadString(address) + " ]";
}
2014-01-07 15:26:03 +00:00
}
catch
2014-01-07 15:26:03 +00:00
{
return String.Empty;
}
return response;
}
internal async Task<string> QueryAsync(string request, bool oauth, bool cfid, int wait)
{
string parameters = "?&ref=&cors=&_=" + GetTimestamp();
if (request.Contains("?"))
{
parameters = parameters.Substring(1);
}
if (oauth)
{
parameters += "&oauth=" + OauthKey;
}
if (cfid)
{
parameters += "&csrf=" + CfidKey;
}
if (wait != -1)
{
parameters += "&returnafter=" + wait;
parameters += "&returnon=login%2Clogout%2Cplay%2Cpause%2Cerror%2Cap";
}
string address = "http://" + Host + ":4380/" + request + parameters;
string response = "";
try
{
using (var wc = new ExtendedWebClient())
{
if (SpotifyLocalAPI.IsSpotifyRunning())
response = "[ " + await wc.DownloadStringTaskAsync(new Uri(address)) + " ]";
}
}
catch
{
return String.Empty;
2014-01-07 15:26:03 +00:00
}
2014-02-13 13:23:52 +00:00
return response;
2014-01-07 15:26:03 +00:00
}
2014-02-13 13:23:52 +00:00
internal int GetTimestamp()
2014-01-10 07:09:14 +00:00
{
2014-02-01 12:52:33 +00:00
return Convert.ToInt32((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
2014-01-10 07:09:14 +00:00
}
2014-01-07 15:26:03 +00:00
}
}