@@ -3945,6 +3945,33 @@ | |||
A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.IGuild.CreateStickerAsync(System.String,System.String,System.Collections.Generic.IEnumerable{System.String},System.String,Discord.RequestOptions)"> | |||
<summary> | |||
Creates a new sticker in this guild | |||
</summary> | |||
<param name="name">The name of the sticker.</param> | |||
<param name="description">The description of the sticker.</param> | |||
<param name="tags">The tags of the sticker.</param> | |||
<param name="path">The path of the file to upload.</param> | |||
<param name="options">The options to be used when sending the request.</param> | |||
<returns> | |||
A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.IGuild.CreateStickerAsync(System.String,System.String,System.Collections.Generic.IEnumerable{System.String},System.IO.Stream,System.String,Discord.RequestOptions)"> | |||
<summary> | |||
Creates a new sticker in this guild | |||
</summary> | |||
<param name="name">The name of the sticker.</param> | |||
<param name="description">The description of the sticker.</param> | |||
<param name="tags">The tags of the sticker.</param> | |||
<param name="stream">The stream containing the file data.</param> | |||
<param name="filename">The name of the file <b>with</b> the extension, ex: image.png</param> | |||
<param name="options">The options to be used when sending the request.</param> | |||
<returns> | |||
A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.IGuild.GetStickerAsync(System.UInt64,Discord.CacheMode,Discord.RequestOptions)"> | |||
<summary> | |||
Gets a specific sticker within this guild. | |||
@@ -2,6 +2,7 @@ using Discord.Audio; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Globalization; | |||
using System.IO; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
@@ -962,6 +963,33 @@ namespace Discord | |||
/// </returns> | |||
Task<ICustomSticker> CreateStickerAsync(string name, string description, IEnumerable<string> tags, Image image, RequestOptions options = null); | |||
/// <summary> | |||
/// Creates a new sticker in this guild | |||
/// </summary> | |||
/// <param name="name">The name of the sticker.</param> | |||
/// <param name="description">The description of the sticker.</param> | |||
/// <param name="tags">The tags of the sticker.</param> | |||
/// <param name="path">The path of the file to upload.</param> | |||
/// <param name="options">The options to be used when sending the request.</param> | |||
/// <returns> | |||
/// A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
/// </returns> | |||
Task<ICustomSticker> CreateStickerAsync(string name, string description, IEnumerable<string> tags, string path, RequestOptions options = null); | |||
/// <summary> | |||
/// Creates a new sticker in this guild | |||
/// </summary> | |||
/// <param name="name">The name of the sticker.</param> | |||
/// <param name="description">The description of the sticker.</param> | |||
/// <param name="tags">The tags of the sticker.</param> | |||
/// <param name="stream">The stream containing the file data.</param> | |||
/// <param name="filename">The name of the file <b>with</b> the extension, ex: image.png</param> | |||
/// <param name="options">The options to be used when sending the request.</param> | |||
/// <returns> | |||
/// A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
/// </returns> | |||
Task<ICustomSticker> CreateStickerAsync(string name, string description, IEnumerable<string> tags, Stream stream, string filename, RequestOptions options = null); | |||
/// <summary> | |||
/// Gets a specific sticker within this guild. | |||
/// </summary> | |||
@@ -1,4 +1,4 @@ | |||
using System.IO; | |||
using System.IO; | |||
namespace Discord.Net.Rest | |||
{ | |||
@@ -6,11 +6,13 @@ namespace Discord.Net.Rest | |||
{ | |||
public Stream Stream { get; } | |||
public string Filename { get; } | |||
public string ContentType { get; } | |||
public MultipartFile(Stream stream, string filename) | |||
public MultipartFile(Stream stream, string filename, string contentType = null) | |||
{ | |||
Stream = stream; | |||
Filename = filename; | |||
this.ContentType = contentType; | |||
} | |||
} | |||
} |
@@ -15,17 +15,25 @@ namespace Discord.API.Rest | |||
public string Name { get; set; } | |||
public string Description { get; set; } | |||
public string Tags { get; set; } | |||
public string FileName { get; set; } | |||
public IReadOnlyDictionary<string, object> ToDictionary() | |||
{ | |||
var d = new Dictionary<string, object>(); | |||
d["file"] = new MultipartFile(File, Name + ".dat"); | |||
d["name"] = Name; | |||
d["name"] = $"{Name}"; | |||
d["description"] = Description; | |||
d["tags"] = Tags; | |||
string contentType = "image/png"; | |||
if (File is FileStream fileStream) | |||
contentType = $"image/{Path.GetExtension(fileStream.Name)}"; | |||
else if(FileName != null) | |||
contentType = $"image/{Path.GetExtension(FileName)}"; | |||
d["file"] = new MultipartFile(File, FileName ?? "image", contentType.Replace(".", "")); | |||
return d; | |||
} | |||
} | |||
@@ -3540,6 +3540,33 @@ | |||
A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.CreateStickerAsync(System.String,System.String,System.Collections.Generic.IEnumerable{System.String},System.String,Discord.RequestOptions)"> | |||
<summary> | |||
Creates a new sticker in this guild | |||
</summary> | |||
<param name="name">The name of the sticker.</param> | |||
<param name="description">The description of the sticker.</param> | |||
<param name="tags">The tags of the sticker.</param> | |||
<param name="path">The path of the file to upload.</param> | |||
<param name="options">The options to be used when sending the request.</param> | |||
<returns> | |||
A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.CreateStickerAsync(System.String,System.String,System.Collections.Generic.IEnumerable{System.String},System.IO.Stream,System.String,Discord.RequestOptions)"> | |||
<summary> | |||
Creates a new sticker in this guild | |||
</summary> | |||
<param name="name">The name of the sticker.</param> | |||
<param name="description">The description of the sticker.</param> | |||
<param name="tags">The tags of the sticker.</param> | |||
<param name="stream">The stream containing the file data.</param> | |||
<param name="filename">The name of the file <b>with</b> the extension, ex: image.png</param> | |||
<param name="options">The options to be used when sending the request.</param> | |||
<returns> | |||
A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.GetStickerAsync(System.UInt64,Discord.RequestOptions)"> | |||
<summary> | |||
Gets a specific sticker within this guild. | |||
@@ -3707,6 +3734,24 @@ | |||
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#GetApplicationCommandsAsync(Discord.RequestOptions)"> | |||
<inheritdoc /> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#CreateStickerAsync(System.String,System.String,System.Collections.Generic.IEnumerable{System.String},Discord.Image,Discord.RequestOptions)"> | |||
<inheritdoc /> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#CreateStickerAsync(System.String,System.String,System.Collections.Generic.IEnumerable{System.String},System.IO.Stream,System.String,Discord.RequestOptions)"> | |||
<inheritdoc /> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#CreateStickerAsync(System.String,System.String,System.Collections.Generic.IEnumerable{System.String},System.String,Discord.RequestOptions)"> | |||
<inheritdoc /> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#GetStickerAsync(System.UInt64,Discord.CacheMode,Discord.RequestOptions)"> | |||
<inheritdoc /> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#GetStickersAsync(Discord.CacheMode,Discord.RequestOptions)"> | |||
<inheritdoc /> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#DeleteStickerAsync(Discord.ICustomSticker,Discord.RequestOptions)"> | |||
<inheritdoc /> | |||
</member> | |||
<member name="P:Discord.Rest.RestGuildIntegration.Name"> | |||
<inheritdoc /> | |||
</member> | |||
@@ -8,6 +8,7 @@ using WidgetModel = Discord.API.GuildWidget; | |||
using Model = Discord.API.Guild; | |||
using RoleModel = Discord.API.Role; | |||
using ImageModel = Discord.API.Image; | |||
using System.IO; | |||
namespace Discord.Rest | |||
{ | |||
@@ -559,6 +560,32 @@ namespace Discord.Rest | |||
return await client.ApiClient.CreateGuildStickerAsync(apiArgs, guild.Id, options).ConfigureAwait(false); | |||
} | |||
public static async Task<API.Sticker> CreateStickerAsync(BaseDiscordClient client, IGuild guild, string name, string description, IEnumerable<string> tags, | |||
Stream file, string filename, RequestOptions options = null) | |||
{ | |||
Preconditions.NotNull(name, nameof(name)); | |||
Preconditions.NotNull(description, nameof(description)); | |||
Preconditions.NotNull(file, nameof(file)); | |||
Preconditions.NotNull(filename, nameof(filename)); | |||
Preconditions.AtLeast(name.Length, 2, nameof(name)); | |||
Preconditions.AtLeast(description.Length, 2, nameof(description)); | |||
Preconditions.AtMost(name.Length, 30, nameof(name)); | |||
Preconditions.AtMost(description.Length, 100, nameof(name)); | |||
var apiArgs = new CreateStickerParams() | |||
{ | |||
Name = name, | |||
Description = description, | |||
File = file, | |||
Tags = string.Join(", ", tags), | |||
FileName = filename | |||
}; | |||
return await client.ApiClient.CreateGuildStickerAsync(apiArgs, guild.Id, options).ConfigureAwait(false); | |||
} | |||
public static async Task<API.Sticker> ModifyStickerAsync(BaseDiscordClient client, ulong guildId, ISticker sticker, Action<StickerProperties> func, | |||
RequestOptions options = null) | |||
{ | |||
@@ -8,6 +8,7 @@ using System.Linq; | |||
using System.Threading.Tasks; | |||
using WidgetModel = Discord.API.GuildWidget; | |||
using Model = Discord.API.Guild; | |||
using System.IO; | |||
namespace Discord.Rest | |||
{ | |||
@@ -946,6 +947,42 @@ namespace Discord.Rest | |||
return CustomSticker.Create(Discord, model, this, model.User.IsSpecified ? model.User.Value.Id : null); | |||
} | |||
/// <summary> | |||
/// Creates a new sticker in this guild | |||
/// </summary> | |||
/// <param name="name">The name of the sticker.</param> | |||
/// <param name="description">The description of the sticker.</param> | |||
/// <param name="tags">The tags of the sticker.</param> | |||
/// <param name="path">The path of the file to upload.</param> | |||
/// <param name="options">The options to be used when sending the request.</param> | |||
/// <returns> | |||
/// A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
/// </returns> | |||
public Task<CustomSticker> CreateStickerAsync(string name, string description, IEnumerable<string> tags, string path, | |||
RequestOptions options = null) | |||
{ | |||
var fs = File.OpenRead(path); | |||
return CreateStickerAsync(name, description, tags, fs, Path.GetFileName(fs.Name), options); | |||
} | |||
/// <summary> | |||
/// Creates a new sticker in this guild | |||
/// </summary> | |||
/// <param name="name">The name of the sticker.</param> | |||
/// <param name="description">The description of the sticker.</param> | |||
/// <param name="tags">The tags of the sticker.</param> | |||
/// <param name="stream">The stream containing the file data.</param> | |||
/// <param name="filename">The name of the file <b>with</b> the extension, ex: image.png</param> | |||
/// <param name="options">The options to be used when sending the request.</param> | |||
/// <returns> | |||
/// A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
/// </returns> | |||
public async Task<CustomSticker> CreateStickerAsync(string name, string description, IEnumerable<string> tags, Stream stream, | |||
string filename, RequestOptions options = null) | |||
{ | |||
var model = await GuildHelper.CreateStickerAsync(Discord, this, name, description, tags, stream, filename, options).ConfigureAwait(false); | |||
return CustomSticker.Create(Discord, model, this, model.User.IsSpecified ? model.User.Value.Id : null); | |||
} | |||
/// <summary> | |||
/// Gets a specific sticker within this guild. | |||
/// </summary> | |||
/// <param name="id">The id of the sticker to get.</param> | |||
@@ -1262,8 +1299,16 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
async Task<IReadOnlyCollection<IApplicationCommand>> IGuild.GetApplicationCommandsAsync (RequestOptions options) | |||
=> await GetApplicationCommandsAsync(options).ConfigureAwait(false); | |||
/// <inheritdoc /> | |||
async Task<ICustomSticker> IGuild.CreateStickerAsync(string name, string description, IEnumerable<string> tags, Image image, RequestOptions options) | |||
=> await CreateStickerAsync(name, description, tags, image, options); | |||
/// <inheritdoc /> | |||
async Task<ICustomSticker> IGuild.CreateStickerAsync(string name, string description, IEnumerable<string> tags, Stream stream, string filename, RequestOptions options) | |||
=> await CreateStickerAsync(name, description, tags, stream, filename, options); | |||
/// <inheritdoc /> | |||
async Task<ICustomSticker> IGuild.CreateStickerAsync(string name, string description, IEnumerable<string> tags, string path, RequestOptions options) | |||
=> await CreateStickerAsync(name, description, tags, path, options); | |||
/// <inheritdoc /> | |||
async Task<ICustomSticker> IGuild.GetStickerAsync(ulong id, CacheMode mode, RequestOptions options) | |||
{ | |||
if (mode != CacheMode.AllowDownload) | |||
@@ -1271,6 +1316,7 @@ namespace Discord.Rest | |||
return await GetStickerAsync(id, options); | |||
} | |||
/// <inheritdoc /> | |||
async Task<IReadOnlyCollection<ICustomSticker>> IGuild.GetStickersAsync(CacheMode mode, RequestOptions options) | |||
{ | |||
if (mode != CacheMode.AllowDownload) | |||
@@ -1278,6 +1324,7 @@ namespace Discord.Rest | |||
return await GetStickersAsync(options); | |||
} | |||
/// <inheritdoc /> | |||
Task IGuild.DeleteStickerAsync(ICustomSticker sticker, RequestOptions options) | |||
=> sticker.DeleteAsync(); | |||
} | |||
@@ -7,6 +7,7 @@ using System.IO; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Net.Http; | |||
using System.Net.Http.Headers; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
@@ -101,7 +102,7 @@ namespace Discord.Net.Rest | |||
switch (p.Value) | |||
{ | |||
#pragma warning disable IDISP004 | |||
case string stringValue: { content.Add(new StringContent(stringValue), p.Key); continue; } | |||
case string stringValue: { content.Add(new StringContent(stringValue, Encoding.UTF8, "text/plain"), p.Key); continue; } | |||
case byte[] byteArrayValue: { content.Add(new ByteArrayContent(byteArrayValue), p.Key); continue; } | |||
case Stream streamValue: { content.Add(new StreamContent(streamValue), p.Key); continue; } | |||
case MultipartFile fileValue: | |||
@@ -116,8 +117,16 @@ namespace Discord.Net.Rest | |||
stream = memoryStream; | |||
#pragma warning restore IDISP001 | |||
} | |||
content.Add(new StreamContent(stream), p.Key, fileValue.Filename); | |||
var streamContent = new StreamContent(stream); | |||
var extension = fileValue.Filename.Split('.').Last(); | |||
if(fileValue.ContentType != null) | |||
streamContent.Headers.ContentType = new MediaTypeHeaderValue(fileValue.ContentType); | |||
content.Add(streamContent, p.Key, fileValue.Filename); | |||
#pragma warning restore IDISP004 | |||
continue; | |||
} | |||
default: throw new InvalidOperationException($"Unsupported param type \"{p.Value.GetType().Name}\"."); | |||
@@ -20,6 +20,7 @@ using RoleModel = Discord.API.Role; | |||
using UserModel = Discord.API.User; | |||
using VoiceStateModel = Discord.API.VoiceState; | |||
using StickerModel = Discord.API.Sticker; | |||
using System.IO; | |||
namespace Discord.WebSocket | |||
{ | |||
@@ -1248,6 +1249,42 @@ namespace Discord.WebSocket | |||
return AddOrUpdateSticker(model); | |||
} | |||
/// <summary> | |||
/// Creates a new sticker in this guild | |||
/// </summary> | |||
/// <param name="name">The name of the sticker.</param> | |||
/// <param name="description">The description of the sticker.</param> | |||
/// <param name="tags">The tags of the sticker.</param> | |||
/// <param name="path">The path of the file to upload.</param> | |||
/// <param name="options">The options to be used when sending the request.</param> | |||
/// <returns> | |||
/// A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
/// </returns> | |||
public Task<SocketCustomSticker> CreateStickerAsync(string name, string description, IEnumerable<string> tags, string path, | |||
RequestOptions options = null) | |||
{ | |||
var fs = File.OpenRead(path); | |||
return CreateStickerAsync(name, description, tags, fs, Path.GetFileName(fs.Name), options); | |||
} | |||
/// <summary> | |||
/// Creates a new sticker in this guild | |||
/// </summary> | |||
/// <param name="name">The name of the sticker.</param> | |||
/// <param name="description">The description of the sticker.</param> | |||
/// <param name="tags">The tags of the sticker.</param> | |||
/// <param name="stream">The stream containing the file data.</param> | |||
/// <param name="filename">The name of the file <b>with</b> the extension, ex: image.png</param> | |||
/// <param name="options">The options to be used when sending the request.</param> | |||
/// <returns> | |||
/// A task that represents the asynchronous creation operation. The task result contains the created sticker. | |||
/// </returns> | |||
public async Task<SocketCustomSticker> CreateStickerAsync(string name, string description, IEnumerable<string> tags, Stream stream, | |||
string filename, RequestOptions options = null) | |||
{ | |||
var model = await GuildHelper.CreateStickerAsync(Discord, this, name, description, tags, stream, filename, options).ConfigureAwait(false); | |||
return AddOrUpdateSticker(model); | |||
} | |||
/// <summary> | |||
/// Deletes a sticker within this guild. | |||
/// </summary> | |||
/// <param name="sticker">The sticker to delete.</param> | |||
@@ -1632,12 +1669,22 @@ namespace Discord.WebSocket | |||
/// <inheritdoc /> | |||
async Task<IReadOnlyCollection<IApplicationCommand>> IGuild.GetApplicationCommandsAsync (RequestOptions options) | |||
=> await GetApplicationCommandsAsync(options).ConfigureAwait(false); | |||
/// <inheritdoc /> | |||
async Task<ICustomSticker> IGuild.CreateStickerAsync(string name, string description, IEnumerable<string> tags, Image image, RequestOptions options) | |||
=> await CreateStickerAsync(name, description, tags, image, options); | |||
/// <inheritdoc /> | |||
async Task<ICustomSticker> IGuild.CreateStickerAsync(string name, string description, IEnumerable<string> tags, Stream stream, string filename, RequestOptions options) | |||
=> await CreateStickerAsync(name, description, tags, stream, filename, options); | |||
/// <inheritdoc /> | |||
async Task<ICustomSticker> IGuild.CreateStickerAsync(string name, string description, IEnumerable<string> tags, string path, RequestOptions options) | |||
=> await CreateStickerAsync(name, description, tags, path, options); | |||
/// <inheritdoc /> | |||
async Task<ICustomSticker> IGuild.GetStickerAsync(ulong id, CacheMode mode, RequestOptions options) | |||
=> await GetStickerAsync(id, mode, options); | |||
/// <inheritdoc /> | |||
async Task<IReadOnlyCollection<ICustomSticker>> IGuild.GetStickersAsync(CacheMode mode, RequestOptions options) | |||
=> await GetStickersAsync(mode, options); | |||
/// <inheritdoc /> | |||
Task IGuild.DeleteStickerAsync(ICustomSticker sticker, RequestOptions options) | |||
=> DeleteStickerAsync(_stickers[sticker.Id], options); | |||