mirror of
https://github.com/flibusta-apps/book_bot.git
synced 2025-12-06 15:35:35 +01:00
Add title to page formating
This commit is contained in:
@@ -7,7 +7,7 @@ use teloxide::{dispatching::UpdateFilterExt, dptree, prelude::*, adaptors::{Thro
|
|||||||
use crate::{bots::approved_bot::{
|
use crate::{bots::approved_bot::{
|
||||||
services::{
|
services::{
|
||||||
book_library::{
|
book_library::{
|
||||||
formaters::Format, get_author_books, get_sequence_books, get_translator_books,
|
formaters::{Format, FormatTitle}, get_author_books, get_sequence_books, get_translator_books,
|
||||||
types::Page,
|
types::Page,
|
||||||
},
|
},
|
||||||
user_settings::get_user_or_default_lang_codes,
|
user_settings::get_user_or_default_lang_codes,
|
||||||
@@ -113,7 +113,7 @@ impl GetPaginationCallbackData for BookCallbackData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_book_handler<T, Fut>(
|
async fn send_book_handler<T, P, Fut>(
|
||||||
message: Message,
|
message: Message,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
command: BookCommand,
|
command: BookCommand,
|
||||||
@@ -122,7 +122,8 @@ async fn send_book_handler<T, Fut>(
|
|||||||
) -> crate::bots::BotHandlerInternal
|
) -> crate::bots::BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone,
|
T: Format + Clone,
|
||||||
Fut: std::future::Future<Output = Result<Page<T>, Box<dyn std::error::Error + Send + Sync>>>,
|
P: FormatTitle + Clone,
|
||||||
|
Fut: std::future::Future<Output = Result<Page<T, P>, Box<dyn std::error::Error + Send + Sync>>>,
|
||||||
{
|
{
|
||||||
let id = match command {
|
let id = match command {
|
||||||
BookCommand::Author { id } => id,
|
BookCommand::Author { id } => id,
|
||||||
@@ -189,7 +190,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_pagination_book_handler<T, Fut>(
|
async fn send_pagination_book_handler<T, P, Fut>(
|
||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
callback_data: BookCallbackData,
|
callback_data: BookCallbackData,
|
||||||
@@ -198,7 +199,8 @@ async fn send_pagination_book_handler<T, Fut>(
|
|||||||
) -> crate::bots::BotHandlerInternal
|
) -> crate::bots::BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone,
|
T: Format + Clone,
|
||||||
Fut: std::future::Future<Output = Result<Page<T>, Box<dyn std::error::Error + Send + Sync>>>,
|
P: FormatTitle + Clone,
|
||||||
|
Fut: std::future::Future<Output = Result<Page<T, P>, Box<dyn std::error::Error + Send + Sync>>>,
|
||||||
{
|
{
|
||||||
let (id, page) = match callback_data {
|
let (id, page) = match callback_data {
|
||||||
BookCallbackData::Author { id, page } => (id, page),
|
BookCallbackData::Author { id, page } => (id, page),
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::{bots::{
|
|||||||
approved_bot::{
|
approved_bot::{
|
||||||
services::{
|
services::{
|
||||||
book_library::{
|
book_library::{
|
||||||
formaters::Format, search_author, search_book, search_sequence, search_translator,
|
formaters::{Format, FormatTitle}, search_author, search_book, search_sequence, search_translator,
|
||||||
types::Page,
|
types::Page,
|
||||||
},
|
},
|
||||||
user_settings::get_user_or_default_lang_codes,
|
user_settings::get_user_or_default_lang_codes,
|
||||||
@@ -106,7 +106,7 @@ fn get_query(cq: CallbackQuery) -> Option<String> {
|
|||||||
.unwrap_or(None)
|
.unwrap_or(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn generic_search_pagination_handler<T, Fut>(
|
async fn generic_search_pagination_handler<T, P, Fut>(
|
||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
search_data: SearchCallbackData,
|
search_data: SearchCallbackData,
|
||||||
@@ -115,7 +115,8 @@ async fn generic_search_pagination_handler<T, Fut>(
|
|||||||
) -> BotHandlerInternal
|
) -> BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone,
|
T: Format + Clone,
|
||||||
Fut: std::future::Future<Output = Result<Page<T>, Box<dyn std::error::Error + Send + Sync>>>,
|
P: FormatTitle + Clone,
|
||||||
|
Fut: std::future::Future<Output = Result<Page<T, P>, Box<dyn std::error::Error + Send + Sync>>>,
|
||||||
{
|
{
|
||||||
let chat_id = cq.chat_id();
|
let chat_id = cq.chat_id();
|
||||||
let user_id = cq.from.id;
|
let user_id = cq.from.id;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::bots::approved_bot::modules::download::StartDownloadData;
|
|||||||
|
|
||||||
use super::types::{
|
use super::types::{
|
||||||
Author, AuthorBook, Book, BookAuthor, BookGenre, SearchBook, Sequence, Translator,
|
Author, AuthorBook, Book, BookAuthor, BookGenre, SearchBook, Sequence, Translator,
|
||||||
TranslatorBook, SequenceBook, BookTranslator,
|
TranslatorBook, SequenceBook, BookTranslator, Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
const NO_LIMIT: usize = 4096;
|
const NO_LIMIT: usize = 4096;
|
||||||
@@ -25,6 +25,62 @@ pub trait FormatInline {
|
|||||||
fn format_inline(&self) -> String;
|
fn format_inline(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait FormatTitle {
|
||||||
|
fn format_title(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatTitle for Empty {
|
||||||
|
fn format_title(&self) -> String {
|
||||||
|
"".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatTitle for BookAuthor {
|
||||||
|
fn format_title(&self) -> String {
|
||||||
|
let BookAuthor {
|
||||||
|
id,
|
||||||
|
last_name,
|
||||||
|
first_name,
|
||||||
|
middle_name,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
if *id == 0 {
|
||||||
|
return "".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
format!("👤 {last_name} {first_name} {middle_name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatTitle for BookTranslator {
|
||||||
|
fn format_title(&self) -> String {
|
||||||
|
let BookTranslator {
|
||||||
|
id,
|
||||||
|
first_name,
|
||||||
|
last_name,
|
||||||
|
middle_name,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
if *id == 0 {
|
||||||
|
return "".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
format!("👤 {last_name} {first_name} {middle_name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatTitle for Sequence {
|
||||||
|
fn format_title(&self) -> String {
|
||||||
|
let Sequence { id, name } = self;
|
||||||
|
|
||||||
|
if *id == 0 {
|
||||||
|
return "".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
format!("📚 {name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FormatInline for BookAuthor {
|
impl FormatInline for BookAuthor {
|
||||||
fn format_inline(&self) -> String {
|
fn format_inline(&self) -> String {
|
||||||
let BookAuthor {
|
let BookAuthor {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ use serde::de::DeserializeOwned;
|
|||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
|
|
||||||
|
use self::types::Empty;
|
||||||
|
|
||||||
fn get_allowed_langs_params(allowed_langs: Vec<String>) -> Vec<(&'static str, String)> {
|
fn get_allowed_langs_params(allowed_langs: Vec<String>) -> Vec<(&'static str, String)> {
|
||||||
allowed_langs
|
allowed_langs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -83,7 +85,7 @@ pub async fn get_genre_metas() -> Result<Vec<String>, Box<dyn std::error::Error
|
|||||||
|
|
||||||
pub async fn get_genres(
|
pub async fn get_genres(
|
||||||
meta: String,
|
meta: String,
|
||||||
) -> Result<types::Page<types::Genre>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::Genre, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let params = vec![("meta", meta)];
|
let params = vec![("meta", meta)];
|
||||||
|
|
||||||
_make_request("/api/v1/genres/", params).await
|
_make_request("/api/v1/genres/", params).await
|
||||||
@@ -95,7 +97,7 @@ pub async fn search_book(
|
|||||||
query: String,
|
query: String,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: Vec<String>,
|
||||||
) -> Result<types::Page<types::SearchBook>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::SearchBook, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
params.push(("page", page.to_string()));
|
params.push(("page", page.to_string()));
|
||||||
@@ -108,7 +110,7 @@ pub async fn search_author(
|
|||||||
query: String,
|
query: String,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: Vec<String>,
|
||||||
) -> Result<types::Page<types::Author>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::Author, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
params.push(("page", page.to_string()));
|
params.push(("page", page.to_string()));
|
||||||
@@ -121,7 +123,7 @@ pub async fn search_sequence(
|
|||||||
query: String,
|
query: String,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: Vec<String>,
|
||||||
) -> Result<types::Page<types::Sequence>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::Sequence, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
params.push(("page", page.to_string()));
|
params.push(("page", page.to_string()));
|
||||||
@@ -134,7 +136,7 @@ pub async fn search_translator(
|
|||||||
query: String,
|
query: String,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: Vec<String>,
|
||||||
) -> Result<types::Page<types::Translator>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::Translator, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
params.push(("page", page.to_string()));
|
params.push(("page", page.to_string()));
|
||||||
@@ -163,7 +165,7 @@ pub async fn get_author_books(
|
|||||||
id: u32,
|
id: u32,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: Vec<String>,
|
||||||
) -> Result<types::Page<types::AuthorBook>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::AuthorBook, types::BookAuthor>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
params.push(("page", page.to_string()));
|
params.push(("page", page.to_string()));
|
||||||
@@ -176,7 +178,7 @@ pub async fn get_translator_books(
|
|||||||
id: u32,
|
id: u32,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: Vec<String>,
|
||||||
) -> Result<types::Page<types::TranslatorBook>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::TranslatorBook, types::BookTranslator>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
params.push(("page", page.to_string()));
|
params.push(("page", page.to_string()));
|
||||||
@@ -189,7 +191,7 @@ pub async fn get_sequence_books(
|
|||||||
id: u32,
|
id: u32,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: Vec<String>,
|
||||||
) -> Result<types::Page<types::SequenceBook>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::SequenceBook, types::Sequence>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
params.push(("page", page.to_string()));
|
params.push(("page", page.to_string()));
|
||||||
@@ -202,7 +204,7 @@ pub async fn get_uploaded_books(
|
|||||||
page: u32,
|
page: u32,
|
||||||
uploaded_gte: String,
|
uploaded_gte: String,
|
||||||
uploaded_lte: String,
|
uploaded_lte: String,
|
||||||
) -> Result<types::Page<types::SearchBook>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::SearchBook, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let params = vec![
|
let params = vec![
|
||||||
("page", page.to_string()),
|
("page", page.to_string()),
|
||||||
("size", PAGE_SIZE.to_string()),
|
("size", PAGE_SIZE.to_string()),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use super::formaters::{Format, FormatResult};
|
use super::formaters::{Format, FormatResult, FormatTitle};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Default, Deserialize, Debug, Clone)]
|
||||||
pub struct BookAuthor {
|
pub struct BookAuthor {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub first_name: String,
|
pub first_name: String,
|
||||||
@@ -11,7 +11,7 @@ pub struct BookAuthor {
|
|||||||
pub middle_name: String,
|
pub middle_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Default, Deserialize, Debug, Clone)]
|
||||||
pub struct BookTranslator {
|
pub struct BookTranslator {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub first_name: String,
|
pub first_name: String,
|
||||||
@@ -55,7 +55,7 @@ pub struct Translator {
|
|||||||
pub annotation_exists: bool,
|
pub annotation_exists: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Default, Deserialize, Debug, Clone)]
|
||||||
pub struct Sequence {
|
pub struct Sequence {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -71,8 +71,11 @@ pub struct Genre {
|
|||||||
pub meta: String,
|
pub meta: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Debug, Clone)]
|
||||||
|
pub struct Empty {}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct Page<T> {
|
pub struct Page<T, P> {
|
||||||
pub items: Vec<T>,
|
pub items: Vec<T>,
|
||||||
pub total: u32,
|
pub total: u32,
|
||||||
|
|
||||||
@@ -80,18 +83,36 @@ pub struct Page<T> {
|
|||||||
|
|
||||||
pub size: u32,
|
pub size: u32,
|
||||||
pub pages: u32,
|
pub pages: u32,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub parent_item: Option<P>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Page<T>
|
impl<T, P> Page<T, P>
|
||||||
where
|
where
|
||||||
T: Format + Clone,
|
T: Format + Clone,
|
||||||
|
P: FormatTitle + Clone
|
||||||
{
|
{
|
||||||
pub fn format_items(&self, max_size: usize) -> String {
|
pub fn format_items(&self, max_size: usize) -> String {
|
||||||
|
let title: String = match &self.parent_item {
|
||||||
|
Some(parent_item) => {
|
||||||
|
let item_title = parent_item.format_title();
|
||||||
|
|
||||||
|
if item_title.is_empty() {
|
||||||
|
return "".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
format!("{item_title}\n\n\n")
|
||||||
|
},
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
let title_len: usize = title.len();
|
||||||
|
|
||||||
let separator = "\n\n\n";
|
let separator = "\n\n\n";
|
||||||
let separator_len: usize = separator.len();
|
let separator_len: usize = separator.len();
|
||||||
|
|
||||||
let items_count: usize = self.items.len();
|
let items_count: usize = self.items.len();
|
||||||
let item_size: usize = (max_size - separator_len * items_count) / items_count;
|
let item_size: usize = (max_size - title_len - separator_len * items_count) / items_count;
|
||||||
|
|
||||||
let format_result: Vec<FormatResult> = self.items
|
let format_result: Vec<FormatResult> = self.items
|
||||||
.iter()
|
.iter()
|
||||||
@@ -118,7 +139,7 @@ where
|
|||||||
.map(|item| item_size - item.current_size)
|
.map(|item| item_size - item.current_size)
|
||||||
.sum();
|
.sum();
|
||||||
|
|
||||||
self.items
|
let items_string = self.items
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, item)| {
|
.map(|(index, item)| {
|
||||||
@@ -136,7 +157,9 @@ where
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(separator)
|
.join(separator);
|
||||||
|
|
||||||
|
format!("{title}{items_string}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user