feat: add support for album links
- perform little code refactor, create new module spotifypull/1/head
parent
34c294ef0f
commit
cea5958e43
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "songlify"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2018"
|
||||
|
||||
# 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 aspotify::Client;
|
||||
use teloxide::prelude::*;
|
||||
|
||||
enum SpotifyURL {
|
||||
Track(String),
|
||||
}
|
||||
use spotify::SpotifyKind::Track;
|
||||
|
||||
struct TrackInfo {
|
||||
name: String,
|
||||
artist: Vec<String>,
|
||||
duration: Duration,
|
||||
}
|
||||
use crate::spotify::SpotifyKind::Album;
|
||||
|
||||
fn get_spotify_entry(url: &str) -> Option<SpotifyURL> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
mod spotify;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
@ -42,16 +16,14 @@ async fn main() {
|
|||
|
||||
let bot = Bot::from_env().auto_send();
|
||||
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 {
|
||||
Some(spotify) => {
|
||||
let spotify_creds =
|
||||
ClientCredentials::from_env().expect("CLIENT_ID and CLIENT_SECRET not found.");
|
||||
let spotify_client = Box::new(Client::new(spotify_creds));
|
||||
let spotify_client = spotify::get_spotify_client();
|
||||
match spotify {
|
||||
Track(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 {
|
||||
Some(info) => {
|
||||
let reply = format!(
|
||||
|
@ -60,7 +32,7 @@ async fn main() {
|
|||
🧑🎤 Artist(s): {}\n\
|
||||
⏳ Duration: {} second(s)",
|
||||
info.name,
|
||||
info.artist.join(", "),
|
||||
info.artists.join(", "),
|
||||
info.duration.as_secs()
|
||||
);
|
||||
Some(message.reply_to(reply).await?)
|
||||
|
@ -68,6 +40,37 @@ async fn main() {
|
|||
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,
|
||||
|
|
|
@ -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…
Reference in New Issue