summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kobert <dennis@kobert.dev>2020-03-03 18:59:03 +0100
committerDennis Kobert <dennis@kobert.dev>2020-03-03 18:59:03 +0100
commite4ce9a3ced88745116fe85e1a3093f1536df2ad9 (patch)
treee77fdb0495c426058b00f795032fb701bf40c8ff
parent51bc62b4346446dab84e02aa4533d4a4340b7485 (diff)
Restructure fetching of spotify songs
-rw-r--r--src/database.rs2
-rw-r--r--src/errors.rs1
-rw-r--r--src/main.rs2
-rw-r--r--src/spotify.rs181
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(())