Skip to content

Commit

Permalink
Merge pull request #1255 from TelegramBots/develop
Browse files Browse the repository at this point in the history
Release v19 stable
  • Loading branch information
tuscen committed May 7, 2023
2 parents 9473a52 + 9fbd3aa commit 6fe1f1e
Show file tree
Hide file tree
Showing 57 changed files with 294 additions and 305 deletions.
2 changes: 1 addition & 1 deletion .azure-pipelines/variables.yml
Expand Up @@ -3,7 +3,7 @@ variables:
- name: versionPrefix
value: 19.0.0
- name: versionSuffix
value: 'preview.4'
value: ''
- name: ciVersionSuffix
value: ci.$(Build.BuildId)+git.commit.$(Build.SourceVersion)
- name: isPreRelease
Expand Down
4 changes: 4 additions & 0 deletions Telegram.Bot.sln
Expand Up @@ -21,6 +21,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json
README.md = README.md
THIRD_PARTY_NOTICES = THIRD_PARTY_NOTICES
.gitattributes = .gitattributes
.gitignore = .gitignore
.gitpod.yml = .gitpod.yml
LICENSE = LICENSE
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".azure-pipelines", ".azure-pipelines", "{71662597-40F2-4192-AC4D-5FB9A1F12642}"
Expand Down
31 changes: 14 additions & 17 deletions src/Telegram.Bot/Converters/InputFileConverter.cs
@@ -1,41 +1,38 @@
using System.IO;
using System.Reflection;
using Newtonsoft.Json.Linq;

namespace Telegram.Bot.Converters;

internal class InputFileConverter : JsonConverter
internal class InputFileConverter : JsonConverter<InputFile?>
{
public override bool CanConvert(Type objectType) =>
objectType.GetTypeInfo().IsSubclassOf(typeof(IInputFile));

public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
public override void WriteJson(JsonWriter writer, InputFile? value, JsonSerializer serializer)
{
writer.WriteValue(value switch
{
InputFileId file => file.Id,
InputFileUrl file => file.Url,
InputFile file => $"attach://{file.FileName}",
_ => throw new NotSupportedException("File Type not supported")
InputFileId file => file.Id,
InputFileUrl file => file.Url,
InputFileStream file => $"attach://{file.FileName}",
_ => throw new NotSupportedException("File Type not supported"),
});
}

public override object ReadJson(
public override InputFile? ReadJson(
JsonReader reader,
Type objectType,
object? existingValue,
InputFile? existingValue,
bool hasExistingValue,
JsonSerializer serializer)
{
var value = JToken.ReadFrom(reader).Value<string>();

if (value is null) { return null!; }
if (value.StartsWith("attach://", StringComparison.InvariantCulture))
if (value is null) { return null; }
if (value.StartsWith("attach://", StringComparison.OrdinalIgnoreCase))
{
return new InputFile(Stream.Null, value.Substring(9));
return new InputFileStream(Stream.Null, value.Substring(9));
}

return Uri.IsWellFormedUriString(value, UriKind.Absolute)
? new InputFileUrl(value)
return Uri.TryCreate(value, UriKind.Absolute, out var url)
? new InputFileUrl(url)
: new InputFileId(value);
}
}
10 changes: 6 additions & 4 deletions src/Telegram.Bot/Extensions/HttpContentExtensions.cs
Expand Up @@ -8,11 +8,13 @@ internal static class HttpContentExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static MultipartFormDataContent AddContentIfInputFile(
this MultipartFormDataContent multipartContent,
IInputFile? media,
InputFile? media,
string name)
{
if (media is not InputFile inputFile) // || inputFile is not { })
if (media is not InputFileStream inputFile) // || inputFile is not { })
{
return multipartContent;
}

string fileName = inputFile.FileName ?? name;
string contentDisposition = $@"form-data; name=""{name}""; filename=""{fileName}""".EncodeUtf8();
Expand All @@ -24,8 +26,8 @@ internal static class HttpContentExtensions
Headers =
{
{"Content-Type", "application/octet-stream"},
{"Content-Disposition", contentDisposition}
}
{"Content-Disposition", contentDisposition},
},
};
#pragma warning restore CA2000

Expand Down
Expand Up @@ -27,7 +27,7 @@ public class DeleteForumTopicRequest : RequestBase<bool>, IChatTargetable
/// <param name="chatId">Unique identifier for the target chat or username of the target supergroup</param>
/// <param name="messageThreadId">Unique identifier for the target message thread of the forum topic</param>
public DeleteForumTopicRequest(ChatId chatId, int messageThreadId)
: base("reopenForumTopic")
: base("deleteForumTopic")
{
ChatId = chatId;
MessageThreadId = messageThreadId;
Expand Down
Expand Up @@ -20,7 +20,7 @@ public class SetChatPhotoRequest : FileRequestBase<bool>, IChatTargetable
/// New chat photo, uploaded using multipart/form-data
/// </summary>
[JsonProperty(Required = Required.Always)]
public InputFile Photo { get; }
public InputFileStream Photo { get; }

/// <summary>
/// Initializes a new request with chatId and photo
Expand All @@ -29,14 +29,14 @@ public class SetChatPhotoRequest : FileRequestBase<bool>, IChatTargetable
/// (in the format <c>@channelusername</c>)
/// </param>
/// <param name="photo">New chat photo, uploaded using multipart/form-data</param>
public SetChatPhotoRequest(ChatId chatId, InputFile photo)
public SetChatPhotoRequest(ChatId chatId, InputFileStream photo)
: base("setChatPhoto")
{
ChatId = chatId;
Photo = photo;
}

/// <inheritdoc />
public override HttpContent? ToHttpContent()
public override HttpContent ToHttpContent()
=> ToMultipartFormDataContent("photo", Photo);
}
Expand Up @@ -32,7 +32,7 @@ public class SendAnimationRequest : FileRequestBase<Message>, IChatTargetable
/// to get an animation from the Internet, or upload a new animation using multipart/form-data
/// </summary>
[JsonProperty(Required = Required.Always)]
public IInputFile Animation { get; }
public InputFile Animation { get; }

/// <summary>
/// Duration of sent animation in seconds
Expand All @@ -54,7 +54,7 @@ public class SendAnimationRequest : FileRequestBase<Message>, IChatTargetable

/// <inheritdoc cref="Abstractions.Documentation.Thumbnail"/>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public IInputFile? Thumbnail { get; set; }
public InputFile? Thumbnail { get; set; }

/// <summary>
/// Animation caption (may also be used when resending animation by
Expand Down Expand Up @@ -108,29 +108,18 @@ public class SendAnimationRequest : FileRequestBase<Message>, IChatTargetable
/// that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to
/// get an animation from the Internet, or upload a new animation using multipart/form-data
/// </param>
public SendAnimationRequest(ChatId chatId, IInputFile animation)
public SendAnimationRequest(ChatId chatId, InputFile animation)
: base("sendAnimation")
{
ChatId = chatId;
Animation = animation;
}

/// <inheritdoc />
public override HttpContent? ToHttpContent()
{
HttpContent? httpContent;

if (Animation is InputFile || Thumbnail is InputFile)
{
httpContent = GenerateMultipartFormDataContent("animation", "thumbnail")
public override HttpContent? ToHttpContent() =>
Animation is InputFileStream || Thumbnail is InputFileStream
? GenerateMultipartFormDataContent("animation", "thumbnail")
.AddContentIfInputFile(media: Animation, name: "animation")
.AddContentIfInputFile(media: Thumbnail, name: "thumbnail");
}
else
{
httpContent = base.ToHttpContent();
}

return httpContent;
}
.AddContentIfInputFile(media: Thumbnail, name: "thumbnail")
: base.ToHttpContent();
}
Expand Up @@ -33,7 +33,7 @@ public class SendAudioRequest : FileRequestBase<Message>, IChatTargetable
/// Telegram to get an audio file from the Internet, or upload a new one using multipart/form-data
/// </summary>
[JsonProperty(Required = Required.Always)]
public IInputFile Audio { get; }
public InputFile Audio { get; }

/// <summary>
/// Audio caption, 0-1024 characters after entities parsing
Expand Down Expand Up @@ -69,7 +69,7 @@ public class SendAudioRequest : FileRequestBase<Message>, IChatTargetable

/// <inheritdoc cref="Abstractions.Documentation.Thumbnail"/>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public IInputFile? Thumbnail { get; set; }
public InputFile? Thumbnail { get; set; }

/// <inheritdoc cref="Abstractions.Documentation.DisableNotification"/>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
Expand Down Expand Up @@ -102,29 +102,18 @@ public class SendAudioRequest : FileRequestBase<Message>, IChatTargetable
/// file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for
/// Telegram to get an audio file from the Internet, or upload a new one using multipart/form-data
/// </param>
public SendAudioRequest(ChatId chatId, IInputFile audio)
public SendAudioRequest(ChatId chatId, InputFile audio)
: base("sendAudio")
{
ChatId = chatId;
Audio = audio;
}

/// <inheritdoc />
public override HttpContent? ToHttpContent()
{
HttpContent? httpContent;

if (Audio is InputFile || Thumbnail is InputFile)
{
httpContent = GenerateMultipartFormDataContent("audio", "thumbnail")
public override HttpContent? ToHttpContent() =>
Audio is InputFileStream || Thumbnail is InputFileStream
? GenerateMultipartFormDataContent("audio", "thumbnail")
.AddContentIfInputFile(media: Audio, name: "audio")
.AddContentIfInputFile(media: Thumbnail, name: "thumbnail");
}
else
{
httpContent = base.ToHttpContent();
}

return httpContent;
}
.AddContentIfInputFile(media: Thumbnail, name: "thumbnail")
: base.ToHttpContent();
}
Expand Up @@ -32,11 +32,11 @@ public class SendDocumentRequest : FileRequestBase<Message>, IChatTargetable
/// to get a file from the Internet, or upload a new one using multipart/form-data
/// </summary>
[JsonProperty(Required = Required.Always)]
public IInputFile Document { get; }
public InputFile Document { get; }

/// <inheritdoc cref="Abstractions.Documentation.Thumbnail"/>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public IInputFile? Thumbnail { get; set; }
public InputFile? Thumbnail { get; set; }

/// <summary>
/// Document caption (may also be used when resending documents by file_id), 0-1024 characters
Expand Down Expand Up @@ -90,29 +90,18 @@ public class SendDocumentRequest : FileRequestBase<Message>, IChatTargetable
/// exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram
/// to get a file from the Internet, or upload a new one using multipart/form-data
/// </param>
public SendDocumentRequest(ChatId chatId, IInputFile document)
public SendDocumentRequest(ChatId chatId, InputFile document)
: base("sendDocument")
{
ChatId = chatId;
Document = document;
}

/// <inheritdoc />
public override HttpContent? ToHttpContent()
{
HttpContent? httpContent;

if (Document is InputFile || Thumbnail is InputFile)
{
httpContent = GenerateMultipartFormDataContent("document", "thumbnail")
public override HttpContent? ToHttpContent() =>
Document is InputFileStream || Thumbnail is InputFileStream
? GenerateMultipartFormDataContent("document", "thumbnail")
.AddContentIfInputFile(media: Document, name: "document")
.AddContentIfInputFile(media: Thumbnail, name: "thumbnail");
}
else
{
httpContent = base.ToHttpContent();
}

return httpContent;
}
.AddContentIfInputFile(media: Thumbnail, name: "thumbnail")
: base.ToHttpContent();
}
Expand Up @@ -68,12 +68,12 @@ public override HttpContent ToHttpContent()

foreach (var mediaItem in Media)
{
if (mediaItem is InputMedia { Media: InputFile file })
if (mediaItem is InputMedia { Media: InputFileStream file })
{
multipartContent.AddContentIfInputFile(file, file.FileName!);
}

if (mediaItem is IInputMediaThumb { Thumbnail: InputFile thumbnail })
if (mediaItem is IInputMediaThumb { Thumbnail: InputFileStream thumbnail })
{
multipartContent.AddContentIfInputFile(thumbnail, thumbnail.FileName!);
}
Expand Down
Expand Up @@ -31,7 +31,7 @@ public class SendPhotoRequest : FileRequestBase<Message>, IChatTargetable
/// Width and height ratio must be at most 20
/// </summary>
[JsonProperty(Required = Required.Always)]
public IInputFile Photo { get; }
public InputFile Photo { get; }

/// <summary>
/// Photo caption (may also be used when resending photos by <see cref="InputFileId"/>),
Expand Down Expand Up @@ -86,7 +86,7 @@ public class SendPhotoRequest : FileRequestBase<Message>, IChatTargetable
/// get a photo from the Internet, or upload a new photo using multipart/form-data. The photo
/// must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total.
/// Width and height ratio must be at most 20</param>
public SendPhotoRequest(ChatId chatId, IInputFile photo)
public SendPhotoRequest(ChatId chatId, InputFile photo)
: base("sendPhoto")
{
ChatId = chatId;
Expand All @@ -97,7 +97,7 @@ public SendPhotoRequest(ChatId chatId, IInputFile photo)
public override HttpContent? ToHttpContent() =>
Photo switch
{
InputFile photo => ToMultipartFormDataContent(fileParameterName: "photo", inputFile: photo),
InputFileStream photo => ToMultipartFormDataContent(fileParameterName: "photo", inputFile: photo),
_ => base.ToHttpContent()
};
}
Expand Up @@ -30,7 +30,7 @@ public class SendVideoNoteRequest : FileRequestBase<Message>, IChatTargetable
/// multipart/form-data. Sending video notes by a URL is currently unsupported
/// </summary>
[JsonProperty(Required = Required.Always)]
public IInputFile VideoNote { get; }
public InputFile VideoNote { get; }

/// <summary>
/// Duration of sent video in seconds
Expand All @@ -46,7 +46,7 @@ public class SendVideoNoteRequest : FileRequestBase<Message>, IChatTargetable

/// <inheritdoc cref="Abstractions.Documentation.Thumbnail"/>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public IInputFile? Thumbnail { get; set; }
public InputFile? Thumbnail { get; set; }

/// <inheritdoc cref="Abstractions.Documentation.DisableNotification"/>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
Expand Down Expand Up @@ -79,29 +79,18 @@ public class SendVideoNoteRequest : FileRequestBase<Message>, IChatTargetable
/// note that exists on the Telegram servers (recommended) or upload a new video using
/// multipart/form-data. Sending video notes by a URL is currently unsupported
/// </param>
public SendVideoNoteRequest(ChatId chatId, IInputFile videoNote)
public SendVideoNoteRequest(ChatId chatId, InputFile videoNote)
: base("sendVideoNote")
{
ChatId = chatId;
VideoNote = videoNote;
}

/// <inheritdoc />
public override HttpContent? ToHttpContent()
{
HttpContent? httpContent;

if (VideoNote is InputFile || Thumbnail is InputFile)
{
httpContent = GenerateMultipartFormDataContent("video_note", "thumbnail")
public override HttpContent? ToHttpContent() =>
VideoNote is InputFileStream || Thumbnail is InputFileStream
? GenerateMultipartFormDataContent("video_note", "thumbnail")
.AddContentIfInputFile(media: VideoNote, name: "video_note")
.AddContentIfInputFile(media: Thumbnail, name: "thumbnail");
}
else
{
httpContent = base.ToHttpContent();
}

return httpContent;
}
.AddContentIfInputFile(media: Thumbnail, name: "thumbnail")
: base.ToHttpContent();
}

0 comments on commit 6fe1f1e

Please sign in to comment.