Added support for streams for EditStream(icon) and EditUser(avatar)
This commit is contained in:
@@ -45,7 +45,6 @@
|
|||||||
|
|
||||||
public const string Voice = "voice";
|
public const string Voice = "voice";
|
||||||
public const string VoiceRegions = "voice/regions";
|
public const string VoiceRegions = "voice/regions";
|
||||||
//public const string VoiceIce = "voice/ice";
|
|
||||||
|
|
||||||
public const string StatusActiveMaintenance = "scheduled-maintenances/active.json";
|
public const string StatusActiveMaintenance = "scheduled-maintenances/active.json";
|
||||||
public const string StatusUpcomingMaintenance = "scheduled-maintenances/upcoming.json";
|
public const string StatusUpcomingMaintenance = "scheduled-maintenances/upcoming.json";
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Discord.Net.Rest;
|
using Discord.Net.Rest;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -198,12 +199,13 @@ namespace Discord
|
|||||||
var request = new SendMessageRequest { Content = message, Mentions = mentionedUserIds ?? new long[0], Nonce = nonce, IsTTS = isTTS ? true : false };
|
var request = new SendMessageRequest { Content = message, Mentions = mentionedUserIds ?? new long[0], Nonce = nonce, IsTTS = isTTS ? true : false };
|
||||||
return _rest.Post<SendMessageResponse>(Endpoints.ChannelMessages(channelId), request);
|
return _rest.Post<SendMessageResponse>(Endpoints.ChannelMessages(channelId), request);
|
||||||
}
|
}
|
||||||
public Task<SendMessageResponse> SendFile(long channelId, string filePath)
|
public Task<SendMessageResponse> SendFile(long channelId, string filename, Stream stream)
|
||||||
{
|
{
|
||||||
if (channelId <= 0) throw new ArgumentOutOfRangeException(nameof(channelId));
|
if (channelId <= 0) throw new ArgumentOutOfRangeException(nameof(channelId));
|
||||||
if (filePath == null) throw new ArgumentNullException(nameof(filePath));
|
if (filename == null) throw new ArgumentNullException(nameof(filename));
|
||||||
|
if (stream == null) throw new ArgumentNullException(nameof(stream));
|
||||||
|
|
||||||
return _rest.PostFile<SendMessageResponse>(Endpoints.ChannelMessages(channelId), filePath);
|
return _rest.PostFile<SendMessageResponse>(Endpoints.ChannelMessages(channelId), filename, stream);
|
||||||
}
|
}
|
||||||
public Task DeleteMessage(long messageId, long channelId)
|
public Task DeleteMessage(long messageId, long channelId)
|
||||||
{
|
{
|
||||||
@@ -301,38 +303,39 @@ namespace Discord
|
|||||||
|
|
||||||
return _rest.Delete<DeleteServerResponse>(Endpoints.Server(serverId));
|
return _rest.Delete<DeleteServerResponse>(Endpoints.Server(serverId));
|
||||||
}
|
}
|
||||||
public Task<EditServerResponse> EditServer(long serverId, string name = null, string region = null, ImageType iconType = ImageType.Png, byte[] icon = null)
|
public Task<EditServerResponse> EditServer(long serverId, string name = null, string region = null, Stream icon = null, ImageType iconType = ImageType.Png)
|
||||||
{
|
{
|
||||||
if (serverId <= 0) throw new ArgumentOutOfRangeException(nameof(serverId));
|
if (serverId <= 0) throw new ArgumentOutOfRangeException(nameof(serverId));
|
||||||
|
|
||||||
var request = new EditServerRequest { Name = name, Region = region, Icon = Base64Picture(iconType, icon) };
|
var request = new EditServerRequest { Name = name, Region = region, Icon = Base64Picture(icon, iconType) };
|
||||||
return _rest.Patch<EditServerResponse>(Endpoints.Server(serverId), request);
|
return _rest.Patch<EditServerResponse>(Endpoints.Server(serverId), request);
|
||||||
}
|
}
|
||||||
|
|
||||||
//User
|
//User
|
||||||
public Task<EditUserResponse> EditUser(string currentPassword = "",
|
public Task<EditUserResponse> EditProfile(string currentPassword = "",
|
||||||
string username = null, string email = null, string password = null,
|
string username = null, string email = null, string password = null,
|
||||||
ImageType avatarType = ImageType.Png, byte[] avatar = null)
|
Stream avatar = null, ImageType avatarType = ImageType.Png)
|
||||||
{
|
{
|
||||||
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword));
|
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword));
|
||||||
|
|
||||||
var request = new EditUserRequest { CurrentPassword = currentPassword, Username = username, Email = email, Password = password, Avatar = Base64Picture(avatarType, avatar) };
|
var request = new EditUserRequest { CurrentPassword = currentPassword, Username = username, Email = email, Password = password, Avatar = Base64Picture(avatar, avatarType) };
|
||||||
return _rest.Patch<EditUserResponse>(Endpoints.UserMe, request);
|
return _rest.Patch<EditUserResponse>(Endpoints.UserMe, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Voice
|
//Voice
|
||||||
public Task<GetRegionsResponse> GetVoiceRegions()
|
public Task<GetRegionsResponse> GetVoiceRegions()
|
||||||
=> _rest.Get<GetRegionsResponse>(Endpoints.VoiceRegions);
|
=> _rest.Get<GetRegionsResponse>(Endpoints.VoiceRegions);
|
||||||
/*public Task<GetIceResponse> GetVoiceIce()
|
|
||||||
=> _rest.Get<GetIceResponse>(Endpoints.VoiceIce);*/
|
|
||||||
|
|
||||||
private string Base64Picture(ImageType type, byte[] data)
|
private string Base64Picture(Stream stream, ImageType type)
|
||||||
{
|
{
|
||||||
if (type == ImageType.None)
|
if (type == ImageType.None)
|
||||||
return "";
|
return "";
|
||||||
else if (data != null)
|
else if (stream != null)
|
||||||
{
|
{
|
||||||
string base64 = Convert.ToBase64String(data);
|
byte[] bytes = new byte[stream.Length - stream.Position];
|
||||||
|
stream.Read(bytes, 0, bytes.Length);
|
||||||
|
|
||||||
|
string base64 = Convert.ToBase64String(bytes);
|
||||||
string imageType = type == ImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64";
|
string imageType = type == ImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64";
|
||||||
return $"data:{imageType},{base64}";
|
return $"data:{imageType},{base64}";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,8 +170,18 @@ namespace Discord
|
|||||||
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
if (filePath == null) throw new ArgumentNullException(nameof(filePath));
|
if (filePath == null) throw new ArgumentNullException(nameof(filePath));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|
||||||
|
return _api.SendFile(channel.Id, Path.GetFileName(filePath), File.OpenRead(filePath));
|
||||||
|
}
|
||||||
|
/// <summary> Sends a file to the provided channel. </summary>
|
||||||
|
public Task SendFile(Channel channel, string filename, Stream stream)
|
||||||
|
{
|
||||||
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
|
if (filename == null) throw new ArgumentNullException(nameof(filename));
|
||||||
|
if (stream == null) throw new ArgumentNullException(nameof(stream));
|
||||||
|
CheckReady();
|
||||||
|
|
||||||
return _api.SendFile(channel.Id, filePath);
|
return _api.SendFile(channel.Id, filename, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Edits the provided message, changing only non-null attributes. </summary>
|
/// <summary> Edits the provided message, changing only non-null attributes. </summary>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -93,12 +94,12 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Edits the provided server, changing only non-null attributes. </summary>
|
/// <summary> Edits the provided server, changing only non-null attributes. </summary>
|
||||||
public async Task EditServer(Server server, string name = null, string region = null, ImageType iconType = ImageType.Png, byte[] icon = null)
|
public async Task EditServer(Server server, string name = null, string region = null, Stream icon = null, ImageType iconType = ImageType.Png)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|
||||||
var response = await _api.EditServer(server.Id, name: name ?? server.Name, region: region, iconType: iconType, icon: icon).ConfigureAwait(false);
|
var response = await _api.EditServer(server.Id, name: name ?? server.Name, region: region, icon: icon, iconType: iconType).ConfigureAwait(false);
|
||||||
server.Update(response);
|
server.Update(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -282,14 +283,14 @@ namespace Discord
|
|||||||
|
|
||||||
public Task EditProfile(string currentPassword = "",
|
public Task EditProfile(string currentPassword = "",
|
||||||
string username = null, string email = null, string password = null,
|
string username = null, string email = null, string password = null,
|
||||||
ImageType avatarType = ImageType.Png, byte[] avatar = null)
|
Stream avatar = null, ImageType avatarType = ImageType.Png)
|
||||||
{
|
{
|
||||||
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword));
|
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|
||||||
return _api.EditUser(currentPassword: currentPassword,
|
return _api.EditProfile(currentPassword: currentPassword,
|
||||||
username: username ?? _privateUser?.Name, email: email ?? _privateUser?.Global.Email, password: password,
|
username: username ?? _privateUser?.Name, email: email ?? _privateUser?.Global.Email, password: password,
|
||||||
avatarType: avatarType, avatar: avatar);
|
avatar: avatar, avatarType: avatarType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SetStatus(UserStatus status)
|
public Task SetStatus(UserStatus status)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Threading;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord.Net.Rest
|
namespace Discord.Net.Rest
|
||||||
@@ -7,6 +8,6 @@ namespace Discord.Net.Rest
|
|||||||
{
|
{
|
||||||
void SetToken(string token);
|
void SetToken(string token);
|
||||||
Task<string> Send(string method, string path, string json, CancellationToken cancelToken);
|
Task<string> Send(string method, string path, string json, CancellationToken cancelToken);
|
||||||
Task<string> SendFile(string method, string path, string filePath, CancellationToken cancelToken);
|
Task<string> SendFile(string method, string path, string filename, Stream stream, CancellationToken cancelToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -65,15 +66,15 @@ namespace Discord.Net.Rest
|
|||||||
internal Task Put(string path)
|
internal Task Put(string path)
|
||||||
=> Send("PUT", path);
|
=> Send("PUT", path);
|
||||||
|
|
||||||
internal Task<ResponseT> PostFile<ResponseT>(string path, string filePath) where ResponseT : class
|
internal Task<ResponseT> PostFile<ResponseT>(string path, string filename, Stream stream) where ResponseT : class
|
||||||
=> SendFile<ResponseT>("POST", path, filePath);
|
=> SendFile<ResponseT>("POST", path, filename, stream);
|
||||||
internal Task PostFile(string path, string filePath)
|
internal Task PostFile(string path, string filename, Stream stream)
|
||||||
=> SendFile("POST", path, filePath);
|
=> SendFile("POST", path, filename, stream);
|
||||||
|
|
||||||
internal Task<ResponseT> PutFile<ResponseT>(string path, string filePath) where ResponseT : class
|
internal Task<ResponseT> PutFile<ResponseT>(string path, string filename, Stream stream) where ResponseT : class
|
||||||
=> SendFile<ResponseT>("PUT", path, filePath);
|
=> SendFile<ResponseT>("PUT", path, filename, stream);
|
||||||
internal Task PutFile(string path, string filePath)
|
internal Task PutFile(string path, string filename, Stream stream)
|
||||||
=> SendFile("PUT", path, filePath);
|
=> SendFile("PUT", path, filename, stream);
|
||||||
|
|
||||||
private async Task<ResponseT> Send<ResponseT>(string method, string path, object content = null)
|
private async Task<ResponseT> Send<ResponseT>(string method, string path, object content = null)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
@@ -117,22 +118,22 @@ namespace Discord.Net.Rest
|
|||||||
return responseJson;
|
return responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ResponseT> SendFile<ResponseT>(string method, string path, string filePath)
|
private async Task<ResponseT> SendFile<ResponseT>(string method, string path, string filename, Stream stream)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
{
|
{
|
||||||
string responseJson = await SendFile(method, path, filePath, true).ConfigureAwait(false);
|
string responseJson = await SendFile(method, path, filename, stream, true).ConfigureAwait(false);
|
||||||
return DeserializeResponse<ResponseT>(responseJson);
|
return DeserializeResponse<ResponseT>(responseJson);
|
||||||
}
|
}
|
||||||
private Task SendFile(string method, string path, string filePath)
|
private Task SendFile(string method, string path, string filename, Stream stream)
|
||||||
=> SendFile(method, path, filePath, false);
|
=> SendFile(method, path, filename, stream, false);
|
||||||
private async Task<string> SendFile(string method, string path, string filePath, bool hasResponse)
|
private async Task<string> SendFile(string method, string path, string filename, Stream stream, bool hasResponse)
|
||||||
{
|
{
|
||||||
Stopwatch stopwatch = null;
|
Stopwatch stopwatch = null;
|
||||||
|
|
||||||
if (_config.LogLevel >= LogMessageSeverity.Verbose)
|
if (_config.LogLevel >= LogMessageSeverity.Verbose)
|
||||||
stopwatch = Stopwatch.StartNew();
|
stopwatch = Stopwatch.StartNew();
|
||||||
|
|
||||||
string responseJson = await _engine.SendFile(method, path, filePath, _cancelToken).ConfigureAwait(false);
|
string responseJson = await _engine.SendFile(method, path, filename, stream, _cancelToken).ConfigureAwait(false);
|
||||||
|
|
||||||
#if TEST_RESPONSES
|
#if TEST_RESPONSES
|
||||||
if (!hasResponse && !string.IsNullOrEmpty(responseJson))
|
if (!hasResponse && !string.IsNullOrEmpty(responseJson))
|
||||||
@@ -143,7 +144,7 @@ namespace Discord.Net.Rest
|
|||||||
{
|
{
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
if (_config.LogLevel >= LogMessageSeverity.Debug)
|
if (_config.LogLevel >= LogMessageSeverity.Debug)
|
||||||
RaiseOnRequest(method, path, filePath, stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond);
|
RaiseOnRequest(method, path, filename, stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond);
|
||||||
else
|
else
|
||||||
RaiseOnRequest(method, path, null, stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond);
|
RaiseOnRequest(method, path, null, stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Discord.API;
|
using Discord.API;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -44,10 +45,10 @@ namespace Discord.Net.Rest
|
|||||||
request.AddParameter("application/json", json, ParameterType.RequestBody);
|
request.AddParameter("application/json", json, ParameterType.RequestBody);
|
||||||
return Send(request, cancelToken);
|
return Send(request, cancelToken);
|
||||||
}
|
}
|
||||||
public Task<string> SendFile(string method, string path, string filePath, CancellationToken cancelToken)
|
public Task<string> SendFile(string method, string path, string filename, Stream stream, CancellationToken cancelToken)
|
||||||
{
|
{
|
||||||
var request = new RestRequest(path, Method.POST);
|
var request = new RestRequest(path, Method.POST);
|
||||||
request.AddFile("file", filePath);
|
request.AddFile("file", x => stream.CopyTo(x), filename);
|
||||||
return Send(request, cancelToken);
|
return Send(request, cancelToken);
|
||||||
}
|
}
|
||||||
private async Task<string> Send(RestRequest request, CancellationToken cancelToken)
|
private async Task<string> Send(RestRequest request, CancellationToken cancelToken)
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
"System.Collections": "4.0.11-beta-23516",
|
"System.Collections": "4.0.11-beta-23516",
|
||||||
"System.Collections.Concurrent": "4.0.11-beta-23516",
|
"System.Collections.Concurrent": "4.0.11-beta-23516",
|
||||||
"System.Dynamic.Runtime": "4.0.11-beta-23516",
|
"System.Dynamic.Runtime": "4.0.11-beta-23516",
|
||||||
|
"System.IO.FileSystem": "4.0.1-beta-23516",
|
||||||
"System.IO.Compression": "4.1.0-beta-23516",
|
"System.IO.Compression": "4.1.0-beta-23516",
|
||||||
"System.Linq": "4.0.1-beta-23516",
|
"System.Linq": "4.0.1-beta-23516",
|
||||||
"System.Net.NameResolution": "4.0.0-beta-23516",
|
"System.Net.NameResolution": "4.0.0-beta-23516",
|
||||||
|
|||||||
Reference in New Issue
Block a user