From 600f0e6a847017ee46c67e885ffbe1acdcba1ded Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Thu, 30 Jan 2020 02:20:16 +0100 Subject: Add web-api --- src/main.rs | 44 +++++---------------- src/serve.rs | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 35 deletions(-) create mode 100644 src/serve.rs (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 1bd3417..8b7af53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,13 @@ +#![feature(proc_macro_hygiene, decl_macro)] + +#[macro_use] +extern crate rocket; use rspotify::spotify::client::Spotify; use rspotify::spotify::oauth2::{SpotifyClientCredentials, SpotifyOAuth}; use rspotify::spotify::util::get_token; +mod serve; + fn main() { // Set client_id and client_secret in .env file or // export CLIENT_ID="your client_id" @@ -14,39 +20,7 @@ fn main() { // .client_secret("this-is-my-client-secret") // .redirect_uri("http://localhost:8888/callback") // .build(); - - let mut spotify_oauth = SpotifyOAuth::default() - .scope("playlist-read-private, playlist-read-collaborative") - .build(); - match get_token(&mut spotify_oauth) { - Some(token_info) => { - let client_credential = SpotifyClientCredentials::default() - .token_info(token_info) - .build(); - - // Or set client_id and client_secret explictly - // let client_credential = SpotifyClientCredentials::default() - // .client_id("this-is-my-client-id") - // .client_secret("this-is-my-client-secret") - // .build(); - let spotify = Spotify::default() - .client_credentials_manager(client_credential) - .build(); - //this is my(samray's) user_id, so just change - // user_id to yours, or you will get a 403 forbidden error - let user_id = "d-kobert"; - let playlists = spotify.user_playlists(user_id, Some(10), None); - for playlist in playlists.unwrap().items { - println!("{:?}", playlist.name); - for track in spotify - .user_playlist_tracks(user_id, &playlist.id, None, Some(2), None, None) - .unwrap() - .items - { - println!("{:?}", track.track.name); - } - } - } - None => println!("auth failed"), - }; + rocket::ignite() + .mount("/", routes![serve::token, serve::get_tracks]) + .launch(); } diff --git a/src/serve.rs b/src/serve.rs new file mode 100644 index 0000000..0dff5da --- /dev/null +++ b/src/serve.rs @@ -0,0 +1,124 @@ +use lazy_static::lazy_static; +use rocket::http::Status; +use rocket::response::{status, Redirect}; +use rspotify::spotify::client::{ApiError, Spotify}; +use rspotify::spotify::oauth2::{SpotifyClientCredentials, SpotifyOAuth}; +use rspotify::spotify::util::process_token; +use std::collections::HashMap; +use std::sync::{Arc, Mutex}; + +lazy_static! { + static ref CACHE: Arc>> = + Arc::new(Mutex::new(HashMap::new())); +} + +#[get("/callback//")] +pub fn get_tracks(name: String, url: String) -> String { + let mut guard = CACHE.lock().unwrap(); + let mut oauth = guard.remove(&name).unwrap(); + println!("auth: {:?} url: {}", oauth, url); + let token_info = process_token(&mut oauth, &mut ("?code=".to_owned() + url.as_ref())); + let client_credential = SpotifyClientCredentials::default() + .token_info(token_info.unwrap()) + .build(); + + let spotify = Spotify::default() + .client_credentials_manager(client_credential) + .build(); + let user_id = spotify.current_user().unwrap().id; + let chunk_size = 50; + let mut playlist_index = 0; + loop { + match spotify.user_playlists(user_id.as_ref(), Some(chunk_size), Some(playlist_index)) { + Ok(playlists) => { + playlist_index += chunk_size; + if playlists.items.is_empty() { + break; + } + for playlist in playlists.items { + println!("playlist: {:?}", playlist.name); + let mut track_index = 0; + + loop { + match spotify.user_playlist_tracks( + user_id.as_ref(), + &playlist.id, + None, + Some(chunk_size), + Some(track_index), + None, + ) { + Ok(tracks) => { + track_index += chunk_size; + if tracks.items.is_empty() { + break; + } + for track in tracks.items { + println!("{:?}", track.track.name); + } + } + Err(e) => match e.downcast::() { + Ok(ApiError::RateLimited(x)) => std::thread::sleep( + std::time::Duration::from_secs(x.unwrap_or(5) as u64), + ), + + cause => { + println!("Error: {:?}", cause); + break; + } + }, + } + } + } + } + Err(e) => match e.downcast::() { + Ok(ApiError::RateLimited(x)) => { + std::thread::sleep(std::time::Duration::from_secs(x.unwrap_or(5) as u64)) + } + + cause => { + println!("Error: {:?}", cause); + break; + } + }, + } + } + name +} +#[get("/token/")] +pub fn token(name: String) -> Result> { + let state = rspotify::spotify::util::generate_random_string(16); + let oauth = SpotifyOAuth::default(); + //let callback = oauth.redirect_uri.clone(); + let oauth = oauth + .scope("playlist-read-private, playlist-read-collaborative, user-read-private, user-follow-read, user-library-read") + //.redirect_uri(format!("{}/{}", callback, &state).as_ref()) + .build(); + let auth_url = oauth.get_authorize_url(Some(&state), None); + match CACHE.lock() { + Ok(mut guard) => { + guard.insert(name, oauth); + Ok(Redirect::to(auth_url)) + } + Err(_) => Err(status::Custom( + Status::ImATeapot, + "Internal Server Error".to_owned(), + )), + } + /*match get_token(&mut oauth) { + Some(token_info) => { + let client_credential = SpotifyClientCredentials::default() + .token_info(token_info) + .build(); + // Or set client_id and client_secret explictly + // let client_credential = SpotifyClientCredentials::default() + // .client_id("this-is-my-client-id") + // .client_secret("this-is-my-client-secret") + // .build(); + let spotify = Spotify::default() + .client_credentials_manager(client_credential) + .build(); + } + None => {} + }*/ +} -- cgit v1.2.3-70-g09d2