A decentralized music tracking and discovery platform built on AT Protocol 馃幍
rocksky.app
spotify
atproto
lastfm
musicbrainz
scrobbling
listenbrainz
1use std::sync::{Arc, Mutex};
2
3use actix_web::{web, HttpRequest, HttpResponse};
4use albums::{get_album_tracks, get_albums, get_top_albums};
5use anyhow::Error;
6use artists::{get_artist_albums, get_artist_tracks, get_artists, get_top_artists};
7use duckdb::Connection;
8use scrobbles::{get_distinct_scrobbles, get_scrobbles};
9use stats::{
10 get_album_scrobbles, get_artist_scrobbles, get_scrobbles_per_day, get_scrobbles_per_month,
11 get_scrobbles_per_year, get_stats, get_track_scrobbles,
12};
13use tracks::{get_loved_tracks, get_top_tracks, get_tracks};
14
15use crate::handlers::{
16 artists::get_artist_listeners,
17 stats::{get_compatibility, get_neighbours},
18};
19
20pub mod albums;
21pub mod artists;
22pub mod scrobbles;
23pub mod stats;
24pub mod tracks;
25
26#[macro_export]
27macro_rules! read_payload {
28 ($payload:expr) => {{
29 let mut body = Vec::new();
30 while let Some(chunk) = $payload.next().await {
31 match chunk {
32 Ok(bytes) => body.extend_from_slice(&bytes),
33 Err(err) => return Err(err.into()),
34 }
35 }
36 body
37 }};
38}
39
40pub async fn handle(
41 method: &str,
42 payload: &mut web::Payload,
43 req: &HttpRequest,
44 conn: Arc<Mutex<Connection>>,
45) -> Result<HttpResponse, Error> {
46 match method {
47 "library.getAlbums" => get_albums(payload, req, conn.clone()).await,
48 "library.getArtists" => get_artists(payload, req, conn.clone()).await,
49 "library.getTracks" => get_tracks(payload, req, conn.clone()).await,
50 "library.getScrobbles" => get_scrobbles(payload, req, conn.clone()).await,
51 "library.getDistinctScrobbles" => get_distinct_scrobbles(payload, req, conn.clone()).await,
52 "library.getLovedTracks" => get_loved_tracks(payload, req, conn.clone()).await,
53 "library.getStats" => get_stats(payload, req, conn.clone()).await,
54 "library.getTopAlbums" => get_top_albums(payload, req, conn.clone()).await,
55 "library.getTopArtists" => get_top_artists(payload, req, conn.clone()).await,
56 "library.getTopTracks" => get_top_tracks(payload, req, conn.clone()).await,
57 "library.getScrobblesPerDay" => get_scrobbles_per_day(payload, req, conn.clone()).await,
58 "library.getScrobblesPerMonth" => get_scrobbles_per_month(payload, req, conn.clone()).await,
59 "library.getScrobblesPerYear" => get_scrobbles_per_year(payload, req, conn.clone()).await,
60 "library.getAlbumScrobbles" => get_album_scrobbles(payload, req, conn.clone()).await,
61 "library.getArtistScrobbles" => get_artist_scrobbles(payload, req, conn.clone()).await,
62 "library.getTrackScrobbles" => get_track_scrobbles(payload, req, conn.clone()).await,
63 "library.getAlbumTracks" => get_album_tracks(payload, req, conn.clone()).await,
64 "library.getArtistAlbums" => get_artist_albums(payload, req, conn.clone()).await,
65 "library.getArtistTracks" => get_artist_tracks(payload, req, conn.clone()).await,
66 "library.getArtistListeners" => get_artist_listeners(payload, req, conn.clone()).await,
67 "library.getNeighbours" => get_neighbours(payload, req, conn.clone()).await,
68 "library.getCompatibility" => get_compatibility(payload, req, conn.clone()).await,
69 _ => return Err(anyhow::anyhow!("Method not found")),
70 }
71}