diff options
-rw-r--r-- | src/database.rs | 2 | ||||
-rw-r--r-- | src/errors.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/spotify.rs | 181 |
4 files changed, 72 insertions, 114 deletions
diff --git a/src/database.rs b/src/database.rs index 1a3a415..d3e5e03 100644 --- a/src/database.rs +++ b/src/database.rs @@ -9,7 +9,7 @@ lazy_static! { )); } -fn initialize_db() -> Result<(), Error> { +pub fn initialize_db() -> Result<(), Error> { let mut client = CLIENT.lock()?; client.batch_execute( r#" diff --git a/src/errors.rs b/src/errors.rs index d9893ba..8fb2793 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -3,6 +3,7 @@ use rocket::request::Request; use rocket::response::{self, Responder, Response}; use rspotify::spotify::client::ApiError; use rspotify::spotify::oauth2::SpotifyOAuth; +use std::collections::HashMap; use std::io::Cursor; use std::sync::{MutexGuard, PoisonError}; use tokio_postgres::error::Error as DbError; diff --git a/src/main.rs b/src/main.rs index 93a22a6..9dd4551 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ mod serve; mod spotify; fn main() { - //database::initialize_db().unwrap(); + database::initialize_db().expect("failed to initialize_db"); println!("connected with db"); rocket::ignite() .mount( diff --git a/src/spotify.rs b/src/spotify.rs index b9a1147..596dec3 100644 --- a/src/spotify.rs +++ b/src/spotify.rs @@ -2,7 +2,6 @@ use crate::database; use crate::errors::Error; use lazy_static::lazy_static; use rspotify::spotify::client::{ApiError, Spotify}; -use rspotify::spotify::model::playlist::FullPlaylist; use rspotify::spotify::oauth2::{SpotifyClientCredentials, SpotifyOAuth}; use rspotify::spotify::util::process_token; use std::collections::HashMap; @@ -13,127 +12,85 @@ lazy_static! { Arc::new(Mutex::new(HashMap::new())); } -static CHUNK_SIZE: i32 = 50; +static CHUNK_SIZE: u32 = 50; macro_rules! get_items { - ($func_name:ident, $spotify_call:stmt, $t: ty) => { - fn $func_name(spotify_uid: &str, spotify: &mut Spotify) -> Result<Vec<$t>, Error> { - let mut index = 0; - let mut result = Vec::new(); - loop { - match $spotify_call { - Ok(items) => { - index += CHUNK_SIZE; - if items.items.is_empty() { - break; - } - result.append(items.items); + ($t: ty, $index:ident, $spotify_call:expr) => {{ + $index = 0; + let mut result: Vec<$t> = Vec::new(); + loop { + match $spotify_call { + Ok(mut items) => { + $index += CHUNK_SIZE; + if items.items.is_empty() { + 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; - } - }, + result.append(&mut items.items); } - } - Ok((result)) - } - }; -} + Err(e) => match e.downcast::<ApiError>() { + Ok(ApiError::RateLimited(x)) => { + std::thread::sleep(std::time::Duration::from_secs(x.unwrap_or(5) as u64)) + } -get_items!( - playlists, - spotify.user_playlists(spotify_uid.as_ref(), Some(CHUNK_SIZE), Some(playlist_index)), - FullPlaylist -); -fn load_playlist(spotify_uid: &str, spotify: &mut Spotify) -> Result<Vec<FullPlaylist>, Error> { - let mut playlist_index = 0; - loop { - match spotify.user_playlists(spotify_uid.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 {} + 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; - } - }, } - } - Ok(()) + result + }}; } +use rspotify::spotify::model::playlist::*; +use rspotify::spotify::model::track::*; +use rspotify::spotify::senum::TimeRange; pub fn load_profile(db_uid: i32, spotify_uid: &str, spotify: Spotify) -> Result<(), Error> { - let mut playlist_index = 0; - loop { - match spotify.user_playlists(spotify_uid.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( - spotify_uid.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 { - if let Err(e) = insert_track(uid, track.track) { - println!("failed to load track to db: {:?}", e) - }; - } - } - 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; - } - }, + let mut index; + let playlists = get_items!( + SimplifiedPlaylist, + index, + spotify.current_user_playlists(CHUNK_SIZE, index) + ); + let library = get_items!( + SavedTrack, + index, + spotify.current_user_saved_tracks(CHUNK_SIZE, index) + ); + let top_tracks = get_items!( + FullTrack, + index, + 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) { + 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) { + println!("failed to load track to db: {:?}", e) + }; + } + for playlist in playlists { + let tracks = get_items!( + PlaylistTrack, + index, + spotify.user_playlist_tracks( + spotify_uid.as_ref(), + &playlist.id, + None, + CHUNK_SIZE, + index, + None, + ) + ); + for track in tracks { + if let Err(e) = database::insert_track(db_uid, track.track, 1) { + println!("failed to load track to db: {:?}", e) + }; } } Ok(()) |