feat(stalk): add github + youtube profile stalk endpoints

Ported from Shirokami-API scraper/stalk/{github,youtube}.js:
- /stalk/github (GitHub public API profile)
- /stalk/youtube (ytInitialData parse from /videos subpage:
  handles lockupViewModel (new), videoRenderer, gridVideoRenderer,
  shortsLockupViewModel; channel metadata + top-5 videos)

Also fix misc harga-emas main price to smallest-gram (1gr).
This commit is contained in:
asepharyana
2026-09-01 19:31:37 +07:00
parent 6df8af54eb
commit 242e3498fe
7 changed files with 478 additions and 0 deletions
+1
View File
@@ -5,3 +5,4 @@ pub mod health;
pub mod komik;
pub mod misc;
pub mod proxy;
pub mod stalk;
+44
View File
@@ -0,0 +1,44 @@
//! Axum handlers for stalk (profile/user lookups).
//!
//! Ported from Shirokami-API `scraper/stalk/*.js`.
use axum::extract::Query;
use axum::http::StatusCode;
use axum::Json;
use serde::Deserialize;
use serde_json::Value;
use crate::application::stalk as use_cases;
use crate::presentation::error::AppError;
/// Query params for stalk endpoints.
#[derive(Deserialize)]
pub struct StalkParams {
pub username: Option<String>,
pub user_id: Option<String>,
pub userid: Option<String>,
pub zone_id: Option<String>,
pub zoneid: Option<String>,
}
/// GET /stalk/github?username=asepharyana
pub async fn github_handler(
Query(params): Query<StalkParams>,
) -> Result<(StatusCode, Json<Value>), AppError> {
let username = params
.username
.ok_or_else(|| AppError::BadRequest("Missing 'username' parameter".to_string()))?;
let result = use_cases::github(&username).await?;
Ok((StatusCode::OK, Json(result)))
}
/// GET /stalk/youtube?username=<handle>
pub async fn youtube_handler(
Query(params): Query<StalkParams>,
) -> Result<(StatusCode, Json<Value>), AppError> {
let username = params
.username
.ok_or_else(|| AppError::BadRequest("Missing 'username' parameter".to_string()))?;
let result = use_cases::youtube(&username).await?;
Ok((StatusCode::OK, Json(result)))
}
+9
View File
@@ -273,6 +273,15 @@ pub fn build_router(app_state: Arc<AppState>) -> anyhow::Result<Router> {
"/misc/server-info",
axum::routing::get(crate::presentation::handler::misc::server_info_handler),
)
// Stalk routes
.route(
"/stalk/github",
axum::routing::get(crate::presentation::handler::stalk::github_handler),
)
.route(
"/stalk/youtube",
axum::routing::get(crate::presentation::handler::stalk::youtube_handler),
)
// Health
.route(
"/health",