From c4fa52adb3fe3356566e7f48f3fa982b872d7695 Mon Sep 17 00:00:00 2001 From: Bulat Kurbanov Date: Sat, 12 Aug 2023 19:03:14 +0200 Subject: [PATCH] Fix --- src/meilisearch.rs | 31 ++++++++++++++ src/views/authors.rs | 64 ++++++++++------------------- src/views/books.rs | 55 +++++++++---------------- src/views/common/get_random_item.rs | 31 ++++++++++++++ src/views/common/mod.rs | 1 + src/views/mod.rs | 1 + src/views/sequences.rs | 63 ++++++++++------------------ src/views/translators.rs | 24 +++++------ 8 files changed, 135 insertions(+), 135 deletions(-) create mode 100644 src/views/common/get_random_item.rs create mode 100644 src/views/common/mod.rs diff --git a/src/meilisearch.rs b/src/meilisearch.rs index 21d2272..b406426 100644 --- a/src/meilisearch.rs +++ b/src/meilisearch.rs @@ -11,6 +11,10 @@ pub fn get_meili_client() -> Client { ) } +pub trait GetId { + fn get_id(&self) -> i32; +} + #[derive(Deserialize)] pub struct AuthorMeili { pub id: i32, @@ -22,6 +26,13 @@ pub struct AuthorMeili { pub books_count: i32 } +impl GetId for AuthorMeili { + fn get_id(&self) -> i32 { + self.id + } +} + + #[derive(Deserialize)] pub struct BookMeili { pub id: i32, @@ -30,6 +41,13 @@ pub struct BookMeili { pub genres: Vec } +impl GetId for BookMeili { + fn get_id(&self) -> i32 { + self.id + } +} + + #[derive(Deserialize)] pub struct GenreMeili { pub id: i32, @@ -39,6 +57,13 @@ pub struct GenreMeili { pub books_count: i32 } +impl GetId for GenreMeili { + fn get_id(&self) -> i32 { + self.id + } +} + + #[derive(Deserialize)] pub struct SequenceMeili { pub id: i32, @@ -46,3 +71,9 @@ pub struct SequenceMeili { pub langs: Vec, pub books_count: i32 } + +impl GetId for SequenceMeili { + fn get_id(&self) -> i32 { + self.id + } +} diff --git a/src/views/authors.rs b/src/views/authors.rs index ca01a4e..99fe815 100644 --- a/src/views/authors.rs +++ b/src/views/authors.rs @@ -2,11 +2,9 @@ use std::collections::HashSet; use axum::{Router, extract::{Query, Path}, Json, response::IntoResponse, routing::get, http::StatusCode}; -use rand::Rng; - use crate::{prisma::{author, author_annotation::{self}, book, book_author, translator, book_sequence}, serializers::{pagination::{Pagination, Page, PageWithParent}, author::{Author, AuthorBook}, author_annotation::AuthorAnnotation, allowed_langs::AllowedLangs}, meilisearch::{get_meili_client, AuthorMeili}}; -use super::Database; +use super::{Database, common::get_random_item::get_random_item}; async fn get_authors( @@ -47,36 +45,20 @@ async fn get_random_author( db: Database, axum_extra::extract::Query(AllowedLangs { allowed_langs }): axum_extra::extract::Query ) -> impl IntoResponse { - let client = get_meili_client(); - - let authors_index = client.index("authors"); - - let filter = format!( - "author_langs IN [{}]", - allowed_langs.join(", ") - ); - - let result = authors_index - .search() - .with_filter(&filter) - .execute::() - .await - .unwrap(); - let author_id = { - let offset: usize = rand::thread_rng().gen_range(0..result.estimated_total_hits.unwrap().try_into().unwrap()); + let client = get_meili_client(); - let result = authors_index - .search() - .with_limit(1) - .with_offset(offset) - .execute::() - .await - .unwrap(); + let authors_index = client.index("authors"); - let author = &result.hits.get(0).unwrap().result; + let filter = format!( + "author_langs IN [{}]", + allowed_langs.join(", ") + ); - author.id + get_random_item::( + authors_index, + filter + ).await }; let author = db @@ -162,28 +144,24 @@ async fn get_author_books( None => return StatusCode::NOT_FOUND.into_response(), }; + let books_filter = vec![ + book::is_deleted::equals(false), + book::book_authors::some(vec![ + book_author::author_id::equals(author_id) + ]), + book::lang::in_vec(allowed_langs.clone()) + ]; + let books_count = db .book() - .count(vec![ - book::is_deleted::equals(false), - book::book_authors::some(vec![ - book_author::author_id::equals(author_id) - ]), - book::lang::in_vec(allowed_langs.clone()) - ]) + .count(books_filter.clone()) .exec() .await .unwrap(); let books = db .book() - .find_many(vec![ - book::is_deleted::equals(false), - book::book_authors::some(vec![ - book_author::author_id::equals(author_id) - ]), - book::lang::in_vec(allowed_langs) - ]) + .find_many(books_filter) .with( book::source::fetch() ) diff --git a/src/views/books.rs b/src/views/books.rs index 2b59e05..26fc661 100644 --- a/src/views/books.rs +++ b/src/views/books.rs @@ -1,10 +1,9 @@ use axum::{Router, routing::get, extract::{Query, Path}, Json, response::IntoResponse, http::StatusCode}; use prisma_client_rust::Direction; -use rand::Rng; use crate::{serializers::{book::{BookFilter, RemoteBook, BaseBook, DetailBook, RandomBookFilter, Book}, pagination::{Pagination, Page}, book_annotation::BookAnnotation, allowed_langs::AllowedLangs}, prisma::{book::{self}, book_author, author, translator, book_sequence, book_genre, book_annotation, genre}, meilisearch::{get_meili_client, BookMeili}}; -use super::Database; +use super::{Database, common::get_random_item::get_random_item}; pub async fn get_books( @@ -110,44 +109,28 @@ pub async fn get_random_book( db: Database, axum_extra::extract::Query(book_filter): axum_extra::extract::Query, ) -> impl IntoResponse { - let client = get_meili_client(); + let book_id = { + let client = get_meili_client(); - let authors_index = client.index("books"); + let authors_index = client.index("books"); - let filter = { - let langs_filter = format!( - "lang IN [{}]", - book_filter.allowed_langs.join(", ") - ); - let genre_filter = match book_filter.genre { - Some(v) => format!(" AND genres = {v}"), - None => "".to_string(), + let filter = { + let langs_filter = format!( + "lang IN [{}]", + book_filter.allowed_langs.join(", ") + ); + let genre_filter = match book_filter.genre { + Some(v) => format!(" AND genres = {v}"), + None => "".to_string(), + }; + + format!("{langs_filter}{genre_filter}") }; - format!("{langs_filter}{genre_filter}") - }; - - let result = authors_index - .search() - .with_filter(&filter) - .execute::() - .await - .unwrap(); - - let book_id = { - let offset: usize = rand::thread_rng().gen_range(0..result.estimated_total_hits.unwrap().try_into().unwrap()); - - let result = authors_index - .search() - .with_limit(1) - .with_offset(offset) - .execute::() - .await - .unwrap(); - - let book = &result.hits.get(0).unwrap().result; - - book.id + get_random_item::( + authors_index, + filter + ).await }; let book = db diff --git a/src/views/common/get_random_item.rs b/src/views/common/get_random_item.rs new file mode 100644 index 0000000..2bdd582 --- /dev/null +++ b/src/views/common/get_random_item.rs @@ -0,0 +1,31 @@ +use meilisearch_sdk::indexes::Index; +use rand::Rng; +use serde::de::DeserializeOwned; + +use crate::meilisearch::GetId; + +pub async fn get_random_item<'a, T>( + index: Index, filter: String, +) -> i32 +where T: DeserializeOwned + GetId + 'static { + let result = index + .search() + .with_filter(&filter) + .execute::() + .await + .unwrap(); + + let offset: usize = rand::thread_rng().gen_range(0..result.estimated_total_hits.unwrap().try_into().unwrap()); + + let result = index + .search() + .with_limit(1) + .with_offset(offset) + .execute::() + .await + .unwrap(); + + let item = &result.hits.get(0).unwrap().result; + + item.get_id() +} diff --git a/src/views/common/mod.rs b/src/views/common/mod.rs new file mode 100644 index 0000000..b3fbc3e --- /dev/null +++ b/src/views/common/mod.rs @@ -0,0 +1 @@ +pub mod get_random_item; diff --git a/src/views/mod.rs b/src/views/mod.rs index 3cf3cd9..707021a 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -15,6 +15,7 @@ pub mod books; pub mod genres; pub mod sequences; pub mod translators; +pub mod common; pub type Database = Extension>; diff --git a/src/views/sequences.rs b/src/views/sequences.rs index f9c47de..c814471 100644 --- a/src/views/sequences.rs +++ b/src/views/sequences.rs @@ -1,47 +1,30 @@ use std::collections::HashSet; use axum::{Router, routing::get, extract::{Path, Query}, http::StatusCode, response::IntoResponse, Json}; -use rand::Rng; use crate::{prisma::{sequence, book_sequence, book, book_author, author, translator}, serializers::{sequence::{Sequence, SequenceBook}, allowed_langs::AllowedLangs, pagination::{PageWithParent, Pagination, Page}}, meilisearch::{get_meili_client, SequenceMeili}}; -use super::Database; +use super::{Database, common::get_random_item::get_random_item}; async fn get_random_sequence( db: Database, axum_extra::extract::Query(AllowedLangs { allowed_langs }): axum_extra::extract::Query ) -> impl IntoResponse { - let client = get_meili_client(); - - let authors_index = client.index("sequences"); - - let filter = format!( - "langs IN [{}]", - allowed_langs.join(", ") - ); - - let result = authors_index - .search() - .with_filter(&filter) - .execute::() - .await - .unwrap(); - let sequence_id = { - let offset: usize = rand::thread_rng().gen_range(0..result.estimated_total_hits.unwrap().try_into().unwrap()); + let client = get_meili_client(); - let result = authors_index - .search() - .with_limit(1) - .with_offset(offset) - .execute::() - .await - .unwrap(); + let authors_index = client.index("sequences"); - let sequence = &result.hits.get(0).unwrap().result; + let filter = format!( + "langs IN [{}]", + allowed_langs.join(", ") + ); - sequence.id + get_random_item::( + authors_index, + filter + ).await }; let sequence = db @@ -182,28 +165,24 @@ async fn get_sequence_books( None => return StatusCode::NOT_FOUND.into_response(), }; + let books_filter = vec![ + book::is_deleted::equals(false), + book::book_sequences::some(vec![ + book_sequence::sequence_id::equals(sequence_id) + ]), + book::lang::in_vec(allowed_langs.clone()) + ]; + let books_count = db .book() - .count(vec![ - book::is_deleted::equals(false), - book::book_sequences::some(vec![ - book_sequence::sequence_id::equals(sequence_id) - ]), - book::lang::in_vec(allowed_langs.clone()) - ]) + .count(books_filter.clone()) .exec() .await .unwrap(); let books = db .book() - .find_many(vec![ - book::is_deleted::equals(false), - book::book_sequences::some(vec![ - book_sequence::sequence_id::equals(sequence_id) - ]), - book::lang::in_vec(allowed_langs.clone()) - ]) + .find_many(books_filter) .with( book::source::fetch() ) diff --git a/src/views/translators.rs b/src/views/translators.rs index 8cb952a..b1f78d1 100644 --- a/src/views/translators.rs +++ b/src/views/translators.rs @@ -30,28 +30,24 @@ async fn get_translated_books( None => return StatusCode::NOT_FOUND.into_response(), }; + let books_filter = vec![ + book::is_deleted::equals(false), + book::translations::some(vec![ + translator::author_id::equals(translator_id) + ]), + book::lang::in_vec(allowed_langs.clone()) + ]; + let books_count = db .book() - .count(vec![ - book::is_deleted::equals(false), - book::translations::some(vec![ - translator::author_id::equals(translator_id) - ]), - book::lang::in_vec(allowed_langs.clone()) - ]) + .count(books_filter.clone()) .exec() .await .unwrap(); let books = db .book() - .find_many(vec![ - book::is_deleted::equals(false), - book::translations::some(vec![ - translator::author_id::equals(translator_id) - ]), - book::lang::in_vec(allowed_langs) - ]) + .find_many(books_filter) .with( book::source::fetch() )