Skip to content

Commit 0ceec7e

Browse files
committed
Added experimental ZSH completion, some more commands and cleanup
1 parent 00f3b76 commit 0ceec7e

File tree

17 files changed

+464
-76
lines changed

17 files changed

+464
-76
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,4 @@ MigrationBackup/
359359

360360
# End of https://www.toptal.com/developers/gitignore/api/csharp
361361
sp0_aur/
362+
Sp0.Core/sp0-dev

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,48 @@ This configuration does not allow to manage and access user related endpoints, l
4646

4747
Afterwards, login via `sp0 login` and follow the instructions.
4848

49+
## Examples
50+
51+
### Transfer Playback using fzf
52+
53+
```bash
54+
#!/bin/sh
55+
device="$(sp0 player devices | jq -r "map(.name + \":\" + .id) | join(\"\n\")" | fzf | cut -d':' -f2)"
56+
if [ "$device" ]; then
57+
sp0 player transfer "$device" --play
58+
fi
59+
```
60+
61+
### Export a Playlist
62+
63+
```bash
64+
#!/bin/sh
65+
backupFile="${1:-backup.txt}"
66+
67+
playlist="$(sp0 playlists of-user | jq -sr "map(.name + \":\" + .id) | join(\"\n\")" | fzf)"
68+
playlistId="$(echo "$playlist" | rev | cut -d':' -f 1 | rev)"
69+
playlistName="$(echo "$playlist" | rev | cut -d':' -f 2- | rev)"
70+
file="$(printf '%q' "$playlistName")"
71+
if [ "$playlistId" ]; then
72+
sp0 playlists get-items "$playlistId" --output uri > "$backupFile"
73+
echo "Playlist track/epsiode URIs can be found in $backupFile"
74+
fi
75+
```
76+
77+
### Import a Playlist
78+
79+
```bash
80+
#!/bin/sh
81+
backupFile="${1:-backup.txt}"
82+
playlistName="${2:-Imported Playlist}"
83+
84+
if [[ -f "$backupFile" ]]; then
85+
uris="$(cat "$backupFile" | xargs echo -n | tr ' ' ',')"
86+
paylistId="$(sp0 playlists create "$playlistName" --private --output id)"
87+
sp0 playlists add-items "$playlistId" "$uris"
88+
fi
89+
```
90+
4991
## File Size & Exectution Notes
5092

5193
As you may have noted, the binary size of ~26MB is higher than usual form similar CLI Tools. This is because the binary includes the full .NET environment in a compressed form, accomplished by [dotnet-warp](https://github.com/Hubert-Rybak/dotnet-warp).

Sp0.Core/src/App.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Threading.Tasks;
45
using McMaster.Extensions.CommandLineUtils;
@@ -41,6 +42,8 @@ public async Task<int> RunApp(string[] args, ServiceProvider services)
4142
() => $"sp0 version {Version.AppVersion}"
4243
);
4344

45+
app.CompletionCommand("completion", new List<ICompletionProvider> { new ZSHCompletionProvider() });
46+
4447
try
4548
{
4649
return await app.ExecuteAsync(args);

Sp0.Core/src/Arguments/PagingArguments.cs

Lines changed: 0 additions & 12 deletions
This file was deleted.

Sp0.Core/src/Commands/LoginCommand.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,39 @@ public void Register(CommandLineApplication app)
3131
{
3232
login.Description = "Log into a user account via OAuth2. Only required when accessing user related data.";
3333

34-
var addressCmd = login.Option<Uri?>(
34+
var addressCmd = login.OptionalOption<Uri?>(
3535
"-a|--address",
36-
$"Optional: URI of the webserver used to authenticate. Also needs to be added as redirect uri to your spotify app. Default: {addressDefault}",
36+
$"URI of the webserver used to authenticate. Also needs to be added as redirect uri to your spotify app",
37+
addressDefault,
3738
CommandOptionType.SingleValue
3839
);
3940
addressCmd.Validators.Add(new AbsoluteURIValidator());
4041

41-
var portOpt = login.Option<int?>(
42+
var portOpt = login.OptionalOption<int?>(
4243
"-p|--port",
43-
$"Optional: Listen port of the authentication webserver. Default: {portDefault}",
44+
$"Listen port of the authentication webserver",
45+
portDefault,
4446
CommandOptionType.SingleValue
4547
);
4648

47-
var scopesOpt = login.Option<List<string>?>(
49+
var scopesOpt = login.OptionalOption<List<string>?>(
4850
"-s|--scopes",
49-
$"Optional: A comma seperated list of scopes to request. Default: All",
51+
$"A comma seperated list of scopes to request",
52+
"All",
5053
CommandOptionType.SingleValue
5154
);
5255

53-
var timeoutOpt = login.Option<int?>(
56+
var timeoutOpt = login.OptionalOption<int?>(
5457
"-t|--timeout",
55-
$"Optional: Timeout of command in seconds. Default: ${timeoutDefault}",
58+
$"Timeout of command in seconds",
59+
timeoutDefault,
5660
CommandOptionType.SingleValue
5761
);
5862

59-
var stateOpt = login.Option<int?>(
63+
var stateOpt = login.OptionalOption<int?>(
6064
"--state",
61-
$"Optional: State value used for the authentcation. Default: random generated string",
65+
$"State value used for the authentcation",
66+
"random generated string",
6267
CommandOptionType.SingleValue
6368
);
6469

Sp0.Core/src/Commands/PlayerCommand.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ public void Register(CommandLineApplication app)
4040

4141
private CommandOption DeviceIdOption(CommandLineApplication app)
4242
{
43-
return app.Option(
43+
return app.OptionalOption<string>(
4444
"-d|--device-id",
45-
"Optional: The id of the device this command is targeting. If not supplied, the user’s currently active device is the target.",
45+
"The id of the device this command is targeting",
46+
"the user’s currently active device",
4647
CommandOptionType.SingleValue
4748
);
4849
}
@@ -104,9 +105,10 @@ private void CurrentPlaybackCommand(CommandLineApplication player)
104105
{
105106
currentPlayback.Description = "Get information about the user’s current playback state, including track or episode, progress, and active device.";
106107

107-
var market = currentPlayback.Option<string>(
108+
var market = currentPlayback.OptionalOption<string>(
108109
"-m|--market",
109-
"Optional: The specifc market, used for track re-linking",
110+
"The specifc market, used for track re-linking",
111+
"User's market",
110112
CommandOptionType.SingleValue
111113
);
112114

@@ -251,27 +253,31 @@ private void PlayCommand(CommandLineApplication player)
251253

252254
var deviceId = DeviceIdOption(play);
253255

254-
var contextUri = play.Option(
256+
var contextUri = play.OptionalOption<string>(
255257
"-c|--context-uri",
256-
"Optional: Spotify URI of the context to play. Valid contexts are albums, artists, playlists.",
258+
"Spotify URI of the context to play. Valid contexts are albums, artists, playlists.",
259+
"none",
257260
CommandOptionType.SingleValue
258261
);
259262

260-
var uris = play.Option<List<string>>(
263+
var uris = play.OptionalOption<List<string>>(
261264
"-u|--uris",
262-
"Optional: A list of Spotify track URIs to play, seperated by comma",
265+
"A list of Spotify track URIs to play, seperated by comma",
266+
"none",
263267
CommandOptionType.SingleValue
264268
);
265269

266-
var positionMs = play.Option<int?>(
270+
var positionMs = play.OptionalOption<int?>(
267271
"-p|--positon-ms",
268-
"Optional: Indicates from what position to start playback. Must be a positive number. Passing in a position that is greater than the length of the track will cause the player to start playing the next song.",
272+
"Indicates from what position to start playback. Must be a positive number. Passing in a position that is greater than the length of the track will cause the player to start playing the next song.",
273+
"none",
269274
CommandOptionType.SingleValue
270275
);
271276

272-
var offset = play.Option<string>(
277+
var offset = play.OptionalOption<string>(
273278
"-o|--offset",
274-
"Optional: Indicates from where in the context playback should start. Only available when context-uri corresponds to an album or playlist object, or when the uris parameter is used. Either a zero based position or URI",
279+
"Indicates from where in the context playback should start. Only available when context-uri corresponds to an album or playlist object, or when the uris parameter is used. Either a zero based position or URI",
280+
"none",
275281
CommandOptionType.SingleValue
276282
);
277283

0 commit comments

Comments
 (0)