Change download logic to just opening file

Co-authored-by: Kurbanov Bulat <kurbanovbul@gmail.com>
This commit is contained in:
Шатунов Антон
2024-05-07 02:13:17 +03:00
parent dbd4b547c6
commit e18d9555a6
4 changed files with 20 additions and 30 deletions

1
Cargo.lock generated
View File

@@ -2217,6 +2217,7 @@ dependencies = [
"libc", "libc",
"mio", "mio",
"num_cpus", "num_cpus",
"parking_lot",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"socket2", "socket2",

View File

@@ -15,7 +15,7 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"]}
tower-http = { version = "0.5.2", features = ["trace"] } tower-http = { version = "0.5.2", features = ["trace"] }
sentry-tracing = "0.32.3" sentry-tracing = "0.32.3"
tokio = "1.37.0" tokio = { version = "1.37.0", features = [ "full" ] }
tokio-util = { version = "0.7.11", features = [ "full" ] } tokio-util = { version = "0.7.11", features = [ "full" ] }
axum-prometheus = "0.6.1" axum-prometheus = "0.6.1"

View File

@@ -1,17 +1,13 @@
use std::pin::Pin; use std::error::Error;
use axum::body::Bytes; use axum::body::Bytes;
use futures::TryStreamExt;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use serde::Serialize; use serde::Serialize;
use teloxide::{ use teloxide::{
net::Download,
requests::Requester, requests::Requester,
types::{ChatId, InputFile, MessageId, Recipient}, types::{ChatId, InputFile, MessageId, Recipient},
Bot,
}; };
use tokio::io::AsyncRead; use tokio::fs::File;
use tokio_util::compat::FuturesAsyncReadCompatExt;
use tracing::log; use tracing::log;
use moka::future::Cache; use moka::future::Cache;
@@ -111,27 +107,13 @@ pub async fn download_file(chat_id: i64, message_id: i32) -> Option<BotDownloade
log::info!("File path: {}", path); log::info!("File path: {}", path);
return Some(BotDownloader::new(bot, path)); return Some(BotDownloader(path));
} }
pub struct BotDownloader { pub struct BotDownloader(String);
bot: Bot,
file_path: String,
}
impl BotDownloader { impl BotDownloader {
pub fn new(bot: Bot, file_path: String) -> Self { pub async fn get_file(self) -> Result<File, Box<dyn Error>> {
Self { bot, file_path } Ok(File::open(self.0).await?)
}
pub fn get_async_read(self) -> Pin<Box<dyn AsyncRead + Send>> {
let stream = self.bot.download_file_stream(&self.file_path);
Box::pin(
stream
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
.into_async_read()
.compat(),
)
} }
} }

View File

@@ -12,6 +12,7 @@ use axum_typed_multipart::{TryFromMultipart, TypedMultipart};
use tokio_util::io::ReaderStream; use tokio_util::io::ReaderStream;
use tower_http::trace::{self, TraceLayer}; use tower_http::trace::{self, TraceLayer};
use tracing::Level; use tracing::Level;
use tracing::log;
use crate::config::CONFIG; use crate::config::CONFIG;
@@ -89,14 +90,20 @@ async fn upload(data: TypedMultipart<UploadFileRequest>) -> impl IntoResponse {
} }
async fn download(Path((chat_id, message_id)): Path<(i64, i32)>) -> impl IntoResponse { async fn download(Path((chat_id, message_id)): Path<(i64, i32)>) -> impl IntoResponse {
let downloader = download_file(chat_id, message_id).await; let downloader = match download_file(chat_id, message_id).await {
Some(v) => v,
let data = match downloader {
Some(v) => v.get_async_read(),
None => return StatusCode::BAD_REQUEST.into_response() None => return StatusCode::BAD_REQUEST.into_response()
}; };
let reader = ReaderStream::new(data); let file = match downloader.get_file().await {
Ok(v) => v,
Err(err) => {
log::error!("{}", err);
return StatusCode::BAD_REQUEST.into_response()
}
} ;
let reader = ReaderStream::new(file);
axum::body::Body::from_stream(reader).into_response() axum::body::Body::from_stream(reader).into_response()
} }