feat: add support for album links
- perform little code refactor, create new module spotify
This commit is contained in:
		
							parent
							
								
									34c294ef0f
								
							
						
					
					
						commit
						cea5958e43
					
				| @ -1,6 +1,6 @@ | |||||||
| [package] | [package] | ||||||
| name = "songlify" | name = "songlify" | ||||||
| version = "0.1.0" | version = "0.2.0" | ||||||
| edition = "2018" | edition = "2018" | ||||||
| 
 | 
 | ||||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  | |||||||
							
								
								
									
										77
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -1,39 +1,13 @@ | |||||||
| use crate::SpotifyURL::Track; |  | ||||||
| use aspotify::{Client, ClientCredentials}; |  | ||||||
| use std::time::Duration; | use std::time::Duration; | ||||||
|  | 
 | ||||||
|  | use aspotify::Client; | ||||||
| use teloxide::prelude::*; | use teloxide::prelude::*; | ||||||
| 
 | 
 | ||||||
| enum SpotifyURL { | use spotify::SpotifyKind::Track; | ||||||
|     Track(String), |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| struct TrackInfo { | use crate::spotify::SpotifyKind::Album; | ||||||
|     name: String, |  | ||||||
|     artist: Vec<String>, |  | ||||||
|     duration: Duration, |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| fn get_spotify_entry(url: &str) -> Option<SpotifyURL> { | mod spotify; | ||||||
|     if url.contains("https://open.spotify.com/track/") { |  | ||||||
|         let track_id = url.rsplit('/').next().and_then(|x| x.split('?').next()); |  | ||||||
|         return match track_id { |  | ||||||
|             Some(id) => Some(SpotifyURL::Track(id.to_string())), |  | ||||||
|             None => None, |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
|     return None; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| async fn get_spotify_track(spotify: Box<Client>, id: &String) -> Option<TrackInfo> { |  | ||||||
|     match spotify.tracks().get_track(id.as_str(), None).await { |  | ||||||
|         Ok(track) => Some(TrackInfo { |  | ||||||
|             name: track.data.name, |  | ||||||
|             artist: track.data.artists.iter().map(|x| x.name.clone()).collect(), |  | ||||||
|             duration: track.data.duration, |  | ||||||
|         }), |  | ||||||
|         Err(_e) => None, |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| #[tokio::main] | #[tokio::main] | ||||||
| async fn main() { | async fn main() { | ||||||
| @ -42,16 +16,14 @@ async fn main() { | |||||||
| 
 | 
 | ||||||
|     let bot = Bot::from_env().auto_send(); |     let bot = Bot::from_env().auto_send(); | ||||||
|     teloxide::repl(bot, |message| async move { |     teloxide::repl(bot, |message| async move { | ||||||
|         let text = message.update.text().and_then(get_spotify_entry); |         let text = message.update.text().and_then(spotify::get_spotify_entry); | ||||||
|         match text { |         match text { | ||||||
|             Some(spotify) => { |             Some(spotify) => { | ||||||
|                 let spotify_creds = |                 let spotify_client = spotify::get_spotify_client(); | ||||||
|                     ClientCredentials::from_env().expect("CLIENT_ID and CLIENT_SECRET not found."); |  | ||||||
|                 let spotify_client = Box::new(Client::new(spotify_creds)); |  | ||||||
|                 match spotify { |                 match spotify { | ||||||
|                     Track(id) => { |                     Track(id) => { | ||||||
|                         log::debug!("Parsing spotify song: {}", id); |                         log::debug!("Parsing spotify song: {}", id); | ||||||
|                         let track_info = get_spotify_track(spotify_client, &id).await; |                         let track_info = spotify::get_spotify_track(spotify_client, &id).await; | ||||||
|                         match track_info { |                         match track_info { | ||||||
|                             Some(info) => { |                             Some(info) => { | ||||||
|                                 let reply = format!( |                                 let reply = format!( | ||||||
| @ -60,7 +32,7 @@ async fn main() { | |||||||
|                                 🧑🎤 Artist(s): {}\n\ |                                 🧑🎤 Artist(s): {}\n\ | ||||||
|                                 ⏳ Duration: {} second(s)",
 |                                 ⏳ Duration: {} second(s)",
 | ||||||
|                                     info.name, |                                     info.name, | ||||||
|                                     info.artist.join(", "), |                                     info.artists.join(", "), | ||||||
|                                     info.duration.as_secs() |                                     info.duration.as_secs() | ||||||
|                                 ); |                                 ); | ||||||
|                                 Some(message.reply_to(reply).await?) |                                 Some(message.reply_to(reply).await?) | ||||||
| @ -68,6 +40,37 @@ async fn main() { | |||||||
|                             None => None, |                             None => None, | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                     Album(id) => { | ||||||
|  |                         log::debug!("Parsing spotify album: {}", id); | ||||||
|  |                         let album_info = spotify::get_spotify_album(spotify_client, &id).await; | ||||||
|  |                         match album_info { | ||||||
|  |                             Some(info) => { | ||||||
|  |                                 let mut reply = format!( | ||||||
|  |                                     "Album information:\n\ | ||||||
|  |                                     🎵 Album name name: {}\n\ | ||||||
|  |                                 🧑🎤 Artist(s): {}",
 | ||||||
|  |                                     info.name, | ||||||
|  |                                     info.artists.join(", ") | ||||||
|  |                                 ); | ||||||
|  |                                 if !info.genres.is_empty() { | ||||||
|  |                                     reply.push_str( | ||||||
|  |                                         format!("\n💿 Genre(s): {}", info.genres.join(", ")) | ||||||
|  |                                             .as_str(), | ||||||
|  |                                     ); | ||||||
|  |                                 } | ||||||
|  |                                 if !info.songs.is_empty() { | ||||||
|  |                                     let songs = info | ||||||
|  |                                         .songs | ||||||
|  |                                         .iter() | ||||||
|  |                                         .map(|x| x.name.clone() + "\n") | ||||||
|  |                                         .collect::<String>(); | ||||||
|  |                                     reply.push_str(format!("\n🎶 Song(s): {}", songs).as_str()); | ||||||
|  |                                 } | ||||||
|  |                                 Some(message.reply_to(reply).await?) | ||||||
|  |                             } | ||||||
|  |                             None => None, | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             None => None, |             None => None, | ||||||
|  | |||||||
							
								
								
									
										76
									
								
								src/spotify/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/spotify/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | |||||||
|  | use std::time::Duration; | ||||||
|  | 
 | ||||||
|  | use aspotify::{Client, ClientCredentials}; | ||||||
|  | 
 | ||||||
|  | pub enum SpotifyKind { | ||||||
|  |     Track(String), | ||||||
|  |     Album(String), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn get_id_in_url(url: &str) -> Option<&str> { | ||||||
|  |     url.rsplit('/') | ||||||
|  |         .next() | ||||||
|  |         .and_then(|x| x.split(' ').next()) | ||||||
|  |         .and_then(|x| x.split('?').next()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn get_spotify_entry(url: &str) -> Option<SpotifyKind> { | ||||||
|  |     if url.contains("https://open.spotify.com/track/") { | ||||||
|  |         let track_id = get_id_in_url(url); | ||||||
|  |         return match track_id { | ||||||
|  |             Some(id) => Some(SpotifyKind::Track(id.to_string())), | ||||||
|  |             None => None, | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  |     if url.contains("https://open.spotify.com/album/") { | ||||||
|  |         let album_id = get_id_in_url(url); | ||||||
|  |         return match album_id { | ||||||
|  |             Some(id) => Some(SpotifyKind::Album(id.to_string())), | ||||||
|  |             None => None, | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  |     return None; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn get_spotify_client() -> Box<Client> { | ||||||
|  |     let spotify_creds = | ||||||
|  |         ClientCredentials::from_env().expect("CLIENT_ID and CLIENT_SECRET not found."); | ||||||
|  |     let spotify_client = Box::new(Client::new(spotify_creds)); | ||||||
|  |     spotify_client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct TrackInfo { | ||||||
|  |     name: String, | ||||||
|  |     artists: Vec<String>, | ||||||
|  |     duration: Duration, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct AlbumInfo { | ||||||
|  |     pub(crate) name: String, | ||||||
|  |     pub(crate) artists: Vec<String>, | ||||||
|  |     pub(crate) genres: Vec<String>, | ||||||
|  |     songs: Vec<TrackInfo>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub async fn get_spotify_track(spotify: Box<Client>, id: &String) -> Option<TrackInfo> { | ||||||
|  |     match spotify.tracks().get_track(id.as_str(), None).await { | ||||||
|  |         Ok(track) => Some(TrackInfo { | ||||||
|  |             name: track.data.name, | ||||||
|  |             artists: track.data.artists.iter().map(|x| x.name.clone()).collect(), | ||||||
|  |             duration: track.data.duration, | ||||||
|  |         }), | ||||||
|  |         Err(_e) => None, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub async fn get_spotify_album(spotify: Box<Client>, id: &String) -> Option<AlbumInfo> { | ||||||
|  |     match spotify.albums().get_album(id.as_str(), None).await { | ||||||
|  |         Ok(album) => Some(AlbumInfo { | ||||||
|  |             name: album.data.name, | ||||||
|  |             artists: album.data.artists.iter().map(|x| x.name.clone()).collect(), | ||||||
|  |             genres: album.data.genres, | ||||||
|  |             songs: vec![], // TODO we could lookup songs and put them here!
 | ||||||
|  |         }), | ||||||
|  |         Err(_e) => None, | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user