From 731870d782908a77f1ebeb96087cdb1b7accf608 Mon Sep 17 00:00:00 2001 From: Sreelal TS Date: Fri, 4 Oct 2024 22:00:46 +0530 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=93=81=20`MultipartFile`=20->=20`Loca?= =?UTF-8?q?lFile`=20Added=20our=20representation=20of=20local=20file=20to?= =?UTF-8?q?=20be=20uploaded?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/src/televerse/api/raw_api.dart | 10 +++++----- lib/src/televerse/models/local_file.dart | 24 ++++++++++++++++++++++++ lib/src/televerse/models/models.dart | 3 ++- lib/src/televerse/models/payload.dart | 10 +++++----- lib/src/utils/http.dart | 19 ++++++++++++++++++- 5 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 lib/src/televerse/models/local_file.dart diff --git a/lib/src/televerse/api/raw_api.dart b/lib/src/televerse/api/raw_api.dart index cd45c22e..878d91c5 100644 --- a/lib/src/televerse/api/raw_api.dart +++ b/lib/src/televerse/api/raw_api.dart @@ -163,14 +163,14 @@ class RawAPI { /// /// A new list of maps representing multipart files. The list will be empty if /// no matching elements are found in the input list. - List> _getFiles(List<_MultipartHelper> list) { - List> files = list.where((el) { + List> _getFiles(List<_MultipartHelper> list) { + List> files = list.where((el) { return el.type == InputFileType.bytes; }).map((e) { return { - e.field: MultipartFile.fromBytes( + e.field: LocalFile( e.file.getBytes(), - filename: e.name, + fileName: e.name, ), }; }).toList(); @@ -3034,7 +3034,7 @@ class RawAPI { "format": format.value, }; - List>? files; + List>? files; if (thumbnail != null) { files = _getFiles([ diff --git a/lib/src/televerse/models/local_file.dart b/lib/src/televerse/models/local_file.dart new file mode 100644 index 00000000..7dd592c3 --- /dev/null +++ b/lib/src/televerse/models/local_file.dart @@ -0,0 +1,24 @@ +part of 'models.dart'; + +/// The File to be uploaded. +class LocalFile { + /// The file name of the file. + final String? fileName; + + /// The actual bytes of the file. + final Uint8List bytes; + + /// MIME content type for the file + final String? contentType; + + /// Additional headers + final Map>? headers; + + /// Constructs the Local File with the given bytes, and file name. + const LocalFile( + this.bytes, { + this.fileName, + this.contentType, + this.headers, + }); +} diff --git a/lib/src/televerse/models/models.dart b/lib/src/televerse/models/models.dart index 7c98712f..8f801b6b 100644 --- a/lib/src/televerse/models/models.dart +++ b/lib/src/televerse/models/models.dart @@ -7,7 +7,7 @@ import 'dart:async'; import 'dart:io' as io; import 'dart:typed_data'; -import 'package:dio/dio.dart' show DioException, MultipartFile; +import 'package:dio/dio.dart' show DioException; import 'package:televerse/telegram.dart'; import 'package:televerse/televerse.dart' hide HandlerScope; @@ -24,3 +24,4 @@ part 'payload.dart'; part 'telegram_exception.dart'; part 'televerse_exception.dart'; part 'webhook_exception.dart'; +part 'local_file.dart'; diff --git a/lib/src/televerse/models/payload.dart b/lib/src/televerse/models/payload.dart index e0768c38..1120029b 100644 --- a/lib/src/televerse/models/payload.dart +++ b/lib/src/televerse/models/payload.dart @@ -3,9 +3,9 @@ part of 'models.dart'; /// Represents a list of maps containing key-value pairs for multipart files. /// /// Each map associates a field key (a `String`) with its corresponding -/// `MultipartFile` object. This type is used to represent a collection +/// `LocalFile` object. This type is used to represent a collection /// of files to be uploaded in a multipart request. -typedef PayloadFiles = List>; +typedef PayloadFiles = List>; /// Represents a payload object used for making API calls. /// @@ -20,7 +20,7 @@ typedef PayloadFiles = List>; /// request to the API. /// * [files]: A list of maps containing key-value pairs for multipart files. /// Each map associates a field key (a `String`) with its corresponding -/// `MultipartFile` object. This type is typically used to represent a collection +/// `LocalFile` object. This type is typically used to represent a collection /// of files to be uploaded in a multipart request. /// class Payload { @@ -34,7 +34,7 @@ class Payload { /// Represents a list of maps containing key-value pairs for multipart files. /// /// Each map associates a field key (a `String`) with its corresponding - /// `MultipartFile` object. This type is used to represent a collection + /// `LocalFile` object. This type is used to represent a collection /// of files to be uploaded in a multipart request. PayloadFiles? files; @@ -51,7 +51,7 @@ class Payload { /// request to the API. (See [Payload.params] for details) /// * [files]: A list of maps containing key-value pairs for multipart files. /// Each map associates a field key (a `String`) with its corresponding - /// `MultipartFile` object. This type is typically used to represent a collection + /// `LocalFile` object. This type is typically used to represent a collection /// of files to be uploaded in a multipart request. (See [Payload.files] for details) Payload([Map? params, this.files]) : params = params ?? {}; diff --git a/lib/src/utils/http.dart b/lib/src/utils/http.dart index 9eeee06b..ef81ea67 100644 --- a/lib/src/utils/http.dart +++ b/lib/src/utils/http.dart @@ -101,7 +101,9 @@ class _HttpClient { final filesMap = payload.files!.expand((element) => element.entries); final formData = FormData() ..fields.addAll(parameters) - ..files.addAll(filesMap); + ..files.addAll( + filesMap.map((e) => MapEntry(e.key, _toMultipartFile(e.value))), + ); try { final req = await _dio.postUri( @@ -138,4 +140,19 @@ class _HttpClient { void close() { _dio.close(); } + + /// Converts the [LocalFile] into a MultipartFile for sending along with the request. + /// Converts the file into a `MultipartFile` instance + MultipartFile _toMultipartFile(LocalFile file) { + return MultipartFile.fromBytes( + file.bytes, + filename: file.fileName, + contentType: file.contentType != null + ? DioMediaType.parse( + file.contentType!, + ) + : null, + headers: file.headers, + ); + } } From 7cc449793e5387572f1bfdc19567836bb010ae15 Mon Sep 17 00:00:00 2001 From: Sreelal TS Date: Fri, 4 Oct 2024 22:02:55 +0530 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=85=20Version=20Update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5e902b1..77ccca61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.26.4 + +- Added `LocalFile` class. +- Redefined `Payload.files` parameter with the `LocalFile` objects instead of `MultipartFile` from Dio. + # 1.26.3 - 🐞 Fix: Webhook Bots crashed when an invalid body was present in the request. diff --git a/pubspec.yaml b/pubspec.yaml index ce414fda..12a57610 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: televerse description: Televerse lets you create your own efficient Telegram bots with ease in Dart. Supports latest Telegram Bot API - 7.10! -version: 1.26.3 +version: 1.26.4 homepage: https://televerse.xooniverse.com repository: https://github.com/xooniverse/televerse topics: