From 4b398807df82d49275b2fc44e85b4d79377aa8f9 Mon Sep 17 00:00:00 2001 From: meep334 Date: Wed, 18 Jan 2023 19:32:17 +0100 Subject: [PATCH] api in a working state --- .vscode/settings.json | 1 + src/api/v1/route/chapter.rs | 82 +++++++++++++++++++++++++++++++++++++ src/api/v1/route/manga.rs | 10 ++++- src/api/v1/route/mod.rs | 1 + src/middleware/auth.rs | 1 + 5 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 src/api/v1/route/chapter.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index f4d61f2..3ac31dc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -42,4 +42,5 @@ } ], "discord.enabled": true, + "vscord.enabled": true, } \ No newline at end of file diff --git a/src/api/v1/route/chapter.rs b/src/api/v1/route/chapter.rs new file mode 100644 index 0000000..362a9f6 --- /dev/null +++ b/src/api/v1/route/chapter.rs @@ -0,0 +1,82 @@ +use crate::api::v1::data; +use crate::api::v1::data::paginate::Paginate; +use crate::api::v1::route::manga::MANGA_PARSER; +use actix_web::error::{ErrorInternalServerError, ErrorNotFound}; +use actix_web::{web, Responder, Result}; +use entity::chapter::{Column as ChapterColumn, Entity as chapter, Model as Chapter}; +use manga_parser::parser::Parser; +use manga_parser::Url; +use sea_orm::{ + ColumnTrait, DatabaseConnection, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder, +}; + +#[get("")] +async fn index( + path: web::Path, + conn: web::Data, + query: web::Query, +) -> Result>> { + let db = conn.as_ref(); + let manga_id = path.into_inner(); + + // Create paginate object + let paginate = chapter::find() + .filter(ChapterColumn::MangaId.eq(manga_id)) + .order_by(ChapterColumn::Id, migration::Order::Asc) + .paginate(db, query.limit); + + // Get max page + let amount = paginate + .num_items_and_pages() + .await + .map_err(ErrorInternalServerError)?; + + // Get items from page + let items = paginate + .fetch_page(query.page) + .await + .map_err(ErrorInternalServerError)?; + + Ok(Paginate { + total: amount.number_of_items, + max_page: amount.number_of_pages, + page: query.page, + limit: query.limit, + items, + }) +} + +#[get("/{chapter_id}")] +async fn get( + path: web::Path<(i32, i32)>, + conn: web::Data, +) -> Result { + let (manga_id, chapter_id) = path.into_inner(); + let db = conn.as_ref(); + + // Get chapter + let chap = chapter::find() + .filter(ChapterColumn::Id.eq(chapter_id)) + .filter(ChapterColumn::MangaId.eq(manga_id)) + .one(db) + .await + .map_err(ErrorInternalServerError)? + .ok_or(ErrorNotFound("Manga not found"))?; + + // Get images + let images = MANGA_PARSER + .images(&Url::parse(&chap.url).unwrap()) + .await + .map_err(ErrorInternalServerError)?; + + Ok(web::Json(images)) +} + +pub fn routes() -> actix_web::Scope { + web::scope("/{manga_id}/chapter") + .service(index) + .service(get) +} + +#[cfg(test)] +mod test {} diff --git a/src/api/v1/route/manga.rs b/src/api/v1/route/manga.rs index ee8dea2..d288820 100644 --- a/src/api/v1/route/manga.rs +++ b/src/api/v1/route/manga.rs @@ -20,6 +20,12 @@ use crate::api::v1::data::paginate::Paginate; use crate::api::v1::util::search::manga::lucene_filter; use crate::middleware::auth::AuthService; +use super::chapter; + +lazy_static! { + pub static ref MANGA_PARSER: MangaParser = MangaParser::new(); +} + pub const NEXT_UPDATE_QUERY: &str = "(MAX(chapter.posted) + (MAX(chapter.posted) - MIN(chapter.posted)) / NULLIF(COUNT(*) - 1, 0))"; @@ -47,8 +53,7 @@ pub async fn save_manga( ) -> actix_web::Result { info!("Saving manga [{}]", url.to_string()); - let manga_parser = MangaParser::new(); - let m = manga_parser + let m = MANGA_PARSER .manga(url) .await .map_err(ErrorInternalServerError)?; @@ -283,6 +288,7 @@ pub fn routes() -> actix_web::Scope { .service(store) .service(get) .service(delete) + .service(chapter::routes()) } #[cfg(test)] diff --git a/src/api/v1/route/mod.rs b/src/api/v1/route/mod.rs index 2ad179f..295fa35 100644 --- a/src/api/v1/route/mod.rs +++ b/src/api/v1/route/mod.rs @@ -1,3 +1,4 @@ pub mod user; pub mod manga; +pub mod chapter; pub mod reading; diff --git a/src/middleware/auth.rs b/src/middleware/auth.rs index 89af6da..591752d 100644 --- a/src/middleware/auth.rs +++ b/src/middleware/auth.rs @@ -45,6 +45,7 @@ pub struct AuthService { pub user: User, } +#[allow(dead_code)] impl AuthService { pub fn is_restricted(&self) -> bool { self.user.permissions == 0