summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDennis Kobert <dennis@kobert.dev>2020-01-30 02:20:16 +0100
committerDennis Kobert <dennis@kobert.dev>2020-01-30 02:20:16 +0100
commit600f0e6a847017ee46c67e885ffbe1acdcba1ded (patch)
tree3886fa9376053d26c70355b20dcc76708769ebc4 /src
parent4878b00ba634ed9f4eeeffc1d488a5702f9383d9 (diff)
Add web-api
Diffstat (limited to 'src')
-rw-r--r--src/main.rs44
-rw-r--r--src/serve.rs124
2 files changed, 133 insertions, 35 deletions
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<Mutex<HashMap<String, SpotifyOAuth>>> =
+ Arc::new(Mutex::new(HashMap::new()));
+}
+
+#[get("/callback/<name>/<url>")]
+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::<ApiError>() {
+ 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::<ApiError>() {
+ 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/<name>")]
+pub fn token(name: String) -> Result<Redirect, status::Custom<String>> {
+ 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 => {}
+ }*/
+}