diff options
| author | Fuwn <[email protected]> | 2021-05-06 17:33:46 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2021-05-06 17:33:46 -0700 |
| commit | ba5cf895d7213efed871dd23a37622454dc228d1 (patch) | |
| tree | b70e2faf16e1c221aff44bf143a67ca3a361deae /src | |
| parent | etc: Remove useless CORS headers (diff) | |
| download | api-ba5cf895d7213efed871dd23a37622454dc228d1.tar.xz api-ba5cf895d7213efed871dd23a37622454dc228d1.zip | |
feat(global): :star:
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 35 | ||||
| -rw-r--r-- | src/routes.rs | 41 | ||||
| -rw-r--r-- | src/utils.rs | 20 |
3 files changed, 56 insertions, 40 deletions
diff --git a/src/main.rs b/src/main.rs index 50e4d9b..18f56fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,27 +1,36 @@ // Copyleft (ɔ) 2021-2021 The Senpy Club // SPDX-License-Identifier: GPL-3.0-only -#![feature(proc_macro_hygiene, decl_macro, type_ascription)] +#![feature(type_ascription)] #[macro_use] -extern crate rocket; +extern crate actix_web; pub mod constants; pub mod routes; pub mod structures; pub mod utils; -#[launch] -fn rocket() -> _ { +#[actix_web::main] +async fn main() -> std::io::Result<()> { dotenv::dotenv().ok(); - rocket::build().mount("/", routes![routes::index]).mount( - "/api/v1", - routes![ - routes::github, - routes::languages, - routes::language, - routes::random - ], - ) + actix_web::HttpServer::new(|| { + actix_web::App::new() + .wrap(actix_cors::Cors::default().allow_any_origin()) + .service(routes::index) + .service( + actix_web::web::scope("/api/v1") + .service(routes::github) + .service(routes::languages) + .service(routes::language) + .service(routes::random), + ) + }) + .bind(format!( + "0.0.0.0:{}", + std::env::var("PORT").expect("no port was provided... ~why~") + ))? + .run() + .await } diff --git a/src/routes.rs b/src/routes.rs index d7512b4..8c831ac 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -1,17 +1,18 @@ // Copyleft (ɔ) 2021-2021 The Senpy Club // SPDX-License-Identifier: GPL-3.0-only +use actix_web::{HttpRequest, HttpResponse}; use rand::{thread_rng, Rng}; -use rocket_contrib::json::Json; use crate::{ - structures::{GitHubAPIResponse, SenpyRandom}, + structures::SenpyRandom, utils::{filter_images_by_language, filter_languages, github_api}, }; #[get("/")] -pub fn index() -> &'static str { - r#"# senpy-api +pub fn index() -> HttpResponse { + HttpResponse::Ok().body( + r#"# senpy-api ## routes if a language requires a parameter, it will be notated like <this>. for example; if a route is notated as "/api/v1/route?<parameter>", you can @@ -41,38 +42,38 @@ https://github.com/fuwn ### license gnu general public license v3.0 (gpl-3.0-only) -https://github.com/senpy-club/api/blob/main/license"# +https://github.com/senpy-club/api/blob/main/license"#, + ) } #[get("/github")] -pub async fn github() -> Json<GitHubAPIResponse> { Json(github_api().await.unwrap()) } +pub async fn github() -> HttpResponse { HttpResponse::Ok().json(github_api().await.unwrap()) } #[get("/languages")] -pub async fn languages() -> Json<Vec<String>> { Json(filter_languages().await) } +pub async fn languages() -> HttpResponse { HttpResponse::Ok().json(filter_languages().await) } -#[get("/language?<lang>")] -pub async fn language(lang: Option<String>) -> Json<Vec<String>> { - // lang.map(async |lang| Json(filter_images_by_language(lang).await)) - // .unwrap_or_else(|| Json(vec!["invalid language or no language - // specified".to_string()])); +#[get("/language")] +pub async fn language(req: HttpRequest) -> HttpResponse { + let queries = qstring::QString::from(req.query_string()); + let lang = queries.get("lang").unwrap_or("null"); - return if lang.is_none() { - Json(vec!["invalid language or no language specified".to_string()]) + return if lang == "null" { + HttpResponse::Ok().json(vec!["invalid language or no language specified".to_string()]) } else { - Json(filter_images_by_language(lang.unwrap()).await) + HttpResponse::Ok().json(filter_images_by_language(lang).await) }; } #[get("/random")] -pub async fn random() -> Json<SenpyRandom> { +pub async fn random() -> HttpResponse { let filtered_languages = filter_languages().await; let random_language = &filtered_languages[thread_rng().gen_range(0..filtered_languages.len() - 1)]; - let filtered_images = filter_images_by_language(random_language.clone().to_owned()).await; + let filtered_images = filter_images_by_language(random_language).await; let random_image = &filtered_images[thread_rng().gen_range(0..filtered_images.len() - 1)]; - Json(SenpyRandom { - language: random_language.clone().to_owned(), - image: random_image.clone().to_owned(), + HttpResponse::Ok().json(SenpyRandom { + language: random_language.clone(), + image: random_image.clone(), }) } diff --git a/src/utils.rs b/src/utils.rs index 9cadfca..bf10d71 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -6,19 +6,25 @@ use crate::{ structures::GitHubAPIResponse, }; -pub async fn github_api() -> Result<GitHubAPIResponse, reqwest::Error> { +pub async fn github_api() -> Result<GitHubAPIResponse, Box<dyn std::error::Error>> { Ok( - reqwest::Client::new() + actix_web::client::Client::new() .get(GITHUB_API_ENDPOINT) .header("User-Agent", USER_AGENT) .header( "Authorization", - format!("token {}", std::env::var("GITHUB_TOKEN").unwrap()), + format!( + "token {}", + std::env::var("GITHUB_TOKEN").unwrap_or_else(|_| "Null".to_string()) + ), ) .send() - .await? + .await + .unwrap() .json::<GitHubAPIResponse>() - .await?, + .limit(20_000_000) + .await + .unwrap(), ) } @@ -34,7 +40,7 @@ pub async fn filter_languages() -> Vec<String> { languages } -pub async fn filter_images_by_language(language: String) -> Vec<String> { +pub async fn filter_images_by_language(language: &str) -> Vec<String> { let mut images = vec![]; for i in github_api().await.unwrap().tree { @@ -42,7 +48,7 @@ pub async fn filter_images_by_language(language: String) -> Vec<String> { // "Language/Image.png" would become ["Language", "Image.png"] // TODO: Fix this with type_ascription - let x: Vec<&str> = i.path.split("/").collect(); + let x: Vec<&str> = i.path.split('/').collect(); if x[0] == language && i.path.contains('/') { images.push(format!("{}{}", GITHUB_USER_CONTENT, i.path)) } |