forked from JohnnyCrazy/SpotifyAPI-NET
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRemoteHandler.cs
More file actions
128 lines (112 loc) · 4.4 KB
/
RemoteHandler.cs
File metadata and controls
128 lines (112 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using Newtonsoft.Json;
using SpotifyAPI.Local.Models;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace SpotifyAPI.Local
{
internal class RemoteHandler
{
public string OauthKey { get; private set; }
public string CfidKey { get; private set; }
public const string Host = "127.0.0.1"; //Localhost since domain fails to resolve on some hosts
internal async Task<bool> Init()
{
OauthKey = await GetOAuthKey();
CfidKey = await GetCfid();
return !string.IsNullOrEmpty(CfidKey);
}
internal async Task SendPauseRequest()
{
await QueryAsync("remote/pause.json?pause=true", true, true, -1).ConfigureAwait(false);
}
internal async Task SendPlayRequest()
{
await QueryAsync("remote/pause.json?pause=false", true, true, -1).ConfigureAwait(false);
}
internal async Task SendPlayRequest(string url, string context = "")
{
// 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.
await QueryAsync($"remote/play.json?uri={url}&context={context}", true, true, -1).ConfigureAwait(false);
}
internal async Task SendQueueRequest(string url)
{
await QueryAsync("remote/play.json?uri=" + url + "?action=queue", true, true, -1).ConfigureAwait(false);
}
internal async Task<StatusResponse> GetNewStatus()
{
string response = await QueryAsync("remote/status.json", true, true, -1);
if (string.IsNullOrEmpty(response))
{
return null;
}
response = response.Replace("\\n", "");
byte[] bytes = Encoding.UTF8.GetBytes(response);
response = Encoding.UTF8.GetString(bytes);
List<StatusResponse> raw = JsonConvert.DeserializeObject<List<StatusResponse>>(response);
return raw[0];
}
internal async Task<string> GetOAuthKey()
{
using (HttpClient httpClient = new HttpClient())
{
string raw = await httpClient.GetStringAsync("http://open.spotify.com/token");
Dictionary<string, object> dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(raw);
return dic == null ? "" : (string) dic["t"];
}
}
internal async Task<string> GetCfid()
{
string response = await QueryAsync("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 : "";
}
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 = "https://" + Host + ":4371/" + request + parameters;
string response = "";
try
{
using (var wc = new ExtendedWebClient())
{
response = "[ " + await wc.GetStringAsync(new Uri(address)).ConfigureAwait(false) + " ]";
}
}
catch
{
return string.Empty;
}
return response;
}
internal int GetTimestamp()
{
return Convert.ToInt32((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
}
}
}