commit 3052f31ffdaac2c8ec288fca73af1a7418d05daa (patch)
parent e3e64330f1fa44f51ef3f87cb4a99c4a75410432
Author: Alex Karle <alex@alexkarle.com>
Date: Tue, 4 Feb 2025 20:38:26 -0500
Add CLI that pages through playlists using token
Diffstat:
A | cli.pl | | | 54 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | get-token.pl | | | 74 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
D | spotilist.pl | | | 74 | -------------------------------------------------------------------------- |
3 files changed, 128 insertions(+), 74 deletions(-)
diff --git a/cli.pl b/cli.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+# utf8 shenanis -- files written and stdout both utf8
+use utf8;
+use open qw(:std :encoding(UTF-8));
+
+use LWP::UserAgent;
+use JSON::PP;
+
+if (!$ENV{SPOTIFY_TOKEN}) {
+ die "SPOTIFY_TOKEN not set in environment\n";
+}
+
+if (!@ARGV) {
+ die "usage: $0 username\n";
+}
+
+my $user = $ARGV[0];
+my $API = "https://api.spotify.com/v1";
+
+sub get_playlists {
+ my $ua = LWP::UserAgent->new();
+ my @playlists;
+ my $url = "$API/users/$user/playlists";
+ while (1) {
+ $ua->default_header(
+ "Authorization" => "Bearer $ENV{SPOTIFY_TOKEN}"
+ );
+ my $res = $ua->get($url);
+ if (!$res->is_success) {
+ use Data::Dumper;
+ print(Dumper($res));
+ my $err = $res->decoded_content;
+ die "Failed to fetch playlists: $err";
+ }
+ my $j = decode_json($res->decoded_content);
+ foreach my $item (@{$j->{items}}) {
+ push(@playlists, $item);
+ }
+ if (!$j->{next}) {
+ last;
+ }
+ print("Paging: $url\n");
+ $url = $j->{next};
+ }
+ return @playlists;
+}
+
+my @p = get_playlists();
+print($_->{name} . "\n") for @p;
+
+exit 0;
diff --git a/get-token.pl b/get-token.pl
@@ -0,0 +1,74 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use Mojolicious::Lite;
+use LWP::UserAgent;
+use MIME::Base64;
+use JSON::PP;
+
+my $CLIENT_ID = $ENV{SPOTIFY_CLIENT_ID};
+my $CLIENT_SECRET = $ENV{SPOTIFY_CLIENT_SECRET};
+if (!$CLIENT_ID || !$CLIENT_SECRET) {
+ die "Spotify Env Vars not set\n";
+}
+
+my $AUTH_URL = "https://accounts.spotify.com/authorize"
+ . "?client_id=$CLIENT_ID"
+ . "&response_type=code"
+ . "&redirect_uri=http://localhost:3000/auth"
+ . "&scope=playlist-read-private%20playlist-read-collaborative"
+ . "&state=" . int(rand() * 100);
+
+get '/' => sub {
+ my $c = shift;
+ $c->render(
+ template => "index",
+ AUTH_URL => $AUTH_URL,
+ );
+};
+
+get 'auth' => sub {
+ my $c = shift;
+
+ # TODO: check state too if ever productionize / allow multiple
+ # users instead of local-only
+ my $code = $c->param("code");
+ if (!$code) {
+ $c->render(text => "Failed to Authorize; Go back and try again");
+ return;
+ }
+ my $ua = LWP::UserAgent->new();
+ my $hash = encode_base64("$CLIENT_ID:$CLIENT_SECRET", "");
+ $ua->default_header('Authorization' => "Basic $hash");
+ my %form = (
+ grant_type => "authorization_code",
+ code => $code,
+ redirect_uri => "http://localhost:3000/auth",
+ );
+ my $res = $ua->post(
+ "https://accounts.spotify.com/api/token",
+ \%form,
+ );
+ if (!$res->is_success) {
+ my $err = $res->decoded_content;
+ return $c->render(text => "Error Authenticating: $err");
+ }
+ my $json = decode_json($res->decoded_content);
+ my $tok = $json->{access_token} . "";
+ $c->render(text => $tok);
+};
+
+
+app->start;
+
+__DATA__
+
+@@index.html.ep
+<h1>Spotify Playlist Exporter</h1>
+<p>Hello and welcome to the Spotify Playlist Exporter!</p>
+<p>To start, first log in to Spotify and authorize this
+app by clicking the link below:</p>
+<a href=<%= $AUTH_URL %>>
+Authorize
+</a>
diff --git a/spotilist.pl b/spotilist.pl
@@ -1,74 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-use warnings;
-
-use Mojolicious::Lite;
-use LWP::UserAgent;
-use MIME::Base64;
-use JSON::PP;
-
-my $CLIENT_ID = $ENV{SPOTIFY_CLIENT_ID};
-my $CLIENT_SECRET = $ENV{SPOTIFY_CLIENT_SECRET};
-if (!$CLIENT_ID || !$CLIENT_SECRET) {
- die "Spotify Env Vars not set\n";
-}
-
-my $AUTH_URL = "https://accounts.spotify.com/authorize"
- . "?client_id=$CLIENT_ID"
- . "&response_type=code"
- . "&redirect_uri=http://localhost:3000/auth"
- . "&scope=playlist-read-private%20playlist-read-collaborative"
- . "&state=" . int(rand() * 100);
-
-get '/' => sub {
- my $c = shift;
- $c->render(
- template => "index",
- AUTH_URL => $AUTH_URL,
- );
-};
-
-get 'auth' => sub {
- my $c = shift;
-
- # TODO: check state too if ever productionize / allow multiple
- # users instead of local-only
- my $code = $c->param("code");
- if (!$code) {
- $c->render(text => "Failed to Authorize; Go back and try again");
- return;
- }
- my $ua = LWP::UserAgent->new();
- my $hash = encode_base64("$CLIENT_ID:$CLIENT_SECRET", "");
- $ua->default_header('Authorization' => "Basic $hash");
- my %form = (
- grant_type => "authorization_code",
- code => $code,
- redirect_uri => "http://localhost:3000/auth",
- );
- my $res = $ua->post(
- "https://accounts.spotify.com/api/token",
- \%form,
- );
- if (!$res->is_success) {
- my $err = $res->decoded_content;
- return $c->render(text => "Error Authenticating: $err");
- }
- my $json = decode_json($res->decoded_content);
- my $tok = $json->{access_token} . "";
- return $c->render(text => $tok);
-};
-
-
-app->start;
-
-__DATA__
-
-@@index.html.ep
-<h1>Spotify Playlist Exporter</h1>
-<p>Hello and welcome to the Spotify Playlist Exporter!</p>
-<p>To start, first log in to Spotify and authorize this
-app by clicking the link below:</p>
-<a href=<%= $AUTH_URL %>>
-Authorize
-</a>