Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Api: Get one movie/package/extra #15

Merged
merged 3 commits into from
Mar 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions api/api/src/controllers/extras.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
use crate::dto::extra::NewExtra;
use crate::error_handling::{ApiError, ApiRawResult};
use crate::responses::extra_creation::ExtraCreationResponse;
use crate::error_handling::{ApiError, ApiRawResult, ApiResult};
use crate::responses::extra::{ExtraCreationResponse, ExtraResponse};
use crate::services;
use diesel::Connection;
use domain::models::artist::Artist;
use infrastructure::Database;
use rocket::response::status;
use rocket::serde::uuid::Uuid;
use rocket::{post, serde::json::Json};
use rocket_okapi::okapi::openapi3::OpenApi;
use rocket_okapi::settings::OpenApiSettings;
use rocket_okapi::{openapi, openapi_get_routes_spec};

pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
openapi_get_routes_spec![settings: new_extra]
openapi_get_routes_spec![settings: new_extra, get_extra]
}

/// Create a new extra
Expand Down Expand Up @@ -75,3 +76,12 @@ async fn new_extra(
|v| Ok(status::Created::new("").body(Json(v))),
)
}

/// Get a Single extra
#[openapi(tag = "Extras")]
#[get("/<uuid>")]
async fn get_extra(db: Database, uuid: Uuid) -> ApiResult<ExtraResponse> {
db.run(move |conn| services::extra::find(&uuid, conn))
.await
.map_or_else(|e| Err(ApiError::from(e)), |v| Ok(Json(v)))
}
22 changes: 22 additions & 0 deletions api/api/src/controllers/files.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::error_handling::{ApiError, ApiResult};
use crate::services;
use domain::models::file::File;
use infrastructure::Database;
use rocket::serde::json::Json;
use rocket::serde::uuid::Uuid;
use rocket_okapi::okapi::openapi3::OpenApi;
use rocket_okapi::settings::OpenApiSettings;
use rocket_okapi::{openapi, openapi_get_routes_spec};

pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
openapi_get_routes_spec![settings: get_file]
}

/// Get a Single File
#[openapi(tag = "Files")]
#[get("/<uuid>")]
async fn get_file(db: Database, uuid: Uuid) -> ApiResult<File> {
db.run(move |conn| services::file::find(&uuid, conn))
.await
.map_or_else(|e| Err(ApiError::from(e)), |v| Ok(Json(v)))
}
2 changes: 2 additions & 0 deletions api/api/src/controllers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub mod artists;
pub mod extras;
pub mod files;
pub mod images;
pub mod index;
pub mod movies;
pub mod packages;
26 changes: 23 additions & 3 deletions api/api/src/controllers/movies.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
use crate::dto::movie::NewMovie;
use crate::error_handling::{ApiError, ApiRawResult};
use crate::responses::movie_creation::MovieCreationResponse;
use crate::error_handling::{ApiError, ApiRawResult, ApiResult};
use crate::responses::chapter::ChapterResponse;
use crate::responses::movie::{MovieCreationResponse, MovieResponse};
use crate::services;
use diesel::Connection;
use domain::models::artist::Artist;
use infrastructure::Database;
use rocket::response::status;
use rocket::serde::uuid::Uuid;
use rocket::{post, serde::json::Json};
use rocket_okapi::okapi::openapi3::OpenApi;
use rocket_okapi::settings::OpenApiSettings;
use rocket_okapi::{openapi, openapi_get_routes_spec};

pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
openapi_get_routes_spec![settings: new_movie]
openapi_get_routes_spec![settings: new_movie, get_movie, get_movie_chapters]
}

/// Create a new movie with its chapters
Expand Down Expand Up @@ -77,3 +79,21 @@ async fn new_movie(
|v| Ok(status::Created::new("").body(Json(v))),
)
}

/// Get a Single Movie
#[openapi(tag = "Movies")]
#[get("/<slug_or_uuid>")]
async fn get_movie(db: Database, slug_or_uuid: String) -> ApiResult<MovieResponse> {
db.run(move |conn| services::movie::find(&slug_or_uuid, conn))
.await
.map_or_else(|e| Err(ApiError::from(e)), |v| Ok(Json(v)))
}

/// Get a Movie's Chapters
#[openapi(tag = "Movies")]
#[get("/<uuid>/chapters")]
async fn get_movie_chapters(db: Database, uuid: Uuid) -> ApiResult<Vec<ChapterResponse>> {
db.run(move |conn| services::chapters::find_by_movie(&uuid, conn))
.await
.map_or_else(|e| Err(ApiError::from(e)), |v| Ok(Json(v)))
}
21 changes: 21 additions & 0 deletions api/api/src/controllers/packages.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use crate::error_handling::{ApiError, ApiResult};
use crate::responses::package::PackageResponse;
use crate::services;
use infrastructure::Database;
use rocket::serde::json::Json;
use rocket_okapi::okapi::openapi3::OpenApi;
use rocket_okapi::settings::OpenApiSettings;
use rocket_okapi::{openapi, openapi_get_routes_spec};

pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
openapi_get_routes_spec![settings: get_package]
}

/// Get a Single Package
#[openapi(tag = "Package")]
#[get("/<slug_or_uuid>")]
async fn get_package(db: Database, slug_or_uuid: String) -> ApiResult<PackageResponse> {
db.run(move |conn| services::package::find(&slug_or_uuid, conn))
.await
.map_or_else(|e| Err(ApiError::from(e)), |v| Ok(Json(v)))
}
2 changes: 2 additions & 0 deletions api/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ fn create_server() -> Rocket<Build> {
building_rocket, "/".to_owned(), openapi_settings,
"/artists" => controllers::artists::get_routes_and_docs(&openapi_settings),
"/extras" => controllers::extras::get_routes_and_docs(&openapi_settings),
"/files" => controllers::files::get_routes_and_docs(&openapi_settings),
"/images" => controllers::images::get_routes_and_docs(&openapi_settings),
"/movies" => controllers::movies::get_routes_and_docs(&openapi_settings),
"/packages" => controllers::packages::get_routes_and_docs(&openapi_settings),
"/swagger" => (vec![], custom_openapi_spec()),
};

Expand Down
12 changes: 12 additions & 0 deletions api/api/src/responses/chapter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use domain::models::chapter::Chapter;
use domain::models::image::Image;
use rocket_okapi::okapi::schemars;
use rocket_okapi::okapi::schemars::JsonSchema;
use serde::Serialize;

#[derive(Serialize, JsonSchema)]
pub struct ChapterResponse {
#[serde(flatten)]
pub chapter: Chapter,
pub thumbnail: Option<Image>,
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::swagger_examples::*;
use domain::models::{extra::Extra, file::File, image::Image, package::Package};
use rocket::serde::uuid::Uuid;
use rocket_okapi::okapi::schemars;
use rocket_okapi::okapi::schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use super::artist::ArtistResponse;

#[derive(Serialize, Deserialize, JsonSchema, Debug)]
#[serde(crate = "rocket::serde")]
pub struct ExtraCreationResponse {
Expand All @@ -18,3 +21,19 @@ pub struct ExtraCreationResponse {
#[schemars(example = "example_uuid")]
pub file_id: Uuid,
}

#[derive(Serialize, JsonSchema)]
pub struct ExtraResponse {
#[serde(flatten)]
pub extra: Extra,
pub thumbnail: Option<Image>,
#[schemars(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
pub package: Option<Package>,
#[schemars(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
pub artist: Option<ArtistResponse>,
#[schemars(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
pub file: Option<File>,
}
6 changes: 4 additions & 2 deletions api/api/src/responses/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod artist;
pub mod extra_creation;
pub mod movie_creation;
pub mod chapter;
pub mod extra;
pub mod movie;
pub mod package;
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::swagger_examples::*;
use domain::models::{file::File, image::Image, movie::Movie, package::Package};
use rocket::serde::uuid::Uuid;
use rocket_okapi::okapi::schemars;
use rocket_okapi::okapi::schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use super::artist::ArtistResponse;

#[derive(Serialize, Deserialize, JsonSchema, Debug)]
#[serde(crate = "rocket::serde")]
pub struct MovieCreationResponse {
Expand All @@ -19,3 +22,19 @@ pub struct MovieCreationResponse {
pub file_id: Uuid,
pub chapters_id: Vec<Uuid>,
}

#[derive(Serialize, JsonSchema)]
pub struct MovieResponse {
#[serde(flatten)]
pub movie: Movie,
pub poster: Option<Image>,
#[schemars(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
pub package: Option<Package>,
#[schemars(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
pub artist: Option<ArtistResponse>,
#[schemars(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
pub file: Option<File>,
}
14 changes: 14 additions & 0 deletions api/api/src/responses/package.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use domain::models::{artist::Artist, image::Image, package::Package};
use rocket_okapi::okapi::schemars;
use rocket_okapi::okapi::schemars::JsonSchema;
use serde::Serialize;

#[derive(Serialize, JsonSchema)]
pub struct PackageResponse {
#[serde(flatten)]
pub package: Package,
pub poster: Option<Image>,
#[schemars(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
pub artist: Option<Option<Artist>>,
}
21 changes: 9 additions & 12 deletions api/api/src/services/artist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,16 @@ pub fn find<'s>(
use domain::schema::artists::dsl::*;
use domain::schema::images::dsl::images;
let uuid_parse_result = Uuid::parse_str(slug_or_uuid);
let mut query = artists.left_join(images).into_boxed();

let (artist, image) = match uuid_parse_result {
Ok(uuid) => artists
.left_join(images)
.filter(id.eq(uuid))
.select((Artist::as_select(), Option::<Image>::as_select()))
.first(connection),
_ => artists
.left_join(images)
.filter(slug.eq(slug_or_uuid))
.select((Artist::as_select(), Option::<Image>::as_select()))
.first(connection),
}?;
if let Ok(uuid) = uuid_parse_result {
query = query.filter(id.eq(uuid));
} else {
query = query.filter(slug.eq(slug_or_uuid))
}
let (artist, image) = query
.select((Artist::as_select(), Option::<Image>::as_select()))
.first(connection)?;

Ok(ArtistResponse {
artist,
Expand Down
29 changes: 29 additions & 0 deletions api/api/src/services/chapters.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use diesel::prelude::*;
use domain::models::{chapter::Chapter, image::Image};
use rocket::serde::uuid::Uuid;

use crate::responses::chapter::ChapterResponse;

pub fn find_by_movie(
movie_uuid: &Uuid,
connection: &mut PgConnection,
) -> Result<Vec<ChapterResponse>, diesel::result::Error> {
use domain::schema::chapters::dsl::*;
use domain::schema::images::dsl::*;

let movie_chapters: Vec<(Chapter, Option<Image>)> = chapters
.filter(movie_id.eq(movie_uuid))
.left_join(images)
.order(start_time.asc())
.get_results(connection)?;

Ok(movie_chapters
.iter()
.map(move |(chapter, thumbnail)| -> ChapterResponse {
ChapterResponse {
chapter: chapter.clone(),
thumbnail: thumbnail.clone(),
}
})
.collect())
}
30 changes: 28 additions & 2 deletions api/api/src/services/extra.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use diesel::{prelude::*, PgConnection};
use domain::models::extra::{Extra, ExtraType};
use domain::models::{
extra::{Extra, ExtraType},
image::Image,
};
use rocket::serde::uuid::Uuid;
use slug::slugify;

use crate::responses::extra::ExtraResponse;

pub fn create<'s>(
extra_name: &'s str,
disc: Option<i16>,
Expand All @@ -29,6 +34,27 @@ pub fn create<'s>(

diesel::insert_into(extras)
.values(&creation_dto)
// .select(Extra::as_select())
.get_result::<Extra>(connection)
}

pub fn find(
uuid: &Uuid,
connection: &mut PgConnection,
) -> Result<ExtraResponse, diesel::result::Error> {
use domain::schema::extras::dsl::*;
use domain::schema::images::dsl::images;

let (extra, image) = extras
.filter(id.eq(uuid))
.left_join(images)
.select((Extra::as_select(), Option::<Image>::as_select()))
.first(connection)?;

Ok(ExtraResponse {
extra,
thumbnail: image,
artist: None,
package: None,
file: None,
})
}
7 changes: 7 additions & 0 deletions api/api/src/services/file.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use diesel::prelude::*;
use domain::models::{file::File, video_quality::VideoQuality};
use rocket::serde::uuid::Uuid;

pub fn create_or_find<'s>(
file_path: &'s str,
Expand All @@ -26,3 +27,9 @@ pub fn create_or_find<'s>(
.values(&creation_dto)
.get_result(connection)
}

pub fn find(uuid: &Uuid, connection: &mut PgConnection) -> Result<File, diesel::result::Error> {
use domain::schema::files::dsl::*;

files.filter(id.eq(uuid)).first(connection)
}
1 change: 1 addition & 0 deletions api/api/src/services/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod artist;
pub mod chapter;
pub mod chapters;
pub mod extra;
pub mod file;
pub mod image;
Expand Down
Loading
Loading