feat(search): add bmkg, jadwal-sholat, weather, yt-search, google endpoints

This commit is contained in:
asepharyana
2026-09-01 19:51:34 +07:00
parent 091a68bd55
commit 7ffc1bdd81
11 changed files with 442 additions and 24 deletions
+1
View File
@@ -5,5 +5,6 @@ pub mod health;
pub mod komik;
pub mod misc;
pub mod proxy;
pub mod search;
pub mod stalk;
pub mod weebs;
+62
View File
@@ -0,0 +1,62 @@
//! Axum handlers for search utilities.
//!
//! Ported from Shirokami-API `scraper/search/*.js`.
use axum::extract::Query;
use axum::http::StatusCode;
use axum::Json;
use serde::Deserialize;
use serde_json::Value;
use crate::application::search as use_cases;
use crate::presentation::error::AppError;
#[derive(Deserialize)]
pub struct SearchParams {
pub query: Option<String>,
pub q: Option<String>,
pub kota: Option<String>,
pub city: Option<String>,
}
fn require<'a>(v: Option<&'a String>, name: &str) -> Result<String, AppError> {
v.cloned()
.ok_or_else(|| AppError::BadRequest(format!("Missing '{}' parameter", name)))
}
/// GET /search/bmkg
pub async fn bmkg_handler() -> Result<(StatusCode, Json<Value>), AppError> {
Ok((StatusCode::OK, Json(use_cases::bmkg().await?)))
}
/// GET /search/jadwal-sholat?kota=jakarta
pub async fn jadwal_sholat_handler(
Query(p): Query<SearchParams>,
) -> Result<(StatusCode, Json<Value>), AppError> {
let kota = require(p.kota.as_ref(), "kota")?;
Ok((StatusCode::OK, Json(use_cases::jadwal_sholat(&kota).await?)))
}
/// GET /search/weather?city=jakarta
pub async fn weather_handler(
Query(p): Query<SearchParams>,
) -> Result<(StatusCode, Json<Value>), AppError> {
let city = require(p.city.as_ref().or(p.q.as_ref()), "city")?;
Ok((StatusCode::OK, Json(use_cases::weather(&city).await?)))
}
/// GET /search/google?query=rust
pub async fn google_handler(
Query(p): Query<SearchParams>,
) -> Result<(StatusCode, Json<Value>), AppError> {
let query = require(p.query.as_ref().or(p.q.as_ref()), "query")?;
Ok((StatusCode::OK, Json(use_cases::google(&query).await?)))
}
/// GET /search/yt?query=rickroll
pub async fn yt_handler(
Query(p): Query<SearchParams>,
) -> Result<(StatusCode, Json<Value>), AppError> {
let query = require(p.query.as_ref().or(p.q.as_ref()), "query")?;
Ok((StatusCode::OK, Json(use_cases::yt_search(&query).await?)))
}
+21
View File
@@ -303,6 +303,27 @@ pub fn build_router(app_state: Arc<AppState>) -> anyhow::Result<Router> {
"/weebs/nsfw-waifu",
axum::routing::get(crate::presentation::handler::weebs::nsfw_waifu_handler),
)
// Search routes
.route(
"/search/bmkg",
axum::routing::get(crate::presentation::handler::search::bmkg_handler),
)
.route(
"/search/jadwal-sholat",
axum::routing::get(crate::presentation::handler::search::jadwal_sholat_handler),
)
.route(
"/search/weather",
axum::routing::get(crate::presentation::handler::search::weather_handler),
)
.route(
"/search/google",
axum::routing::get(crate::presentation::handler::search::google_handler),
)
.route(
"/search/yt",
axum::routing::get(crate::presentation::handler::search::yt_handler),
)
// Health
.route(
"/health",