A decentralized music tracking and discovery platform built on AT Protocol 🎵
listenbrainz spotify atproto lastfm musicbrainz scrobbling

Merge branch 'main' into feat/feed-generator

Changed files
+73 -40
crates
spotify
src
+73 -40
crates/spotify/src/lib.rs
··· 931 931 ); 932 932 933 933 if changed { 934 - scrobble( 935 - cache.clone(), 936 - &spotify_email, 937 - &did, 938 - &token, 939 - &client_id, 940 - &client_secret, 941 - ) 942 - .await?; 934 + cache.setex( 935 + &format!("changed:{}:{}", spotify_email, data_item.id), 936 + &data_item.duration_ms.to_string(), 937 + 3600 * 24, 938 + )?; 939 + } 940 + 941 + let current_track = 942 + match cache.get(&format!("changed:{}:{}", spotify_email, data_item.id)) { 943 + Ok(x) => x.is_some(), 944 + Err(_) => false, 945 + }; 943 946 944 - thread::spawn(move || { 945 - let rt = tokio::runtime::Runtime::new().unwrap(); 946 - match rt.block_on(async { 947 - get_album_tracks( 948 - cache.clone(), 949 - &data_item.album.id, 950 - &token, 951 - &client_id, 952 - &client_secret, 953 - ) 954 - .await?; 955 - get_album( 956 - cache.clone(), 957 - &data_item.album.id, 958 - &token, 959 - &client_id, 960 - &client_secret, 961 - ) 962 - .await?; 963 - update_library( 947 + if let Ok(Some(cached)) = cache.get(&format!("{}:current", spotify_email)) { 948 + let current_song = serde_json::from_str::<CurrentlyPlaying>(&cached)?; 949 + if let Some(item) = current_song.item { 950 + let percentage = current_song.progress_ms.unwrap_or(0) as f32 951 + / data_item.duration_ms as f32 952 + * 100.0; 953 + if current_track && percentage >= 40.0 && item.id == data_item.id { 954 + println!( 955 + "{} Scrobbling track: {} {}", 956 + format!("[{}]", spotify_email).bright_green(), 957 + item.name.yellow(), 958 + format!("{:.2}%", percentage) 959 + ); 960 + scrobble( 964 961 cache.clone(), 965 962 &spotify_email, 966 963 &did, ··· 969 966 &client_secret, 970 967 ) 971 968 .await?; 972 - Ok::<(), Error>(()) 973 - }) { 974 - Ok(_) => {} 975 - Err(e) => { 976 - println!( 977 - "{} {}", 978 - format!("[{}]", spotify_email).bright_green(), 979 - e.to_string().bright_red() 980 - ); 981 - } 969 + 970 + match cache.del(&format!("changed:{}:{}", spotify_email, data_item.id)) { 971 + Ok(_) => {} 972 + Err(_) => tracing::error!("Failed to delete cache entry"), 973 + }; 974 + 975 + thread::spawn(move || { 976 + let rt = tokio::runtime::Runtime::new().unwrap(); 977 + match rt.block_on(async { 978 + get_album_tracks( 979 + cache.clone(), 980 + &data_item.album.id, 981 + &token, 982 + &client_id, 983 + &client_secret, 984 + ) 985 + .await?; 986 + get_album( 987 + cache.clone(), 988 + &data_item.album.id, 989 + &token, 990 + &client_id, 991 + &client_secret, 992 + ) 993 + .await?; 994 + update_library( 995 + cache.clone(), 996 + &spotify_email, 997 + &did, 998 + &token, 999 + &client_id, 1000 + &client_secret, 1001 + ) 1002 + .await?; 1003 + Ok::<(), Error>(()) 1004 + }) { 1005 + Ok(_) => {} 1006 + Err(e) => { 1007 + println!( 1008 + "{} {}", 1009 + format!("[{}]", spotify_email).bright_green(), 1010 + e.to_string().bright_red() 1011 + ); 1012 + } 1013 + } 1014 + }); 982 1015 } 983 - }); 1016 + } 984 1017 } 985 1018 } 986 1019