Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor client request handling module #418

Merged
merged 6 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 15 additions & 36 deletions spotify_player/src/cli/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ use tracing::Instrument;

use crate::{
cli::Request,
client::Client,
client::{Client, PlayerRequest},
config::get_cache_folder_path,
event::PlayerRequest,
state::{Context, ContextId, Playback, SharedState, SimplifiedPlayback},
state::{Context, ContextId, Playback, PlaybackMetadata, SharedState},
};
use rspotify::{
model::*,
Expand All @@ -25,8 +24,8 @@ use rspotify::{
use super::*;

pub async fn start_socket(client: Client, socket: UdpSocket, state: Option<SharedState>) {
// initialize the receive buffer to be 4096 bytes
let mut buf = [0; MAX_REQUEST_SIZE];

loop {
match socket.recv_from(&mut buf).await {
Err(err) => tracing::warn!("Failed to receive from the socket: {err:#}"),
Expand Down Expand Up @@ -95,7 +94,6 @@ async fn current_playback(
match state {
Some(ref state) => Ok(state.player.read().current_playback()),
None => client
.spotify
.current_playback(None, None::<Vec<_>>)
.await
.context("get current playback"),
Expand All @@ -107,11 +105,8 @@ async fn handle_socket_request(
state: &Option<SharedState>,
request: super::Request,
) -> Result<Vec<u8>> {
if client.spotify.session().await.is_invalid() {
if let Some(state) = state {
tracing::info!("Spotify client's session is invalid, re-creating a new session...");
client.new_session(state).await?;
}
if let Some(state) = state {
client.check_valid_session(state).await?;
}

match request {
Expand All @@ -127,7 +122,7 @@ async fn handle_socket_request(
let id = match data {
IdOrName::Id(id) => id,
IdOrName::Name(name) => {
let devices = client.spotify.device().await?;
let devices = client.device().await?;
match devices
.into_iter()
.find(|d| d.name == name)
Expand All @@ -141,7 +136,7 @@ async fn handle_socket_request(
}
};

client.spotify.transfer_playback(&id, None).await?;
client.transfer_playback(&id, None).await?;
Ok(Vec::new())
}
Request::Like { unlike } => {
Expand All @@ -158,12 +153,9 @@ async fn handle_socket_request(

if let Some(id) = track.and_then(|t| t.id.to_owned()) {
if unlike {
client
.spotify
.current_user_saved_tracks_delete([id])
.await?;
client.current_user_saved_tracks_delete([id]).await?;
} else {
client.spotify.current_user_saved_tracks_add([id]).await?;
client.current_user_saved_tracks_add([id]).await?;
}
}

Expand All @@ -187,7 +179,7 @@ async fn handle_get_key_request(
serde_json::to_vec(&playback)?
}
Key::Devices => {
let devices = client.spotify.device().await?;
let devices = client.device().await?;
serde_json::to_vec(&devices)?
}
Key::UserPlaylists => {
Expand All @@ -211,7 +203,7 @@ async fn handle_get_key_request(
serde_json::to_vec(&artists)?
}
Key::Queue => {
let queue = client.spotify.current_user_queue().await?;
let queue = client.current_user_queue().await?;
serde_json::to_vec(&queue)?
}
})
Expand Down Expand Up @@ -326,11 +318,8 @@ async fn handle_playback_request(
let playback = match state {
Some(state) => state.player.read().buffered_playback.clone(),
None => {
let playback = client
.spotify
.current_playback(None, None::<Vec<_>>)
.await?;
playback.as_ref().map(SimplifiedPlayback::from_playback)
let playback = client.current_playback(None, None::<Vec<_>>).await?;
playback.as_ref().map(PlaybackMetadata::from_playback)
}
};

Expand Down Expand Up @@ -413,7 +402,6 @@ async fn handle_playback_request(
// the function scope is from the application's state (cached) or the `current_playback` API.
// Therefore, we need to make an additional API request to get the playback's progress.
let progress = client
.spotify
.current_playback(None, None::<Vec<_>>)
.await?
.context("no active playback found!")?
Expand Down Expand Up @@ -457,7 +445,7 @@ async fn handle_playback_request(
}

async fn handle_playlist_request(client: &Client, command: PlaylistCommand) -> Result<String> {
let uid = client.spotify.current_user().await?.id;
let uid = client.current_user().await?.id;

match command {
PlaylistCommand::New {
Expand All @@ -467,7 +455,6 @@ async fn handle_playlist_request(client: &Client, command: PlaylistCommand) -> R
description,
} => {
let resp = client
.spotify
.user_playlist_create(
uid,
name.as_str(),
Expand All @@ -483,7 +470,6 @@ async fn handle_playlist_request(client: &Client, command: PlaylistCommand) -> R
}
PlaylistCommand::Delete { id } => {
let following = client
.spotify
.playlist_check_follow(id.to_owned(), &[uid])
.await
.context(format!("Could not find playlist '{}'", id.id()))?
Expand All @@ -492,7 +478,7 @@ async fn handle_playlist_request(client: &Client, command: PlaylistCommand) -> R

// Won't delete if not following
if following {
client.spotify.playlist_unfollow(id.to_owned()).await?;
client.playlist_unfollow(id.to_owned()).await?;
Ok(format!("Playlist '{id}' was deleted/unfollowed"))
} else {
Ok(format!(
Expand All @@ -518,14 +504,12 @@ async fn handle_playlist_request(client: &Client, command: PlaylistCommand) -> R
} => playlist_import(client, import_from, import_to, delete).await,
PlaylistCommand::Fork { id } => {
let from = client
.spotify
.playlist(id.to_owned(), None, None)
.await
.context(format!("Cannot import from {}.", id.id()))?;
let from_desc = from.description.unwrap_or_default();

let to = client
.spotify
.user_playlist_create(
uid,
&from.name,
Expand Down Expand Up @@ -568,7 +552,6 @@ async fn handle_playlist_request(client: &Client, command: PlaylistCommand) -> R
}

let pl_follow = client
.spotify
.playlist_check_follow(to_id.as_ref(), &[uid.as_ref()])
.await?
.pop()
Expand Down Expand Up @@ -682,7 +665,6 @@ async fn playlist_import(

if track_buff.len() == TRACK_BUFFER_CAP {
client
.spotify
.playlist_remove_all_occurrences_of_items(
import_to.as_ref(),
track_buff,
Expand All @@ -695,7 +677,6 @@ async fn playlist_import(

if !track_buff.is_empty() {
client
.spotify
.playlist_remove_all_occurrences_of_items(import_to.as_ref(), track_buff, None)
.await?;
}
Expand All @@ -717,7 +698,6 @@ async fn playlist_import(

if track_buff.len() == TRACK_BUFFER_CAP {
client
.spotify
.playlist_add_items(import_to.as_ref(), track_buff, None)
.await?;
track_buff = Vec::new();
Expand All @@ -728,7 +708,6 @@ async fn playlist_import(

if !track_buff.is_empty() {
client
.spotify
.playlist_add_items(import_to.as_ref(), track_buff, None)
.await?;
}
Expand Down
3 changes: 2 additions & 1 deletion spotify_player/src/cli/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use super::*;
use anyhow::{Context, Result};
use clap::{ArgMatches, Id};
use clap_complete::{generate, Shell};
use rspotify::clients::BaseClient;
use std::net::UdpSocket;

fn receive_response(socket: &UdpSocket) -> Result<Response> {
Expand Down Expand Up @@ -159,7 +160,7 @@ fn try_connect_to_client(socket: &UdpSocket, configs: &state::Configs) -> Result
// create a Spotify API client
let client =
client::Client::new(session, auth_config, configs.app_config.client_id.clone());
rt.block_on(client.init_token())?;
rt.block_on(client.refresh_token())?;

// create a client socket for handling CLI commands
let client_socket = rt.block_on(tokio::net::UdpSocket::bind(("127.0.0.1", port)))?;
Expand Down
13 changes: 6 additions & 7 deletions spotify_player/src/client/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ use anyhow::Context;
use rspotify::model::PlayableItem;
use tracing::Instrument;

use crate::{event::ClientRequest, state::*};
use crate::state::*;

#[cfg(feature = "lyric-finder")]
use crate::utils::map_join;

use super::ClientRequest;

struct PlayerEventHandlerState {
add_track_to_queue_req_timer: std::time::Instant,
}
Expand All @@ -18,12 +20,9 @@ pub async fn start_client_handler(
client_sub: flume::Receiver<ClientRequest>,
) {
while let Ok(request) = client_sub.recv_async().await {
if client.spotify.session().await.is_invalid() {
tracing::info!("Spotify client's session is invalid, re-creating a new session...");
if let Err(err) = client.new_session(&state).await {
tracing::error!("Failed to create a new session: {err:#}");
continue;
}
if let Err(err) = client.check_valid_session(&state).await {
tracing::error!("{err:#}");
continue;
}

let state = state.clone();
Expand Down
Loading
Loading