mirror of
https://github.com/flibusta-apps/book_bot.git
synced 2025-12-06 15:35:35 +01:00
Update
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use std::str::FromStr;
|
use std::{str::FromStr, time::Duration};
|
||||||
|
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use moka::future::Cache;
|
use moka::future::Cache;
|
||||||
@@ -11,7 +11,9 @@ use teloxide::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
types::*,
|
types::*,
|
||||||
};
|
};
|
||||||
|
use tokio::time::sleep;
|
||||||
use tokio_util::compat::FuturesAsyncReadCompatExt;
|
use tokio_util::compat::FuturesAsyncReadCompatExt;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bots::{
|
bots::{
|
||||||
@@ -22,7 +24,9 @@ use crate::{
|
|||||||
types::{CachedMessage, DownloadFile},
|
types::{CachedMessage, DownloadFile},
|
||||||
},
|
},
|
||||||
book_library::{get_book, get_author_books_available_types, get_translator_books_available_types, get_sequence_books_available_types},
|
book_library::{get_book, get_author_books_available_types, get_translator_books_available_types, get_sequence_books_available_types},
|
||||||
donation_notificatioins::send_donation_notification, user_settings::get_user_or_default_lang_codes,
|
donation_notificatioins::send_donation_notification, user_settings::get_user_or_default_lang_codes, batch_downloader::{TaskObjectType, CreateTaskData},
|
||||||
|
batch_downloader::{create_task, get_task, TaskStatus}
|
||||||
|
|
||||||
},
|
},
|
||||||
tools::filter_callback_query,
|
tools::filter_callback_query,
|
||||||
},
|
},
|
||||||
@@ -410,18 +414,93 @@ async fn get_download_archive_keyboard_handler(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn download_archive(
|
||||||
|
cq: CallbackQuery,
|
||||||
|
download_archive_query_data: DownloadArchiveQueryData,
|
||||||
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
|
app_state: AppState
|
||||||
|
) -> BotHandlerInternal {
|
||||||
|
let allowed_langs = get_user_or_default_lang_codes(
|
||||||
|
cq.from.id,
|
||||||
|
app_state.user_langs_cache
|
||||||
|
).await;
|
||||||
|
|
||||||
|
let (id, file_type, task_type) = match download_archive_query_data {
|
||||||
|
DownloadArchiveQueryData::Sequence { id, file_type } => (id, file_type, TaskObjectType::Sequence),
|
||||||
|
DownloadArchiveQueryData::Author { id, file_type } => (id, file_type, TaskObjectType::Author),
|
||||||
|
DownloadArchiveQueryData::Translator { id, file_type } => (id, file_type, TaskObjectType::Translator),
|
||||||
|
};
|
||||||
|
|
||||||
|
let message = cq.message.unwrap();
|
||||||
|
|
||||||
|
let task = create_task(CreateTaskData {
|
||||||
|
object_id: id,
|
||||||
|
object_type: task_type,
|
||||||
|
file_format: file_type,
|
||||||
|
allowed_langs
|
||||||
|
}).await;
|
||||||
|
|
||||||
|
let mut task = match task {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(err) => {
|
||||||
|
bot
|
||||||
|
.edit_message_text(message.chat.id, message.id, "Ошибка! Попробуйте позже :(")
|
||||||
|
.reply_markup(InlineKeyboardMarkup {
|
||||||
|
inline_keyboard: vec![],
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
return Err(err);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
bot
|
||||||
|
.edit_message_text(message.chat.id, message.id, "Подготовка архива...")
|
||||||
|
.reply_markup(InlineKeyboardMarkup {
|
||||||
|
inline_keyboard: vec![],
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
while task.status != TaskStatus::Complete {
|
||||||
|
task = match get_task(task.id).await {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(err) => {
|
||||||
|
bot
|
||||||
|
.edit_message_text(message.chat.id, message.id, "Ошибка! Попробуйте позже :(")
|
||||||
|
.reply_markup(InlineKeyboardMarkup {
|
||||||
|
inline_keyboard: vec![],
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
return Err(err);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
sleep(Duration::from_secs(5)).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
bot
|
||||||
|
.send_document(
|
||||||
|
message.chat.id,
|
||||||
|
InputFile::url(
|
||||||
|
Url::from_str(&task.result_link.unwrap()
|
||||||
|
).unwrap())
|
||||||
|
)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_download_hander() -> crate::bots::BotHandler {
|
pub fn get_download_hander() -> crate::bots::BotHandler {
|
||||||
dptree::entry()
|
dptree::entry()
|
||||||
.branch(
|
.branch(
|
||||||
Update::filter_message()
|
Update::filter_message()
|
||||||
.chain(filter_command::<StartDownloadCommand>())
|
.chain(filter_command::<StartDownloadCommand>())
|
||||||
.endpoint(
|
.endpoint(get_download_keyboard_handler),
|
||||||
|message: Message,
|
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
|
||||||
download_data: StartDownloadCommand| async move {
|
|
||||||
get_download_keyboard_handler(message, bot, download_data).await
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.branch(
|
.branch(
|
||||||
Update::filter_callback_query()
|
Update::filter_callback_query()
|
||||||
@@ -447,10 +526,11 @@ pub fn get_download_hander() -> crate::bots::BotHandler {
|
|||||||
.branch(
|
.branch(
|
||||||
Update::filter_message()
|
Update::filter_message()
|
||||||
.chain(filter_command::<DownloadArchiveCommand>())
|
.chain(filter_command::<DownloadArchiveCommand>())
|
||||||
.endpoint(|
|
.endpoint(get_download_archive_keyboard_handler)
|
||||||
message: Message, bot: CacheMe<Throttle<Bot>>, command: DownloadArchiveCommand, app_state: AppState
|
)
|
||||||
| async move {
|
.branch(
|
||||||
get_download_archive_keyboard_handler(message, bot, command, app_state.user_langs_cache).await
|
Update::filter_callback_query()
|
||||||
})
|
.chain(filter_callback_query::<DownloadArchiveQueryData>())
|
||||||
|
.endpoint(download_archive)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
64
src/bots/approved_bot/services/batch_downloader.rs
Normal file
64
src/bots/approved_bot/services/batch_downloader.rs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum TaskObjectType {
|
||||||
|
Sequence,
|
||||||
|
Author,
|
||||||
|
Translator,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum TaskStatus {
|
||||||
|
InProgress,
|
||||||
|
Archiving,
|
||||||
|
Complete,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct CreateTaskData {
|
||||||
|
pub object_id: u32,
|
||||||
|
pub object_type: TaskObjectType,
|
||||||
|
pub file_format: String,
|
||||||
|
pub allowed_langs: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Task {
|
||||||
|
pub id: String,
|
||||||
|
pub object_id: u32,
|
||||||
|
pub object_type: TaskObjectType,
|
||||||
|
pub status: TaskStatus,
|
||||||
|
pub result_link: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_task(
|
||||||
|
data: CreateTaskData,
|
||||||
|
) -> Result<Task, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
Ok(reqwest::Client::new()
|
||||||
|
.post(format!("{}/api/", &config::CONFIG.batch_downloader_url))
|
||||||
|
.body(serde_json::to_string(&data).unwrap())
|
||||||
|
.header("Authorization", &config::CONFIG.batch_downloader_api_key)
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?
|
||||||
|
.json::<Task>()
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_task(task_id: String) -> Result<Task, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
Ok(reqwest::Client::new()
|
||||||
|
.get(format!(
|
||||||
|
"{}/api/check_archive/{task_id}/",
|
||||||
|
&config::CONFIG.batch_downloader_url
|
||||||
|
))
|
||||||
|
.header("Authorization", &config::CONFIG.batch_downloader_api_key)
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?
|
||||||
|
.json::<Task>()
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
@@ -2,3 +2,4 @@ pub mod book_cache;
|
|||||||
pub mod book_library;
|
pub mod book_library;
|
||||||
pub mod user_settings;
|
pub mod user_settings;
|
||||||
pub mod donation_notificatioins;
|
pub mod donation_notificatioins;
|
||||||
|
pub mod batch_downloader;
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ pub struct Config {
|
|||||||
pub cache_server_url: String,
|
pub cache_server_url: String,
|
||||||
pub cache_server_api_key: String,
|
pub cache_server_api_key: String,
|
||||||
|
|
||||||
|
pub batch_downloader_url: String,
|
||||||
|
pub batch_downloader_api_key: String,
|
||||||
|
|
||||||
pub sentry_dsn: String,
|
pub sentry_dsn: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +51,9 @@ impl Config {
|
|||||||
cache_server_url: get_env("CACHE_SERVER_URL"),
|
cache_server_url: get_env("CACHE_SERVER_URL"),
|
||||||
cache_server_api_key: get_env("CACHE_SERVER_API_KEY"),
|
cache_server_api_key: get_env("CACHE_SERVER_API_KEY"),
|
||||||
|
|
||||||
|
batch_downloader_url: get_env("BATCH_DOWNLOADER_URL"),
|
||||||
|
batch_downloader_api_key: get_env("BATCH_DOWNLOADER_API_KEY"),
|
||||||
|
|
||||||
sentry_dsn: get_env("SENTRY_DSN"),
|
sentry_dsn: get_env("SENTRY_DSN"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user