A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
98
fork

Configure Feed

Select the types of activity you want to include in your feed.

[scrobbler] add valite token endpoint

+60
+17
crates/scrobbler/src/handlers/mod.rs
··· 12 12 use crate::cache::Cache; 13 13 use crate::listenbrainz::submit::submit_listens; 14 14 use crate::listenbrainz::types::SubmitListensRequest; 15 + use crate::listenbrainz::validate_token::validate_token; 15 16 use crate::BANNER; 16 17 17 18 pub mod scrobble; ··· 119 120 .map_err(actix_web::error::ErrorBadRequest)?; 120 121 121 122 submit_listens(req, cache.get_ref(), data.get_ref(), token) 123 + .await 124 + .map_err(actix_web::error::ErrorInternalServerError) 125 + } 126 + 127 + #[get("/listenbrainz/1/validate-token")] 128 + pub async fn handle_validate_token( 129 + req: HttpRequest, 130 + ) -> impl Responder { 131 + let token = match req.headers().get("Authorization") { 132 + Some(header) => header.to_str().map_err(actix_web::error::ErrorBadRequest)?, 133 + None => return Ok(HttpResponse::Unauthorized().finish()), 134 + }; 135 + let token = token.trim_start_matches("Token "); 136 + let token = token.trim_start_matches("Bearer "); 137 + 138 + validate_token(token) 122 139 .await 123 140 .map_err(actix_web::error::ErrorInternalServerError) 124 141 }
+1
crates/scrobbler/src/listenbrainz/mod.rs
··· 1 1 pub mod submit; 2 2 pub mod types; 3 + pub mod validate_token;
+13
crates/scrobbler/src/listenbrainz/submit.rs
··· 1 1 use std::sync::Arc; 2 2 use anyhow::Error; 3 3 use actix_web::HttpResponse; 4 + use owo_colors::OwoColorize; 4 5 use serde_json::json; 5 6 6 7 use crate::{cache::Cache, scrobbler::scrobble_listenbrainz}; ··· 13 14 pool: &Arc<sqlx::Pool<sqlx::Postgres>>, 14 15 token: &str 15 16 ) -> Result<HttpResponse, Error> { 17 + if payload.listen_type != "single" { 18 + println!("skipping listen type: {}", payload.listen_type.cyan()); 19 + return Ok(HttpResponse::Ok().json( 20 + json!({ 21 + "status": "ok", 22 + "payload": { 23 + "submitted_listens": 0, 24 + "ignored_listens": 1 25 + }, 26 + }) 27 + )); 28 + } 16 29 match scrobble_listenbrainz(pool, cache, payload, token) 17 30 .await { 18 31 Ok(_) => Ok(HttpResponse::Ok().json(
+28
crates/scrobbler/src/listenbrainz/validate_token.rs
··· 1 + use actix_web::HttpResponse; 2 + use anyhow::Error; 3 + 4 + use crate::auth::decode_token; 5 + 6 + pub async fn validate_token( 7 + token: &str 8 + ) -> Result<HttpResponse, Error> { 9 + match decode_token(token) { 10 + Ok(_) => Ok(HttpResponse::Ok().json( 11 + serde_json::json!({ 12 + "status": "ok", 13 + "payload": { 14 + "valid": true, 15 + }, 16 + }) 17 + )), 18 + Err(e) => { 19 + println!("Error validating token: {}", e); 20 + Ok(HttpResponse::BadRequest().json( 21 + serde_json::json!({ 22 + "error": 4, 23 + "message": format!("Failed to validate token: {}", e) 24 + }) 25 + )) 26 + } 27 + } 28 + }
+1
crates/scrobbler/src/main.rs
··· 77 77 .service(handlers::handle_nowplaying) 78 78 .service(handlers::handle_submission) 79 79 .service(handlers::handle_submit_listens) 80 + .service(handlers::handle_validate_token) 80 81 .service(handlers::index) 81 82 .service(handlers::handle_get) 82 83 })