summaryrefslogtreecommitdiff
path: root/src/spotify.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/spotify.rs')
-rw-r--r--src/spotify.rs95
1 files changed, 64 insertions, 31 deletions
diff --git a/src/spotify.rs b/src/spotify.rs
index 0e18c43..ea05b14 100644
--- a/src/spotify.rs
+++ b/src/spotify.rs
@@ -1,19 +1,16 @@
use crate::database;
use crate::errors::Error;
use lazy_static::lazy_static;
-use rspotify::client::{ApiError, Spotify};
-use rspotify::model::page::Page;
+use rand::{Rng, RngCore};
+use rspotify::client::{ClientError, Spotify};
+use rspotify::model::enums::TimeRange;
use rspotify::model::playlist::*;
use rspotify::model::track::*;
-use rspotify::oauth2::{SpotifyClientCredentials, SpotifyOAuth};
-use rspotify::senum::TimeRange;
-use rspotify::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()));
+ static ref CACHE: Arc<Mutex<HashMap<String, Spotify>>> = Arc::new(Mutex::new(HashMap::new()));
}
static CHUNK_SIZE: u32 = 50;
@@ -23,8 +20,7 @@ macro_rules! get_items {
$index = 0;
let mut result: Vec<$t> = Vec::new();
loop {
- let res: Result<Page<$t>, failure::Error> = $spotify_call.await;
- match res {
+ match $spotify_call.await {
Ok(mut page) => {
$index += CHUNK_SIZE;
if page.items.is_empty() {
@@ -32,8 +28,8 @@ macro_rules! get_items {
}
result.append(&mut page.items);
}
- Err(e) => match e.downcast::<ApiError>() {
- Ok(ApiError::RateLimited(x)) => {
+ Err(e) => match e {
+ ClientError::RateLimited(x) => {
std::thread::sleep(std::time::Duration::from_secs(x.unwrap_or(5) as u64))
}
@@ -66,22 +62,23 @@ pub async fn load_profile(db_uid: i32, spotify_uid: &str, spotify: Spotify) -> R
spotify.current_user_top_tracks(CHUNK_SIZE, index, TimeRange::MediumTerm)
);
for track in library {
- if let Err(e) = database::insert_track(db_uid, track.track, 5) {
+ if let Err(e) = database::insert_track(db_uid, track.track, 5).await {
println!("failed to load track to db: {:?}", e)
};
}
for (pos, track) in top_tracks.iter().enumerate() {
let weight = ((50.0 - pos as f64) / 50.0 * 10.0).floor() as i32;
- if let Err(e) = database::insert_track(db_uid, track.clone(), 5 + weight) {
+ if let Err(e) = database::insert_track(db_uid, track.clone(), 5 + weight).await {
println!("failed to load track to db: {:?}", e)
};
}
+ let playlists = playlists.iter().map(|x| x.clone());
for playlist in playlists {
let tracks = get_items!(
- PlaylistTrack,
+ PlaylistItem,
index,
- spotify.user_playlist_tracks(
- spotify_uid.as_ref(),
+ spotify.playlist_tracks(
+ //spotify_uid.as_ref(),
&playlist.id,
None,
CHUNK_SIZE,
@@ -89,8 +86,9 @@ pub async fn load_profile(db_uid: i32, spotify_uid: &str, spotify: Spotify) -> R
None,
)
);
- for track in tracks.iter().map(|x| x.track.clone()).flatten() {
- if let Err(e) = database::insert_track(db_uid, track, 1) {
+ let tracks: Vec<FullTrack> = tracks.iter().map(|x| x.track.clone()).flatten().collect();
+ for track in tracks {
+ if let Err(e) = database::insert_track(db_uid, track, 1).await {
println!("failed to load track to db: {:?}", e)
};
}
@@ -98,21 +96,37 @@ pub async fn load_profile(db_uid: i32, spotify_uid: &str, spotify: Spotify) -> R
Ok(())
}
-pub async fn auth_user(name: &str, url: String) -> Result<(String, Spotify), Error> {
- let mut oauth = {
- let mut guard = CACHE.lock()?;
+use rspotify::client::SpotifyBuilder;
+use rspotify::oauth2::{CredentialsBuilder, OAuthBuilder};
+
+/// Generate `length` random chars
+fn generate_random_uuid(length: usize) -> String {
+ let alphanum: &[u8] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".as_bytes();
+ let mut buf = vec![0u8; length];
+ rand::thread_rng().fill_bytes(buf.as_mut_slice());
+ let range = alphanum.len();
+
+ buf.iter()
+ .map(|byte| alphanum[*byte as usize % range] as char)
+ .collect()
+}
+
+pub async fn auth_user(name: &str, code: &str) -> Result<(String, Spotify), Error> {
+ let mut spotify = {
+ let mut guard = (*CACHE).lock()?;
guard.remove(name)?
};
- println!("auth: {:?} url: {}", oauth, url);
- let mut token_string = format!("?code={}", url);
- let token_info = process_token(&mut oauth, &mut token_string);
- let client_credential = SpotifyClientCredentials::default()
+ println!("auth: {:?} url: {}", name, code);
+ spotify.request_user_token(code).await?;
+ //let token_info = process_token(&mut oauth, &mut token_string);
+ /*let client_credential = SpotifyClientCredentials::default()
.token_info(token_info.await?)
.build();
let spotify = Spotify::default()
- .client_credentials_manager(client_credential)
- .build();
+ .client_credentials_manager(client_credential)
+ .build();*/
let user_id = spotify
.current_user()
.await
@@ -122,13 +136,32 @@ pub async fn auth_user(name: &str, url: String) -> Result<(String, Spotify), Err
}
pub fn token(name: String) -> Result<String, Error> {
- let state = rspotify::util::generate_random_string(16);
+ let scope = "playlist-read-private playlist-read-collaborative user-read-private user-follow-read user-library-read";
+
+ let oauth = OAuthBuilder::from_env()
+ .scope(scope.split_whitespace().map(|x| x.to_owned()).collect())
+ .build()
+ .unwrap();
+ let creds = CredentialsBuilder::from_env().build().unwrap();
+
+ let spotify = SpotifyBuilder::default()
+ .credentials(creds)
+ .oauth(oauth)
+ .build()
+ .unwrap();
+
+ let auth_url = spotify.get_authorize_url(false).unwrap();
+
+ //let token = spotify.token.as_ref().unwrap();
+
+ /*let state = rspotify::util::generate_random_string(16);
let oauth = SpotifyOAuth::default();
let oauth = oauth
.scope("playlist-read-private, playlist-read-collaborative, user-read-private, user-follow-read, user-library-read")
.build();
- let auth_url = oauth.get_authorize_url(Some(&state), None);
- let mut guard = CACHE.lock()?;
- guard.insert(name, oauth);
+ */
+ //let auth_url = oauth.get_authorize_url(Some(&state), None);
+ let mut guard = (*CACHE).lock()?;
+ guard.insert(name, spotify);
Ok(auth_url)
}