Repository: aome510/spotify-player (language: rust)

Issue:
playback (CLI) should be able to play a single chosen track
**Is your feature already implemented in the latest `master`?**
No. But maybe it is buried in an undocumented feature?

**Is your feature request related to a problem? Please describe.**
If I want to play a specific track from a specific album using the CLI, I should be able to do that through the CLI. I know I can do it through the TUI; but this functionality is not easily available through the CLI.

**Describe the solution you'd like**
```
spotify_player search <search> | {json fiddling here}
{get the id}
spotify_player playback start context track --id <id>
```




Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 4205a291..cc9ef9a8 100644
--- a/README.md
+++ b/README.md
@@ -275,6 +275,7 @@ To enable [fuzzy search](https://en.wikipedia.org/wiki/Approximate_string_matchi
 
 - `get`: Get Spotify data (playlist/album/artist data, user's data, etc)
 - `playback`: Interact with the playback (start a playback, play-pause, next, etc)
+- `search`: Search spotify
 - `connect`: Connect to a Spotify device
 - `like`: Like currently playing track
 - `authenticate`: Authenticate the application
@@ -287,6 +288,18 @@ For more details, run `spotify_player -h` or `spotify_player {command} -h`, in w
 - When using the CLI for the first time, you'll need to run `spotify_player authenticate` to authenticate the application beforehand.
 - Under the hood, CLI command is handled by sending requests to a `spotify_player` client socket running on port `client_port`, [a general application configuration](https://github.com/aome510/spotify-player/blob/master/docs/config.md#general) with a default value of `8080`. If there is no running application's instance, a new client will be created upon handling the CLI commands, which increases the latency of the command.
 
+#### Scripting
+
+The `spotify_player` command-line interface makes scripting easy.
+With the `search` subcommand, you can search Spotify and retrieve data in JSON format, enabling queries with tools like [jq](https://jqlang.github.io/jq/).
+
+Here’s an example of starting playback for the first track from a search query:
+
+```sh
+read -p "Search spotify: " query
+spotify_player playback start track --id $(spotify_player search "$query" | jq '.tracks.[0].id' | xargs)
+```
+
 ## Commands
 
 To go to the shortcut help page, press `?` or `C-h` (default shortcuts for `OpenCommandHelp` command).
diff --git a/spotify_player/src/cli/client.rs b/spotify_player/src/cli/client.rs
index b1cc0786..a2afa17e 100644
--- a/spotify_player/src/cli/client.rs
+++ b/spotify_player/src/cli/client.rs
@@ -388,6 +388,15 @@ async fn handle_playback_request(
 
             PlayerRequest::StartPlayback(Playback::Context(context_id, None), Some(shuffle))
         }
+        Command::StartTrack(id_or_name) => {
+            let ItemId::Track(id) = get_spotify_id(client, ItemType::Track, id_or_name).await?
+            else {
+                anyhow::bail!("Unable to get track id")
+            };
+
+            let track = client.track(id).await?;
+            PlayerRequest::StartPlayback(Playback::URIs(vec![track.id.into()], None), None)
+        }
         Command::PlayPause => PlayerRequest::ResumePause,
         Command::Play => PlayerRequest::Resume,
         Command::Pause => PlayerRequest::Pause,
diff --git a/spotify_player/src/cli/commands.rs b/spotify_player/src/cli/commands.rs
index 14c71c85..2e5e6b4e 100644
--- a/spotify_player/src/cli/commands.rs
+++ b/spotify_player/src/cli/commands.rs
@@ -47,6 +47,9 @@ fn init_playback_start_subcommand() -> Command {
                         .help("Shuffle tracks within the launched playback"),
                 ),
         ))
+        .subcommand(add_id_or_name_group(
+            Command::new("track").about("Start playback for a track"),
+        ))
         .subcommand(
             Command::new("liked")
                 .about("Start a liked tracks playback")
diff --git a/spotify_player/src/cli/handlers.rs b/spotify_player/src/cli/handlers.rs
index 3bb36984..11ec3480 100644
--- a/spotify_player/src/cli/handlers.rs
+++ b/spotify_player/src/cli/handlers.rs
@@ -75,6 +75,7 @@ fn handle_playback_subcommand(args: &ArgMatches) -> Result<Request> {
     let (cmd, args) = args.subcommand().expect("playback subcommand is required");
     let command = match cmd {
         "start" => match args.subcommand() {
+            Some(("track", args)) => Command::StartTrack(get_id_or_name(args)),
             Some(("context", args)) => {
                 let context_type = args
                     .get_one::<ContextType>("context_type")
diff --git a/spotify_player/src/cli/mod.rs b/spotify_player/src/cli/mod.rs
index 06685584..3bee6516 100644
--- a/spotify_player/src/cli/mod.rs
+++ b/spotify_player/src/cli/mod.rs
@@ -91,6 +91,7 @@ pub enum Command {
         id_or_name: IdOrName,
         shuffle: bool,
     },
+    StartTrack(IdOrName),
     StartLikedTracks {
         limit: usize,
         random: bool,


Test patch: